aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2021-10-01 15:20:24 -0700
committerJavac Team <javac-team+copybara@google.com>2021-10-01 15:21:00 -0700
commit0b547dc65ba2628d4dc595e8395c6f4cd7652170 (patch)
treeda2d4068f949bacc1653178c8a5d7be241848d61 /java
parent3452789854d581fbad3068d22d64b7319d19e8b4 (diff)
downloadturbine-0b547dc65ba2628d4dc595e8395c6f4cd7652170.tar.gz
Initial support for sealed classes
PiperOrigin-RevId: 400303125
Diffstat (limited to 'java')
-rw-r--r--java/com/google/turbine/binder/CanonicalTypeBinder.java1
-rw-r--r--java/com/google/turbine/binder/CompUnitPreprocessor.java1
-rw-r--r--java/com/google/turbine/binder/ConstBinder.java1
-rw-r--r--java/com/google/turbine/binder/DisambiguateTypeAnnotations.java1
-rw-r--r--java/com/google/turbine/binder/TypeBinder.java10
-rw-r--r--java/com/google/turbine/binder/bound/SourceTypeBoundClass.java8
-rw-r--r--java/com/google/turbine/binder/bound/TypeBoundClass.java4
-rw-r--r--java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java5
-rw-r--r--java/com/google/turbine/bytecode/Attribute.java17
-rw-r--r--java/com/google/turbine/bytecode/AttributeWriter.java13
-rw-r--r--java/com/google/turbine/bytecode/ClassFile.java8
-rw-r--r--java/com/google/turbine/bytecode/ClassReader.java1
-rw-r--r--java/com/google/turbine/bytecode/LowerAttributes.java3
-rw-r--r--java/com/google/turbine/deps/Transitive.java1
-rw-r--r--java/com/google/turbine/lower/Lower.java6
-rw-r--r--java/com/google/turbine/model/TurbineFlag.java3
-rw-r--r--java/com/google/turbine/parse/Parser.java77
-rw-r--r--java/com/google/turbine/tree/Pretty.java13
-rw-r--r--java/com/google/turbine/tree/Tree.java7
-rw-r--r--java/com/google/turbine/tree/TurbineModifier.java6
20 files changed, 179 insertions, 7 deletions
diff --git a/java/com/google/turbine/binder/CanonicalTypeBinder.java b/java/com/google/turbine/binder/CanonicalTypeBinder.java
index cbdc025..944563f 100644
--- a/java/com/google/turbine/binder/CanonicalTypeBinder.java
+++ b/java/com/google/turbine/binder/CanonicalTypeBinder.java
@@ -67,6 +67,7 @@ public final class CanonicalTypeBinder {
ImmutableList<FieldInfo> fields = fields(base.source(), env, sym, base.fields());
return new SourceTypeBoundClass(
interfaceTypes.build(),
+ base.permits(),
superClassType,
typParamTypes,
base.access(),
diff --git a/java/com/google/turbine/binder/CompUnitPreprocessor.java b/java/com/google/turbine/binder/CompUnitPreprocessor.java
index 3323938..0e9f4e5 100644
--- a/java/com/google/turbine/binder/CompUnitPreprocessor.java
+++ b/java/com/google/turbine/binder/CompUnitPreprocessor.java
@@ -225,6 +225,7 @@ public final class CompUnitPreprocessor {
ImmutableList.of(),
ImmutableList.of(),
ImmutableList.of(),
+ ImmutableList.of(),
TurbineTyKind.INTERFACE,
/* javadoc= */ null);
}
diff --git a/java/com/google/turbine/binder/ConstBinder.java b/java/com/google/turbine/binder/ConstBinder.java
index 232370c..3ba059f 100644
--- a/java/com/google/turbine/binder/ConstBinder.java
+++ b/java/com/google/turbine/binder/ConstBinder.java
@@ -110,6 +110,7 @@ public class ConstBinder {
ImmutableList<MethodInfo> methods = bindMethods(base.methods());
return new SourceTypeBoundClass(
bindTypes(base.interfaceTypes()),
+ base.permits(),
base.superClassType() != null ? bindType(base.superClassType()) : null,
bindTypeParameters(base.typeParameterTypes()),
base.access(),
diff --git a/java/com/google/turbine/binder/DisambiguateTypeAnnotations.java b/java/com/google/turbine/binder/DisambiguateTypeAnnotations.java
index 4929962..65c1021 100644
--- a/java/com/google/turbine/binder/DisambiguateTypeAnnotations.java
+++ b/java/com/google/turbine/binder/DisambiguateTypeAnnotations.java
@@ -71,6 +71,7 @@ public final class DisambiguateTypeAnnotations {
SourceTypeBoundClass base, Env<ClassSymbol, TypeBoundClass> env) {
return new SourceTypeBoundClass(
base.interfaceTypes(),
+ base.permits(),
base.superClassType(),
base.typeParameterTypes(),
base.access(),
diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java
index f4b4849..ccc0ad3 100644
--- a/java/com/google/turbine/binder/TypeBinder.java
+++ b/java/com/google/turbine/binder/TypeBinder.java
@@ -229,6 +229,15 @@ public class TypeBinder {
interfaceTypes.add(bindClassTy(bindingScope, i));
}
+ ImmutableList.Builder<ClassSymbol> permits = ImmutableList.builder();
+ for (Tree.ClassTy i : base.decl().permits()) {
+ Type type = bindClassTy(bindingScope, i);
+ if (!type.tyKind().equals(Type.TyKind.CLASS_TY)) {
+ throw new AssertionError(type.tyKind());
+ }
+ permits.add(((Type.ClassTy) type).sym());
+ }
+
CompoundScope scope =
base.scope()
.toScope(Resolve.resolveFunction(env, owner))
@@ -251,6 +260,7 @@ public class TypeBinder {
return new SourceTypeBoundClass(
interfaceTypes.build(),
+ permits.build(),
superClassType,
typeParameterTypes,
base.access(),
diff --git a/java/com/google/turbine/binder/bound/SourceTypeBoundClass.java b/java/com/google/turbine/binder/bound/SourceTypeBoundClass.java
index fb3ee27..5e9817e 100644
--- a/java/com/google/turbine/binder/bound/SourceTypeBoundClass.java
+++ b/java/com/google/turbine/binder/bound/SourceTypeBoundClass.java
@@ -44,6 +44,7 @@ public class SourceTypeBoundClass implements TypeBoundClass {
private final ImmutableMap<TyVarSymbol, TyVarInfo> typeParameterTypes;
private final @Nullable Type superClassType;
private final ImmutableList<Type> interfaceTypes;
+ private final ImmutableList<ClassSymbol> permits;
private final ImmutableList<RecordComponentInfo> components;
private final ImmutableList<MethodInfo> methods;
private final ImmutableList<FieldInfo> fields;
@@ -57,6 +58,7 @@ public class SourceTypeBoundClass implements TypeBoundClass {
public SourceTypeBoundClass(
ImmutableList<Type> interfaceTypes,
+ ImmutableList<ClassSymbol> permits,
@Nullable Type superClassType,
ImmutableMap<TyVarSymbol, TyVarInfo> typeParameterTypes,
int access,
@@ -75,6 +77,7 @@ public class SourceTypeBoundClass implements TypeBoundClass {
SourceFile source,
Tree.TyDecl decl) {
this.interfaceTypes = interfaceTypes;
+ this.permits = permits;
this.superClassType = superClassType;
this.typeParameterTypes = typeParameterTypes;
this.access = access;
@@ -117,6 +120,11 @@ public class SourceTypeBoundClass implements TypeBoundClass {
}
@Override
+ public ImmutableList<ClassSymbol> permits() {
+ return permits;
+ }
+
+ @Override
public int access() {
return access;
}
diff --git a/java/com/google/turbine/binder/bound/TypeBoundClass.java b/java/com/google/turbine/binder/bound/TypeBoundClass.java
index cc28901..8321bde 100644
--- a/java/com/google/turbine/binder/bound/TypeBoundClass.java
+++ b/java/com/google/turbine/binder/bound/TypeBoundClass.java
@@ -18,6 +18,7 @@ package com.google.turbine.binder.bound;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.FieldSymbol;
import com.google.turbine.binder.sym.MethodSymbol;
import com.google.turbine.binder.sym.ParamSymbol;
@@ -43,6 +44,9 @@ public interface TypeBoundClass extends HeaderBoundClass {
/** Implemented interface types. */
ImmutableList<Type> interfaceTypes();
+ /** The permitted direct subclasses. */
+ ImmutableList<ClassSymbol> permits();
+
ImmutableMap<TyVarSymbol, TyVarInfo> typeParameterTypes();
/** Declared fields. */
diff --git a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
index 516a027..9be2dd1 100644
--- a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
+++ b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java
@@ -306,6 +306,11 @@ public class BytecodeBoundClass implements TypeBoundClass {
return interfaceTypes.get();
}
+ @Override
+ public ImmutableList<ClassSymbol> permits() {
+ return ImmutableList.of();
+ }
+
private final Supplier<ImmutableMap<TyVarSymbol, TyVarInfo>> typeParameterTypes =
Suppliers.memoize(
new Supplier<ImmutableMap<TyVarSymbol, TyVarInfo>>() {
diff --git a/java/com/google/turbine/bytecode/Attribute.java b/java/com/google/turbine/bytecode/Attribute.java
index 581de3d..ad6ffc1 100644
--- a/java/com/google/turbine/bytecode/Attribute.java
+++ b/java/com/google/turbine/bytecode/Attribute.java
@@ -45,7 +45,8 @@ interface Attribute {
NEST_HOST("NestHost"),
NEST_MEMBERS("NestMembers"),
RECORD("Record"),
- TURBINE_TRANSITIVE_JAR("TurbineTransitiveJar");
+ TURBINE_TRANSITIVE_JAR("TurbineTransitiveJar"),
+ PERMITTED_SUBCLASSES("PermittedSubclasses");
private final String signature;
@@ -396,6 +397,20 @@ interface Attribute {
}
}
+ /** A JVMS ยง4.7.31 PermittedSubclasses attribute. */
+ class PermittedSubclasses implements Attribute {
+ final List<String> permits;
+
+ public PermittedSubclasses(List<String> permits) {
+ this.permits = permits;
+ }
+
+ @Override
+ public Kind kind() {
+ return Kind.PERMITTED_SUBCLASSES;
+ }
+ }
+
/** A custom attribute for recording the original jar of repackaged transitive classes. */
class TurbineTransitiveJar implements Attribute {
diff --git a/java/com/google/turbine/bytecode/AttributeWriter.java b/java/com/google/turbine/bytecode/AttributeWriter.java
index ed7b2ab..6aac19a 100644
--- a/java/com/google/turbine/bytecode/AttributeWriter.java
+++ b/java/com/google/turbine/bytecode/AttributeWriter.java
@@ -95,6 +95,9 @@ public class AttributeWriter {
case RECORD:
writeRecord(output, (Attribute.Record) attribute);
break;
+ case PERMITTED_SUBCLASSES:
+ writePermittedSubclasses(output, (Attribute.PermittedSubclasses) attribute);
+ break;
case TURBINE_TRANSITIVE_JAR:
writeTurbineTransitiveJar(output, (Attribute.TurbineTransitiveJar) attribute);
break;
@@ -318,6 +321,16 @@ public class AttributeWriter {
output.write(data);
}
+ private void writePermittedSubclasses(
+ ByteArrayDataOutput output, Attribute.PermittedSubclasses attribute) {
+ output.writeShort(pool.utf8(attribute.kind().signature()));
+ output.writeInt(2 + attribute.permits.size() * 2);
+ output.writeShort(attribute.permits.size());
+ for (String permits : attribute.permits) {
+ output.writeShort(pool.classInfo(permits));
+ }
+ }
+
private void writeTurbineTransitiveJar(
ByteArrayDataOutput output, TurbineTransitiveJar attribute) {
output.writeShort(pool.utf8(attribute.kind().signature()));
diff --git a/java/com/google/turbine/bytecode/ClassFile.java b/java/com/google/turbine/bytecode/ClassFile.java
index 124e03c..820f17d 100644
--- a/java/com/google/turbine/bytecode/ClassFile.java
+++ b/java/com/google/turbine/bytecode/ClassFile.java
@@ -37,6 +37,7 @@ public class ClassFile {
private final @Nullable String signature;
private final @Nullable String superClass;
private final List<String> interfaces;
+ private final List<String> permits;
private final List<MethodInfo> methods;
private final List<FieldInfo> fields;
private final List<AnnotationInfo> annotations;
@@ -55,6 +56,7 @@ public class ClassFile {
@Nullable String signature,
@Nullable String superClass,
List<String> interfaces,
+ List<String> permits,
List<MethodInfo> methods,
List<FieldInfo> fields,
List<AnnotationInfo> annotations,
@@ -71,6 +73,7 @@ public class ClassFile {
this.signature = signature;
this.superClass = superClass;
this.interfaces = interfaces;
+ this.permits = permits;
this.methods = methods;
this.fields = fields;
this.annotations = annotations;
@@ -113,6 +116,11 @@ public class ClassFile {
return interfaces;
}
+ /** The permitted direct subclasses. */
+ public List<String> permits() {
+ return permits;
+ }
+
/** Methods declared by this class or interfaces type. */
public List<MethodInfo> methods() {
return methods;
diff --git a/java/com/google/turbine/bytecode/ClassReader.java b/java/com/google/turbine/bytecode/ClassReader.java
index b429032..0f08fc3 100644
--- a/java/com/google/turbine/bytecode/ClassReader.java
+++ b/java/com/google/turbine/bytecode/ClassReader.java
@@ -143,6 +143,7 @@ public class ClassReader {
signature,
superClass,
interfaces,
+ /* permits= */ ImmutableList.of(),
methodinfos,
fieldinfos,
annotations.build(),
diff --git a/java/com/google/turbine/bytecode/LowerAttributes.java b/java/com/google/turbine/bytecode/LowerAttributes.java
index 54937fc..8952dff 100644
--- a/java/com/google/turbine/bytecode/LowerAttributes.java
+++ b/java/com/google/turbine/bytecode/LowerAttributes.java
@@ -54,6 +54,9 @@ public final class LowerAttributes {
if (classfile.record() != null) {
attributes.add(recordAttribute(classfile.record()));
}
+ if (!classfile.permits().isEmpty()) {
+ attributes.add(new Attribute.PermittedSubclasses(classfile.permits()));
+ }
if (classfile.transitiveJar() != null) {
attributes.add(new Attribute.TurbineTransitiveJar(classfile.transitiveJar()));
}
diff --git a/java/com/google/turbine/deps/Transitive.java b/java/com/google/turbine/deps/Transitive.java
index 62d15c3..fa3d475 100644
--- a/java/com/google/turbine/deps/Transitive.java
+++ b/java/com/google/turbine/deps/Transitive.java
@@ -95,6 +95,7 @@ public final class Transitive {
cf.signature(),
cf.superName(),
cf.interfaces(),
+ cf.permits(),
// drop methods, except for annotations where we need to resolve key/value information
(cf.access() & TurbineFlag.ACC_ANNOTATION) == TurbineFlag.ACC_ANNOTATION
? cf.methods()
diff --git a/java/com/google/turbine/lower/Lower.java b/java/com/google/turbine/lower/Lower.java
index 0f3eb24..ff7e13c 100644
--- a/java/com/google/turbine/lower/Lower.java
+++ b/java/com/google/turbine/lower/Lower.java
@@ -192,6 +192,7 @@ public class Lower {
/* signature= */ null,
/* superClass= */ null,
/* interfaces= */ ImmutableList.of(),
+ /* permits= */ ImmutableList.of(),
/* methods= */ ImmutableList.of(),
/* fields= */ ImmutableList.of(),
annotations,
@@ -259,6 +260,10 @@ public class Lower {
for (ClassSymbol i : info.interfaces()) {
interfaces.add(sig.descriptor(i));
}
+ List<String> permits = new ArrayList<>();
+ for (ClassSymbol i : info.permits()) {
+ permits.add(sig.descriptor(i));
+ }
ClassFile.RecordInfo record = null;
if (info.kind().equals(TurbineTyKind.RECORD)) {
@@ -310,6 +315,7 @@ public class Lower {
signature,
superName,
interfaces,
+ permits,
methods,
fields.build(),
annotations,
diff --git a/java/com/google/turbine/model/TurbineFlag.java b/java/com/google/turbine/model/TurbineFlag.java
index c138d46..6e8d64b 100644
--- a/java/com/google/turbine/model/TurbineFlag.java
+++ b/java/com/google/turbine/model/TurbineFlag.java
@@ -55,5 +55,8 @@ public final class TurbineFlag {
/** Synthetic constructors (e.g. of inner classes and enums). */
public static final int ACC_SYNTH_CTOR = 1 << 18;
+ public static final int ACC_SEALED = 1 << 19;
+ public static final int ACC_NON_SEALED = 1 << 20;
+
private TurbineFlag() {}
}
diff --git a/java/com/google/turbine/parse/Parser.java b/java/com/google/turbine/parse/Parser.java
index 06b3db6..ed8958e 100644
--- a/java/com/google/turbine/parse/Parser.java
+++ b/java/com/google/turbine/parse/Parser.java
@@ -17,8 +17,10 @@
package com.google.turbine.parse;
import static com.google.turbine.parse.Token.COMMA;
+import static com.google.turbine.parse.Token.IDENT;
import static com.google.turbine.parse.Token.INTERFACE;
import static com.google.turbine.parse.Token.LPAREN;
+import static com.google.turbine.parse.Token.MINUS;
import static com.google.turbine.parse.Token.RPAREN;
import static com.google.turbine.parse.Token.SEMI;
import static com.google.turbine.tree.TurbineModifier.PROTECTED;
@@ -187,12 +189,25 @@ public class Parser {
{
Ident ident = ident();
if (ident.value().equals("record")) {
- ident = eatIdent();
+ next();
decls.add(recordDeclaration(access, annos.build()));
access = EnumSet.noneOf(TurbineModifier.class);
annos = ImmutableList.builder();
break;
}
+ if (ident.value().equals("sealed")) {
+ next();
+ access.add(TurbineModifier.SEALED);
+ break;
+ }
+ if (ident.value().equals("non")) {
+ int start = position;
+ next();
+ eatNonSealed(start);
+ next();
+ access.add(TurbineModifier.NON_SEALED);
+ break;
+ }
if (access.isEmpty()
&& (ident.value().equals("module") || ident.value().equals("open"))) {
boolean open = false;
@@ -216,6 +231,22 @@ public class Parser {
}
}
+ // Handle the hypenated pseudo-keyword 'non-sealed'.
+ //
+ // This will need to be updated to handle other hyphenated keywords if when/they are introduced.
+ private void eatNonSealed(int start) {
+ eat(Token.MINUS);
+ if (token != IDENT) {
+ throw error(token);
+ }
+ if (!ident().value().equals("sealed")) {
+ throw error(token);
+ }
+ if (position != start + "non-".length()) {
+ throw error(token);
+ }
+ }
+
private void next() {
token = lexer.next();
position = lexer.position();
@@ -255,6 +286,7 @@ public class Parser {
typarams,
Optional.<ClassTy>empty(),
interfaces.build(),
+ /* permits= */ ImmutableList.of(),
members,
formals.build(),
TurbineTyKind.RECORD,
@@ -279,6 +311,15 @@ public class Parser {
interfaces.add(classty());
} while (maybe(Token.COMMA));
}
+ ImmutableList.Builder<ClassTy> permits = ImmutableList.builder();
+ if (token == Token.IDENT) {
+ if (ident().value().equals("permits")) {
+ eat(Token.IDENT);
+ do {
+ permits.add(classty());
+ } while (maybe(Token.COMMA));
+ }
+ }
eat(Token.LBRACE);
ImmutableList<Tree> members = classMembers();
eat(Token.RBRACE);
@@ -290,6 +331,7 @@ public class Parser {
typarams,
Optional.<ClassTy>empty(),
interfaces.build(),
+ permits.build(),
members,
ImmutableList.of(),
TurbineTyKind.INTERFACE,
@@ -312,6 +354,7 @@ public class Parser {
ImmutableList.<TyParam>of(),
Optional.<ClassTy>empty(),
ImmutableList.<ClassTy>of(),
+ ImmutableList.of(),
members,
ImmutableList.of(),
TurbineTyKind.ANNOTATION,
@@ -342,6 +385,7 @@ public class Parser {
ImmutableList.<TyParam>of(),
Optional.<ClassTy>empty(),
interfaces.build(),
+ ImmutableList.of(),
members,
ImmutableList.of(),
TurbineTyKind.ENUM,
@@ -569,6 +613,15 @@ public class Parser {
interfaces.add(classty());
} while (maybe(Token.COMMA));
}
+ ImmutableList.Builder<ClassTy> permits = ImmutableList.builder();
+ if (token == Token.IDENT) {
+ if (ident().value().equals("permits")) {
+ eat(Token.IDENT);
+ do {
+ permits.add(classty());
+ } while (maybe(Token.COMMA));
+ }
+ }
switch (token) {
case LBRACE:
next();
@@ -588,6 +641,7 @@ public class Parser {
tyParams,
Optional.ofNullable(xtnds),
interfaces.build(),
+ permits.build(),
members,
ImmutableList.of(),
TurbineTyKind.CLASS,
@@ -665,8 +719,22 @@ public class Parser {
case IDENT:
Ident ident = ident();
+ if (ident.value().equals("non")) {
+ int pos = position;
+ next();
+ if (token != MINUS) {
+ acc.addAll(member(access, annos.build(), ImmutableList.of(), pos, ident));
+ access = EnumSet.noneOf(TurbineModifier.class);
+ annos = ImmutableList.builder();
+ } else {
+ eatNonSealed(pos);
+ next();
+ access.add(TurbineModifier.NON_SEALED);
+ }
+ break;
+ }
if (ident.value().equals("record")) {
- eat(Token.IDENT);
+ eat(IDENT);
acc.add(recordDeclaration(access, annos.build()));
access = EnumSet.noneOf(TurbineModifier.class);
annos = ImmutableList.builder();
@@ -758,13 +826,13 @@ public class Parser {
case IDENT:
int pos = position;
Ident ident = eatIdent();
- return classMemberIdent(access, annos, typaram, pos, ident);
+ return member(access, annos, typaram, pos, ident);
default:
throw error(token);
}
}
- private ImmutableList<Tree> classMemberIdent(
+ private ImmutableList<Tree> member(
EnumSet<TurbineModifier> access,
ImmutableList<Anno> annos,
ImmutableList<TyParam> typaram,
@@ -820,6 +888,7 @@ public class Parser {
ImmutableList.<Type>of(),
ImmutableList.of());
break;
+
default:
throw error(token);
}
diff --git a/java/com/google/turbine/tree/Pretty.java b/java/com/google/turbine/tree/Pretty.java
index 84b4ab5..788ab58 100644
--- a/java/com/google/turbine/tree/Pretty.java
+++ b/java/com/google/turbine/tree/Pretty.java
@@ -459,6 +459,17 @@ public class Pretty implements Tree.Visitor<@Nullable Void, @Nullable Void> {
first = false;
}
}
+ if (!tyDecl.permits().isEmpty()) {
+ append(" permits ");
+ boolean first = true;
+ for (Tree.ClassTy t : tyDecl.permits()) {
+ if (!first) {
+ append(", ");
+ }
+ t.accept(this, null);
+ first = false;
+ }
+ }
append(" {").append('\n');
indent++;
switch (tyDecl.tykind()) {
@@ -522,6 +533,8 @@ public class Pretty implements Tree.Visitor<@Nullable Void, @Nullable Void> {
case TRANSIENT:
case DEFAULT:
case TRANSITIVE:
+ case SEALED:
+ case NON_SEALED:
append(mod.toString()).append(' ');
break;
case ACC_SUPER:
diff --git a/java/com/google/turbine/tree/Tree.java b/java/com/google/turbine/tree/Tree.java
index ce32628..f7917b9 100644
--- a/java/com/google/turbine/tree/Tree.java
+++ b/java/com/google/turbine/tree/Tree.java
@@ -934,6 +934,7 @@ public abstract class Tree {
private final ImmutableList<TyParam> typarams;
private final Optional<ClassTy> xtnds;
private final ImmutableList<ClassTy> impls;
+ private final ImmutableList<ClassTy> permits;
private final ImmutableList<Tree> members;
private final ImmutableList<VarDecl> components;
private final TurbineTyKind tykind;
@@ -947,6 +948,7 @@ public abstract class Tree {
ImmutableList<TyParam> typarams,
Optional<ClassTy> xtnds,
ImmutableList<ClassTy> impls,
+ ImmutableList<ClassTy> permits,
ImmutableList<Tree> members,
ImmutableList<VarDecl> components,
TurbineTyKind tykind,
@@ -958,6 +960,7 @@ public abstract class Tree {
this.typarams = typarams;
this.xtnds = xtnds;
this.impls = impls;
+ this.permits = permits;
this.members = members;
this.components = components;
this.tykind = tykind;
@@ -999,6 +1002,10 @@ public abstract class Tree {
return impls;
}
+ public ImmutableList<ClassTy> permits() {
+ return permits;
+ }
+
public ImmutableList<Tree> members() {
return members;
}
diff --git a/java/com/google/turbine/tree/TurbineModifier.java b/java/com/google/turbine/tree/TurbineModifier.java
index 35dc11c..e5153b9 100644
--- a/java/com/google/turbine/tree/TurbineModifier.java
+++ b/java/com/google/turbine/tree/TurbineModifier.java
@@ -45,7 +45,9 @@ public enum TurbineModifier {
ACC_SYNTHETIC(TurbineFlag.ACC_SYNTHETIC),
ACC_BRIDGE(TurbineFlag.ACC_BRIDGE),
DEFAULT(TurbineFlag.ACC_DEFAULT),
- TRANSITIVE(TurbineFlag.ACC_TRANSITIVE);
+ TRANSITIVE(TurbineFlag.ACC_TRANSITIVE),
+ SEALED(TurbineFlag.ACC_SEALED),
+ NON_SEALED(TurbineFlag.ACC_NON_SEALED);
private final int flag;
@@ -59,6 +61,6 @@ public enum TurbineModifier {
@Override
public String toString() {
- return name().toLowerCase(ENGLISH);
+ return name().replace('_', '-').toLowerCase(ENGLISH);
}
}