mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
TS: Extract type alias relation
This commit is contained in:
@@ -102,6 +102,16 @@ interface PropertyLookupTable {
|
||||
propertyTypes: number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes `(aliasType, underlyingType)` tuples as two staggered arrays.
|
||||
*
|
||||
* Such a tuple denotes that `aliasType` is an alias for `underlyingType`.
|
||||
*/
|
||||
interface TypeAliasTable {
|
||||
aliasTypes: number[];
|
||||
underlyingTypes: number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes type signature tuples `(baseType, kind, index, signature)` as four
|
||||
* staggered arrays.
|
||||
@@ -287,6 +297,11 @@ export class TypeTable {
|
||||
propertyTypes: [],
|
||||
};
|
||||
|
||||
private typeAliases: TypeAliasTable = {
|
||||
aliasTypes: [],
|
||||
underlyingTypes: [],
|
||||
};
|
||||
|
||||
private signatureMappings: SignatureTable = {
|
||||
baseTypes: [],
|
||||
kinds: [],
|
||||
@@ -304,7 +319,7 @@ export class TypeTable {
|
||||
propertyTypes: [],
|
||||
};
|
||||
|
||||
private buildTypeWorklist: [ts.Type, number][] = [];
|
||||
private buildTypeWorklist: [ts.Type, number, boolean][] = [];
|
||||
|
||||
private expansiveTypes: Map<number, boolean> = new Map();
|
||||
|
||||
@@ -409,7 +424,7 @@ export class TypeTable {
|
||||
id = this.typeIds.size;
|
||||
this.typeIds.set(content, id);
|
||||
this.typeToStringValues.push(stringValue);
|
||||
this.buildTypeWorklist.push([type, id]);
|
||||
this.buildTypeWorklist.push([type, id, unfoldAlias]);
|
||||
this.typeExtractionState.push(
|
||||
this.isInShallowTypeContext ? TypeExtractionState.PendingShallow : TypeExtractionState.PendingFull);
|
||||
// If the type is the self-type for a named type (not a generic instantiation of it),
|
||||
@@ -426,7 +441,7 @@ export class TypeTable {
|
||||
this.typeExtractionState[id] = TypeExtractionState.PendingFull;
|
||||
} else if (state === TypeExtractionState.DoneShallow) {
|
||||
this.typeExtractionState[id] = TypeExtractionState.PendingFull;
|
||||
this.buildTypeWorklist.push([type, id]);
|
||||
this.buildTypeWorklist.push([type, id, unfoldAlias]);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
@@ -789,6 +804,7 @@ export class TypeTable {
|
||||
typeStrings: Array.from(this.typeIds.keys()),
|
||||
typeToStringValues: this.typeToStringValues,
|
||||
propertyLookups: this.propertyLookups,
|
||||
typeAliases: this.typeAliases,
|
||||
symbolStrings: Array.from(this.symbolIds.keys()),
|
||||
moduleMappings: this.moduleMappings,
|
||||
globalMappings: this.globalMappings,
|
||||
@@ -812,10 +828,17 @@ export class TypeTable {
|
||||
let worklist = this.buildTypeWorklist;
|
||||
let typeExtractionState = this.typeExtractionState;
|
||||
while (worklist.length > 0) {
|
||||
let [type, id] = worklist.pop();
|
||||
let [type, id, unfoldAlias] = worklist.pop();
|
||||
let isShallowContext = typeExtractionState[id] === TypeExtractionState.PendingShallow;
|
||||
if (isShallowContext && !isTypeAlwaysSafeToExpand(type)) {
|
||||
typeExtractionState[id] = TypeExtractionState.DoneShallow;
|
||||
} else if (type.aliasSymbol != null && !unfoldAlias) {
|
||||
typeExtractionState[id] = TypeExtractionState.DoneFull;
|
||||
let underlyingTypeId = this.getId(type, true);
|
||||
if (underlyingTypeId != null) {
|
||||
this.typeAliases.aliasTypes.push(id);
|
||||
this.typeAliases.underlyingTypes.push(underlyingTypeId);
|
||||
}
|
||||
} else {
|
||||
typeExtractionState[id] = TypeExtractionState.DoneFull;
|
||||
this.isInShallowTypeContext = isShallowContext || this.isExpansiveTypeReference(type);
|
||||
|
||||
@@ -81,6 +81,7 @@ public class TypeExtractor {
|
||||
extractType(i);
|
||||
}
|
||||
extractPropertyLookups(table.getPropertyLookups());
|
||||
extractTypeAliases(table.getTypeAliases());
|
||||
for (int i = 0; i < table.getNumberOfSymbols(); ++i) {
|
||||
extractSymbol(i);
|
||||
}
|
||||
@@ -161,6 +162,19 @@ public class TypeExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTypeAliases(JsonObject aliases) {
|
||||
JsonArray aliasTypes = aliases.get("aliasTypes").getAsJsonArray();
|
||||
JsonArray underlyingTypes = aliases.get("underlyingTypes").getAsJsonArray();
|
||||
for (int i = 0; i < aliasTypes.size(); ++i) {
|
||||
int aliasType = aliasTypes.get(i).getAsInt();
|
||||
int underlyingType = underlyingTypes.get(i).getAsInt();
|
||||
trapWriter.addTuple(
|
||||
"type_alias",
|
||||
trapWriter.globalID("type;" + aliasType),
|
||||
trapWriter.globalID("type;" + underlyingType));
|
||||
}
|
||||
}
|
||||
|
||||
private void extractSymbol(int index) {
|
||||
// Format is: kind;decl;parent;name
|
||||
String[] parts = split(table.getSymbolString(index), 4);
|
||||
|
||||
@@ -12,6 +12,7 @@ public class TypeTable {
|
||||
private final JsonArray typeStrings;
|
||||
private final JsonArray typeToStringValues;
|
||||
private final JsonObject propertyLookups;
|
||||
private final JsonObject typeAliases;
|
||||
private final JsonArray symbolStrings;
|
||||
private final JsonObject moduleMappings;
|
||||
private final JsonObject globalMappings;
|
||||
@@ -27,6 +28,7 @@ public class TypeTable {
|
||||
this.typeStrings = typeTable.get("typeStrings").getAsJsonArray();
|
||||
this.typeToStringValues = typeTable.get("typeToStringValues").getAsJsonArray();
|
||||
this.propertyLookups = typeTable.get("propertyLookups").getAsJsonObject();
|
||||
this.typeAliases = typeTable.get("typeAliases").getAsJsonObject();
|
||||
this.symbolStrings = typeTable.get("symbolStrings").getAsJsonArray();
|
||||
this.moduleMappings = typeTable.get("moduleMappings").getAsJsonObject();
|
||||
this.globalMappings = typeTable.get("globalMappings").getAsJsonObject();
|
||||
@@ -51,6 +53,10 @@ public class TypeTable {
|
||||
return propertyLookups;
|
||||
}
|
||||
|
||||
public JsonObject getTypeAliases() {
|
||||
return typeAliases;
|
||||
}
|
||||
|
||||
public int getNumberOfTypes() {
|
||||
return typeStrings.size();
|
||||
}
|
||||
|
||||
@@ -2287,6 +2287,24 @@ class EnumLiteralType extends TypeReference {
|
||||
EnumMember getEnumMember() { result = declaration }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type that refers to a type alias.
|
||||
*/
|
||||
class TypeAliasReference extends TypeReference {
|
||||
TypeAliasReference() {
|
||||
type_alias(this, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type behind the type alias.
|
||||
*
|
||||
* For example, for `type B<T> = T[][]`, this maps the type `B<number>` to `number[][]`.
|
||||
*/
|
||||
Type getAliasedType() {
|
||||
type_alias(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An anonymous interface type, such as `{ x: number }`.
|
||||
*/
|
||||
|
||||
@@ -703,6 +703,10 @@ type_property(
|
||||
varchar(900) name: string ref,
|
||||
int propertyType: @type ref);
|
||||
|
||||
type_alias(
|
||||
unique int aliasType: @type ref,
|
||||
int underlyingType: @type ref);
|
||||
|
||||
@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype | @bigintliteraltype;
|
||||
@type_with_literal_value = @stringliteraltype | @numberliteraltype | @bigintliteraltype;
|
||||
type_literal_value(
|
||||
|
||||
@@ -3,6 +3,13 @@ rightHandSide
|
||||
| tst.ts:2:1:2:16 | type B<T> = T[]; | T[] |
|
||||
| tst.ts:8:10:8:20 | type C = A; | number |
|
||||
| tst.ts:15:1:15:23 | type Un ... \| Two; | One \| Two |
|
||||
getAliasedType
|
||||
| B<T> | T[] |
|
||||
| B<number> | number[] |
|
||||
| Union | One \| Two |
|
||||
getTypeArgument
|
||||
| B<T> | 0 | T |
|
||||
| B<number> | 0 | number |
|
||||
#select
|
||||
| tst.ts:1:1:1:16 | type A = number; | tst.ts:1:6:1:6 | A | 0 | tst.ts:1:10:1:15 | number |
|
||||
| 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[] |
|
||||
|
||||
@@ -6,3 +6,11 @@ select decl, decl.getIdentifier(), decl.getNumTypeParameter(), decl.getDefinitio
|
||||
query Type rightHandSide(TypeAliasDeclaration decl) {
|
||||
result = decl.getDefinition().getType()
|
||||
}
|
||||
|
||||
query Type getAliasedType(TypeAliasReference ref) {
|
||||
result = ref.getAliasedType()
|
||||
}
|
||||
|
||||
query Type getTypeArgument(TypeAliasReference ref, int n) {
|
||||
result = ref.getTypeArgument(n)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user