Skip to content

Commit 90a1027

Browse files
committed
resolve element access property names
1 parent bb2acd9 commit 90a1027

15 files changed

+221
-38
lines changed

internal/binder/referenceresolver.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type ReferenceResolver interface {
1111
GetReferencedImportDeclaration(node *ast.IdentifierNode) *ast.Declaration
1212
GetReferencedValueDeclaration(node *ast.IdentifierNode) *ast.Declaration
1313
GetReferencedValueDeclarations(node *ast.IdentifierNode) []*ast.Declaration
14+
GetElementAccessExpressionName(expression *ast.ElementAccessExpression) string
1415
}
1516

1617
type ReferenceResolverHooks struct {
@@ -21,6 +22,7 @@ type ReferenceResolverHooks struct {
2122
GetSymbolOfDeclaration func(*ast.Declaration) *ast.Symbol
2223
GetTypeOnlyAliasDeclaration func(symbol *ast.Symbol, include ast.SymbolFlags) *ast.Declaration
2324
GetExportSymbolOfValueSymbolIfExported func(*ast.Symbol) *ast.Symbol
25+
GetElementAccessExpressionName func(*ast.ElementAccessExpression) (string, bool)
2426
}
2527

2628
var _ ReferenceResolver = &referenceResolver{}
@@ -236,3 +238,14 @@ func (r *referenceResolver) GetReferencedValueDeclarations(node *ast.IdentifierN
236238
}
237239
return declarations
238240
}
241+
242+
func (r *referenceResolver) GetElementAccessExpressionName(expression *ast.ElementAccessExpression) string {
243+
if expression != nil {
244+
if r.hooks.GetElementAccessExpressionName != nil {
245+
if name, ok := r.hooks.GetElementAccessExpressionName(expression); ok {
246+
return name
247+
}
248+
}
249+
}
250+
return ""
251+
}

internal/checker/emitresolver.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ func (r *emitResolver) getReferenceResolver() binder.ReferenceResolver {
825825
GetSymbolOfDeclaration: r.checker.getSymbolOfDeclaration,
826826
GetTypeOnlyAliasDeclaration: r.checker.getTypeOnlyAliasDeclarationEx,
827827
GetExportSymbolOfValueSymbolIfExported: r.checker.getExportSymbolOfValueSymbolIfExported,
828+
GetElementAccessExpressionName: r.checker.tryGetElementAccessExpressionName,
828829
})
829830
}
830831
return r.referenceResolver
@@ -879,6 +880,17 @@ func (r *emitResolver) GetReferencedValueDeclarations(node *ast.IdentifierNode)
879880
return r.getReferenceResolver().GetReferencedValueDeclarations(node)
880881
}
881882

883+
func (r *emitResolver) GetElementAccessExpressionName(expression *ast.ElementAccessExpression) string {
884+
if !ast.IsParseTreeNode(expression.AsNode()) {
885+
return ""
886+
}
887+
888+
r.checkerMu.Lock()
889+
defer r.checkerMu.Unlock()
890+
891+
return r.getReferenceResolver().GetElementAccessExpressionName(expression)
892+
}
893+
882894
// TODO: the emit resolver being responsible for some amount of node construction is a very leaky abstraction,
883895
// and requires giving it access to a lot of context it's otherwise not required to have, which also further complicates the API
884896
// and likely reduces performance. There's probably some refactoring that could be done here to simplify this.

internal/transformers/declarations/transform.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,18 +1826,13 @@ func (tx *DeclarationTransformer) visitExpressionStatement(node *ast.ExpressionS
18261826

18271827
func (tx *DeclarationTransformer) transformExpandoAssignment(node *ast.BinaryExpression) *ast.Node {
18281828
left := node.Left
1829-
1830-
if ast.IsElementAccessExpression(left) {
1831-
return nil
1832-
}
1833-
18341829
symbol := node.Symbol
18351830
if symbol == nil || symbol.Flags&ast.SymbolFlagsAssignment == 0 {
18361831
return nil
18371832
}
18381833

1839-
ns := ast.GetFirstIdentifier(left)
1840-
if ns == nil {
1834+
ns := ast.GetLeftmostAccessExpression(left)
1835+
if ns == nil || ns.Kind != ast.KindIdentifier {
18411836
return nil
18421837
}
18431838

@@ -1852,7 +1847,14 @@ func (tx *DeclarationTransformer) transformExpandoAssignment(node *ast.BinaryExp
18521847
}
18531848

18541849
name := tx.Factory().NewIdentifier(ns.Text())
1850+
property := tx.tryGetPropertyName(left)
1851+
if property == "" || !scanner.IsIdentifierText(property, core.LanguageVariantStandard) {
1852+
return nil
1853+
}
1854+
18551855
tx.transformExpandoHost(name, declaration)
1856+
isNonContextualKeywordName := ast.IsNonContextualKeyword(scanner.StringToToken(property))
1857+
exportName := core.IfElse(isNonContextualKeywordName, tx.Factory().NewGeneratedNameForNode(left), tx.Factory().NewIdentifier(property))
18561858

18571859
synthesizedNamespace := tx.Factory().NewModuleDeclaration(nil /*modifiers*/, ast.KindNamespaceKeyword, name, tx.Factory().NewModuleBlock(tx.Factory().NewNodeList([]*ast.Node{})))
18581860
synthesizedNamespace.Parent = tx.enclosingDeclaration
@@ -1868,10 +1870,6 @@ func (tx *DeclarationTransformer) transformExpandoAssignment(node *ast.BinaryExp
18681870
t := tx.resolver.CreateTypeOfExpression(tx.EmitContext(), left, synthesizedNamespace, declarationEmitNodeBuilderFlags, declarationEmitInternalNodeBuilderFlags|nodebuilder.InternalFlagsNoSyntacticPrinter, tx.tracker)
18691871
tx.state.getSymbolAccessibilityDiagnostic = saveDiag
18701872

1871-
nameToken := scanner.StringToToken(left.Name().Text())
1872-
isNonContextualKeywordName := ast.IsNonContextualKeyword(nameToken)
1873-
1874-
exportName := core.IfElse(isNonContextualKeywordName, tx.Factory().NewGeneratedNameForNode(left), tx.Factory().NewIdentifier(left.Name().Text()))
18751873
statements := []*ast.Statement{
18761874
tx.Factory().NewVariableStatement(
18771875
nil, /*modifiers*/
@@ -1964,3 +1962,13 @@ func extractExpandoHostParams(node *ast.Node) (typeParameters *ast.TypeParameter
19641962
return fn.TypeParameters, fn.Parameters, fn.AsteriskToken
19651963
}
19661964
}
1965+
1966+
func (tx *DeclarationTransformer) tryGetPropertyName(node *ast.Node) string {
1967+
if ast.IsElementAccessExpression(node) {
1968+
return tx.resolver.GetElementAccessExpressionName(node.AsElementAccessExpression())
1969+
}
1970+
if ast.IsPropertyAccessExpression(node) {
1971+
return node.Name().Text()
1972+
}
1973+
return ""
1974+
}

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundAssignments.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ export declare function foo(): void;
3939
export declare namespace foo {
4040
const bar: number;
4141
}
42+
export declare namespace foo {
43+
const strMemName: string;
44+
}

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundAssignments.js.diff

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
- var bar: number;
88
- var strMemName: string;
99
+ const bar: number;
10+
+}
11+
+export declare namespace foo {
12+
+ const strMemName: string;
1013
}

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundAssignments2.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,13 @@ arrow10[emoji] = 0;
121121

122122
//// [declarationEmitLateBoundAssignments2.d.ts]
123123
export declare function decl(): void;
124+
export declare namespace decl {
125+
const B: string;
126+
}
124127
export declare function decl2(): void;
128+
export declare namespace decl2 {
129+
const C: number;
130+
}
125131
export declare function decl3(): void;
126132
export declare function decl4(): void;
127133
export declare function decl5(): void;
@@ -130,14 +136,14 @@ export declare function decl7(): void;
130136
export declare function decl8(): void;
131137
export declare function decl9(): void;
132138
export declare function decl10(): void;
133-
export declare const arrow: {
134-
(): void;
135-
B: string;
136-
};
137-
export declare const arrow2: {
138-
(): void;
139-
C: number;
140-
};
139+
export declare function arrow(): void;
140+
export declare namespace arrow {
141+
const B: string;
142+
}
143+
export declare function arrow2(): void;
144+
export declare namespace arrow2 {
145+
const C: number;
146+
}
141147
export declare const arrow3: {
142148
(): void;
143149
77: number;

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundAssignments2.js.diff

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
--- old.declarationEmitLateBoundAssignments2.js
22
+++ new.declarationEmitLateBoundAssignments2.js
3-
@@= skipped -120, +120 lines =@@
4-
3+
@@= skipped -121, +121 lines =@@
54
//// [declarationEmitLateBoundAssignments2.d.ts]
65
export declare function decl(): void;
7-
-export declare namespace decl {
6+
export declare namespace decl {
87
- var B: string;
9-
-}
8+
+ const B: string;
9+
}
1010
export declare function decl2(): void;
11-
-export declare namespace decl2 {
11+
export declare namespace decl2 {
1212
- var C: number;
13-
-}
13+
+ const C: number;
14+
}
1415
export declare function decl3(): void;
1516
-export declare namespace decl3 { }
1617
export declare function decl4(): void;
@@ -27,6 +28,22 @@
2728
-export declare namespace decl9 { }
2829
export declare function decl10(): void;
2930
-export declare namespace decl10 { }
30-
export declare const arrow: {
31+
-export declare const arrow: {
32+
- (): void;
33+
- B: string;
34+
-};
35+
-export declare const arrow2: {
36+
- (): void;
37+
- C: number;
38+
-};
39+
+export declare function arrow(): void;
40+
+export declare namespace arrow {
41+
+ const B: string;
42+
+}
43+
+export declare function arrow2(): void;
44+
+export declare namespace arrow2 {
45+
+ const C: number;
46+
+}
47+
export declare const arrow3: {
3148
(): void;
32-
B: string;
49+
77: number;

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundJSAssignments.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ export declare function foo(): void;
2929
export declare namespace foo {
3030
const bar: number;
3131
}
32+
export declare namespace foo {
33+
const strMemName: string;
34+
}

testdata/baselines/reference/submodule/compiler/declarationEmitLateBoundJSAssignments.js.diff

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@
1111
+export declare function foo(): void;
1212
+export declare namespace foo {
1313
+ const bar: number;
14+
+}
15+
+export declare namespace foo {
16+
+ const strMemName: string;
1417
}

testdata/baselines/reference/submodule/compiler/expandoFunctionExpressionsWithDynamicNames.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ exports.expr2[s] = 0;
2727

2828

2929
//// [expandoFunctionExpressionsWithDynamicNames.d.ts]
30-
export declare const expr: {
31-
(): void;
32-
X: number;
33-
};
34-
export declare const expr2: {
35-
(): void;
36-
X: number;
37-
};
30+
export declare function expr(): void;
31+
export declare namespace expr {
32+
const X: number;
33+
}
34+
export declare function expr2(): void;
35+
export declare namespace expr2 {
36+
const X: number;
37+
}

0 commit comments

Comments
 (0)