Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions java/ql/lib/semmle/code/java/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,44 @@ class ClassOrInterface extends RefType, @classorinterface {
}
}

private string getAPublicObjectMethodSignature() {
exists(Method m |
m.getDeclaringType() instanceof TypeObject and
m.isPublic() and
result = m.getSignature()
)
}

private Method getAnAbstractMethod(Interface interface) {
interface.inherits(result) and
result.isAbstract() and
// JLS 9.8, ignore Object methods
not result.getSignature() = getAPublicObjectMethodSignature() and
// Make sure that there is no other non-abstract method
// (e.g. `default`) which overrides the abstract one
not exists(Method m |
interface.inherits(m) and
not m.isAbstract() and
m.overrides(result)
)
}

/**
* A functional interface is an interface that has just one abstract method
* (aside from the methods of Object), and thus represents a single function
* contract.
*
* See JLS 9.8, Functional Interfaces.
*/
class FunctionalInterface extends Interface {
Method run;

FunctionalInterface() { run = unique(Method r | r = getAnAbstractMethod(this)) }

/** Gets the single abstract method of this interface. */
Method getRunMethod() { result = run }
}

/**
* A primitive type.
*
Expand Down
31 changes: 0 additions & 31 deletions java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,6 @@
import java
import VirtualDispatch

private string getAPublicObjectMethodSignature() {
exists(Method m |
m.getDeclaringType() instanceof TypeObject and
m.isPublic() and
result = m.getSignature()
)
}

private Method getAPotentialRunMethod(Interface i) {
i.inherits(result) and
result.isPublic() and
not result.getSignature() = getAPublicObjectMethodSignature()
}

/**
* A functional interface is an interface that has just one abstract method
* (aside from the methods of Object), and thus represents a single function
* contract.
*
* See JLS 9.8, Functional Interfaces.
*/
class FunctionalInterface extends Interface {
FunctionalInterface() {
1 = strictcount(getAPotentialRunMethod(this)) and
not exists(Method m | this.inherits(m) and m.isDefault())
}

/** Gets the single method of this interface. */
Method getRunMethod() { getAPotentialRunMethod(this).getSourceDeclaration() = result }
}

/**
* Holds if `m` might invoke `runmethod` through a functional interface on the
* `n`th parameter.
Expand Down