diff --git a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java index ddf57b32cff..00939503eeb 100644 --- a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java +++ b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java @@ -705,7 +705,7 @@ public class NodeCopier implements Visitor { @Override public INode visit(TupleTypeExpr nd, Void c) { - return new TupleTypeExpr(visit(nd.getLoc()), copy(nd.getElementTypes()), nd.getElementNames()); + return new TupleTypeExpr(visit(nd.getLoc()), copy(nd.getElementTypes()), copy(nd.getElementNames())); } @Override diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 4bf57075b0b..1050590f14d 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -1820,9 +1820,8 @@ public class ASTExtractor { public Label visit(TupleTypeExpr nd, Context c) { Label key = super.visit(nd, c); if (nd.getElementNames() != null) { - for (int i = 0; i < nd.getElementNames().size(); i++) { - trapwriter.addTuple("tuple_element_name", key, i, nd.getElementNames().get(i)); - } + // Element names are index -1, -2, -3... + visitAll(nd.getElementNames(), key, IdContext.typeDecl, -1, -1); } visitAll(nd.getElementTypes(), key, IdContext.typeBind, 0); return key; diff --git a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java index 83529f8b1b4..546739d7f28 100644 --- a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java @@ -2183,18 +2183,13 @@ public class TypeScriptASTConverter { List elements = new ArrayList<>(); ((JsonArray)node.get("elements")).iterator().forEachRemaining(elements::add); - List elementNames = elements.stream() + List names = convertNodes(elements.stream() .filter(n -> getKind(n).equals("NamedTupleMember")) .map(n -> n.getAsJsonObject().get("name")) - .map(n -> n.getAsJsonObject().get("escapedText")) - .map(n -> n.getAsString()) - .collect(Collectors.toList()); + .collect(Collectors.toList()) + ); - if (elementNames.size() == 0) { - elementNames = null; - } - - return new TupleTypeExpr(loc, convertChildrenAsTypes(node, "elements"), elementNames); + return new TupleTypeExpr(loc, convertChildrenAsTypes(node, "elements"), names); } // This method just does a trivial forward to the type. The names have already been extracted in `convertTupleType`. diff --git a/javascript/extractor/src/com/semmle/ts/ast/TupleTypeExpr.java b/javascript/extractor/src/com/semmle/ts/ast/TupleTypeExpr.java index 9d49899fafd..a42df41847e 100644 --- a/javascript/extractor/src/com/semmle/ts/ast/TupleTypeExpr.java +++ b/javascript/extractor/src/com/semmle/ts/ast/TupleTypeExpr.java @@ -1,5 +1,6 @@ package com.semmle.ts.ast; +import com.semmle.js.ast.Identifier; import com.semmle.js.ast.SourceLocation; import com.semmle.js.ast.Visitor; import java.util.List; @@ -7,9 +8,9 @@ import java.util.List; /** A tuple type, such as [number, string]. */ public class TupleTypeExpr extends TypeExpression { private final List elementTypes; - private final List elementNames; + private final List elementNames; - public TupleTypeExpr(SourceLocation loc, List elementTypes, List elementNames) { + public TupleTypeExpr(SourceLocation loc, List elementTypes, List elementNames) { super("TupleTypeExpr", loc); this.elementTypes = elementTypes; this.elementNames = elementNames; @@ -19,7 +20,7 @@ public class TupleTypeExpr extends TypeExpression { return elementTypes; } - public List getElementNames() { + public List getElementNames() { return elementNames; } diff --git a/javascript/ql/src/semmle/javascript/TypeScript.qll b/javascript/ql/src/semmle/javascript/TypeScript.qll index 82088638a60..799f386e2a0 100644 --- a/javascript/ql/src/semmle/javascript/TypeScript.qll +++ b/javascript/ql/src/semmle/javascript/TypeScript.qll @@ -846,7 +846,7 @@ class ParenthesizedTypeExpr extends @parenthesizedtypeexpr, TypeExpr { */ class TupleTypeExpr extends @tupletypeexpr, TypeExpr { /** Gets the `n`th element type in the tuple, starting at 0. */ - TypeExpr getElementType(int n) { result = getChildTypeExpr(n) } + TypeExpr getElementType(int n) { result = getChildTypeExpr(n) and n >= 0 } /** Gets any of the element types in the tuple. */ TypeExpr getAnElementType() { result = getElementType(_) } @@ -854,8 +854,13 @@ class TupleTypeExpr extends @tupletypeexpr, TypeExpr { /** Gets the number of elements in the tuple type. */ int getNumElementType() { result = count(getAnElementType()) } - /** Gets the name of the `n`th tuple member if the tuple members are named. */ - string getElementName(int n) { tuple_element_name(this, n, result) } + /** + * Gets the name of the `n`th tuple member, starting at 0. + * Only has a result if the tuple members are named. + * + * Type element names are at indices -1, -2, -3, ... + */ + Identifier getElementName(int n) { result = getChild(-(n + 1)) and n >= 0 } } /** diff --git a/javascript/ql/src/semmlecode.javascript.dbscheme b/javascript/ql/src/semmlecode.javascript.dbscheme index 3f291931cb8..c73fbfca57f 100644 --- a/javascript/ql/src/semmlecode.javascript.dbscheme +++ b/javascript/ql/src/semmlecode.javascript.dbscheme @@ -790,13 +790,6 @@ tuple_type_rest( unique int typ: @type ref ); -#keyset[tuple, index] -tuple_element_name ( - int tuple: @tupletypeexpr ref, - int index: int ref, - varchar(900) name: string ref -); - // comments comments (unique int id: @comment, int kind: int ref, diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/TupleTypeExpr.qll b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/TupleTypeExpr.qll index 03fe4325786..adabff94060 100644 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/TupleTypeExpr.qll +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/TupleTypeExpr.qll @@ -4,6 +4,6 @@ query predicate test_TupleTypeExpr(TupleTypeExpr type, int n, int res0, TypeExpr res0 = type.getNumElementType() and res1 = type.getElementType(n) } -query predicate test_TupleTypeElementName(TupleTypeExpr type, int n, string name) { +query predicate test_TupleTypeElementName(TupleTypeExpr type, int n, Identifier name) { name = type.getElementName(n) } diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected index 00bda23ab3f..9ae9bdfe456 100644 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected @@ -219,8 +219,8 @@ test_TupleTypeExpr | tst.ts:179:21:179:44 | [...Str ... umbers] | 0 | 2 | tst.ts:179:22:179:31 | ...Strings | | tst.ts:179:21:179:44 | [...Str ... umbers] | 1 | 2 | tst.ts:179:34:179:43 | ...Numbers | test_TupleTypeElementName -| tst.ts:169:34:169:64 | [first: ... number] | 0 | first | -| tst.ts:169:34:169:64 | [first: ... number] | 1 | second | +| tst.ts:169:34:169:64 | [first: ... number] | 0 | tst.ts:169:35:169:39 | first | +| tst.ts:169:34:169:64 | [first: ... number] | 1 | tst.ts:169:50:169:55 | second | test_FieldTypes | tst.ts:15:3:15:22 | numberField: number; | tst.ts:15:16:15:21 | number | | tst.ts:16:3:16:22 | stringField: string; | tst.ts:16:16:16:21 | string | diff --git a/javascript/upgrades/2dc7a0389827d235763a3748aba73c2d4a677b15/semmlecode.javascript.dbscheme b/javascript/upgrades/2dc7a0389827d235763a3748aba73c2d4a677b15/semmlecode.javascript.dbscheme index 3f291931cb8..c73fbfca57f 100644 --- a/javascript/upgrades/2dc7a0389827d235763a3748aba73c2d4a677b15/semmlecode.javascript.dbscheme +++ b/javascript/upgrades/2dc7a0389827d235763a3748aba73c2d4a677b15/semmlecode.javascript.dbscheme @@ -790,13 +790,6 @@ tuple_type_rest( unique int typ: @type ref ); -#keyset[tuple, index] -tuple_element_name ( - int tuple: @tupletypeexpr ref, - int index: int ref, - varchar(900) name: string ref -); - // comments comments (unique int id: @comment, int kind: int ref,