Merge pull request #7988 from Marcono1234/marcono1234/sealed-types-predicates

Java: Add predicates for sealed classes
This commit is contained in:
Tony Torralba
2022-02-15 15:11:56 +01:00
committed by GitHub
22 changed files with 68 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added predicates `ClassOrInterface.getAPermittedSubtype` and `isSealed` exposing information about sealed classes.

View File

@@ -913,6 +913,12 @@ class ClassOrInterface extends RefType, @classorinterface {
not this.isProtected() and
not this.isPublic()
}
/** Gets a permitted subtype in case this class or interface is a sealed class (Java 17 feature). */
ClassOrInterface getAPermittedSubtype() { permits(this, result) }
/** Holds if this class or interface is explicitly or implicitly a sealed class (Java 17 feature). */
predicate isSealed() { exists(this.getAPermittedSubtype()) }
}
private string getAPublicObjectMethodSignature() {

View File

@@ -0,0 +1,12 @@
| SealedClasses.java:5:25:5:44 | ExplicitPermitsClass | SealedClasses.java:7:25:7:38 | SealedSubClass |
| SealedClasses.java:5:25:5:44 | ExplicitPermitsClass | SealedClasses.java:10:29:10:45 | NonSealedSubClass |
| SealedClasses.java:5:25:5:44 | ExplicitPermitsClass | SealedClasses.java:12:24:12:36 | FinalSubClass |
| SealedClasses.java:7:25:7:38 | SealedSubClass | SealedClasses.java:8:24:8:39 | FinalSubSubClass |
| SealedClasses.java:17:22:17:45 | ExplicitPermitsInterface | SealedClasses.java:7:25:7:38 | SealedSubClass |
| SealedClasses.java:17:22:17:45 | ExplicitPermitsInterface | SealedClasses.java:19:22:19:39 | SealedSubInterface |
| SealedClasses.java:17:22:17:45 | ExplicitPermitsInterface | SealedClasses.java:22:26:22:46 | NonSealedSubInterface |
| SealedClasses.java:17:22:17:45 | ExplicitPermitsInterface | SealedClasses.java:24:12:24:22 | RecordClass |
| SealedClasses.java:17:22:17:45 | ExplicitPermitsInterface | SealedClasses.java:26:10:26:18 | EnumClass |
| SealedClasses.java:19:22:19:39 | SealedSubInterface | SealedClasses.java:20:24:20:42 | FinalInterfaceClass |
| SealedClasses.java:32:22:32:45 | ImplicitPermitsInterface | SealedClasses.java:33:26:33:52 | ImplicitPermitsSubInterface |
| SealedClasses.java:37:10:37:29 | ImplicitlySealedEnum | SealedClasses.java:38:9:38:9 | new ImplicitlySealedEnum(...) { ... } |

View File

@@ -0,0 +1,40 @@
class SealedClasses {
static class NonSealedClass { }
interface NonSealedInterface { }
static sealed class ExplicitPermitsClass permits SealedSubClass, NonSealedSubClass, FinalSubClass { }
static sealed class SealedSubClass extends ExplicitPermitsClass implements ExplicitPermitsInterface { }
static final class FinalSubSubClass extends SealedSubClass { }
static non-sealed class NonSealedSubClass extends ExplicitPermitsClass { }
static final class FinalSubClass extends ExplicitPermitsClass { }
static class ExtendingNonSealedClass extends NonSealedSubClass { }
sealed interface ExplicitPermitsInterface permits SealedSubClass, SealedSubInterface, NonSealedSubInterface, RecordClass, EnumClass { }
sealed interface SealedSubInterface extends ExplicitPermitsInterface { }
static final class FinalInterfaceClass implements SealedSubInterface { }
non-sealed interface NonSealedSubInterface extends ExplicitPermitsInterface { }
record RecordClass() implements ExplicitPermitsInterface { }
enum EnumClass implements ExplicitPermitsInterface { }
interface ExtendingNonSealedInterface extends NonSealedSubInterface { }
// `permits` clause may be omitted if all subtypes are in the same compilation unit
sealed interface ImplicitPermitsInterface { }
non-sealed interface ImplicitPermitsSubInterface extends ImplicitPermitsInterface { }
// Enum with anonymous subclass is implicitly sealed, see JLS 17 8.9
enum ImplicitlySealedEnum {
A { }
}
}

View File

@@ -0,0 +1,5 @@
import java
from ClassOrInterface c
where c.fromSource()
select c, c.getAPermittedSubtype()

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args --enable-preview -source 16 -target 16