Skip to content
Permalink
Browse files
8266466: [lworld] Enhance javac to consume unified primitive class fi…
…les generated under the option -XDunifiedValRefClass
  • Loading branch information
Srikanth Adayapalam committed May 24, 2021
1 parent ae4ce74 commit f9806a412e9440e3bf025f6421049dcdfb39e64d
Showing 15 changed files with 310 additions and 63 deletions.
@@ -1216,7 +1216,7 @@ public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
errorType.getKind() == TypeKind.ERROR) {
return extraType2OriginalMap.computeIfAbsent(classType, tt ->
new ClassType(classType.getEnclosingType(), classType.typarams_field,
classType.tsym, classType.getMetadata(), classType.isReferenceProjection()) {
classType.tsym, classType.getMetadata(), classType.getFlavor()) {
@Override
public Type baseType() { return classType; }
@Override
@@ -52,6 +52,7 @@
import javax.tools.JavaFileObject;

import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Type.ClassType.Flavor;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr;
@@ -1343,7 +1344,7 @@ public ClassSymbol(long flags, Name name, Symbol owner) {
this(
flags,
name,
new ClassType(Type.noType, null, null),
new ClassType(Type.noType, null, null, TypeMetadata.EMPTY, Flavor.X_Typeof_X),
owner);
this.type.tsym = this;
}
@@ -1381,7 +1382,7 @@ public Type erasure(Types types) {
erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
List.nil(), this,
type.getMetadata(),
type.isReferenceProjection());
type.getFlavor());
return erasure_field;
}

@@ -1450,6 +1451,14 @@ public void complete() throws CompletionFailure {
flags_field |= (PUBLIC|STATIC);
this.type = new ErrorType(this, Type.noType);
throw ex;
} finally {
if (this.type != null && this.type.hasTag(CLASS)) {
ClassType ct = (ClassType) this.type;
ct.flavor = ct.flavor.metamorphose((this.flags_field & PRIMITIVE_CLASS) != 0);
if (this.erasure_field != null && this.erasure_field.hasTag(CLASS)) {
((ClassType) this.erasure_field).flavor = ct.flavor;
}
}
}
}

@@ -1627,6 +1636,7 @@ public void reset() {
classType.supertype_field = null;
classType.interfaces_field = null;
classType.all_interfaces_field = null;
classType.flavor = Flavor.X_Typeof_X;
}
clearAnnotationMetadata();
}
@@ -35,6 +35,7 @@
import javax.lang.model.type.*;

import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType.Flavor;
import com.sun.tools.javac.code.TypeMetadata.Entry;
import com.sun.tools.javac.code.Types.TypeMapping;
import com.sun.tools.javac.code.Types.UniqueType;
@@ -240,6 +241,14 @@ public boolean isPrimitiveClass() {
return false;
}

/**
* Return the `flavor' associated with a ClassType.
* @see ClassType.Flavor
*/
public Flavor getFlavor() {
throw new AssertionError("Unexpected call to getFlavor() on a Type that is not a ClassType: " + this);
}

/**
* @return true IFF the receiver is a reference projection of an inline type and false
* for primitives or plain references
@@ -286,7 +295,7 @@ public Type visitClassType(ClassType t, S s) {
List<Type> typarams = t.getTypeArguments();
List<Type> typarams1 = visit(typarams, s);
if (outer1 == outer && typarams1 == typarams) return t;
else return new ClassType(outer1, typarams1, t.tsym, t.metadata, t.isReferenceProjection()) {
else return new ClassType(outer1, typarams1, t.tsym, t.metadata, t.getFlavor()) {
@Override
protected boolean needsStripping() {
return true;
@@ -1017,6 +1026,85 @@ public String toString() {
public static class ClassType extends Type implements DeclaredType, LoadableConstant,
javax.lang.model.type.ErrorType {

/**
* The 'flavor' of a ClassType indicates its reference/primitive projectionness
* viewed against the default nature of the associated class.
*/
public enum Flavor {

/**
* Classic reference type. Also reference projection type of a reference-favoring aka
* reference-default primitive class type
*/
L_TypeOf_L,

/**
* Reference projection type of a primitive-favoring aka primitive-default
* plain vanilla primitive class type,
*/
L_TypeOf_Q,

/**
* Value projection type of a primitive-favoring aka primitive-default
* plain vanilla primitive class type,
*/
Q_TypeOf_Q,

/**
* Value projection type of a reference-favoring aka
* reference-default primitive class type
*/
Q_TypeOf_L,

/**
* Reference projection type of a class type of an as yet unknown default provenance, 'X' will be
* discovered to be 'L' or 'Q' in "due course" and mutated suitably.
*/
L_TypeOf_X,

/**
* Value projection type of a class type of an as yet unknown default provenance, 'X' will be
* discovered to be 'L' or 'Q' in "due course" and mutated suitably.
*/
Q_TypeOf_X,

/**
* As yet unknown projection type of an as yet unknown default provenance class.
*/
X_Typeof_X,

/**
* An error type - we don't care to discriminate them any further.
*/
E_Typeof_X;

// We don't seem to need X_Typeof_L or X_Typeof_Q so far.

// Transform a larval form into a more evolved form
public Flavor metamorphose(boolean isPrimtiveClass) {

switch (this) {

case E_Typeof_X: // stunted form
case L_TypeOf_L:
case L_TypeOf_Q:
case Q_TypeOf_L:
case Q_TypeOf_Q:
// These are fully evolved sealed forms or stunted - no futher transformation
return this;
case L_TypeOf_X:
return isPrimtiveClass ? L_TypeOf_Q : L_TypeOf_L;
case Q_TypeOf_X:
return isPrimtiveClass ? Q_TypeOf_Q : Q_TypeOf_L;
case X_Typeof_X:
// TODO: Discriminate between ref-val defaultness
return isPrimtiveClass ? Q_TypeOf_Q : L_TypeOf_L;
default:
throw new AssertionError("Unexpected class type flavor");
}
}
}

/** The enclosing type of this type. If this is the type of an inner
* class, outer_field refers to the type of its enclosing
* instance class, in all other cases it refers to noType.
@@ -1050,28 +1138,27 @@ public static class ClassType extends Type implements DeclaredType, LoadableCons
*/
public ClassType projection;

/** Is this class type a reference projection of a primitive class type ?
/** Is this L of default {L, Q, X} or Q of default {L, Q, X} ?
*/
private boolean isReferenceProjection;
public Flavor flavor;

/*
* Use of this constructor is kinda sorta deprecated, use the other constructor
* that forces the call site to consider and include the class type flavor.
*/
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
this(outer, typarams, tsym, TypeMetadata.EMPTY, false);
this(outer, typarams, tsym, TypeMetadata.EMPTY, Flavor.L_TypeOf_L);
}

public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
TypeMetadata metadata) {
this(outer, typarams, tsym, metadata, false);
}

public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
TypeMetadata metadata, boolean isReferenceProjection) {
TypeMetadata metadata, Flavor flavor) {
super(tsym, metadata);
this.outer_field = outer != null && outer.isReferenceProjection() ? outer.valueProjection() : outer;
this.outer_field = outer;
this.typarams_field = typarams;
this.allparams_field = null;
this.supertype_field = null;
this.interfaces_field = null;
this.isReferenceProjection = isReferenceProjection;
this.flavor = flavor;
}

public int poolTag() {
@@ -1080,7 +1167,7 @@ public int poolTag() {

@Override
public ClassType cloneWithMetadata(TypeMetadata md) {
return new ClassType(outer_field, typarams_field, tsym, md, isReferenceProjection) {
return new ClassType(outer_field, typarams_field, tsym, md, flavor) {
@Override
public Type baseType() { return ClassType.this.baseType(); }
};
@@ -1098,7 +1185,7 @@ public <R,S> R accept(Type.Visitor<R,S> v, S s) {

public Type constType(Object constValue) {
final Object value = constValue;
return new ClassType(getEnclosingType(), typarams_field, tsym, metadata, isReferenceProjection) {
return new ClassType(getEnclosingType(), typarams_field, tsym, metadata, flavor) {
@Override
public Object constValue() {
return value;
@@ -1125,6 +1212,12 @@ public String toString() {
buf.append(className(tsym, true));
}

boolean isReferenceProjection;
try {
isReferenceProjection = isReferenceProjection();
} catch (CompletionFailure cf) {
isReferenceProjection = false; // handle missing types gracefully.
}
if (isReferenceProjection) {
buf.append('.');
buf.append(tsym.name.table.names.ref);
@@ -1171,6 +1264,10 @@ private String className(Symbol sym, boolean longform) {
return s;
}

public Flavor getFlavor() {
return flavor;
}

@DefinedBy(Api.LANGUAGE_MODEL)
public List<Type> getTypeArguments() {
if (typarams_field == null) {
@@ -1187,11 +1284,14 @@ public boolean hasErasedSupertypes() {

@DefinedBy(Api.LANGUAGE_MODEL)
public Type getEnclosingType() {
if (outer_field != null && outer_field.isReferenceProjection()) {
outer_field = outer_field.valueProjection();
}
return outer_field;
}

public void setEnclosingType(Type outer) {
outer_field = outer != null && outer.isReferenceProjection() ? outer.valueProjection() : outer;
outer_field = outer;
}

public List<Type> allparams() {
@@ -1220,12 +1320,18 @@ public boolean isReference() {

@Override
public boolean isPrimitiveClass() {
return !isReferenceProjection && tsym != null && tsym.isPrimitiveClass();
return !isReferenceProjection() && tsym != null && tsym.isPrimitiveClass();
}

@Override
public boolean isReferenceProjection() {
return isReferenceProjection;
// gaurd against over-eager and/or inopportune completion
if (tsym != null) {
if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
flavor = flavor.metamorphose(tsym.isPrimitiveClass());
}
}
return flavor == Flavor.L_TypeOf_Q;
}

@Override
@@ -1236,7 +1342,7 @@ public Type valueProjection() {
if (projection != null)
return projection;

projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), false);
projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.Q_TypeOf_Q);
projection.allparams_field = allparams_field;
projection.supertype_field = supertype_field;

@@ -1256,7 +1362,7 @@ public ClassType referenceProjection() {
if (projection != null)
return projection;

projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), true);
projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.L_TypeOf_Q);
projection.allparams_field = allparams_field;
projection.supertype_field = supertype_field;

@@ -1314,7 +1420,7 @@ public <R, P> R accept(TypeVisitor<R, P> v, P p) {
public static class ErasedClassType extends ClassType {
public ErasedClassType(Type outer, TypeSymbol tsym,
TypeMetadata metadata) {
super(outer, List.nil(), tsym, metadata, false);
super(outer, List.nil(), tsym, metadata, tsym.type.getFlavor());
}

@Override
@@ -2479,21 +2585,20 @@ public ErrorType(ClassSymbol c, Type originalType) {
}

public ErrorType(Type originalType, TypeSymbol tsym) {
super(noType, List.nil(), null);
this.tsym = tsym;
super(noType, List.nil(), tsym, TypeMetadata.EMPTY, Flavor.E_Typeof_X);
this.originalType = (originalType == null ? noType : originalType);
}

private ErrorType(Type originalType, TypeSymbol tsym,
TypeMetadata metadata) {
super(noType, List.nil(), null, metadata);
TypeMetadata metadata, Flavor flavor) {
super(noType, List.nil(), null, metadata, flavor);
this.tsym = tsym;
this.originalType = (originalType == null ? noType : originalType);
}

@Override
public ErrorType cloneWithMetadata(TypeMetadata md) {
return new ErrorType(originalType, tsym, md) {
return new ErrorType(originalType, tsym, md, getFlavor()) {
@Override
public Type baseType() { return ErrorType.this.baseType(); }
};
@@ -627,7 +627,7 @@ public Type visitClassType(ClassType t, List<TypeCompound> s) {
} else {
ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
t.typarams_field, t.tsym,
t.getMetadata(), t.isReferenceProjection());
t.getMetadata(), t.getFlavor());
ret.all_interfaces_field = t.all_interfaces_field;
ret.allparams_field = t.allparams_field;
ret.interfaces_field = t.interfaces_field;

0 comments on commit f9806a4

Please sign in to comment.