Skip to content

Commit 1e7b4c2

Browse files
author
Max Schaefer
authored
Merge pull request github#1953 from asger-semmle/typescript-call-signature-api
TS: Make overload index and functions signature more available
2 parents 47a0942 + c2f6855 commit 1e7b4c2

32 files changed

+2957
-163
lines changed

javascript/extractor/lib/typescript/src/ast_extractor.ts

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface AugmentedNode extends ts.Node {
2222
$symbol?: number;
2323
$resolvedSignature?: number;
2424
$overloadIndex?: number;
25+
$declaredSignature?: number;
2526
}
2627

2728
export type AugmentedPos = number;
@@ -263,6 +264,17 @@ export function augmentAst(ast: AugmentedSourceFile, code: string, project: Proj
263264
namePart.$symbol = typeTable.getSymbolId(symbol);
264265
}
265266
}
267+
if (ts.isFunctionLike(node)) {
268+
let signature = typeChecker.getSignatureFromDeclaration(node);
269+
if (signature != null) {
270+
let kind = ts.isConstructSignatureDeclaration(node) || ts.isConstructorDeclaration(node)
271+
? ts.SignatureKind.Construct : ts.SignatureKind.Call;
272+
let id = typeTable.getSignatureId(kind, signature);
273+
if (id != null) {
274+
(node as AugmentedNode).$declaredSignature = id;
275+
}
276+
}
277+
}
266278
}
267279
}
268280
}
@@ -295,54 +307,61 @@ function isNamedNodeWithSymbol(node: ts.Node): node is NamedNodeWithSymbol {
295307
*/
296308
function isTypedNode(node: ts.Node): boolean {
297309
switch (node.kind) {
298-
case ts.SyntaxKind.ArrayLiteralExpression:
299-
case ts.SyntaxKind.ArrowFunction:
300-
case ts.SyntaxKind.AsExpression:
301-
case ts.SyntaxKind.AwaitExpression:
302-
case ts.SyntaxKind.BinaryExpression:
303-
case ts.SyntaxKind.CallExpression:
304-
case ts.SyntaxKind.ClassExpression:
305-
case ts.SyntaxKind.CommaListExpression:
306-
case ts.SyntaxKind.ConditionalExpression:
307-
case ts.SyntaxKind.DeleteExpression:
308-
case ts.SyntaxKind.ElementAccessExpression:
309-
case ts.SyntaxKind.ExpressionStatement:
310-
case ts.SyntaxKind.ExpressionWithTypeArguments:
311-
case ts.SyntaxKind.FalseKeyword:
312-
case ts.SyntaxKind.FunctionDeclaration:
313-
case ts.SyntaxKind.FunctionExpression:
314-
case ts.SyntaxKind.Identifier:
315-
case ts.SyntaxKind.JsxExpression:
316-
case ts.SyntaxKind.LiteralType:
317-
case ts.SyntaxKind.NewExpression:
318-
case ts.SyntaxKind.NonNullExpression:
319-
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
320-
case ts.SyntaxKind.NumericLiteral:
321-
case ts.SyntaxKind.ObjectKeyword:
322-
case ts.SyntaxKind.ObjectLiteralExpression:
323-
case ts.SyntaxKind.OmittedExpression:
324-
case ts.SyntaxKind.ParenthesizedExpression:
325-
case ts.SyntaxKind.PartiallyEmittedExpression:
326-
case ts.SyntaxKind.PostfixUnaryExpression:
327-
case ts.SyntaxKind.PrefixUnaryExpression:
328-
case ts.SyntaxKind.PropertyAccessExpression:
329-
case ts.SyntaxKind.RegularExpressionLiteral:
330-
case ts.SyntaxKind.StringLiteral:
331-
case ts.SyntaxKind.TaggedTemplateExpression:
332-
case ts.SyntaxKind.TemplateExpression:
333-
case ts.SyntaxKind.TemplateHead:
334-
case ts.SyntaxKind.TemplateMiddle:
335-
case ts.SyntaxKind.TemplateSpan:
336-
case ts.SyntaxKind.TemplateTail:
337-
case ts.SyntaxKind.TrueKeyword:
338-
case ts.SyntaxKind.TypeAssertionExpression:
339-
case ts.SyntaxKind.TypeLiteral:
340-
case ts.SyntaxKind.TypeOfExpression:
341-
case ts.SyntaxKind.VoidExpression:
342-
case ts.SyntaxKind.YieldExpression:
343-
return true;
344-
default:
345-
return ts.isTypeNode(node);
310+
case ts.SyntaxKind.ArrayLiteralExpression:
311+
case ts.SyntaxKind.ArrowFunction:
312+
case ts.SyntaxKind.AsExpression:
313+
case ts.SyntaxKind.AwaitExpression:
314+
case ts.SyntaxKind.BinaryExpression:
315+
case ts.SyntaxKind.CallExpression:
316+
case ts.SyntaxKind.ClassExpression:
317+
case ts.SyntaxKind.ClassDeclaration:
318+
case ts.SyntaxKind.CommaListExpression:
319+
case ts.SyntaxKind.ConditionalExpression:
320+
case ts.SyntaxKind.Constructor:
321+
case ts.SyntaxKind.DeleteExpression:
322+
case ts.SyntaxKind.ElementAccessExpression:
323+
case ts.SyntaxKind.ExpressionStatement:
324+
case ts.SyntaxKind.ExpressionWithTypeArguments:
325+
case ts.SyntaxKind.FalseKeyword:
326+
case ts.SyntaxKind.FunctionDeclaration:
327+
case ts.SyntaxKind.FunctionExpression:
328+
case ts.SyntaxKind.GetAccessor:
329+
case ts.SyntaxKind.Identifier:
330+
case ts.SyntaxKind.IndexSignature:
331+
case ts.SyntaxKind.JsxExpression:
332+
case ts.SyntaxKind.LiteralType:
333+
case ts.SyntaxKind.MethodDeclaration:
334+
case ts.SyntaxKind.MethodSignature:
335+
case ts.SyntaxKind.NewExpression:
336+
case ts.SyntaxKind.NonNullExpression:
337+
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
338+
case ts.SyntaxKind.NumericLiteral:
339+
case ts.SyntaxKind.ObjectKeyword:
340+
case ts.SyntaxKind.ObjectLiteralExpression:
341+
case ts.SyntaxKind.OmittedExpression:
342+
case ts.SyntaxKind.ParenthesizedExpression:
343+
case ts.SyntaxKind.PartiallyEmittedExpression:
344+
case ts.SyntaxKind.PostfixUnaryExpression:
345+
case ts.SyntaxKind.PrefixUnaryExpression:
346+
case ts.SyntaxKind.PropertyAccessExpression:
347+
case ts.SyntaxKind.RegularExpressionLiteral:
348+
case ts.SyntaxKind.SetAccessor:
349+
case ts.SyntaxKind.StringLiteral:
350+
case ts.SyntaxKind.TaggedTemplateExpression:
351+
case ts.SyntaxKind.TemplateExpression:
352+
case ts.SyntaxKind.TemplateHead:
353+
case ts.SyntaxKind.TemplateMiddle:
354+
case ts.SyntaxKind.TemplateSpan:
355+
case ts.SyntaxKind.TemplateTail:
356+
case ts.SyntaxKind.TrueKeyword:
357+
case ts.SyntaxKind.TypeAssertionExpression:
358+
case ts.SyntaxKind.TypeLiteral:
359+
case ts.SyntaxKind.TypeOfExpression:
360+
case ts.SyntaxKind.VoidExpression:
361+
case ts.SyntaxKind.YieldExpression:
362+
return true;
363+
default:
364+
return ts.isTypeNode(node);
346365
}
347366
}
348367

javascript/extractor/src/com/semmle/js/ast/AFunctionExpression.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
public abstract class AFunctionExpression extends Expression implements IFunction {
1313
private final AFunction<? extends Node> fn;
1414
private int symbol = -1;
15+
private int declaredSignature = -1;
1516

1617
public AFunctionExpression(
1718
String type,
@@ -144,4 +145,14 @@ public int getSymbol() {
144145
public void setSymbol(int symbol) {
145146
this.symbol = symbol;
146147
}
148+
149+
@Override
150+
public int getDeclaredSignatureId() {
151+
return declaredSignature;
152+
}
153+
154+
@Override
155+
public void setDeclaredSignatureId(int id) {
156+
declaredSignature = id;
157+
}
147158
}

javascript/extractor/src/com/semmle/js/ast/FunctionDeclaration.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class FunctionDeclaration extends Statement implements IFunction {
1919
private final AFunction<? extends Node> fn;
2020
private final boolean hasDeclareKeyword;
2121
private int symbol = -1;
22+
private int staticType = -1;
23+
private int declaredSignature = -1;
2224

2325
public FunctionDeclaration(
2426
SourceLocation loc,
@@ -185,4 +187,24 @@ public int getSymbol() {
185187
public void setSymbol(int symbol) {
186188
this.symbol = symbol;
187189
}
190+
191+
@Override
192+
public int getStaticTypeId() {
193+
return staticType;
194+
}
195+
196+
@Override
197+
public void setStaticTypeId(int id) {
198+
staticType = id;
199+
}
200+
201+
@Override
202+
public int getDeclaredSignatureId() {
203+
return declaredSignature;
204+
}
205+
206+
@Override
207+
public void setDeclaredSignatureId(int id) {
208+
declaredSignature = id;
209+
}
188210
}

javascript/extractor/src/com/semmle/js/ast/IFunction.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
import com.semmle.ts.ast.DecoratorList;
44
import com.semmle.ts.ast.INodeWithSymbol;
55
import com.semmle.ts.ast.ITypeExpression;
6+
import com.semmle.ts.ast.ITypedAstNode;
67
import com.semmle.ts.ast.TypeParameter;
78
import java.util.List;
89

910
/** A function declaration or expression. */
10-
public interface IFunction extends IStatementContainer, INodeWithSymbol {
11+
public interface IFunction extends IStatementContainer, INodeWithSymbol, ITypedAstNode {
1112
/** The function name; may be null for function expressions. */
1213
public Identifier getId();
1314

@@ -63,4 +64,15 @@ public interface IFunction extends IStatementContainer, INodeWithSymbol {
6364
public List<DecoratorList> getParameterDecorators();
6465

6566
public boolean hasDeclareKeyword();
67+
68+
/**
69+
* Gets the type signature of this function as determined by the TypeScript compiler, or -1 if no
70+
* call signature was extracted.
71+
*
72+
* <p>The ID refers to a signature in a table that is extracted on a per-project basis, and the
73+
* meaning of this type ID is not available at the AST level.
74+
*/
75+
public int getDeclaredSignatureId();
76+
77+
public void setDeclaredSignatureId(int id);
6678
}

javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ public Label visit(FunctionDeclaration nd, Context c) {
762762
trapwriter.addTuple("hasDeclareKeyword", key);
763763
}
764764
extractFunction(nd, key);
765+
emitStaticType(nd, key);
765766
return key;
766767
}
767768

@@ -833,7 +834,13 @@ private void extractFunction(IFunction nd, Label key) {
833834
extractParameterDefaultsAndTypes(nd, key, i);
834835

835836
extractFunctionAttributes(nd, key);
837+
838+
// Extract associated symbol and signature
836839
emitNodeSymbol(nd, key);
840+
if (nd.getDeclaredSignatureId() != -1) {
841+
Label signatureKey = trapwriter.globalID("signature;" + nd.getDeclaredSignatureId());
842+
trapwriter.addTuple("declared_function_signature", key, signatureKey);
843+
}
837844

838845
boolean oldIsStrict = isStrict;
839846
isStrict = bodyIsStrict;

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
package com.semmle.js.extractor;
22

3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.ArrayList;
6+
import java.util.LinkedHashSet;
7+
import java.util.List;
8+
import java.util.Set;
9+
import java.util.regex.Pattern;
10+
311
import com.semmle.js.extractor.ExtractorConfig.HTMLHandling;
412
import com.semmle.js.extractor.ExtractorConfig.Platform;
513
import com.semmle.js.extractor.ExtractorConfig.SourceType;
@@ -23,21 +31,14 @@
2331
import com.semmle.util.process.ArgsParser;
2432
import com.semmle.util.process.ArgsParser.FileMode;
2533
import com.semmle.util.trap.TrapWriter;
26-
import java.io.File;
27-
import java.io.IOException;
28-
import java.util.ArrayList;
29-
import java.util.LinkedHashSet;
30-
import java.util.List;
31-
import java.util.Set;
32-
import java.util.regex.Pattern;
3334

3435
/** The main entry point of the JavaScript extractor. */
3536
public class Main {
3637
/**
3738
* A version identifier that should be updated every time the extractor changes in such a way that
3839
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
3940
*/
40-
public static final String EXTRACTOR_VERSION = "2019-09-13";
41+
public static final String EXTRACTOR_VERSION = "2019-09-18";
4142

4243
public static final Pattern NEWLINE = Pattern.compile("\n");
4344

0 commit comments

Comments
 (0)