From 8a5b63a66932c1fa601a7e3c04f189d4a4282731 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 13 Nov 2015 23:25:40 +0300 Subject: [PATCH] Inline PLATFORM_TYPES = true, simplify signature propagation --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 53 --- .../jetbrains/kotlin/codegen/StackValue.java | 4 +- .../TraceBasedExternalSignatureResolver.java | 4 +- .../java/sam/SingleAbstractMethodUtils.java | 3 +- .../PropagationHeuristics.java | 120 ----- .../SignaturesPropagationData.java | 436 +----------------- .../LazyJavaAnnotationDescriptor.kt | 3 +- .../java/lazy/descriptors/LazyJavaScope.kt | 12 +- .../java/lazy/types/LazyJavaTypeResolver.kt | 7 +- .../resolve/jvm/JavaDescriptorResolver.kt | 15 +- .../load/kotlin/reflect/RuntimeModuleData.kt | 2 +- 11 files changed, 31 insertions(+), 628 deletions(-) delete mode 100644 compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/PropagationHeuristics.java diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 156e21bd0d0..916150aa61a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -38,20 +38,17 @@ import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; -import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.DeprecationUtilKt; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.inline.InlineUtil; -import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolverKt; import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.serialization.jvm.BitEncoding; import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor; -import org.jetbrains.kotlin.types.FlexibleTypesKt; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; @@ -643,43 +640,6 @@ public class AsmUtil { } } - public static boolean genNotNullAssertionForField( - @NotNull InstructionAdapter v, - @NotNull GenerationState state, - @NotNull PropertyDescriptor descriptor - ) { - return genNotNullAssertion(v, state, descriptor, "checkFieldIsNotNull"); - } - - private static boolean genNotNullAssertion( - @NotNull InstructionAdapter v, - @NotNull GenerationState state, - @NotNull CallableDescriptor descriptor, - @NotNull String assertMethodToCall - ) { - // Assertions are generated elsewhere for platform types - if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return false; - - if (!state.isCallAssertionsEnabled()) return false; - - if (!isDeclaredInJava(descriptor)) return false; - - KotlinType type = descriptor.getReturnType(); - if (type == null || isNullableType(FlexibleTypesKt.lowerIfFlexible(type))) return false; - - Type asmType = state.getTypeMapper().mapReturnType(descriptor); - if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { - v.dup(); - v.visitLdcInsn(descriptor.getContainingDeclaration().getName().asString()); - v.visitLdcInsn(descriptor.getName().asString()); - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, assertMethodToCall, - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", false); - return true; - } - - return false; - } - @NotNull public static StackValue genNotNullAssertions( @NotNull GenerationState state, @@ -704,19 +664,6 @@ public class AsmUtil { }; } - private static boolean isDeclaredInJava(@NotNull CallableDescriptor callableDescriptor) { - CallableDescriptor descriptor = callableDescriptor; - while (true) { - if (descriptor instanceof JavaCallableMemberDescriptor) { - return true; - } - CallableDescriptor original = descriptor.getOriginal(); - if (descriptor == original) break; - descriptor = original; - } - return false; - } - public static void pushDefaultValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) { if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { v.aconst(null); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 4c069dd18aa..28a4336f167 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -1084,9 +1084,7 @@ public abstract class StackValue { v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor()); - if (!genNotNullAssertionForField(v, state, descriptor)) { - genNotNullAssertionForLateInitIfNeeded(v); - } + genNotNullAssertionForLateInitIfNeeded(v); coerceTo(type, v); } else { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/TraceBasedExternalSignatureResolver.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/TraceBasedExternalSignatureResolver.java index 1fc5646731b..22647cfc901 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/TraceBasedExternalSignatureResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/components/TraceBasedExternalSignatureResolver.java @@ -50,8 +50,8 @@ public class TraceBasedExternalSignatureResolver implements ExternalSignatureRes SignaturesPropagationData data = new SignaturesPropagationData(owner, returnType, receiverType, valueParameters, typeParameters, method); return new AlternativeMethodSignature( - data.getModifiedReturnType(), data.getModifiedReceiverType(), data.getModifiedValueParameters(), - data.getModifiedTypeParameters(), data.getSignatureErrors(), data.getModifiedHasStableParameterNames() + returnType, data.getModifiedReceiverType(), data.getModifiedValueParameters(), + typeParameters, data.getSignatureErrors(), data.getModifiedHasStableParameterNames() ); } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java index 6b805e2496f..36dd357537b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; -import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolverKt; import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils; import org.jetbrains.kotlin.types.*; @@ -104,7 +103,7 @@ public class SingleAbstractMethodUtils { KotlinType type = fixProjections(substitute); if (type == null) return null; - if (JavaDescriptorResolverKt.getPLATFORM_TYPES() && FlexibleTypesKt.isNullabilityFlexible(samType)) { + if (FlexibleTypesKt.isNullabilityFlexible(samType)) { return LazyJavaTypeResolver.FlexibleJavaClassifierTypeCapabilities.create(type, TypeUtils.makeNullable(type)); } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/PropagationHeuristics.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/PropagationHeuristics.java deleted file mode 100644 index 0d8866f8ff0..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/PropagationHeuristics.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.resolve.jvm.kotlinSignature; - -import com.google.common.collect.Lists; -import com.intellij.openapi.util.Condition; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; -import org.jetbrains.kotlin.renderer.DescriptorRenderer; -import org.jetbrains.kotlin.resolve.scopes.MemberScope; -import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.types.KotlinTypeImpl; -import org.jetbrains.kotlin.types.TypeProjectionImpl; -import org.jetbrains.kotlin.types.Variance; -import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; - -import java.util.Arrays; -import java.util.List; - -import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isArray; - -// This class contains heuristics for processing corner cases in propagation -class PropagationHeuristics { - // Checks for case when method returning Super[] is overridden with method returning Sub[] - static void checkArrayInReturnType( - @NotNull SignaturesPropagationData data, - @NotNull KotlinType type, - @NotNull List typesFromSuper - ) { - List arrayTypesFromSuper = ContainerUtil - .filter(typesFromSuper, new Condition() { - @Override - public boolean value(SignaturesPropagationData.TypeAndVariance typeAndVariance) { - return isArray(typeAndVariance.type); - } - }); - if (isArray(type) && !arrayTypesFromSuper.isEmpty()) { - assert type.getArguments().size() == 1; - if (type.getArguments().get(0).getProjectionKind() == Variance.INVARIANT) { - for (SignaturesPropagationData.TypeAndVariance typeAndVariance : arrayTypesFromSuper) { - KotlinType arrayTypeFromSuper = typeAndVariance.type; - assert arrayTypeFromSuper.getArguments().size() == 1; - KotlinType elementTypeInSuper = arrayTypeFromSuper.getArguments().get(0).getType(); - KotlinType elementType = type.getArguments().get(0).getType(); - - if (KotlinTypeChecker.DEFAULT.isSubtypeOf(elementType, elementTypeInSuper) - && !KotlinTypeChecker.DEFAULT.equalTypes(elementType, elementTypeInSuper)) { - KotlinTypeImpl betterTypeInSuper = KotlinTypeImpl.create( - arrayTypeFromSuper.getAnnotations(), - arrayTypeFromSuper.getConstructor(), - arrayTypeFromSuper.isMarkedNullable(), - Arrays.asList(new TypeProjectionImpl(Variance.OUT_VARIANCE, elementTypeInSuper)), - MemberScope.Empty.INSTANCE); - - data.reportError("Return type is not a subtype of overridden method. " + - "To fix it, add annotation with Kotlin signature to super method with type " - + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(arrayTypeFromSuper) + " replaced with " - + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(betterTypeInSuper) + " in return type"); - } - } - } - } - } - - // Weird workaround for weird case. The sample code below is compiled by javac. - // In this case, we try to replace "Any" parameter type with "T" to fix substitution principle. - // - // public interface Super { - // void foo(T t); - // } - // - // public interface Sub extends Super { - // void foo(Object o); - // } - // - // This method is called from SignaturesPropagationData. - @Nullable - static ClassifierDescriptor tryToFixOverridingTWithRawType( - @NotNull SignaturesPropagationData data, - @NotNull List typesFromSuper - ) { - List typeParameterClassifiersFromSuper = Lists.newArrayList(); - for (SignaturesPropagationData.TypeAndVariance typeFromSuper : typesFromSuper) { - ClassifierDescriptor classifierFromSuper = typeFromSuper.type.getConstructor().getDeclarationDescriptor(); - if (classifierFromSuper instanceof TypeParameterDescriptor) { - typeParameterClassifiersFromSuper.add((TypeParameterDescriptor) classifierFromSuper); - } - } - - if (!typeParameterClassifiersFromSuper.isEmpty() && typeParameterClassifiersFromSuper.size() == typesFromSuper.size()) { - for (TypeParameterDescriptor typeParameter : typeParameterClassifiersFromSuper) { - if (typeParameter.getContainingDeclaration() == data.containingClass) { - return typeParameter; - } - } - } - - return null; - } - - private PropagationHeuristics() { - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java index 7d3ba4e211b..ed2ffdac045 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.resolve.jvm.kotlinSignature; import com.google.common.collect.Lists; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import kotlin.CollectionsKt; @@ -28,31 +26,23 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; -import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; -import org.jetbrains.kotlin.load.java.components.TypeUsage; import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor; import org.jetbrains.kotlin.load.java.structure.JavaMethod; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.platform.JavaToKotlinClassMap; -import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; -import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolverKt; -import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapperKt; -import org.jetbrains.kotlin.resolve.scopes.MemberScope; -import org.jetbrains.kotlin.types.*; +import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.TypeUtils; import java.util.*; -import static org.jetbrains.kotlin.load.java.components.TypeUsage.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; -import static org.jetbrains.kotlin.types.Variance.INVARIANT; public class SignaturesPropagationData { @@ -61,16 +51,9 @@ public class SignaturesPropagationData { KotlinToJvmSignatureMapper.class.getClassLoader() ).iterator().next(); - private final JavaMethodDescriptor autoMethodDescriptor; - - private final List modifiedTypeParameters; private final ValueParameters modifiedValueParameters; - - private final KotlinType modifiedReturnType; - private final List signatureErrors = Lists.newArrayList(); + private final List signatureErrors = new ArrayList(0); private final List superFunctions; - private final Map autoTypeParameterToModified; - final ClassDescriptor containingClass; public SignaturesPropagationData( @NotNull ClassDescriptor containingClass, @@ -80,25 +63,21 @@ public class SignaturesPropagationData { @NotNull List autoTypeParameters, // descriptors built by signature resolver @NotNull JavaMethod method ) { - this.containingClass = containingClass; + assert receiverType == null : "Parameters before propagation have receiver type," + + " but propagation should be disabled for functions compiled from Kotlin in class: " + + DescriptorUtils.getFqName(containingClass); - autoMethodDescriptor = - createAutoMethodDescriptor(containingClass, method, autoReturnType, receiverType, autoValueParameters, autoTypeParameters); + JavaMethodDescriptor autoMethodDescriptor = + createAutoMethodDescriptor(containingClass, method, autoReturnType, autoValueParameters, autoTypeParameters); superFunctions = getSuperFunctionsForMethod(method, autoMethodDescriptor, containingClass); - - autoTypeParameterToModified = JavaResolverUtils.recreateTypeParametersAndReturnMapping(autoTypeParameters, null); - - modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters); - modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType); - modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(receiverType, autoValueParameters); + modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(autoValueParameters); } @NotNull private static JavaMethodDescriptor createAutoMethodDescriptor( @NotNull ClassDescriptor containingClass, @NotNull JavaMethod method, KotlinType autoReturnType, - @Nullable KotlinType receiverType, @NotNull List autoValueParameters, @NotNull List autoTypeParameters ) { @@ -110,7 +89,7 @@ public class SignaturesPropagationData { SourceElement.NO_SOURCE ); autoMethodDescriptor.initialize( - receiverType, + /* receiverParameterType = */ null, containingClass.getThisAsReceiverParameter(), autoTypeParameters, autoValueParameters, @@ -121,10 +100,6 @@ public class SignaturesPropagationData { return autoMethodDescriptor; } - public List getModifiedTypeParameters() { - return modifiedTypeParameters; - } - public KotlinType getModifiedReceiverType() { return modifiedValueParameters.receiverType; } @@ -137,84 +112,15 @@ public class SignaturesPropagationData { return modifiedValueParameters.hasStableParameterNames; } - public KotlinType getModifiedReturnType() { - return modifiedReturnType; - } - public List getSignatureErrors() { return signatureErrors; } - public List getSuperFunctions() { - return superFunctions; - } - void reportError(String error) { signatureErrors.add(error); } - private KotlinType modifyReturnTypeAccordingToSuperMethods( - @NotNull KotlinType autoType // type built by JavaTypeTransformer - ) { - if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType; - - List typesFromSuperMethods = ContainerUtil.map(superFunctions, - new Function() { - @Override - public TypeAndVariance fun(FunctionDescriptor superFunction) { - return new TypeAndVariance(superFunction.getReturnType(), - Variance.OUT_VARIANCE); - } - }); - - return modifyTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, MEMBER_SIGNATURE_COVARIANT); - } - - private List modifyTypeParametersAccordingToSuperMethods(List autoTypeParameters) { - if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoTypeParameters; - - List result = Lists.newArrayList(); - - for (TypeParameterDescriptor autoParameter : autoTypeParameters) { - int index = autoParameter.getIndex(); - TypeParameterDescriptorImpl modifiedTypeParameter = autoTypeParameterToModified.get(autoParameter); - - List> upperBoundFromSuperFunctionsIterators = Lists.newArrayList(); - for (FunctionDescriptor superFunction : superFunctions) { - upperBoundFromSuperFunctionsIterators.add(superFunction.getTypeParameters().get(index).getUpperBounds().iterator()); - } - - for (KotlinType autoUpperBound : autoParameter.getUpperBounds()) { - List upperBoundsFromSuperFunctions = Lists.newArrayList(); - - for (Iterator iterator : upperBoundFromSuperFunctionsIterators) { - assert iterator.hasNext(); - upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), INVARIANT)); - } - - KotlinType modifiedUpperBound = modifyTypeAccordingToSuperMethods(autoUpperBound, upperBoundsFromSuperFunctions, UPPER_BOUND); - modifiedTypeParameter.addUpperBound(modifiedUpperBound); - } - - for (Iterator iterator : upperBoundFromSuperFunctionsIterators) { - assert !iterator.hasNext(); - } - - modifiedTypeParameter.setInitialized(); - result.add(modifiedTypeParameter); - } - - return result; - } - - private ValueParameters modifyValueParametersAccordingToSuperMethods( - @Nullable KotlinType receiverType, - @NotNull List parameters // descriptors built by parameters resolver - ) { - assert receiverType == null : "Parameters before propagation have receiver type," + - " but propagation should be disabled for functions compiled from Kotlin in class: " + - DescriptorUtils.getFqName(containingClass); - + private ValueParameters modifyValueParametersAccordingToSuperMethods(@NotNull List parameters) { KotlinType resultReceiverType = null; List resultParameters = new ArrayList(parameters.size()); @@ -239,9 +145,7 @@ public class SignaturesPropagationData { VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam); - KotlinType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, - convertToTypeVarianceList(typesFromSuperMethods), - MEMBER_SIGNATURE_CONTRAVARIANT); + KotlinType altType = varargCheckResult.parameterType; if (shouldBeExtension && originalIndex == 0) { resultReceiverType = altType; @@ -284,16 +188,6 @@ public class SignaturesPropagationData { return new ValueParameters(resultReceiverType, resultParameters, hasStableParameterNames); } - @NotNull - private static List convertToTypeVarianceList(@NotNull List list) { - return CollectionsKt.map(list, new Function1() { - @Override - public TypeAndVariance invoke(TypeAndName tvn) { - return new TypeAndVariance(tvn.type, INVARIANT); - } - }); - } - private static List getSuperFunctionsForMethod( @NotNull JavaMethod method, @NotNull JavaMethodDescriptor autoMethodDescriptor, @@ -388,284 +282,6 @@ public class SignaturesPropagationData { return new VarargCheckResult(originalType, originalVarargElementType != null); } - @NotNull - private KotlinType modifyTypeAccordingToSuperMethods( - @NotNull KotlinType autoType, - @NotNull List typesFromSuper, - @NotNull TypeUsage howThisTypeIsUsed - ) { - if (autoType.isError()) return autoType; - - if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType; - - boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed); - ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper); - List resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper); - MemberScope resultScope; - if (resultClassifier instanceof ClassDescriptor) { - resultScope = ((ClassDescriptor) resultClassifier).getMemberScope(resultArguments); - } - else { - resultScope = autoType.getMemberScope(); - } - - KotlinType type = KotlinTypeImpl.create(autoType.getAnnotations(), - resultClassifier.getTypeConstructor(), - resultNullable, - resultArguments, - resultScope); - - PropagationHeuristics.checkArrayInReturnType(this, type, typesFromSuper); - return type; - } - - @NotNull - private List getTypeArgsOfType( - @NotNull KotlinType autoType, - @NotNull ClassifierDescriptor classifier, - @NotNull List typesFromSuper - ) { - if (typesFromSuper.isEmpty()) return autoType.getArguments(); - - List autoArguments = autoType.getArguments(); - - if (!(classifier instanceof ClassDescriptor)) { - assert autoArguments.isEmpty() : - "Unexpected type arguments when type constructor is not ClassDescriptor, type = " + autoType + - ", classifier = " + classifier + ", classifier class = " + classifier.getClass(); - return autoArguments; - } - - List> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper((ClassDescriptor) classifier, - typesFromSuper); - - // Modify type arguments using info from typesFromSuper - List resultArguments = Lists.newArrayList(); - for (TypeParameterDescriptor parameter : classifier.getTypeConstructor().getParameters()) { - TypeProjection argument = autoArguments.get(parameter.getIndex()); - - KotlinType argumentType = argument.getType(); - List projectionsFromSuper = typeArgumentsFromSuper.get(parameter.getIndex()); - List argTypesFromSuper = getTypes(projectionsFromSuper); - - KotlinType type = modifyTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, TYPE_ARGUMENT); - Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper); - - resultArguments.add(new TypeProjectionImpl(projectionKind, type)); - } - return resultArguments; - } - - private Variance calculateArgumentProjectionKindFromSuper( - @NotNull TypeProjection argument, - @NotNull List projectionsFromSuper - ) { - if (projectionsFromSuper.isEmpty()) return argument.getProjectionKind(); - - Set projectionKindsInSuper = Sets.newLinkedHashSet(); - for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) { - projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind()); - } - - Variance defaultProjectionKind = argument.getProjectionKind(); - if (projectionKindsInSuper.size() == 0) { - return defaultProjectionKind; - } - else if (projectionKindsInSuper.size() == 1) { - Variance projectionKindInSuper = projectionKindsInSuper.iterator().next(); - if (defaultProjectionKind == INVARIANT || defaultProjectionKind == projectionKindInSuper) { - return projectionKindInSuper; - } - else { - reportError("Incompatible projection kinds in type arguments of super methods' return types: " - + projectionsFromSuper + ", defined in current: " + argument); - return defaultProjectionKind; - } - } - else { - reportError("Incompatible projection kinds in type arguments of super methods' return types: " + projectionsFromSuper); - return defaultProjectionKind; - } - } - - @NotNull - private static List getTypes(@NotNull List projections) { - List types = Lists.newArrayList(); - for (TypeProjectionAndVariance projection : projections) { - types.add(new TypeAndVariance(projection.typeProjection.getType(), - merge(projection.varianceOfPosition, projection.typeProjection.getProjectionKind()))); - } - return types; - } - - private static Variance merge(Variance positionOfOuter, Variance projectionKind) { - // Inv>, X is in invariant position - if (positionOfOuter == INVARIANT) return INVARIANT; - // Out, X is in out-position - if (projectionKind == INVARIANT) return positionOfOuter; - // Out>, X is in out-position - // In>, X is in out-position - // Out>, X is in in-position - // In>, X is in in-position - return positionOfOuter.superpose(projectionKind); - } - - // Returns list with type arguments info from supertypes - // Example: - // - Foo is a subtype of Bar>, Baz - // - input: klass = Foo, typesFromSuper = [Bar>, Baz] - // - output[0] = [String, CharSequence], output[1] = [] - private static List> calculateTypeArgumentsFromSuper( - @NotNull ClassDescriptor klass, - @NotNull Collection typesFromSuper - ) { - // For each superclass of klass and its parameters, hold their mapping to klass' parameters - // #0 of Bar -> A - // #1 of Bar -> List - // #0 of Baz -> Boolean - // #1 of Baz -> A - // #0 of Foo -> A (mapped to itself) - // #1 of Foo -> B (mapped to itself) - Multimap substitution = SubstitutionUtils.buildDeepSubstitutionMultimap( - TypeUtils.makeUnsubstitutedType(klass, ErrorUtils.createErrorScope("Do not access this scope", true))); - - // for each parameter of klass, hold arguments in corresponding supertypes - List> parameterToArgumentsFromSuper = Lists.newArrayList(); - for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) { - parameterToArgumentsFromSuper.add(new ArrayList()); - } - - // Enumerate all types from super and all its parameters - for (TypeAndVariance typeFromSuper : typesFromSuper) { - for (TypeParameterDescriptor parameter : typeFromSuper.type.getConstructor().getParameters()) { - TypeProjection argument = typeFromSuper.type.getArguments().get(parameter.getIndex()); - - // for given example, this block is executed four times: - // 1. typeFromSuper = Bar>, parameter = "#0 of Bar", argument = String - // 2. typeFromSuper = Bar>, parameter = "#1 of Bar", argument = List - // 3. typeFromSuper = Baz, parameter = "#0 of Baz", argument = Boolean - // 4. typeFromSuper = Baz, parameter = "#1 of Baz", argument = CharSequence - - // if it is mapped to klass' parameter, then store it into map - for (TypeProjection projection : substitution.get(parameter)) { - // 1. projection = A - // 2. projection = List - // 3. projection = Boolean - // 4. projection = A - ClassifierDescriptor classifier = projection.getType().getConstructor().getDeclarationDescriptor(); - - // this condition is true for 1 and 4, false for 2 and 3 - if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) { - int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex(); - Variance effectiveVariance = parameter.getVariance().superpose(typeFromSuper.varianceOfPosition); - parameterToArgumentsFromSuper.get(parameterIndex).add(new TypeProjectionAndVariance(argument, effectiveVariance)); - } - } - } - } - return parameterToArgumentsFromSuper; - } - - private boolean typeMustBeNullable( - @NotNull KotlinType autoType, - @NotNull List typesFromSuper, - @NotNull TypeUsage howThisTypeIsUsed - ) { - boolean someSupersNotCovariantNullable = false; - boolean someSupersCovariantNullable = false; - boolean someSupersNotNull = false; - for (TypeAndVariance typeFromSuper : typesFromSuper) { - if (!TypeUtils.isNullableType(typeFromSuper.type)) { - someSupersNotNull = true; - } - else { - if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) { - someSupersCovariantNullable = true; - } - else { - someSupersNotCovariantNullable = true; - } - } - } - - if (someSupersNotNull && someSupersNotCovariantNullable) { - reportError("Incompatible types in superclasses: " + typesFromSuper); - return TypeUtils.isNullableType(autoType); - } - else if (someSupersNotNull) { - return false; - } - else if (someSupersNotCovariantNullable || someSupersCovariantNullable) { - boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !TypeUtils.isNullableType(autoType); - - if (annotatedAsNotNull && someSupersNotCovariantNullable) { - DescriptorRenderer renderer = DescriptorRenderer.SHORT_NAMES_IN_TYPES; - reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + renderer.renderType(autoType)); - return true; - } - - return !annotatedAsNotNull; - } - return TypeUtils.isNullableType(autoType); - } - - @NotNull - private ClassifierDescriptor modifyTypeClassifier( - @NotNull KotlinType autoType, - @NotNull List typesFromSuper - ) { - ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor(); - if (!(classifier instanceof ClassDescriptor)) { - assert classifier != null : "no declaration descriptor for type " + autoType + ", auto method descriptor: " + autoMethodDescriptor; - - if (classifier instanceof TypeParameterDescriptor && autoTypeParameterToModified.containsKey(classifier)) { - return autoTypeParameterToModified.get(classifier); - } - return classifier; - } - ClassDescriptor klass = (ClassDescriptor) classifier; - - boolean someSupersMutable = false; - boolean someSupersCovariantReadOnly = false; - boolean someSupersNotCovariantReadOnly = false; - for (TypeAndVariance typeFromSuper : typesFromSuper) { - ClassifierDescriptor classifierFromSuper = typeFromSuper.type.getConstructor().getDeclarationDescriptor(); - if (classifierFromSuper instanceof ClassDescriptor) { - ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper; - - if (JavaToKotlinClassMap.INSTANCE.isMutable(classFromSuper)) { - someSupersMutable = true; - } - else if (JavaToKotlinClassMap.INSTANCE.isReadOnly(classFromSuper)) { - if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) { - someSupersCovariantReadOnly = true; - } - else { - someSupersNotCovariantReadOnly = true; - } - } - } - } - - if (someSupersMutable && someSupersNotCovariantReadOnly) { - reportError("Incompatible types in superclasses: " + typesFromSuper); - return classifier; - } - else if (someSupersMutable) { - if (JavaToKotlinClassMap.INSTANCE.isReadOnly(klass)) { - return JavaToKotlinClassMap.INSTANCE.convertReadOnlyToMutable(klass); - } - } - else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) { - if (JavaToKotlinClassMap.INSTANCE.isMutable(klass)) { - return JavaToKotlinClassMap.INSTANCE.convertMutableToReadOnly(klass); - } - } - - ClassifierDescriptor fixed = PropagationHeuristics.tryToFixOverridingTWithRawType(this, typesFromSuper); - return fixed != null ? fixed : classifier; - } - private static boolean isArrayType(@NotNull KotlinType type) { return KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type); } @@ -680,34 +296,6 @@ public class SignaturesPropagationData { } } - private static class TypeProjectionAndVariance { - public final TypeProjection typeProjection; - public final Variance varianceOfPosition; - - public TypeProjectionAndVariance(TypeProjection typeProjection, Variance varianceOfPosition) { - this.typeProjection = typeProjection; - this.varianceOfPosition = varianceOfPosition; - } - - public String toString() { - return typeProjection.toString(); - } - } - - static class TypeAndVariance { - public final KotlinType type; - public final Variance varianceOfPosition; - - public TypeAndVariance(KotlinType type, Variance varianceOfPosition) { - this.type = type; - this.varianceOfPosition = varianceOfPosition; - } - - public String toString() { - return type.toString(); - } - } - private static class TypeAndName { public final KotlinType type; public final Name name; diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index 11719459b18..d86bc6b9abc 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -34,14 +34,13 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass -import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.utils.keysToMapExceptNulls import org.jetbrains.kotlin.utils.valuesToMap fun LazyJavaResolverContext.resolveAnnotation(annotation: JavaAnnotation): LazyJavaAnnotationDescriptor? { val classId = annotation.getClassId() - if (classId == null || isSpecialAnnotation(classId, !PLATFORM_TYPES)) return null + if (classId == null || isSpecialAnnotation(classId, false)) return null return LazyJavaAnnotationDescriptor(this, annotation) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index d0b6d879a3f..d0071104eea 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.load.java.structure.JavaValueParameter import org.jetbrains.kotlin.load.java.typeEnhacement.enhanceSignatures import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -278,15 +277,14 @@ public abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : get() = isFinal && isStatic private fun getPropertyType(field: JavaField, annotations: Annotations): KotlinType { - // Fields do not have their own generic parameters - val finalStatic = field.isFinalStatic - // simple static constants should not have flexible types: - val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) + // Fields do not have their own generic parameters. + // Simple static constants should not have flexible types. + val allowFlexible = !(field.isFinalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) val propertyType = c.typeResolver.transformJavaType( - field.getType(), + field.type, LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible) ) - if ((!allowFlexible || !PLATFORM_TYPES) && finalStatic) { + if (!allowFlexible) { return TypeUtils.makeNotNullable(propertyType) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index def8c1e84bc..34ad0640333 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -32,7 +32,6 @@ import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.* import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.JavaToKotlinClassMap -import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.Variance.* import org.jetbrains.kotlin.types.typeUtil.createProjection @@ -54,7 +53,7 @@ class LazyJavaTypeResolver( else c.module.builtIns.getUnitType() } is JavaClassifierType -> - if (PLATFORM_TYPES && attr.allowFlexible && attr.howThisTypeIsUsed != SUPERTYPE) + if (attr.allowFlexible && attr.howThisTypeIsUsed != SUPERTYPE) FlexibleJavaClassifierTypeCapabilities.create( LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_LOWER_BOUND)), LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_UPPER_BOUND)) @@ -71,7 +70,7 @@ class LazyJavaTypeResolver( val primitiveType = (javaComponentType as? JavaPrimitiveType)?.getType() if (primitiveType != null) { val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType) - return@run if (PLATFORM_TYPES && attr.allowFlexible) + return@run if (attr.allowFlexible) FlexibleJavaClassifierTypeCapabilities.create(jetType, TypeUtils.makeNullable(jetType)) else TypeUtils.makeNullableAsSpecified(jetType, !attr.isMarkedNotNull) } @@ -79,7 +78,7 @@ class LazyJavaTypeResolver( val componentType = transformJavaType(javaComponentType, TYPE_ARGUMENT.toAttributes(attr.allowFlexible, attr.isForAnnotationParameter)) - if (PLATFORM_TYPES && attr.allowFlexible) { + if (attr.allowFlexible) { return@run FlexibleJavaClassifierTypeCapabilities.create( c.module.builtIns.getArrayType(INVARIANT, componentType), TypeUtils.makeNullable(c.module.builtIns.getArrayType(OUT_VARIANCE, componentType))) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt index 0c2051076aa..d35bc8baeb5 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/resolve/jvm/JavaDescriptorResolver.kt @@ -16,17 +16,12 @@ package org.jetbrains.kotlin.resolve.jvm -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.load.java.sources.JavaSourceElement +import org.jetbrains.kotlin.load.java.structure.JavaClass -public var PLATFORM_TYPES: Boolean = true - -public class JavaDescriptorResolver(public val packageFragmentProvider: LazyJavaPackageFragmentProvider, private val module: ModuleDescriptor) { - - public fun resolveClass(javaClass: JavaClass): ClassDescriptor? { +class JavaDescriptorResolver(val packageFragmentProvider: LazyJavaPackageFragmentProvider) { + fun resolveClass(javaClass: JavaClass): ClassDescriptor? { return packageFragmentProvider.getClass(javaClass) } -} \ No newline at end of file +} diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt index 8fc1657b90a..9ccdcb4b89f 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt @@ -64,7 +64,7 @@ public class RuntimeModuleData private constructor(public val deserialization: D val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext, module, ReflectionTypes(module)) - val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module) + val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(module, storageManager, reflectKotlinClassFinder, RuntimeErrorReporter) val deserializationComponentsForJava = DeserializationComponentsForJava(