Skip to content

Commit 8d9060f

Browse files
committed
JS: Store in the Java AST
1 parent c715de2 commit 8d9060f

File tree

9 files changed

+63
-34
lines changed

9 files changed

+63
-34
lines changed

javascript/extractor/src/com/semmle/jcorn/ESNextParser.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ protected ExportDeclaration parseExportRest(SourceLocation exportStart, Set<Stri
314314
this.parseExportSpecifiersMaybe(specifiers, exports);
315315
}
316316
Literal source = (Literal) this.parseExportFrom(specifiers, null, true);
317-
Expression assertion = this.parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST
318-
return this.finishNode(new ExportNamedDeclaration(exportStart, null, specifiers, source));
317+
Expression assertion = this.parseImportOrExportAssertionAndSemicolon();
318+
return this.finishNode(new ExportNamedDeclaration(exportStart, null, specifiers, source, assertion));
319319
}
320320

321321
return super.parseExportRest(exportStart, exports);
@@ -331,8 +331,8 @@ protected ExportDeclaration parseExportAll(
331331
List<ExportSpecifier> specifiers = CollectionUtil.makeList(nsSpec);
332332
this.parseExportSpecifiersMaybe(specifiers, exports);
333333
Literal source = (Literal) this.parseExportFrom(specifiers, null, true);
334-
Expression assertion = this.parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST
335-
return this.finishNode(new ExportNamedDeclaration(exportStart, null, specifiers, source));
334+
Expression assertion = this.parseImportOrExportAssertionAndSemicolon();
335+
return this.finishNode(new ExportNamedDeclaration(exportStart, null, specifiers, source, assertion));
336336
}
337337

338338
return super.parseExportAll(exportStart, starLoc, exports);
@@ -437,12 +437,12 @@ private MetaProperty parseImportMeta(Position loc) {
437437
*/
438438
private DynamicImport parseDynamicImport(Position startLoc) {
439439
Expression source = parseMaybeAssign(false, null, null);
440-
Expression assertion = null;
440+
Expression attributes = null;
441441
if (this.eat(TokenType.comma)) {
442-
assertion = this.parseMaybeAssign(false, null, null); // TODO: store in AST
442+
attributes = this.parseMaybeAssign(false, null, null);
443443
}
444444
this.expect(TokenType.parenR);
445-
DynamicImport di = this.finishNode(new DynamicImport(new SourceLocation(startLoc), source));
445+
DynamicImport di = this.finishNode(new DynamicImport(new SourceLocation(startLoc), source, attributes));
446446
return di;
447447
}
448448

javascript/extractor/src/com/semmle/jcorn/Parser.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3429,10 +3429,10 @@ protected ExportDeclaration parseExportRest(SourceLocation loc, Set<String> expo
34293429
declaration = null;
34303430
specifiers = this.parseExportSpecifiers(exports);
34313431
source = parseExportFrom(specifiers, source, false);
3432-
assertion = parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST
3432+
assertion = parseImportOrExportAssertionAndSemicolon();
34333433
}
34343434
return this.finishNode(
3435-
new ExportNamedDeclaration(loc, declaration, specifiers, (Literal) source));
3435+
new ExportNamedDeclaration(loc, declaration, specifiers, (Literal) source, assertion));
34363436
}
34373437

34383438
/** Parses the 'from' clause of an export, not including the assertion or semicolon. */
@@ -3460,8 +3460,8 @@ protected Expression parseExportFrom(
34603460
protected ExportDeclaration parseExportAll(
34613461
SourceLocation loc, Position starLoc, Set<String> exports) {
34623462
Expression source = parseExportFrom(null, null, true);
3463-
Expression assertion = parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST
3464-
return this.finishNode(new ExportAllDeclaration(loc, (Literal) source));
3463+
Expression assertion = parseImportOrExportAssertionAndSemicolon();
3464+
return this.finishNode(new ExportAllDeclaration(loc, (Literal) source, assertion));
34653465
}
34663466

34673467
private void checkExport(Set<String> exports, String name, Position pos) {
@@ -3549,9 +3549,9 @@ protected ImportDeclaration parseImportRest(SourceLocation loc) {
35493549
if (this.type != TokenType.string) this.unexpected();
35503550
source = (Literal) this.parseExprAtom(null);
35513551
}
3552-
Expression assertion = this.parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST
3552+
Expression assertion = this.parseImportOrExportAssertionAndSemicolon();
35533553
if (specifiers == null) return null;
3554-
return this.finishNode(new ImportDeclaration(loc, specifiers, source));
3554+
return this.finishNode(new ImportDeclaration(loc, specifiers, source, assertion));
35553555
}
35563556

35573557
// Parses a comma-separated list of module imports.

javascript/extractor/src/com/semmle/jcorn/flow/FlowParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,12 +943,12 @@ protected ExportDeclaration parseExportRest(SourceLocation loc, Set<String> expo
943943
// `export type { foo, bar };`
944944
List<ExportSpecifier> specifiers = this.parseExportSpecifiers(exports);
945945
this.parseExportFrom(specifiers, null, false);
946-
this.parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST?
946+
this.parseImportOrExportAssertionAndSemicolon();
947947
return null;
948948
} else if (this.eat(TokenType.star)) {
949949
if (this.eatContextual("as")) this.parseIdent(true);
950950
this.parseExportFrom(null, null, true);
951-
this.parseImportOrExportAssertionAndSemicolon(); // TODO: store in AST?
951+
this.parseImportOrExportAssertionAndSemicolon();
952952
return null;
953953
} else {
954954
// `export type Foo = Bar;`

javascript/extractor/src/com/semmle/js/ast/DynamicImport.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
public class DynamicImport extends Expression {
44
private final Expression source;
5+
private final Expression attributes;
56

6-
public DynamicImport(SourceLocation loc, Expression source) {
7+
public DynamicImport(SourceLocation loc, Expression source, Expression attributes) {
78
super("DynamicImport", loc);
89
this.source = source;
10+
this.attributes = attributes;
911
}
1012

1113
public Expression getSource() {
1214
return source;
1315
}
1416

17+
/** Returns the second "argument" provided to the import, such as <code>{ assert: { type: "json" }}</code>. */
18+
public Expression getAttributes() {
19+
return attributes;
20+
}
21+
1522
@Override
1623
public <C, R> R accept(Visitor<C, R> v, C c) {
1724
return v.visit(this, c);

javascript/extractor/src/com/semmle/js/ast/ExportAllDeclaration.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@
99
*/
1010
public class ExportAllDeclaration extends ExportDeclaration {
1111
private final Literal source;
12+
private final Expression assertion;
1213

13-
public ExportAllDeclaration(SourceLocation loc, Literal source) {
14+
public ExportAllDeclaration(SourceLocation loc, Literal source, Expression assertion) {
1415
super("ExportAllDeclaration", loc);
1516
this.source = source;
17+
this.assertion = assertion;
1618
}
1719

1820
public Literal getSource() {
1921
return source;
2022
}
2123

24+
public Expression getAssertion() {
25+
return assertion;
26+
}
27+
2228
@Override
2329
public <C, R> R accept(Visitor<C, R> v, C c) {
2430
return v.visit(this, c);

javascript/extractor/src/com/semmle/js/ast/ExportNamedDeclaration.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,22 @@ public class ExportNamedDeclaration extends ExportDeclaration {
1515
private final Statement declaration;
1616
private final List<ExportSpecifier> specifiers;
1717
private final Literal source;
18+
private final Expression assertion;
1819
private final boolean hasTypeKeyword;
1920

2021
public ExportNamedDeclaration(
21-
SourceLocation loc, Statement declaration, List<ExportSpecifier> specifiers, Literal source) {
22-
this(loc, declaration, specifiers, source, false);
22+
SourceLocation loc, Statement declaration, List<ExportSpecifier> specifiers, Literal source, Expression assertion) {
23+
this(loc, declaration, specifiers, source, assertion, false);
2324
}
2425

2526
public ExportNamedDeclaration(
2627
SourceLocation loc, Statement declaration, List<ExportSpecifier> specifiers, Literal source,
27-
boolean hasTypeKeyword) {
28+
Expression assertion, boolean hasTypeKeyword) {
2829
super("ExportNamedDeclaration", loc);
2930
this.declaration = declaration;
3031
this.specifiers = specifiers;
3132
this.source = source;
33+
this.assertion = assertion;
3234
this.hasTypeKeyword = hasTypeKeyword;
3335
}
3436

@@ -57,6 +59,11 @@ public <C, R> R accept(Visitor<C, R> v, C c) {
5759
return v.visit(this, c);
5860
}
5961

62+
/** Returns the expression after the <code>assert</code> keyword, if any, such as <code>{ type: "json" }</code>. */
63+
public Expression getAssertion() {
64+
return assertion;
65+
}
66+
6067
/** Returns true if this is an <code>export type</code> declaration. */
6168
public boolean hasTypeKeyword() {
6269
return hasTypeKeyword;

javascript/extractor/src/com/semmle/js/ast/ImportDeclaration.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,21 @@ public class ImportDeclaration extends Statement implements INodeWithSymbol {
2323
/** The module from which declarations are imported. */
2424
private final Literal source;
2525

26+
private final Expression assertion;
27+
2628
private int symbol = -1;
2729

2830
private boolean hasTypeKeyword;
2931

30-
public ImportDeclaration(SourceLocation loc, List<ImportSpecifier> specifiers, Literal source) {
31-
this(loc, specifiers, source, false);
32+
public ImportDeclaration(SourceLocation loc, List<ImportSpecifier> specifiers, Literal source, Expression assertion) {
33+
this(loc, specifiers, source, assertion, false);
3234
}
3335

34-
public ImportDeclaration(SourceLocation loc, List<ImportSpecifier> specifiers, Literal source, boolean hasTypeKeyword) {
36+
public ImportDeclaration(SourceLocation loc, List<ImportSpecifier> specifiers, Literal source, Expression assertion, boolean hasTypeKeyword) {
3537
super("ImportDeclaration", loc);
3638
this.specifiers = specifiers;
3739
this.source = source;
40+
this.assertion = assertion;
3841
this.hasTypeKeyword = hasTypeKeyword;
3942
}
4043

@@ -46,6 +49,11 @@ public List<ImportSpecifier> getSpecifiers() {
4649
return specifiers;
4750
}
4851

52+
/** Returns the expression after the <code>assert</code> keyword, if any, such as <code>{ type: "json" }</code>. */
53+
public Expression getAssertion() {
54+
return assertion;
55+
}
56+
4957
@Override
5058
public <C, R> R accept(Visitor<C, R> v, C c) {
5159
return v.visit(this, c);

javascript/extractor/src/com/semmle/js/ast/NodeCopier.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ public MetaProperty visit(MetaProperty nd, Void c) {
523523

524524
@Override
525525
public ExportAllDeclaration visit(ExportAllDeclaration nd, Void c) {
526-
return new ExportAllDeclaration(visit(nd.getLoc()), copy(nd.getSource()));
526+
return new ExportAllDeclaration(visit(nd.getLoc()), copy(nd.getSource()), copy(nd.getAssertion()));
527527
}
528528

529529
@Override
@@ -537,7 +537,8 @@ public ExportNamedDeclaration visit(ExportNamedDeclaration nd, Void c) {
537537
visit(nd.getLoc()),
538538
copy(nd.getDeclaration()),
539539
copy(nd.getSpecifiers()),
540-
copy(nd.getSource()));
540+
copy(nd.getSource()),
541+
copy(nd.getAssertion()));
541542
}
542543

543544
@Override
@@ -558,7 +559,7 @@ public ExportSpecifier visit(ExportSpecifier nd, Void c) {
558559
@Override
559560
public ImportDeclaration visit(ImportDeclaration nd, Void c) {
560561
return new ImportDeclaration(
561-
visit(nd.getLoc()), copy(nd.getSpecifiers()), copy(nd.getSource()));
562+
visit(nd.getLoc()), copy(nd.getSpecifiers()), copy(nd.getSource()), copy(nd.getAssertion()), nd.hasTypeKeyword());
562563
}
563564

564565
@Override
@@ -678,7 +679,7 @@ public INode visit(ExternalModuleReference nd, Void c) {
678679

679680
@Override
680681
public INode visit(DynamicImport nd, Void c) {
681-
return new DynamicImport(visit(nd.getLoc()), copy(nd.getSource()));
682+
return new DynamicImport(visit(nd.getLoc()), copy(nd.getSource()), copy(nd.getAttributes()));
682683
}
683684

684685
@Override

javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private Node convertNodeUntyped(JsonObject node, String defaultKind) throws Pars
342342
return convertArrowFunction(node, loc);
343343
case "AsExpression":
344344
return convertTypeAssertionExpression(node, loc);
345-
case "SatisfiesExpression":
345+
case "SatisfiesExpression":
346346
return convertSatisfiesExpression(node, loc);
347347
case "AwaitExpression":
348348
return convertAwaitExpression(node, loc);
@@ -888,7 +888,7 @@ private Node convertBreakStatement(JsonObject node, SourceLocation loc) throws P
888888
private Node convertCallExpression(JsonObject node, SourceLocation loc) throws ParseError {
889889
List<Expression> arguments = convertChildren(node, "arguments");
890890
if (arguments.size() == 1 && hasKind(node.get("expression"), "ImportKeyword")) {
891-
return new DynamicImport(loc, arguments.get(0));
891+
return new DynamicImport(loc, arguments.get(0), null); // TODO: preserve import attributes
892892
}
893893
Expression callee = convertChild(node, "expression");
894894
List<ITypeExpression> typeArguments = convertChildrenAsTypes(node, "typeArguments");
@@ -1199,9 +1199,9 @@ private Node convertExportDeclaration(JsonObject node, SourceLocation loc) throw
11991199
hasKind(node.get("exportClause"), "NamespaceExport")
12001200
? Collections.singletonList(convertChild(node, "exportClause"))
12011201
: convertChildren(node.get("exportClause").getAsJsonObject(), "elements");
1202-
return new ExportNamedDeclaration(loc, null, specifiers, source, hasTypeKeyword);
1202+
return new ExportNamedDeclaration(loc, null, specifiers, source, null, hasTypeKeyword); // TODO: preserve import assertions
12031203
} else {
1204-
return new ExportAllDeclaration(loc, source);
1204+
return new ExportAllDeclaration(loc, source, null); // TODO: preserve import assertions
12051205
}
12061206
}
12071207

@@ -1400,7 +1400,7 @@ private Node convertImportDeclaration(JsonObject node, SourceLocation loc) throw
14001400
}
14011401
hasTypeKeyword = importClause.get("isTypeOnly").getAsBoolean();
14021402
}
1403-
ImportDeclaration importDecl = new ImportDeclaration(loc, specifiers, src, hasTypeKeyword);
1403+
ImportDeclaration importDecl = new ImportDeclaration(loc, specifiers, src, null, hasTypeKeyword); // TODO: preserve import assertions
14041404
attachSymbolInformation(importDecl, node);
14051405
return importDecl;
14061406
}
@@ -1746,7 +1746,7 @@ private Node convertNamespaceDeclaration(JsonObject node, SourceLocation loc) th
17461746
if (hasFlag(node, "NestedNamespace")) {
17471747
// In a nested namespace declaration `namespace A.B`, the nested namespace `B`
17481748
// is implicitly exported.
1749-
return new ExportNamedDeclaration(loc, decl, new ArrayList<>(), null);
1749+
return new ExportNamedDeclaration(loc, decl, new ArrayList<>(), null, null); // TODO: preserve import assertion
17501750
} else {
17511751
return fixExports(loc, decl);
17521752
}
@@ -2455,7 +2455,7 @@ private Node fixExports(SourceLocation loc, Node decl) {
24552455
advance(loc, skipped);
24562456
// capture group 1 is `default`, if present
24572457
if (m.group(1) == null)
2458-
return new ExportNamedDeclaration(outerLoc, (Statement) decl, new ArrayList<>(), null);
2458+
return new ExportNamedDeclaration(outerLoc, (Statement) decl, new ArrayList<>(), null, null); // TODO: preserve import assertions
24592459
return new ExportDefaultDeclaration(outerLoc, decl);
24602460
}
24612461
return decl;

0 commit comments

Comments
 (0)