Merge pull request #15887 from michaelnebel/csharp/qualifiedname

C#: Fully qualified name.
This commit is contained in:
Michael Nebel
2024-04-09 14:26:36 +02:00
committed by GitHub
23 changed files with 117 additions and 165 deletions

View File

@@ -2,4 +2,4 @@ import csharp
from Class c
where c.fromSource()
select c, c.getBaseClass().getFullyQualifiedName()
select c, c.getBaseClass().getFullyQualifiedNameDebug()

View File

@@ -102,25 +102,8 @@ class NamedElement extends Element, @named_element {
final predicate hasName(string name) { name = this.getName() }
/**
* Gets the fully qualified name of this element, for example the
* fully qualified name of `M` on line 3 is `N.C.M` in
* DEPRECATED: Use `hasFullyQualifiedName` instead.
*
* ```csharp
* namespace N {
* class C {
* void M(int i, string s) { }
* }
* }
* ```
*/
cached
deprecated final string getQualifiedName() {
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
if qualifier = "" then result = name else result = qualifier + "." + name
)
}
/**
* Gets the fully qualified name of this element, for example the
* fully qualified name of `M` on line 3 is `N.C.M` in
*
@@ -135,21 +118,39 @@ class NamedElement extends Element, @named_element {
* Unbound generic types, such as `IList<T>`, are represented as
* ``System.Collections.Generic.IList`1``.
*/
cached
final string getFullyQualifiedName() {
deprecated final string getFullyQualifiedName() {
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
if qualifier = "" then result = name else result = qualifier + "." + name
)
}
/**
* DEPRECATED: Use `hasFullyQualifiedName` instead.
* INTERNAL: Do not use.
*
* Holds if this element has the qualified name `qualifier`.`name`.
* This is intended for DEBUG ONLY.
* Constructing the fully qualified name for all elements in a large codebase
* puts severe stress on the string pool.
*
* Gets the fully qualified name of this element, for example the
* fully qualified name of `M` on line 3 is `N.C.M` in
*
* ```csharp
* namespace N {
* class C {
* void M(int i, string s) { }
* }
* }
* ```
*
* Unbound generic types, such as `IList<T>`, are represented as
* ``System.Collections.Generic.IList`1``.
*/
cached
deprecated predicate hasQualifiedName(string qualifier, string name) {
qualifier = "" and name = this.getName()
bindingset[this]
pragma[inline_late]
final string getFullyQualifiedNameDebug() {
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
if qualifier = "" then result = name else result = qualifier + "." + name
)
}
/** Holds if this element has the fully qualified name `qualifier`.`name`. */

View File

@@ -71,17 +71,11 @@ class Declaration extends NamedElement, @declaration {
override string toString() { result = this.getName() }
deprecated override predicate hasQualifiedName(string qualifier, string name) {
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, qualifier, name)
}
override predicate hasFullyQualifiedName(string qualifier, string name) {
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, qualifier, name)
}
/**
* DEPRECATED: Use `getFullyQualifiedNameWithTypes` instead.
*
* Gets the fully qualified name of this declaration, including types, for example
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
*
@@ -93,33 +87,13 @@ class Declaration extends NamedElement, @declaration {
* }
* ```
*/
deprecated string getQualifiedNameWithTypes() {
exists(string qual |
qual = this.getDeclaringType().getQualifiedName() and
deprecated string getFullyQualifiedNameWithTypes() {
exists(string fullqual, string qual, string name |
this.getDeclaringType().hasFullyQualifiedName(qual, name) and
fullqual = getQualifiedName(qual, name) and
if this instanceof NestedType
then result = qual + "+" + this.toStringWithTypes()
else result = qual + "." + this.toStringWithTypes()
)
}
/**
* Gets the fully qualified name of this declaration, including types, for example
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
*
* ```csharp
* namespace N {
* class C {
* void M(int i, string s) { }
* }
* }
* ```
*/
string getFullyQualifiedNameWithTypes() {
exists(string qual |
qual = this.getDeclaringType().getFullyQualifiedName() and
if this instanceof NestedType
then result = qual + "+" + this.toStringWithTypes()
else result = qual + "." + this.toStringWithTypes()
then result = fullqual + "+" + this.toStringWithTypes()
else result = fullqual + "." + this.toStringWithTypes()
)
}
@@ -263,17 +237,6 @@ class Member extends Modifiable, @member {
/** Gets an access to this member. */
MemberAccess getAnAccess() { result.getTarget() = this }
/**
* DEPRECATED: Use `hasFullyQualifiedName` instead.
*
* Holds if this member has name `name` and is defined in type `type`
* with namespace `namespace`.
*/
cached
deprecated final predicate hasQualifiedName(string namespace, string type, string name) {
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
}
/**
* Holds if this member has name `name` and is defined in type `type`
* with namespace `namespace`.

View File

@@ -38,16 +38,6 @@ class Namespace extends TypeContainer, Declaration, @namespace {
parent_namespace(result, this)
}
/**
* Holds if this namespace has the qualified name `qualifier`.`name`.
*
* For example if the qualified name is `System.Collections.Generic`, then
* `qualifier`=`System.Collections` and `name`=`Generic`.
*/
deprecated override predicate hasQualifiedName(string qualifier, string name) {
namespaceHasQualifiedName(this, qualifier, name)
}
/**
* Holds if this namespace has the qualified name `qualifier`.`name`.
*

View File

@@ -219,3 +219,28 @@ predicate splitQualifiedName(string qualifiedName, string qualifier, string name
name = qualifiedName
)
}
/**
* INTERNAL: Do not use.
*
* Gets the fully qualified name of this declaration, including types, for example
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
*
* ```csharp
* namespace N {
* class C {
* void M(int i, string s) { }
* }
* }
* ```
*/
bindingset[d]
string getFullyQualifiedNameWithTypes(Declaration d) {
exists(string fullqual, string qual, string name |
d.getDeclaringType().hasFullyQualifiedName(qual, name) and
fullqual = getQualifiedName(qual, name) and
if d instanceof NestedType
then result = fullqual + "+" + d.toStringWithTypes()
else result = fullqual + "." + d.toStringWithTypes()
)
}

View File

@@ -120,7 +120,7 @@ module Ssa {
result = prefix + "." + this.getAssignable()
|
if f.(Modifiable).isStatic()
then prefix = f.getDeclaringType().getFullyQualifiedName()
then prefix = f.getDeclaringType().getName()
else prefix = "this"
)
}

View File

@@ -3,6 +3,7 @@
*/
private import csharp
private import semmle.code.csharp.commons.QualifiedName
private import semmle.code.csharp.frameworks.system.linq.Expressions
private import codeql.dataflow.internal.FlowSummaryImpl
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
@@ -42,10 +43,18 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CsharpDataFlow>
string encodeContent(ContentSet c, string arg) {
c = TElementContent() and result = "Element" and arg = ""
or
exists(Field f | c = TFieldContent(f) and result = "Field" and arg = f.getFullyQualifiedName())
exists(Field f, string qualifier, string name |
c = TFieldContent(f) and
f.hasFullyQualifiedName(qualifier, name) and
arg = getQualifiedName(qualifier, name) and
result = "Field"
)
or
exists(Property p |
c = TPropertyContent(p) and result = "Property" and arg = p.getFullyQualifiedName()
exists(Property p, string qualifier, string name |
c = TPropertyContent(p) and
p.hasFullyQualifiedName(qualifier, name) and
arg = getQualifiedName(qualifier, name) and
result = "Property"
)
or
exists(SyntheticField f |

View File

@@ -139,13 +139,13 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi {
/** Gets a textual representation of this element. */
string toString() {
exists(Callable m, int index, string indexString |
exists(Callable m, int index, string indexString, string qualifier, string name |
if index = -1 then indexString = "qualifier" else indexString = "param " + index
|
this = TExternalApiParameter(m, index) and
m.getDeclaringType().hasFullyQualifiedName(qualifier, name) and
result =
m.getDeclaringType().getFullyQualifiedName() + "." + m.toStringWithTypes() + " [" +
indexString + "]"
getQualifiedName(qualifier, name) + "." + m.toStringWithTypes() + " [" + indexString + "]"
)
}
}

View File

@@ -1,9 +1,7 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
from Attributable element, Attribute attribute, string qualifier, string name
from Attributable element, Attribute attribute
where
attribute = element.getAnAttribute() and
(attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"]) and
attribute.getType().hasFullyQualifiedName(qualifier, name)
select element, attribute, getQualifiedName(qualifier, name)
(attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"])
select element, attribute, attribute.getType().getFullyQualifiedNameDebug()

View File

@@ -3,11 +3,10 @@
*/
import csharp
import semmle.code.csharp.commons.QualifiedName
from Destructor c, string qualifier, string name
where
c.getDeclaringType().hasFullyQualifiedName(qualifier, name) and
qualifier = "Constructors" and
name = "Class"
select c, c.getDeclaringType().getFullyQualifiedName()
select c, c.getDeclaringType().getFullyQualifiedNameDebug()

View File

@@ -1,5 +1,4 @@
import csharp
private import semmle.code.csharp.commons.QualifiedName
private predicate isInteresting(Type t) {
(
@@ -20,10 +19,7 @@ query predicate typemodifiers(Type t, string modifier) {
query predicate qualifiedtypes(Type t, string qualifiedName) {
isInteresting(t) and
exists(string qualifier, string name |
t.hasFullyQualifiedName(qualifier, name) and
qualifiedName = getQualifiedName(qualifier, name)
)
qualifiedName = t.getFullyQualifiedNameDebug()
}
query predicate filetypes(Type t) {

View File

@@ -1,12 +1,10 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
from LocalVariable v1, LocalVariable v2, Type t, string qualifier, string name
from LocalVariable v1, LocalVariable v2, Type t
where
v1.getFile().getStem() = "NativeInt" and
v2.getFile().getStem() = "NativeInt" and
t = v1.getType() and
t = v2.getType() and
t.hasFullyQualifiedName(qualifier, name) and
v1 != v2
select v1, v2, getQualifiedName(qualifier, name)
select v1, v2, t.getFullyQualifiedNameDebug()

View File

@@ -1,13 +1,8 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
from
Method m, Method overrider, string mnamespace, string mtype, string mname, string onamespace,
string otype, string oname
from Method m, Method overrider
where
m.getAnOverrider() = overrider and
m.getFile().getStem() = "CovariantReturn" and
m.hasFullyQualifiedName(mnamespace, mtype, mname) and
overrider.hasFullyQualifiedName(onamespace, otype, oname)
select getQualifiedName(mnamespace, mtype, mname), m.getReturnType().toString(),
getQualifiedName(onamespace, otype, oname), overrider.getReturnType().toString()
m.getFile().getStem() = "CovariantReturn"
select m.getFullyQualifiedNameDebug(), m.getReturnType().toString(),
overrider.getFullyQualifiedNameDebug(), overrider.getReturnType().toString()

View File

@@ -1,5 +1,4 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
private string getLocation(Member m) {
if m.fromSource() then result = m.getALocation().(SourceLocation).toString() else result = "-"
@@ -9,13 +8,9 @@ private string getIsAsync(ForeachStmt f) {
if f.isAsync() then result = "async" else result = "sync"
}
from
ForeachStmt f, string qualifier1, string type1, string qualifier2, string type2,
string qualifier3, string type3
where
f.getGetEnumerator().getDeclaringType().hasFullyQualifiedName(qualifier1, type1) and
f.getCurrent().getDeclaringType().hasFullyQualifiedName(qualifier2, type2) and
f.getMoveNext().getDeclaringType().hasFullyQualifiedName(qualifier3, type3)
select f, f.getElementType().toString(), getIsAsync(f), getQualifiedName(qualifier1, type1),
getLocation(f.getGetEnumerator()), getQualifiedName(qualifier2, type2),
getLocation(f.getCurrent()), getQualifiedName(qualifier3, type3), getLocation(f.getMoveNext())
from ForeachStmt f
select f, f.getElementType().toString(), getIsAsync(f),
f.getGetEnumerator().getDeclaringType().getFullyQualifiedNameDebug(),
getLocation(f.getGetEnumerator()), f.getCurrent().getDeclaringType().getFullyQualifiedNameDebug(),
getLocation(f.getCurrent()), f.getMoveNext().getDeclaringType().getFullyQualifiedNameDebug(),
getLocation(f.getMoveNext())

View File

@@ -7,18 +7,10 @@ query predicate records(RecordClass t, string i, RecordCloneMethod clone) {
t.fromSource()
}
private string getMemberName(Member m) {
exists(string qualifier, string name |
m.getDeclaringType().hasFullyQualifiedName(qualifier, name)
|
result = getQualifiedName(qualifier, name) + "." + m.toStringWithTypes()
)
}
query predicate members(RecordClass t, string ms, string l) {
t.fromSource() and
exists(Member m | t.hasMember(m) |
ms = getMemberName(m) and
ms = getFullyQualifiedNameWithTypes(m) and
if m.fromSource() then l = m.getLocation().toString() else l = "no location"
)
}

View File

@@ -1,19 +1,11 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
private string getSignature(Method m) {
exists(string qualifier, string name |
m.getDeclaringType().hasFullyQualifiedName(qualifier, name)
|
result = getQualifiedName(qualifier, name) + "." + m.toStringWithTypes()
)
}
query predicate withExpr(WithExpr with, string type, Expr expr, ObjectInitializer init, string clone) {
type = with.getType().toStringWithTypes() and
expr = with.getExpr() and
init = with.getInitializer() and
clone = getSignature(with.getCloneMethod())
clone = getFullyQualifiedNameWithTypes(with.getCloneMethod())
}
query predicate withTarget(WithExpr with, RecordCloneMethod clone, Constructor ctor) {
@@ -25,7 +17,7 @@ query predicate cloneOverrides(string b, string o) {
exists(RecordCloneMethod base, RecordCloneMethod overrider |
base.getDeclaringType().fromSource() and
base.getAnOverrider() = overrider and
b = getSignature(base) and
o = getSignature(overrider)
b = getFullyQualifiedNameWithTypes(base) and
o = getFullyQualifiedNameWithTypes(overrider)
)
}

View File

@@ -1,8 +1,9 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
import semmle.code.csharp.dispatch.Dispatch
from DispatchCall call, Callable callable
where
callable = call.getADynamicTarget() and
callable.fromSource()
select call, callable.getFullyQualifiedNameWithTypes()
select call, getFullyQualifiedNameWithTypes(callable)

View File

@@ -3,13 +3,11 @@
*/
import csharp
import semmle.code.csharp.commons.QualifiedName
from EnumConstant c, string namespace, string name
from EnumConstant c
where
c.getName() = "Green" and
c.getDeclaringType().hasFullyQualifiedName("Enums", "LongColor") and
c.getType() = c.getDeclaringType() and
c.getValue() = "1" and
c.getDeclaringType().getBaseClass().hasFullyQualifiedName(namespace, name)
select c, getQualifiedName(namespace, name)
c.getValue() = "1"
select c, c.getDeclaringType().getBaseClass().getFullyQualifiedNameDebug()

View File

@@ -1,4 +1,5 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
import semmle.code.csharp.frameworks.System
from ValueOrRefType t, Method m, boolean b
@@ -6,4 +7,4 @@ where
t.fromSource() and
m = getInvokedDisposeMethod(t) and
if implementsDispose(t) then b = true else b = false
select t, m.getFullyQualifiedNameWithTypes(), b
select t, getFullyQualifiedNameWithTypes(m), b

View File

@@ -1,4 +1,5 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
import semmle.code.csharp.frameworks.System
from ValueOrRefType t, Method m, boolean b
@@ -6,4 +7,4 @@ where
t.fromSource() and
m = getInvokedEqualsMethod(t) and
if implementsEquals(t) then b = true else b = false
select t, m.getFullyQualifiedNameWithTypes(), b
select t, getFullyQualifiedNameWithTypes(m), b

View File

@@ -231,18 +231,18 @@ query predicate test27(ConstructedType ct, UnboundGenericType ugt, UnboundGeneri
query predicate test28(UnboundGeneric ug, string s) {
ug.fromSource() and
s = ug.getFullyQualifiedNameWithTypes()
s = getFullyQualifiedNameWithTypes(ug)
}
query predicate test29(ConstructedGeneric cg, string s) {
cg.fromSource() and
s = cg.getFullyQualifiedNameWithTypes()
s = getFullyQualifiedNameWithTypes(cg)
}
query predicate test30(Declaration d, string s) {
d.fromSource() and
d instanceof @generic and
s = d.getFullyQualifiedNameWithTypes() and
s = getFullyQualifiedNameWithTypes(d) and
d != d.getUnboundDeclaration() and
not d instanceof Generic
}
@@ -263,21 +263,17 @@ query predicate test33(ConstructedMethod cm, string s1, string s2) {
exists(string namespace, string type, string name |
cm.hasFullyQualifiedName(namespace, type, name) and s1 = getQualifiedName(namespace, type, name)
) and
cm.getFullyQualifiedNameWithTypes() = s2
getFullyQualifiedNameWithTypes(cm) = s2
}
query predicate test34(UnboundGeneric ug, string s1, string s2) {
ug.fromSource() and
exists(string qualifier, string name |
ug.hasFullyQualifiedName(qualifier, name) and s1 = getQualifiedName(qualifier, name)
) and
ug.getFullyQualifiedNameWithTypes() = s2
s1 = ug.getFullyQualifiedNameDebug() and
s2 = getFullyQualifiedNameWithTypes(ug)
}
query predicate test35(UnboundGenericMethod gm, string s1, string s2) {
gm.fromSource() and
exists(string namespace, string type, string name |
gm.hasFullyQualifiedName(namespace, type, name) and s1 = getQualifiedName(namespace, type, name)
) and
gm.getFullyQualifiedNameWithTypes() = s2
s1 = gm.getFullyQualifiedNameDebug() and
s2 = getFullyQualifiedNameWithTypes(gm)
}

View File

@@ -1,4 +1,5 @@
import csharp
import semmle.code.csharp.commons.QualifiedName
from Overridable v1, Overridable v2, string kind
where
@@ -9,4 +10,4 @@ where
) and
v1.fromSource() and
v2.fromSource()
select v1.getFullyQualifiedNameWithTypes(), v2.getFullyQualifiedNameWithTypes(), kind
select getFullyQualifiedNameWithTypes(v1), getFullyQualifiedNameWithTypes(v2), kind

View File

@@ -1,3 +1,4 @@
import semmle.code.csharp.commons.QualifiedName
import semmle.code.csharp.Unification
class InterestingType extends @type {
@@ -7,9 +8,9 @@ class InterestingType extends @type {
}
string toString() {
result = this.(Type).getFullyQualifiedNameWithTypes()
result = getFullyQualifiedNameWithTypes(this.(Type))
or
not exists(this.(Type).getFullyQualifiedNameWithTypes()) and
not exists(getFullyQualifiedNameWithTypes(this.(Type))) and
result = this.(Type).toStringWithTypes()
}