C#: Move TypeRefs into a separate file and import it privately. Reorder imports into alphabetical order.

This commit is contained in:
Calum Grant
2020-05-13 12:04:50 +01:00
committed by Tom Hvitved
parent 4740b47f5d
commit 9a51192d86
13 changed files with 105 additions and 90 deletions

View File

@@ -7,6 +7,7 @@
*/
import csharp
private import TypeRef
private module Annotations {
newtype TAnnotation =

View File

@@ -4,6 +4,7 @@
import Type
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* An element that can have attributes. Either an assembly (`Assembly`), a field (`Field`),

View File

@@ -3,13 +3,14 @@
* such as methods and operators.
*/
import Type
import Member
import Stmt
import Type
import exprs.Call
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.metrics.Complexity
private import TypeRef
/**
* An element that can be called.

View File

@@ -4,6 +4,7 @@
import Member
import Type
private import TypeRef
/**
* An event, for example `E` on line 3 in

View File

@@ -16,6 +16,7 @@
import Location
import Namespace
private import dotnet
private import TypeRef
/**
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a

View File

@@ -1,11 +1,12 @@
/** Provides classes relating to declarations and type members. */
import Element
import Variable
import Callable
import Element
import Modifier
private import Implements
import Variable
private import dotnet
private import Implements
private import TypeRef
/**
* A declaration.

View File

@@ -2,12 +2,13 @@
* Provides classes for properties, indexers, and accessors.
*/
import Type
import Member
import Stmt
private import semmle.code.csharp.ExprOrStmtParent
private import dotnet
import Type
private import cil
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* A declaration that may have accessors. Either an event (`Event`), a property

View File

@@ -4,12 +4,13 @@
* All statements have the common base class `Stmt`.
*/
import Location
import Element
import Location
import Member
import exprs.Expr
private import semmle.code.csharp.Enclosing::Internal
private import semmle.code.csharp.frameworks.System
private import TypeRef
/**
* A statement.

View File

@@ -1,14 +1,15 @@
/** Provides classes for types. */
import Location
import Namespace
import Callable
import Property
import Event
import Generics
import Location
import Namespace
import Property
private import Conversion
private import semmle.code.csharp.metrics.Coupling
private import dotnet
private import semmle.code.csharp.metrics.Coupling
private import TypeRef
/**
* A type.
@@ -1002,73 +1003,3 @@ class TypeMention extends @type_mention {
/** Gets the location of this type mention. */
Location getLocation() { type_mention_location(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.
*/
@type_or_ref getTypeRef(@type type) {
result = type
or
type = result.(TypeRefs::TypeRef).getCanonicalType()
}
/**
* Module for reasoning about typerefs.
*/
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
isCanonicalType(result)
}
}
/** Gets the 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 a "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()
}
private predicate isCanonicalType(Type type) {
not exists(TypeRef tr |
type = tr.getAType() and
locationIsBetter(canonicalTypeLocation(type), canonicalTypeLocation(tr.getAType()))
)
}
}

View File

@@ -0,0 +1,73 @@
/**
* INTERNAL: Do not use.
* Provides support for type-references.
*/
import csharp
/**
* 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.
*/
@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
isCanonicalType(result)
}
}
/** 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()
}
private predicate isCanonicalType(Type type) {
not exists(TypeRef tr |
type = tr.getAType() and
locationIsBetter(canonicalTypeLocation(type), canonicalTypeLocation(tr.getAType()))
)
}
}

View File

@@ -5,6 +5,7 @@
*/
import Element
private import TypeRef
/**
* A `using` directive. Either a namespace `using` directive

View File

@@ -3,12 +3,13 @@
* constants.
*/
import Element
import Callable
import Type
import Assignable
import Callable
import Element
import Type
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* A variable. Either a variable with local scope (`LocalScopeVariable`) or a field (`Field`).

View File

@@ -4,10 +4,6 @@
* All expressions have the common base class `Expr`.
*/
import semmle.code.csharp.Location
import semmle.code.csharp.Stmt
import semmle.code.csharp.Callable
import semmle.code.csharp.Type
import Access
import ArithmeticOperation
import Assignment
@@ -19,9 +15,14 @@ import Dynamic
import Literal
import LogicalOperation
import semmle.code.csharp.controlflow.ControlFlowElement
import semmle.code.csharp.Callable
import semmle.code.csharp.Location
import semmle.code.csharp.Stmt
import semmle.code.csharp.Type
private import dotnet
private import semmle.code.csharp.Enclosing::Internal
private import semmle.code.csharp.frameworks.System
private import dotnet
private import semmle.code.csharp.TypeRef
/**
* An expression. Either an access (`Access`), a call (`Call`), an object or