本文整理汇总了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] = ©
}
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;未经允许,请勿转载。 |
请发表评论