]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/noder: refactor irgen import handling
authorMatthew Dempsky <mdempsky@google.com>
Thu, 27 May 2021 09:48:33 +0000 (02:48 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 27 May 2021 23:54:29 +0000 (23:54 +0000)
Rather than re-parsing and re-resolving the import path string, use
the PkgName object provided by types2 to determine what package path
it refers to.

Also, decompose importfile into smaller functions, so that we can
directly pass the already-resolved package path to the importer.

Finally, switch to simply using height as calculated by types2 rather
than redoing the calculations.

Change-Id: I3338f4e68387b2835b2e58d6df65d740d6a648cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/323309
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
Trust: Dan Scales <danscales@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/noder/decl.go
src/cmd/compile/internal/noder/import.go
src/cmd/compile/internal/noder/irgen.go

index 40cbe50affd602a1ab6f38c0351f2b2850fcfbb4..375eb418989a78fe6d0bc8dc66287649fe4483d7 100644 (file)
@@ -46,7 +46,12 @@ func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
 
        g.pragmaFlags(decl.Pragma, 0)
 
-       ipkg := importfile(decl)
+       // Get the imported package's path, as resolved already by types2
+       // and gcimporter. This is the same path as would be computed by
+       // parseImportPath.
+       path := pkgNameOf(g.info, decl).Imported().Path()
+
+       ipkg := readImportFile(g.target, path)
        if ipkg == ir.Pkgs.Unsafe {
                p.importedUnsafe = true
        }
@@ -55,6 +60,14 @@ func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
        }
 }
 
+// pkgNameOf returns the PkgName associated with the given ImportDecl.
+func pkgNameOf(info *types2.Info, decl *syntax.ImportDecl) *types2.PkgName {
+       if name := decl.LocalPkgName; name != nil {
+               return info.Defs[name].(*types2.PkgName)
+       }
+       return info.Implicits[decl].(*types2.PkgName)
+}
+
 func (g *irgen) constDecl(out *ir.Nodes, decl *syntax.ConstDecl) {
        g.pragmaFlags(decl.Pragma, 0)
 
index c4a57806ebf9330760e466cb812ba16c35ce9f7c..24d911ba381d748664eeeb1dfd1d878a85984f69 100644 (file)
@@ -175,36 +175,44 @@ func resolveImportPath(path string) (string, error) {
        return path, nil
 }
 
-// TODO(mdempsky): Return an error instead.
 func importfile(decl *syntax.ImportDecl) *types.Pkg {
-       if decl.Path.Kind != syntax.StringLit {
-               base.Errorf("import path must be a string")
+       path, err := parseImportPath(decl.Path)
+       if err != nil {
+               base.Errorf("%s", err)
                return nil
        }
 
-       path, err := strconv.Unquote(decl.Path.Value)
-       if err != nil {
-               base.Errorf("import path must be a string")
-               return nil
+       pkg := readImportFile(typecheck.Target, path)
+       if pkg != ir.Pkgs.Unsafe && pkg.Height >= myheight {
+               myheight = pkg.Height + 1
        }
+       return pkg
+}
 
-       if err := checkImportPath(path, false); err != nil {
-               base.Errorf("%s", err.Error())
-               return nil
+func parseImportPath(pathLit *syntax.BasicLit) (string, error) {
+       if pathLit.Kind != syntax.StringLit {
+               return "", errors.New("import path must be a string")
        }
 
-       path, err = resolveImportPath(path)
+       path, err := strconv.Unquote(pathLit.Value)
        if err != nil {
-               base.Errorf("%s", err)
-               return nil
+               return "", errors.New("import path must be a string")
+       }
+
+       if err := checkImportPath(path, false); err != nil {
+               return "", err
        }
 
+       return resolveImportPath(path)
+}
+
+func readImportFile(target *ir.Package, path string) *types.Pkg {
        importpkg := types.NewPkg(path, "")
        if importpkg.Direct {
                return importpkg // already fully loaded
        }
        importpkg.Direct = true
-       typecheck.Target.Imports = append(typecheck.Target.Imports, importpkg)
+       target.Imports = append(target.Imports, importpkg)
 
        if path == "unsafe" {
                return importpkg // initialized with universe
@@ -324,10 +332,6 @@ func importfile(decl *syntax.ImportDecl) *types.Pkg {
                base.Ctxt.AddImport(file[len(file)-len(path)-len(".a"):], fingerprint)
        }
 
-       if importpkg.Height >= myheight {
-               myheight = importpkg.Height + 1
-       }
-
        return importpkg
 }
 
index f02246111fc8fdd8d4845078162d8cdb48c3b394..abaaa8cbb0480bde517ff928da786c299e5fe6b7 100644 (file)
@@ -98,6 +98,7 @@ type irgen struct {
 
 func (g *irgen) generate(noders []*noder) {
        types.LocalPkg.Name = g.self.Name()
+       types.LocalPkg.Height = g.self.Height()
        typecheck.TypecheckAllowed = true
 
        // Prevent size calculations until we set the underlying type
@@ -132,8 +133,6 @@ Outer:
                        }
                }
        }
-       assert(myheight == g.self.Height())
-       types.LocalPkg.Height = myheight
 
        // 2. Process all package-block type declarations. As with imports,
        // we need to make sure all types are properly instantiated before