diff options
Diffstat (limited to 'src/pkg/go/typechecker/typechecker.go')
-rw-r--r-- | src/pkg/go/typechecker/typechecker.go | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/src/pkg/go/typechecker/typechecker.go b/src/pkg/go/typechecker/typechecker.go index e9aefa240..b151f5834 100644 --- a/src/pkg/go/typechecker/typechecker.go +++ b/src/pkg/go/typechecker/typechecker.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// INCOMPLETE PACKAGE. +// DEPRECATED PACKAGE - SEE go/types INSTEAD. // This package implements typechecking of a Go AST. // The result of the typecheck is an augmented AST // with object and type information for each identifier. @@ -53,7 +53,7 @@ func CheckPackage(fset *token.FileSet, pkg *ast.Package, importer Importer) os.E // func CheckFile(fset *token.FileSet, file *ast.File, importer Importer) os.Error { // create a single-file dummy package - pkg := &ast.Package{file.Name.Name, nil, map[string]*ast.File{fset.Position(file.Name.NamePos).Filename: file}} + pkg := &ast.Package{file.Name.Name, nil, nil, map[string]*ast.File{fset.Position(file.Name.NamePos).Filename: file}} return CheckPackage(fset, pkg, importer) } @@ -65,6 +65,7 @@ type typechecker struct { fset *token.FileSet scanner.ErrorVector importer Importer + globals []*ast.Object // list of global objects topScope *ast.Scope // current top-most scope cyclemap map[*ast.Object]bool // for cycle detection iota int // current value of iota @@ -94,7 +95,7 @@ phase 1: declare all global objects; also collect all function and method declar - report global double declarations phase 2: bind methods to their receiver base types - - received base types must be declared in the package, thus for + - receiver base types must be declared in the package, thus for each method a corresponding (unresolved) type must exist - report method double declarations and errors with base types @@ -142,16 +143,16 @@ func (tc *typechecker) checkPackage(pkg *ast.Package) { } // phase 3: resolve all global objects - // (note that objects with _ name are also in the scope) tc.cyclemap = make(map[*ast.Object]bool) - for _, obj := range tc.topScope.Objects { + for _, obj := range tc.globals { tc.resolve(obj) } assert(len(tc.cyclemap) == 0) // 4: sequentially typecheck function and method bodies for _, f := range funcs { - tc.checkBlock(f.Body.List, f.Name.Obj.Type) + ftype, _ := f.Name.Obj.Type.(*Type) + tc.checkBlock(f.Body.List, ftype) } pkg.Scope = tc.topScope @@ -183,11 +184,11 @@ func (tc *typechecker) declGlobal(global ast.Decl) { } } for _, name := range s.Names { - tc.decl(ast.Con, name, s, iota) + tc.globals = append(tc.globals, tc.decl(ast.Con, name, s, iota)) } case token.VAR: for _, name := range s.Names { - tc.decl(ast.Var, name, s, 0) + tc.globals = append(tc.globals, tc.decl(ast.Var, name, s, 0)) } default: panic("unreachable") @@ -196,9 +197,10 @@ func (tc *typechecker) declGlobal(global ast.Decl) { iota++ case *ast.TypeSpec: obj := tc.decl(ast.Typ, s.Name, s, 0) + tc.globals = append(tc.globals, obj) // give all type objects an unresolved type so // that we can collect methods in the type scope - typ := ast.NewType(ast.Unresolved) + typ := NewType(Unresolved) obj.Type = typ typ.Obj = obj default: @@ -208,7 +210,7 @@ func (tc *typechecker) declGlobal(global ast.Decl) { case *ast.FuncDecl: if d.Recv == nil { - tc.decl(ast.Fun, d.Name, d, 0) + tc.globals = append(tc.globals, tc.decl(ast.Fun, d.Name, d, 0)) } default: @@ -239,8 +241,8 @@ func (tc *typechecker) bindMethod(method *ast.FuncDecl) { } else if obj.Kind != ast.Typ { tc.Errorf(name.Pos(), "invalid receiver: %s is not a type", name.Name) } else { - typ := obj.Type - assert(typ.Form == ast.Unresolved) + typ := obj.Type.(*Type) + assert(typ.Form == Unresolved) scope = typ.Scope } } @@ -261,7 +263,7 @@ func (tc *typechecker) bindMethod(method *ast.FuncDecl) { 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) + tc.Errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name) obj.Kind = ast.Bad return } @@ -271,7 +273,7 @@ func (tc *typechecker) resolve(obj *ast.Object) { }() // resolve non-type objects - typ := obj.Type + typ, _ := obj.Type.(*Type) if typ == nil { switch obj.Kind { case ast.Bad: @@ -282,12 +284,12 @@ func (tc *typechecker) resolve(obj *ast.Object) { case ast.Var: tc.declVar(obj) - //obj.Type = tc.typeFor(nil, obj.Decl.(*ast.ValueSpec).Type, false) + obj.Type = tc.typeFor(nil, obj.Decl.(*ast.ValueSpec).Type, false) case ast.Fun: - obj.Type = ast.NewType(ast.Function) + obj.Type = NewType(Function) t := obj.Decl.(*ast.FuncDecl).Type - tc.declSignature(obj.Type, nil, t.Params, t.Results) + tc.declSignature(obj.Type.(*Type), nil, t.Params, t.Results) default: // type objects have non-nil types when resolve is called @@ -300,32 +302,34 @@ func (tc *typechecker) resolve(obj *ast.Object) { } // resolve type objects - if typ.Form == ast.Unresolved { + if typ.Form == 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) + obj.Type = NewType(Method) f := obj.Decl.(*ast.FuncDecl) t := f.Type - tc.declSignature(obj.Type, f.Recv, t.Params, t.Results) + tc.declSignature(obj.Type.(*Type), f.Recv, t.Params, t.Results) } } } } -func (tc *typechecker) checkBlock(body []ast.Stmt, ftype *ast.Type) { +func (tc *typechecker) checkBlock(body []ast.Stmt, ftype *Type) { tc.openScope() defer tc.closeScope() // inject function/method parameters into block scope, if any if ftype != nil { for _, par := range ftype.Params.Objects { - obj := tc.topScope.Insert(par) - assert(obj == par) // ftype has no double declarations + if par.Name != "_" { + alt := tc.topScope.Insert(par) + assert(alt == nil) // ftype has no double declarations + } } } @@ -362,8 +366,8 @@ func (tc *typechecker) declFields(scope *ast.Scope, fields *ast.FieldList, ref b } -func (tc *typechecker) declSignature(typ *ast.Type, recv, params, results *ast.FieldList) { - assert((typ.Form == ast.Method) == (recv != nil)) +func (tc *typechecker) declSignature(typ *Type, recv, params, results *ast.FieldList) { + assert((typ.Form == Method) == (recv != nil)) typ.Params = ast.NewScope(nil) tc.declFields(typ.Params, recv, true) tc.declFields(typ.Params, params, true) @@ -371,7 +375,7 @@ func (tc *typechecker) declSignature(typ *ast.Type, recv, params, results *ast.F } -func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Type) { +func (tc *typechecker) typeFor(def *Type, x ast.Expr, ref bool) (typ *Type) { x = unparen(x) // type name @@ -381,10 +385,10 @@ func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Ty if obj.Kind != ast.Typ { tc.Errorf(t.Pos(), "%s is not a type", t.Name) if def == nil { - typ = ast.NewType(ast.BadType) + typ = NewType(BadType) } else { typ = def - typ.Form = ast.BadType + typ.Form = BadType } typ.Expr = x return @@ -393,7 +397,7 @@ func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Ty if !ref { tc.resolve(obj) // check for cycles even if type resolved } - typ = obj.Type + typ = obj.Type.(*Type) if def != nil { // new type declaration: copy type structure @@ -410,7 +414,7 @@ func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Ty // type literal typ = def if typ == nil { - typ = ast.NewType(ast.BadType) + typ = NewType(BadType) } typ.Expr = x @@ -419,42 +423,42 @@ func (tc *typechecker) typeFor(def *ast.Type, x ast.Expr, ref bool) (typ *ast.Ty if debug { fmt.Println("qualified identifier unimplemented") } - typ.Form = ast.BadType + typ.Form = BadType case *ast.StarExpr: - typ.Form = ast.Pointer + typ.Form = Pointer typ.Elt = tc.typeFor(nil, t.X, true) case *ast.ArrayType: if t.Len != nil { - typ.Form = ast.Array + typ.Form = Array // TODO(gri) compute the real length // (this may call resolve recursively) (*typ).N = 42 } else { - typ.Form = ast.Slice + typ.Form = Slice } typ.Elt = tc.typeFor(nil, t.Elt, t.Len == nil) case *ast.StructType: - typ.Form = ast.Struct + typ.Form = Struct tc.declFields(typ.Scope, t.Fields, false) case *ast.FuncType: - typ.Form = ast.Function + typ.Form = Function tc.declSignature(typ, nil, t.Params, t.Results) case *ast.InterfaceType: - typ.Form = ast.Interface + typ.Form = Interface tc.declFields(typ.Scope, t.Methods, true) case *ast.MapType: - typ.Form = ast.Map + typ.Form = Map typ.Key = tc.typeFor(nil, t.Key, true) typ.Elt = tc.typeFor(nil, t.Value, true) case *ast.ChanType: - typ.Form = ast.Channel + typ.Form = Channel typ.N = uint(t.Dir) typ.Elt = tc.typeFor(nil, t.Value, true) |