Skip to content

Commit 65c5c0b

Browse files
updating decl naming
1 parent 3c9b135 commit 65c5c0b

File tree

11 files changed

+670
-240
lines changed

11 files changed

+670
-240
lines changed

compiler/compiler_test.go

Lines changed: 309 additions & 117 deletions
Large diffs are not rendered by default.

compiler/declNames.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package compiler
2+
3+
import (
4+
"go/types"
5+
6+
"github.com/gopherjs/gopherjs/compiler/internal/symbol"
7+
"github.com/gopherjs/gopherjs/compiler/internal/typeparams"
8+
)
9+
10+
// importDeclFullName returns a unique name for an import declaration.
11+
// This import name may be duplicated in different packages if they both
12+
// import the same package, they are only unique per package.
13+
func importDeclFullName(importedPkg *types.Package) string {
14+
return `import:` + importedPkg.Path()
15+
}
16+
17+
// varDeclFullName returns a name for a package-level variable declaration.
18+
// This var name only references the first named variable in an assignment.
19+
// If no variables are named, the name is `var:blank` and not unique.
20+
func varDeclFullName(init *types.Initializer) string {
21+
for _, lhs := range init.Lhs {
22+
if lhs.Name() != `_` {
23+
return `var:` + symbol.New(lhs).String()
24+
}
25+
}
26+
return `var:blank`
27+
}
28+
29+
// funcVarDeclFullName returns a name for a package-level variable
30+
// that is used for a function (without a receiver) declaration.
31+
// The name is unique unless the function is an `init` function.
32+
// If the function is generic, this declaration name is also for the list
33+
// of instantiations of the function.
34+
func funcVarDeclFullName(o *types.Func) string {
35+
return `funcVar:` + symbol.New(o).String()
36+
}
37+
38+
// mainFuncFullName returns the name for the declaration used to invoke the
39+
// main function of the program. There should only be one decl with this name.
40+
func mainFuncDeclFullName() string {
41+
return `init:main`
42+
}
43+
44+
// funcDeclFullName returns a name for a package-level function
45+
// declaration for the given instance of a function.
46+
// The name is unique except unless the function is an `init` function.
47+
func funcDeclFullName(inst typeparams.Instance) string {
48+
return `func:` + inst.String()
49+
}
50+
51+
// typeVarDeclFullName returns a unique name for a package-level variable
52+
// that is used for a named type declaration.
53+
// If the type is generic, this declaration name is also for the list
54+
// of instantiations of the type.
55+
func typeVarDeclFullName(o *types.TypeName) string {
56+
return `typeVar:` + symbol.New(o).String()
57+
}
58+
59+
// typeDeclFullName returns a unique name for a package-level type declaration
60+
// for the given instance of a type. Names are only unique per package.
61+
func typeDeclFullName(inst typeparams.Instance) string {
62+
return `type:` + inst.String()
63+
}
64+
65+
// anonTypeDeclFullName returns a unique name for a package-level type
66+
// declaration for an anonymous type. Names are only unique per package.
67+
// These names are generated for types that are not named in the source code.
68+
func anonTypeDeclFullName(o types.Object) string {
69+
return `anonType:` + symbol.New(o).String()
70+
}

compiler/decls.go

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ func (fc *funcContext) importDecls() (importedPaths []string, importDecls []*Dec
160160
func (fc *funcContext) newImportDecl(importedPkg *types.Package) *Decl {
161161
pkgVar := fc.importedPkgVar(importedPkg)
162162
d := &Decl{
163+
FullName: importDeclFullName(importedPkg),
163164
Vars: []string{pkgVar},
164165
DeclCode: []byte(fmt.Sprintf("\t%s = $packages[\"%s\"];\n", pkgVar, importedPkg.Path())),
165166
InitCode: fc.CatchOutput(1, func() { fc.translateStmt(fc.importInitializer(importedPkg.Path()), nil) }),
@@ -224,7 +225,9 @@ func (fc *funcContext) varDecls(vars []*types.Var) []*Decl {
224225
// newVarDecl creates a new Decl describing a variable, given an explicit
225226
// initializer.
226227
func (fc *funcContext) newVarDecl(init *types.Initializer) *Decl {
227-
var d Decl
228+
d := &Decl{
229+
FullName: varDeclFullName(init),
230+
}
228231

229232
assignLHS := []ast.Expr{}
230233
for _, o := range init.Lhs {
@@ -241,7 +244,7 @@ func (fc *funcContext) newVarDecl(init *types.Initializer) *Decl {
241244
}
242245
}
243246

244-
fc.pkgCtx.CollectDCEDeps(&d, func() {
247+
fc.pkgCtx.CollectDCEDeps(d, func() {
245248
fc.localVars = nil
246249
d.InitCode = fc.CatchOutput(1, func() {
247250
fc.translateStmt(&ast.AssignStmt{
@@ -261,7 +264,7 @@ func (fc *funcContext) newVarDecl(init *types.Initializer) *Decl {
261264
if len(init.Lhs) != 1 || analysis.HasSideEffect(init.Rhs, fc.pkgCtx.Info.Info) {
262265
d.Dce().SetAsAlive()
263266
}
264-
return &d
267+
return d
265268
}
266269

267270
// funcDecls translates all package-level function and methods.
@@ -279,15 +282,18 @@ func (fc *funcContext) funcDecls(functions []*ast.FuncDecl) ([]*Decl, error) {
279282
if fun.Recv == nil {
280283
// Auxiliary decl shared by all instances of the function that defines
281284
// package-level variable by which they all are referenced.
282-
varDecl := Decl{}
285+
objName := fc.objectName(o)
286+
varDecl := &Decl{
287+
FullName: funcVarDeclFullName(o),
288+
Vars: []string{objName},
289+
}
283290
varDecl.Dce().SetName(o)
284-
varDecl.Vars = []string{fc.objectName(o)}
285291
if o.Type().(*types.Signature).TypeParams().Len() != 0 {
286292
varDecl.DeclCode = fc.CatchOutput(0, func() {
287-
fc.Printf("%s = {};", fc.objectName(o))
293+
fc.Printf("%s = {};", objName)
288294
})
289295
}
290-
funcDecls = append(funcDecls, &varDecl)
296+
funcDecls = append(funcDecls, varDecl)
291297
}
292298

293299
for _, inst := range fc.knownInstances(o) {
@@ -306,6 +312,7 @@ func (fc *funcContext) funcDecls(functions []*ast.FuncDecl) ([]*Decl, error) {
306312
// been initialized. It must come after all other functions, especially all
307313
// init() functions, otherwise main() will be invoked too early.
308314
funcDecls = append(funcDecls, &Decl{
315+
FullName: mainFuncDeclFullName(),
309316
InitCode: fc.CatchOutput(1, func() { fc.translateStmt(fc.callMainFunc(mainFunc), nil) }),
310317
})
311318
}
@@ -316,7 +323,7 @@ func (fc *funcContext) funcDecls(functions []*ast.FuncDecl) ([]*Decl, error) {
316323
func (fc *funcContext) newFuncDecl(fun *ast.FuncDecl, inst typeparams.Instance) *Decl {
317324
o := fc.pkgCtx.Defs[fun.Name].(*types.Func)
318325
d := &Decl{
319-
FullName: o.FullName(),
326+
FullName: funcDeclFullName(inst),
320327
Blocking: fc.pkgCtx.IsBlocking(inst),
321328
LinkingName: symbol.New(o),
322329
}
@@ -417,15 +424,19 @@ func (fc *funcContext) namedTypeDecls(typeNames typesutil.TypeNames) ([]*Decl, e
417424
// of the type, keyed by the type argument combination. Otherwise it contains
418425
// the type definition directly.
419426
func (fc *funcContext) newNamedTypeVarDecl(obj *types.TypeName) *Decl {
420-
varDecl := &Decl{Vars: []string{fc.objectName(obj)}}
427+
name := fc.objectName(obj)
428+
varDecl := &Decl{
429+
FullName: typeVarDeclFullName(obj),
430+
Vars: []string{name},
431+
}
421432
if typeparams.HasTypeParams(obj.Type()) {
422433
varDecl.DeclCode = fc.CatchOutput(0, func() {
423-
fc.Printf("%s = {};", fc.objectName(obj))
434+
fc.Printf("%s = {};", name)
424435
})
425436
}
426437
if isPkgLevel(obj) {
427438
varDecl.TypeInitCode = fc.CatchOutput(0, func() {
428-
fc.Printf("$pkg.%s = %s;", encodeIdent(obj.Name()), fc.objectName(obj))
439+
fc.Printf("$pkg.%s = %s;", encodeIdent(obj.Name()), name)
429440
})
430441
}
431442
return varDecl
@@ -449,7 +460,9 @@ func (fc *funcContext) newNamedTypeInstDecl(inst typeparams.Instance) (*Decl, er
449460
}
450461

451462
underlying := instanceType.Underlying()
452-
d := &Decl{}
463+
d := &Decl{
464+
FullName: typeDeclFullName(inst),
465+
}
453466
d.Dce().SetName(inst.Object, inst.TArgs...)
454467
fc.pkgCtx.CollectDCEDeps(d, func() {
455468
// Code that declares a JS type (i.e. prototype) for each Go type.
@@ -571,7 +584,8 @@ func (fc *funcContext) anonTypeDecls(anonTypes []*types.TypeName) []*Decl {
571584
decls := []*Decl{}
572585
for _, t := range anonTypes {
573586
d := &Decl{
574-
Vars: []string{t.Name()},
587+
FullName: anonTypeDeclFullName(t),
588+
Vars: []string{t.Name()},
575589
}
576590
d.Dce().SetName(t)
577591
fc.pkgCtx.CollectDCEDeps(d, func() {

compiler/functions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (fc *funcContext) namedFuncContext(inst typeparams.Instance) *funcContext {
8282
// go/types doesn't generate *types.Func objects for function literals, we
8383
// generate a synthetic one for it.
8484
func (fc *funcContext) literalFuncContext(fun *ast.FuncLit) *funcContext {
85-
info := fc.pkgCtx.FuncLitInfo(fun)
85+
info := fc.pkgCtx.FuncLitInfo(fun, fc.TypeArgs())
8686
sig := fc.pkgCtx.TypeOf(fun).(*types.Signature)
8787
o := types.NewFunc(fun.Pos(), fc.pkgCtx.Pkg, fc.newLitFuncName(), sig)
8888
inst := typeparams.Instance{Object: o}

compiler/internal/analysis/defer.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package analysis
22

33
import (
44
"go/ast"
5+
"go/types"
56

67
"github.com/gopherjs/gopherjs/compiler/internal/typeparams"
8+
"github.com/gopherjs/gopherjs/compiler/typesutil"
79
)
810

911
// deferStmt represents a defer statement that is blocking or not.
@@ -49,8 +51,9 @@ import (
4951
//
5052
// [CFG]: https://en.wikipedia.org/wiki/Control-flow_graph
5153
type deferStmt struct {
52-
inst *typeparams.Instance
53-
lit *ast.FuncLit
54+
obj types.Object
55+
lit *ast.FuncLit
56+
typeArgs typesutil.TypeList
5457
}
5558

5659
// newBlockingDefer creates a new defer statement that is blocking.
@@ -65,25 +68,25 @@ func newBlockingDefer() *deferStmt {
6568
// newInstDefer creates a new defer statement for an instances of a method.
6669
// The instance is used to look up the blocking information later.
6770
func newInstDefer(inst typeparams.Instance) *deferStmt {
68-
return &deferStmt{inst: &inst}
71+
return &deferStmt{obj: inst.Object, typeArgs: inst.TArgs}
6972
}
7073

7174
// newLitDefer creates a new defer statement for a function literal.
7275
// The literal is used to look up the blocking information later.
73-
func newLitDefer(lit *ast.FuncLit) *deferStmt {
74-
return &deferStmt{lit: lit}
76+
func newLitDefer(lit *ast.FuncLit, typeArgs typesutil.TypeList) *deferStmt {
77+
return &deferStmt{lit: lit, typeArgs: typeArgs}
7578
}
7679

7780
// IsBlocking determines if the defer statement is blocking or not.
7881
func (d *deferStmt) IsBlocking(info *Info) bool {
79-
// If the instance or the literal is set then we can look up the blocking,
82+
// If the object or the literal is set then we can look up the blocking,
8083
// otherwise assume blocking because otherwise the defer wouldn't
8184
// have been recorded.
82-
if d.inst != nil {
83-
return info.FuncInfo(*d.inst).IsBlocking()
85+
if d.obj != nil {
86+
return info.IsBlocking(typeparams.Instance{Object: d.obj, TArgs: d.typeArgs})
8487
}
8588
if d.lit != nil {
86-
return info.FuncLitInfo(d.lit).IsBlocking()
89+
return info.FuncLitInfo(d.lit, d.typeArgs).IsBlocking()
8790
}
8891
return true
8992
}

0 commit comments

Comments
 (0)