mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge pull request #6648 from aschackmull/java/func-interface
Java: Fix FunctionalInterface.
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user