C#: Teach cs/useless-upcast about disambiguating constructor calls

This commit is contained in:
Tom Hvitved
2019-05-29 15:16:08 +02:00
parent d8482083b9
commit 6b99e1a1bf
2 changed files with 20 additions and 2 deletions

View File

@@ -65,6 +65,13 @@ int getMaximumArguments(Callable c) {
result = c.getNumberOfParameters()
}
private class ConstructorCall extends Call {
ConstructorCall() {
this instanceof ObjectCreation or
this instanceof ConstructorInitializer
}
}
/** An explicit upcast. */
class ExplicitUpcast extends ExplicitCast {
ValueOrRefType src;
@@ -140,6 +147,17 @@ class ExplicitUpcast extends ExplicitCast {
)
}
/** Holds if this upcast may be used to disambiguate the target of a constructor call. */
pragma[nomagic]
private predicate isDisambiguatingConstructorCall(Constructor other, int args) {
exists(ConstructorCall cc, Constructor target, ValueOrRefType t | this.isArgument(cc, target) |
t = target.getDeclaringType() and
t.hasMember(other) and
args = cc.getNumberOfArguments() and
other != target
)
}
/** Holds if this upcast may be used to disambiguate the target of a call. */
private predicate isDisambiguatingCall() {
exists(Callable other, int args |
@@ -148,6 +166,8 @@ class ExplicitUpcast extends ExplicitCast {
this.isDisambiguatingExtensionCall(other, args)
or
this.isDisambiguatingStaticCall(other, args)
or
this.isDisambiguatingConstructorCall(other, args)
|
args >= getMinimumArguments(other) and
not args > getMaximumArguments(other)

View File

@@ -4,8 +4,6 @@
| UselessUpcast.cs:85:12:85:15 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:20:7:20:7 | B | B | UselessUpcast.cs:13:7:13:7 | A | A |
| UselessUpcast.cs:94:12:94:15 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:20:7:20:7 | B | B | UselessUpcast.cs:13:7:13:7 | A | A |
| UselessUpcast.cs:105:16:105:19 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:27:7:27:7 | C | C | UselessUpcast.cs:20:7:20:7 | B | B |
| UselessUpcast.cs:141:32:141:36 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:153:11:153:13 | Sub | Sub | UselessUpcast.cs:9:11:9:12 | I2 | I2 |
| UselessUpcast.cs:146:26:146:30 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:136:7:136:18 | Constructors | Constructors | UselessUpcast.cs:9:11:9:12 | I2 | I2 |
| UselessUpcast.cs:160:34:160:40 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:158:11:158:16 | SubSub | SubSub | UselessUpcast.cs:153:11:153:13 | Sub | Sub |
| UselessUpcast.cs:164:21:164:27 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcast.cs:158:11:158:16 | SubSub | SubSub | UselessUpcast.cs:153:11:153:13 | Sub | Sub |
| UselessUpcastBad.cs:9:23:9:32 | (...) ... | There is no need to upcast from $@ to $@ - the conversion can be done implicitly. | UselessUpcastBad.cs:4:11:4:13 | Sub | Sub | UselessUpcastBad.cs:3:11:3:15 | Super | Super |