mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
C#: Introduce class Overridable
The class `Overridable` generalizes the existing class `Virtualizable` by also including accessors. This allows for quite a bit of code to be simplified.
This commit is contained in:
@@ -205,7 +205,7 @@ private class RefArg extends AssignableAccess {
|
||||
*/
|
||||
predicate isAnalyzable(Parameter p) {
|
||||
exists(Callable callable | callable = this.getUnboundDeclarationTarget(p) |
|
||||
not callable.(Virtualizable).isOverridableOrImplementable() and
|
||||
not callable.(Overridable).isOverridableOrImplementable() and
|
||||
callable.hasBody()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Provides logic for determining interface member implementations.
|
||||
*
|
||||
* Do not use the predicates in this library directly; use the methods
|
||||
* of the class `Virtualizable` instead.
|
||||
* of the class `Overridable` instead.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
@@ -35,7 +35,7 @@ private import Conversion
|
||||
* `implements(A.M, I.M, B)` and `implements(C.M, I.M, C)`.
|
||||
*/
|
||||
cached
|
||||
predicate implements(Virtualizable m1, Virtualizable m2, ValueOrRefType t) {
|
||||
predicate implements(Overridable m1, Overridable m2, ValueOrRefType t) {
|
||||
exists(Interface i |
|
||||
i = m2.getDeclaringType() and
|
||||
t.getABaseInterface+() = i and
|
||||
@@ -66,7 +66,7 @@ predicate implements(Virtualizable m1, Virtualizable m2, ValueOrRefType t) {
|
||||
* for type `C`, because `C.M()` conflicts.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Virtualizable getAnImplementedInterfaceMemberForSubType(Virtualizable m, ValueOrRefType t) {
|
||||
private Overridable getAnImplementedInterfaceMemberForSubType(Overridable m, ValueOrRefType t) {
|
||||
result = getACompatibleInterfaceMember(m) and
|
||||
t = m.getDeclaringType()
|
||||
or
|
||||
@@ -78,7 +78,7 @@ private Virtualizable getAnImplementedInterfaceMemberForSubType(Virtualizable m,
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasMemberCompatibleWithInterfaceMember(ValueOrRefType t, Virtualizable m) {
|
||||
private predicate hasMemberCompatibleWithInterfaceMember(ValueOrRefType t, Overridable m) {
|
||||
m = getACompatibleInterfaceMember(t.getAMember())
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ private predicate hasMemberCompatibleWithInterfaceMember(ValueOrRefType t, Virtu
|
||||
* the interface member is accessed.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleInterfaceMember(Virtualizable m) {
|
||||
private Overridable getACompatibleInterfaceMember(Overridable m) {
|
||||
result = getACompatibleInterfaceMemberAux(m) and
|
||||
(
|
||||
// If there is both an implicit and an explicit compatible member
|
||||
@@ -100,14 +100,14 @@ private Virtualizable getACompatibleInterfaceMember(Virtualizable m) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleExplicitInterfaceMember(Virtualizable m, ValueOrRefType declType) {
|
||||
private Overridable getACompatibleExplicitInterfaceMember(Overridable m, ValueOrRefType declType) {
|
||||
result = getACompatibleInterfaceMemberAux(m) and
|
||||
declType = m.getDeclaringType() and
|
||||
m.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleInterfaceMemberAux(Virtualizable m) {
|
||||
private Overridable getACompatibleInterfaceMemberAux(Overridable m) {
|
||||
result = getACompatibleInterfaceAccessor(m) or
|
||||
result = getACompatibleInterfaceIndexer(m) or
|
||||
result = getACompatibleInterfaceMethod(m)
|
||||
|
||||
@@ -180,29 +180,15 @@ class Member extends DotNet::Member, Modifiable, @member {
|
||||
override predicate isStatic() { Modifiable.super.isStatic() }
|
||||
}
|
||||
|
||||
private class TOverridable = @virtualizable or @callable_accessor;
|
||||
|
||||
/**
|
||||
* A member where the `virtual` modifier is valid. That is, a method,
|
||||
* a property, an indexer, or an event.
|
||||
* A declaration that can be overridden or implemented. That is, a method,
|
||||
* a property, an indexer, an event, or an accessor.
|
||||
*
|
||||
* Equivalently, these are the members that can be defined in an interface.
|
||||
* Unlike `Virtualizable`, this class includes accessors.
|
||||
*/
|
||||
class Virtualizable extends Member, @virtualizable {
|
||||
/** Holds if this member has the modifier `override`. */
|
||||
predicate isOverride() { this.hasModifier("override") }
|
||||
|
||||
/** Holds if this member is `virtual`. */
|
||||
predicate isVirtual() { this.hasModifier("virtual") }
|
||||
|
||||
override predicate isPublic() {
|
||||
Member.super.isPublic() or
|
||||
this.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
override predicate isPrivate() {
|
||||
super.isPrivate() and
|
||||
not this.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
class Overridable extends Declaration, TOverridable {
|
||||
/**
|
||||
* Gets any interface this member explicitly implements; this only applies
|
||||
* to members that can be declared on an interface, i.e. methods, properties,
|
||||
@@ -216,19 +202,10 @@ class Virtualizable extends Member, @virtualizable {
|
||||
predicate implementsExplicitInterface() { exists(this.getExplicitlyImplementedInterface()) }
|
||||
|
||||
/** Holds if this member can be overridden or implemented. */
|
||||
predicate isOverridableOrImplementable() {
|
||||
not this.isSealed() and
|
||||
not this.getDeclaringType().isSealed() and
|
||||
(
|
||||
this.isVirtual() or
|
||||
this.isOverride() or
|
||||
this.isAbstract() or
|
||||
this.getDeclaringType() instanceof Interface
|
||||
)
|
||||
}
|
||||
predicate isOverridableOrImplementable() { none() }
|
||||
|
||||
/** Gets the member that is immediately overridden by this member, if any. */
|
||||
Virtualizable getOverridee() {
|
||||
Overridable getOverridee() {
|
||||
overrides(this, result)
|
||||
or
|
||||
// For accessors (which are `Callable`s), the extractor generates entries
|
||||
@@ -242,7 +219,7 @@ class Virtualizable extends Member, @virtualizable {
|
||||
}
|
||||
|
||||
/** Gets a member that immediately overrides this member, if any. */
|
||||
Virtualizable getAnOverrider() { this = result.getOverridee() }
|
||||
Overridable getAnOverrider() { this = result.getOverridee() }
|
||||
|
||||
/** Holds if this member is overridden by some other member. */
|
||||
predicate isOverridden() { exists(this.getAnOverrider()) }
|
||||
@@ -273,10 +250,10 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* `A.M.getImplementee(B) = I.M` and
|
||||
* `C.M.getImplementee(C) = I.M`.
|
||||
*/
|
||||
Virtualizable getImplementee(ValueOrRefType t) { implements(this, result, t) }
|
||||
Overridable getImplementee(ValueOrRefType t) { implements(this, result, t) }
|
||||
|
||||
/** Gets the interface member that is immediately implemented by this member, if any. */
|
||||
Virtualizable getImplementee() { result = this.getImplementee(_) }
|
||||
Overridable getImplementee() { result = this.getImplementee(_) }
|
||||
|
||||
/**
|
||||
* Gets a member that immediately implements this interface member, if any.
|
||||
@@ -301,10 +278,10 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* `I.M.getAnImplementor(B) = A.M` and
|
||||
* `I.M.getAnImplementor(C) = C.M`.
|
||||
*/
|
||||
Virtualizable getAnImplementor(ValueOrRefType t) { this = result.getImplementee(t) }
|
||||
Overridable getAnImplementor(ValueOrRefType t) { this = result.getImplementee(t) }
|
||||
|
||||
/** Gets a member that immediately implements this interface member, if any. */
|
||||
Virtualizable getAnImplementor() { this = result.getImplementee() }
|
||||
Overridable getAnImplementor() { this = result.getImplementee() }
|
||||
|
||||
/**
|
||||
* Gets an interface member that is (transitively) implemented by this
|
||||
@@ -334,8 +311,8 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* - If this member is `D.M` then `I.M = getAnUltimateImplementee()`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
Virtualizable getAnUltimateImplementee() {
|
||||
exists(Virtualizable implementation, ValueOrRefType implementationType |
|
||||
Overridable getAnUltimateImplementee() {
|
||||
exists(Overridable implementation, ValueOrRefType implementationType |
|
||||
implements(implementation, result, implementationType)
|
||||
|
|
||||
this = implementation
|
||||
@@ -354,7 +331,7 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* Note that this is generally *not* equivalent with
|
||||
* `getImplementor().getAnOverrider*()` (see `getImplementee`).
|
||||
*/
|
||||
Virtualizable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
|
||||
Overridable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
|
||||
|
||||
/** Holds if this interface member is implemented by some other member. */
|
||||
predicate isImplemented() { exists(this.getAnImplementor()) }
|
||||
@@ -366,7 +343,7 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* Holds if this member overrides or implements (transitively)
|
||||
* `that` member.
|
||||
*/
|
||||
predicate overridesOrImplements(Virtualizable that) {
|
||||
predicate overridesOrImplements(Overridable that) {
|
||||
this.getOverridee+() = that or
|
||||
this.getAnUltimateImplementee() = that
|
||||
}
|
||||
@@ -375,12 +352,49 @@ class Virtualizable extends Member, @virtualizable {
|
||||
* Holds if this member overrides or implements (reflexively, transitively)
|
||||
* `that` member.
|
||||
*/
|
||||
predicate overridesOrImplementsOrEquals(Virtualizable that) {
|
||||
predicate overridesOrImplementsOrEquals(Overridable that) {
|
||||
this = that or
|
||||
this.overridesOrImplements(that)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A member where the `virtual` modifier is valid. That is, a method,
|
||||
* a property, an indexer, or an event.
|
||||
*
|
||||
* Equivalently, these are the members that can be defined in an interface.
|
||||
*
|
||||
* Unlike `Overridable`, this class excludes accessors.
|
||||
*/
|
||||
class Virtualizable extends Overridable, Member, @virtualizable {
|
||||
/** Holds if this member has the modifier `override`. */
|
||||
predicate isOverride() { this.hasModifier("override") }
|
||||
|
||||
/** Holds if this member is `virtual`. */
|
||||
predicate isVirtual() { this.hasModifier("virtual") }
|
||||
|
||||
override predicate isPublic() {
|
||||
Member.super.isPublic() or
|
||||
this.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
override predicate isPrivate() {
|
||||
super.isPrivate() and
|
||||
not this.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
override predicate isOverridableOrImplementable() {
|
||||
not this.isSealed() and
|
||||
not this.getDeclaringType().isSealed() and
|
||||
(
|
||||
this.isVirtual() or
|
||||
this.isOverride() or
|
||||
this.isAbstract() or
|
||||
this.getDeclaringType() instanceof Interface
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameterizable declaration. Either a callable (`Callable`), a delegate
|
||||
* type (`DelegateType`), or an indexer (`Indexer`).
|
||||
|
||||
@@ -315,7 +315,7 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
|
||||
* An accessor. Either a getter (`Getter`), a setter (`Setter`), or event
|
||||
* accessor (`EventAccessor`).
|
||||
*/
|
||||
class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
|
||||
class Accessor extends Callable, Modifiable, Attributable, Overridable, @callable_accessor {
|
||||
override ValueOrRefType getDeclaringType() { result = this.getDeclaration().getDeclaringType() }
|
||||
|
||||
/** Gets the assembly name of this accessor. */
|
||||
@@ -376,6 +376,10 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
|
||||
not (result instanceof AccessModifier and exists(this.getAnAccessModifier()))
|
||||
}
|
||||
|
||||
override predicate isOverridableOrImplementable() {
|
||||
this.getDeclaration().isOverridableOrImplementable()
|
||||
}
|
||||
|
||||
override Accessor getUnboundDeclaration() { accessors(this, _, _, _, result) }
|
||||
|
||||
override Location getALocation() { accessor_location(this, result) }
|
||||
|
||||
@@ -1086,7 +1086,7 @@ module Internal {
|
||||
*/
|
||||
private Callable customNullCheck(Parameter p, BooleanValue retVal, boolean isNull) {
|
||||
result.getReturnType() instanceof BoolType and
|
||||
not result.(Virtualizable).isOverridableOrImplementable() and
|
||||
not result.(Overridable).isOverridableOrImplementable() and
|
||||
p.getCallable() = result and
|
||||
not p.isParams() and
|
||||
p.getType() = any(Type t | t instanceof RefType or t instanceof NullableType) and
|
||||
|
||||
@@ -360,11 +360,7 @@ private class UnboundCallable extends Callable {
|
||||
|
||||
predicate overridesOrImplementsUnbound(UnboundCallable that) {
|
||||
exists(Callable c |
|
||||
this.(Virtualizable).overridesOrImplementsOrEquals(c) or
|
||||
this = c.(OverridableCallable).getAnUltimateImplementor() or
|
||||
this = c.(OverridableCallable).getAnOverrider+()
|
||||
|
|
||||
this != c and
|
||||
this.(OverridableCallable).overridesOrImplements(c) and
|
||||
that = c.getUnboundDeclaration()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,24 +8,11 @@ import csharp
|
||||
/**
|
||||
* A callable that can be overridden or implemented.
|
||||
*
|
||||
* Unlike the class `Virtualizable`, this class only includes methods that
|
||||
* can actually be overriden/implemented. Additionally, this class includes
|
||||
* accessors whose declarations can actually be overridden/implemented.
|
||||
* Unlike the class `Overridable`, this class only includes callables that
|
||||
* can actually be overriden/implemented.
|
||||
*/
|
||||
class OverridableCallable extends Callable {
|
||||
OverridableCallable() {
|
||||
this.(Method).isOverridableOrImplementable() or
|
||||
this.(Accessor).getDeclaration().isOverridableOrImplementable()
|
||||
}
|
||||
|
||||
/** Gets a callable that immediately overrides this callable, if any. */
|
||||
Callable getAnOverrider() { none() }
|
||||
|
||||
/**
|
||||
* Gets a callable that immediately implements this interface callable,
|
||||
* if any.
|
||||
*/
|
||||
Callable getAnImplementor(ValueOrRefType t) { none() }
|
||||
class OverridableCallable extends Callable, Overridable {
|
||||
OverridableCallable() { this.isOverridableOrImplementable() }
|
||||
|
||||
/**
|
||||
* Gets a callable that immediately implements this interface member,
|
||||
@@ -68,40 +55,6 @@ class OverridableCallable extends Callable {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a callable that (transitively) implements this interface callable,
|
||||
* if any. That is, either this interface callable is immediately implemented
|
||||
* by the result, or the result overrides (transitively) another callable that
|
||||
* immediately implements this interface callable.
|
||||
*
|
||||
* Note that this is generally *not* equivalent with
|
||||
*
|
||||
* ```ql
|
||||
* result = getAnImplementor()
|
||||
* or
|
||||
* result = getAnImplementor().(OverridableCallable).getAnOverrider+()`
|
||||
* ```
|
||||
*
|
||||
* as the example below illustrates:
|
||||
*
|
||||
* ```csharp
|
||||
* interface I { void M(); }
|
||||
*
|
||||
* class A { public virtual void M() { } }
|
||||
*
|
||||
* class B : A, I { }
|
||||
*
|
||||
* class C : A { public override void M() }
|
||||
*
|
||||
* class D : B { public override void M() }
|
||||
* ```
|
||||
*
|
||||
* If this callable is `I.M` then `A.M = getAnUltimateImplementor() ` and
|
||||
* `D.M = getAnUltimateImplementor()`. However, it is *not* the case that
|
||||
* `C.M = getAnUltimateImplementor()`, because `C` is not a sub type of `I`.
|
||||
*/
|
||||
Callable getAnUltimateImplementor() { none() }
|
||||
|
||||
/**
|
||||
* Gets a callable that overrides (transitively) another callable that
|
||||
* implements this interface callable, if any.
|
||||
@@ -210,73 +163,10 @@ class OverridableCallable extends Callable {
|
||||
}
|
||||
|
||||
/** An overridable method. */
|
||||
class OverridableMethod extends Method, OverridableCallable {
|
||||
override Method getAnOverrider() { result = Method.super.getAnOverrider() }
|
||||
|
||||
override Method getAnImplementor(ValueOrRefType t) { result = Method.super.getAnImplementor(t) }
|
||||
|
||||
override Method getAnUltimateImplementor() { result = Method.super.getAnUltimateImplementor() }
|
||||
|
||||
override Method getInherited(ValueOrRefType t) {
|
||||
result = OverridableCallable.super.getInherited(t)
|
||||
}
|
||||
|
||||
override Method getAnOverrider(ValueOrRefType t) {
|
||||
result = OverridableCallable.super.getAnOverrider(t)
|
||||
}
|
||||
}
|
||||
deprecated class OverridableMethod extends Method, OverridableCallable { }
|
||||
|
||||
/** An overridable accessor. */
|
||||
class OverridableAccessor extends Accessor, OverridableCallable {
|
||||
override Accessor getAnOverrider() { overrides(result, this) }
|
||||
|
||||
override Accessor getAnImplementor(ValueOrRefType t) {
|
||||
exists(Virtualizable implementor, int kind |
|
||||
this.getAnImplementorAux(t, implementor, kind) and
|
||||
result.getDeclaration() = implementor and
|
||||
getAccessorKind(result) = kind
|
||||
)
|
||||
}
|
||||
|
||||
// predicate folding to get proper join order
|
||||
private predicate getAnImplementorAux(ValueOrRefType t, Virtualizable implementor, int kind) {
|
||||
exists(Virtualizable implementee |
|
||||
implementee = this.getDeclaration() and
|
||||
kind = getAccessorKind(this) and
|
||||
implementor = implementee.getAnImplementor(t)
|
||||
)
|
||||
}
|
||||
|
||||
override Accessor getAnUltimateImplementor() {
|
||||
exists(Virtualizable implementor, int kind |
|
||||
this.getAnUltimateImplementorAux(implementor, kind) and
|
||||
result.getDeclaration() = implementor and
|
||||
getAccessorKind(result) = kind
|
||||
)
|
||||
}
|
||||
|
||||
// predicate folding to get proper join order
|
||||
private predicate getAnUltimateImplementorAux(Virtualizable implementor, int kind) {
|
||||
exists(Virtualizable implementee |
|
||||
implementee = this.getDeclaration() and
|
||||
kind = getAccessorKind(this) and
|
||||
implementor = implementee.getAnUltimateImplementor()
|
||||
)
|
||||
}
|
||||
|
||||
override Accessor getInherited(ValueOrRefType t) {
|
||||
result = OverridableCallable.super.getInherited(t)
|
||||
}
|
||||
|
||||
override Accessor getAnOverrider(ValueOrRefType t) {
|
||||
result = OverridableCallable.super.getAnOverrider(t)
|
||||
}
|
||||
}
|
||||
|
||||
private int getAccessorKind(Accessor a) {
|
||||
accessors(a, result, _, _, _) or
|
||||
event_accessors(a, -result, _, _, _)
|
||||
}
|
||||
deprecated class OverridableAccessor extends Accessor, OverridableCallable { }
|
||||
|
||||
/** An unbound type. */
|
||||
class UnboundDeclarationType extends Type {
|
||||
|
||||
@@ -996,7 +996,7 @@ class QualifiableExpr extends Expr, @qualifiable_expr {
|
||||
*/
|
||||
predicate targetIsOverridableOrImplementable() {
|
||||
not this.getQualifier() instanceof BaseAccess and
|
||||
this.getQualifiedDeclaration().(Virtualizable).isOverridableOrImplementable()
|
||||
this.getQualifiedDeclaration().(Overridable).isOverridableOrImplementable()
|
||||
}
|
||||
|
||||
/** Holds if this expression has a conditional qualifier `?.` */
|
||||
|
||||
@@ -54,7 +54,7 @@ class ExternalAPIDataNode extends DataFlow::Node {
|
||||
// Defined outside the source archive
|
||||
not call.getTarget().fromSource() and
|
||||
// Not a call to a method which is overridden in source
|
||||
not exists(Virtualizable m |
|
||||
not exists(Overridable m |
|
||||
m.overridesOrImplementsOrEquals(call.getTarget().getUnboundDeclaration()) and
|
||||
m.fromSource()
|
||||
) and
|
||||
|
||||
@@ -155,4 +155,4 @@ int getFieldBitOffset(Field f) {
|
||||
/**
|
||||
* Holds if the specified `Function` can be overridden in a derived class.
|
||||
*/
|
||||
predicate isFunctionVirtual(Function f) { f.(CSharp::Virtualizable).isOverridableOrImplementable() }
|
||||
predicate isFunctionVirtual(Function f) { f.(CSharp::Overridable).isOverridableOrImplementable() }
|
||||
|
||||
@@ -19,7 +19,7 @@ query predicate withTarget(WithExpr with, RecordCloneMethod clone, Constructor c
|
||||
query predicate cloneOverrides(string b, string o) {
|
||||
exists(RecordCloneMethod base, RecordCloneMethod overrider |
|
||||
base.getDeclaringType().fromSource() and
|
||||
base.(Virtualizable).getAnOverrider() = overrider and
|
||||
base.getAnOverrider() = overrider and
|
||||
b = getSignature(base) and
|
||||
o = getSignature(overrider)
|
||||
)
|
||||
|
||||
@@ -187,12 +187,6 @@ edges
|
||||
| CollectionFlow.cs:373:52:373:53 | access to parameter ts [element] : A | CollectionFlow.cs:373:52:373:56 | access to array element |
|
||||
| CollectionFlow.cs:373:52:373:53 | access to parameter ts [element] : A | CollectionFlow.cs:373:52:373:56 | access to array element |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | CollectionFlow.cs:375:63:375:69 | access to indexer |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | CollectionFlow.cs:375:63:375:69 | access to indexer |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | CollectionFlow.cs:375:63:375:69 | access to indexer |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | CollectionFlow.cs:375:63:375:69 | access to indexer |
|
||||
| CollectionFlow.cs:377:61:377:64 | dict [element, property Value] : A | CollectionFlow.cs:377:75:377:78 | access to parameter dict [element, property Value] : A |
|
||||
| CollectionFlow.cs:377:75:377:78 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:377:75:377:81 | access to indexer |
|
||||
@@ -204,12 +198,6 @@ edges
|
||||
| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A |
|
||||
| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A |
|
||||
| CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A |
|
||||
| CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A |
|
||||
@@ -402,12 +390,6 @@ nodes
|
||||
| CollectionFlow.cs:373:52:373:53 | access to parameter ts [element] : A | semmle.label | access to parameter ts [element] : A |
|
||||
| CollectionFlow.cs:373:52:373:56 | access to array element | semmle.label | access to array element |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:375:49:375:52 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:375:63:375:69 | access to indexer | semmle.label | access to indexer |
|
||||
| CollectionFlow.cs:377:61:377:64 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A |
|
||||
@@ -424,16 +406,7 @@ nodes
|
||||
| CollectionFlow.cs:381:41:381:45 | access to array element : A | semmle.label | access to array element : A |
|
||||
| CollectionFlow.cs:381:41:381:45 | access to array element : A | semmle.label | access to array element : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A |
|
||||
| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A |
|
||||
| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A |
|
||||
| CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A |
|
||||
| CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A | semmle.label | access to parameter dict [element, property Value] : A |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import csharp
|
||||
|
||||
from Virtualizable v1, Virtualizable v2
|
||||
from Overridable v1, Overridable v2
|
||||
where
|
||||
v1 = v2.getAnUltimateImplementor() and
|
||||
v1.fromSource() and
|
||||
|
||||
@@ -16,23 +16,44 @@
|
||||
| overrides.A8.Item[int] | overrides.A1.Item[int] | overrides |
|
||||
| overrides.A8.M<T>(dynamic[], T) | overrides.A1.M<T>(dynamic[], T) | overrides |
|
||||
| overrides.A8.Property | overrides.A1.Property | overrides |
|
||||
| overrides.A8.add_Event(EventHandler) | overrides.A1.add_Event(EventHandler) | overrides |
|
||||
| overrides.A8.get_Item(int) | overrides.A1.get_Item(int) | overrides |
|
||||
| overrides.A8.get_Property() | overrides.A1.get_Property() | overrides |
|
||||
| overrides.A8.remove_Event(EventHandler) | overrides.A1.remove_Event(EventHandler) | overrides |
|
||||
| overrides.A8.set_Property(int) | overrides.A1.set_Property(int) | overrides |
|
||||
| overrides.A9.Event | overrides.A1.Event | overrides |
|
||||
| overrides.A9.Item[int] | overrides.A1.Item[int] | overrides |
|
||||
| overrides.A9.M<T>(dynamic[], T) | overrides.A1.M<T>(dynamic[], T) | overrides |
|
||||
| overrides.A9.Property | overrides.A1.Property | overrides |
|
||||
| overrides.A9.add_Event(EventHandler) | overrides.A1.add_Event(EventHandler) | overrides |
|
||||
| overrides.A9.get_Item(int) | overrides.A1.get_Item(int) | overrides |
|
||||
| overrides.A9.get_Property() | overrides.A1.get_Property() | overrides |
|
||||
| overrides.A9.remove_Event(EventHandler) | overrides.A1.remove_Event(EventHandler) | overrides |
|
||||
| overrides.A9.set_Property(int) | overrides.A1.set_Property(int) | overrides |
|
||||
| overrides.A.E1 | overrides.B.E1 | overrides |
|
||||
| overrides.A.P1 | overrides.B.P1 | overrides |
|
||||
| overrides.A.P2 | overrides.B.P2 | overrides |
|
||||
| overrides.A.P3 | overrides.B.P3 | overrides |
|
||||
| overrides.A.P4 | overrides.C.P4 | overrides |
|
||||
| overrides.A.add_E1(EventHandler) | overrides.B.add_E1(EventHandler) | overrides |
|
||||
| overrides.A.f2() | overrides.B.f2() | overrides |
|
||||
| overrides.A.f3() | overrides.B.f3() | overrides |
|
||||
| overrides.A.f4() | overrides.C.f4() | overrides |
|
||||
| overrides.A.f5() | overrides.B.f5() | overrides |
|
||||
| overrides.A.f6() | overrides.B.f6() | overrides |
|
||||
| overrides.A.get_P1() | overrides.B.get_P1() | overrides |
|
||||
| overrides.A.get_P2() | overrides.B.get_P2() | overrides |
|
||||
| overrides.A.get_P3() | overrides.B.get_P3() | overrides |
|
||||
| overrides.A.get_P4() | overrides.C.get_P4() | overrides |
|
||||
| overrides.A.remove_E1(EventHandler) | overrides.B.remove_E1(EventHandler) | overrides |
|
||||
| overrides.A.set_P1(string) | overrides.B.set_P1(string) | overrides |
|
||||
| overrides.A.set_P3(string) | overrides.B.set_P3(string) | overrides |
|
||||
| overrides.A.set_P4(string) | overrides.C.set_P4(string) | overrides |
|
||||
| overrides.B.f5() | overrides.C.f5() | overrides |
|
||||
| overrides.C2.Prop | overrides.C1.Prop | overrides |
|
||||
| overrides.C2.Prop | overrides.I3.Prop | implements |
|
||||
| overrides.C2.get_Prop() | overrides.C1.get_Prop() | overrides |
|
||||
| overrides.C2.set_Prop(string) | overrides.C1.set_Prop(string) | overrides |
|
||||
| overrides.C3<>.Item[int] | overrides.I4.MyIndexer[int] | implements |
|
||||
| overrides.C3<>.Method() | overrides.I4.Method() | implements |
|
||||
| overrides.C3<>.Prop | overrides.I3.Prop | implements |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import csharp
|
||||
|
||||
from Virtualizable v1, Virtualizable v2, string kind
|
||||
from Overridable v1, Overridable v2, string kind
|
||||
where
|
||||
(
|
||||
v1.getOverridee() = v2 and kind = "overrides"
|
||||
|
||||
Reference in New Issue
Block a user