• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang ast.Object类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中go/ast.Object的典型用法代码示例。如果您正苦于以下问题:Golang Object类的具体用法?Golang Object怎么用?Golang Object使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



在下文中一共展示了Object类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。

示例1: resolve

func (tc *typechecker) resolve(obj *ast.Object) {
	// check for declaration cycles
	if tc.cyclemap[obj] {
		tc.Errorf(objPos(obj), "illegal cycle in declaration of %s", obj.Name)
		obj.Kind = ast.Bad
		return
	}
	tc.cyclemap[obj] = true
	defer func() {
		tc.cyclemap[obj] = false, false
	}()

	// resolve non-type objects
	typ := obj.Type
	if typ == nil {
		switch obj.Kind {
		case ast.Bad:
			// ignore

		case ast.Con:
			tc.declConst(obj)

		case ast.Var:
			tc.declVar(obj)
			//obj.Type = tc.typeFor(nil, obj.Decl.(*ast.ValueSpec).Type, false)

		case ast.Fun:
			obj.Type = ast.NewType(ast.Function)
			t := obj.Decl.(*ast.FuncDecl).Type
			tc.declSignature(obj.Type, nil, t.Params, t.Results)

		default:
			// type objects have non-nil types when resolve is called
			if debug {
				fmt.Printf("kind = %s\n", obj.Kind)
			}
			panic("unreachable")
		}
		return
	}

	// resolve type objects
	if typ.Form == ast.Unresolved {
		tc.typeFor(typ, typ.Obj.Decl.(*ast.TypeSpec).Type, false)

		// provide types for all methods
		for _, obj := range typ.Scope.Objects {
			if obj.Kind == ast.Fun {
				assert(obj.Type == nil)
				obj.Type = ast.NewType(ast.Method)
				f := obj.Decl.(*ast.FuncDecl)
				t := f.Type
				tc.declSignature(obj.Type, f.Recv, t.Params, t.Results)
			}
		}
	}
}
开发者ID:GNA-SERVICES-INC,项目名称:MoNGate,代码行数:57,代码来源:typechecker.go


示例2: objDoc

func objDoc(fset *token.FileSet, pkg *ast.Package, tabIndent bool, tabWidth int, obj *ast.Object) *Doc {
	decl := obj.Decl
	kind := obj.Kind.String()
	tp := fset.Position(obj.Pos())
	objSrc := ""
	pkgName := ""
	if pkg != nil && pkg.Name != "builtin" {
		pkgName = pkg.Name
	}

	if obj.Kind == ast.Pkg {
		pkgName = ""
		doc := ""
		// special-case `package name` is generated as a TypeSpec
		if v, ok := obj.Decl.(*ast.TypeSpec); ok && v.Doc != nil {
			doc = "/*\n" + v.Doc.Text() + "\n*/\n"
		}
		objSrc = doc + "package " + obj.Name
	} else if af, ok := pkg.Files[tp.Filename]; ok {
		switch decl.(type) {
		case *ast.TypeSpec, *ast.ValueSpec, *ast.Field:
			line := tp.Line - 1
			for _, cg := range af.Comments {
				cgp := fset.Position(cg.End())
				if cgp.Filename == tp.Filename && cgp.Line == line {
					switch v := decl.(type) {
					case *ast.TypeSpec:
						v.Doc = cg
					case *ast.ValueSpec:
						v.Doc = cg
					case *ast.Field:
						pkgName = ""
						kind = "field"
					}
					break
				}
			}
		}
	}

	if objSrc == "" {
		objSrc, _ = printSrc(fset, decl, tabIndent, tabWidth)
	}

	return &Doc{
		Src:  objSrc,
		Pkg:  pkgName,
		Name: obj.Name,
		Kind: kind,
		Fn:   tp.Filename,
		Row:  tp.Line - 1,
		Col:  tp.Column - 1,
	}
}
开发者ID:hardPass,项目名称:MarGo,代码行数:54,代码来源:ac_doc.go


示例3: checkObj

// checkObj type checks an object.
func (c *checker) checkObj(obj *ast.Object, ref bool) {
	if obj.Type != nil {
		// object has already been type checked
		return
	}

	switch obj.Kind {
	case ast.Bad:
		// ignore

	case ast.Con:
		// TODO(gri) complete this

	case ast.Typ:
		typ := &Name{Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = Underlying(c.makeType(obj.Decl.(*ast.TypeSpec).Type, ref))

	case ast.Var:
		// TODO(gri) complete this

	case ast.Fun:
		// TODO(gri) complete this

	default:
		panic("unreachable")
	}
}
开发者ID:anuvazhayil,项目名称:HelloWorld_32bitOS,代码行数:29,代码来源:check.go


示例4: valueSpec

func (check *checker) valueSpec(pos token.Pos, obj *ast.Object, lhs []*ast.Ident, typ ast.Expr, rhs []ast.Expr, iota int) {
	if len(lhs) == 0 {
		check.invalidAST(pos, "missing lhs in declaration")
		return
	}

	// determine type for all of lhs, if any
	// (but only set it for the object we typecheck!)
	var t Type
	if typ != nil {
		t = check.typ(typ, false)
	}

	// len(lhs) > 0
	if len(lhs) == len(rhs) {
		// check only lhs and rhs corresponding to obj
		var l, r ast.Expr
		for i, name := range lhs {
			if name.Obj == obj {
				l = lhs[i]
				r = rhs[i]
				break
			}
		}
		assert(l != nil)
		obj.Type = t
		check.assign1to1(l, r, nil, true, iota)
		return
	}

	// there must be a type or initialization expressions
	if t == nil && len(rhs) == 0 {
		check.invalidAST(pos, "missing type or initialization expression")
		t = Typ[Invalid]
	}

	// if we have a type, mark all of lhs
	if t != nil {
		for _, name := range lhs {
			name.Obj.Type = t
		}
	}

	// check initial values, if any
	if len(rhs) > 0 {
		// TODO(gri) should try to avoid this conversion
		lhx := make([]ast.Expr, len(lhs))
		for i, e := range lhs {
			lhx[i] = e
		}
		check.assignNtoM(lhx, rhs, true, iota)
	}
}
开发者ID:timnau,项目名称:golang,代码行数:53,代码来源:check.go


示例5: collectParams

func (check *checker) collectParams(list *ast.FieldList, variadicOk bool) (params ObjList, isVariadic bool) {
	if list == nil {
		return
	}
	var last *ast.Object
	for i, field := range list.List {
		ftype := field.Type
		if t, _ := ftype.(*ast.Ellipsis); t != nil {
			ftype = t.Elt
			if variadicOk && i == len(list.List)-1 {
				isVariadic = true
			} else {
				check.invalidAST(field.Pos(), "... not permitted")
				// ok to continue
			}
		}
		// the parser ensures that f.Tag is nil and we don't
		// care if a constructed AST contains a non-nil tag
		typ := check.typ(ftype, true)
		if len(field.Names) > 0 {
			// named parameter
			for _, name := range field.Names {
				obj := name.Obj
				obj.Type = typ
				params = append(params, obj)
				last = obj
			}
		} else {
			// anonymous parameter
			obj := ast.NewObj(ast.Var, "")
			obj.Type = typ
			params = append(params, obj)
			last = obj
		}
	}
	// For a variadic function, change the last parameter's object type
	// from T to []T (this is the type used inside the function), but
	// keep a copy of the object with the original type T in the params
	// list (this is the externally visible type).
	if isVariadic {
		// if isVariadic is set, last must exist and len(params) > 0
		copy := *last
		last.Type = &Slice{Elt: last.Type.(Type)}
		params[len(params)-1] = &copy
	}
	return
}
开发者ID:redcatmiss,项目名称:gcc,代码行数:47,代码来源:expr.go


示例6: assocMethod

// assocMethod associates a method declaration with the respective
// receiver base type. meth.Recv must exist.
//
func (check *checker) assocMethod(meth *ast.FuncDecl) {
	// The receiver type is one of the following (enforced by parser):
	// - *ast.Ident
	// - *ast.StarExpr{*ast.Ident}
	// - *ast.BadExpr (parser error)
	typ := meth.Recv.List[0].Type
	if ptr, ok := typ.(*ast.StarExpr); ok {
		typ = ptr.X
	}
	// determine receiver base type object (or nil if error)
	var obj *ast.Object
	if ident, ok := typ.(*ast.Ident); ok && ident.Obj != nil {
		obj = ident.Obj
		if obj.Kind != ast.Typ {
			check.errorf(ident.Pos(), "%s is not a type", ident.Name)
			obj = nil
		}
		// TODO(gri) determine if obj was defined in this package
		/*
			if check.notLocal(obj) {
				check.errorf(ident.Pos(), "cannot define methods on non-local type %s", ident.Name)
				obj = nil
			}
		*/
	} else {
		// If it's not an identifier or the identifier wasn't declared/resolved,
		// the parser/resolver already reported an error. Nothing to do here.
	}
	// determine base type scope (or nil if error)
	var scope *ast.Scope
	if obj != nil {
		if obj.Data != nil {
			scope = obj.Data.(*ast.Scope)
		} else {
			scope = ast.NewScope(nil)
			obj.Data = scope
		}
	} else {
		// use a dummy scope so that meth can be declared in
		// presence of an error and get an associated object
		// (always use a new scope so that we don't get double
		// declaration errors)
		scope = ast.NewScope(nil)
	}
	check.declare(scope, ast.Fun, meth.Name, meth)
}
开发者ID:mm120,项目名称:gcc,代码行数:49,代码来源:check.go


示例7: checkObj

// checkObj type checks an object.
func (c *checker) checkObj(obj *ast.Object, ref bool) {
	if obj.Type != nil {
		// object has already been type checked
		return
	}

	switch obj.Kind {
	case ast.Bad:
		// ignore

	case ast.Con:
		// TODO(gri) complete this

	case ast.Typ:
		typ := &Name{Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = Underlying(c.makeType(obj.Decl.(*ast.TypeSpec).Type, ref))

	case ast.Var:
		// TODO(gri) complete this

	case ast.Fun:
		fdecl := obj.Decl.(*ast.FuncDecl)
		ftyp := c.makeType(fdecl.Type, ref).(*Func)
		obj.Type = ftyp
		if fdecl.Recv != nil {
			recvField := fdecl.Recv.List[0]
			if len(recvField.Names) > 0 {
				ftyp.Recv = recvField.Names[0].Obj
			} else {
				ftyp.Recv = ast.NewObj(ast.Var, "_")
				ftyp.Recv.Decl = recvField
			}
			c.checkObj(ftyp.Recv, ref)
			// TODO(axw) add method to a list in the receiver type.
		}
		// TODO(axw) check function body, if non-nil.

	default:
		panic("unreachable")
	}
}
开发者ID:stevenxiao215,项目名称:go,代码行数:43,代码来源:check.go


示例8: assocMethod

// assocMethod associates a method declaration with the respective
// receiver base type. meth.Recv must exist.
//
func (check *checker) assocMethod(meth *ast.FuncDecl) {
	// The receiver type is one of the following (enforced by parser):
	// - *ast.Ident
	// - *ast.StarExpr{*ast.Ident}
	// - *ast.BadExpr (parser error)
	typ := meth.Recv.List[0].Type
	if ptr, ok := typ.(*ast.StarExpr); ok {
		typ = ptr.X
	}
	// determine receiver base type object
	var obj *ast.Object
	if ident, ok := typ.(*ast.Ident); ok && ident.Obj != nil {
		obj = ident.Obj
		if obj.Kind != ast.Typ {
			check.errorf(ident.Pos(), "%s is not a type", ident.Name)
			return // ignore this method
		}
		// TODO(gri) determine if obj was defined in this package
		/*
			if check.notLocal(obj) {
				check.errorf(ident.Pos(), "cannot define methods on non-local type %s", ident.Name)
				return // ignore this method
			}
		*/
	} else {
		// If it's not an identifier or the identifier wasn't declared/resolved,
		// the parser/resolver already reported an error. Nothing to do here.
		return // ignore this method
	}
	// declare method in receiver base type scope
	var scope *ast.Scope
	if obj.Data != nil {
		scope = obj.Data.(*ast.Scope)
	} else {
		scope = ast.NewScope(nil)
		obj.Data = scope
	}
	check.declare(scope, ast.Fun, meth.Name, meth)
}
开发者ID:timnau,项目名称:golang,代码行数:42,代码来源:check.go


示例9: valueSpec

func (check *checker) valueSpec(pos token.Pos, obj *ast.Object, lhs []*ast.Ident, typ ast.Expr, rhs []ast.Expr, iota int) {
	if len(lhs) == 0 {
		check.invalidAST(pos, "missing lhs in declaration")
		return
	}

	var t Type
	if typ != nil {
		t = check.typ(typ, false)
	}

	// len(lhs) >= 1
	if len(lhs) == len(rhs) {
		// check only corresponding lhs and rhs
		var l, r ast.Expr
		for i, ident := range lhs {
			if ident.Obj == obj {
				l = lhs[i]
				r = rhs[i]
				break
			}
		}
		assert(l != nil)
		obj.Type = t
		// check rhs
		var x operand
		check.expr(&x, r, t, iota)
		// assign to lhs
		check.assignment(l, &x, true)
		return
	}

	if t != nil {
		for _, name := range lhs {
			name.Obj.Type = t
		}
	}

	// check initial values, if any
	if len(rhs) > 0 {
		// TODO(gri) should try to avoid this conversion
		lhx := make([]ast.Expr, len(lhs))
		for i, e := range lhs {
			lhx[i] = e
		}
		check.assignNtoM(lhx, rhs, true, iota)
	}
}
开发者ID:hfeeki,项目名称:go,代码行数:48,代码来源:check.go


示例10: maybeConvertUntyped

// convertUntyped takes an object, and, if it is untyped, gives it
// a named builtin type: bool, rune, int, float64, complex128 or string.
func maybeConvertUntyped(obj *ast.Object) bool {
	switch obj.Type {
	case Bool.Underlying:
		obj.Type = Bool
	case Rune.Underlying:
		obj.Type = Rune
	case Int.Underlying:
		obj.Type = Int
	case Float64.Underlying:
		obj.Type = Float64
	case Complex128.Underlying:
		obj.Type = Complex128
	case String.Underlying:
		obj.Type = String
	default:
		return false
	}
	return true
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:21,代码来源:check.go


示例11: obj

// obj type checks an object.
func (check *checker) obj(obj *ast.Object, cycleOk bool) {
	if trace {
		fmt.Printf("obj(%s)\n", obj.Name)
	}

	if obj.Type != nil {
		// object has already been type checked
		return
	}

	switch obj.Kind {
	case ast.Bad, ast.Pkg:
		// nothing to do

	case ast.Con:
		if obj.Data == nil {
			check.errorf(obj.Pos(), "illegal cycle in initialization of %s", obj.Name)
			return
		}
		spec, ok := obj.Decl.(*ast.ValueSpec)
		assert(ok)
		// The Data stored with the constant is the value of iota for that
		// ast.ValueSpec. Use it for the evaluation of the initialization
		// expressions.
		iota := obj.Data.(int)
		obj.Data = nil
		check.decl(spec.Pos(), obj, spec.Names, spec.Type, check.specValues(spec), iota)

	case ast.Var:
		// TODO(gri) missing cycle detection
		spec, ok := obj.Decl.(*ast.ValueSpec)
		if !ok {
			// TODO(gri) the assertion fails for "x, y := 1, 2, 3" it seems
			fmt.Printf("var = %s\n", obj.Name)
		}
		assert(ok)
		check.decl(spec.Pos(), obj, spec.Names, spec.Type, spec.Values, 0)

	case ast.Typ:
		typ := &NamedType{Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = underlying(check.typ(obj.Decl.(*ast.TypeSpec).Type, cycleOk))
		// collect associated methods, if any
		if obj.Data != nil {
			scope := obj.Data.(*ast.Scope)
			// struct fields must not conflict with methods
			if t, ok := typ.Underlying.(*Struct); ok {
				for _, f := range t.Fields {
					if m := scope.Lookup(f.Name); m != nil {
						check.errorf(m.Pos(), "type %s has both field and method named %s", obj.Name, f.Name)
					}
				}
			}
			// collect methods
			methods := make(ObjList, len(scope.Objects))
			i := 0
			for _, m := range scope.Objects {
				methods[i] = m
				i++
			}
			methods.Sort()
			typ.Methods = methods
			// methods cannot be associated with an interface type
			// (do this check after sorting for reproducible error positions - needed for testing)
			if _, ok := typ.Underlying.(*Interface); ok {
				for _, m := range methods {
					recv := m.Decl.(*ast.FuncDecl).Recv.List[0].Type
					check.errorf(recv.Pos(), "invalid receiver type %s (%s is an interface type)", obj.Name, obj.Name)
				}
			}
		}

	case ast.Fun:
		fdecl := obj.Decl.(*ast.FuncDecl)
		ftyp := check.typ(fdecl.Type, cycleOk).(*Signature)
		obj.Type = ftyp
		if fdecl.Recv != nil {
			// TODO(gri) handle method receiver
		}
		check.stmt(fdecl.Body)

	default:
		panic("unreachable")
	}
}
开发者ID:dersebi,项目名称:golang_exp,代码行数:86,代码来源:check.go


示例12: VisitValueSpec

func (c *compiler) VisitValueSpec(valspec *ast.ValueSpec, isconst bool) {
	// Check if the value-spec has already been visited (referenced
	// before definition visited.)
	if len(valspec.Names) > 0 {
		if _, ok := valspec.Names[0].Obj.Data.(Value); ok {
			return
		}
	}

	var iotaObj *ast.Object = types.Universe.Lookup("iota")
	defer func(data interface{}) {
		iotaObj.Data = data
	}(iotaObj.Data)

	pkgname, ispackagelevel := c.pkgmap[valspec.Names[0].Obj]
	if ispackagelevel && !isconst {
		c.createGlobals(valspec.Names, valspec.Values, pkgname)
		return
	}

	var values []Value
	if len(valspec.Values) == 1 && len(valspec.Names) > 1 {
		values = c.destructureExpr(valspec.Values[0])
	} else if len(valspec.Values) > 0 {
		values = make([]Value, len(valspec.Names))
		for i, name_ := range valspec.Names {
			if isconst {
				if iota_, isint := (name_.Obj.Data).(int); isint {
					iotaValue := c.NewConstValue(token.INT, strconv.Itoa(iota_))
					iotaObj.Data = iotaValue
				}
			}
			values[i] = c.VisitExpr(valspec.Values[i])
		}
	}

	for i, name := range valspec.Names {
		if name.Name == "_" {
			continue
		}

		// For constants, we just pass the ConstValue around. Otherwise, we
		// will convert it to an LLVMValue.
		var value Value
		if isconst {
			value = values[i].Convert(name.Obj.Type.(types.Type))
		} else {
			// The variable should be allocated on the stack if it's
			// declared inside a function.
			var llvmInit llvm.Value
			typ := name.Obj.Type.(types.Type)
			ptr := c.builder.CreateAlloca(c.types.ToLLVM(typ), name.Name)
			if values == nil || values[i] == nil {
				// If no initialiser was specified, set it to the
				// zero value.
				llvmInit = llvm.ConstNull(c.types.ToLLVM(typ))
			} else {
				llvmInit = values[i].Convert(typ).LLVMValue()
			}
			c.builder.CreateStore(llvmInit, ptr)
			value = c.NewLLVMValue(ptr, &types.Pointer{Base: typ}).makePointee()
		}
		name.Obj.Data = value
	}
}
开发者ID:kisielk,项目名称:llgo,代码行数:65,代码来源:decl.go


示例13: check

func check(fset *token.FileSet, pkg *ast.Package, types map[ast.Expr]Type) error {
	var check checker
	check.fset = fset
	check.pkg = pkg
	check.types = types

	// Compute sorted list of file names so that
	// package file iterations are reproducible (needed for testing).
	filenames := make([]string, len(pkg.Files))
	{
		i := 0
		for filename := range pkg.Files {
			filenames[i] = filename
			i++
		}
		sort.Strings(filenames)
	}

	// Associate methods with types
	// TODO(gri) All other objects are resolved by the parser.
	//           Consider doing this in the parser (and provide the info
	//           in the AST. In the long-term (might require Go 1 API
	//           changes) it's probably easier to do all the resolution
	//           in one place in the type checker. See also comment
	//           with checker.declare.
	for _, filename := range filenames {
		file := pkg.Files[filename]
		for _, decl := range file.Decls {
			if meth, ok := decl.(*ast.FuncDecl); ok && meth.Recv != nil {
				// The receiver type is one of the following (enforced by parser):
				// - *ast.Ident
				// - *ast.StarExpr{*ast.Ident}
				// - *ast.BadExpr (parser error)
				typ := meth.Recv.List[0].Type
				if ptr, ok := typ.(*ast.StarExpr); ok {
					typ = ptr.X
				}
				// determine receiver base type object (or nil if error)
				var obj *ast.Object
				if ident, ok := typ.(*ast.Ident); ok && ident.Obj != nil {
					obj = ident.Obj
					if obj.Kind != ast.Typ {
						check.errorf(ident.Pos(), "%s is not a type", ident.Name)
						obj = nil
					}
					// TODO(gri) determine if obj was defined in this package
					/*
						if check.notLocal(obj) {
							check.errorf(ident.Pos(), "cannot define methods on non-local type %s", ident.Name)
							obj = nil
						}
					*/
				} else {
					// If it's not an identifier or the identifier wasn't declared/resolved,
					// the parser/resolver already reported an error. Nothing to do here.
				}
				// determine base type scope (or nil if error)
				var scope *ast.Scope
				if obj != nil {
					if obj.Data != nil {
						scope = obj.Data.(*ast.Scope)
					} else {
						scope = ast.NewScope(nil)
						obj.Data = scope
					}
				} else {
					// use a dummy scope so that meth can be declared in
					// presence of an error and get an associated object
					// (always use a new scope so that we don't get double
					// declaration errors)
					scope = ast.NewScope(nil)
				}
				check.declare(scope, ast.Fun, meth.Name, meth)
			}
		}
	}

	// Sort objects so that we get reproducible error
	// positions (this is only needed for testing).
	// TODO(gri): Consider ast.Scope implementation that
	// provides both a list and a map for fast lookup.
	// Would permit the use of scopes instead of ObjMaps
	// elsewhere.
	list := make(ObjList, len(pkg.Scope.Objects))
	{
		i := 0
		for _, obj := range pkg.Scope.Objects {
			list[i] = obj
			i++
		}
		list.Sort()
	}

	// Check global objects.
	for _, obj := range list {
		check.obj(obj, false)
	}

	// TODO(gri) Missing pieces:
	// - blank (_) objects and init functions are not in scopes but should be type-checked
//.........这里部分代码省略.........
开发者ID:dersebi,项目名称:golang_exp,代码行数:101,代码来源:check.go


示例14: object

// object typechecks an object by assigning it a type; obj.Type must be nil.
// Callers must check obj.Type before calling object; this eliminates a call
// for each identifier that has been typechecked already, a common scenario.
//
func (check *checker) object(obj *ast.Object, cycleOk bool) {
	assert(obj.Type == nil)

	switch obj.Kind {
	case ast.Bad, ast.Pkg:
		// nothing to do

	case ast.Con, ast.Var:
		// The obj.Data field for constants and variables is initialized
		// to the respective (hypothetical, for variables) iota value by
		// the parser. The object's fields can be in one of the following
		// states:
		// Type != nil  =>  the constant value is Data
		// Type == nil  =>  the object is not typechecked yet, and Data can be:
		// Data is int  =>  Data is the value of iota for this declaration
		// Data == nil  =>  the object's expression is being evaluated
		if obj.Data == nil {
			check.errorf(obj.Pos(), "illegal cycle in initialization of %s", obj.Name)
			obj.Type = Typ[Invalid]
			return
		}
		spec := obj.Decl.(*ast.ValueSpec)
		iota := obj.Data.(int)
		obj.Data = nil
		// determine initialization expressions
		values := spec.Values
		if len(values) == 0 && obj.Kind == ast.Con {
			values = check.initexprs[spec]
		}
		check.valueSpec(spec.Pos(), obj, spec.Names, spec.Type, values, iota)

	case ast.Typ:
		typ := &NamedType{Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = underlying(check.typ(obj.Decl.(*ast.TypeSpec).Type, cycleOk))
		// typecheck associated method signatures
		if obj.Data != nil {
			scope := obj.Data.(*ast.Scope)
			switch t := typ.Underlying.(type) {
			case *Struct:
				// struct fields must not conflict with methods
				for _, f := range t.Fields {
					if m := scope.Lookup(f.Name); m != nil {
						check.errorf(m.Pos(), "type %s has both field and method named %s", obj.Name, f.Name)
						// ok to continue
					}
				}
			case *Interface:
				// methods cannot be associated with an interface type
				for _, m := range scope.Objects {
					recv := m.Decl.(*ast.FuncDecl).Recv.List[0].Type
					check.errorf(recv.Pos(), "invalid receiver type %s (%s is an interface type)", obj.Name, obj.Name)
					// ok to continue
				}
			}
			// typecheck method signatures
			for _, obj := range scope.Objects {
				mdecl := obj.Decl.(*ast.FuncDecl)
				sig := check.typ(mdecl.Type, cycleOk).(*Signature)
				params, _ := check.collectParams(mdecl.Recv, false)
				sig.Recv = params[0] // the parser/assocMethod ensure there is exactly one parameter
				obj.Type = sig
				check.later(obj, sig, mdecl.Body)
			}
		}

	case ast.Fun:
		fdecl := obj.Decl.(*ast.FuncDecl)
		// methods are typechecked when their receivers are typechecked
		if fdecl.Recv == nil {
			sig := check.typ(fdecl.Type, cycleOk).(*Signature)
			if obj.Name == "init" && (len(sig.Params) != 0 || len(sig.Results) != 0) {
				check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
				// ok to continue
			}
			obj.Type = sig
			check.later(obj, sig, fdecl.Body)
		}

	default:
		panic("unreachable")
	}
}
开发者ID:timnau,项目名称:golang,代码行数:87,代码来源:check.go


示例15: Resolve

func (c *compiler) Resolve(obj *ast.Object) Value {
	if obj.Kind == ast.Pkg {
		return nil
	} else if obj.Kind == ast.Typ {
		return TypeValue{obj.Type.(types.Type)}
	}

	value, isvalue := (obj.Data).(Value)
	if isvalue {
		return value
	}

	switch obj.Kind {
	case ast.Con:
		if obj.Decl != nil {
			valspec := obj.Decl.(*ast.ValueSpec)
			c.VisitValueSpec(valspec, true)
			value = (obj.Data).(Value)
		} else if obj == types.Nil {
			return NilValue{c}
		} else {
			var typ types.Type
			switch x := obj.Type.(type) {
			case *types.Basic:
				typ = x
			case *types.Name:
				typ = x.Underlying.(*types.Basic)
			default:
				panic(fmt.Sprintf("unreachable (%T)", x))
			}
			value = ConstValue{(obj.Data.(types.Const)), c, typ}
			obj.Data = value
		}

	case ast.Fun:
		var funcdecl *ast.FuncDecl
		if obj.Decl != nil {
			funcdecl = obj.Decl.(*ast.FuncDecl)
		} else {
			funcdecl = &ast.FuncDecl{
				Name: &ast.Ident{Name: obj.Name, Obj: obj},
			}
		}
		value = c.VisitFuncProtoDecl(funcdecl)
		obj.Data = value

	case ast.Var:
		switch x := (obj.Decl).(type) {
		case *ast.ValueSpec:
			c.VisitValueSpec(x, false)
		case *ast.Field:
			// No-op. Fields will be yielded for function
			// arg/recv/ret. We update the .Data field of the
			// object when we enter the function definition.
			if obj.Data == nil {
				panic("expected obj.Data value")
			}
		}

		// If it's an external variable, we'll need to create a global
		// value reference here.
		if obj.Data == nil {
			module := c.module.Module
			t := obj.Type.(types.Type)
			name := c.pkgmap[obj] + "." + obj.Name
			g := llvm.AddGlobal(module, c.types.ToLLVM(t), name)
			g.SetLinkage(llvm.AvailableExternallyLinkage)
			obj.Data = c.NewLLVMValue(g, t)
		}

		value = (obj.Data).(Value)
	}

	return value
}
开发者ID:c0der007,项目名称:llgo,代码行数:75,代码来源:compiler.go


示例16: Resolve

func (c *compiler) Resolve(obj *ast.Object) Value {
	if obj.Kind == ast.Pkg {
		return nil
	} else if obj.Kind == ast.Typ {
		return TypeValue{obj.Type.(types.Type)}
	}

	value, isvalue := (obj.Data).(Value)
	if isvalue {
		return value
	}

	switch obj.Kind {
	case ast.Con:
		if obj.Decl != nil {
			valspec := obj.Decl.(*ast.ValueSpec)
			c.VisitValueSpec(valspec, true)
			value = (obj.Data).(Value)
		} else if obj == types.Nil {
			return NilValue{c}
		} else {
			typ := obj.Type.(types.Type)
			value = ConstValue{(obj.Data.(types.Const)), c, typ}
			obj.Data = value
		}

	case ast.Fun:
		var funcdecl *ast.FuncDecl
		if obj.Decl != nil {
			funcdecl = obj.Decl.(*ast.FuncDecl)
		} else {
			funcdecl = &ast.FuncDecl{
				Name: &ast.Ident{Name: obj.Name, Obj: obj},
			}
		}
		value = c.VisitFuncProtoDecl(funcdecl)
		obj.Data = value

	case ast.Var:
		switch x := (obj.Decl).(type) {
		case *ast.ValueSpec:
			c.VisitValueSpec(x, false)
		case *ast.Field:
			// No-op. Fields will be yielded for function
			// arg/recv/ret. We update the .Data field of the
			// object when we enter the function definition.
			if obj.Data == nil {
				panic("expected obj.Data value")
			}
		}

		// If it's an external variable, we'll need to create a global
		// value reference here. It may be possible for multiple objects
		// to refer to the same variable.
		if obj.Data == nil {
			module := c.module.Module
			t := obj.Type.(types.Type)
			name := c.pkgmap[obj] + "." + obj.Name
			g := module.NamedGlobal(name)
			if g.IsNil() {
				g = llvm.AddGlobal(module, c.types.ToLLVM(t), name)
			}
			obj.Data = c.NewLLVMValue(g, &types.Pointer{Base: t}).makePointee()
		}

		value = (obj.Data).(Value)
	}

	return value
}
开发者ID:dtcaciuc,项目名称:llgo,代码行数:70,代码来源:compiler.go


示例17: object

// object typechecks an object by assigning it a type; obj.Type must be nil.
// Callers must check obj.Type before calling object; this eliminates a call
// for each identifier that has been typechecked already, a common scenario.
//
func (check *checker) object(obj *ast.Object, cycleOk bool) {
	assert(obj.Type == nil)

	switch obj.Kind {
	case ast.Bad, ast.Pkg:
		// nothing to do

	case ast.Con, ast.Var:
		// The obj.Data field for constants and variables is initialized
		// to the respective (hypothetical, for variables) iota value by
		// the parser. The object's fields can be in one of the following
		// states:
		// Type != nil  =>  the constant value is Data
		// Type == nil  =>  the object is not typechecked yet, and Data can be:
		// Data is int  =>  Data is the value of iota for this declaration
		// Data == nil  =>  the object's expression is being evaluated
		if obj.Data == nil {
			check.errorf(obj.Pos(), "illegal cycle in initialization of %s", obj.Name)
			obj.Type = Typ[Invalid]
			return
		}
		spec := obj.Decl.(*ast.ValueSpec)
		iota := obj.Data.(int)
		obj.Data = nil
		// determine initialization expressions
		values := spec.Values
		if len(values) == 0 && obj.Kind == ast.Con {
			values = check.initexprs[spec]
		}
		check.valueSpec(spec.Pos(), obj, spec.Names, spec.Type, values, iota)

	case ast.Typ:
		typ := &NamedType{Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = underlying(check.typ(obj.Decl.(*ast.TypeSpec).Type, cycleOk))
		// typecheck associated method signatures
		if obj.Data != nil {
			scope := obj.Data.(*ast.Scope)
			switch t := typ.Underlying.(type) {
			case *Struct:
				// struct fields must not conflict with methods
				for _, f := range t.Fields {
					if m := scope.Lookup(f.Name); m != nil {
						check.errorf(m.Pos(), "type %s has both field and method named %s", obj.Name, f.Name)
					}
				}
				// ok to continue
			case *Interface:
				// methods cannot be associated with an interface type
				for _, m := range scope.Objects {
					recv := m.Decl.(*ast.FuncDecl).Recv.List[0].Type
					check.errorf(recv.Pos(), "invalid receiver type %s (%s is an interface type)", obj.Name, obj.Name)
				}
				// ok to continue
			}
			// typecheck method signatures
			for _, m := range scope.Objects {
				mdecl := m.Decl.(*ast.FuncDecl)
				// TODO(gri) At the moment, the receiver is type-checked when checking
				// the method body. Also, we don't properly track if the receiver is
				// a pointer (i.e., currently, method sets are too large). FIX THIS.
				mtyp := check.typ(mdecl.Type, cycleOk).(*Signature)
				m.Type = mtyp
			}
		}

	case ast.Fun:
		fdecl := obj.Decl.(*ast.FuncDecl)
		if fdecl.Recv != nil {
			// This will ensure that the method base type is
			// type-checked
			check.collectFields(token.FUNC, fdecl.Recv, true)
		}
		ftyp := check.typ(fdecl.Type, cycleOk).(*Signature)
		obj.Type = ftyp
		check.function(ftyp, fdecl.Body)

	default:
		panic("unreachable")
	}
}
开发者ID:mm120,项目名称:gcc,代码行数:85,代码来源:check.go


示例18: VisitValueSpec

func (c *compiler) VisitValueSpec(valspec *ast.ValueSpec, isconst bool) {
	var value_type types.Type
	if valspec.Type != nil {
		value_type = c.GetType(valspec.Type)
	}

	var iota_obj *ast.Object = types.Universe.Lookup("iota")
	defer func(data interface{}) {
		iota_obj.Data = data
	}(iota_obj.Data)

	for i, name_ := range valspec.Names {
		// We may resolve constants in the process of resolving others.
		obj := name_.Obj
		if _, isvalue := (obj.Data).(Value); isvalue {
			continue
		}

		// Set iota if necessary.
		if isconst {
			if iota_, isint := (name_.Obj.Data).(int); isint {
				iota_value := c.NewConstValue(token.INT, strconv.Itoa(iota_))
				iota_obj.Data = iota_value

				// Con objects with an iota have an embedded ValueSpec
				// in the Decl field. We'll just pull it out and use it
				// for evaluating the expression below.
				valspec = (name_.Obj.Decl).(*ast.ValueSpec)
			}
		}

		// Expression may have side-effects, so compute it regardless of
		// whether it'll be assigned to a name.
		var expr ast.Expr
		if i < len(valspec.Values) && valspec.Values[i] != nil {
			expr = valspec.Values[i]
		}

		// For constants, we just pass the ConstValue around. Otherwise, we
		// will convert it to an LLVMValue.
		var value Value
		name := name_.String()
		if !isconst {
			ispackagelevel := len(c.functions) == 0
			if !ispackagelevel {
				// Visit the expression.
				var init_ Value
				if expr != nil {
					init_ = c.VisitExpr(expr)
					if value_type == nil {
						value_type = init_.Type()
					}
				}

				// The variable should be allocated on the stack if it's
				// declared inside a function.
				var llvm_init llvm.Value
				stack_value := c.builder.CreateAlloca(
					c.types.ToLLVM(value_type), name)
				if init_ == nil {
					// If no initialiser was specified, set it to the
					// zero value.
					llvm_init = llvm.ConstNull(c.types.ToLLVM(value_type))
				} else {
					llvm_init = init_.Convert(value_type).LLVMValue()
				}
				c.builder.CreateStore(llvm_init, stack_value)
				llvm_value := c.NewLLVMValue(stack_value, &types.Pointer{Base: value_type})
				value = llvm_value.makePointee()
			} else { // ispackagelevel
				// Set the initialiser. If it's a non-const value, then
				// we'll have to do the assignment in a global constructor
				// function.
				export := name_.IsExported()
				value = c.createGlobal(expr, value_type, name, export)
			}
		} else { // isconst
			value = c.VisitExpr(expr).(ConstValue)
			if value_type != nil {
				value = value.Convert(value_type)
			}
		}

		if name != "_" {
			obj.Data = value
		}
	}
}
开发者ID:c0der007,项目名称:llgo,代码行数:88,代码来源:decl.go


示例19: checkObj

// checkObj type checks an object.
func (c *checker) checkObj(obj *ast.Object, ref bool) {
	if obj.Type != nil {
		// object has already been type checked
		return
	}

	switch obj.Kind {
	case ast.Bad:
		// ignore

	case ast.Con:
		valspec := obj.Decl.(*ast.ValueSpec)
		if valspec.Type != nil {
			obj.Type = c.makeType(valspec.Type, ref)
			for _, name := range valspec.Names {
				name.Obj.Type = obj.Type
			}
		}
		if valspec.Values != nil {
			oldData := Iota.Data
			for i, name := range valspec.Names {
				if name.Obj != nil {
					c.checkExpr(valspec.Values[i], []*ast.Ident{name})
					iotaValue := name.Obj.Data.(int)
					Iota.Data = Const{big.NewInt(int64(iotaValue))}
					constValue := c.evalConst(valspec.Values[i])
					typ := name.Obj.Type.(Type)
					name.Obj.Data = constValue.Convert(&typ)
				} else {
					c.checkExpr(valspec.Values[i], nil)
				}
			}
			if oldData != nil {
				Iota.Data = oldData
			}
		}

	case ast.Typ:
		typ := &Name{Package: c.pkgid, Obj: obj}
		obj.Type = typ // "mark" object so recursion terminates
		typ.Underlying = Underlying(c.makeType(obj.Decl.(*ast.TypeSpec).Type, ref))
		if methobjs := c.methods[obj]; methobjs != nil {
			methobjs.Sort()
			typ.Methods = methobjs

			// Check for instances of field and method with same name.
			if s, ok := typ.Underlying.(*Struct); ok {
				for _, m := range methobjs {
					if _, ok := s.FieldIndices[m.Name]; ok {
						c.errorf(m.Pos(), "type %s has both field and method named %s", obj.Name, m.Name)
					}
				}
			}

			// methods cannot be associated with an interface type
			// (do this check after sorting for reproducible error positions - needed for testing)
			if _, ok := typ.Underlying.(*Interface); ok {
				for _, m := range methobjs {
					recv := m.Decl.(*ast.FuncDecl).Recv.List[0].Type
					c.errorf(recv.Pos(), "invalid receiver type %s (%s is an interface type)", obj.Name, obj.Name)
				}
			}
		}
		for _, m := range typ.Methods {
			c.checkObj(m, ref)
		}

	case ast.Var:
		var names []*ast.Ident
		var values []ast.Expr
		var typexpr ast.Expr
		switch x := obj.Decl.(type) {
		case *ast.ValueSpec:
			names = x.Names
			values = x.Values
			typexpr = x.Type
		case *ast.Field:
			names = x.Names
			typexpr = x.Type
		case *ast.AssignStmt:
			c.checkStmt(x)
			if obj.Type == nil {
				panic("obj.Type == nil")
			}
		default:
			panic(fmt.Sprintf("unimplemented (%T)", x))
		}
		if names != nil { // nil for anonymous field
			var typ Type
			if typexpr != nil {
				typ = c.makeType(typexpr, ref)
				for i, name := range names {
					if name.Obj != nil {
						name.Obj.Type = typ
					} else {
						names[i] = nil
					}
				}
			}
//.........这里部分代码省略.........
开发者ID:kelsieflynn,项目名称:llgo,代码行数:101,代码来源:check.go


示例20: stmt


//.........这里部分代码省略.........
			check.expr(&x, s.Tag, nil, -1)
		} else {
			// TODO(gri) should provide a position (see IncDec) for good error messages
			x.mode = constant
			x.typ = Typ[UntypedBool]
			x.val = true
		}

		check.multipleDefaults(s.Body.List)
		for _, s := range s.Body.List {
			clause, _ := s.(*ast.CaseClause)
			if clause == nil {
				continue // error reported before
			}
			for _, expr := range clause.List {
				var y operand
				check.expr(&y, expr, nil, -1)
				// TODO(gri) x and y must be comparable
			}
			check.stmtList(clause.Body)
		}

	case *ast.TypeSwitchStmt:
		check.optionalStmt(s.Init)

		// A type switch guard must be of the form:
		//
		//     TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
		//
		// The parser is checking syntactic correctness;
		// remaining syntactic errors are considered AST errors here.
		// TODO(gri) better factoring of error handling (invalid ASTs)
		//
		var lhs *ast.Object // lhs identifier object or nil
		var rhs ast.Expr
		switch guard := s.Assign.(type) {
		case *ast.ExprStmt:
			rhs = guard.X
		case *ast.AssignStmt:
			if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
				check.invalidAST(s.Pos(), "incorrect form of type switch guard")
				return
			}
			ident, _ := guard.Lhs[0].(*ast.Ident)
			if ident == nil {
				check.invalidAST(s.Pos(), "incorrect form of type switch guard")
				return
			}
			lhs = ident.Obj
			rhs = guard.Rhs[0]
		default:
			check.invalidAST(s.Pos(), "incorrect form of type switch guard")
			return
		}

		// rhs must be of the form: expr.(type) and expr must be an interface
		expr, _ := rhs.(*ast.TypeAssertExpr)
		if expr == nil || expr.Type != nil {
			check.invalidAST(s.Pos(), "incorrect form of type switch guard")
			return
		}
		var x operand
		check.expr(&x, expr.X, nil, -1)
		if x.mode == invalid {
			return
		}
开发者ID:Lao16,项目名称:gcc,代码行数:67,代码来源:stmt.go



注:本文中的go/ast.Object类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang ast.ReturnStmt类代码示例发布时间:2022-05-28
下一篇:
Golang ast.Node类代码示例发布时间:2022-05-28
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap