зеркало из https://github.com/github/codeql.git
Merge pull request #2237 from asger-semmle/typescript3.7-rc
TS: Add support for TypeScript 3.7
This commit is contained in:
Коммит
770a4703c9
|
@ -12,7 +12,7 @@
|
|||
|
||||
* 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.
|
||||
* TypeScript 3.6 and 3.7 features are now supported.
|
||||
|
||||
* Automatic classification of generated files has been improved, in particular files generated by Doxygen are now recognized.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "typescript-parser-wrapper",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"typescript": "3.6.3"
|
||||
"typescript": "^3.7.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --project tsconfig.json",
|
||||
|
|
|
@ -126,7 +126,7 @@ function checkCycle(root: any) {
|
|||
function isBlacklistedProperty(k: string) {
|
||||
return k === "parent" || k === "pos" || k === "end"
|
||||
|| k === "symbol" || k === "localSymbol"
|
||||
|| k === "flowNode" || k === "returnFlowNode"
|
||||
|| k === "flowNode" || k === "returnFlowNode" || k === "endFlowNode"
|
||||
|| k === "nextContainer" || k === "locals"
|
||||
|| k === "bindDiagnostics" || k === "bindSuggestionDiagnostics";
|
||||
}
|
||||
|
|
|
@ -597,7 +597,7 @@ export class TypeTable {
|
|||
let tupleType = tupleReference.target;
|
||||
let minLength = tupleType.minLength != null
|
||||
? tupleType.minLength
|
||||
: tupleReference.typeArguments.length;
|
||||
: this.typeChecker.getTypeArguments(tupleReference).length;
|
||||
let hasRestElement = tupleType.hasRestElement ? 't' : 'f';
|
||||
let prefix = `tuple;${minLength};${hasRestElement}`;
|
||||
return this.makeTypeStringVectorFromTypeReferenceArguments(prefix, type);
|
||||
|
@ -714,11 +714,12 @@ export class TypeTable {
|
|||
// There can be an extra type argument at the end, denoting an explicit 'this' type argument.
|
||||
// We discard the extra argument in our model.
|
||||
let target = type.target;
|
||||
if (type.typeArguments == null) return tag;
|
||||
let typeArguments = this.typeChecker.getTypeArguments(type);
|
||||
if (typeArguments == null) return tag;
|
||||
if (target.typeParameters != null) {
|
||||
return this.makeTypeStringVector(tag, type.typeArguments, target.typeParameters.length);
|
||||
return this.makeTypeStringVector(tag, typeArguments, target.typeParameters.length);
|
||||
} else {
|
||||
return this.makeTypeStringVector(tag, type.typeArguments);
|
||||
return this.makeTypeStringVector(tag, typeArguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -992,7 +993,7 @@ export class TypeTable {
|
|||
* `T` is the type parameter declared on the `Promise` interface.
|
||||
*/
|
||||
private getSelfType(type: ts.Type): ts.TypeReference {
|
||||
if (isTypeReference(type) && type.typeArguments != null && type.typeArguments.length > 0) {
|
||||
if (isTypeReference(type) && this.typeChecker.getTypeArguments(type).length > 0) {
|
||||
return type.target;
|
||||
}
|
||||
return null;
|
||||
|
@ -1181,8 +1182,9 @@ export class TypeTable {
|
|||
if (isTypeReference(type)) {
|
||||
// Note that this case also handles tuple types, since a tuple type is represented as
|
||||
// a reference to a synthetic generic interface.
|
||||
if (type.typeArguments != null) {
|
||||
type.typeArguments.forEach(callback);
|
||||
let typeArguments = this.typeChecker.getTypeArguments(type);
|
||||
if (typeArguments != null) {
|
||||
typeArguments.forEach(callback);
|
||||
}
|
||||
} else if (type.flags & ts.TypeFlags.UnionOrIntersection) {
|
||||
(type as ts.UnionOrIntersectionType).types.forEach(callback);
|
||||
|
|
|
@ -225,9 +225,9 @@ tsutils@^2.12.1:
|
|||
dependencies:
|
||||
tslib "^1.8.1"
|
||||
|
||||
typescript@3.6.3:
|
||||
version "3.6.3"
|
||||
resolved "typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
|
||||
typescript@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "typescript-3.7.2.tgz"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.semmle.js.ast.AssignmentExpression;
|
|||
import com.semmle.js.ast.BlockStatement;
|
||||
import com.semmle.js.ast.CallExpression;
|
||||
import com.semmle.js.ast.CatchClause;
|
||||
import com.semmle.js.ast.Chainable;
|
||||
import com.semmle.js.ast.ClassExpression;
|
||||
import com.semmle.js.ast.ComprehensionBlock;
|
||||
import com.semmle.js.ast.ComprehensionExpression;
|
||||
|
@ -470,7 +471,8 @@ public class CustomParser extends FlowParser {
|
|||
|
||||
Expression property = this.parsePropertyIdentifierOrIdentifier();
|
||||
MemberExpression node =
|
||||
new MemberExpression(start, base, property, false, false, isOnOptionalChain(false, base));
|
||||
new MemberExpression(
|
||||
start, base, property, false, false, Chainable.isOnOptionalChain(false, base));
|
||||
return Pair.make(this.finishNode(node), true);
|
||||
} else if (this.eat(doubleDot)) {
|
||||
SourceLocation start = new SourceLocation(startLoc);
|
||||
|
|
|
@ -1520,10 +1520,6 @@ public class Parser {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean isOnOptionalChain(boolean optional, Expression base) {
|
||||
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single subscript {@code s}; if more subscripts could follow, return {@code Pair.make(s,
|
||||
* true}, otherwise return {@code Pair.make(s, false)}.
|
||||
|
@ -1544,7 +1540,7 @@ public class Parser {
|
|||
this.parseExpression(false, null),
|
||||
true,
|
||||
optional,
|
||||
isOnOptionalChain(optional, base));
|
||||
Chainable.isOnOptionalChain(optional, base));
|
||||
this.expect(TokenType.bracketR);
|
||||
return Pair.make(this.finishNode(node), true);
|
||||
} else if (!noCalls && this.eat(TokenType.parenL)) {
|
||||
|
@ -1572,10 +1568,10 @@ public class Parser {
|
|||
new ArrayList<>(),
|
||||
exprList,
|
||||
optional,
|
||||
isOnOptionalChain(optional, base));
|
||||
Chainable.isOnOptionalChain(optional, base));
|
||||
return Pair.make(this.finishNode(node), true);
|
||||
} else if (this.type == TokenType.backQuote) {
|
||||
if (isOnOptionalChain(optional, base)) {
|
||||
if (Chainable.isOnOptionalChain(optional, base)) {
|
||||
this.raise(base, "An optional chain may not be used in a tagged template expression.");
|
||||
}
|
||||
TaggedTemplateExpression node =
|
||||
|
@ -1590,7 +1586,7 @@ public class Parser {
|
|||
this.parseIdent(true),
|
||||
false,
|
||||
optional,
|
||||
isOnOptionalChain(optional, base));
|
||||
Chainable.isOnOptionalChain(optional, base));
|
||||
return Pair.make(this.finishNode(node), true);
|
||||
} else {
|
||||
return Pair.make(base, false);
|
||||
|
@ -1832,7 +1828,7 @@ public class Parser {
|
|||
Expression callee =
|
||||
this.parseSubscripts(this.parseExprAtom(null), innerStartPos, innerStartLoc, true);
|
||||
|
||||
if (isOnOptionalChain(false, callee))
|
||||
if (Chainable.isOnOptionalChain(false, callee))
|
||||
this.raise(callee, "An optional chain may not be used in a `new` expression.");
|
||||
|
||||
return parseNewArguments(startLoc, callee);
|
||||
|
@ -2314,7 +2310,7 @@ public class Parser {
|
|||
}
|
||||
|
||||
if (node instanceof MemberExpression) {
|
||||
if (isOnOptionalChain(false, (MemberExpression) node))
|
||||
if (Chainable.isOnOptionalChain(false, (MemberExpression) node))
|
||||
this.raise(node, "Invalid left-hand side in assignment");
|
||||
if (!isBinding) return node;
|
||||
}
|
||||
|
|
|
@ -7,4 +7,14 @@ public interface Chainable {
|
|||
|
||||
/** Is this on an optional chain? */
|
||||
abstract boolean isOnOptionalChain();
|
||||
|
||||
/**
|
||||
* Returns true if a chainable node is on an optional chain.
|
||||
*
|
||||
* @param optional true if the node in question is itself optional (has the ?. token)
|
||||
* @param base the calle or base of the optional access
|
||||
*/
|
||||
public static boolean isOnOptionalChain(boolean optional, Expression base) {
|
||||
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@ public class DeclarationFlags {
|
|||
public static final int protected_ = 1 << 6;
|
||||
public static final int optional = 1 << 7;
|
||||
public static final int definiteAssignmentAssertion = 1 << 8;
|
||||
public static final int declareKeyword = 1 << 9;
|
||||
|
||||
public static final int none = 0;
|
||||
public static final int numberOfFlags = 9;
|
||||
public static final int numberOfFlags = 10;
|
||||
|
||||
public static final List<String> names =
|
||||
Arrays.asList(
|
||||
|
@ -31,7 +32,8 @@ public class DeclarationFlags {
|
|||
"private",
|
||||
"protected",
|
||||
"optional",
|
||||
"definiteAssignmentAssertion");
|
||||
"definiteAssignmentAssertion",
|
||||
"declare");
|
||||
|
||||
public static final List<String> relationNames =
|
||||
Arrays.asList(
|
||||
|
@ -43,7 +45,8 @@ public class DeclarationFlags {
|
|||
"hasPrivateKeyword",
|
||||
"hasProtectedKeyword",
|
||||
"isOptionalMember",
|
||||
"hasDefiniteAssignmentAssertion");
|
||||
"hasDefiniteAssignmentAssertion",
|
||||
"hasDeclareKeyword");
|
||||
|
||||
public static boolean isComputed(int flags) {
|
||||
return (flags & computed) != 0;
|
||||
|
@ -81,6 +84,10 @@ public class DeclarationFlags {
|
|||
return (flags & definiteAssignmentAssertion) != 0;
|
||||
}
|
||||
|
||||
public static boolean hasDeclareKeyword(int flags) {
|
||||
return (flags & declareKeyword) != 0;
|
||||
}
|
||||
|
||||
/** Returns a mask with the computed bit set to the value of <tt>enable</tt>. */
|
||||
public static int getComputed(boolean enable) {
|
||||
return enable ? computed : 0;
|
||||
|
@ -128,6 +135,11 @@ public class DeclarationFlags {
|
|||
return enable ? definiteAssignmentAssertion : 0;
|
||||
}
|
||||
|
||||
/** Returns a mask with the declare keyword bit set to the value of <tt>enable</tt>. */
|
||||
public static int getDeclareKeyword(boolean enable) {
|
||||
return enable ? declareKeyword : 0;
|
||||
}
|
||||
|
||||
/** Returns true if the <tt>n</tt>th bit is set in <tt>flags</tt>. */
|
||||
public static boolean hasNthFlag(int flags, int n) {
|
||||
return (flags & (1 << n)) != 0;
|
||||
|
|
|
@ -34,13 +34,13 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.NonNullAssertion;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
|
@ -634,7 +634,7 @@ public class DefaultVisitor<C, R> implements Visitor<C, R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public R visit(IsTypeExpr nd, C c) {
|
||||
public R visit(PredicateTypeExpr nd, C c) {
|
||||
return visit((TypeExpression) nd, c);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,11 @@ public abstract class MemberDefinition<V extends Expression> extends Node {
|
|||
return DeclarationFlags.isReadonly(flags);
|
||||
}
|
||||
|
||||
/** Returns true if this has the <tt>declare</tt> modifier. */
|
||||
public boolean hasDeclareKeyword() {
|
||||
return DeclarationFlags.hasDeclareKeyword(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expression denoting the name of the member, or {@code null} if this is a
|
||||
* call/construct signature.
|
||||
|
|
|
@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.NonNullAssertion;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
|
@ -717,8 +717,12 @@ public class NodeCopier implements Visitor<Void, INode> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public INode visit(IsTypeExpr nd, Void c) {
|
||||
return new IsTypeExpr(visit(nd.getLoc()), copy(nd.getLeft()), copy(nd.getRight()));
|
||||
public INode visit(PredicateTypeExpr nd, Void c) {
|
||||
return new PredicateTypeExpr(
|
||||
visit(nd.getLoc()),
|
||||
copy(nd.getExpression()),
|
||||
copy(nd.getTypeExpr()),
|
||||
nd.hasAssertsKeyword());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.NonNullAssertion;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
|
@ -256,7 +256,7 @@ public interface Visitor<C, R> {
|
|||
|
||||
public R visit(TypeofTypeExpr nd, C c);
|
||||
|
||||
public R visit(IsTypeExpr nd, C c);
|
||||
public R visit(PredicateTypeExpr nd, C c);
|
||||
|
||||
public R visit(InterfaceTypeExpr nd, C c);
|
||||
|
||||
|
|
|
@ -125,13 +125,13 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.NonNullAssertion;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
|
@ -1410,6 +1410,10 @@ public class ASTExtractor {
|
|||
}
|
||||
}
|
||||
|
||||
if (nd.hasDeclareKeyword()) {
|
||||
trapwriter.addTuple("hasDeclareKeyword", methkey);
|
||||
}
|
||||
|
||||
return methkey;
|
||||
}
|
||||
|
||||
|
@ -1707,10 +1711,13 @@ public class ASTExtractor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Label visit(IsTypeExpr nd, Context c) {
|
||||
public Label visit(PredicateTypeExpr nd, Context c) {
|
||||
Label key = super.visit(nd, c);
|
||||
visit(nd.getLeft(), key, 0, IdContext.varInTypeBind);
|
||||
visit(nd.getRight(), key, 1, IdContext.typeBind);
|
||||
visit(nd.getExpression(), key, 0, IdContext.varInTypeBind);
|
||||
visit(nd.getTypeExpr(), key, 1, IdContext.typeBind);
|
||||
if (nd.hasAssertsKeyword()) {
|
||||
trapwriter.addTuple("hasAssertsKeyword", key);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
import com.semmle.ts.ast.UnionTypeExpr;
|
||||
|
@ -660,8 +660,8 @@ public class ScopeManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Void visit(IsTypeExpr nd, Void c) {
|
||||
return nd.getRight().accept(this, c);
|
||||
public Void visit(PredicateTypeExpr nd, Void c) {
|
||||
return nd.getTypeExpr().accept(this, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,11 +16,11 @@ import com.semmle.ts.ast.IndexedAccessTypeExpr;
|
|||
import com.semmle.ts.ast.InferTypeExpr;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeParameter;
|
||||
|
@ -159,7 +159,7 @@ public class TypeExprKinds {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer visit(IsTypeExpr nd, Void c) {
|
||||
public Integer visit(PredicateTypeExpr nd, Void c) {
|
||||
return isTypeExpr;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.semmle.js.ast.BlockStatement;
|
|||
import com.semmle.js.ast.BreakStatement;
|
||||
import com.semmle.js.ast.CallExpression;
|
||||
import com.semmle.js.ast.CatchClause;
|
||||
import com.semmle.js.ast.Chainable;
|
||||
import com.semmle.js.ast.ClassBody;
|
||||
import com.semmle.js.ast.ClassDeclaration;
|
||||
import com.semmle.js.ast.ClassExpression;
|
||||
|
@ -126,13 +127,13 @@ import com.semmle.ts.ast.InferTypeExpr;
|
|||
import com.semmle.ts.ast.InterfaceDeclaration;
|
||||
import com.semmle.ts.ast.InterfaceTypeExpr;
|
||||
import com.semmle.ts.ast.IntersectionTypeExpr;
|
||||
import com.semmle.ts.ast.IsTypeExpr;
|
||||
import com.semmle.ts.ast.KeywordTypeExpr;
|
||||
import com.semmle.ts.ast.MappedTypeExpr;
|
||||
import com.semmle.ts.ast.NamespaceDeclaration;
|
||||
import com.semmle.ts.ast.NonNullAssertion;
|
||||
import com.semmle.ts.ast.OptionalTypeExpr;
|
||||
import com.semmle.ts.ast.ParenthesizedTypeExpr;
|
||||
import com.semmle.ts.ast.PredicateTypeExpr;
|
||||
import com.semmle.ts.ast.RestTypeExpr;
|
||||
import com.semmle.ts.ast.TupleTypeExpr;
|
||||
import com.semmle.ts.ast.TypeAliasDeclaration;
|
||||
|
@ -877,7 +878,10 @@ public class TypeScriptASTConverter {
|
|||
}
|
||||
Expression callee = convertChild(node, "expression");
|
||||
List<ITypeExpression> typeArguments = convertChildrenAsTypes(node, "typeArguments");
|
||||
CallExpression call = new CallExpression(loc, callee, typeArguments, arguments, false, false);
|
||||
boolean optional = node.has("questionDotToken");
|
||||
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, callee);
|
||||
CallExpression call =
|
||||
new CallExpression(loc, callee, typeArguments, arguments, optional, onOptionalChain);
|
||||
attachResolvedSignature(call, node);
|
||||
return call;
|
||||
}
|
||||
|
@ -1108,7 +1112,9 @@ public class TypeScriptASTConverter {
|
|||
throws ParseError {
|
||||
Expression object = convertChild(node, "expression");
|
||||
Expression property = convertChild(node, "argumentExpression");
|
||||
return new MemberExpression(loc, object, property, true, false, false);
|
||||
boolean optional = node.has("questionDotToken");
|
||||
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, object);
|
||||
return new MemberExpression(loc, object, property, true, optional, onOptionalChain);
|
||||
}
|
||||
|
||||
private Node convertEmptyStatement(SourceLocation loc) {
|
||||
|
@ -1584,10 +1590,14 @@ 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 keywordKind =
|
||||
syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString();
|
||||
String identifier = keywordKind.equals("ImportKeyword") ? "import" : "new";
|
||||
Position metaEnd =
|
||||
new Position(metaStart.getLine(), metaStart.getColumn() + identifier.length(), metaStart.getOffset() + identifier.length());
|
||||
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"));
|
||||
|
@ -1967,8 +1977,11 @@ public class TypeScriptASTConverter {
|
|||
|
||||
private Node convertPropertyAccessExpression(JsonObject node, SourceLocation loc)
|
||||
throws ParseError {
|
||||
Expression base = convertChild(node, "expression");
|
||||
boolean optional = node.has("questionDotToken");
|
||||
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, base);
|
||||
return new MemberExpression(
|
||||
loc, convertChild(node, "expression"), convertChild(node, "name"), false, false, false);
|
||||
loc, base, convertChild(node, "name"), false, optional, onOptionalChain);
|
||||
}
|
||||
|
||||
private Node convertPropertyAssignment(JsonObject node, SourceLocation loc) throws ParseError {
|
||||
|
@ -1996,6 +2009,9 @@ public class TypeScriptASTConverter {
|
|||
if (node.get("exclamationToken") != null) {
|
||||
flags |= DeclarationFlags.definiteAssignmentAssertion;
|
||||
}
|
||||
if (hasModifier(node, "DeclareKeyword")) {
|
||||
flags |= DeclarationFlags.declareKeyword;
|
||||
}
|
||||
FieldDefinition fieldDefinition =
|
||||
new FieldDefinition(
|
||||
loc,
|
||||
|
@ -2186,8 +2202,11 @@ public class TypeScriptASTConverter {
|
|||
}
|
||||
|
||||
private Node convertTypePredicate(JsonObject node, SourceLocation loc) throws ParseError {
|
||||
return new IsTypeExpr(
|
||||
loc, convertChildAsType(node, "parameterName"), convertChildAsType(node, "type"));
|
||||
return new PredicateTypeExpr(
|
||||
loc,
|
||||
convertChildAsType(node, "parameterName"),
|
||||
convertChildAsType(node, "type"),
|
||||
node.has("assertsModifier"));
|
||||
}
|
||||
|
||||
private Node convertTypeReference(JsonObject node, SourceLocation loc) throws ParseError {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package com.semmle.ts.ast;
|
||||
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
import com.semmle.js.ast.Visitor;
|
||||
|
||||
/**
|
||||
* A type of form <tt>E is T</tt> where <tt>E</tt> is a parameter name or <tt>this</tt> and
|
||||
* <tt>T</tt> is a type.
|
||||
*/
|
||||
public class IsTypeExpr extends TypeExpression {
|
||||
private final ITypeExpression left; // Always Identifier or KeywordTypeExpr (in case of 'this')
|
||||
private final ITypeExpression right;
|
||||
|
||||
public IsTypeExpr(SourceLocation loc, ITypeExpression left, ITypeExpression right) {
|
||||
super("IsTypeExpr", loc);
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public ITypeExpression getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ITypeExpression getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C, R> R accept(Visitor<C, R> v, C c) {
|
||||
return v.visit(this, c);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.semmle.ts.ast;
|
||||
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
import com.semmle.js.ast.Visitor;
|
||||
|
||||
/**
|
||||
* A type of form <tt>E is T</tt>, <tt>asserts E is T</tt> or <tt>asserts E</tt> where <tt>E</tt> is
|
||||
* a parameter name or <tt>this</tt> and <tt>T</tt> is a type.
|
||||
*/
|
||||
public class PredicateTypeExpr extends TypeExpression {
|
||||
private final ITypeExpression expression;
|
||||
private final ITypeExpression type;
|
||||
private final boolean hasAssertsKeyword;
|
||||
|
||||
public PredicateTypeExpr(
|
||||
SourceLocation loc,
|
||||
ITypeExpression expression,
|
||||
ITypeExpression type,
|
||||
boolean hasAssertsKeyword) {
|
||||
super("PredicateTypeExpr", loc);
|
||||
this.expression = expression;
|
||||
this.type = type;
|
||||
this.hasAssertsKeyword = hasAssertsKeyword;
|
||||
}
|
||||
|
||||
/** Returns the <tt>E</tt> in <tt>E is T</tt>. */
|
||||
public ITypeExpression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
/** Returns the <tt>T</tt> in <tt>E is T</tt>. */
|
||||
public ITypeExpression getTypeExpr() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean hasAssertsKeyword() {
|
||||
return hasAssertsKeyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C, R> R accept(Visitor<C, R> v, C c) {
|
||||
return v.visit(this, c);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
base?.x.y;
|
||||
base?.(x).y;
|
||||
base?.[z].y;
|
|
@ -0,0 +1,303 @@
|
|||
#10000=@"/optionalChaining.ts;sourcefile"
|
||||
files(#10000,"/optionalChaining.ts","optionalChaining","ts",0)
|
||||
#10001=@"/;folder"
|
||||
folders(#10001,"/","")
|
||||
containerparent(#10001,#10000)
|
||||
#10002=@"loc,{#10000},0,0,0,0"
|
||||
locations_default(#10002,#10000,0,0,0,0)
|
||||
hasLocation(#10000,#10002)
|
||||
#20000=@"global_scope"
|
||||
scopes(#20000,0)
|
||||
#20001=@"script;{#10000},1,1"
|
||||
#20002=*
|
||||
lines(#20002,#20001,"base?.x.y;","
|
||||
")
|
||||
#20003=@"loc,{#10000},1,1,1,10"
|
||||
locations_default(#20003,#10000,1,1,1,10)
|
||||
hasLocation(#20002,#20003)
|
||||
#20004=*
|
||||
lines(#20004,#20001,"base?.(x).y;","
|
||||
")
|
||||
#20005=@"loc,{#10000},2,1,2,12"
|
||||
locations_default(#20005,#10000,2,1,2,12)
|
||||
hasLocation(#20004,#20005)
|
||||
#20006=*
|
||||
lines(#20006,#20001,"base?.[z].y;","
|
||||
")
|
||||
#20007=@"loc,{#10000},3,1,3,12"
|
||||
locations_default(#20007,#10000,3,1,3,12)
|
||||
hasLocation(#20006,#20007)
|
||||
numlines(#20001,3,3,0)
|
||||
#20008=*
|
||||
tokeninfo(#20008,6,#20001,0,"base")
|
||||
#20009=@"loc,{#10000},1,1,1,4"
|
||||
locations_default(#20009,#10000,1,1,1,4)
|
||||
hasLocation(#20008,#20009)
|
||||
#20010=*
|
||||
tokeninfo(#20010,8,#20001,1,"?.")
|
||||
#20011=@"loc,{#10000},1,5,1,6"
|
||||
locations_default(#20011,#10000,1,5,1,6)
|
||||
hasLocation(#20010,#20011)
|
||||
#20012=*
|
||||
tokeninfo(#20012,6,#20001,2,"x")
|
||||
#20013=@"loc,{#10000},1,7,1,7"
|
||||
locations_default(#20013,#10000,1,7,1,7)
|
||||
hasLocation(#20012,#20013)
|
||||
#20014=*
|
||||
tokeninfo(#20014,8,#20001,3,".")
|
||||
#20015=@"loc,{#10000},1,8,1,8"
|
||||
locations_default(#20015,#10000,1,8,1,8)
|
||||
hasLocation(#20014,#20015)
|
||||
#20016=*
|
||||
tokeninfo(#20016,6,#20001,4,"y")
|
||||
#20017=@"loc,{#10000},1,9,1,9"
|
||||
locations_default(#20017,#10000,1,9,1,9)
|
||||
hasLocation(#20016,#20017)
|
||||
#20018=*
|
||||
tokeninfo(#20018,8,#20001,5,";")
|
||||
#20019=@"loc,{#10000},1,10,1,10"
|
||||
locations_default(#20019,#10000,1,10,1,10)
|
||||
hasLocation(#20018,#20019)
|
||||
#20020=*
|
||||
tokeninfo(#20020,6,#20001,6,"base")
|
||||
#20021=@"loc,{#10000},2,1,2,4"
|
||||
locations_default(#20021,#10000,2,1,2,4)
|
||||
hasLocation(#20020,#20021)
|
||||
#20022=*
|
||||
tokeninfo(#20022,8,#20001,7,"?.")
|
||||
#20023=@"loc,{#10000},2,5,2,6"
|
||||
locations_default(#20023,#10000,2,5,2,6)
|
||||
hasLocation(#20022,#20023)
|
||||
#20024=*
|
||||
tokeninfo(#20024,8,#20001,8,"(")
|
||||
#20025=@"loc,{#10000},2,7,2,7"
|
||||
locations_default(#20025,#10000,2,7,2,7)
|
||||
hasLocation(#20024,#20025)
|
||||
#20026=*
|
||||
tokeninfo(#20026,6,#20001,9,"x")
|
||||
#20027=@"loc,{#10000},2,8,2,8"
|
||||
locations_default(#20027,#10000,2,8,2,8)
|
||||
hasLocation(#20026,#20027)
|
||||
#20028=*
|
||||
tokeninfo(#20028,8,#20001,10,")")
|
||||
#20029=@"loc,{#10000},2,9,2,9"
|
||||
locations_default(#20029,#10000,2,9,2,9)
|
||||
hasLocation(#20028,#20029)
|
||||
#20030=*
|
||||
tokeninfo(#20030,8,#20001,11,".")
|
||||
#20031=@"loc,{#10000},2,10,2,10"
|
||||
locations_default(#20031,#10000,2,10,2,10)
|
||||
hasLocation(#20030,#20031)
|
||||
#20032=*
|
||||
tokeninfo(#20032,6,#20001,12,"y")
|
||||
#20033=@"loc,{#10000},2,11,2,11"
|
||||
locations_default(#20033,#10000,2,11,2,11)
|
||||
hasLocation(#20032,#20033)
|
||||
#20034=*
|
||||
tokeninfo(#20034,8,#20001,13,";")
|
||||
#20035=@"loc,{#10000},2,12,2,12"
|
||||
locations_default(#20035,#10000,2,12,2,12)
|
||||
hasLocation(#20034,#20035)
|
||||
#20036=*
|
||||
tokeninfo(#20036,6,#20001,14,"base")
|
||||
#20037=@"loc,{#10000},3,1,3,4"
|
||||
locations_default(#20037,#10000,3,1,3,4)
|
||||
hasLocation(#20036,#20037)
|
||||
#20038=*
|
||||
tokeninfo(#20038,8,#20001,15,"?.")
|
||||
#20039=@"loc,{#10000},3,5,3,6"
|
||||
locations_default(#20039,#10000,3,5,3,6)
|
||||
hasLocation(#20038,#20039)
|
||||
#20040=*
|
||||
tokeninfo(#20040,8,#20001,16,"[")
|
||||
#20041=@"loc,{#10000},3,7,3,7"
|
||||
locations_default(#20041,#10000,3,7,3,7)
|
||||
hasLocation(#20040,#20041)
|
||||
#20042=*
|
||||
tokeninfo(#20042,6,#20001,17,"z")
|
||||
#20043=@"loc,{#10000},3,8,3,8"
|
||||
locations_default(#20043,#10000,3,8,3,8)
|
||||
hasLocation(#20042,#20043)
|
||||
#20044=*
|
||||
tokeninfo(#20044,8,#20001,18,"]")
|
||||
#20045=@"loc,{#10000},3,9,3,9"
|
||||
locations_default(#20045,#10000,3,9,3,9)
|
||||
hasLocation(#20044,#20045)
|
||||
#20046=*
|
||||
tokeninfo(#20046,8,#20001,19,".")
|
||||
#20047=@"loc,{#10000},3,10,3,10"
|
||||
locations_default(#20047,#10000,3,10,3,10)
|
||||
hasLocation(#20046,#20047)
|
||||
#20048=*
|
||||
tokeninfo(#20048,6,#20001,20,"y")
|
||||
#20049=@"loc,{#10000},3,11,3,11"
|
||||
locations_default(#20049,#10000,3,11,3,11)
|
||||
hasLocation(#20048,#20049)
|
||||
#20050=*
|
||||
tokeninfo(#20050,8,#20001,21,";")
|
||||
#20051=@"loc,{#10000},3,12,3,12"
|
||||
locations_default(#20051,#10000,3,12,3,12)
|
||||
hasLocation(#20050,#20051)
|
||||
#20052=*
|
||||
tokeninfo(#20052,0,#20001,22,"")
|
||||
#20053=@"loc,{#10000},4,1,4,0"
|
||||
locations_default(#20053,#10000,4,1,4,0)
|
||||
hasLocation(#20052,#20053)
|
||||
toplevels(#20001,0)
|
||||
#20054=@"loc,{#10000},1,1,4,0"
|
||||
locations_default(#20054,#10000,1,1,4,0)
|
||||
hasLocation(#20001,#20054)
|
||||
#20055=*
|
||||
stmts(#20055,2,#20001,0,"base?.x.y;")
|
||||
hasLocation(#20055,#20003)
|
||||
stmtContainers(#20055,#20001)
|
||||
#20056=*
|
||||
exprs(#20056,14,#20055,0,"base?.x.y")
|
||||
#20057=@"loc,{#10000},1,1,1,9"
|
||||
locations_default(#20057,#10000,1,1,1,9)
|
||||
hasLocation(#20056,#20057)
|
||||
enclosingStmt(#20056,#20055)
|
||||
exprContainers(#20056,#20001)
|
||||
#20058=*
|
||||
exprs(#20058,14,#20056,0,"base?.x")
|
||||
#20059=@"loc,{#10000},1,1,1,7"
|
||||
locations_default(#20059,#10000,1,1,1,7)
|
||||
hasLocation(#20058,#20059)
|
||||
enclosingStmt(#20058,#20055)
|
||||
exprContainers(#20058,#20001)
|
||||
#20060=*
|
||||
exprs(#20060,79,#20058,0,"base")
|
||||
hasLocation(#20060,#20009)
|
||||
enclosingStmt(#20060,#20055)
|
||||
exprContainers(#20060,#20001)
|
||||
literals("base","base",#20060)
|
||||
#20061=@"var;{base};{#20000}"
|
||||
variables(#20061,"base",#20000)
|
||||
bind(#20060,#20061)
|
||||
#20062=*
|
||||
exprs(#20062,0,#20058,1,"x")
|
||||
hasLocation(#20062,#20013)
|
||||
enclosingStmt(#20062,#20055)
|
||||
exprContainers(#20062,#20001)
|
||||
literals("x","x",#20062)
|
||||
isOptionalChaining(#20058)
|
||||
#20063=*
|
||||
exprs(#20063,0,#20056,1,"y")
|
||||
hasLocation(#20063,#20017)
|
||||
enclosingStmt(#20063,#20055)
|
||||
exprContainers(#20063,#20001)
|
||||
literals("y","y",#20063)
|
||||
#20064=*
|
||||
stmts(#20064,2,#20001,1,"base?.(x).y;")
|
||||
hasLocation(#20064,#20005)
|
||||
stmtContainers(#20064,#20001)
|
||||
#20065=*
|
||||
exprs(#20065,14,#20064,0,"base?.(x).y")
|
||||
#20066=@"loc,{#10000},2,1,2,11"
|
||||
locations_default(#20066,#10000,2,1,2,11)
|
||||
hasLocation(#20065,#20066)
|
||||
enclosingStmt(#20065,#20064)
|
||||
exprContainers(#20065,#20001)
|
||||
#20067=*
|
||||
exprs(#20067,13,#20065,0,"base?.(x)")
|
||||
#20068=@"loc,{#10000},2,1,2,9"
|
||||
locations_default(#20068,#10000,2,1,2,9)
|
||||
hasLocation(#20067,#20068)
|
||||
enclosingStmt(#20067,#20064)
|
||||
exprContainers(#20067,#20001)
|
||||
#20069=*
|
||||
exprs(#20069,79,#20067,-1,"base")
|
||||
hasLocation(#20069,#20021)
|
||||
enclosingStmt(#20069,#20064)
|
||||
exprContainers(#20069,#20001)
|
||||
literals("base","base",#20069)
|
||||
bind(#20069,#20061)
|
||||
#20070=*
|
||||
exprs(#20070,79,#20067,0,"x")
|
||||
hasLocation(#20070,#20027)
|
||||
enclosingStmt(#20070,#20064)
|
||||
exprContainers(#20070,#20001)
|
||||
literals("x","x",#20070)
|
||||
#20071=@"var;{x};{#20000}"
|
||||
variables(#20071,"x",#20000)
|
||||
bind(#20070,#20071)
|
||||
isOptionalChaining(#20067)
|
||||
#20072=*
|
||||
exprs(#20072,0,#20065,1,"y")
|
||||
hasLocation(#20072,#20033)
|
||||
enclosingStmt(#20072,#20064)
|
||||
exprContainers(#20072,#20001)
|
||||
literals("y","y",#20072)
|
||||
#20073=*
|
||||
stmts(#20073,2,#20001,2,"base?.[z].y;")
|
||||
hasLocation(#20073,#20007)
|
||||
stmtContainers(#20073,#20001)
|
||||
#20074=*
|
||||
exprs(#20074,14,#20073,0,"base?.[z].y")
|
||||
#20075=@"loc,{#10000},3,1,3,11"
|
||||
locations_default(#20075,#10000,3,1,3,11)
|
||||
hasLocation(#20074,#20075)
|
||||
enclosingStmt(#20074,#20073)
|
||||
exprContainers(#20074,#20001)
|
||||
#20076=*
|
||||
exprs(#20076,15,#20074,0,"base?.[z]")
|
||||
#20077=@"loc,{#10000},3,1,3,9"
|
||||
locations_default(#20077,#10000,3,1,3,9)
|
||||
hasLocation(#20076,#20077)
|
||||
enclosingStmt(#20076,#20073)
|
||||
exprContainers(#20076,#20001)
|
||||
#20078=*
|
||||
exprs(#20078,79,#20076,0,"base")
|
||||
hasLocation(#20078,#20037)
|
||||
enclosingStmt(#20078,#20073)
|
||||
exprContainers(#20078,#20001)
|
||||
literals("base","base",#20078)
|
||||
bind(#20078,#20061)
|
||||
#20079=*
|
||||
exprs(#20079,79,#20076,1,"z")
|
||||
hasLocation(#20079,#20043)
|
||||
enclosingStmt(#20079,#20073)
|
||||
exprContainers(#20079,#20001)
|
||||
literals("z","z",#20079)
|
||||
#20080=@"var;{z};{#20000}"
|
||||
variables(#20080,"z",#20000)
|
||||
bind(#20079,#20080)
|
||||
isOptionalChaining(#20076)
|
||||
#20081=*
|
||||
exprs(#20081,0,#20074,1,"y")
|
||||
hasLocation(#20081,#20049)
|
||||
enclosingStmt(#20081,#20073)
|
||||
exprContainers(#20081,#20001)
|
||||
literals("y","y",#20081)
|
||||
#20082=*
|
||||
entry_cfg_node(#20082,#20001)
|
||||
#20083=@"loc,{#10000},1,1,1,0"
|
||||
locations_default(#20083,#10000,1,1,1,0)
|
||||
hasLocation(#20082,#20083)
|
||||
#20084=*
|
||||
exit_cfg_node(#20084,#20001)
|
||||
hasLocation(#20084,#20053)
|
||||
successor(#20073,#20078)
|
||||
successor(#20081,#20074)
|
||||
successor(#20079,#20076)
|
||||
successor(#20078,#20079)
|
||||
successor(#20076,#20081)
|
||||
successor(#20078,#20084)
|
||||
successor(#20074,#20084)
|
||||
successor(#20064,#20069)
|
||||
successor(#20072,#20065)
|
||||
successor(#20070,#20067)
|
||||
successor(#20069,#20070)
|
||||
successor(#20067,#20072)
|
||||
successor(#20069,#20073)
|
||||
successor(#20065,#20073)
|
||||
successor(#20055,#20060)
|
||||
successor(#20063,#20056)
|
||||
successor(#20062,#20058)
|
||||
successor(#20060,#20062)
|
||||
successor(#20058,#20063)
|
||||
successor(#20060,#20064)
|
||||
successor(#20056,#20064)
|
||||
successor(#20082,#20055)
|
||||
numlines(#10000,3,3,0)
|
||||
filetype(#10000,"typescript")
|
|
@ -1059,6 +1059,12 @@ class FieldDeclaration extends MemberDeclaration, @field {
|
|||
|
||||
/** Holds if this is a TypeScript field marked as definitely assigned with the `!` operator. */
|
||||
predicate hasDefiniteAssignmentAssertion() { hasDefiniteAssignmentAssertion(this) }
|
||||
|
||||
override predicate isAmbient() {
|
||||
hasDeclareKeyword(this)
|
||||
or
|
||||
getParent().isAmbient()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -914,20 +914,49 @@ class TypeofTypeExpr extends @typeoftypeexpr, TypeExpr {
|
|||
}
|
||||
|
||||
/**
|
||||
* A type of form `E is T` where `E` is a parameter name or `this`, and `T` is a type.
|
||||
* A function return type that refines the type of one of its parameters or `this`.
|
||||
*
|
||||
* This can only occur as the return type of a function type.
|
||||
* Examples:
|
||||
* ```js
|
||||
* function f(x): x is string {}
|
||||
* function f(x): asserts x is string {}
|
||||
* function f(x): asserts x {}
|
||||
* ```
|
||||
*/
|
||||
class IsTypeExpr extends @istypeexpr, TypeExpr {
|
||||
class PredicateTypeExpr extends @predicatetypeexpr, TypeExpr {
|
||||
/**
|
||||
* Gets the parameter name or `this` token `E` in `E is T`.
|
||||
*/
|
||||
VarTypeAccess getParameterName() { result = this.getChildTypeExpr(0) }
|
||||
|
||||
/**
|
||||
* Gets the type `T` in `E is T`.
|
||||
* Gets the type `T` in `E is T` or `asserts E is T`.
|
||||
*
|
||||
* Has no results for types of form `asserts E`.
|
||||
*/
|
||||
TypeExpr getPredicateType() { result = this.getChildTypeExpr(1) }
|
||||
|
||||
/**
|
||||
* Holds if this is a type of form `asserts E is T` or `asserts E`.
|
||||
*/
|
||||
predicate hasAssertsKeyword() {
|
||||
hasAssertsKeyword(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function return type of form `x is T` or `asserts x is T`.
|
||||
*
|
||||
* Examples:
|
||||
* ```js
|
||||
* function f(x): x is string {}
|
||||
* function f(x): asserts x is string {}
|
||||
* ```
|
||||
*/
|
||||
class IsTypeExpr extends PredicateTypeExpr {
|
||||
IsTypeExpr() {
|
||||
exists(getPredicateType())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -966,15 +995,16 @@ class ReadonlyTypeExpr extends @readonlytypeexpr, TypeExpr {
|
|||
*
|
||||
* This can occur as
|
||||
* - part of the operand to a `typeof` type, or
|
||||
* - as the first operand to an `is` type.
|
||||
* - as the first operand to a predicate type
|
||||
*
|
||||
* For example, it may occur as the `E` in these examples:
|
||||
* ```
|
||||
* var x : typeof E
|
||||
* function f(...) : E is T {}
|
||||
* function f(...) : asserts E {}
|
||||
* ```
|
||||
*
|
||||
* In the latter case, this may also refer to the pseudo-variable `this`.
|
||||
* In the latter two cases, this may also refer to the pseudo-variable `this`.
|
||||
*/
|
||||
class VarTypeAccess extends @vartypeaccess, TypeExpr { }
|
||||
|
||||
|
|
|
@ -200,8 +200,8 @@ case @stmt.kind of
|
|||
|
||||
isInstantiated(unique int decl: @namespacedeclaration ref);
|
||||
|
||||
@declarablestmt = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration;
|
||||
hasDeclareKeyword(unique int stmt: @declarablestmt ref);
|
||||
@declarablenode = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration | @field;
|
||||
hasDeclareKeyword(unique int stmt: @declarablenode ref);
|
||||
|
||||
isForAwaitOf(unique int forof: @forofstmt ref);
|
||||
|
||||
|
@ -559,7 +559,7 @@ case @typeexpr.kind of
|
|||
| 17 = @localvartypeaccess
|
||||
| 18 = @qualifiedvartypeaccess
|
||||
| 19 = @thisvartypeaccess
|
||||
| 20 = @istypeexpr
|
||||
| 20 = @predicatetypeexpr
|
||||
| 21 = @interfacetypeexpr
|
||||
| 22 = @typeparameter
|
||||
| 23 = @plainfunctiontypeexpr
|
||||
|
@ -637,6 +637,8 @@ case @type.kind of
|
|||
@unionorintersectiontype = @uniontype | @intersectiontype;
|
||||
@typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype;
|
||||
|
||||
hasAssertsKeyword(int node: @predicatetypeexpr ref);
|
||||
|
||||
@typed_ast_node = @expr | @typeexpr | @function;
|
||||
ast_node_type(
|
||||
unique int node: @typed_ast_node ref,
|
||||
|
|
|
@ -850,7 +850,7 @@
|
|||
<v>20</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@istypeexpr</k>
|
||||
<k>@predicatetypeexpr</k>
|
||||
<v>86</v>
|
||||
</e>
|
||||
<e>
|
||||
|
@ -7918,6 +7918,17 @@
|
|||
<dependencies/>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>hasAssertsKeyword</name>
|
||||
<cardinality>66</cardinality>
|
||||
<columnsizes>
|
||||
<e>
|
||||
<k>node</k>
|
||||
<v>66</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies/>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>isAbstractMember</name>
|
||||
<cardinality>66</cardinality>
|
||||
<columnsizes>
|
||||
|
|
|
@ -208,6 +208,8 @@
|
|||
| nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule |
|
||||
| nodeJsLib.js:3:15:3:37 | function nodeJsFoo |
|
||||
| nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo |
|
||||
| nullish-coalescing-op.ts:1:1:3:1 | function test |
|
||||
| nullish-coalescing-op.ts:1:1:3:1 | instance of function test |
|
||||
| o.js:1:1:2:0 | exports object of module o |
|
||||
| o.js:1:1:2:0 | module object of module o |
|
||||
| objlit.js:1:14:1:15 | object literal |
|
||||
|
|
|
@ -204,6 +204,8 @@
|
|||
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | esLib.js:3:8:3:24 | function foo |
|
||||
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (call) |
|
||||
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (heap) |
|
||||
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | indefinite value (call) |
|
||||
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | non-zero value |
|
||||
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | file://:0:0:0:0 | indefinite value (global) |
|
||||
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | objlit.js:1:14:1:15 | object literal |
|
||||
| objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | objlit.js:7:9:7:10 | object literal |
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
| nestedImport.js:9:1:12:1 | instance of function tst | nestedImport.js:9:1:12:1 | instance of function tst |
|
||||
| nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule | nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule |
|
||||
| nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo | nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo |
|
||||
| nullish-coalescing-op.ts:1:1:3:1 | instance of function test | nullish-coalescing-op.ts:1:1:3:1 | instance of function test |
|
||||
| objlit.js:2:9:2:21 | instance of anonymous function | objlit.js:2:9:2:21 | instance of anonymous function |
|
||||
| objlit.js:4:8:4:20 | instance of method baz | objlit.js:4:8:4:20 | instance of method baz |
|
||||
| objlit.js:10:2:12:1 | instance of anonymous function | objlit.js:10:2:12:1 | instance of anonymous function |
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
function test(x) {
|
||||
let y = x ?? 0.5;
|
||||
}
|
|
@ -113,6 +113,7 @@
|
|||
| nodeJsClient.js:2:5:2:6 | es | nodeJsClient.js:2:10:2:27 | require('./esLib') | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| nodeJsClient.js:4:5:4:6 | x1 | nodeJsClient.js:4:10:4:15 | nj.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
| objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | object |
|
||||
| objlit.js:14:5:14:6 | x1 | objlit.js:14:10:14:10 | A | boolean, class, date, function, null, number, object, regular expression,string or undefined |
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) | short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) |
|
||||
| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] | short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] |
|
||||
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] |
|
||||
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) |
|
||||
| short-circuiting.js:3:5:3:18 | x?.(o1 = null) | short-circuiting.js:3:5:3:18 | x?.(o1 = null) |
|
||||
| short-circuiting.js:7:5:7:18 | x?.[o2 = null] | short-circuiting.js:7:5:7:18 | x?.[o2 = null] |
|
||||
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:18 | x?.[o3 = null] |
|
||||
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) |
|
||||
| tst-typescript.ts:2:1:2:6 | a?.b.c | tst-typescript.ts:2:1:2:4 | a?.b |
|
||||
| tst-typescript.ts:3:1:3:6 | a.b?.c | tst-typescript.ts:3:1:3:6 | a.b?.c |
|
||||
| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:4 | a?.b |
|
||||
| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:7 | a?.b?.c |
|
||||
| tst-typescript.ts:7:1:7:7 | f?.()() | tst-typescript.ts:7:1:7:5 | f?.() |
|
||||
| tst-typescript.ts:8:1:8:7 | f()?.() | tst-typescript.ts:8:1:8:7 | f()?.() |
|
||||
| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:5 | f?.() |
|
||||
| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:9 | f?.()?.() |
|
||||
| tst-typescript.ts:12:1:12:8 | a?.m().b | tst-typescript.ts:12:1:12:4 | a?.m |
|
||||
| tst-typescript.ts:13:1:13:9 | a.m?.().b | tst-typescript.ts:13:1:13:7 | a.m?.() |
|
||||
| tst-typescript.ts:14:1:14:8 | a.m()?.b | tst-typescript.ts:14:1:14:8 | a.m()?.b |
|
||||
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:4 | a?.m |
|
||||
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:8 | a?.m?.() |
|
||||
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:11 | a?.m?.()?.b |
|
||||
| tst.js:2:1:2:6 | a?.b.c | tst.js:2:1:2:4 | a?.b |
|
||||
| tst.js:3:1:3:6 | a.b?.c | tst.js:3:1:3:6 | a.b?.c |
|
||||
| tst.js:4:1:4:7 | a?.b?.c | tst.js:4:1:4:4 | a?.b |
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) |
|
||||
| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] |
|
||||
| short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] |
|
||||
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) |
|
||||
| short-circuiting.js:3:5:3:18 | x?.(o1 = null) |
|
||||
| short-circuiting.js:7:5:7:18 | x?.[o2 = null] |
|
||||
| short-circuiting.js:12:5:12:18 | x?.[o3 = null] |
|
||||
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) |
|
||||
| tst-typescript.ts:2:1:2:4 | a?.b |
|
||||
| tst-typescript.ts:3:1:3:6 | a.b?.c |
|
||||
| tst-typescript.ts:4:1:4:4 | a?.b |
|
||||
| tst-typescript.ts:4:1:4:7 | a?.b?.c |
|
||||
| tst-typescript.ts:7:1:7:5 | f?.() |
|
||||
| tst-typescript.ts:8:1:8:7 | f()?.() |
|
||||
| tst-typescript.ts:9:1:9:5 | f?.() |
|
||||
| tst-typescript.ts:9:1:9:9 | f?.()?.() |
|
||||
| tst-typescript.ts:12:1:12:4 | a?.m |
|
||||
| tst-typescript.ts:13:1:13:7 | a.m?.() |
|
||||
| tst-typescript.ts:14:1:14:8 | a.m()?.b |
|
||||
| tst-typescript.ts:15:1:15:4 | a?.m |
|
||||
| tst-typescript.ts:15:1:15:8 | a?.m?.() |
|
||||
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b |
|
||||
| tst.js:2:1:2:4 | a?.b |
|
||||
| tst.js:3:1:3:6 | a.b?.c |
|
||||
| tst.js:4:1:4:4 | a?.b |
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
| short-circuiting-typescript.ts:4:10:4:11 | o1 | file://:0:0:0:0 | null |
|
||||
| short-circuiting-typescript.ts:4:10:4:11 | o1 | short-circuiting-typescript.ts:2:14:2:15 | object literal |
|
||||
| short-circuiting-typescript.ts:8:10:8:11 | o2 | file://:0:0:0:0 | null |
|
||||
| short-circuiting-typescript.ts:8:10:8:11 | o2 | short-circuiting-typescript.ts:6:14:6:15 | object literal |
|
||||
| short-circuiting-typescript.ts:13:10:13:11 | o3 | file://:0:0:0:0 | null |
|
||||
| short-circuiting-typescript.ts:13:10:13:11 | o3 | short-circuiting-typescript.ts:10:14:10:15 | object literal |
|
||||
| short-circuiting-typescript.ts:14:10:14:11 | o4 | file://:0:0:0:0 | null |
|
||||
| short-circuiting-typescript.ts:14:10:14:11 | o4 | short-circuiting-typescript.ts:11:14:11:15 | object literal |
|
||||
| short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null |
|
||||
| short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal |
|
||||
| short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null |
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
| short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null |
|
||||
| short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal |
|
||||
| short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null |
|
||||
| short-circuiting.js:8:10:8:11 | o2 | short-circuiting.js:6:14:6:15 | object literal |
|
||||
| short-circuiting.js:13:10:13:11 | o3 | file://:0:0:0:0 | null |
|
||||
| short-circuiting.js:13:10:13:11 | o3 | short-circuiting.js:10:14:10:15 | object literal |
|
||||
| short-circuiting.js:14:10:14:11 | o4 | file://:0:0:0:0 | null |
|
||||
| short-circuiting.js:14:10:14:11 | o4 | short-circuiting.js:11:14:11:15 | object literal |
|
|
@ -1,7 +0,0 @@
|
|||
import javascript
|
||||
|
||||
from CallExpr c, Expr arg
|
||||
where
|
||||
c.getCalleeName() = "DUMP" and
|
||||
arg = c.getArgument(0)
|
||||
select arg, arg.analyze().getAValue()
|
|
@ -0,0 +1,15 @@
|
|||
(function() {
|
||||
var o1 = {};
|
||||
x?.(o1 = null);
|
||||
DUMP(o1);
|
||||
|
||||
var o2 = {};
|
||||
x?.[o2 = null];
|
||||
DUMP(o2);
|
||||
|
||||
var o3 = {},
|
||||
o4 = {};
|
||||
x?.[o3 = null]?.(o4 = null);
|
||||
DUMP(o3);
|
||||
DUMP(o4);
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
a.b.c;
|
||||
a?.b.c;
|
||||
a.b?.c;
|
||||
a?.b?.c;
|
||||
|
||||
f()();
|
||||
f?.()();
|
||||
f()?.();
|
||||
f?.()?.();
|
||||
|
||||
a.m().b;
|
||||
a?.m().b;
|
||||
a.m?.().b;
|
||||
a.m()?.b;
|
||||
a?.m?.()?.b;
|
|
@ -0,0 +1 @@
|
|||
| tst.ts:2:5:2:22 | declare x: number; | true |
|
|
@ -0,0 +1,5 @@
|
|||
import javascript
|
||||
|
||||
from FieldDeclaration f, boolean ambient
|
||||
where if f.isAmbient() then ambient = true else ambient = false
|
||||
select f, ambient
|
|
@ -0,0 +1,3 @@
|
|||
class C {
|
||||
declare x: number;
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
| p1 | MyPromise<string> | string |
|
||||
| p2 | MyPromise<any> | any |
|
||||
| p3 | Promise<string> | string |
|
||||
| p4 | PromiseLike<string> | string |
|
||||
| p5 | PromiseLike<string> | string |
|
||||
| p6 | Thenable<string> | string |
|
||||
| p7 | Thenable<string> | string |
|
||||
| p8 | ThenPromise<string> | string |
|
||||
| p9 | JQueryPromise<string> | string |
|
||||
| p10 | JQueryGenericPromise<string> | string |
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import javascript
|
||||
|
||||
query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) {
|
||||
res0 = type.getParameterName() and res1 = type.getPredicateType()
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import javascript
|
||||
|
||||
query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) {
|
||||
res0 = type.getParameterName() and res1 = type.getPredicateType()
|
||||
}
|
||||
|
||||
query predicate test_PredicateTypeExpr(PredicateTypeExpr type, VarTypeAccess res0) {
|
||||
res0 = type.getParameterName()
|
||||
}
|
||||
|
||||
query predicate test_hasAssertsKeyword(PredicateTypeExpr type) {
|
||||
type.hasAssertsKeyword()
|
||||
}
|
|
@ -105,6 +105,9 @@ test_VariableTypes
|
|||
| tst.ts:135:5:135:24 | tupleWithRestElement | tupleWithRestElement | tst.ts:135:27:135:47 | [number ... ring[]] |
|
||||
| tst.ts:136:5:136:36 | tupleWi ... lements | tupleWithOptionalAndRestElements | tst.ts:136:39:136:68 | [number ... mber[]] |
|
||||
| tst.ts:137:5:137:15 | unknownType | unknownType | tst.ts:137:18:137:24 | unknown |
|
||||
| tst.ts:142:17:142:25 | condition | condition | tst.ts:142:28:142:30 | any |
|
||||
| tst.ts:142:33:142:35 | msg | msg | tst.ts:142:39:142:44 | string |
|
||||
| tst.ts:148:25:148:27 | val | val | tst.ts:148:30:148:32 | any |
|
||||
test_QualifiedTypeAccess
|
||||
| tst.ts:63:19:63:21 | N.I | tst.ts:63:19:63:19 | N | tst.ts:63:21:63:21 | I |
|
||||
| tst.ts:64:20:64:24 | N.M.I | tst.ts:64:20:64:22 | N.M | tst.ts:64:24:64:24 | I |
|
||||
|
@ -148,6 +151,17 @@ test_IsTypeExpr
|
|||
| tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that | tst.ts:76:29:76:32 | Leaf |
|
||||
| tst.ts:80:36:80:55 | x is Generic<Leaf[]> | tst.ts:80:36:80:36 | x | tst.ts:80:41:80:55 | Generic<Leaf[]> |
|
||||
| tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x | tst.ts:81:43:81:50 | typeof x |
|
||||
| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val | tst.ts:148:51:148:56 | string |
|
||||
test_PredicateTypeExpr
|
||||
| tst.ts:75:17:75:28 | this is Leaf | tst.ts:75:17:75:20 | this |
|
||||
| tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that |
|
||||
| tst.ts:80:36:80:55 | x is Generic<Leaf[]> | tst.ts:80:36:80:36 | x |
|
||||
| tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x |
|
||||
| tst.ts:142:48:142:64 | asserts condition | tst.ts:142:56:142:64 | condition |
|
||||
| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val |
|
||||
test_hasAssertsKeyword
|
||||
| tst.ts:142:48:142:64 | asserts condition |
|
||||
| tst.ts:148:36:148:56 | asserts ... string |
|
||||
test_ThisParameterTypes
|
||||
| function hasThisParam | tst.ts:116:29:116:32 | void |
|
||||
| method hasThisParam of interface InterfaceWithThisParam | tst.ts:119:22:119:43 | Interfa ... isParam |
|
||||
|
@ -254,6 +268,8 @@ test_ReturnTypes
|
|||
| tst.ts:94:1:94:37 | functio ... rn x; } | function f1 | tst.ts:94:23:94:23 | S |
|
||||
| tst.ts:95:1:95:53 | functio ... x,y]; } | function f2 | tst.ts:95:31:95:35 | [S,T] |
|
||||
| tst.ts:96:1:96:52 | functio ... rn x; } | function f3 | tst.ts:96:38:96:38 | S |
|
||||
| tst.ts:142:1:146:1 | functio ... )\\n }\\n} | function assert | tst.ts:142:48:142:64 | asserts condition |
|
||||
| tst.ts:148:1:152:1 | functio ... ;\\n }\\n} | function assertIsString | tst.ts:148:36:148:56 | asserts ... string |
|
||||
test_KeyofTypeExpr
|
||||
| tst.ts:49:16:49:30 | keyof Interface | tst.ts:49:22:49:30 | Interface |
|
||||
| tst.ts:113:26:113:35 | keyof Node | tst.ts:113:32:113:35 | Node |
|
||||
|
|
|
@ -11,7 +11,7 @@ import GenericTypeExpr
|
|||
import IntersectionTypeExpr
|
||||
import FunctionTypeReturns
|
||||
import InterfaceTypeExpr
|
||||
import IsTypeExpr
|
||||
import PredicateTypeExpr
|
||||
import ThisParameterTypes
|
||||
import ChildIndex
|
||||
import TypeArguments
|
||||
|
|
|
@ -138,3 +138,15 @@ let unknownType: unknown;
|
|||
|
||||
let taggedTemplateLiteralTypeArg1 = someTag<number>`Hello`;
|
||||
let taggedTemplateLiteralTypeArg2 = someTag<number, string>`Hello`;
|
||||
|
||||
function assert(condition: any, msg?: string): asserts condition {
|
||||
if (!condition) {
|
||||
throw new AssertionError(msg)
|
||||
}
|
||||
}
|
||||
|
||||
function assertIsString(val: any): asserts val is string {
|
||||
if (typeof val !== "string") {
|
||||
throw new AssertionError("Not a string!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,30 @@
|
|||
| tst.ts:43:28:43:30 | foo | "foo" |
|
||||
| tst.ts:43:33:43:37 | "foo" | "foo" |
|
||||
| type_alias.ts:3:5:3:5 | b | boolean |
|
||||
| type_alias.ts:7:5:7:5 | c | ValueOrArray<number> |
|
||||
| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any |
|
||||
| type_alias.ts:14:10:14:17 | property | string |
|
||||
| type_alias.ts:17:5:17:8 | json | Json |
|
||||
| type_alias.ts:21:18:21:35 | [key: string]: any | any |
|
||||
| type_alias.ts:21:19:21:21 | key | string |
|
||||
| type_alias.ts:23:7:23:12 | myNode | VirtualNode |
|
||||
| type_alias.ts:24:5:27:5 | ["div", ... ]\\n ] | VirtualNode |
|
||||
| type_alias.ts:24:6:24:10 | "div" | "div" |
|
||||
| type_alias.ts:24:13:24:28 | { id: "parent" } | string \| { [key: string]: any; } |
|
||||
| type_alias.ts:24:15:24:16 | id | string |
|
||||
| type_alias.ts:24:19:24:26 | "parent" | "parent" |
|
||||
| type_alias.ts:25:9:25:61 | ["div", ... child"] | VirtualNode |
|
||||
| type_alias.ts:25:10:25:14 | "div" | "div" |
|
||||
| type_alias.ts:25:17:25:37 | { id: " ... hild" } | string \| { [key: string]: any; } |
|
||||
| type_alias.ts:25:19:25:20 | id | string |
|
||||
| type_alias.ts:25:23:25:35 | "first-child" | "first-child" |
|
||||
| type_alias.ts:25:40:25:60 | "I'm th ... child" | "I'm the first child" |
|
||||
| type_alias.ts:26:9:26:63 | ["div", ... child"] | VirtualNode |
|
||||
| type_alias.ts:26:10:26:14 | "div" | "div" |
|
||||
| type_alias.ts:26:17:26:38 | { id: " ... hild" } | string \| { [key: string]: any; } |
|
||||
| type_alias.ts:26:19:26:20 | id | string |
|
||||
| type_alias.ts:26:23:26:36 | "second-child" | "second-child" |
|
||||
| type_alias.ts:26:41:26:62 | "I'm th ... child" | "I'm the second child" |
|
||||
| type_definition_objects.ts:1:13:1:17 | dummy | typeof dummy.ts |
|
||||
| type_definition_objects.ts:1:24:1:32 | "./dummy" | any |
|
||||
| type_definition_objects.ts:3:14:3:14 | C | C |
|
||||
|
@ -115,4 +139,4 @@
|
|||
| type_definitions.ts:16:5:16:9 | color | Color |
|
||||
| type_definitions.ts:18:6:18:22 | EnumWithOneMember | EnumWithOneMember |
|
||||
| type_definitions.ts:19:5:19:5 | e | EnumWithOneMember |
|
||||
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | number[] |
|
||||
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias<number> |
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
|
||||
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
|
||||
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
|
||||
| type_alias.ts:19:1:21:57 | type Vi ... ode[]]; | VirtualNode |
|
||||
| type_definition_objects.ts:3:8:3:17 | class C {} | C |
|
||||
| type_definition_objects.ts:6:8:6:16 | enum E {} | E |
|
||||
| type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | I<S> |
|
||||
| type_definitions.ts:8:1:10:1 | class C ... x: T\\n} | C<T> |
|
||||
| type_definitions.ts:13:1:15:1 | enum Co ... blue\\n} | Color |
|
||||
| type_definitions.ts:18:1:18:33 | enum En ... ember } | EnumWithOneMember |
|
||||
| type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; | T[] |
|
||||
| type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; | Alias<T> |
|
||||
|
|
|
@ -57,20 +57,56 @@
|
|||
| tst.ts:37:17:37:18 | [] | [] |
|
||||
| tst.ts:38:27:38:47 | [number ... ring[]] | [number, ...string[]] |
|
||||
| tst.ts:38:28:38:33 | number | number |
|
||||
| tst.ts:38:36:38:46 | ...string[] | string[] |
|
||||
| tst.ts:38:36:38:46 | ...string[] | string |
|
||||
| tst.ts:38:39:38:44 | string | string |
|
||||
| tst.ts:38:39:38:46 | string[] | string[] |
|
||||
| tst.ts:39:39:39:68 | [number ... mber[]] | [number, string?, ...number[]] |
|
||||
| tst.ts:39:40:39:45 | number | number |
|
||||
| tst.ts:39:48:39:53 | string | string |
|
||||
| tst.ts:39:48:39:54 | string? | string |
|
||||
| tst.ts:39:57:39:67 | ...number[] | number[] |
|
||||
| tst.ts:39:57:39:67 | ...number[] | number |
|
||||
| tst.ts:39:60:39:65 | number | number |
|
||||
| tst.ts:39:60:39:67 | number[] | number[] |
|
||||
| tst.ts:40:18:40:24 | unknown | unknown |
|
||||
| type_alias.ts:1:6:1:6 | B | boolean |
|
||||
| type_alias.ts:1:10:1:16 | boolean | boolean |
|
||||
| type_alias.ts:3:8:3:8 | B | boolean |
|
||||
| type_alias.ts:5:6:5:17 | ValueOrArray | ValueOrArray<T> |
|
||||
| type_alias.ts:5:19:5:19 | T | T |
|
||||
| type_alias.ts:5:24:5:24 | T | T |
|
||||
| type_alias.ts:5:24:5:49 | T \| Arr ... ray<T>> | ValueOrArray<T> |
|
||||
| type_alias.ts:5:28:5:32 | Array | T[] |
|
||||
| type_alias.ts:5:28:5:49 | Array<V ... ray<T>> | ValueOrArray<T>[] |
|
||||
| type_alias.ts:5:34:5:45 | ValueOrArray | ValueOrArray<T> |
|
||||
| type_alias.ts:5:34:5:48 | ValueOrArray<T> | ValueOrArray<T> |
|
||||
| type_alias.ts:5:47:5:47 | T | T |
|
||||
| type_alias.ts:7:8:7:19 | ValueOrArray | ValueOrArray<T> |
|
||||
| type_alias.ts:7:8:7:27 | ValueOrArray<number> | ValueOrArray<number> |
|
||||
| type_alias.ts:7:21:7:26 | number | number |
|
||||
| type_alias.ts:9:6:9:9 | Json | Json |
|
||||
| type_alias.ts:10:5:15:12 | \| strin ... Json[] | Json |
|
||||
| type_alias.ts:10:7:10:12 | string | string |
|
||||
| type_alias.ts:11:7:11:12 | number | number |
|
||||
| type_alias.ts:12:7:12:13 | boolean | boolean |
|
||||
| type_alias.ts:13:7:13:10 | null | null |
|
||||
| type_alias.ts:14:7:14:34 | { [prop ... Json } | { [property: string]: Json; } |
|
||||
| type_alias.ts:14:20:14:25 | string | string |
|
||||
| type_alias.ts:14:29:14:32 | Json | Json |
|
||||
| type_alias.ts:15:7:15:10 | Json | Json |
|
||||
| type_alias.ts:15:7:15:12 | Json[] | Json[] |
|
||||
| type_alias.ts:17:11:17:14 | Json | Json |
|
||||
| type_alias.ts:19:6:19:16 | VirtualNode | VirtualNode |
|
||||
| type_alias.ts:20:5:21:56 | \| strin ... Node[]] | VirtualNode |
|
||||
| type_alias.ts:20:7:20:12 | string | string |
|
||||
| type_alias.ts:21:7:21:56 | [string ... Node[]] | [string, { [key: string]: any; }, ...VirtualNod... |
|
||||
| type_alias.ts:21:8:21:13 | string | string |
|
||||
| type_alias.ts:21:16:21:37 | { [key: ... : any } | { [key: string]: any; } |
|
||||
| type_alias.ts:21:24:21:29 | string | string |
|
||||
| type_alias.ts:21:33:21:35 | any | any |
|
||||
| type_alias.ts:21:40:21:55 | ...VirtualNode[] | VirtualNode |
|
||||
| type_alias.ts:21:43:21:53 | VirtualNode | VirtualNode |
|
||||
| type_alias.ts:21:43:21:55 | VirtualNode[] | VirtualNode[] |
|
||||
| type_alias.ts:23:15:23:25 | VirtualNode | VirtualNode |
|
||||
| type_definitions.ts:3:11:3:11 | I | I<S> |
|
||||
| type_definitions.ts:3:13:3:13 | S | S |
|
||||
| type_definitions.ts:4:6:4:6 | S | S |
|
||||
|
@ -84,10 +120,10 @@
|
|||
| type_definitions.ts:11:10:11:15 | number | number |
|
||||
| type_definitions.ts:16:12:16:16 | Color | Color |
|
||||
| type_definitions.ts:19:8:19:24 | EnumWithOneMember | EnumWithOneMember |
|
||||
| type_definitions.ts:21:6:21:10 | Alias | T[] |
|
||||
| type_definitions.ts:21:6:21:10 | Alias | Alias<T> |
|
||||
| type_definitions.ts:21:12:21:12 | T | T |
|
||||
| type_definitions.ts:21:17:21:17 | T | T |
|
||||
| type_definitions.ts:21:17:21:19 | T[] | T[] |
|
||||
| type_definitions.ts:22:26:22:30 | Alias | T[] |
|
||||
| type_definitions.ts:22:26:22:38 | Alias<number> | number[] |
|
||||
| type_definitions.ts:21:17:21:19 | T[] | Alias<T> |
|
||||
| type_definitions.ts:22:26:22:30 | Alias | Alias<T> |
|
||||
| type_definitions.ts:22:26:22:38 | Alias<number> | Alias<number> |
|
||||
| type_definitions.ts:22:32:22:37 | number | number |
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
| Alias<T> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
|
||||
| Alias<number> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
|
||||
| C | type_definition_objects.ts:3:8:3:17 | class C {} |
|
||||
| C<T> | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} |
|
||||
| C<number> | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} |
|
||||
|
@ -9,3 +11,7 @@
|
|||
| EnumWithOneMember | type_definitions.ts:18:26:18:31 | member |
|
||||
| I<S> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
||||
| I<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
||||
| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; |
|
||||
| ValueOrArray<T> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
||||
| ValueOrArray<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
||||
| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; |
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
type B = boolean;
|
||||
|
||||
var b: B;
|
||||
|
||||
type ValueOrArray<T> = T | Array<ValueOrArray<T>>;
|
||||
|
||||
var c: ValueOrArray<number>;
|
||||
|
||||
type Json =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| { [property: string]: Json }
|
||||
| Json[];
|
||||
|
||||
var json: Json;
|
||||
|
||||
type VirtualNode =
|
||||
| string
|
||||
| [string, { [key: string]: any }, ...VirtualNode[]];
|
||||
|
||||
const myNode: VirtualNode =
|
||||
["div", { id: "parent" },
|
||||
["div", { id: "first-child" }, "I'm the first child"],
|
||||
["div", { id: "second-child" }, "I'm the second child"]
|
||||
];
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,2 @@
|
|||
description: add support for TypeScript 3.7 features
|
||||
compatibility: backwards
|
Загрузка…
Ссылка в новой задаче