C#: Simplify TypeRef.qll

This commit is contained in:
Tom Hvitved
2020-08-05 14:38:34 +02:00
parent d17f88bbcd
commit afbbafe132

View File

@@ -1,67 +1,29 @@
/**
* INTERNAL: Do not use.
*
* Provides support for type-references.
*/
import csharp
/** A typeref is a reference to a type in some assembly. */
private class TypeRef extends @typeref {
string getName() { typerefs(this, result) }
string toString() { result = this.getName() }
Type getReferencedType() { typeref_type(this, result) }
}
/**
* INTERNAL: Do not use.
*
* Gets a type reference for a given type `type`.
* This is used for extensionals that can be supplied
* as either type references or types.
*/
cached
@type_or_ref getTypeRef(@type type) {
@type_or_ref getTypeRef(Type type) {
result = type
or
type = result.(TypeRefs::TypeRef).getCanonicalType()
}
private module TypeRefs {
/**
* A typeref is a reference to a type in some assembly.
* Often, a type can be present in multiple assemblies.
*/
class TypeRef extends @typeref {
string getName() { typerefs(this, result) }
string toString() { result = getName() }
Type getAType() { typeref_type(this, result) }
/**
* Gets the "canonical type" represented by a typeref.
* This is because a typeref can reference multiple types, or a type with the same
* fully qualified name can exist in multiple assemblies.
* The canonical type is an arbitrarily chosen type from the list of candidate types.
*/
Type getCanonicalType() {
result = this.getAType() and
not locationIsBetter(canonicalTypeLocation(result), canonicalTypeLocation(this.getAType()))
}
}
/** Gets a location of a type. */
private Location typeLocation(Type t) {
type_location(t, result)
or
exists(Type decl | constructed_generic(decl, t) and result = typeLocation(decl))
}
/** Gets the "canonical location" for a type. A type has only one canonical location. */
private Location canonicalTypeLocation(Type t) {
result = typeLocation(t) and
not locationIsBetter(result, typeLocation(t))
}
pragma[inline]
private predicate locationIsBetter(Location typeLocation, Location betterLocation) {
typeLocation.(Assembly).getFullName() < betterLocation.(Assembly).getFullName()
or
typeLocation instanceof Assembly and betterLocation instanceof SourceLocation
or
typeLocation.(SourceLocation).getFile().getAbsolutePath() <
betterLocation.(SourceLocation).getFile().getAbsolutePath()
}
result.(TypeRef).getReferencedType() = type
}