Swift: extract or ignore last remaining types

This commit is contained in:
Paolo Tranquilli
2022-11-10 17:35:32 +01:00
parent bda4b52395
commit 88dc65cb3c
26 changed files with 132 additions and 144 deletions

View File

@@ -25,6 +25,7 @@ using PackExprTag = void;
using PackTypeTag = void;
using ReifyPackExprTag = void;
using PackExpansionTypeTag = void;
using SequenceArchetypeTypeTag = void;
// Placeholder types appear in ambiguous types but are anyway transformed to UnresolvedType
using PlaceholderTypeTag = void;
// SIL types that cannot really appear in the frontend run
@@ -32,6 +33,8 @@ using SILBlockStorageTypeTag = void;
using SILBoxTypeTag = void;
using SILFunctionTypeTag = void;
using SILTokenTypeTag = void;
// This is created during type checking and is only used for constraint checking
using TypeVariableTypeTag = void;
#define MAP_TYPE_TO_TAG(TYPE, TAG) \
template <> \

View File

@@ -258,4 +258,20 @@ codeql::OpaqueTypeArchetypeType TypeTranslator::translateOpaqueTypeArchetypeType
entry.declaration = dispatcher.fetchLabel(type.getDecl());
return entry;
}
codeql::ErrorType TypeTranslator::translateErrorType(const swift::ErrorType& type) {
return createTypeEntry(type);
}
codeql::UnresolvedType TypeTranslator::translateUnresolvedType(const swift::UnresolvedType& type) {
return createTypeEntry(type);
}
codeql::ParameterizedProtocolType TypeTranslator::translateParameterizedProtocolType(
const swift::ParameterizedProtocolType& type) {
auto entry = createTypeEntry(type);
entry.base = dispatcher.fetchLabel(type.getBaseType());
entry.args = dispatcher.fetchRepeatedLabels(type.getArgs());
return entry;
}
} // namespace codeql

View File

@@ -71,6 +71,10 @@ class TypeTranslator : public TypeTranslatorBase<TypeTranslator> {
codeql::ModuleType translateModuleType(const swift::ModuleType& type);
codeql::OpaqueTypeArchetypeType translateOpaqueTypeArchetypeType(
const swift::OpaqueTypeArchetypeType& type);
codeql::ErrorType translateErrorType(const swift::ErrorType& type);
codeql::UnresolvedType translateUnresolvedType(const swift::UnresolvedType& type);
codeql::ParameterizedProtocolType translateParameterizedProtocolType(
const swift::ParameterizedProtocolType& type);
private:
void fillType(const swift::TypeBase& type, codeql::Type& entry);

View File

@@ -263,7 +263,6 @@ import codeql.swift.elements.type.PrimaryArchetypeType
import codeql.swift.elements.type.ProtocolCompositionType
import codeql.swift.elements.type.ProtocolType
import codeql.swift.elements.type.ReferenceStorageType
import codeql.swift.elements.type.SequenceArchetypeType
import codeql.swift.elements.type.StructType
import codeql.swift.elements.type.SubstitutableType
import codeql.swift.elements.type.SugarType
@@ -272,7 +271,6 @@ import codeql.swift.elements.type.TupleType
import codeql.swift.elements.type.Type
import codeql.swift.elements.type.TypeAliasType
import codeql.swift.elements.type.TypeRepr
import codeql.swift.elements.type.TypeVariableType
import codeql.swift.elements.type.UnarySyntaxSugarType
import codeql.swift.elements.type.UnboundGenericType
import codeql.swift.elements.type.UnmanagedStorageType

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.type.SequenceArchetypeType
class SequenceArchetypeType extends Generated::SequenceArchetypeType { }

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.Raw
predicate constructSequenceArchetypeType(Raw::SequenceArchetypeType id) { any() }

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.type.TypeVariableType
class TypeVariableType extends Generated::TypeVariableType { }

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.Raw
predicate constructTypeVariableType(Raw::TypeVariableType id) { any() }

View File

@@ -3953,21 +3953,6 @@ private module Impl {
)
}
private Element getImmediateChildOfTypeVariableType(
TypeVariableType e, int index, string partialPredicateCall
) {
exists(int b, int bType, int n |
b = 0 and
bType = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfType(e, i, _)) | i) and
n = bType and
(
none()
or
result = getImmediateChildOfType(e, index - b, partialPredicateCall)
)
)
}
private Element getImmediateChildOfUnresolvedType(
UnresolvedType e, int index, string partialPredicateCall
) {
@@ -4522,22 +4507,6 @@ private module Impl {
)
}
private Element getImmediateChildOfSequenceArchetypeType(
SequenceArchetypeType e, int index, string partialPredicateCall
) {
exists(int b, int bArchetypeType, int n |
b = 0 and
bArchetypeType =
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfArchetypeType(e, i, _)) | i) and
n = bArchetypeType and
(
none()
or
result = getImmediateChildOfArchetypeType(e, index - b, partialPredicateCall)
)
)
}
private Element getImmediateChildOfUnarySyntaxSugarType(
UnarySyntaxSugarType e, int index, string partialPredicateCall
) {
@@ -5088,8 +5057,6 @@ private module Impl {
or
result = getImmediateChildOfTupleType(e, index, partialAccessor)
or
result = getImmediateChildOfTypeVariableType(e, index, partialAccessor)
or
result = getImmediateChildOfUnresolvedType(e, index, partialAccessor)
or
result = getImmediateChildOfBuiltinBridgeObjectType(e, index, partialAccessor)
@@ -5146,8 +5113,6 @@ private module Impl {
or
result = getImmediateChildOfPrimaryArchetypeType(e, index, partialAccessor)
or
result = getImmediateChildOfSequenceArchetypeType(e, index, partialAccessor)
or
result = getImmediateChildOfArraySliceType(e, index, partialAccessor)
or
result = getImmediateChildOfBoundGenericClassType(e, index, partialAccessor)

View File

@@ -1302,6 +1302,10 @@ module Raw {
class ParameterizedProtocolType extends @parameterized_protocol_type, Type {
override string toString() { result = "ParameterizedProtocolType" }
ProtocolType getBase() { parameterized_protocol_types(this, result) }
Type getArg(int index) { parameterized_protocol_type_args(this, index, result) }
}
class ProtocolCompositionType extends @protocol_composition_type, Type {
@@ -1326,10 +1330,6 @@ module Raw {
string getName(int index) { tuple_type_names(this, index, result) }
}
class TypeVariableType extends @type_variable_type, Type {
override string toString() { result = "TypeVariableType" }
}
class UnresolvedType extends @unresolved_type, Type, UnresolvedElement {
override string toString() { result = "UnresolvedType" }
}
@@ -1479,10 +1479,6 @@ module Raw {
override string toString() { result = "PrimaryArchetypeType" }
}
class SequenceArchetypeType extends @sequence_archetype_type, ArchetypeType {
override string toString() { result = "SequenceArchetypeType" }
}
class UnarySyntaxSugarType extends @unary_syntax_sugar_type, SyntaxSugarType {
Type getBaseType() { unary_syntax_sugar_types(this, result) }
}

View File

@@ -290,12 +290,10 @@ module Synth {
constructProtocolCompositionType(id)
} or
TProtocolType(Raw::ProtocolType id) { constructProtocolType(id) } or
TSequenceArchetypeType(Raw::SequenceArchetypeType id) { constructSequenceArchetypeType(id) } or
TStructType(Raw::StructType id) { constructStructType(id) } or
TTupleType(Raw::TupleType id) { constructTupleType(id) } or
TTypeAliasType(Raw::TypeAliasType id) { constructTypeAliasType(id) } or
TTypeRepr(Raw::TypeRepr id) { constructTypeRepr(id) } or
TTypeVariableType(Raw::TypeVariableType id) { constructTypeVariableType(id) } or
TUnboundGenericType(Raw::UnboundGenericType id) { constructUnboundGenericType(id) } or
TUnmanagedStorageType(Raw::UnmanagedStorageType id) { constructUnmanagedStorageType(id) } or
TUnownedStorageType(Raw::UnownedStorageType id) { constructUnownedStorageType(id) } or
@@ -435,9 +433,7 @@ module Synth {
class TAnyMetatypeType = TExistentialMetatypeType or TMetatypeType;
class TArchetypeType =
TOpaqueTypeArchetypeType or TOpenedArchetypeType or TPrimaryArchetypeType or
TSequenceArchetypeType;
class TArchetypeType = TOpaqueTypeArchetypeType or TOpenedArchetypeType or TPrimaryArchetypeType;
class TBoundGenericType =
TBoundGenericClassType or TBoundGenericEnumType or TBoundGenericStructType;
@@ -464,8 +460,7 @@ module Synth {
TAnyFunctionType or TAnyGenericType or TAnyMetatypeType or TBuiltinType or
TDependentMemberType or TDynamicSelfType or TErrorType or TExistentialType or TInOutType or
TLValueType or TModuleType or TParameterizedProtocolType or TProtocolCompositionType or
TReferenceStorageType or TSubstitutableType or TSugarType or TTupleType or
TTypeVariableType or TUnresolvedType;
TReferenceStorageType or TSubstitutableType or TSugarType or TTupleType or TUnresolvedType;
class TUnarySyntaxSugarType = TArraySliceType or TOptionalType or TVariadicSequenceType;
@@ -1308,11 +1303,6 @@ module Synth {
cached
TProtocolType convertProtocolTypeFromRaw(Raw::Element e) { result = TProtocolType(e) }
cached
TSequenceArchetypeType convertSequenceArchetypeTypeFromRaw(Raw::Element e) {
result = TSequenceArchetypeType(e)
}
cached
TStructType convertStructTypeFromRaw(Raw::Element e) { result = TStructType(e) }
@@ -1325,9 +1315,6 @@ module Synth {
cached
TTypeRepr convertTypeReprFromRaw(Raw::Element e) { result = TTypeRepr(e) }
cached
TTypeVariableType convertTypeVariableTypeFromRaw(Raw::Element e) { result = TTypeVariableType(e) }
cached
TUnboundGenericType convertUnboundGenericTypeFromRaw(Raw::Element e) {
result = TUnboundGenericType(e)
@@ -1970,8 +1957,6 @@ module Synth {
result = convertOpenedArchetypeTypeFromRaw(e)
or
result = convertPrimaryArchetypeTypeFromRaw(e)
or
result = convertSequenceArchetypeTypeFromRaw(e)
}
cached
@@ -2094,8 +2079,6 @@ module Synth {
or
result = convertTupleTypeFromRaw(e)
or
result = convertTypeVariableTypeFromRaw(e)
or
result = convertUnresolvedTypeFromRaw(e)
}
@@ -2945,11 +2928,6 @@ module Synth {
cached
Raw::Element convertProtocolTypeToRaw(TProtocolType e) { e = TProtocolType(result) }
cached
Raw::Element convertSequenceArchetypeTypeToRaw(TSequenceArchetypeType e) {
e = TSequenceArchetypeType(result)
}
cached
Raw::Element convertStructTypeToRaw(TStructType e) { e = TStructType(result) }
@@ -2962,9 +2940,6 @@ module Synth {
cached
Raw::Element convertTypeReprToRaw(TTypeRepr e) { e = TTypeRepr(result) }
cached
Raw::Element convertTypeVariableTypeToRaw(TTypeVariableType e) { e = TTypeVariableType(result) }
cached
Raw::Element convertUnboundGenericTypeToRaw(TUnboundGenericType e) {
e = TUnboundGenericType(result)
@@ -3607,8 +3582,6 @@ module Synth {
result = convertOpenedArchetypeTypeToRaw(e)
or
result = convertPrimaryArchetypeTypeToRaw(e)
or
result = convertSequenceArchetypeTypeToRaw(e)
}
cached
@@ -3731,8 +3704,6 @@ module Synth {
or
result = convertTupleTypeToRaw(e)
or
result = convertTypeVariableTypeToRaw(e)
or
result = convertUnresolvedTypeToRaw(e)
}

View File

@@ -212,12 +212,10 @@ import codeql.swift.elements.type.ParenTypeConstructor
import codeql.swift.elements.type.PrimaryArchetypeTypeConstructor
import codeql.swift.elements.type.ProtocolCompositionTypeConstructor
import codeql.swift.elements.type.ProtocolTypeConstructor
import codeql.swift.elements.type.SequenceArchetypeTypeConstructor
import codeql.swift.elements.type.StructTypeConstructor
import codeql.swift.elements.type.TupleTypeConstructor
import codeql.swift.elements.type.TypeAliasTypeConstructor
import codeql.swift.elements.type.TypeReprConstructor
import codeql.swift.elements.type.TypeVariableTypeConstructor
import codeql.swift.elements.type.UnboundGenericTypeConstructor
import codeql.swift.elements.type.UnmanagedStorageTypeConstructor
import codeql.swift.elements.type.UnownedStorageTypeConstructor

View File

@@ -1,10 +1,62 @@
// generated by codegen/codegen.py
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.type.ProtocolType
import codeql.swift.elements.type.Type
module Generated {
/**
* A sugar type of the form `P<X>` with `P` a protocol.
*
* If `P` has primary associated type `A`, then `T: P<X>` is a shortcut for `T: P where T.A == X`.
*/
class ParameterizedProtocolType extends Synth::TParameterizedProtocolType, Type {
override string getAPrimaryQlClass() { result = "ParameterizedProtocolType" }
/**
* Gets the base of this parameterized protocol type.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
ProtocolType getImmediateBase() {
result =
Synth::convertProtocolTypeFromRaw(Synth::convertParameterizedProtocolTypeToRaw(this)
.(Raw::ParameterizedProtocolType)
.getBase())
}
/**
* Gets the base of this parameterized protocol type.
*/
final ProtocolType getBase() { result = getImmediateBase().resolve() }
/**
* Gets the `index`th argument of this parameterized protocol type (0-based).
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
Type getImmediateArg(int index) {
result =
Synth::convertTypeFromRaw(Synth::convertParameterizedProtocolTypeToRaw(this)
.(Raw::ParameterizedProtocolType)
.getArg(index))
}
/**
* Gets the `index`th argument of this parameterized protocol type (0-based).
*/
final Type getArg(int index) { result = getImmediateArg(index).resolve() }
/**
* Gets any of the arguments of this parameterized protocol type.
*/
final Type getAnArg() { result = getArg(_) }
/**
* Gets the number of arguments of this parameterized protocol type.
*/
final int getNumberOfArgs() { result = count(getAnArg()) }
}
}

View File

@@ -1,10 +0,0 @@
// generated by codegen/codegen.py
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.type.ArchetypeType
module Generated {
class SequenceArchetypeType extends Synth::TSequenceArchetypeType, ArchetypeType {
override string getAPrimaryQlClass() { result = "SequenceArchetypeType" }
}
}

View File

@@ -1,10 +0,0 @@
// generated by codegen/codegen.py
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.type.Type
module Generated {
class TypeVariableType extends Synth::TTypeVariableType, Type {
override string getAPrimaryQlClass() { result = "TypeVariableType" }
}
}

View File

@@ -1841,7 +1841,6 @@ while_stmts( //dir=stmt
| @substitutable_type
| @sugar_type
| @tuple_type
| @type_variable_type
| @unresolved_type
;
@@ -1964,7 +1963,15 @@ module_types( //dir=type
);
parameterized_protocol_types( //dir=type
unique int id: @parameterized_protocol_type
unique int id: @parameterized_protocol_type,
int base: @protocol_type_or_none ref
);
#keyset[id, index]
parameterized_protocol_type_args( //dir=type
int id: @parameterized_protocol_type ref,
int index: int ref,
int arg: @type_or_none ref
);
protocol_composition_types( //dir=type
@@ -2019,10 +2026,6 @@ tuple_type_names( //dir=type
string name: string ref
);
type_variable_types( //dir=type
unique int id: @type_variable_type
);
unresolved_types( //dir=type
unique int id: @unresolved_type
);
@@ -2036,7 +2039,6 @@ unresolved_types( //dir=type
@opaque_type_archetype_type
| @opened_archetype_type
| @primary_archetype_type
| @sequence_archetype_type
;
#keyset[id]
@@ -2214,10 +2216,6 @@ primary_archetype_types( //dir=type
unique int id: @primary_archetype_type
);
sequence_archetype_types( //dir=type
unique int id: @sequence_archetype_type
);
@unary_syntax_sugar_type =
@array_slice_type
| @optional_type
@@ -2405,6 +2403,11 @@ variadic_sequence_types( //dir=type
| @unspecified_element
;
@protocol_type_or_none =
@protocol_type
| @unspecified_element
;
@stmt_or_none =
@stmt
| @unspecified_element

View File

@@ -6,6 +6,8 @@ predicate toBeTested(Element e) {
or
e instanceof AppliedPropertyWrapperExpr
or
e instanceof ParameterizedProtocolType
or
exists(ModuleDecl m |
m = e and
not m.isBuiltinModule() and

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1 @@
| P<Int, String> | getName: | P<Int, String> | getCanonicalType: | P<Int, String> | getBase: | P |

View File

@@ -0,0 +1,12 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParameterizedProtocolType x, string getName, Type getCanonicalType, ProtocolType getBase
where
toBeTested(x) and
not x.isUnknown() and
getName = x.getName() and
getCanonicalType = x.getCanonicalType() and
getBase = x.getBase()
select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getBase:", getBase

View File

@@ -0,0 +1,2 @@
| P<Int, String> | 0 | Int |
| P<Int, String> | 1 | String |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ParameterizedProtocolType x, int index
where toBeTested(x) and not x.isUnknown()
select x, index, x.getArg(index)

View File

@@ -0,0 +1,6 @@
protocol P<One, Two> {
associatedtype One;
associatedtype Two;
}
func foo<T: P<Int, String>>(_: T) {}

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -868,9 +868,6 @@ class TupleType(Type):
types: list[Type]
names: list[optional[string]]
class TypeVariableType(Type):
pass
class UnresolvedType(Type, UnresolvedElement):
pass
@@ -981,9 +978,6 @@ class OpenedArchetypeType(ArchetypeType):
class PrimaryArchetypeType(ArchetypeType):
pass
class SequenceArchetypeType(ArchetypeType):
pass
class UnarySyntaxSugarType(SyntaxSugarType):
base_type: Type
@@ -1018,4 +1012,10 @@ class VariadicSequenceType(UnarySyntaxSugarType):
pass
class ParameterizedProtocolType(Type):
pass
"""
A sugar type of the form `P<X>` with `P` a protocol.
If `P` has primary associated type `A`, then `T: P<X>` is a shortcut for `T: P where T.A == X`.
"""
base: ProtocolType
args: list[Type]