You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
3.9 KiB

3 years ago
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.infer;
public class DynamicDispatch {
static interface Interface {
public Object foo();
}
static class Impl implements Interface {
@Override
public Object foo() {
return null;
}
}
static void interfaceShouldNotCauseFalseNegativeEasy() {
Interface i = new Impl();
// should be a warning since Impl's implementation of foo returns null
i.foo().toString();
}
static void interfaceShouldNotCauseFalseNegativeHard(Interface i) {
i.foo().toString();
}
static void callWithBadImplementation(Impl impl) {
interfaceShouldNotCauseFalseNegativeHard(impl);
}
static class Supertype {
Object foo() {
return new Object();
}
Object bar() {
return null;
}
}
static class Subtype extends Supertype {
@Override
Object foo() {
return null;
}
@Override
Object bar() {
return new Object();
}
}
static void dynamicDispatchShouldNotCauseFalseNegativeEasy() {
Supertype o = new Subtype();
// should report a warning because we know the dynamic type of o is Subtype
o.foo().toString();
}
static void dynamicDispatchShouldNotCauseFalsePositiveEasy() {
Supertype o = new Subtype();
// should not report a warning because we know the dynamic type of o is Subtype
o.bar().toString();
}
static void FP_dynamicDispatchShouldNotReportWhenCallingSupertype(Supertype o) {
// should not report a warning because the Supertype implementation
// of foo() does not return null
o.foo().toString();
}
static void dynamicDispatchShouldReportWhenCalledWithSubtypeParameter(Subtype o) {
// should report a warning because the Subtype implementation
// of foo() returns null
FP_dynamicDispatchShouldNotReportWhenCallingSupertype(o);
}
static Object dynamicDispatchWrapperFoo(Supertype o) {
return o.foo();
}
static Object dynamicDispatchWrapperBar(Supertype o) {
return o.bar();
}
static void dynamicDispatchCallsWrapperWithSupertypeOkay() {
// Should not report because Supertype.foo() does not return null
Supertype o = new Supertype();
dynamicDispatchWrapperFoo(o).toString();
}
static void dynamicDispatchCallsWrapperWithSupertypeBad() {
// Should report because Supertype.bar() returns null
Supertype o = new Supertype();
dynamicDispatchWrapperBar(o).toString();
}
static void dynamicDispatchCallsWrapperWithSubtypeBad() {
// Should report because Subtype.foo() returns null
Supertype o = new Subtype();
dynamicDispatchWrapperFoo(o).toString();
}
static void dynamicDispatchCallsWrapperWithSubtypeOkay() {
// Should not report because Subtype.bar() does not returns null
Supertype o = new Subtype();
dynamicDispatchWrapperBar(o).toString();
}
static class WithField {
Supertype mField;
WithField(Supertype t) {
mField = t;
}
static void dispatchOnFieldOk() {
Supertype subtype = new Subtype();
WithField object = new WithField(subtype);
object.mField.bar().toString();
}
static void dispatchOnFieldBad() {
Supertype subtype = new Subtype();
WithField object = new WithField(subtype);
object.mField.foo().toString();
}
}
private Object callFoo(Supertype o) {
return o.foo();
}
void dynamicResolutionWithPrivateMethodBad() {
Supertype subtype = new Subtype();
callFoo(subtype).toString();
}
Object variadicMethod(Supertype... args) {
if (args.length == 0) {
return null;
} else {
return args[0].foo();
}
}
void dynamicResolutionWithVariadicMethodBad() {
Supertype subtype = new Subtype();
variadicMethod(subtype, null, null).toString();
}
}