mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
JS: Add parsing support in JS parser
This commit is contained in:
@@ -61,6 +61,7 @@ import com.semmle.js.ast.IfStatement;
|
|||||||
import com.semmle.js.ast.ImportDeclaration;
|
import com.semmle.js.ast.ImportDeclaration;
|
||||||
import com.semmle.js.ast.ImportDefaultSpecifier;
|
import com.semmle.js.ast.ImportDefaultSpecifier;
|
||||||
import com.semmle.js.ast.ImportNamespaceSpecifier;
|
import com.semmle.js.ast.ImportNamespaceSpecifier;
|
||||||
|
import com.semmle.js.ast.ImportPhaseModifier;
|
||||||
import com.semmle.js.ast.ImportSpecifier;
|
import com.semmle.js.ast.ImportSpecifier;
|
||||||
import com.semmle.js.ast.LabeledStatement;
|
import com.semmle.js.ast.LabeledStatement;
|
||||||
import com.semmle.js.ast.Literal;
|
import com.semmle.js.ast.Literal;
|
||||||
@@ -3587,6 +3588,7 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected ImportDeclaration parseImportRest(SourceLocation loc) {
|
protected ImportDeclaration parseImportRest(SourceLocation loc) {
|
||||||
|
ImportPhaseModifier[] phaseModifier = { ImportPhaseModifier.NONE };
|
||||||
List<ImportSpecifier> specifiers;
|
List<ImportSpecifier> specifiers;
|
||||||
Literal source;
|
Literal source;
|
||||||
// import '...'
|
// import '...'
|
||||||
@@ -3594,27 +3596,32 @@ public class Parser {
|
|||||||
specifiers = new ArrayList<ImportSpecifier>();
|
specifiers = new ArrayList<ImportSpecifier>();
|
||||||
source = (Literal) this.parseExprAtom(null);
|
source = (Literal) this.parseExprAtom(null);
|
||||||
} else {
|
} else {
|
||||||
specifiers = this.parseImportSpecifiers();
|
specifiers = this.parseImportSpecifiers(phaseModifier);
|
||||||
this.expectContextual("from");
|
this.expectContextual("from");
|
||||||
if (this.type != TokenType.string) this.unexpected();
|
if (this.type != TokenType.string) this.unexpected();
|
||||||
source = (Literal) this.parseExprAtom(null);
|
source = (Literal) this.parseExprAtom(null);
|
||||||
}
|
}
|
||||||
Expression attributes = this.parseImportOrExportAttributesAndSemicolon();
|
Expression attributes = this.parseImportOrExportAttributesAndSemicolon();
|
||||||
if (specifiers == null) return null;
|
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.
|
// Parses a comma-separated list of module imports.
|
||||||
protected List<ImportSpecifier> parseImportSpecifiers() {
|
protected List<ImportSpecifier> parseImportSpecifiers(ImportPhaseModifier[] phaseModifier) {
|
||||||
List<ImportSpecifier> nodes = new ArrayList<ImportSpecifier>();
|
List<ImportSpecifier> nodes = new ArrayList<ImportSpecifier>();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
if (this.type == TokenType.name) {
|
if (this.type == TokenType.name) {
|
||||||
// import defaultObj, { x, y as z } from '...'
|
// import defaultObj, { x, y as z } from '...'
|
||||||
SourceLocation loc = new SourceLocation(this.startLoc);
|
SourceLocation loc = new SourceLocation(this.startLoc);
|
||||||
Identifier local = this.parseIdent(false);
|
Identifier local = this.parseIdent(false);
|
||||||
this.checkLVal(local, true, null);
|
// Parse `import defer *` as the beginning of a deferred import, instead of a default import specifier
|
||||||
nodes.add(this.finishNode(new ImportDefaultSpecifier(loc, local)));
|
if (this.type == TokenType.star && local.getName().equals("defer")) {
|
||||||
if (!this.eat(TokenType.comma)) return nodes;
|
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) {
|
if (this.type == TokenType.star) {
|
||||||
SourceLocation loc = new SourceLocation(this.startLoc);
|
SourceLocation loc = new SourceLocation(this.startLoc);
|
||||||
@@ -3647,7 +3654,7 @@ public class Parser {
|
|||||||
if (this.type == TokenType.string) {
|
if (this.type == TokenType.string) {
|
||||||
// Arbitrary Module Namespace Identifiers
|
// Arbitrary Module Namespace Identifiers
|
||||||
// e.g. `import { "Foo::new" as Foo_new } from "./foo.wasm"`
|
// 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();
|
String str = ((Literal)string).getStringValue();
|
||||||
imported = this.finishNode(new Identifier(loc, str));
|
imported = this.finishNode(new Identifier(loc, str));
|
||||||
// only makes sense if there is a local identifier
|
// only makes sense if there is a local identifier
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.semmle.js.ast.Expression;
|
|||||||
import com.semmle.js.ast.ExpressionStatement;
|
import com.semmle.js.ast.ExpressionStatement;
|
||||||
import com.semmle.js.ast.FieldDefinition;
|
import com.semmle.js.ast.FieldDefinition;
|
||||||
import com.semmle.js.ast.Identifier;
|
import com.semmle.js.ast.Identifier;
|
||||||
|
import com.semmle.js.ast.ImportPhaseModifier;
|
||||||
import com.semmle.js.ast.ImportSpecifier;
|
import com.semmle.js.ast.ImportSpecifier;
|
||||||
import com.semmle.js.ast.Literal;
|
import com.semmle.js.ast.Literal;
|
||||||
import com.semmle.js.ast.MethodDefinition;
|
import com.semmle.js.ast.MethodDefinition;
|
||||||
@@ -1064,13 +1065,13 @@ public class FlowParser extends ESNextParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ImportSpecifier> parseImportSpecifiers() {
|
protected List<ImportSpecifier> parseImportSpecifiers(ImportPhaseModifier[] phaseModifier) {
|
||||||
String kind = null;
|
String kind = null;
|
||||||
if (flow()) {
|
if (flow()) {
|
||||||
kind = flowParseImportSpecifiers();
|
kind = flowParseImportSpecifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ImportSpecifier> specs = super.parseImportSpecifiers();
|
List<ImportSpecifier> specs = super.parseImportSpecifiers(phaseModifier);
|
||||||
if (kind != null || specs.isEmpty()) return null;
|
if (kind != null || specs.isEmpty()) return null;
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import defer * as deferred from "somewhere";
|
||||||
|
import * as normal from "somewhere";
|
||||||
|
import defer from "somewhere";
|
||||||
@@ -1 +1,2 @@
|
|||||||
|
| test-js.js:1:1:1:44 | import ... where"; |
|
||||||
| tst.ts:1:1:1:44 | import ... where"; |
|
| tst.ts:1:1:1:44 | import ... where"; |
|
||||||
|
|||||||
Reference in New Issue
Block a user