TS: Support type-only import/export

This commit is contained in:
Asger Feldthaus
2020-02-07 16:25:49 +00:00
parent 0351f0b775
commit 8d58aad0f2
11 changed files with 138 additions and 11 deletions

View File

@@ -125,7 +125,7 @@ class ASTNode extends @ast_node, Locatable {
* Holds if this is part of an ambient declaration or type annotation in a TypeScript file.
*
* A declaration is ambient if it occurs under a `declare` modifier or is
* an interface declaration, type alias, or type annotation.
* an interface declaration, type alias, type annotation, or type-only import/export declaration.
*
* The TypeScript compiler emits no code for ambient declarations, but they
* can affect name resolution and type checking at compile-time.

View File

@@ -76,6 +76,16 @@ class ImportDeclaration extends Stmt, Import, @importdeclaration {
// `import { createServer } from 'http'`
result = DataFlow::destructuredModuleImportNode(this)
}
/** Holds if this is declared with the `type` keyword, so it only imports types. */
predicate isTypeOnly() {
hasTypeKeyword(this)
}
override predicate isAmbient() {
Stmt.super.isAmbient() or
isTypeOnly()
}
}
/** A literal path expression appearing in an `import` declaration. */
@@ -256,6 +266,16 @@ abstract class ExportDeclaration extends Stmt, @exportdeclaration {
* to module `a` or possibly to some other module from which `a` re-exports.
*/
abstract DataFlow::Node getSourceNode(string name);
/** Holds if is declared with the `type` keyword, so only types are exported. */
predicate isTypeOnly() {
hasTypeKeyword(this)
}
override predicate isAmbient() {
Stmt.super.isAmbient() or
isTypeOnly()
}
}
/**
@@ -413,6 +433,18 @@ class ExportNamedDeclaration extends ExportDeclaration, @exportnameddeclaration
}
}
/**
* An export declaration with the `type` modifier.
*/
private class TypeOnlyExportDeclaration extends ExportNamedDeclaration {
TypeOnlyExportDeclaration() { isTypeOnly() }
override predicate exportsAs(LexicalName v, string name) {
super.exportsAs(v, name) and
not v instanceof Variable
}
}
/**
* An export specifier in an export declaration.
*

View File

@@ -385,6 +385,8 @@ case @expr.kind of
@exportspecifier = @namedexportspecifier | @exportdefaultspecifier | @exportnamespacespecifier;
@import_or_export_declaration = @importdeclaration | @exportdeclaration;
@typeassertion = @astypeassertion | @prefixtypeassertion;
@classdefinition = @classdeclstmt | @classexpr;
@@ -518,6 +520,7 @@ hasPublicKeyword (int id: @property ref);
hasPrivateKeyword (int id: @property ref);
hasProtectedKeyword (int id: @property ref);
hasReadonlyKeyword (int id: @property ref);
hasTypeKeyword (int id: @import_or_export_declaration ref);
isOptionalMember (int id: @property ref);
hasDefiniteAssignmentAssertion (int id: @field_or_vardeclarator ref);
isOptionalParameterDeclaration (unique int parameter: @pattern ref);