Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e25ee18

Browse files
committed
TS: Extract type alias relation
1 parent f11dc11 commit e25ee18

7 files changed

Lines changed: 84 additions & 4 deletions

File tree

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ interface PropertyLookupTable {
102102
propertyTypes: number[];
103103
}
104104

105+
/**
106+
* Encodes `(aliasType, underlyingType)` tuples as two staggered arrays.
107+
*
108+
* Such a tuple denotes that `aliasType` is an alias for `underlyingType`.
109+
*/
110+
interface TypeAliasTable {
111+
aliasTypes: number[];
112+
underlyingTypes: number[];
113+
}
114+
105115
/**
106116
* Encodes type signature tuples `(baseType, kind, index, signature)` as four
107117
* staggered arrays.
@@ -287,6 +297,11 @@ export class TypeTable {
287297
propertyTypes: [],
288298
};
289299

300+
private typeAliases: TypeAliasTable = {
301+
aliasTypes: [],
302+
underlyingTypes: [],
303+
};
304+
290305
private signatureMappings: SignatureTable = {
291306
baseTypes: [],
292307
kinds: [],
@@ -304,7 +319,7 @@ export class TypeTable {
304319
propertyTypes: [],
305320
};
306321

307-
private buildTypeWorklist: [ts.Type, number][] = [];
322+
private buildTypeWorklist: [ts.Type, number, boolean][] = [];
308323

309324
private expansiveTypes: Map<number, boolean> = new Map();
310325

@@ -409,7 +424,7 @@ export class TypeTable {
409424
id = this.typeIds.size;
410425
this.typeIds.set(content, id);
411426
this.typeToStringValues.push(stringValue);
412-
this.buildTypeWorklist.push([type, id]);
427+
this.buildTypeWorklist.push([type, id, unfoldAlias]);
413428
this.typeExtractionState.push(
414429
this.isInShallowTypeContext ? TypeExtractionState.PendingShallow : TypeExtractionState.PendingFull);
415430
// If the type is the self-type for a named type (not a generic instantiation of it),
@@ -426,7 +441,7 @@ export class TypeTable {
426441
this.typeExtractionState[id] = TypeExtractionState.PendingFull;
427442
} else if (state === TypeExtractionState.DoneShallow) {
428443
this.typeExtractionState[id] = TypeExtractionState.PendingFull;
429-
this.buildTypeWorklist.push([type, id]);
444+
this.buildTypeWorklist.push([type, id, unfoldAlias]);
430445
}
431446
}
432447
return id;
@@ -789,6 +804,7 @@ export class TypeTable {
789804
typeStrings: Array.from(this.typeIds.keys()),
790805
typeToStringValues: this.typeToStringValues,
791806
propertyLookups: this.propertyLookups,
807+
typeAliases: this.typeAliases,
792808
symbolStrings: Array.from(this.symbolIds.keys()),
793809
moduleMappings: this.moduleMappings,
794810
globalMappings: this.globalMappings,
@@ -812,10 +828,17 @@ export class TypeTable {
812828
let worklist = this.buildTypeWorklist;
813829
let typeExtractionState = this.typeExtractionState;
814830
while (worklist.length > 0) {
815-
let [type, id] = worklist.pop();
831+
let [type, id, unfoldAlias] = worklist.pop();
816832
let isShallowContext = typeExtractionState[id] === TypeExtractionState.PendingShallow;
817833
if (isShallowContext && !isTypeAlwaysSafeToExpand(type)) {
818834
typeExtractionState[id] = TypeExtractionState.DoneShallow;
835+
} else if (type.aliasSymbol != null && !unfoldAlias) {
836+
typeExtractionState[id] = TypeExtractionState.DoneFull;
837+
let underlyingTypeId = this.getId(type, true);
838+
if (underlyingTypeId != null) {
839+
this.typeAliases.aliasTypes.push(id);
840+
this.typeAliases.underlyingTypes.push(underlyingTypeId);
841+
}
819842
} else {
820843
typeExtractionState[id] = TypeExtractionState.DoneFull;
821844
this.isInShallowTypeContext = isShallowContext || this.isExpansiveTypeReference(type);

javascript/extractor/src/com/semmle/ts/extractor/TypeExtractor.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public void extract() {
8181
extractType(i);
8282
}
8383
extractPropertyLookups(table.getPropertyLookups());
84+
extractTypeAliases(table.getTypeAliases());
8485
for (int i = 0; i < table.getNumberOfSymbols(); ++i) {
8586
extractSymbol(i);
8687
}
@@ -161,6 +162,19 @@ private void extractPropertyLookups(JsonObject lookups) {
161162
}
162163
}
163164

165+
private void extractTypeAliases(JsonObject aliases) {
166+
JsonArray aliasTypes = aliases.get("aliasTypes").getAsJsonArray();
167+
JsonArray underlyingTypes = aliases.get("underlyingTypes").getAsJsonArray();
168+
for (int i = 0; i < aliasTypes.size(); ++i) {
169+
int aliasType = aliasTypes.get(i).getAsInt();
170+
int underlyingType = underlyingTypes.get(i).getAsInt();
171+
trapWriter.addTuple(
172+
"type_alias",
173+
trapWriter.globalID("type;" + aliasType),
174+
trapWriter.globalID("type;" + underlyingType));
175+
}
176+
}
177+
164178
private void extractSymbol(int index) {
165179
// Format is: kind;decl;parent;name
166180
String[] parts = split(table.getSymbolString(index), 4);

javascript/extractor/src/com/semmle/ts/extractor/TypeTable.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class TypeTable {
1212
private final JsonArray typeStrings;
1313
private final JsonArray typeToStringValues;
1414
private final JsonObject propertyLookups;
15+
private final JsonObject typeAliases;
1516
private final JsonArray symbolStrings;
1617
private final JsonObject moduleMappings;
1718
private final JsonObject globalMappings;
@@ -27,6 +28,7 @@ public TypeTable(JsonObject typeTable) {
2728
this.typeStrings = typeTable.get("typeStrings").getAsJsonArray();
2829
this.typeToStringValues = typeTable.get("typeToStringValues").getAsJsonArray();
2930
this.propertyLookups = typeTable.get("propertyLookups").getAsJsonObject();
31+
this.typeAliases = typeTable.get("typeAliases").getAsJsonObject();
3032
this.symbolStrings = typeTable.get("symbolStrings").getAsJsonArray();
3133
this.moduleMappings = typeTable.get("moduleMappings").getAsJsonObject();
3234
this.globalMappings = typeTable.get("globalMappings").getAsJsonObject();
@@ -51,6 +53,10 @@ public JsonObject getPropertyLookups() {
5153
return propertyLookups;
5254
}
5355

56+
public JsonObject getTypeAliases() {
57+
return typeAliases;
58+
}
59+
5460
public int getNumberOfTypes() {
5561
return typeStrings.size();
5662
}

javascript/ql/src/semmle/javascript/TypeScript.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,24 @@ class EnumLiteralType extends TypeReference {
22872287
EnumMember getEnumMember() { result = declaration }
22882288
}
22892289

2290+
/**
2291+
* A type that refers to a type alias.
2292+
*/
2293+
class TypeAliasReference extends TypeReference {
2294+
TypeAliasReference() {
2295+
type_alias(this, _)
2296+
}
2297+
2298+
/**
2299+
* Gets the type behind the type alias.
2300+
*
2301+
* For example, for `type B<T> = T[][]`, this maps the type `B<number>` to `number[][]`.
2302+
*/
2303+
Type getAliasedType() {
2304+
type_alias(this, result)
2305+
}
2306+
}
2307+
22902308
/**
22912309
* An anonymous interface type, such as `{ x: number }`.
22922310
*/

javascript/ql/src/semmlecode.javascript.dbscheme

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ type_property(
703703
varchar(900) name: string ref,
704704
int propertyType: @type ref);
705705

706+
type_alias(
707+
unique int aliasType: @type ref,
708+
int underlyingType: @type ref);
709+
706710
@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype | @bigintliteraltype;
707711
@type_with_literal_value = @stringliteraltype | @numberliteraltype | @bigintliteraltype;
708712
type_literal_value(

javascript/ql/test/library-tests/TypeScript/TypeAliases/TypeAliases.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ rightHandSide
33
| tst.ts:2:1:2:16 | type B<T> = T[]; | T[] |
44
| tst.ts:8:10:8:20 | type C = A; | number |
55
| tst.ts:15:1:15:23 | type Un ... \| Two; | One \| Two |
6+
getAliasedType
7+
| B<T> | T[] |
8+
| B<number> | number[] |
9+
| Union | One \| Two |
10+
getTypeArgument
11+
| B<T> | 0 | T |
12+
| B<number> | 0 | number |
613
#select
714
| tst.ts:1:1:1:16 | type A = number; | tst.ts:1:6:1:6 | A | 0 | tst.ts:1:10:1:15 | number |
815
| tst.ts:2:1:2:16 | type B<T> = T[]; | tst.ts:2:6:2:6 | B | 1 | tst.ts:2:13:2:15 | T[] |

javascript/ql/test/library-tests/TypeScript/TypeAliases/TypeAliases.ql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,11 @@ select decl, decl.getIdentifier(), decl.getNumTypeParameter(), decl.getDefinitio
66
query Type rightHandSide(TypeAliasDeclaration decl) {
77
result = decl.getDefinition().getType()
88
}
9+
10+
query Type getAliasedType(TypeAliasReference ref) {
11+
result = ref.getAliasedType()
12+
}
13+
14+
query Type getTypeArgument(TypeAliasReference ref, int n) {
15+
result = ref.getTypeArgument(n)
16+
}

0 commit comments

Comments
 (0)