Skip to content

Commit

Permalink
Initial support for sealed classes
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 400303125
  • Loading branch information
cushon authored and Javac Team committed Oct 1, 2021
1 parent 3452789 commit 0b547dc
Show file tree
Hide file tree
Showing 27 changed files with 229 additions and 8 deletions.
1 change: 1 addition & 0 deletions java/com/google/turbine/binder/CanonicalTypeBinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static SourceTypeBoundClass bind(
ImmutableList<FieldInfo> fields = fields(base.source(), env, sym, base.fields());
return new SourceTypeBoundClass(
interfaceTypes.build(),
base.permits(),
superClassType,
typParamTypes,
base.access(),
Expand Down
1 change: 1 addition & 0 deletions java/com/google/turbine/binder/CompUnitPreprocessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ private static TyDecl packageInfoTree(PkgDecl pkgDecl) {
ImmutableList.of(),
ImmutableList.of(),
ImmutableList.of(),
ImmutableList.of(),
TurbineTyKind.INTERFACE,
/* javadoc= */ null);
}
Expand Down
1 change: 1 addition & 0 deletions java/com/google/turbine/binder/ConstBinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public SourceTypeBoundClass bind() {
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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public static SourceTypeBoundClass bind(
SourceTypeBoundClass base, Env<ClassSymbol, TypeBoundClass> env) {
return new SourceTypeBoundClass(
base.interfaceTypes(),
base.permits(),
base.superClassType(),
base.typeParameterTypes(),
base.access(),
Expand Down
10 changes: 10 additions & 0 deletions java/com/google/turbine/binder/TypeBinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ private SourceTypeBoundClass bind() {
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))
Expand All @@ -251,6 +260,7 @@ private SourceTypeBoundClass bind() {

return new SourceTypeBoundClass(
interfaceTypes.build(),
permits.build(),
superClassType,
typeParameterTypes,
base.access(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -75,6 +77,7 @@ public SourceTypeBoundClass(
SourceFile source,
Tree.TyDecl decl) {
this.interfaceTypes = interfaceTypes;
this.permits = permits;
this.superClassType = superClassType;
this.typeParameterTypes = typeParameterTypes;
this.access = access;
Expand Down Expand Up @@ -116,6 +119,11 @@ public ImmutableList<ClassSymbol> interfaces() {
return result.build();
}

@Override
public ImmutableList<ClassSymbol> permits() {
return permits;
}

@Override
public int access() {
return access;
Expand Down
4 changes: 4 additions & 0 deletions java/com/google/turbine/binder/bound/TypeBoundClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

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;
Expand All @@ -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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,11 @@ public ImmutableList<Type> interfaceTypes() {
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>>() {
Expand Down
17 changes: 16 additions & 1 deletion java/com/google/turbine/bytecode/Attribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ enum Kind {
NEST_HOST("NestHost"),
NEST_MEMBERS("NestMembers"),
RECORD("Record"),
TURBINE_TRANSITIVE_JAR("TurbineTransitiveJar");
TURBINE_TRANSITIVE_JAR("TurbineTransitiveJar"),
PERMITTED_SUBCLASSES("PermittedSubclasses");

private final String signature;

Expand Down Expand Up @@ -396,6 +397,20 @@ List<Attribute> attributes() {
}
}

/** 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 {

Expand Down
13 changes: 13 additions & 0 deletions java/com/google/turbine/bytecode/AttributeWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ public void write(ByteArrayDataOutput output, Attribute attribute) {
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;
Expand Down Expand Up @@ -318,6 +321,16 @@ private void writeRecord(ByteArrayDataOutput output, Attribute.Record attribute)
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()));
Expand Down
8 changes: 8 additions & 0 deletions java/com/google/turbine/bytecode/ClassFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -55,6 +56,7 @@ public ClassFile(
@Nullable String signature,
@Nullable String superClass,
List<String> interfaces,
List<String> permits,
List<MethodInfo> methods,
List<FieldInfo> fields,
List<AnnotationInfo> annotations,
Expand All @@ -71,6 +73,7 @@ public ClassFile(
this.signature = signature;
this.superClass = superClass;
this.interfaces = interfaces;
this.permits = permits;
this.methods = methods;
this.fields = fields;
this.annotations = annotations;
Expand Down Expand Up @@ -113,6 +116,11 @@ public List<String> interfaces() {
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;
Expand Down
1 change: 1 addition & 0 deletions java/com/google/turbine/bytecode/ClassReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ private ClassFile read() {
signature,
superClass,
interfaces,
/* permits= */ ImmutableList.of(),
methodinfos,
fieldinfos,
annotations.build(),
Expand Down
3 changes: 3 additions & 0 deletions java/com/google/turbine/bytecode/LowerAttributes.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ static List<Attribute> classAttributes(ClassFile classfile) {
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()));
}
Expand Down
1 change: 1 addition & 0 deletions java/com/google/turbine/deps/Transitive.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public static ClassFile trimClass(ClassFile cf, @Nullable String jarFile) {
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()
Expand Down
6 changes: 6 additions & 0 deletions java/com/google/turbine/lower/Lower.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ private byte[] lower(SourceModuleInfo module, Set<ClassSymbol> symbols, int majo
/* signature= */ null,
/* superClass= */ null,
/* interfaces= */ ImmutableList.of(),
/* permits= */ ImmutableList.of(),
/* methods= */ ImmutableList.of(),
/* fields= */ ImmutableList.of(),
annotations,
Expand Down Expand Up @@ -259,6 +260,10 @@ private byte[] 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)) {
Expand Down Expand Up @@ -310,6 +315,7 @@ record = new ClassFile.RecordInfo(components.build());
signature,
superName,
interfaces,
permits,
methods,
fields.build(),
annotations,
Expand Down
3 changes: 3 additions & 0 deletions java/com/google/turbine/model/TurbineFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
}
Loading

0 comments on commit 0b547dc

Please sign in to comment.