All the special types are now handled by SpecialTypes class
- this concept used to be called "known types" before
This commit is contained in:
@@ -217,7 +217,7 @@ public class CodegenContexts {
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, typeMapper.getClassFQName(contextDescriptor), "this$0", false)
|
||||
? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,11 +83,78 @@ public class JetTypeMapper {
|
||||
public static final Type TYPE_FUNCTION0 = Type.getObjectType("jet/Function0");
|
||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||
|
||||
public static class SpecialTypes {
|
||||
private static final class SpecialTypeKey {
|
||||
@NotNull
|
||||
private final FqNameUnsafe className;
|
||||
private final boolean nullable;
|
||||
|
||||
private SpecialTypeKey(@NotNull FqNameUnsafe className, boolean nullable) {
|
||||
this.className = className;
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SpecialTypeKey that = (SpecialTypeKey) o;
|
||||
|
||||
if (nullable != that.nullable) return false;
|
||||
if (!className.equals(that.className)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = className.hashCode();
|
||||
result = 31 * result + (nullable ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<SpecialTypeKey, Type> asmTypes = Maps.newHashMap();
|
||||
|
||||
@Nullable
|
||||
public Type get(@NotNull JetType type) {
|
||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||
return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable()));
|
||||
}
|
||||
|
||||
private void register(@NotNull ClassName className, @NotNull Type nonNullType, @NotNull Type nullableType) {
|
||||
asmTypes.put(new SpecialTypeKey(className.getFqName().toUnsafe(), true), nullableType);
|
||||
asmTypes.put(new SpecialTypeKey(className.getFqName().toUnsafe(), false), nonNullType);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
register(JetStandardLibraryNames.NOTHING, TYPE_NOTHING, TYPE_NOTHING);
|
||||
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||
register(primitiveType.getClassName(), jvmPrimitiveType.getAsmType(), jvmPrimitiveType.getWrapper().getAsmType());
|
||||
}
|
||||
|
||||
register(JetStandardLibraryNames.NUMBER, JL_NUMBER_TYPE, JL_NUMBER_TYPE);
|
||||
register(JetStandardLibraryNames.STRING, JL_STRING_TYPE, JL_STRING_TYPE);
|
||||
register(JetStandardLibraryNames.CHAR_SEQUENCE, JL_CHAR_SEQUENCE_TYPE, JL_CHAR_SEQUENCE_TYPE);
|
||||
register(JetStandardLibraryNames.THROWABLE, TYPE_THROWABLE, TYPE_THROWABLE);
|
||||
register(JetStandardLibraryNames.COMPARABLE, JL_COMPARABLE_TYPE, JL_COMPARABLE_TYPE);
|
||||
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||
register(primitiveType.getArrayClassName(), jvmPrimitiveType.getAsmArrayType(), jvmPrimitiveType.getAsmArrayType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public BindingContext bindingContext;
|
||||
private ClosureAnnotator closureAnnotator;
|
||||
private boolean mapBuiltinsToJava;
|
||||
private ClassBuilderMode classBuilderMode;
|
||||
|
||||
private final SpecialTypes specialTypes = new SpecialTypes();
|
||||
|
||||
@Inject
|
||||
public void setBindingContext(BindingContext bindingContext) {
|
||||
@@ -111,12 +178,9 @@ public class JetTypeMapper {
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
initKnownTypes();
|
||||
specialTypes.init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean hasThis0(ClassDescriptor classDescriptor) {
|
||||
return closureAnnotator.hasThis0(classDescriptor);
|
||||
}
|
||||
@@ -125,40 +189,6 @@ public class JetTypeMapper {
|
||||
return closureAnnotator;
|
||||
}
|
||||
|
||||
private static final class KnownTypeKey {
|
||||
@NotNull
|
||||
private final FqNameUnsafe className;
|
||||
private final boolean nullable;
|
||||
|
||||
private KnownTypeKey(@NotNull FqNameUnsafe className, boolean nullable) {
|
||||
this.className = className;
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
KnownTypeKey that = (KnownTypeKey) o;
|
||||
|
||||
if (nullable != that.nullable) return false;
|
||||
if (!className.equals(that.className)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = className.hashCode();
|
||||
result = 31 * result + (nullable ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final HashMap<KnownTypeKey, Type> knowTypes = Maps.newHashMap();
|
||||
|
||||
|
||||
public static boolean isIntPrimitive(Type type) {
|
||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
||||
}
|
||||
@@ -308,17 +338,12 @@ public class JetTypeMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JvmClassName getClassFQName(ClassDescriptor classDescriptor) {
|
||||
return JvmClassName.byInternalName(getFQName(classDescriptor));
|
||||
public JvmClassName getJvmClassName(ClassDescriptor classDescriptor) {
|
||||
return JvmClassName.byInternalName(getJvmInternalFQName(classDescriptor));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Internal name
|
||||
*
|
||||
* @see DescriptorUtils#getFQName(DeclarationDescriptor)
|
||||
*/
|
||||
@NotNull
|
||||
private String getFQName(@NotNull DeclarationDescriptor descriptor) {
|
||||
private String getJvmInternalFQName(@NotNull DeclarationDescriptor descriptor) {
|
||||
descriptor = descriptor.getOriginal();
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
@@ -339,15 +364,15 @@ public class JetTypeMapper {
|
||||
if (klass.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration();
|
||||
if (containingKlass.getKind() == ClassKind.ENUM_CLASS) {
|
||||
return getFQName(containingKlass);
|
||||
return getJvmInternalFQName(containingKlass);
|
||||
}
|
||||
else {
|
||||
return getFQName(containingKlass) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
return getJvmInternalFQName(containingKlass) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (klass.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return getFQName(klass.getContainingDeclaration());
|
||||
return getJvmInternalFQName(klass.getContainingDeclaration());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +390,7 @@ public class JetTypeMapper {
|
||||
return className.getInternalName();
|
||||
}
|
||||
|
||||
String baseName = getFQName(container);
|
||||
String baseName = getJvmInternalFQName(container);
|
||||
if (!baseName.isEmpty()) {
|
||||
return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier();
|
||||
}
|
||||
@@ -385,17 +410,16 @@ public class JetTypeMapper {
|
||||
|
||||
if (mapBuiltinsToJava) {
|
||||
if (classifier instanceof ClassDescriptor) {
|
||||
KnownTypeKey key = new KnownTypeKey(DescriptorUtils.getFQName(classifier), jetType.isNullable());
|
||||
known = knowTypes.get(key);
|
||||
known = specialTypes.get(jetType);
|
||||
}
|
||||
}
|
||||
|
||||
if (known != null) {
|
||||
if (kind == MapTypeMode.VALUE) {
|
||||
return mapKnownAsmType(jetType, known, signatureVisitor, false);
|
||||
return mapKnownAsmType(jetType, known, signatureVisitor);
|
||||
}
|
||||
else if (kind == MapTypeMode.TYPE_PARAMETER) {
|
||||
return mapKnownAsmType(jetType, known, signatureVisitor, true);
|
||||
return mapKnownAsmType(jetType, boxType(known), signatureVisitor);
|
||||
}
|
||||
else if (kind == MapTypeMode.TRAIT_IMPL) {
|
||||
throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType);
|
||||
@@ -428,7 +452,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
Type asmType = Type.getObjectType("error/NonExistentClass");
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, asmType, true);
|
||||
writeSimpleType(signatureVisitor, asmType, true);
|
||||
}
|
||||
checkValidType(asmType);
|
||||
return asmType;
|
||||
@@ -461,7 +485,7 @@ public class JetTypeMapper {
|
||||
|
||||
if (JetStandardClasses.getAny().equals(descriptor)) {
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, TYPE_OBJECT, jetType.isNullable());
|
||||
writeSimpleType(signatureVisitor, TYPE_OBJECT, jetType.isNullable());
|
||||
}
|
||||
checkValidType(TYPE_OBJECT);
|
||||
return TYPE_OBJECT;
|
||||
@@ -469,33 +493,12 @@ public class JetTypeMapper {
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
|
||||
Type asmType;
|
||||
boolean forceReal;
|
||||
|
||||
if (JetStandardLibraryNames.COMPARABLE.is((ClassDescriptor) descriptor) && mapBuiltinsToJava) {
|
||||
if (jetType.getArguments().size() != 1) {
|
||||
throw new UnsupportedOperationException("Comparable must have one type argument");
|
||||
}
|
||||
JvmClassName name = getJvmClassName((ClassDescriptor) descriptor);
|
||||
Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
|
||||
boolean forceReal = isForceReal(name);
|
||||
|
||||
asmType = JL_COMPARABLE_TYPE;
|
||||
forceReal = false;
|
||||
}
|
||||
else {
|
||||
JvmClassName name = getClassFQName((ClassDescriptor) descriptor);
|
||||
asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
|
||||
forceReal = isForceReal(name);
|
||||
}
|
||||
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable(), forceReal);
|
||||
for (TypeProjection proj : jetType.getArguments()) {
|
||||
// TODO: +-
|
||||
signatureVisitor.writeTypeArgument(proj.getProjectionKind());
|
||||
mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER);
|
||||
signatureVisitor.writeTypeArgumentEnd();
|
||||
}
|
||||
signatureVisitor.writeClassEnd();
|
||||
}
|
||||
writeGenericType(jetType, signatureVisitor, asmType, forceReal);
|
||||
|
||||
checkValidType(asmType);
|
||||
return asmType;
|
||||
@@ -515,26 +518,34 @@ public class JetTypeMapper {
|
||||
|
||||
throw new UnsupportedOperationException("Unknown type " + jetType);
|
||||
}
|
||||
|
||||
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) {
|
||||
if (boxPrimitive) {
|
||||
Type boxed = boxType(asmType);
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, boxed, jetType.isNullable());
|
||||
|
||||
private void writeGenericType(JetType jetType, BothSignatureWriter signatureVisitor, Type asmType, boolean forceReal) {
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable(), forceReal);
|
||||
for (TypeProjection proj : jetType.getArguments()) {
|
||||
// TODO: +-
|
||||
signatureVisitor.writeTypeArgument(proj.getProjectionKind());
|
||||
mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER);
|
||||
signatureVisitor.writeTypeArgumentEnd();
|
||||
}
|
||||
checkValidType(boxed);
|
||||
return boxed;
|
||||
}
|
||||
else {
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, asmType, jetType.isNullable());
|
||||
}
|
||||
checkValidType(asmType);
|
||||
return asmType;
|
||||
signatureVisitor.writeClassEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
|
||||
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||
if (signatureVisitor != null) {
|
||||
if (jetType.getArguments().isEmpty()) {
|
||||
writeSimpleType(signatureVisitor, asmType, jetType.isNullable());
|
||||
}
|
||||
else {
|
||||
writeGenericType(jetType, signatureVisitor, asmType, false);
|
||||
}
|
||||
}
|
||||
checkValidType(asmType);
|
||||
return asmType;
|
||||
}
|
||||
|
||||
public static void writeSimpleType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
|
||||
visitor.writeAsmType(asmType, nullable);
|
||||
}
|
||||
|
||||
@@ -1029,30 +1040,6 @@ public class JetTypeMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void registerKnownType(@NotNull ClassName className, @NotNull Type nonNullType, @NotNull Type nullableType) {
|
||||
knowTypes.put(new KnownTypeKey(className.getFqName().toUnsafe(), true), nullableType);
|
||||
knowTypes.put(new KnownTypeKey(className.getFqName().toUnsafe(), false), nonNullType);
|
||||
}
|
||||
|
||||
private void initKnownTypes() {
|
||||
registerKnownType(JetStandardLibraryNames.NOTHING, TYPE_NOTHING, TYPE_NOTHING);
|
||||
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||
registerKnownType(primitiveType.getClassName(), jvmPrimitiveType.getAsmType(), jvmPrimitiveType.getWrapper().getAsmType());
|
||||
}
|
||||
|
||||
registerKnownType(JetStandardLibraryNames.NUMBER, JL_NUMBER_TYPE, JL_NUMBER_TYPE);
|
||||
registerKnownType(JetStandardLibraryNames.STRING, JL_STRING_TYPE, JL_STRING_TYPE);
|
||||
registerKnownType(JetStandardLibraryNames.CHAR_SEQUENCE, JL_CHAR_SEQUENCE_TYPE, JL_CHAR_SEQUENCE_TYPE);
|
||||
registerKnownType(JetStandardLibraryNames.THROWABLE, TYPE_THROWABLE, TYPE_THROWABLE);
|
||||
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||
registerKnownType(primitiveType.getArrayClassName(), jvmPrimitiveType.getAsmArrayType(), jvmPrimitiveType.getAsmArrayType());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isForceReal(JvmClassName className) {
|
||||
return JvmPrimitiveType.getByWrapperClass(className) != null
|
||||
|| className.getFqName().getFqName().equals("java.lang.String")
|
||||
|
||||
Reference in New Issue
Block a user