Exemplo n.º 1
0
func (p *printer) file(src *ast.File) {
	p.setComment(src.Doc)
	p.print(src.Pos(), src.Tok, blank)
	p.expr(src.Name)
	p.declList(src.Decls)
	p.print(newline)
}
Exemplo n.º 2
0
// Merges multiple import blocks and then adds paths
func (p *compiler) addAnthaImports(file *ast.File, paths []string) {
	var specs []ast.Spec
	var decls []ast.Decl
	var pos token.Pos // Dummy position to use for generated imports

	for _, d := range file.Decls {
		gd, ok := d.(*ast.GenDecl)
		if pos == token.NoPos {
			pos = d.Pos()
		}
		if !ok || gd.Tok != token.IMPORT {
			decls = append(decls, d)
			continue
		}
		for _, s := range gd.Specs {
			specs = append(specs, s)
		}
	}

	for _, p := range paths {
		specs = append(specs,
			&ast.ImportSpec{
				Path: &ast.BasicLit{
					Kind:     token.STRING,
					Value:    fmt.Sprintf(`"%s"`, p),
					ValuePos: pos,
				}})
	}

	if len(specs) == 0 {
		if len(decls) != len(file.Decls) {
			// Clean up empty imports
			file.Decls = decls
		}
		return
	}

	//if pos == token.NoPos {
	//	log.Panicf("no declarations in antha file: %s", file.Name)
	//}

	merged := &ast.GenDecl{
		Tok:    token.IMPORT,
		Lparen: pos,
		Rparen: pos,
		Specs:  specs,
	}

	decls = append([]ast.Decl{merged}, decls...)
	file.Decls = decls
	// NB(ddn): tried to sort here, but the following needs proper token.Pos,
	// which are annoying to generate now. A gofmt on the generated file should
	// be just as good.
	//ast.SortImports(token.NewFileSet(), file)
}
Exemplo n.º 3
0
// output when compiled is always a package
// so translate protocol etc into package
func (p *compiler) file(src *ast.File) {
	p.analyze(src)
	p.transform(src)

	p.setComment(src.Doc)

	// Print package name
	p.print(src.Pos(), token.PACKAGE, blank)
	p.expr(src.Name)

	// print (transformed) declarations
	p.declList(src.Decls)
	p.print(newline)

	p.generate()
}
Exemplo n.º 4
0
// fileExports removes unexported declarations from src in place.
//
func (r *reader) fileExports(src *ast.File) {
	j := 0
	for _, d := range src.Decls {
		if r.filterDecl(d) {
			src.Decls[j] = d
			j++
		}
	}
	src.Decls = src.Decls[0:j]
}
Exemplo n.º 5
0
// Remove antha param declarations since they are fully captured in indexParams()
func (p *compiler) removeParamDecls(src *ast.File) {
	var newd []ast.Decl
	for _, decl := range src.Decls {
		toadd := true
		switch decl.(type) {
		case *ast.GenDecl:
			switch decl.(*ast.GenDecl).Tok {
			case token.PARAMETERS, token.DATA, token.INPUTS, token.OUTPUTS:
				toadd = false
			}
		}
		if toadd {
			newd = append(newd, decl)
		}
	}
	src.Decls = newd
}
Exemplo n.º 6
0
// readFile adds the AST for a source file to the reader.
//
func (r *reader) readFile(src *ast.File) {
	// add package documentation
	if src.Doc != nil {
		r.readDoc(src.Doc)
		src.Doc = nil // doc consumed - remove from AST
	}

	// add all declarations
	for _, decl := range src.Decls {
		switch d := decl.(type) {
		case *ast.GenDecl:
			switch d.Tok {
			case token.IMPORT:
				// imports are handled individually
				for _, spec := range d.Specs {
					if s, ok := spec.(*ast.ImportSpec); ok {
						if import_, err := strconv.Unquote(s.Path.Value); err == nil {
							r.imports[import_] = 1
						}
					}
				}
			case token.CONST, token.VAR:
				// constants and variables are always handled as a group
				r.readValue(d)
			case token.TYPE:
				// types are handled individually
				if len(d.Specs) == 1 && !d.Lparen.IsValid() {
					// common case: single declaration w/o parentheses
					// (if a single declaration is parenthesized,
					// create a new fake declaration below, so that
					// antha/doc type declarations always appear w/o
					// parentheses)
					if s, ok := d.Specs[0].(*ast.TypeSpec); ok {
						r.readType(d, s)
					}
					break
				}
				for _, spec := range d.Specs {
					if s, ok := spec.(*ast.TypeSpec); ok {
						// use an individual (possibly fake) declaration
						// for each type; this also ensures that each type
						// gets to (re-)use the declaration documentation
						// if there's none associated with the spec itself
						fake := &ast.GenDecl{
							Doc: d.Doc,
							// don't use the existing TokPos because it
							// will lead to the wrong selection range for
							// the fake declaration if there are more
							// than one type in the group (this affects
							// src/cmd/anthadoc/anthadoc.go's posLink_urlFunc)
							TokPos: s.Pos(),
							Tok:    token.TYPE,
							Specs:  []ast.Spec{s},
						}
						r.readType(fake, s)
					}
				}
			}
		case *ast.FuncDecl:
			r.readFunc(d)
		}
	}

	// collect MARKER(...): annotations
	r.readNotes(src.Comments)
	src.Comments = nil // consumed unassociated comments - remove from AST
}