mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge pull request #10628 from michaelnebel/java/typebasedmodels
Java: Type based summary models.
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
import java
|
||||
|
||||
/**
|
||||
* The type `t` is a parameterization of `g`, where the `i`-th type parameter of
|
||||
* `g` is instantiated to `a`?
|
||||
* Holds if the type `t` is a parameterization of `g`, where the `i`-th type parameter of
|
||||
* `g` is instantiated to `arg`.
|
||||
*
|
||||
* For example, `List<Integer>` parameterizes `List<T>`, instantiating its `0`-th
|
||||
* type parameter to `Integer`, while the raw type `List` also parameterizes
|
||||
|
||||
@@ -195,6 +195,9 @@ class TypeVariable extends BoundedType, Modifiable, @typevariable {
|
||||
result = this.getASuppliedType().(TypeVariable).getAnUltimatelySuppliedType()
|
||||
}
|
||||
|
||||
/** Gets the index of `this` type variable. */
|
||||
int getIndex() { typeVars(this, _, result, _, _) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeVariable" }
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* @tags model-generator
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import internal.CaptureSummaryFlow
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import utils.modelgenerator.internal.CaptureSummaryFlow
|
||||
|
||||
from DataFlowTargetApi api, string noflow
|
||||
where noflow = captureNoFlow(api)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @tags model-generator
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
|
||||
class Activate extends ActiveConfiguration {
|
||||
override predicate activateToSinkConfig() { any() }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @tags model-generator
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
|
||||
class Activate extends ActiveConfiguration {
|
||||
override predicate activateFromSourceConfig() { any() }
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* @tags model-generator
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
import internal.CaptureSummaryFlow
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import utils.modelgenerator.internal.CaptureSummaryFlow
|
||||
|
||||
from DataFlowTargetApi api, string flow
|
||||
where flow = captureFlow(api)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @name Capture typed based summary models.
|
||||
* @description Finds applicable summary models to be used by other queries.
|
||||
* @kind diagnostic
|
||||
* @id java/utils/model-generator/summary-models-typed-based
|
||||
* @tags model-generator
|
||||
*/
|
||||
|
||||
import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels
|
||||
|
||||
from TypeBasedFlowTargetApi api, string flow
|
||||
where flow = captureFlow(api)
|
||||
select flow order by flow
|
||||
@@ -67,6 +67,8 @@ private predicate isRelevantForModels(J::Callable api) {
|
||||
*/
|
||||
predicate isRelevantForDataFlowModels = isRelevantForModels/1;
|
||||
|
||||
predicate isRelevantForTypeBasedFlowModels = isRelevantForModels/1;
|
||||
|
||||
/**
|
||||
* A class of Callables that are relevant for generating summary, source and sinks models for.
|
||||
*
|
||||
@@ -141,7 +143,7 @@ string asPartialNegativeModel(TargetApiSpecific api) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
|
||||
predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
|
||||
t.hasName(["byte", "char", "Byte", "Character"])
|
||||
}
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
private import java
|
||||
private import semmle.code.java.Collections
|
||||
private import semmle.code.java.dataflow.internal.ContainerFlow
|
||||
private import CaptureModelsSpecific as Specific
|
||||
private import CaptureModels
|
||||
|
||||
/**
|
||||
* A type representing instantiations of class types
|
||||
* that has a method which returns an iterator.
|
||||
*/
|
||||
private class IterableClass extends Class {
|
||||
private Type elementType;
|
||||
|
||||
IterableClass() {
|
||||
elementType =
|
||||
unique(Type et |
|
||||
exists(Method m, RefType return, GenericType t, int position | m.getDeclaringType() = t |
|
||||
return = m.getReturnType() and
|
||||
return.getSourceDeclaration().hasQualifiedName("java.util", "Iterator") and
|
||||
t.getTypeParameter(position) = return.(ParameterizedType).getTypeArgument(0) and
|
||||
instantiates(this, t, position, et)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the iterator element type of `this`.
|
||||
*/
|
||||
Type getElementType() { result = elementType }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if type `bound` is an upper bound for type `t` or equal to `t`.
|
||||
*/
|
||||
private predicate isEffectivelyUpperBound(Type t, Type bound) {
|
||||
t = bound or
|
||||
t.(Wildcard).getUpperBound().getType() = bound
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if type `bound` is a lower bound for type `t` or equal to `t`.
|
||||
*/
|
||||
private predicate isEffectivelyLowerBound(Type t, Type bound) {
|
||||
t = bound or
|
||||
t.(Wildcard).getLowerBound().getType() = bound
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `t` is a container like type of `tv` (eg. `List<T>`).
|
||||
*/
|
||||
private predicate genericContainerType(RefType t, TypeVariable tv) {
|
||||
exists(Type et |
|
||||
et =
|
||||
[
|
||||
t.(ContainerType).getElementType(), t.(IterableClass).getElementType(),
|
||||
t.(Array).getElementType()
|
||||
]
|
||||
|
|
||||
isEffectivelyUpperBound(et, tv)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `tv` is a type variable of the immediate type declaring `callable`.
|
||||
*/
|
||||
private predicate classTypeParameter(Callable callable, TypeVariable tv) {
|
||||
callable.getDeclaringType().(GenericType).getATypeParameter() = tv
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `tv` is type variable of `callable` or the type declaring `callable`.
|
||||
*/
|
||||
private predicate localTypeParameter(Callable callable, TypeVariable tv) {
|
||||
classTypeParameter(callable, tv) or
|
||||
callable.(GenericCallable).getATypeParameter() = tv
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the access path postfix for `t`.
|
||||
*/
|
||||
private string getAccessPath(Type t) {
|
||||
if
|
||||
t instanceof Array and
|
||||
not Specific::isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
|
||||
then result = ".ArrayElement"
|
||||
else
|
||||
if t instanceof ContainerType or t instanceof IterableClass
|
||||
then result = ".Element"
|
||||
else result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the access path for parameter `p`.
|
||||
*/
|
||||
private string parameterAccess(Parameter p) {
|
||||
result = "Argument[" + p.getPosition() + "]" + getAccessPath(p.getType())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `callable` has a type parameter `tv` or container parameterized over type `tv`.
|
||||
*/
|
||||
private predicate parameter(Callable callable, string input, TypeVariable tv) {
|
||||
exists(Parameter p, Type pt |
|
||||
input = parameterAccess(p) and
|
||||
p = callable.getAParameter() and
|
||||
pt = p.getType() and
|
||||
(
|
||||
// Parameter of type tv
|
||||
isEffectivelyUpperBound(pt, tv)
|
||||
or
|
||||
// Parameter is a container of type tv
|
||||
genericContainerType(pt, tv)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of a synthetic field corresponding to `tv`.
|
||||
*/
|
||||
private string getSyntheticField(TypeVariable tv) {
|
||||
result = ".SyntheticField[ArgType" + tv.getIndex() + "]"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a models as data string representation of, how a value of type `tv`
|
||||
* can be read or stored implicitly in relation to `callable`.
|
||||
*/
|
||||
private string implicit(Callable callable, TypeVariable tv) {
|
||||
classTypeParameter(callable, tv) and
|
||||
not callable.isStatic() and
|
||||
exists(string access, Type decl |
|
||||
decl = callable.getDeclaringType() and
|
||||
if genericContainerType(decl, tv)
|
||||
then access = getAccessPath(decl)
|
||||
else access = getSyntheticField(tv)
|
||||
|
|
||||
result = Specific::qualifierString() + access
|
||||
)
|
||||
}
|
||||
|
||||
private class GenericFunctionalInterface extends FunctionalInterface, GenericType {
|
||||
override string getAPrimaryQlClass() { result = "GenericFunctionalInterface" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class of types that represents functions.
|
||||
*/
|
||||
private class Function extends ParameterizedType {
|
||||
private GenericFunctionalInterface fi;
|
||||
|
||||
Function() { fi = this.getGenericType() }
|
||||
|
||||
/**
|
||||
* Gets the typevariable that is the placeholder for the type `t`
|
||||
* used in the instantiation of `this`.
|
||||
*/
|
||||
private TypeVariable getTypeReplacement(Type t) {
|
||||
exists(int position |
|
||||
instantiates(this, fi, position, t) and
|
||||
result = fi.getTypeParameter(position)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parameter type of `this` function at position `position`.
|
||||
* Note that functions are often contravariant in their parameter types.
|
||||
*/
|
||||
Type getParameterType(int position) {
|
||||
exists(Type t |
|
||||
fi.getRunMethod().getParameterType(position) = this.getTypeReplacement(t) and
|
||||
isEffectivelyLowerBound(t, result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the return type of `this` function.
|
||||
* Note that functions are often covariant in their return type.
|
||||
*/
|
||||
Type getReturnType() {
|
||||
exists(Type t |
|
||||
fi.getRunMethod().getReturnType() = this.getTypeReplacement(t) and
|
||||
isEffectivelyUpperBound(t, result)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `callable` has a function parameter `f` at parameter position `position`.
|
||||
*/
|
||||
private predicate functional(Callable callable, Function f, int position) {
|
||||
callable.getParameterType(position) = f
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets models as data input/output access relative to the type parameter `tv` in the
|
||||
* type `t` in the scope of `callable`.
|
||||
*
|
||||
* Note: This predicate has to be inlined as `callable` is not related to `return` or `tv`
|
||||
* in every disjunction.
|
||||
*/
|
||||
bindingset[callable]
|
||||
private string getAccess(Callable callable, Type return, TypeVariable tv) {
|
||||
return = tv and result = ""
|
||||
or
|
||||
genericContainerType(return, tv) and result = getAccessPath(return)
|
||||
or
|
||||
not genericContainerType(return, tv) and
|
||||
(
|
||||
return.(ParameterizedType).getATypeArgument() = tv
|
||||
or
|
||||
callable.getDeclaringType() = return and return.(GenericType).getATypeParameter() = tv
|
||||
) and
|
||||
result = getSyntheticField(tv)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `input` is a models as data string representation of, how a value of type `tv`
|
||||
* (or a generic parameterized over `tv`) can be generated by a function parameter of `callable`.
|
||||
*/
|
||||
private predicate functionalSource(Callable callable, string input, TypeVariable tv) {
|
||||
exists(Function f, int position, Type return, string access |
|
||||
functional(callable, f, position) and
|
||||
return = f.getReturnType() and
|
||||
access = getAccess(callable, return, tv) and
|
||||
input = "Argument[" + position + "].ReturnValue" + access
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `input` is a models as data string representation of, how a
|
||||
* value of type `tv` (or a generic parameterized over `tv`)
|
||||
* can be provided as input to `callable`.
|
||||
* This includes
|
||||
* (1) The implicit synthetic field(s) of the declaring type of `callable`.
|
||||
* (2) The parameters of `callable`.
|
||||
* (3) Any function parameters of `callable`.
|
||||
*/
|
||||
private predicate input(Callable callable, string input, TypeVariable tv) {
|
||||
input = implicit(callable, tv)
|
||||
or
|
||||
parameter(callable, input, tv)
|
||||
or
|
||||
functionalSource(callable, input, tv)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `callable` returns a value of type `tv` (or a generic parameterized over `tv`) and `output`
|
||||
* is a models as data string representation of, how data is routed to the return.
|
||||
*/
|
||||
private predicate returns(Callable callable, TypeVariable tv, string output) {
|
||||
exists(Type return, string access | return = callable.getReturnType() |
|
||||
access = getAccess(callable, return, tv) and
|
||||
output = "ReturnValue" + access
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `callable` has a function parameter that accepts a value of type `tv`
|
||||
* and `output` is the models as data string representation of, how data is routed to
|
||||
* the function parameter.
|
||||
*/
|
||||
private predicate functionalSink(Callable callable, TypeVariable tv, string output) {
|
||||
exists(Function f, int p1, int p2 |
|
||||
functional(callable, f, p1) and
|
||||
tv = f.getParameterType(p2) and
|
||||
output = "Argument[" + p1 + "]" + ".Parameter[" + p2 + "]"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `output` is a models as data string representation of, how values of type `tv`
|
||||
* (or generics parameterized over `tv`) can be routed.
|
||||
* This includes
|
||||
* (1) The implicit synthetic field(s) of the declaring type of `callable`.
|
||||
* (2) The return of `callable`.
|
||||
* (3) Any function parameters of `callable`.
|
||||
*/
|
||||
private predicate output(Callable callable, TypeVariable tv, string output) {
|
||||
output = implicit(callable, tv)
|
||||
or
|
||||
returns(callable, tv, output)
|
||||
or
|
||||
functionalSink(callable, tv, output)
|
||||
}
|
||||
|
||||
/**
|
||||
* A class of callables that are relevant generating summaries for based
|
||||
* on the Theorems for Free approach.
|
||||
*/
|
||||
class TypeBasedFlowTargetApi extends Specific::TargetApiSpecific {
|
||||
TypeBasedFlowTargetApi() { Specific::isRelevantForTypeBasedFlowModels(this) }
|
||||
|
||||
/**
|
||||
* Gets the string representation of all type based summaries for `this`
|
||||
* inspired by the Theorems for Free approach.
|
||||
*
|
||||
* Examples could be (see Java pseudo code below)
|
||||
* (1) `get` returns a value of type `T`. We assume that the returned
|
||||
* value was fetched from a (synthetic) field.
|
||||
* (2) `set` consumes a value of type `T`. We assume that the value is stored in
|
||||
* a (synthetic) field.
|
||||
* (3) `apply<S>` is assumed to apply the provided function to a value stored in
|
||||
* a (synthetic) field and return the result.
|
||||
* (4) `apply<S1,S2>` is assumed to apply the provided function to provided value
|
||||
* and return the result.
|
||||
* ```java
|
||||
* public class MyGeneric<T> {
|
||||
* public void set(T x) { ... }
|
||||
* public T get() { ... }
|
||||
* public <S> S apply<S>(Function<T, S> f) { ... }
|
||||
* public <S1,S2> S2 apply<S1, S2>(S1 x, Function<S1, S2> f) { ... }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
string getSummaries() {
|
||||
exists(TypeVariable tv, string input, string output |
|
||||
localTypeParameter(this, tv) and
|
||||
input(this, input, tv) and
|
||||
output(this, tv, output) and
|
||||
input != output
|
||||
|
|
||||
result = asValueModel(this, input, output)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Theorems for Free inspired typed based summaries for `api`.
|
||||
*/
|
||||
string captureFlow(TypeBasedFlowTargetApi api) { result = api.getSummaries() }
|
||||
@@ -0,0 +1,2 @@
|
||||
unexpectedSummary
|
||||
expectedSummary
|
||||
@@ -0,0 +1,26 @@
|
||||
import java
|
||||
import utils.modelgenerator.internal.CaptureTypeBasedSummaryModels
|
||||
|
||||
private string expects() {
|
||||
exists(Javadoc doc |
|
||||
doc.getChild(0).toString().regexpCapture(" *(SPURIOUS-)?MaD=(.*)", 2) = result
|
||||
)
|
||||
}
|
||||
|
||||
private string flows() { exists(TypeBasedFlowTargetApi api | result = captureFlow(api)) }
|
||||
|
||||
query predicate unexpectedSummary(string msg) {
|
||||
exists(string flow |
|
||||
flow = flows() and
|
||||
not flow = expects() and
|
||||
msg = "Unexpected summary found: " + flow
|
||||
)
|
||||
}
|
||||
|
||||
query predicate expectedSummary(string msg) {
|
||||
exists(string e |
|
||||
e = expects() and
|
||||
not e = flows() and
|
||||
msg = "Expected summary missing: " + e
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package p;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MyFunction<T1, T2, T3> {
|
||||
|
||||
// MaD=p;MyFunction;true;apply;(Object,Object);;Argument[-1].SyntheticField[ArgType2];ReturnValue;value;generated
|
||||
// MaD=p;MyFunction;true;apply;(Object,Object);;Argument[0];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;MyFunction;true;apply;(Object,Object);;Argument[1];Argument[-1].SyntheticField[ArgType1];value;generated
|
||||
T3 apply(T1 x, T2 y);
|
||||
}
|
||||
247
java/ql/test/utils/model-generator/typebasedflow/p/Stream.java
Normal file
247
java/ql/test/utils/model-generator/typebasedflow/p/Stream.java
Normal file
@@ -0,0 +1,247 @@
|
||||
package p;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* This is a stub implementation of the Java Stream API.
|
||||
*/
|
||||
public class Stream<T> {
|
||||
|
||||
// MaD=p;Stream;true;iterator;();;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Iterator<T> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;allMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public boolean allMatch(Predicate<? super T> predicate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[-1].Element;Argument[1].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;Argument[2].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;collect;(Supplier,BiConsumer,BiConsumer);;Argument[0].ReturnValue;ReturnValue;value;generated
|
||||
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Collector is not a functional interface, so this is not supported
|
||||
public <R, A> R collect(Collector<? super T, A, R> collector) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;concat;(Stream,Stream);;Argument[0].Element;ReturnValue.Element;value;generated
|
||||
// MaD=p;Stream;true;concat;(Stream,Stream);;Argument[1].Element;ReturnValue.Element;value;generated
|
||||
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;distinct;();;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> distinct() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> Stream<T> empty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;filter;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;filter;(Predicate);;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> filter(Predicate<? super T> predicate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;findAny;();;Argument[-1].Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public Optional<T> findAny() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;findFirst;();;Argument[-1].Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public Optional<T> findFirst() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.Element;value;generated
|
||||
// MaD=p;Stream;true;flatMap;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;flatMapToDouble;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;flatMapToInt;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;flatMapToLong;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;forEach;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;forEachOrdered;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public void forEachOrdered(Consumer<? super T> action) {
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;generate;(Supplier);;Argument[0].ReturnValue;ReturnValue.Element;value;generated
|
||||
public static <T> Stream<T> generate(Supplier<T> s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[0];ReturnValue.Element;value;generated
|
||||
// MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;iterate;(Object,UnaryOperator);;Argument[1].ReturnValue;ReturnValue.Element;value;generated
|
||||
public static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;limit;(long);;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> limit(long maxSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;map;(Function);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;map;(Function);;Argument[0].ReturnValue;ReturnValue.Element;value;generated
|
||||
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;mapToDouble;(ToDoubleFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;mapToInt;(ToIntFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public IntStream mapToInt(ToIntFunction<? super T> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;mapToLong;(ToLongFunction);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public LongStream mapToLong(ToLongFunction<? super T> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;max;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;max;(Comparator);;Argument[-1].Element;Argument[0].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;max;(Comparator);;Argument[-1].Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public Optional<T> max(Comparator<? super T> comparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;min;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;min;(Comparator);;Argument[-1].Element;Argument[0].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;min;(Comparator);;Argument[-1].Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public Optional<T> min(Comparator<? super T> comparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;noneMatch;(Predicate);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
public boolean noneMatch(Predicate<? super T> predicate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;of;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;generated
|
||||
public static <T> Stream<T> of(T... t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;of;(Object);;Argument[0];ReturnValue.Element;value;generated
|
||||
public static <T> Stream<T> of(T t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;peek;(Consumer);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;peek;(Consumer);;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> peek(Consumer<? super T> action) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The generated models are only partially correct.
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;Argument[0].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[-1].Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[0].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
// SPURIOUS-MaD=p;Stream;true;reduce;(BinaryOperator);;Argument[0].ReturnValue;Argument[-1].Element;value;generated
|
||||
public Optional<T> reduce(BinaryOperator<T> accumulator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The generated models are only partially correct.
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[1].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];ReturnValue;value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;generated
|
||||
// SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[-1].Element;ReturnValue;value;generated
|
||||
// SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[0];Argument[-1].Element;value;generated
|
||||
// SPURIOUS-MaD=p;Stream;true;reduce;(Object,BinaryOperator);;Argument[1].ReturnValue;Argument[-1].Element;value;generated
|
||||
public T reduce(T identity, BinaryOperator<T> accumulator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[-1].Element;Argument[1].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];Argument[2].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[0];ReturnValue;value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;Argument[2].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[1].ReturnValue;ReturnValue;value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;Argument[2].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;reduce;(Object,BiFunction,BinaryOperator);;Argument[2].ReturnValue;ReturnValue;value;generated
|
||||
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;skip;(long);;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> skip(long n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;sorted;();;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> sorted() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;Stream;true;sorted;(Comparator);;Argument[-1].Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;Stream;true;sorted;(Comparator);;Argument[-1].Element;Argument[0].Parameter[1];value;generated
|
||||
// MaD=p;Stream;true;sorted;(Comparator);;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public Stream<T> sorted(Comparator<? super T> comparator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Models can never be generated correctly based on the type information
|
||||
// as it involves downcasting.
|
||||
public Object[] toArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The generated result is only partially correct as there is no mentioning of
|
||||
// the type T in the method definition.
|
||||
// MaD=p;Stream;true;toArray;(IntFunction);;Argument[0].ReturnValue.ArrayElement;ReturnValue.ArrayElement;value;generated
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package p;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TypeBasedCollection<T> extends ArrayList<T> {
|
||||
|
||||
// MaD=p;TypeBasedCollection;true;addT;(Object);;Argument[0];Argument[-1].Element;value;generated
|
||||
public void addT(T x) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedCollection;true;addManyT;(List);;Argument[0].Element;Argument[-1].Element;value;generated
|
||||
public void addManyT(List<T> xs) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedCollection;true;firstT;();;Argument[-1].Element;ReturnValue;value;generated
|
||||
public T firstT() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedCollection;true;getManyT;();;Argument[-1].Element;ReturnValue.Element;value;generated
|
||||
public List<T> getManyT() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package p;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TypeBasedComplex<T> {
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;addMany;(List);;Argument[0].Element;Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
public void addMany(List<T> xs) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;getMany;();;Argument[-1].SyntheticField[ArgType0];ReturnValue.Element;value;generated
|
||||
public List<T> getMany() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;apply;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
public Integer apply(Function<T, Integer> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// A method that doesn't mention `T` in its type signature.
|
||||
// This is for testing that we don't generate a summary that involves the
|
||||
// implicit field for `T`.
|
||||
// MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[0];Argument[1].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;apply2;(Object,Function);;Argument[1].ReturnValue;ReturnValue;value;generated
|
||||
public <T1, T2> T2 apply2(T1 x, Function<T1, T2> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[-1].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;flatMap;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public TypeBasedComplex<T> flatMap(Function<T, List<T>> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;flatMap2;(Function);;Argument[0].ReturnValue.Element;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public <S> TypeBasedComplex<S> flatMap2(Function<T, List<S>> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;map;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;map;(Function);;Argument[0].ReturnValue;ReturnValue;value;generated
|
||||
public <S> S map(Function<T, S> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;mapComplex;(Function);;Argument[0].ReturnValue;ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public <S> TypeBasedComplex<S> mapComplex(Function<T, S> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[-1].SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;returnComplex;(Function);;Argument[0].ReturnValue.SyntheticField[ArgType0];ReturnValue.SyntheticField[ArgType0];value;generated
|
||||
public TypeBasedComplex<T> returnComplex(Function<T, TypeBasedComplex<T>> f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;set;(Integer,Function);;Argument[1].ReturnValue;Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
public void set(Integer x, Function<Integer, T> f) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunction;(MyFunction,Integer);;Argument[0].ReturnValue;Argument[0].Parameter[0];value;generated
|
||||
public Integer applyMyFunction(MyFunction<T, Integer, T> f, Integer x) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[-1].SyntheticField[ArgType0];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[0].ReturnValue;ReturnValue;value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object);;Argument[1];Argument[0].Parameter[1];value;generated
|
||||
public <S1, S2> S2 applyMyFunctionGeneric(MyFunction<T, S1, S2> f, S1 x) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[0].ReturnValue;ReturnValue;value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[1];Argument[0].Parameter[0];value;generated
|
||||
// MaD=p;TypeBasedComplex;true;applyMyFunctionGeneric;(MyFunction,Object,Object);;Argument[2];Argument[0].Parameter[1];value;generated
|
||||
public <S1, S2, S3> S3 applyMyFunctionGeneric(MyFunction<S1, S2, S3> f, S1 x, S2 y) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package p;
|
||||
|
||||
public class TypeBasedSimple<T> {
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;TypeBasedSimple;(Object);;Argument[0];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
public TypeBasedSimple(T t) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;get;();;Argument[-1].SyntheticField[ArgType0];ReturnValue;value;generated
|
||||
public T get() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;get;(Object);;Argument[-1].SyntheticField[ArgType0];ReturnValue;value;generated
|
||||
public T get(Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;id;(Object);;Argument[-1].SyntheticField[ArgType0];ReturnValue;value;generated
|
||||
// MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
// MaD=p;TypeBasedSimple;true;id;(Object);;Argument[0];ReturnValue;value;generated
|
||||
public T id(T x) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;id2;(Object);;Argument[0];ReturnValue;value;generated
|
||||
public <S> S id2(S x) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;set;(Object);;Argument[0];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
public void set(T x) {
|
||||
}
|
||||
|
||||
// MaD=p;TypeBasedSimple;true;set;(int,Object);;Argument[1];Argument[-1].SyntheticField[ArgType0];value;generated
|
||||
public void set(int x, T y) {
|
||||
}
|
||||
|
||||
// No summary as S is unrelated to T
|
||||
public <S> void set2(S x) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user