Merge pull request #6059 from smowton/smowton/fix/qualified-name-generic-types

Adapt to static methods and nested types returning unbound declaring types
This commit is contained in:
yo-h
2021-06-23 14:45:51 -04:00
committed by GitHub
10 changed files with 64 additions and 24 deletions

View File

@@ -75,13 +75,25 @@ class GenericType extends RefType {
* Gets the number of type parameters of this generic type.
*/
int getNumberOfTypeParameters() { result = strictcount(getATypeParameter()) }
override string getAPrimaryQlClass() { result = "GenericType" }
}
/** A generic type that is a class. */
class GenericClass extends GenericType, Class { }
class GenericClass extends GenericType, Class {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = GenericType.super.getAPrimaryQlClass()
}
}
/** A generic type that is an interface. */
class GenericInterface extends GenericType, Interface { }
class GenericInterface extends GenericType, Interface {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = GenericType.super.getAPrimaryQlClass()
}
}
/**
* A common super-class for Java types that may have a type bound.
@@ -115,6 +127,8 @@ abstract class BoundedType extends RefType, @boundedtype {
or
result = getUpperBoundType().(BoundedType).getAnUltimateUpperBoundType()
}
override string getAPrimaryQlClass() { result = "BoundedType" }
}
/**
@@ -354,13 +368,25 @@ class ParameterizedType extends RefType {
/** Holds if this type originates from source code. */
override predicate fromSource() { typeVars(_, _, _, _, this) and RefType.super.fromSource() }
override string getAPrimaryQlClass() { result = "ParameterizedType" }
}
/** A parameterized type that is a class. */
class ParameterizedClass extends Class, ParameterizedType { }
class ParameterizedClass extends Class, ParameterizedType {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = ParameterizedType.super.getAPrimaryQlClass()
}
}
/** A parameterized type that is an interface. */
class ParameterizedInterface extends Interface, ParameterizedType { }
class ParameterizedInterface extends Interface, ParameterizedType {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = ParameterizedType.super.getAPrimaryQlClass()
}
}
/**
* The raw version of a generic type is the type that is formed by
@@ -384,13 +410,25 @@ class RawType extends RefType {
/** Holds if this type originates from source code. */
override predicate fromSource() { not any() }
override string getAPrimaryQlClass() { result = "RawType" }
}
/** A raw type that is a class. */
class RawClass extends Class, RawType { }
class RawClass extends Class, RawType {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = RawType.super.getAPrimaryQlClass()
}
}
/** A raw type that is an interface. */
class RawInterface extends Interface, RawType { }
class RawInterface extends Interface, RawType {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = RawType.super.getAPrimaryQlClass()
}
}
// -------- Generic callables --------
/**

View File

@@ -7,11 +7,11 @@ private import semmle.code.java.dataflow.ExternalFlow
private class EntryType extends RefType {
EntryType() {
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "Map<>$Entry")
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "Map$Entry")
}
RefType getValueType() {
exists(GenericType t | t.hasQualifiedName("java.util", "Map<>$Entry") |
exists(GenericType t | t.hasQualifiedName("java.util", "Map$Entry") |
indirectlyInstantiates(this, t, 1, result)
)
}
@@ -95,10 +95,10 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"java.util;Map<>$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"java.util;Map<>$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map<>$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map<>$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"java.util;Map$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value",

View File

@@ -26,10 +26,10 @@ class PlayMvcHttpRequestHeader extends RefType {
}
/**
* A `play.mvc.BodyParser<>$Of` annotation.
* A `play.mvc.BodyParser$Of` annotation.
*/
class PlayBodyParserAnnotation extends Annotation {
PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser<>$Of") }
PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser$Of") }
}
/**

View File

@@ -49,22 +49,22 @@ public class B {
void foo() throws InterruptedException {
{
// "java.util;Map<>$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
// "java.util;Map$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
Object out = null;
Object in = storeMapKeyEntry(source()); out = ((Map.Entry)in).getKey(); sink(out); // $ hasValueFlow
}
{
// "java.util;Map<>$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
// "java.util;Map$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
Object out = null;
Object in = storeMapValueEntry(source()); out = ((Map.Entry)in).getValue(); sink(out); // $ hasValueFlow
}
{
// "java.util;Map<>$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
// "java.util;Map$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
Object out = null;
Object in = storeMapValueEntry(source()); out = ((Map.Entry)in).setValue(null); sink(out); // $ hasValueFlow
}
{
// "java.util;Map<>$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
// "java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
Map.Entry out = null;
Object in = source(); out.setValue(in); sink(readMapValue(out)); // $ hasValueFlow
}

View File

@@ -3,7 +3,7 @@ Example.java:
#-----| -1: (Imports)
# 1| 1: [ImportType] import Set
# 2| 2: [ImportType] import List
# 4| 1: [Interface] Example
# 4| 1: [GenericType,Interface,ParameterizedType] Example
#-----| -2: (Generic Parameters)
# 4| 0: [TypeVariable] A
#-----| -1: (Base Types)

View File

@@ -1,6 +1,6 @@
dependency/A.java:
# 0| [CompilationUnit] A
# 3| 1: [Class] A
# 3| 1: [Class,GenericType,ParameterizedType] A
#-----| -2: (Generic Parameters)
# 3| 0: [TypeVariable] T
# 6| 2: [Class] B

View File

@@ -1 +1 @@
| play.mvc.BodyParser<>$Of |
| play.mvc.BodyParser$Of |

View File

@@ -3,7 +3,7 @@ generics/A.java:
#-----| -1: (Imports)
# 3| 1: [ImportType] import HashMap
# 4| 2: [ImportType] import Map
# 6| 1: [Class] A
# 6| 1: [Class,GenericType,ParameterizedType] A
#-----| -2: (Generic Parameters)
# 6| 0: [TypeVariable] T
# 7| 2: [Class] B
@@ -23,7 +23,7 @@ generics/A.java:
# 13| -3: [TypeAccess] HashMap<String,Object>
# 13| 0: [TypeAccess] String
# 13| 1: [TypeAccess] Object
# 16| 3: [Class] D
# 16| 3: [Class,GenericType,ParameterizedType] D
#-----| -2: (Generic Parameters)
# 16| 0: [TypeVariable] V
# 16| 0: [TypeAccess] Number

View File

@@ -84,7 +84,7 @@ typeaccesses/TA.java:
# 13| 0: [ExprStmt] <Expr>;
# 13| 0: [MethodAccess] method3(...)
# 13| -1: [TypeAccess] TA
# 14| 10: [Class] Inner
# 14| 10: [Class,GenericType,ParameterizedType] Inner
#-----| -2: (Generic Parameters)
# 14| 0: [TypeVariable] T
# 14| 0: [TypeAccess] ArrayList<TA>