add initial support for expressions in TypeScript

This commit is contained in:
Erik Krogh Kristensen
2019-10-22 15:46:54 +02:00
parent 4b27b2ac05
commit 834b572f45
17 changed files with 2399 additions and 10 deletions

View File

@@ -12,6 +12,9 @@
* The call graph has been improved to resolve method calls in more cases. This may produce more security alerts.
* TypeScript 3.6 features are supported.
## New queries
| **Query** | **Tags** | **Purpose** |

View File

@@ -162,10 +162,10 @@ function prepareNextFile() {
}
}
function handleParseCommand(command: ParseCommand) {
function handleParseCommand(command: ParseCommand, checkPending = true) {
let filename = command.filename;
let expectedFilename = state.pendingFiles[state.pendingFileIndex];
if (expectedFilename !== filename) {
if (expectedFilename !== filename && checkPending) {
throw new Error("File requested out of order. Expected '" + expectedFilename + "' but got '" + filename + "'");
}
++state.pendingFileIndex;
@@ -515,13 +515,13 @@ if (process.argv.length > 2) {
handleParseCommand({
command: "parse",
filename: sf.fileName,
});
}, false);
}
} else if (pathlib.extname(argument) === ".ts" || pathlib.extname(argument) === ".tsx") {
handleParseCommand({
command: "parse",
filename: argument,
});
}, false);
} else {
console.error("Unrecognized file or flag: " + argument);
}

View File

@@ -249,6 +249,7 @@ public class ExprKinds {
@Override
public Integer visit(MetaProperty nd, Void c) {
if (nd.getMeta().getName().equals("new")) return 82; // @newtargetexpr
if (nd.getMeta().getName().equals("import")) return 115; // @importmetaexpr
return 93; // @functionsentexpr
}

View File

@@ -1584,10 +1584,12 @@ public class TypeScriptASTConverter {
private Node convertMetaProperty(JsonObject node, SourceLocation loc) throws ParseError {
Position metaStart = loc.getStart();
String keywordKind = syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString();
String identifier = keywordKind.equals("ImportKeyword") ? "import" : "new";
Position metaEnd =
new Position(metaStart.getLine(), metaStart.getColumn() + 3, metaStart.getOffset() + 3);
SourceLocation metaLoc = new SourceLocation("new", metaStart, metaEnd);
Identifier meta = new Identifier(metaLoc, "new");
new Position(metaStart.getLine(), metaStart.getColumn() + identifier.length(), metaStart.getOffset() + identifier.length());
SourceLocation metaLoc = new SourceLocation(identifier, metaStart, metaEnd);
Identifier meta = new Identifier(metaLoc, identifier);
return new MetaProperty(loc, meta, convertChild(node, "name"));
}

View File

@@ -641,4 +641,4 @@ class OriginalExportDeclaration extends ExportDeclaration {
result = this.(ExportDefaultDeclaration).getSourceNode(name) or
result = this.(ExportNamedDeclaration).getSourceNode(name)
}
}
}

View File

@@ -2645,3 +2645,15 @@ class OptionalChainRoot extends ChainElem {
*/
OptionalUse getAnOptionalUse() { result = optionalUse }
}
/**
* An `import.meta` expression.
*
* Example:
* ```js
* let url = import.meta.url;
* ```
*/
class ImportMetaExpr extends @importmetaexpr, Expr {
override predicate isImpure() { none() }
}

View File

@@ -1415,6 +1415,8 @@ module DataFlow {
or
e instanceof NewTargetExpr
or
e instanceof ImportMetaExpr
or
e instanceof FunctionBindExpr
or
e instanceof TaggedTemplateExpr

View File

@@ -235,7 +235,8 @@ module SourceNode {
astNode instanceof FunctionSentExpr or
astNode instanceof FunctionBindExpr or
astNode instanceof DynamicImportExpr or
astNode instanceof ImportSpecifier
astNode instanceof ImportSpecifier or
astNode instanceof ImportMetaExpr
)
or
DataFlow::parameterNode(this, _)

View File

@@ -349,6 +349,7 @@ case @expr.kind of
| 112 = @e4x_xml_static_qualident
| 113 = @e4x_xml_dynamic_qualident
| 114 = @e4x_xml_dotdotexpr
| 115 = @importmetaexpr
;
@varaccess = @proper_varaccess | @export_varaccess;
@@ -1169,4 +1170,4 @@ extraction_data(
varchar(900) cacheFile: string ref,
boolean fromCache: boolean ref,
int length: int ref
)
)

View File

@@ -514,6 +514,10 @@
<v>1</v>
</e>
<e>
<k>@importmetaexpr</k>
<v>1</v>
</e>
<e>
<k>@namedimportspecifier</k>
<v>4</v>
</e>

View File

@@ -0,0 +1 @@
| tst.ts:7:9:7:19 | import.meta |

View File

@@ -0,0 +1,5 @@
import javascript
from Expr prop
where prop instanceof ImportMetaExpr
select prop

View File

@@ -0,0 +1,3 @@
{
}

View File

@@ -0,0 +1,7 @@
interface ImportMeta {
wellKnownProperty: { a: number, b: string, c: boolean };
}
var a = import.meta.wellKnownProperty.a;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: add import.meta expressions to the database database
compatibility: backwards