Example #1
0
func objectKind(obj types.Object) string {
	switch obj := obj.(type) {
	case *types.PkgName:
		return "imported package name"
	case *types.TypeName:
		return "type"
	case *types.Var:
		if obj.IsField() {
			return "field"
		}
	case *types.Func:
		if obj.Type().(*types.Signature).Recv() != nil {
			return "method"
		}
	}
	// label, func, var, const
	return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types."))
}
Example #2
0
func defKind(obj types.Object) string {
	switch obj := obj.(type) {
	case *types.PkgName:
		return definfo.Package
	case *types.Const:
		return definfo.Const
	case *types.TypeName:
		return definfo.Type
	case *types.Var:
		if obj.IsField() {
			return definfo.Field
		}
		return definfo.Var
	case *types.Func:
		sig := obj.Type().(*types.Signature)
		if sig.Recv() == nil {
			return definfo.Func
		} else {
			return definfo.Method
		}
	default:
		panic(fmt.Sprintf("unhandled obj type %T", obj))
	}
}
Example #3
0
// NewDef creates a new Def.
func (g *Grapher) NewDef(obj types.Object, declIdent *ast.Ident) (*Def, error) {
	// Find the AST node that declares this def.
	var declNode ast.Node
	_, astPath, _ := g.program.PathEnclosingInterval(declIdent.Pos(), declIdent.End())
	for _, node := range astPath {
		switch node.(type) {
		case *ast.FuncDecl, *ast.GenDecl, *ast.ValueSpec, *ast.TypeSpec, *ast.Field, *ast.DeclStmt, *ast.AssignStmt:
			declNode = node
			goto found
		}
	}
found:
	if declNode == nil {
		return nil, fmt.Errorf("On ident %s at %s: no DeclNode found (using PathEnclosingInterval)", declIdent.Name, g.program.Fset.Position(declIdent.Pos()))
	}

	key, info, err := g.defInfo(obj)
	if err != nil {
		return nil, err
	}

	si := definfo.DefInfo{
		Exported: info.exported,
		PkgScope: info.pkgscope,
		PkgName:  obj.Pkg().Name(),
		Kind:     defKind(obj),
	}

	if typ := obj.Type(); typ != nil {
		si.TypeString = typ.String()
		if utyp := typ.Underlying(); utyp != nil {
			si.UnderlyingTypeString = utyp.String()
		}
	}

	switch obj := obj.(type) {
	case *types.Var:
		if obj.IsField() {
			if fieldStruct, ok := g.structFields[obj]; ok {
				if struct_, ok := fieldStruct.parent.(*types.Named); ok {
					si.FieldOfStruct = struct_.Obj().Name()
				}
			}
		}
	case *types.Func:
		sig := obj.Type().(*types.Signature)
		if recv := sig.Recv(); recv != nil && recv.Type() != nil {
			// omit package path; just get receiver type name
			si.Receiver = strings.Replace(recv.Type().String(), obj.Pkg().Path()+".", "", 1)
		}
	}

	return &Def{
		Name: obj.Name(),

		DefKey: key,

		File:      g.program.Fset.Position(declIdent.Pos()).Filename,
		IdentSpan: makeSpan(g.program.Fset, declIdent),
		DeclSpan:  makeSpan(g.program.Fset, declNode),

		DefInfo: si,
	}, nil
}