Beispiel #1
0
func doSpec(sk int, sv interface{}, dirpkg string) {
	//Printf("doSpec: %#v\n", sv)
	switch x := sv.(type) {
	case (*ast.ImportSpec):
		path := x.Path.Value
		path = path[1 : len(path)-1] // Omit initial & final <">
		name := path
		j := strings.LastIndex(name, "/")
		if j > 0 {
			name = name[j+1:]
		}
		if x.Name != nil {
			name = x.Name.Name
		}
		//Printf("ImportSpec: NAME %s PATH %s\n", name, path)
		Printf("@@ %s { IMPORT %s path: %s }\n", dirpkg, name, path)
	case (*ast.TypeSpec):
		name := x.Name.Name
		if !ast.IsExported(x.Name.Name) {
			return
		}
		Printf("@@ %s { TYPE %s type: %s }\n", dirpkg, name, typeStr(x.Type))
	case (*ast.ValueSpec):
		for _, nv := range x.Names {
			//Printf("    ValueSPEC [%d] %s : %s\n", nk, nv.Name, Cond(x.Type == nil, "nil", typeStr(x.Type)))
			if !ast.IsExported(nv.Name) {
				return
			}
			Printf("@@ %s { VALUE %s : %s }\n", dirpkg, nv.Name, Cond(x.Type == nil, "!", typeStr(x.Type)))
		}
	default:
		panic(Sprintf("doSpec: DEFAULT: %#v\n", x))
	}
}
Beispiel #2
0
func (g *Grapher) assignMethodPaths(named *types.Named, prefix []string, pkgscope bool) {
	for i := 0; i < named.NumMethods(); i++ {
		m := named.Method(i)
		path := append(append([]string{}, prefix...), m.Name())
		g.paths[m] = path

		g.exported[m] = ast.IsExported(m.Name())
		g.pkgscope[m] = pkgscope

		if s := m.Scope(); s != nil {
			g.assignPaths(s, path, false)
		}
	}

	if iface, ok := named.Underlying().(*types.Interface); ok {
		for i := 0; i < iface.NumExplicitMethods(); i++ {
			m := iface.Method(i)
			path := append(append([]string{}, prefix...), m.Name())
			g.paths[m] = path

			g.exported[m] = ast.IsExported(m.Name())
			g.pkgscope[m] = pkgscope

			if s := m.Scope(); s != nil {
				g.assignPaths(s, path, false)
			}
		}
	}
}
Beispiel #3
0
// lintValueSpecDoc examines package-global variables and constants.
// It complains if they are not individually declared,
// or if they are not suitably documented in the right form (unless they are in a block that is commented).
func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
	kind := "var"
	if gd.Tok == token.CONST {
		kind = "const"
	}

	if len(vs.Names) > 1 {
		// Check that none are exported.
		for _, n := range vs.Names {
			if ast.IsExported(n.Name) {
				f.errorf(vs, 1, "exported %s %s should have its own declaration", kind, n.Name)
				return
			}
		}
	}

	// Only one name.
	name := vs.Names[0].Name
	if !ast.IsExported(name) {
		return
	}

	if vs.Doc == nil {
		if gd.Doc == nil && !genDeclMissingComments[gd] {
			f.errorf(vs, 1, "exported %s %s should have comment or be unexported", kind, name)
			genDeclMissingComments[gd] = true
		}
		return
	}
	prefix := name + " "
	if !strings.HasPrefix(vs.Doc.Text(), prefix) {
		f.errorf(vs.Doc, 1, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
	}
}
Beispiel #4
0
// checkInPackageBlock performs safety checks for renames of
// func/var/const/type objects in the package block.
func (r *renamer) checkInPackageBlock(from types.Object) {
	// Check that there are no references to the name from another
	// package if the renaming would make it unexported.
	if ast.IsExported(from.Name()) && !ast.IsExported(r.to) {
		for pkg, info := range r.packages {
			if pkg == from.Pkg() {
				continue
			}
			if id := someUse(info, from); id != nil &&
				!r.checkExport(id, pkg, from) {
				break
			}
		}
	}

	info := r.packages[from.Pkg()]

	// Check that in the package block, "init" is a function, and never referenced.
	if r.to == "init" {
		kind := objectKind(from)
		if kind == "func" {
			// Reject if intra-package references to it exist.
			for id, obj := range info.Uses {
				if obj == from {
					r.errorf(from.Pos(),
						"renaming this func %q to %q would make it a package initializer",
						from.Name(), r.to)
					r.errorf(id.Pos(), "\tbut references to it exist")
					break
				}
			}
		} else {
			r.errorf(from.Pos(), "you cannot have a %s at package level named %q",
				kind, r.to)
		}
	}

	// Check for conflicts between package block and all file blocks.
	for _, f := range info.Files {
		fileScope := info.Info.Scopes[f]
		b, prev := fileScope.LookupParent(r.to, token.NoPos)
		if b == fileScope {
			r.errorf(from.Pos(), "renaming this %s %q to %q would conflict",
				objectKind(from), from.Name(), r.to)
			r.errorf(prev.Pos(), "\twith this %s",
				objectKind(prev))
			return // since checkInPackageBlock would report redundant errors
		}
	}

	// Check for conflicts in lexical scope.
	if from.Exported() {
		for _, info := range r.packages {
			r.checkInLexicalScope(from, info)
		}
	} else {
		r.checkInLexicalScope(from, info)
	}
}
Beispiel #5
0
// checkInPackageBlock performs safety checks for renames of
// func/var/const/type objects in the package block.
func (r *Unexporter) checkInPackageBlock(objsToUpdate map[types.Object]string, from types.Object, to string) {
	// Check that there are no references to the name from another
	// package if the renaming would make it unexported.
	if ast.IsExported(from.Name()) && !ast.IsExported(to) {
		for pkg, info := range r.packages {
			if pkg == from.Pkg() {
				continue
			}
			if id := someUse(info, from); id != nil &&
				!r.checkExport(id, pkg, from, to) {
				break
			}
		}
	}

	info := r.packages[from.Pkg()]
	lexinfo := r.lexInfo(info)

	// Check that in the package block, "init" is a function, and never referenced.
	if to == "init" {
		kind := objectKind(from)
		if kind == "func" {
			// Reject if intra-package references to it exist.
			if refs := lexinfo.Refs[from]; len(refs) > 0 {
				r.warn(from,
					r.errorf(from.Pos(),
						"renaming this func %q to %q would make it a package initializer",
						from.Name(), to),
					r.errorf(refs[0].Id.Pos(), "\tbut references to it exist"))
			}
		} else {
			r.warn(from, r.errorf(from.Pos(), "you cannot have a %s at package level named %q",
				kind, to))
		}
	}

	// Check for conflicts between package block and all file blocks.
	for _, f := range info.Files {
		if prev, b := lexinfo.Blocks[f].Lookup(to); b == lexinfo.Blocks[f] {
			r.warn(from,
				r.errorf(from.Pos(), "renaming this %s %q to %q would conflict",
					objectKind(from), from.Name(), to),
				r.errorf(prev.Pos(), "\twith this %s",
					objectKind(prev)))
			return // since checkInPackageBlock would report redundant errors
		}
	}

	// Check for conflicts in lexical scope.
	if from.Exported() {
		for _, info := range r.packages {
			r.checkInLexicalScope(objsToUpdate, from, to, info)
		}
	} else {
		r.checkInLexicalScope(objsToUpdate, from, to, info)
	}
}
Beispiel #6
0
func (p *Package) FuncLink(fn *ast.FuncDecl) string {
	recv := FuncReceiver(fn)
	if ast.IsExported(fn.Name.Name) && (recv == "" || ast.IsExported(recv)) {
		if recv != "" {
			return "#" + MethodId(recv, fn.Name.Name)
		}
		return "#" + FuncId(fn.Name.Name)
	}
	return p.ReversePos(fn)
}
Beispiel #7
0
// interfaceMethods returns the expanded list of exported methods for an interface.
// The boolean complete reports whether the list contains all methods (that is, the
// interface has no unexported methods).
// pkg is the complete package name ("net/http")
// iname is the interface name.
func (w *Walker) interfaceMethods(pkg, iname string) (methods []method, complete bool) {
	t, ok := w.interfaces[pkgSymbol{pkg, iname}]
	if !ok {
		log.Fatalf("failed to find interface %s.%s", pkg, iname)
	}

	complete = true
	for _, f := range t.Methods.List {
		typ := f.Type
		switch tv := typ.(type) {
		case *ast.FuncType:
			for _, mname := range f.Names {
				if ast.IsExported(mname.Name) {
					ft := typ.(*ast.FuncType)
					methods = append(methods, method{
						name: mname.Name,
						sig:  w.funcSigString(ft),
					})
				} else {
					complete = false
				}
			}
		case *ast.Ident:
			embedded := typ.(*ast.Ident).Name
			if embedded == "error" {
				methods = append(methods, method{
					name: "Error",
					sig:  "() string",
				})
				continue
			}
			if !ast.IsExported(embedded) {
				log.Fatalf("unexported embedded interface %q in exported interface %s.%s; confused",
					embedded, pkg, iname)
			}
			m, c := w.interfaceMethods(pkg, embedded)
			methods = append(methods, m...)
			complete = complete && c
		case *ast.SelectorExpr:
			lhs := w.nodeString(tv.X)
			rhs := w.nodeString(tv.Sel)
			fpkg, ok := w.selectorFullPkg[lhs]
			if !ok {
				log.Fatalf("can't resolve selector %q in interface %s.%s", lhs, pkg, iname)
			}
			m, c := w.interfaceMethods(fpkg, rhs)
			methods = append(methods, m...)
			complete = complete && c
		default:
			log.Fatalf("unknown type %T in interface field", typ)
		}
	}
	return
}
Beispiel #8
0
func (v *annotationVisitor) Visit(n ast.Node) ast.Visitor {
	switch n := n.(type) {
	case *ast.TypeSpec:
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.FuncDecl:
		if n.Recv != nil {
			ast.Walk(v, n.Recv)
		}
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.Field:
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.ValueSpec:
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.FuncLit:
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.CompositeLit:
		if n.Type != nil {
			ast.Walk(v, n.Type)
		}
		return nil
	case *ast.Ident:
		if !ast.IsExported(n.Name) {
			return nil
		}
		v.addAnnotation(n, "", n.Name)
		return nil
	case *ast.SelectorExpr:
		if !ast.IsExported(n.Sel.Name) {
			return nil
		}
		if i, ok := n.X.(*ast.Ident); ok {
			v.addAnnotation(n, i.Name, n.Sel.Name)
			return nil
		}
	}
	return v
}
Beispiel #9
0
func getGenSpecs(opts *options, structArgs []*structArg) (genSpecs []*genSpec) {
	fset := token.NewFileSet()
	types := getAllTypes(fset)

	for _, structArg := range structArgs {
		g := newGenSpec(structArg.Pointer, structArg.Package, structArg.Name)
		genSpecs = append(genSpecs, g)
		key := joinName(structArg.Package, structArg.Name)
		typ, known := types[key]
		if known {
			g.Methods = getMethods(typ)
			s, err := getStructType(typ)
			if err == nil {
				fieldSpecs := getFieldSpecs(s, fset, opts)
				g.AddFieldSpecs(fieldSpecs)
			}
		} else {
			addError(fmt.Sprintf("%s is not a known struct type", key))
			g.Methods = getMethods(nil)
		}
		if opts.ExportedOnly {
			if ast.IsExported(structArg.Name) {
				notes = append(notes, fmt.Sprintf("the %s type is already exported; the -e[xported] flag is redundant (ignored)", structArg.Name))
			} else {
				addError(fmt.Sprintf("the %s type is not exported; the -e[xported] flag conflicts", structArg.Name))
			}
		}
	}
	if opts.All {
		for key, typ := range types {
			pkg, name := splitName(key)
			if !opts.ExportedOnly || ast.IsExported(name) {
				g := newGenSpec(opts.AllPointer, pkg, name)
				g.Methods = getMethods(typ)
				s, err := getStructType(typ)
				if err == nil {
					fieldSpecs := getFieldSpecs(s, fset, opts)
					g.AddFieldSpecs(fieldSpecs)
				}
				genSpecs = append(genSpecs, g)
			}
		}
	}

	for _, g := range genSpecs {
		g.DetermineImports()
	}

	return
}
Beispiel #10
0
// lintValueSpecDoc examines package-global variables and constants.
// It complains if they are not individually declared,
// or if they are not suitably documented in the right form (unless they are in a block that is commented).
func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
	kind := "var"
	if gd.Tok == token.CONST {
		kind = "const"
	}

	if len(vs.Names) > 1 {
		// Check that none are exported except for the first.
		for _, n := range vs.Names[1:] {
			if ast.IsExported(n.Name) {
				f.errorf(vs, 1, category("comments"), "exported %s %s should have its own declaration", kind, n.Name)
				return
			}
		}
	}

	// Only one name.
	name := vs.Names[0].Name
	if !ast.IsExported(name) {
		return
	}

	if vs.Doc == nil && gd.Doc == nil {
		if genDeclMissingComments[gd] {
			return
		}
		block := ""
		if kind == "const" && gd.Lparen.IsValid() {
			block = " (or a comment on this block)"
		}
		f.errorf(vs, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment%s or be unexported", kind, name, block)
		genDeclMissingComments[gd] = true
		return
	}
	// If this GenDecl has parens and a comment, we don't check its comment form.
	if gd.Lparen.IsValid() && gd.Doc != nil {
		return
	}
	// The relevant text to check will be on either vs.Doc or gd.Doc.
	// Use vs.Doc preferentially.
	doc := vs.Doc
	if doc == nil {
		doc = gd.Doc
	}
	prefix := name + " "
	if !strings.HasPrefix(doc.Text(), prefix) {
		f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
	}
}
Beispiel #11
0
func astFieldListToDecls(f *ast.FieldList, class int, flags int, scope *Scope) map[string]*Decl {
	count := 0
	for _, field := range f.List {
		count += len(field.Names)
	}

	if count == 0 {
		return nil
	}

	decls := make(map[string]*Decl, count)
	for _, field := range f.List {
		for _, name := range field.Names {
			if flags&DECL_FOREIGN != 0 && !ast.IsExported(name.Name()) {
				continue
			}
			d := new(Decl)
			d.Name = name.Name()
			d.Type = field.Type
			d.Class = int16(class)
			d.Flags = int16(flags)
			d.Children = astTypeToChildren(field.Type, flags, scope)
			d.Embedded = astTypeToEmbedded(field.Type)
			d.Scope = scope
			d.ValueIndex = -1
			d.init()
			decls[d.Name] = d
		}

		// add anonymous field as a child (type embedding)
		if class == DECL_VAR && field.Names == nil {
			tp := typePath(field.Type)
			if flags&DECL_FOREIGN != 0 && !ast.IsExported(tp.name) {
				continue
			}
			d := new(Decl)
			d.Name = tp.name
			d.Type = field.Type
			d.Class = int16(class)
			d.Flags = int16(flags)
			d.Scope = scope
			d.ValueIndex = -1
			d.init()
			decls[d.Name] = d
		}
	}
	return decls
}
Beispiel #12
0
func (scope *Scope) getPrimaryKey() string {
	var indirectValue reflect.Value

	indirectValue = reflect.Indirect(reflect.ValueOf(scope.Value))

	if indirectValue.Kind() == reflect.Slice {
		indirectValue = reflect.New(indirectValue.Type().Elem()).Elem()
	}

	if !indirectValue.IsValid() {
		return "id"
	}

	scopeTyp := indirectValue.Type()
	for i := 0; i < scopeTyp.NumField(); i++ {
		fieldStruct := scopeTyp.Field(i)
		if !ast.IsExported(fieldStruct.Name) {
			continue
		}

		// if primaryKey tag found, return column name
		if fieldStruct.Tag.Get("primaryKey") != "" {
			return ToSnake(fieldStruct.Name)
		}
	}

	//If primaryKey tag not found, fallback to id
	return "id"
}
Beispiel #13
0
// Get retrieves a single named value from the given builder.
// If the value has not been set, it returns (nil, false). Otherwise, it will
// return (value, true).
//
// If the named value was last set with Append or Extend, the returned value
// will be a slice. If the given Builder has been registered with Register or
// RegisterType and the given name is an exported field of the registered
// struct, the returned slice will have the same type as that field. Otherwise
// the slice will have type []interface{}. It will panic if the given name is a
// registered struct's exported field and the value set on the Builder is not
// assignable to the field.
func Get(builder interface{}, name string) (interface{}, bool) {
	val, ok := getBuilderMap(builder).Lookup(name)
	if !ok {
		return nil, false
	}

	list, isList := val.(ps.List)
	if isList {
		arrayType := anyArrayType

		if ast.IsExported(name) {
			structType := getBuilderStructType(reflect.TypeOf(builder))
			if structType != nil {
				field, ok := (*structType).FieldByName(name)
				if ok {
					arrayType = field.Type
				}
			}
		}

		val = listToSlice(list, arrayType).Interface()
	}

	return val, true
}
Beispiel #14
0
func (c *compiler) VisitFuncProtoDecl(f *ast.FuncDecl) Value {
	var fn_type *types.Func
	fn_name := f.Name.String()

	exported := ast.IsExported(fn_name)
	if fn_name == "init" {
		// Make "init" functions anonymous.
		fn_name = ""
		// "init" functions aren't recorded by the parser, so f.Name.Obj is
		// not set.
		fn_type = &types.Func{ /* no params or result */ }
	} else {
		fn_type = f.Name.Obj.Type.(*types.Func)
		if c.module.Name == "main" && fn_name == "main" {
			exported = true
		} else {
			pkgname := c.pkgmap[f.Name.Obj]
			fn_name = pkgname + "." + fn_name
		}
	}

	llvm_fn_type := c.types.ToLLVM(fn_type).ElementType()
	fn := llvm.AddFunction(c.module.Module, fn_name, llvm_fn_type)
	if exported {
		fn.SetLinkage(llvm.ExternalLinkage)
	}

	result := c.NewLLVMValue(fn, fn_type)
	if f.Name.Obj != nil {
		f.Name.Obj.Data = result
		f.Name.Obj.Type = fn_type
	}
	return result
}
Beispiel #15
0
func (symbols *Symbols) AddVar(d *ast.ValueSpec) {
	for _, name := range d.Names {
		if ast.IsExported(name.Name) {
			symbols.varcons = append(symbols.varcons, name.Name)
		}
	}
}
Beispiel #16
0
func (w *Walker) walkVar(vs *ast.ValueSpec) {
	for i, ident := range vs.Names {
		if !ast.IsExported(ident.Name) {
			continue
		}

		typ := ""
		if vs.Type != nil {
			typ = w.nodeString(vs.Type)
		} else {
			if len(vs.Values) == 0 {
				log.Fatalf("no values for var %q", ident.Name)
			}
			if len(vs.Values) > 1 {
				log.Fatalf("more than 1 values in ValueSpec not handled, var %q", ident.Name)
			}
			var err error
			typ, err = w.varValueType(vs.Values[i])
			if err != nil {
				log.Fatalf("unknown type of variable %q, type %T, error = %v\ncode: %s",
					ident.Name, vs.Values[i], err, w.nodeString(vs.Values[i]))
			}
		}
		w.emitFeature(fmt.Sprintf("var %s %s", ident, typ))
	}
}
Beispiel #17
0
func fillFunc(node *ast.FuncDecl, src string, fnct *Function) bool {
	if node.Name != nil {
		if !ast.IsExported(node.Name.Name) {
			return false
		}
		fnct.Name = node.Name.Name
	} else {
		return false
	}

	if node.Doc != nil {
		fnct.Doc = node.Doc.Text()
	}
	if node.Type != nil {
		if node.Type.Params != nil {
			fnct.Args = src[node.Type.Params.Pos() : node.Type.Params.End()-2]
		}
		if node.Type.Results != nil {
			fnct.Type = src[node.Type.Results.Pos()-1 : node.Type.Results.End()]
		}
	}

	if node.Recv != nil && len(node.Recv.List) > 0 {
		expr := node.Recv.List[0].Type
		recv := GetExprName(expr)
		if recv != "" {
			fnct.Recv = recv
		}
	}
	return true
}
Beispiel #18
0
func (v *ControllerVisitor) Visit(node ast.Node) ast.Visitor {
	if node == nil {
		return nil
	}

	switch x := node.(type) {
	case *ast.GenDecl:
		if x.Tok == token.IMPORT {
			for _, s := range x.Specs {
				if spec, ok := s.(*ast.ImportSpec); ok {
					p := spec.Path.Value
					v.imports[p[1:len(p)-1]] = true
				}
			}
			// I think this is ok... there's nothing deeper in an import than what we've already gotten, right?
			return nil
		}
	case *ast.FuncDecl:
		/*
			This assumes that a .controller file will export only functions we want to be actions...
			Maybe we should annotate actions somehow?
		*/
		if x.Type.Results.NumFields() != 0 {
			panic(fmt.Sprintf("Could not transform %s.%s: number of result fields is not 0.", v.controllerName, x.Name.Name))
		}
		if ast.IsExported(x.Name.Name) {
			transformAction(x)
			return &RenderFuncVisitor{}
		}
		return nil
	}

	return v
}
Beispiel #19
0
// lintUnexportedReturn examines exported function declarations.
// It complains if any return an unexported type.
func (f *file) lintUnexportedReturn() {
	f.walk(func(n ast.Node) bool {
		fn, ok := n.(*ast.FuncDecl)
		if !ok {
			return true
		}
		if fn.Type.Results == nil {
			return false
		}
		if !fn.Name.IsExported() {
			return false
		}
		thing := "func"
		if fn.Recv != nil && len(fn.Recv.List) > 0 {
			thing = "method"
			if !ast.IsExported(receiverType(fn)) {
				// Don't report exported methods of unexported types,
				// such as private implementations of sort.Interface.
				return false
			}
		}
		for _, ret := range fn.Type.Results.List {
			typ := f.pkg.typeOf(ret.Type)
			if exportedType(typ) {
				continue
			}
			f.errorf(ret.Type, 0.8, category("unexported-type-in-api"),
				"exported %s %s returns unexported type %s, which can be annoying to use",
				thing, fn.Name.Name, typ)
			break // only flag one
		}
		return false
	})
}
Beispiel #20
0
// Objects with names containing blanks are internal and not entered into
// a scope. Objects with exported names are inserted in the unsafe package
// scope; other objects are inserted in the universe scope.
//
func def(obj Object) {
	name := obj.Name()
	if strings.Index(name, " ") >= 0 {
		return // nothing to do
	}
	// fix Obj link for named types
	if typ, ok := obj.Type().(*Named); ok {
		typ.obj = obj.(*TypeName)
	}
	// exported identifiers go into package unsafe
	scope := Universe
	if ast.IsExported(name) {
		scope = Unsafe.scope
		// set Pkg field
		switch obj := obj.(type) {
		case *TypeName:
			obj.pkg = Unsafe
		case *Func:
			obj.pkg = Unsafe
		default:
			unreachable()
		}
	}
	if scope.Insert(obj) != nil {
		panic("internal error: double declaration")
	}
}
Beispiel #21
0
func (fi *funcInfo) writeStub(out io.Writer) {
	fmt.Fprintf(out, "func ")
	if fi.IsMethod() {
		fmt.Fprintf(out, "(%s %s) ", fi.recv.name, fi.recv.expr)
	}
	if ast.IsExported(fi.name) {
		fmt.Fprintf(out, "_real_")
	}
	fmt.Fprintf(out, "%s(", fi.name)
	for i, param := range fi.params {
		if i > 0 {
			fmt.Fprintf(out, ", ")
		}
		n := strings.Join(param.names, ", ")
		fmt.Fprintf(out, "%s %s", n, param.expr)
	}
	fmt.Fprintf(out, ") ")
	if len(fi.results) > 0 {
		fmt.Fprintf(out, "(")
		for i, result := range fi.results {
			if i > 0 {
				fmt.Fprintf(out, ", ")
			}
			n := strings.Join(result.names, ", ")
			fmt.Fprintf(out, "%s %s", n, result.expr)
		}
		fmt.Fprintf(out, ") ")
	}
	fmt.Fprintf(out, "{\n")
	fmt.Fprintf(out, "\tpanic(\"This is only a stub!\")\n")
	fmt.Fprintf(out, "}\n")
	fmt.Fprintf(out, "\n")
}
Beispiel #22
0
func addNodeLinks(nodes map[string]*Node, line string) []byte {
	var buf bytes.Buffer
	scan := bufio.NewScanner(strings.NewReader(line))
	scan.Split(bufio.ScanWords)
	for scan.Scan() {
		word := strings.TrimFunc(scan.Text(), unicode.IsPunct)
		parts := strings.Split(word, ".")
		node := word
		method := ""
		if len(parts) == 2 {
			node = parts[0]
			method = parts[1]
		}
		if nodes[node] != nil && ast.IsExported(node) {
			buf.Write([]byte("["))
			buf.Write(scan.Bytes())
			buf.Write([]byte("]("))
			if method == "" {
				buf.Write([]byte(nodeNameToLink(node)))
			} else {
				buf.Write([]byte(methodNameToLink(node, method)))
			}
			buf.Write([]byte(") "))
		} else {
			buf.Write(scan.Bytes())
			buf.Write([]byte(" "))
		}
	}
	return buf.Bytes()
}
Beispiel #23
0
func processFields(node *Node, s *ast.StructType) {
	for _, field := range s.Fields.List {
		if shouldIgnore(field.Doc) {
			continue
		}
		if field.Names == nil {
			//Anonymous field
			if i, ok := field.Type.(*ast.Ident); ok {
				parent := i.Name
				node.AnonFields = append(node.AnonFields, parent)
			} else if s, ok := field.Type.(*ast.StarExpr); ok {
				if i, ok := s.X.(*ast.Ident); ok {
					parent := i.Name
					node.AnonFields = append(node.AnonFields, parent)
				}
			}
		} else if len(field.Names) == 1 {
			name := field.Names[0].Name
			if !ast.IsExported(name) {
				continue
			}
			ptype := resolveTypeExpr(field.Type)
			node.Properties[name] = &Property{
				Name:   name,
				Doc:    field.Doc,
				Params: []Param{{"value", ptype}},
			}
		}
	}

}
Beispiel #24
0
func (fi *funcInfo) writeReal(out io.Writer) {
	if fi.export != "" {
		fmt.Fprintf(out, "//export %s\n", fi.export)
	}
	fmt.Fprintf(out, "func ")
	if fi.IsMethod() {
		fmt.Fprintf(out, "(%s %s) ", fi.recv.name, fi.recv.expr)
	}
	if ast.IsExported(fi.name) {
		fmt.Fprintf(out, "_real_")
	}
	fmt.Fprintf(out, "%s(", fi.name)
	for i, param := range fi.params {
		if i > 0 {
			fmt.Fprintf(out, ", ")
		}
		n := strings.Join(param.names, ", ")
		fmt.Fprintf(out, "%s %s", n, param.expr)
	}
	fmt.Fprintf(out, ") ")
	if len(fi.results) > 0 {
		fmt.Fprintf(out, "(")
		for i, result := range fi.results {
			if i > 0 {
				fmt.Fprintf(out, ", ")
			}
			n := strings.Join(result.names, ", ")
			fmt.Fprintf(out, "%s %s", n, result.expr)
		}
		fmt.Fprintf(out, ") ")
	}
	out.Write(fi.body)
	fmt.Fprintf(out, "\n")
}
Beispiel #25
0
func loadExportsGoPath(dir string) map[string]bool {
	exports := make(map[string]bool)
	buildPkg, err := build.ImportDir(dir, 0)
	if err != nil {
		if strings.Contains(err.Error(), "no buildable Go source files in") {
			return nil
		}
		fmt.Fprintf(os.Stderr, "could not import %q: %v", dir, err)
		return nil
	}
	fset := token.NewFileSet()
	for _, file := range buildPkg.GoFiles {
		f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0)
		if err != nil {
			fmt.Fprintf(os.Stderr, "could not parse %q: %v", file, err)
			continue
		}
		for name := range f.Scope.Objects {
			if ast.IsExported(name) {
				exports[name] = true
			}
		}
	}
	return exports
}
Beispiel #26
0
// qualifyPkgRefs qualifies all refs to non-package-qualified non-builtin types in f so that they refer to definitions in pkg. E.g., 'func(x MyType) -> func (x pkg.MyType)'.
func qualifyPkgRefs(f *ast.FuncType, pkg string) {
	var qualify func(x ast.Expr) ast.Expr
	qualify = func(x ast.Expr) ast.Expr {
		switch y := x.(type) {
		case *ast.Ident:
			if ast.IsExported(y.Name) {
				return &ast.SelectorExpr{X: ast.NewIdent(pkg), Sel: y}
			}
		case *ast.StarExpr:
			y.X = qualify(y.X)
		case *ast.ArrayType:
			y.Elt = qualify(y.Elt)
		case *ast.MapType:
			y.Key = qualify(y.Key)
			y.Value = qualify(y.Value)
		}
		return x
	}
	for _, p := range f.Params.List {
		p.Type = qualify(p.Type)
	}
	for _, r := range f.Results.List {
		r.Type = qualify(r.Type)
	}
}
Beispiel #27
0
func (f *File) methodSet(set *types.MethodSet) {
	// Build the set of things we're looking for.
	methods := make([]method, 0, set.Len())
	docs := make([]string, set.Len())
	for i := 0; i < set.Len(); i++ {
		if ast.IsExported(set.At(i).Obj().Name()) {
			m := method{
				i,
				set.At(i),
			}
			methods = append(methods, m)
		}
	}
	if len(methods) == 0 {
		return
	}
	// Collect the docs.
	for _, file := range f.allFiles {
		visitor := &methodVisitor{
			File:    file,
			methods: methods,
			docs:    docs,
		}
		ast.Walk(visitor, file.file)
		methods = visitor.methods
	}
	// Print them in order. The incoming method set is sorted by name.
	for _, doc := range docs {
		if doc != "" {
			fmt.Print(doc)
		}
	}
}
Beispiel #28
0
func marshal(buf []byte, prefix string, rv reflect.Value, inArray, arrayTable bool) ([]byte, error) {
	rt := rv.Type()
	for i := 0; i < rv.NumField(); i++ {
		ft := rt.Field(i)
		if !ast.IsExported(ft.Name) {
			continue
		}
		colName, rest := extractTag(rt.Field(i).Tag.Get(fieldTagName))
		if colName == tagSkip {
			continue
		}
		if colName == "" {
			colName = stringutil.ToSnakeCase(ft.Name)
		}
		fv := rv.Field(i)
		switch rest {
		case tagOmitempty:
			if fv.Interface() == reflect.Zero(ft.Type).Interface() {
				continue
			}
		}
		var err error
		if buf, err = encodeValue(buf, prefix, colName, fv, inArray, arrayTable); err != nil {
			return nil, err
		}
	}
	return buf, nil
}
func (c *auto_complete_context) get_candidates_from_decl(cc cursor_context, class decl_class, b *out_buffers) {
	// propose all children of a subject declaration and
	for _, decl := range cc.decl.children {
		if cc.decl.class == decl_package && !ast.IsExported(decl.name) {
			continue
		}
		if cc.struct_field {
			// if we're autocompleting struct field init, skip all methods
			if _, ok := decl.typ.(*ast.FuncType); ok {
				continue
			}
		}
		b.append_decl(cc.partial, decl.name, decl, class)
	}
	// propose all children of an underlying struct/interface type
	adecl := advance_to_struct_or_interface(cc.decl)
	if adecl != nil && adecl != cc.decl {
		for _, decl := range adecl.children {
			if decl.class == decl_var {
				b.append_decl(cc.partial, decl.name, decl, class)
			}
		}
	}
	// propose all children of its embedded types
	b.append_embedded(cc.partial, cc.decl, class)
}
Beispiel #30
0
func (p *Package) FilterCommon(typs ...DocType) ([]string, map[string]interface{}) {
	var ctxsize int
	if p.defctx {
		ctxsize = 1
	} else {
		ctxsize = len(p.contexts)
	}

	var key []string
	cm := make(map[string]interface{})
	def := contextName(&build.Default)
	for _, typ := range typs {
		if m, ok := p.keys[typ]; ok {
			for k, v := range m {
				if len(v) == ctxsize && (ast.IsExported(k) || typ == Struct) {
					key = append(key, k)
					cm[k] = v[def]
				}
			}
			sort.Strings(key)
		}
	}

	return key, cm
}