mirror of
https://github.com/github/codeql.git
synced 2026-02-23 10:23:41 +01:00
C#: Speed up Implements.qll and Unification.qll
Restrict constructed GVN types to those that are complete, and reduce intermediate string construction in `toString()` computations.
This commit is contained in:
@@ -259,7 +259,7 @@ private module Gvn {
|
||||
private newtype TGvnType =
|
||||
TLeafGvnType(LeafType t) or
|
||||
TMethodTypeParameterGvnType(int i) { i = any(MethodTypeParameter p).getIndex() } or
|
||||
TConstructedGvnType(ConstructedGvnTypeList l)
|
||||
TConstructedGvnType(ConstructedGvnTypeList l) { l.isComplete() }
|
||||
|
||||
private newtype TConstructedGvnTypeList =
|
||||
TConstructedGvnTypeNil(Unification::CompoundTypeKind k) or
|
||||
@@ -334,6 +334,8 @@ private module Gvn {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isComplete() { this.getKind().getNumberOfTypeParameters() - 1 = this.length() }
|
||||
|
||||
private GvnType getArg(int i) {
|
||||
exists(GvnType head, ConstructedGvnTypeList tail |
|
||||
this = TConstructedGvnTypeCons(head, tail)
|
||||
@@ -345,47 +347,71 @@ private module Gvn {
|
||||
)
|
||||
}
|
||||
|
||||
private Unification::GenericType getConstructedGenericDeclaringTypeAt(int i) {
|
||||
i = 0 and
|
||||
result = this.getKind().getConstructedSourceDeclaration()
|
||||
or
|
||||
result = this.getConstructedGenericDeclaringTypeAt(i - 1).getGenericDeclaringType()
|
||||
}
|
||||
|
||||
private predicate isDeclaringTypeAt(int i) {
|
||||
exists(this.getConstructedGenericDeclaringTypeAt(i - 1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a textual representation of this constructed type, restricted
|
||||
* to the prefix `t` of the underlying source declaration type.
|
||||
*
|
||||
* The `toString()` calculation needs to be split up into prefixes, in
|
||||
* order to apply the type arguments correctly. For example, a source
|
||||
* declaration type `A<>.B.C<,>` applied to types `int, string, bool`
|
||||
* needs to be printed as `A<int>.B.C<string,bool>`.
|
||||
* Gets the `j`th `toString()` part of the `i`th nested component of this
|
||||
* constructed type, if any. The nested components are sorted in reverse
|
||||
* order, while the individual parts are sorted in normal order.
|
||||
*/
|
||||
language[monotonicAggregates]
|
||||
private string toStringConstructed(Unification::GenericType t) {
|
||||
t = this.getKind().getConstructedSourceDeclaration().getGenericDeclaringType*() and
|
||||
exists(int offset, int children, string name, string nameArgs |
|
||||
offset = t.getNumberOfDeclaringArguments() and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
name = Unification::getNameNested(t) and
|
||||
if children = 0
|
||||
then nameArgs = name
|
||||
else
|
||||
exists(string offsetArgs |
|
||||
offsetArgs =
|
||||
concat(int i |
|
||||
i in [offset .. offset + children - 1]
|
||||
|
|
||||
this.getArg(i).toString(), "," order by i
|
||||
) and
|
||||
nameArgs = name.prefix(name.length() - children - 1) + "<" + offsetArgs + ">"
|
||||
private string toStringConstructedPart(int i, int j) {
|
||||
this.isComplete() and
|
||||
exists(Unification::GenericType t |
|
||||
t = this.getConstructedGenericDeclaringTypeAt(i) and
|
||||
exists(int offset, int children, string name |
|
||||
offset = t.getNumberOfDeclaringArguments() and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
name = Unification::getNameNested(t) and
|
||||
if children = 0
|
||||
then
|
||||
j = 0 and result = name
|
||||
or
|
||||
this.isDeclaringTypeAt(i) and j = 1 and result = "."
|
||||
else (
|
||||
j = 0 and result = name.prefix(name.length() - children - 1) + "<"
|
||||
or
|
||||
j in [1 .. 2 * children - 1] and
|
||||
if j % 2 = 0
|
||||
then result = ","
|
||||
else result = this.getArg((j + 1) / 2 + offset - 1).toString()
|
||||
or
|
||||
j = 2 * children and
|
||||
result = ">"
|
||||
or
|
||||
this.isDeclaringTypeAt(i) and
|
||||
j = 2 * children + 1 and
|
||||
result = "."
|
||||
)
|
||||
|
|
||||
offset = 0 and result = nameArgs
|
||||
or
|
||||
result = this.toStringConstructed(t.getGenericDeclaringType()) + "." + nameArgs
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
string toString() {
|
||||
this.isComplete() and
|
||||
exists(Unification::CompoundTypeKind k | k = this.getKind() |
|
||||
result = k.toStringBuiltin(this.getArg(0).toString())
|
||||
or
|
||||
result = this.toStringConstructed(k.getConstructedSourceDeclaration())
|
||||
result =
|
||||
strictconcat(int i, int j |
|
||||
exists(Unification::GenericType t, int children |
|
||||
t = this.getConstructedGenericDeclaringTypeAt(i) and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
if children = 0 then j = 0 else j in [0 .. 2 * children]
|
||||
)
|
||||
|
|
||||
this.toStringConstructedPart(i, j) order by i desc, j
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,8 @@ module Gvn {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isComplete() { this.getKind().getNumberOfTypeParameters() - 1 = this.length() }
|
||||
|
||||
GvnType getArg(int i) {
|
||||
exists(GvnType head, ConstructedGvnTypeList tail |
|
||||
this = TConstructedGvnTypeCons(head, tail)
|
||||
@@ -224,47 +226,72 @@ module Gvn {
|
||||
)
|
||||
}
|
||||
|
||||
private GenericType getConstructedGenericDeclaringTypeAt(int i) {
|
||||
i = 0 and
|
||||
result = this.getKind().getConstructedSourceDeclaration()
|
||||
or
|
||||
result = this.getConstructedGenericDeclaringTypeAt(i - 1).getGenericDeclaringType()
|
||||
}
|
||||
|
||||
private predicate isDeclaringTypeAt(int i) {
|
||||
exists(this.getConstructedGenericDeclaringTypeAt(i - 1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a textual representation of this constructed type, restricted
|
||||
* to the prefix `t` of the underlying source declaration type.
|
||||
*
|
||||
* The `toString()` calculation needs to be split up into prefixes, in
|
||||
* order to apply the type arguments correctly. For example, a source
|
||||
* declaration type `A<>.B.C<,>` applied to types `int, string, bool`
|
||||
* needs to be printed as `A<int>.B.C<string,bool>`.
|
||||
* Gets the `j`th `toString()` part of the `i`th nested component of this
|
||||
* constructed type, if any. The nested components are sorted in reverse
|
||||
* order, while the individual parts are sorted in normal order.
|
||||
*/
|
||||
language[monotonicAggregates]
|
||||
private string toStringConstructed(GenericType t) {
|
||||
t = this.getKind().getConstructedSourceDeclaration().getGenericDeclaringType*() and
|
||||
exists(int offset, int children, string name, string nameArgs |
|
||||
offset = t.getNumberOfDeclaringArguments() and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
name = getNameNested(t) and
|
||||
if children = 0
|
||||
then nameArgs = name
|
||||
else
|
||||
exists(string offsetArgs |
|
||||
offsetArgs =
|
||||
concat(int i |
|
||||
i in [offset .. offset + children - 1]
|
||||
|
|
||||
this.getArg(i).toString(), "," order by i
|
||||
) and
|
||||
nameArgs = name.prefix(name.length() - children - 1) + "<" + offsetArgs + ">"
|
||||
private string toStringConstructedPart(int i, int j) {
|
||||
this.isComplete() and
|
||||
exists(GenericType t |
|
||||
t = this.getConstructedGenericDeclaringTypeAt(i) and
|
||||
exists(int offset, int children, string name |
|
||||
offset = t.getNumberOfDeclaringArguments() and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
name = getNameNested(t) and
|
||||
if children = 0
|
||||
then
|
||||
j = 0 and result = name
|
||||
or
|
||||
this.isDeclaringTypeAt(i) and j = 1 and result = "."
|
||||
else (
|
||||
j = 0 and result = name.prefix(name.length() - children - 1) + "<"
|
||||
or
|
||||
j in [1 .. 2 * children - 1] and
|
||||
if j % 2 = 0
|
||||
then result = ","
|
||||
else result = this.getArg((j + 1) / 2 + offset - 1).toString()
|
||||
or
|
||||
j = 2 * children and
|
||||
result = ">"
|
||||
or
|
||||
this.isDeclaringTypeAt(i) and
|
||||
j = 2 * children + 1 and
|
||||
result = "."
|
||||
)
|
||||
|
|
||||
offset = 0 and result = nameArgs
|
||||
or
|
||||
result = this.toStringConstructed(t.getGenericDeclaringType()) + "." + nameArgs
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
string toString() {
|
||||
this.isComplete() and
|
||||
exists(CompoundTypeKind k | k = this.getKind() |
|
||||
result = k.toStringBuiltin(this.getArg(0).toString())
|
||||
or
|
||||
result = this.toStringConstructed(k.getConstructedSourceDeclaration())
|
||||
result =
|
||||
strictconcat(int i, int j, int offset |
|
||||
exists(GenericType t, int children |
|
||||
t = this.getConstructedGenericDeclaringTypeAt(i) and
|
||||
children = t.getNumberOfArgumentsSelf() and
|
||||
(if this.isDeclaringTypeAt(i) then offset = 1 else offset = 0) and
|
||||
if children = 0 then j in [0 .. offset] else j in [0 .. 2 * children + offset]
|
||||
)
|
||||
|
|
||||
this.toStringConstructedPart(i, j) order by i desc, j
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -482,7 +509,7 @@ module Gvn {
|
||||
newtype TGvnType =
|
||||
TLeafGvnType(LeafType t) or
|
||||
TTypeParameterGvnType() or
|
||||
TConstructedGvnType(ConstructedGvnTypeList l)
|
||||
TConstructedGvnType(ConstructedGvnTypeList l) { l.isComplete() }
|
||||
|
||||
cached
|
||||
newtype TConstructedGvnTypeList =
|
||||
|
||||
Reference in New Issue
Block a user