Moved all code relevant to signatures propagation to separate class.
#KT-2776 in progress
This commit is contained in:
+253
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.jet.lang.resolve.java.kotlinSignature;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.HierarchicalMethodSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.java.MutableReadOnlyCollectionsMap;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SignaturesPropagation {
|
||||
public static JetType modifyReturnTypeAccordingToSuperMethods(
|
||||
@NotNull JetType autoType,
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
Set<JetType> typesFromSuperMethods = Sets.newHashSet();
|
||||
for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||
DeclarationDescriptor superFun = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, superSignature.getMethod());
|
||||
if (superFun instanceof FunctionDescriptor) {
|
||||
typesFromSuperMethods.add(((FunctionDescriptor) superFun).getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetType modifyReturnTypeAccordingToSuperMethods(
|
||||
@NotNull JetType autoType,
|
||||
@NotNull Collection<JetType> typesFromSuper,
|
||||
boolean covariantPosition
|
||||
) {
|
||||
if (ErrorUtils.isErrorType(autoType)) {
|
||||
return autoType;
|
||||
}
|
||||
|
||||
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition);
|
||||
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper);
|
||||
JetScope resultScope;
|
||||
ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper);
|
||||
if (classifierDescriptor instanceof ClassDescriptor) {
|
||||
resultScope = ((ClassDescriptor) classifierDescriptor).getMemberScope(resultArguments);
|
||||
}
|
||||
else {
|
||||
resultScope = autoType.getMemberScope();
|
||||
}
|
||||
|
||||
return new JetTypeImpl(autoType.getAnnotations(),
|
||||
classifierDescriptor.getTypeConstructor(),
|
||||
resultNullable,
|
||||
resultArguments,
|
||||
resultScope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<TypeProjection> getTypeArgsOfReturnType(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
|
||||
TypeConstructor typeConstructor = autoType.getConstructor();
|
||||
List<TypeProjection> autoArguments = autoType.getArguments();
|
||||
|
||||
if (!(typeConstructor.getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||
return autoArguments;
|
||||
}
|
||||
|
||||
List<List<TypeProjection>> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper(autoType, typesFromSuper);
|
||||
|
||||
// Modify type arguments using info from typesFromSuper
|
||||
List<TypeProjection> resultArguments = Lists.newArrayList();
|
||||
for (int i = 0; i < autoArguments.size(); i++) {
|
||||
TypeProjection argument = autoArguments.get(i);
|
||||
|
||||
TypeCheckingProcedure.EnrichedProjectionKind effectiveProjectionKind =
|
||||
TypeCheckingProcedure.getEffectiveProjectionKind(typeConstructor.getParameters().get(i), argument);
|
||||
|
||||
JetType argumentType = argument.getType();
|
||||
List<TypeProjection> projectionsFromSuper = typeArgumentsFromSuper.get(i);
|
||||
Collection<JetType> argTypesFromSuper = getTypes(projectionsFromSuper);
|
||||
boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT;
|
||||
|
||||
JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition);
|
||||
Variance variance = calculateArgumentVarianceFromSuper(argument, projectionsFromSuper);
|
||||
|
||||
resultArguments.add(new TypeProjection(variance, type));
|
||||
}
|
||||
return resultArguments;
|
||||
}
|
||||
|
||||
private static Variance calculateArgumentVarianceFromSuper(TypeProjection argument, List<TypeProjection> projectionsFromSuper) {
|
||||
Set<Variance> variancesInSuper = Sets.newHashSet();
|
||||
for (TypeProjection projection : projectionsFromSuper) {
|
||||
variancesInSuper.add(projection.getProjectionKind());
|
||||
}
|
||||
|
||||
Variance defaultVariance = argument.getProjectionKind();
|
||||
if (variancesInSuper.size() == 0) {
|
||||
return defaultVariance;
|
||||
}
|
||||
else if (variancesInSuper.size() == 1) {
|
||||
Variance varianceInSuper = variancesInSuper.iterator().next();
|
||||
if (defaultVariance == Variance.INVARIANT || defaultVariance == varianceInSuper) {
|
||||
return varianceInSuper;
|
||||
}
|
||||
else {
|
||||
// TODO report error
|
||||
return defaultVariance;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO report error
|
||||
return defaultVariance;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<JetType> getTypes(@NotNull List<TypeProjection> projections) {
|
||||
List<JetType> types = Lists.newArrayList();
|
||||
for (TypeProjection projection : projections) {
|
||||
types.add(projection.getType());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
// Returns list with type arguments info from supertypes
|
||||
private static List<List<TypeProjection>> calculateTypeArgumentsFromSuper(
|
||||
@NotNull JetType autoType,
|
||||
@NotNull Collection<JetType> typesFromSuper
|
||||
) {
|
||||
ClassDescriptor klass = (ClassDescriptor) autoType.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
// For each superclass of autoType's class and its parameters, hold their mapping to autoType's parameters
|
||||
Multimap<TypeConstructor,TypeProjection> substitution = SubstitutionUtils.buildDeepSubstitutionMultimap(
|
||||
TypeUtils.makeUnsubstitutedType(klass, null));
|
||||
|
||||
// for each parameter of autoType, hold arguments in corresponding supertypes
|
||||
List<List<TypeProjection>> parameterToArgTypesFromSuper = Lists.newArrayList();
|
||||
for (TypeProjection ignored : autoType.getArguments()) {
|
||||
parameterToArgTypesFromSuper.add(new ArrayList<TypeProjection>());
|
||||
}
|
||||
|
||||
// Enumerate all types from super and all its parameters
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
List<TypeParameterDescriptor> typeFromSuperParameters = typeFromSuper.getConstructor().getParameters();
|
||||
for (int i = 0; i < typeFromSuperParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeFromSuperParam = typeFromSuperParameters.get(i);
|
||||
TypeProjection typeFromSuperArgType = typeFromSuper.getArguments().get(i);
|
||||
|
||||
// if it is mapped to autoType's parameter, then store it into map
|
||||
for (TypeProjection projection : substitution.get(typeFromSuperParam.getTypeConstructor())) {
|
||||
ClassifierDescriptor classifier = projection.getType().getConstructor().getDeclarationDescriptor();
|
||||
|
||||
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
|
||||
parameterToArgTypesFromSuper.get(((TypeParameterDescriptor) classifier).getIndex()).add(typeFromSuperArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parameterToArgTypesFromSuper;
|
||||
}
|
||||
|
||||
private static boolean returnTypeMustBeNullable(JetType autoType, Collection<JetType> typesFromSuper, boolean covariantPosition) {
|
||||
boolean someSupersNullable = false;
|
||||
boolean someSupersNotNull = false;
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
if (typeFromSuper.isNullable()) {
|
||||
someSupersNullable = true;
|
||||
}
|
||||
else {
|
||||
someSupersNotNull = true;
|
||||
}
|
||||
}
|
||||
if (someSupersNotNull && someSupersNullable) {
|
||||
//noinspection IfStatementWithIdenticalBranches
|
||||
if (covariantPosition) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// TODO error!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!someSupersNotNull && !someSupersNullable) { // no types from super
|
||||
return autoType.isNullable();
|
||||
}
|
||||
|
||||
return someSupersNullable && autoType.isNullable();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassifierDescriptor getReturnTypeClassifier(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
|
||||
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
|
||||
if (!(classifier instanceof ClassDescriptor)) {
|
||||
return classifier;
|
||||
}
|
||||
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
||||
|
||||
MutableReadOnlyCollectionsMap collectionsMap = MutableReadOnlyCollectionsMap.getInstance();
|
||||
|
||||
if (collectionsMap.isMutableCollection(clazz)) {
|
||||
|
||||
boolean someSupersMutable = false;
|
||||
boolean someSupersReadOnly = false;
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
ClassifierDescriptor classifierFromSuper = typeFromSuper.getConstructor().getDeclarationDescriptor();
|
||||
if (classifierFromSuper instanceof ClassDescriptor) {
|
||||
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
|
||||
|
||||
if (collectionsMap.isMutableCollection(classFromSuper)) {
|
||||
someSupersMutable = true;
|
||||
}
|
||||
else if (collectionsMap.isReadOnlyCollection(classFromSuper)) {
|
||||
someSupersReadOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (someSupersReadOnly && !someSupersMutable) {
|
||||
return collectionsMap.convertMutableToReadOnly(clazz);
|
||||
}
|
||||
}
|
||||
return classifier;
|
||||
}
|
||||
|
||||
private SignaturesPropagation() {
|
||||
}
|
||||
}
|
||||
+8
-211
@@ -17,9 +17,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.HierarchicalMethodSignature;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
@@ -29,20 +27,23 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
|
||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagation;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.provider.DeclarationOrigin.JAVA;
|
||||
import static org.jetbrains.jet.lang.resolve.java.provider.DeclarationOrigin.KOTLIN;
|
||||
@@ -135,15 +136,7 @@ public final class JavaFunctionResolver {
|
||||
.resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
|
||||
JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver);
|
||||
|
||||
Set<JetType> typesFromSuperMethods = Sets.newHashSet();
|
||||
for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||
DeclarationDescriptor superFun = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, superSignature.getMethod());
|
||||
if (superFun instanceof FunctionDescriptor) {
|
||||
typesFromSuperMethods.add(((FunctionDescriptor) superFun).getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
returnType = modifyReturnTypeAccordingToSuperMethods(returnType, typesFromSuperMethods, true);
|
||||
returnType = SignaturesPropagation.modifyReturnTypeAccordingToSuperMethods(returnType, method, trace);
|
||||
|
||||
// TODO consider better place for this check
|
||||
AlternativeMethodSignatureData alternativeMethodSignatureData =
|
||||
@@ -291,202 +284,6 @@ public final class JavaFunctionResolver {
|
||||
return r;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetType modifyReturnTypeAccordingToSuperMethods(
|
||||
@NotNull JetType autoType,
|
||||
@NotNull Collection<JetType> typesFromSuper,
|
||||
boolean covariantPosition
|
||||
) {
|
||||
if (ErrorUtils.isErrorType(autoType)) {
|
||||
return autoType;
|
||||
}
|
||||
|
||||
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition);
|
||||
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper);
|
||||
JetScope resultScope;
|
||||
ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper);
|
||||
if (classifierDescriptor instanceof ClassDescriptor) {
|
||||
resultScope = ((ClassDescriptor) classifierDescriptor).getMemberScope(resultArguments);
|
||||
}
|
||||
else {
|
||||
resultScope = autoType.getMemberScope();
|
||||
}
|
||||
|
||||
return new JetTypeImpl(autoType.getAnnotations(),
|
||||
classifierDescriptor.getTypeConstructor(),
|
||||
resultNullable,
|
||||
resultArguments,
|
||||
resultScope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<TypeProjection> getTypeArgsOfReturnType(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
|
||||
TypeConstructor typeConstructor = autoType.getConstructor();
|
||||
List<TypeProjection> autoArguments = autoType.getArguments();
|
||||
|
||||
if (!(typeConstructor.getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||
return autoArguments;
|
||||
}
|
||||
|
||||
List<List<TypeProjection>> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper(autoType, typesFromSuper);
|
||||
|
||||
// Modify type arguments using info from typesFromSuper
|
||||
List<TypeProjection> resultArguments = Lists.newArrayList();
|
||||
for (int i = 0; i < autoArguments.size(); i++) {
|
||||
TypeProjection argument = autoArguments.get(i);
|
||||
|
||||
TypeCheckingProcedure.EnrichedProjectionKind effectiveProjectionKind =
|
||||
TypeCheckingProcedure.getEffectiveProjectionKind(typeConstructor.getParameters().get(i), argument);
|
||||
|
||||
JetType argumentType = argument.getType();
|
||||
List<TypeProjection> projectionsFromSuper = typeArgumentsFromSuper.get(i);
|
||||
Collection<JetType> argTypesFromSuper = getTypes(projectionsFromSuper);
|
||||
boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT;
|
||||
|
||||
JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition);
|
||||
Variance variance = calculateArgumentVarianceFromSuper(argument, projectionsFromSuper);
|
||||
|
||||
resultArguments.add(new TypeProjection(variance, type));
|
||||
}
|
||||
return resultArguments;
|
||||
}
|
||||
|
||||
private static Variance calculateArgumentVarianceFromSuper(TypeProjection argument, List<TypeProjection> projectionsFromSuper) {
|
||||
Set<Variance> variancesInSuper = Sets.newHashSet();
|
||||
for (TypeProjection projection : projectionsFromSuper) {
|
||||
variancesInSuper.add(projection.getProjectionKind());
|
||||
}
|
||||
|
||||
Variance defaultVariance = argument.getProjectionKind();
|
||||
if (variancesInSuper.size() == 0) {
|
||||
return defaultVariance;
|
||||
}
|
||||
else if (variancesInSuper.size() == 1) {
|
||||
Variance varianceInSuper = variancesInSuper.iterator().next();
|
||||
if (defaultVariance == Variance.INVARIANT || defaultVariance == varianceInSuper) {
|
||||
return varianceInSuper;
|
||||
}
|
||||
else {
|
||||
// TODO report error
|
||||
return defaultVariance;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO report error
|
||||
return defaultVariance;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<JetType> getTypes(@NotNull List<TypeProjection> projections) {
|
||||
List<JetType> types = Lists.newArrayList();
|
||||
for (TypeProjection projection : projections) {
|
||||
types.add(projection.getType());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
// Returns list with type arguments info from supertypes
|
||||
private static List<List<TypeProjection>> calculateTypeArgumentsFromSuper(
|
||||
@NotNull JetType autoType,
|
||||
@NotNull Collection<JetType> typesFromSuper
|
||||
) {
|
||||
ClassDescriptor klass = (ClassDescriptor) autoType.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
// For each superclass of autoType's class and its parameters, hold their mapping to autoType's parameters
|
||||
Multimap<TypeConstructor,TypeProjection> substitution = SubstitutionUtils.buildDeepSubstitutionMultimap(
|
||||
TypeUtils.makeUnsubstitutedType(klass, null));
|
||||
|
||||
// for each parameter of autoType, hold arguments in corresponding supertypes
|
||||
List<List<TypeProjection>> parameterToArgTypesFromSuper = Lists.newArrayList();
|
||||
for (TypeProjection ignored : autoType.getArguments()) {
|
||||
parameterToArgTypesFromSuper.add(new ArrayList<TypeProjection>());
|
||||
}
|
||||
|
||||
// Enumerate all types from super and all its parameters
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
List<TypeParameterDescriptor> typeFromSuperParameters = typeFromSuper.getConstructor().getParameters();
|
||||
for (int i = 0; i < typeFromSuperParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeFromSuperParam = typeFromSuperParameters.get(i);
|
||||
TypeProjection typeFromSuperArgType = typeFromSuper.getArguments().get(i);
|
||||
|
||||
// if it is mapped to autoType's parameter, then store it into map
|
||||
for (TypeProjection projection : substitution.get(typeFromSuperParam.getTypeConstructor())) {
|
||||
ClassifierDescriptor classifier = projection.getType().getConstructor().getDeclarationDescriptor();
|
||||
|
||||
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
|
||||
parameterToArgTypesFromSuper.get(((TypeParameterDescriptor) classifier).getIndex()).add(typeFromSuperArgType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parameterToArgTypesFromSuper;
|
||||
}
|
||||
|
||||
private static boolean returnTypeMustBeNullable(JetType autoType, Collection<JetType> typesFromSuper, boolean covariantPosition) {
|
||||
boolean someSupersNullable = false;
|
||||
boolean someSupersNotNull = false;
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
if (typeFromSuper.isNullable()) {
|
||||
someSupersNullable = true;
|
||||
}
|
||||
else {
|
||||
someSupersNotNull = true;
|
||||
}
|
||||
}
|
||||
if (someSupersNotNull && someSupersNullable) {
|
||||
//noinspection IfStatementWithIdenticalBranches
|
||||
if (covariantPosition) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// TODO error!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!someSupersNotNull && !someSupersNullable) { // no types from super
|
||||
return autoType.isNullable();
|
||||
}
|
||||
|
||||
return someSupersNullable && autoType.isNullable();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassifierDescriptor getReturnTypeClassifier(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
|
||||
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
|
||||
if (!(classifier instanceof ClassDescriptor)) {
|
||||
return classifier;
|
||||
}
|
||||
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
||||
|
||||
MutableReadOnlyCollectionsMap collectionsMap = MutableReadOnlyCollectionsMap.getInstance();
|
||||
|
||||
if (collectionsMap.isMutableCollection(clazz)) {
|
||||
|
||||
boolean someSupersMutable = false;
|
||||
boolean someSupersReadOnly = false;
|
||||
for (JetType typeFromSuper : typesFromSuper) {
|
||||
ClassifierDescriptor classifierFromSuper = typeFromSuper.getConstructor().getDeclarationDescriptor();
|
||||
if (classifierFromSuper instanceof ClassDescriptor) {
|
||||
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
|
||||
|
||||
if (collectionsMap.isMutableCollection(classFromSuper)) {
|
||||
someSupersMutable = true;
|
||||
}
|
||||
else if (collectionsMap.isReadOnlyCollection(classFromSuper)) {
|
||||
someSupersReadOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (someSupersReadOnly && !someSupersMutable) {
|
||||
return collectionsMap.convertMutableToReadOnly(clazz);
|
||||
}
|
||||
}
|
||||
return classifier;
|
||||
}
|
||||
|
||||
private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
||||
String methodName = functionDescriptor.getName().getName();
|
||||
|
||||
Reference in New Issue
Block a user