Skip to content

Commit 2e858db

Browse files
committed
JS: Declare variables from ambient declarations
fixup
1 parent 74af906 commit 2e858db

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

javascript/extractor/src/com/semmle/js/extractor/HTMLExtractor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ public JavaScriptHTMLElementHandler(TextualExtractor textualExtractor) {
4040
this.textualExtractor = textualExtractor;
4141

4242
this.scopeManager =
43-
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(), true);
43+
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(),
44+
ScopeManager.FileKind.TEMPLATE);
4445
}
4546

4647
/*
@@ -425,7 +426,7 @@ private void extractTemplateTags(
425426
extractSnippet(
426427
TopLevelKind.ANGULAR_STYLE_TEMPLATE,
427428
config.withSourceType(SourceType.ANGULAR_STYLE_TEMPLATE),
428-
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2020, true),
429+
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2020, ScopeManager.FileKind.TEMPLATE),
429430
textualExtractor,
430431
m.group(bodyGroup),
431432
m.start(bodyGroup),

javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,43 @@ public Label lookupNamespace(String name) {
9797
}
9898
}
9999

100+
public static enum FileKind {
101+
/** Any file not specific to one of the other file kinds. */
102+
PLAIN,
103+
104+
/** A file potentially containing template tags. */
105+
TEMPLATE,
106+
107+
/** A d.ts file, containing TypeScript ambient declarations. */
108+
TYPESCRIPT_DECLARATION,
109+
}
110+
100111
private final TrapWriter trapWriter;
101112
private Scope curScope;
102113
private final Scope toplevelScope;
103114
private final ECMAVersion ecmaVersion;
104115
private final Set<String> implicitGlobals = new LinkedHashSet<String>();
105116
private Scope implicitVariableScope;
106-
private final boolean isInTemplateScope;
117+
private final FileKind fileKind;
107118

108-
public ScopeManager(TrapWriter trapWriter, ECMAVersion ecmaVersion, boolean isInTemplateScope) {
119+
public ScopeManager(TrapWriter trapWriter, ECMAVersion ecmaVersion, FileKind fileKind) {
109120
this.trapWriter = trapWriter;
110121
this.toplevelScope = enterScope(ScopeKind.GLOBAL, trapWriter.globalID("global_scope"), null);
111122
this.ecmaVersion = ecmaVersion;
112-
this.implicitVariableScope = toplevelScope;
113-
this.isInTemplateScope = isInTemplateScope;
123+
this.implicitVariableScope = toplevelScope;
124+
this.fileKind = fileKind;
114125
}
115126

116127
/**
117128
* Returns true the current scope is potentially in a template file, and may contain
118129
* relevant template tags.
119130
*/
120131
public boolean isInTemplateFile() {
121-
return isInTemplateScope;
132+
return this.fileKind == FileKind.TEMPLATE;
133+
}
134+
135+
public boolean isInTypeScriptDeclarationFile() {
136+
return this.fileKind == FileKind.TYPESCRIPT_DECLARATION;
122137
}
123138

124139
/**
@@ -221,7 +236,7 @@ public Scope getToplevelScope() {
221236

222237
/**
223238
* Get the label for a given variable in the current scope; if it cannot be found, add it to the
224-
* implicit variable scope (usually the global scope).
239+
* implicit variable scope (usually the global scope).
225240
*/
226241
public Label getVarKey(String name) {
227242
Label lbl = curScope.lookupVariable(name);
@@ -411,15 +426,15 @@ public Void visit(Identifier nd, Void v) {
411426
// cases where we turn on the 'declKind' flags
412427
@Override
413428
public Void visit(FunctionDeclaration nd, Void v) {
414-
if (nd.hasDeclareKeyword()) return null;
429+
if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
415430
// strict mode functions are block-scoped, non-strict mode ones aren't
416431
if (blockscope == isStrict) visit(nd.getId(), DeclKind.var);
417432
return null;
418433
}
419434

420435
@Override
421436
public Void visit(ClassDeclaration nd, Void c) {
422-
if (nd.hasDeclareKeyword()) return null;
437+
if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
423438
if (blockscope) visit(nd.getClassDef().getId(), DeclKind.varAndType);
424439
return null;
425440
}
@@ -468,7 +483,7 @@ public Void visit(EnhancedForStatement nd, Void v) {
468483

469484
@Override
470485
public Void visit(VariableDeclaration nd, Void v) {
471-
if (nd.hasDeclareKeyword()) return null;
486+
if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
472487
// in block scoping mode, only process 'let'; in non-block scoping
473488
// mode, only process non-'let'
474489
if (blockscope == nd.isBlockScoped(ecmaVersion)) visit(nd.getDeclarations());
@@ -503,7 +518,8 @@ public Void visit(ClassBody nd, Void c) {
503518
@Override
504519
public Void visit(NamespaceDeclaration nd, Void c) {
505520
if (blockscope) return null;
506-
boolean hasVariable = nd.isInstantiated() && !nd.hasDeclareKeyword();
521+
boolean isAmbientOutsideDtsFile = nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile();
522+
boolean hasVariable = nd.isInstantiated() && !isAmbientOutsideDtsFile;
507523
visit(nd.getName(), hasVariable ? DeclKind.varAndNamespace : DeclKind.namespace);
508524
return null;
509525
}

javascript/extractor/src/com/semmle/js/extractor/ScriptExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public LoCInfo extract(TextualExtractor textualExtractor) {
7777
}
7878

7979
ScopeManager scopeManager =
80-
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(), false);
80+
new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion(), ScopeManager.FileKind.PLAIN);
8181
Label toplevelLabel = null;
8282
LoCInfo loc;
8383
try {

javascript/extractor/src/com/semmle/js/extractor/TypeScriptExtractor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ public LoCInfo extract(TextualExtractor textualExtractor) {
2222
String source = textualExtractor.getSource();
2323
File sourceFile = textualExtractor.getExtractedFile();
2424
Result res = state.getTypeScriptParser().parse(sourceFile, source, textualExtractor.getMetrics());
25-
ScopeManager scopeManager =
26-
new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2017, false);
25+
ScopeManager.FileKind fileKind = sourceFile.getName().endsWith(".d.ts")
26+
? ScopeManager.FileKind.TYPESCRIPT_DECLARATION
27+
: ScopeManager.FileKind.PLAIN;
28+
ScopeManager scopeManager = new ScopeManager(textualExtractor.getTrapwriter(), ECMAVersion.ECMA2017, fileKind);
2729
try {
2830
FileSnippet snippet = state.getSnippets().get(sourceFile.toPath());
2931
SourceType sourceType = snippet != null ? snippet.getSourceType() : jsExtractor.establishSourceType(source, false);

0 commit comments

Comments
 (0)