if ident, ok := e.X.(*ast.Ident); ok {
if pkg, ok := check.lookup(ident).(*Package); ok {
exp := pkg.Scope.Lookup(sel)
- if exp == nil {
- check.errorf(e.Sel.Pos(), "cannot refer to unexported %s", sel)
+ // gcimported package scopes contain non-exported
+ // objects such as types used in partially exported
+ // objects - do not accept them
+ if exp == nil || !ast.IsExported(exp.GetName()) {
+ check.errorf(e.Pos(), "cannot refer to unexported %s", e)
goto Error
}
check.register(e.Sel, exp)
func (obj *Var) GetType() Type { return obj.Type }
func (obj *Func) GetType() Type { return obj.Type }
-func (obj *Package) GetPos() token.Pos { return obj.spec.Pos() }
+func (obj *Package) GetPos() token.Pos {
+ if obj.spec != nil {
+ return obj.spec.Pos()
+ }
+ return token.NoPos
+}
+
func (obj *Const) GetPos() token.Pos {
for _, n := range obj.spec.Names {
if n.Name == obj.Name {
}
return token.NoPos
}
-func (obj *TypeName) GetPos() token.Pos { return obj.spec.Pos() }
+func (obj *TypeName) GetPos() token.Pos {
+ if obj.spec != nil {
+ return obj.spec.Pos()
+ }
+ return token.NoPos
+}
+
func (obj *Var) GetPos() token.Pos {
switch d := obj.decl.(type) {
case *ast.Field:
}
return token.NoPos
}
-func (obj *Func) GetPos() token.Pos { return obj.decl.Name.Pos() }
+func (obj *Func) GetPos() token.Pos {
+ if obj.decl != nil && obj.decl.Name != nil {
+ return obj.decl.Name.Pos()
+ }
+ return token.NoPos
+}
func (*Package) anObject() {}
func (*Const) anObject() {}
"strconv"
)
-func (check *checker) declareObj(scope, altScope *Scope, obj Object) {
+func (check *checker) declareObj(scope, altScope *Scope, obj Object, dotImport token.Pos) {
alt := scope.Insert(obj)
if alt == nil && altScope != nil {
// see if there is a conflicting declaration in altScope
}
if alt != nil {
prevDecl := ""
+
+ // for dot-imports, local declarations are declared first - swap messages
+ if dotImport.IsValid() {
+ if pos := alt.GetPos(); pos.IsValid() {
+ check.errorf(pos, fmt.Sprintf("%s redeclared in this block by dot-import at %s",
+ obj.GetName(), check.fset.Position(dotImport)))
+ return
+ }
+
+ // get by w/o other position
+ check.errorf(dotImport, fmt.Sprintf("dot-import redeclares %s", obj.GetName()))
+ return
+ }
+
if pos := alt.GetPos(); pos.IsValid() {
- prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", check.fset.Position(pos))
+ prevDecl = fmt.Sprintf("\n\tother declaration at %s", check.fset.Position(pos))
}
check.errorf(obj.GetPos(), fmt.Sprintf("%s redeclared in this block%s", obj.GetName(), prevDecl))
}
if name == "." {
// merge imported scope with file scope
for _, obj := range imp.Scope.Entries {
- check.declareObj(fileScope, pkg.Scope, obj)
+ // gcimported package scopes contain non-exported
+ // objects such as types used in partially exported
+ // objects - do not accept them
+ if ast.IsExported(obj.GetName()) {
+ check.declareObj(fileScope, pkg.Scope, obj, spec.Pos())
+ }
}
// TODO(gri) consider registering the "." identifier
// if we have Context.Ident callbacks for say blank
// a new object instead; the Decl field is different
// for different files)
obj := &Package{Name: name, Scope: imp.Scope, spec: spec}
- check.declareObj(fileScope, pkg.Scope, obj)
+ check.declareObj(fileScope, pkg.Scope, obj, token.NoPos)
}
}