From Go's spec on scopes,
Go is lexically scoped using blocks:
- The scope of a predeclared identifier is the universe block.
- The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.
- The scope of the package name of an imported package is the file block of the file containing the import declaration.
- The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
- The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
- The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.
If an explicit period (.) appears instead of a name, all the package's exported identifiers declared in that package's package block will be declared in the importing source file's file block and must be accessed without a qualifier.
Doing a dot import is only legal when none of its exported identifiers overlap with the package's existing exported identifiers (it can't be legal because there'd be no way to distinguish two identifiers with identical names).
./main.go:11: Foo redeclared in this block
previous declaration during import "some/import/path"
However, that doesn't apply for unexported identifers, since they're not accessible anyway, it's okay for a package being dot-imported to have the same unexported identifer as the main package.
But what happens if an exported func within the package being dot-imported refers to one of its unexported identifiers, but that name is already used in the package block of the main package...
Say, we import Foo() which calls foo(), but we already have a foo() in main package.
Does anyone know how Go handles such scenarios?
---
I want to learn the answer for 2 reasons:
1. To know more about how Go works.
2. I have
some Go code that takes an Go package (via import path string) and rewrites it as a single Go AST with all files merged and all dot imports inlined. It works great when no unexported names overlap, but fails when they do.
Thanks!