Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions javascript/extractor/src/com/semmle/jcorn/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.semmle.js.ast.ImportDeclaration;
import com.semmle.js.ast.ImportDefaultSpecifier;
import com.semmle.js.ast.ImportNamespaceSpecifier;
import com.semmle.js.ast.ImportPhaseModifier;
import com.semmle.js.ast.ImportSpecifier;
import com.semmle.js.ast.LabeledStatement;
import com.semmle.js.ast.Literal;
Expand Down Expand Up @@ -3587,34 +3588,40 @@ protected Expression parseImportOrExportAttributesAndSemicolon() {
}

protected ImportDeclaration parseImportRest(SourceLocation loc) {
ImportPhaseModifier[] phaseModifier = { ImportPhaseModifier.NONE };
List<ImportSpecifier> specifiers;
Literal source;
// import '...'
if (this.type == TokenType.string) {
specifiers = new ArrayList<ImportSpecifier>();
source = (Literal) this.parseExprAtom(null);
} else {
specifiers = this.parseImportSpecifiers();
specifiers = this.parseImportSpecifiers(phaseModifier);
this.expectContextual("from");
if (this.type != TokenType.string) this.unexpected();
source = (Literal) this.parseExprAtom(null);
}
Expression attributes = this.parseImportOrExportAttributesAndSemicolon();
if (specifiers == null) return null;
return this.finishNode(new ImportDeclaration(loc, specifiers, source, attributes));
return this.finishNode(new ImportDeclaration(loc, specifiers, source, attributes, phaseModifier[0]));
}

// Parses a comma-separated list of module imports.
protected List<ImportSpecifier> parseImportSpecifiers() {
protected List<ImportSpecifier> parseImportSpecifiers(ImportPhaseModifier[] phaseModifier) {
List<ImportSpecifier> nodes = new ArrayList<ImportSpecifier>();
boolean first = true;
if (this.type == TokenType.name) {
// import defaultObj, { x, y as z } from '...'
SourceLocation loc = new SourceLocation(this.startLoc);
Identifier local = this.parseIdent(false);
this.checkLVal(local, true, null);
nodes.add(this.finishNode(new ImportDefaultSpecifier(loc, local)));
if (!this.eat(TokenType.comma)) return nodes;
// Parse `import defer *` as the beginning of a deferred import, instead of a default import specifier
if (this.type == TokenType.star && local.getName().equals("defer")) {
phaseModifier[0] = ImportPhaseModifier.DEFER;
} else {
this.checkLVal(local, true, null);
nodes.add(this.finishNode(new ImportDefaultSpecifier(loc, local)));
if (!this.eat(TokenType.comma)) return nodes;
}
}
if (this.type == TokenType.star) {
SourceLocation loc = new SourceLocation(this.startLoc);
Expand Down Expand Up @@ -3647,7 +3654,7 @@ protected ImportSpecifier parseImportSpecifier() {
if (this.type == TokenType.string) {
// Arbitrary Module Namespace Identifiers
// e.g. `import { "Foo::new" as Foo_new } from "./foo.wasm"`
Expression string = this.parseExprAtom(null);
Expression string = this.parseExprAtom(null);
String str = ((Literal)string).getStringValue();
imported = this.finishNode(new Identifier(loc, str));
// only makes sense if there is a local identifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.semmle.js.ast.ExpressionStatement;
import com.semmle.js.ast.FieldDefinition;
import com.semmle.js.ast.Identifier;
import com.semmle.js.ast.ImportPhaseModifier;
import com.semmle.js.ast.ImportSpecifier;
import com.semmle.js.ast.Literal;
import com.semmle.js.ast.MethodDefinition;
Expand Down Expand Up @@ -1064,13 +1065,13 @@ private String peekAtSpecialFlowImportSpecifier() {
}

@Override
protected List<ImportSpecifier> parseImportSpecifiers() {
protected List<ImportSpecifier> parseImportSpecifiers(ImportPhaseModifier[] phaseModifier) {
String kind = null;
if (flow()) {
kind = flowParseImportSpecifiers();
}

List<ImportSpecifier> specs = super.parseImportSpecifiers();
List<ImportSpecifier> specs = super.parseImportSpecifiers(phaseModifier);
if (kind != null || specs.isEmpty()) return null;
return specs;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import defer * as deferred from "somewhere";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add inline test expectations?

import * as normal from "somewhere";
import defer from "somewhere";
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
| test-js.js:1:1:1:44 | import ... where"; |
| tst.ts:1:1:1:44 | import ... where"; |