C#: Only use getTypeRef when there is not already a type available

This commit is contained in:
Tom Hvitved
2023-10-26 21:00:41 +02:00
parent a5bfeb68a8
commit 6ad8a4db1c
15 changed files with 187 additions and 40 deletions

View File

@@ -251,15 +251,21 @@ private int getElementTypeFlags(@has_type_annotation element) {
result = strictsum(int b | type_annotation(element, b) | b)
}
private predicate specificTypeParameterNullability(
TypeParameterConstraints constraints, Type type, @nullability n
) {
specific_type_parameter_nullability(constraints, type, n)
or
specific_type_parameter_nullability(constraints, getTypeRef(type), n)
}
private Annotations::Nullability getTypeParameterNullability(
TypeParameterConstraints constraints, Type type
) {
if specific_type_parameter_nullability(constraints, getTypeRef(type), _)
then
specific_type_parameter_nullability(constraints, getTypeRef(type),
Annotations::getNullability(result))
if specificTypeParameterNullability(constraints, type, _)
then specificTypeParameterNullability(constraints, type, Annotations::getNullability(result))
else (
specific_type_parameter_constraints(constraints, getTypeRef(type)) and
type = constraints.getATypeConstraint() and
result instanceof Annotations::NoNullability
)
}

View File

@@ -62,7 +62,12 @@ private string getAttributeName(Attribute a) {
*/
class Attribute extends TopLevelExprParent, @attribute {
/** Gets the type of this attribute. */
Class getType() { attributes(this, _, getTypeRef(result), _) }
Class getType() {
attributes(this, _, result, _)
or
not attributes(this, _, any(Type t), _) and
attributes(this, _, getTypeRef(result), _)
}
/** Gets the element that this attribute is attached to. */
Attributable getTarget() { attributes(this, _, _, result) }

View File

@@ -236,7 +236,12 @@ class Method extends Callable, Virtualizable, Attributable, @method {
override ValueOrRefType getDeclaringType() { methods(this, _, result, _, _) }
override Type getReturnType() { methods(this, _, _, getTypeRef(result), _) }
override Type getReturnType() {
methods(this, _, _, result, _)
or
not methods(this, _, _, any(Type t), _) and
methods(this, _, _, getTypeRef(result), _)
}
override Method getUnboundDeclaration() { methods(this, _, _, _, result) }
@@ -453,7 +458,12 @@ class Operator extends Callable, Member, Attributable, Overridable, @operator {
override ValueOrRefType getDeclaringType() { operators(this, _, _, result, _, _) }
override Type getReturnType() { operators(this, _, _, _, getTypeRef(result), _) }
override Type getReturnType() {
operators(this, _, _, _, result, _)
or
not operators(this, _, _, _, any(Type t), _) and
operators(this, _, _, _, getTypeRef(result), _)
}
override Operator getUnboundDeclaration() { operators(this, _, _, _, _, result) }

View File

@@ -23,7 +23,12 @@ class Event extends DeclarationWithAccessors, @event {
override ValueOrRefType getDeclaringType() { events(this, _, result, _, _) }
override DelegateType getType() { events(this, _, _, getTypeRef(result), _) }
override DelegateType getType() {
events(this, _, _, result, _)
or
not events(this, _, _, any(Type t), _) and
events(this, _, _, getTypeRef(result), _)
}
/** Gets an `add` or `remove` accessor of this event, if any. */
EventAccessor getAnEventAccessor() { result.getDeclaration() = this }

View File

@@ -261,7 +261,11 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
*/
class TypeParameterConstraints extends Element, @type_parameter_constraints {
/** Gets a specific type constraint, if any. */
Type getATypeConstraint() { specific_type_parameter_constraints(this, getTypeRef(result)) }
Type getATypeConstraint() {
specific_type_parameter_constraints(this, result)
or
specific_type_parameter_constraints(this, getTypeRef(result))
}
/** Gets an annotated specific type constraint, if any. */
AnnotatedType getAnAnnotatedTypeConstraint() { result.appliesToTypeConstraint(this) }
@@ -413,9 +417,19 @@ class ConstructedType extends ValueOrRefType, ConstructedGeneric {
override Location getALocation() { result = this.getUnboundDeclaration().getALocation() }
override Type getTypeArgument(int n) { type_arguments(getTypeRef(result), n, this) }
override Type getTypeArgument(int n) {
type_arguments(result, n, this)
or
not type_arguments(any(Type t), n, this) and
type_arguments(getTypeRef(result), n, this)
}
override UnboundGenericType getUnboundGeneric() { constructed_generic(this, getTypeRef(result)) }
override UnboundGenericType getUnboundGeneric() {
constructed_generic(this, result)
or
not constructed_generic(this, any(Type t)) and
constructed_generic(this, getTypeRef(result))
}
final override Type getChild(int n) { result = this.getTypeArgument(n) }
@@ -587,7 +601,12 @@ class UnboundGenericMethod extends Method, UnboundGeneric {
class ConstructedMethod extends Method, ConstructedGeneric {
override Location getALocation() { result = this.getUnboundDeclaration().getALocation() }
override Type getTypeArgument(int n) { type_arguments(getTypeRef(result), n, this) }
override Type getTypeArgument(int n) {
type_arguments(result, n, this)
or
not type_arguments(any(Type t), n, this) and
type_arguments(getTypeRef(result), n, this)
}
override UnboundGenericMethod getUnboundGeneric() { constructed_generic(this, result) }

View File

@@ -215,7 +215,12 @@ class Overridable extends Declaration, TOverridable {
* to members that can be declared on an interface, i.e. methods, properties,
* indexers and events.
*/
Interface getExplicitlyImplementedInterface() { explicitly_implements(this, getTypeRef(result)) }
Interface getExplicitlyImplementedInterface() {
explicitly_implements(this, result)
or
not explicitly_implements(this, any(Interface i)) and
explicitly_implements(this, getTypeRef(result))
}
/**
* Holds if this member implements an interface member explicitly.

View File

@@ -120,7 +120,12 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
override ValueOrRefType getDeclaringType() { properties(this, _, result, _, _) }
override Type getType() { properties(this, _, _, getTypeRef(result), _) }
override Type getType() {
properties(this, _, _, result, _)
or
not properties(this, _, _, any(Type t), _) and
properties(this, _, _, getTypeRef(result), _)
}
/**
* Holds if this property is automatically implemented. For example, `P1`
@@ -260,7 +265,12 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
override ValueOrRefType getDeclaringType() { indexers(this, _, result, _, _) }
override Type getType() { indexers(this, _, _, getTypeRef(result), _) }
override Type getType() {
indexers(this, _, _, result, _)
or
not indexers(this, _, _, any(Type t), _) and
indexers(this, _, _, getTypeRef(result), _)
}
override IndexerAccess getAnAccess() { result.getTarget() = this }

View File

@@ -984,7 +984,12 @@ class CatchClause extends Stmt, @catch {
* }
* ```
*/
ExceptionClass getCaughtExceptionType() { catch_type(this, getTypeRef(result), _) }
ExceptionClass getCaughtExceptionType() {
catch_type(this, result, _)
or
not catch_type(this, any(Type t), _) and
catch_type(this, getTypeRef(result), _)
}
/**
* Gets the `catch` filter clause, if any. For example, the filter expression

View File

@@ -110,9 +110,16 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
parent_namespace_declaration(this, result)
}
private Class getExplicitBaseClass() {
extend(this, result)
or
not extend(this, any(Class c)) and
extend(this, getTypeRef(result))
}
/** Gets the immediate base class of this class, if any. */
final Class getBaseClass() {
extend(this, getTypeRef(result))
result = this.getExplicitBaseClass()
or
not extend(this, _) and
not isObjectClass(this) and
@@ -122,7 +129,11 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
}
/** Gets an immediate base interface of this type, if any. */
Interface getABaseInterface() { implement(this, getTypeRef(result)) }
Interface getABaseInterface() {
implement(this, result)
or
implement(this, getTypeRef(result))
}
/** Gets an immediate base type of this type, if any. */
override ValueOrRefType getABaseType() {
@@ -672,7 +683,12 @@ class Enum extends ValueType, @enum_type {
* }
* ```
*/
IntegralType getUnderlyingType() { enum_underlying_type(this, getTypeRef(result)) }
IntegralType getUnderlyingType() {
enum_underlying_type(this, result)
or
not enum_underlying_type(this, any(Type t)) and
enum_underlying_type(this, getTypeRef(result))
}
/**
* Gets an `enum` constant declared in this `enum`, for example `Even`
@@ -855,7 +871,12 @@ class Interface extends RefType, @interface_type {
*/
class DelegateType extends RefType, Parameterizable, @delegate_type {
/** Gets the return type of this delegate. */
Type getReturnType() { delegate_return_type(this, getTypeRef(result)) }
Type getReturnType() {
delegate_return_type(this, result)
or
not delegate_return_type(this, any(Type t)) and
delegate_return_type(this, getTypeRef(result))
}
/** Gets the annotated return type of this delegate. */
AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
@@ -939,7 +960,12 @@ class UnmanagedCallingConvention extends CallingConvention {
*/
class FunctionPointerType extends Type, Parameterizable, @function_pointer_type {
/** Gets the return type of this function pointer. */
Type getReturnType() { function_pointer_return_type(this, getTypeRef(result)) }
Type getReturnType() {
function_pointer_return_type(this, result)
or
not function_pointer_return_type(this, any(Type t)) and
function_pointer_return_type(this, getTypeRef(result))
}
/** Gets the calling convention. */
CallingConvention getCallingConvention() {
@@ -950,6 +976,9 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
/** Gets the unmanaged calling convention at index `i`. */
Type getUnmanagedCallingConvention(int i) {
has_unmanaged_calling_conventions(this, i, result)
or
not has_unmanaged_calling_conventions(this, i, any(Type t)) and
has_unmanaged_calling_conventions(this, i, getTypeRef(result))
}
@@ -979,7 +1008,12 @@ class NullableType extends ValueType, ConstructedType, @nullable_type {
* Gets the underlying value type of this nullable type.
* For example `int` in `int?`.
*/
Type getUnderlyingType() { nullable_underlying_type(this, getTypeRef(result)) }
Type getUnderlyingType() {
nullable_underlying_type(this, result)
or
not nullable_underlying_type(this, any(Type t)) and
nullable_underlying_type(this, getTypeRef(result))
}
override UnboundGenericStruct getUnboundGeneric() {
result.hasQualifiedName("System", "Nullable<>")
@@ -1021,7 +1055,12 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
predicate isMultiDimensional() { this.getRank() > 1 }
/** Gets the element type of this array, for example `int` in `int[]`. */
override Type getElementType() { array_element_type(this, _, _, getTypeRef(result)) }
override Type getElementType() {
array_element_type(this, _, _, result)
or
not array_element_type(this, _, _, any(Type t)) and
array_element_type(this, _, _, getTypeRef(result))
}
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
predicate hasSameShapeAs(ArrayType that) {
@@ -1076,7 +1115,12 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
* A pointer type, for example `char*`.
*/
class PointerType extends DotNet::PointerType, Type, @pointer_type {
override Type getReferentType() { pointer_referent_type(this, getTypeRef(result)) }
override Type getReferentType() {
pointer_referent_type(this, result)
or
not pointer_referent_type(this, any(Type t)) and
pointer_referent_type(this, getTypeRef(result))
}
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
@@ -1134,7 +1178,12 @@ class UnknownType extends Type, @unknown_type {
*/
class TupleType extends ValueType, @tuple_type {
/** Gets the underlying type of this tuple, which is of type `System.ValueTuple`. */
Struct getUnderlyingType() { tuple_underlying_type(this, getTypeRef(result)) }
Struct getUnderlyingType() {
tuple_underlying_type(this, result)
or
not tuple_underlying_type(this, any(Type t)) and
tuple_underlying_type(this, getTypeRef(result))
}
/**
* Gets the `n`th element of this tuple, indexed from 0.
@@ -1196,7 +1245,11 @@ class TypeMention extends @type_mention {
Type type;
@type_mention_parent parent;
TypeMention() { type_mention(this, getTypeRef(type), parent) }
TypeMention() {
type_mention(this, type, parent)
or
type_mention(this, getTypeRef(type), parent)
}
/** Gets the type being mentioned. */
Type getType() { result = type }

View File

@@ -8,10 +8,13 @@ import csharp
/** A typeref is a reference to a type in some assembly. */
private class TypeRef extends @typeref {
/** Gets the name of type being referenced. */
string getName() { typerefs(this, result) }
/** Gets a textual representation of this type reference. */
string toString() { result = this.getName() }
/** Gets the type being referenced. */
Type getReferencedType() {
typeref_type(this, result)
or
@@ -27,8 +30,4 @@ private class TypeRef extends @typeref {
* This is used for extensionals that can be supplied
* as either type references or types.
*/
@type_or_ref getTypeRef(Type type) {
result = type
or
result.(TypeRef).getReferencedType() = type
}
TypeRef getTypeRef(Type type) { result.getReferencedType() = type }

View File

@@ -15,7 +15,7 @@ module Gvn {
* but only if the enclosing type is not a `GenericType`.
*/
string getNameNested(Type t) {
exists(string name | name = t.getName() |
exists(string name | name = t.getUndecoratedName() |
if not t instanceof NestedType or t.(NestedType).getDeclaringType() instanceof GenericType
then result = name
else result = getNameNested(t.(NestedType).getDeclaringType()) + "+" + name
@@ -267,7 +267,7 @@ module Gvn {
or
this.isDeclaringTypeAt(i) and j = 1 and result = "."
else (
j = 0 and result = name.prefix(name.length() - children - 1) + "<"
j = 0 and result = name + "<"
or
j in [1 .. 2 * children - 1] and
if j % 2 = 0

View File

@@ -64,7 +64,12 @@ class UsingStaticDirective extends UsingDirective, @using_static_directive {
* Gets the target of this type `using` directive, for example
* `System.Console` in `using static System.Console`.
*/
ValueOrRefType getTarget() { using_static_directives(this, getTypeRef(result)) }
ValueOrRefType getTarget() {
using_static_directives(this, result)
or
not using_static_directives(this, any(Type t)) and
using_static_directives(this, getTypeRef(result))
}
override string toString() { result = "using static ...;" }

View File

@@ -195,7 +195,12 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
override string getName() { params(this, result, _, _, _, _, _) }
override Type getType() { params(this, _, getTypeRef(result), _, _, _, _) }
override Type getType() {
params(this, _, result, _, _, _, _)
or
not params(this, _, any(Type t), _, _, _, _) and
params(this, _, getTypeRef(result), _, _, _, _)
}
override Location getALocation() { param_location(this, result) }
@@ -341,7 +346,12 @@ class LocalVariable extends LocalScopeVariable, @local_variable {
override string getName() { localvars(this, _, result, _, _, _) }
override Type getType() { localvars(this, _, _, _, getTypeRef(result), _) }
override Type getType() {
localvars(this, _, _, _, result, _)
or
not localvars(this, _, _, _, any(Type t), _) and
localvars(this, _, _, _, getTypeRef(result), _)
}
override Location getALocation() { localvar_location(this, result) }
@@ -423,7 +433,12 @@ class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent
override string getName() { fields(this, _, result, _, _, _) }
override Type getType() { fields(this, _, _, _, getTypeRef(result), _) }
override Type getType() {
fields(this, _, _, _, result, _)
or
not fields(this, _, _, _, any(Type t), _) and
fields(this, _, _, _, getTypeRef(result), _)
}
override Location getALocation() { field_location(this, result) }

View File

@@ -438,7 +438,12 @@ class LambdaExpr extends AnonymousFunctionExpr, @lambda_expr {
predicate hasExplicitReturnType() { lambda_expr_return_type(this, _) }
/** Gets the explicit return type of this lambda expression, if any. */
Type getExplicitReturnType() { lambda_expr_return_type(this, getTypeRef(result)) }
Type getExplicitReturnType() {
lambda_expr_return_type(this, result)
or
not lambda_expr_return_type(this, any(Type t)) and
lambda_expr_return_type(this, getTypeRef(result))
}
override string toString() { result = "(...) => ..." }

View File

@@ -42,7 +42,12 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr {
override Location getALocation() { expr_location(this, result) }
/** Gets the type of this expression. */
override Type getType() { expressions(this, _, getTypeRef(result)) }
override Type getType() {
expressions(this, _, result)
or
not expressions(this, _, any(Type t)) and
expressions(this, _, getTypeRef(result))
}
/** Gets the annotated type of this expression. */
final AnnotatedType getAnnotatedType() { result.appliesTo(this) }