Extract signature checking logic into an interface
Combine JavaMethodSignatureUtil and RawTypesCheck utility classes into a new PsiBasedMethodSignatureChecker
This commit is contained in:
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedExternalSignatureR
|
|||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
|
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.FakeOverrideVisibilityResolverImpl;
|
import org.jetbrains.jet.lang.resolve.java.resolver.FakeOverrideVisibilityResolverImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
|
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureChecker;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl;
|
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
||||||
@@ -52,6 +53,7 @@ public class InjectorForJavaDescriptorResolver {
|
|||||||
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
|
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
|
||||||
private final FakeOverrideVisibilityResolverImpl fakeOverrideVisibilityResolver;
|
private final FakeOverrideVisibilityResolverImpl fakeOverrideVisibilityResolver;
|
||||||
private final TraceBasedErrorReporter traceBasedErrorReporter;
|
private final TraceBasedErrorReporter traceBasedErrorReporter;
|
||||||
|
private final PsiBasedMethodSignatureChecker psiBasedMethodSignatureChecker;
|
||||||
private final JavaDescriptorResolver javaDescriptorResolver;
|
private final JavaDescriptorResolver javaDescriptorResolver;
|
||||||
private final PsiClassFinderImpl psiClassFinder;
|
private final PsiClassFinderImpl psiClassFinder;
|
||||||
private final VirtualFileFinder virtualFileFinder;
|
private final VirtualFileFinder virtualFileFinder;
|
||||||
@@ -80,6 +82,7 @@ public class InjectorForJavaDescriptorResolver {
|
|||||||
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
|
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
|
||||||
this.fakeOverrideVisibilityResolver = new FakeOverrideVisibilityResolverImpl();
|
this.fakeOverrideVisibilityResolver = new FakeOverrideVisibilityResolverImpl();
|
||||||
this.traceBasedErrorReporter = new TraceBasedErrorReporter();
|
this.traceBasedErrorReporter = new TraceBasedErrorReporter();
|
||||||
|
this.psiBasedMethodSignatureChecker = new PsiBasedMethodSignatureChecker();
|
||||||
this.javaDescriptorResolver = new JavaDescriptorResolver();
|
this.javaDescriptorResolver = new JavaDescriptorResolver();
|
||||||
this.psiClassFinder = new PsiClassFinderImpl();
|
this.psiClassFinder = new PsiClassFinderImpl();
|
||||||
this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class);
|
this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class);
|
||||||
@@ -107,6 +110,8 @@ public class InjectorForJavaDescriptorResolver {
|
|||||||
|
|
||||||
traceBasedErrorReporter.setTrace(bindingTrace);
|
traceBasedErrorReporter.setTrace(bindingTrace);
|
||||||
|
|
||||||
|
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
||||||
|
|
||||||
this.javaDescriptorResolver.setClassResolver(javaClassResolver);
|
this.javaDescriptorResolver.setClassResolver(javaClassResolver);
|
||||||
this.javaDescriptorResolver.setConstructorResolver(javaConstructorResolver);
|
this.javaDescriptorResolver.setConstructorResolver(javaConstructorResolver);
|
||||||
this.javaDescriptorResolver.setFunctionResolver(javaFunctionResolver);
|
this.javaDescriptorResolver.setFunctionResolver(javaFunctionResolver);
|
||||||
@@ -151,6 +156,7 @@ public class InjectorForJavaDescriptorResolver {
|
|||||||
javaFunctionResolver.setCache(traceBasedJavaResolverCache);
|
javaFunctionResolver.setCache(traceBasedJavaResolverCache);
|
||||||
javaFunctionResolver.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
javaFunctionResolver.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
||||||
javaFunctionResolver.setFakeOverrideVisibilityResolver(fakeOverrideVisibilityResolver);
|
javaFunctionResolver.setFakeOverrideVisibilityResolver(fakeOverrideVisibilityResolver);
|
||||||
|
javaFunctionResolver.setSignatureChecker(psiBasedMethodSignatureChecker);
|
||||||
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
|
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
|
||||||
javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
|
javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
|
||||||
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
|
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedExternalSignatureR
|
|||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
|
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.FakeOverrideVisibilityResolverImpl;
|
import org.jetbrains.jet.lang.resolve.java.resolver.FakeOverrideVisibilityResolverImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
|
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureChecker;
|
||||||
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
||||||
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
||||||
@@ -91,6 +92,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
|
private final TraceBasedJavaResolverCache traceBasedJavaResolverCache;
|
||||||
private final FakeOverrideVisibilityResolverImpl fakeOverrideVisibilityResolver;
|
private final FakeOverrideVisibilityResolverImpl fakeOverrideVisibilityResolver;
|
||||||
private final TraceBasedErrorReporter traceBasedErrorReporter;
|
private final TraceBasedErrorReporter traceBasedErrorReporter;
|
||||||
|
private final PsiBasedMethodSignatureChecker psiBasedMethodSignatureChecker;
|
||||||
private final NamespaceFactoryImpl namespaceFactory;
|
private final NamespaceFactoryImpl namespaceFactory;
|
||||||
private final VirtualFileFinder virtualFileFinder;
|
private final VirtualFileFinder virtualFileFinder;
|
||||||
private final DeclarationResolver declarationResolver;
|
private final DeclarationResolver declarationResolver;
|
||||||
@@ -148,6 +150,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
|
this.traceBasedJavaResolverCache = new TraceBasedJavaResolverCache();
|
||||||
this.fakeOverrideVisibilityResolver = new FakeOverrideVisibilityResolverImpl();
|
this.fakeOverrideVisibilityResolver = new FakeOverrideVisibilityResolverImpl();
|
||||||
this.traceBasedErrorReporter = new TraceBasedErrorReporter();
|
this.traceBasedErrorReporter = new TraceBasedErrorReporter();
|
||||||
|
this.psiBasedMethodSignatureChecker = new PsiBasedMethodSignatureChecker();
|
||||||
this.namespaceFactory = new NamespaceFactoryImpl();
|
this.namespaceFactory = new NamespaceFactoryImpl();
|
||||||
this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class);
|
this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class);
|
||||||
this.declarationResolver = new DeclarationResolver();
|
this.declarationResolver = new DeclarationResolver();
|
||||||
@@ -233,6 +236,8 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
|
|
||||||
traceBasedErrorReporter.setTrace(bindingTrace);
|
traceBasedErrorReporter.setTrace(bindingTrace);
|
||||||
|
|
||||||
|
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
||||||
|
|
||||||
this.namespaceFactory.setModuleDescriptor(moduleDescriptor);
|
this.namespaceFactory.setModuleDescriptor(moduleDescriptor);
|
||||||
this.namespaceFactory.setTrace(bindingTrace);
|
this.namespaceFactory.setTrace(bindingTrace);
|
||||||
|
|
||||||
@@ -338,6 +343,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
javaFunctionResolver.setCache(traceBasedJavaResolverCache);
|
javaFunctionResolver.setCache(traceBasedJavaResolverCache);
|
||||||
javaFunctionResolver.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
javaFunctionResolver.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
|
||||||
javaFunctionResolver.setFakeOverrideVisibilityResolver(fakeOverrideVisibilityResolver);
|
javaFunctionResolver.setFakeOverrideVisibilityResolver(fakeOverrideVisibilityResolver);
|
||||||
|
javaFunctionResolver.setSignatureChecker(psiBasedMethodSignatureChecker);
|
||||||
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
|
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
|
||||||
javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
|
javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
|
||||||
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
|
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
|
||||||
|
|||||||
+9
-71
@@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -32,27 +30,22 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmByte
|
|||||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
|
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaSignatureFormatter;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
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.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.OverridingUtil.*;
|
|
||||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.resolveOverrides;
|
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.resolveOverrides;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.*;
|
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.*;
|
||||||
|
|
||||||
public final class JavaFunctionResolver {
|
public final class JavaFunctionResolver {
|
||||||
private static final Logger LOG = Logger.getInstance(JavaFunctionResolver.class);
|
|
||||||
|
|
||||||
private JavaTypeTransformer typeTransformer;
|
private JavaTypeTransformer typeTransformer;
|
||||||
private JavaResolverCache cache;
|
private JavaResolverCache cache;
|
||||||
private JavaTypeParameterResolver typeParameterResolver;
|
private JavaTypeParameterResolver typeParameterResolver;
|
||||||
@@ -60,6 +53,7 @@ public final class JavaFunctionResolver {
|
|||||||
private JavaAnnotationResolver annotationResolver;
|
private JavaAnnotationResolver annotationResolver;
|
||||||
private ExternalSignatureResolver externalSignatureResolver;
|
private ExternalSignatureResolver externalSignatureResolver;
|
||||||
private FakeOverrideVisibilityResolver fakeOverrideVisibilityResolver;
|
private FakeOverrideVisibilityResolver fakeOverrideVisibilityResolver;
|
||||||
|
private MethodSignatureChecker signatureChecker;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
|
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
|
||||||
@@ -96,6 +90,11 @@ public final class JavaFunctionResolver {
|
|||||||
this.fakeOverrideVisibilityResolver = fakeOverrideVisibilityResolver;
|
this.fakeOverrideVisibilityResolver = fakeOverrideVisibilityResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setSignatureChecker(MethodSignatureChecker signatureChecker) {
|
||||||
|
this.signatureChecker = signatureChecker;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) {
|
SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) {
|
||||||
return resolveMethodToFunctionDescriptor(method, owner, false);
|
return resolveMethodToFunctionDescriptor(method, owner, false);
|
||||||
@@ -183,58 +182,11 @@ public final class JavaFunctionResolver {
|
|||||||
cache.recordMethod(method, functionDescriptorImpl);
|
cache.recordMethod(method, functionDescriptorImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RawTypesCheck.hasRawTypesInHierarchicalSignature(method)
|
signatureChecker.checkSignature(method, record, functionDescriptorImpl, signatureErrors, superFunctions);
|
||||||
&& JavaMethodSignatureUtil.isMethodReturnTypeCompatible(method)
|
|
||||||
&& !containsErrorType(superFunctions, functionDescriptorImpl)) {
|
|
||||||
if (signatureErrors.isEmpty()) {
|
|
||||||
checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl);
|
|
||||||
}
|
|
||||||
else if (record) {
|
|
||||||
externalSignatureResolver.reportSignatureErrors(functionDescriptorImpl, signatureErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return functionDescriptorImpl;
|
return functionDescriptorImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkFunctionsOverrideCorrectly(
|
|
||||||
@NotNull JavaMethod method,
|
|
||||||
@NotNull List<FunctionDescriptor> superFunctions,
|
|
||||||
@NotNull FunctionDescriptor functionDescriptor
|
|
||||||
) {
|
|
||||||
for (FunctionDescriptor superFunction : superFunctions) {
|
|
||||||
ClassDescriptor klass = (ClassDescriptor) functionDescriptor.getContainingDeclaration();
|
|
||||||
List<TypeSubstitution> substitutions = Lists.newArrayList();
|
|
||||||
while (true) {
|
|
||||||
substitutions.add(SubstitutionUtils.buildDeepSubstitutor(klass.getDefaultType()).getSubstitution());
|
|
||||||
if (!klass.isInner()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
klass = (ClassDescriptor) klass.getContainingDeclaration();
|
|
||||||
}
|
|
||||||
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutions.toArray(new TypeSubstitution[substitutions.size()]));
|
|
||||||
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
|
|
||||||
|
|
||||||
assert superFunctionSubstituted != null :
|
|
||||||
"Couldn't substitute super function: " + superFunction + ", substitutor = " + substitutor;
|
|
||||||
|
|
||||||
OverrideCompatibilityInfo.Result overridableResult =
|
|
||||||
isOverridableBy(superFunctionSubstituted, functionDescriptor).getResult();
|
|
||||||
boolean paramsOk = overridableResult == OverrideCompatibilityInfo.Result.OVERRIDABLE;
|
|
||||||
boolean returnTypeOk =
|
|
||||||
isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptor);
|
|
||||||
if (!paramsOk || !returnTypeOk) {
|
|
||||||
LOG.error("Loaded Java method overrides another, but resolved as Kotlin function, doesn't.\n"
|
|
||||||
+ "super function = " + superFunction + "\n"
|
|
||||||
+ "super class = " + superFunction.getContainingDeclaration() + "\n"
|
|
||||||
+ "sub function = " + functionDescriptor + "\n"
|
|
||||||
+ "sub class = " + functionDescriptor.getContainingDeclaration() + "\n"
|
|
||||||
+ "sub method = " + JavaSignatureFormatter.getExternalName(method) + "\n"
|
|
||||||
+ "@KotlinSignature = " + SignaturesUtil.getKotlinSignature(method));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<FunctionDescriptor> resolveFunctionGroupForClass(@NotNull NamedMembers members, @NotNull ClassOrNamespaceDescriptor owner) {
|
public Set<FunctionDescriptor> resolveFunctionGroupForClass(@NotNull NamedMembers members, @NotNull ClassOrNamespaceDescriptor owner) {
|
||||||
Name methodName = members.getName();
|
Name methodName = members.getName();
|
||||||
@@ -374,18 +326,4 @@ public final class JavaFunctionResolver {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containsErrorType(@NotNull List<FunctionDescriptor> superFunctions, @NotNull FunctionDescriptor function) {
|
|
||||||
if (ErrorUtils.containsErrorType(function)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (FunctionDescriptor superFunction : superFunctions) {
|
|
||||||
if (ErrorUtils.containsErrorType(superFunction)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 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.resolver;
|
|
||||||
|
|
||||||
import com.intellij.psi.*;
|
|
||||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
|
||||||
import com.intellij.psi.util.MethodSignatureUtil;
|
|
||||||
import com.intellij.psi.util.PsiUtil;
|
|
||||||
import com.intellij.psi.util.TypeConversionUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
// originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil
|
|
||||||
class JavaMethodSignatureUtil {
|
|
||||||
// This and following methods are originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil
|
|
||||||
static boolean isMethodReturnTypeCompatible(@NotNull JavaMethod method) {
|
|
||||||
if (method.isStatic()) return true;
|
|
||||||
|
|
||||||
HierarchicalMethodSignature methodSignature = method.getPsi().getHierarchicalMethodSignature();
|
|
||||||
List<HierarchicalMethodSignature> superSignatures = methodSignature.getSuperSignatures();
|
|
||||||
|
|
||||||
PsiType returnType = methodSignature.getSubstitutor().substitute(method.getPsi().getReturnType());
|
|
||||||
if (returnType == null) return true;
|
|
||||||
|
|
||||||
for (MethodSignatureBackedByPsiMethod superMethodSignature : superSignatures) {
|
|
||||||
PsiMethod superMethod = superMethodSignature.getMethod();
|
|
||||||
PsiType declaredReturnType = superMethod.getReturnType();
|
|
||||||
PsiType superReturnType = superMethodSignature.isRaw() ? TypeConversionUtil.erasure(declaredReturnType) : declaredReturnType;
|
|
||||||
if (superReturnType == null || method == superMethod || superMethod.getContainingClass() == null) continue;
|
|
||||||
if (!areMethodsReturnTypesCompatible(superMethodSignature, superReturnType, methodSignature, returnType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean areMethodsReturnTypesCompatible(
|
|
||||||
@NotNull MethodSignatureBackedByPsiMethod superMethodSignature,
|
|
||||||
@NotNull PsiType superReturnType,
|
|
||||||
@NotNull MethodSignatureBackedByPsiMethod methodSignature,
|
|
||||||
@NotNull PsiType returnType
|
|
||||||
) {
|
|
||||||
PsiType substitutedSuperReturnType;
|
|
||||||
boolean isJdk15 = PsiUtil.isLanguageLevel5OrHigher(methodSignature.getMethod());
|
|
||||||
if (isJdk15 && !superMethodSignature.isRaw() && superMethodSignature.equals(methodSignature)) { //see 8.4.5
|
|
||||||
PsiSubstitutor unifyingSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature,
|
|
||||||
superMethodSignature);
|
|
||||||
substitutedSuperReturnType = unifyingSubstitutor == null
|
|
||||||
? superReturnType
|
|
||||||
: unifyingSubstitutor.substitute(superReturnType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
substitutedSuperReturnType = TypeConversionUtil.erasure(superMethodSignature.getSubstitutor().substitute(superReturnType));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnType.equals(substitutedSuperReturnType)) return true;
|
|
||||||
if (!(returnType instanceof PsiPrimitiveType) && substitutedSuperReturnType.getDeepComponentType() instanceof PsiClassType) {
|
|
||||||
if (isJdk15 && TypeConversionUtil.isAssignable(substitutedSuperReturnType, returnType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JavaMethodSignatureUtil() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.resolver;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface MethodSignatureChecker {
|
||||||
|
void checkSignature(
|
||||||
|
@NotNull JavaMethod method,
|
||||||
|
boolean reportSignatureErrors,
|
||||||
|
@NotNull SimpleFunctionDescriptor descriptor,
|
||||||
|
@NotNull List<String> signatureErrors,
|
||||||
|
@NotNull List<FunctionDescriptor> superFunctions
|
||||||
|
);
|
||||||
|
}
|
||||||
+262
@@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.resolver;
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||||
|
import com.intellij.psi.util.MethodSignatureUtil;
|
||||||
|
import com.intellij.psi.util.PsiUtil;
|
||||||
|
import com.intellij.psi.util.TypeConversionUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.*;
|
||||||
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
|
import org.jetbrains.jet.lang.types.SubstitutionUtils;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitution;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.OverridingUtil.isOverridableBy;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.OverridingUtil.isReturnTypeOkForOverride;
|
||||||
|
|
||||||
|
public class PsiBasedMethodSignatureChecker implements MethodSignatureChecker {
|
||||||
|
private static final Logger LOG = Logger.getInstance(PsiBasedMethodSignatureChecker.class);
|
||||||
|
|
||||||
|
private ExternalSignatureResolver externalSignatureResolver;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
|
||||||
|
this.externalSignatureResolver = externalSignatureResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkFunctionOverridesCorrectly(
|
||||||
|
@NotNull JavaMethod method,
|
||||||
|
@NotNull FunctionDescriptor function,
|
||||||
|
@NotNull FunctionDescriptor superFunction
|
||||||
|
) {
|
||||||
|
ClassDescriptor klass = (ClassDescriptor) function.getContainingDeclaration();
|
||||||
|
List<TypeSubstitution> substitutions = new ArrayList<TypeSubstitution>();
|
||||||
|
while (true) {
|
||||||
|
substitutions.add(SubstitutionUtils.buildDeepSubstitutor(klass.getDefaultType()).getSubstitution());
|
||||||
|
if (!klass.isInner()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
klass = (ClassDescriptor) klass.getContainingDeclaration();
|
||||||
|
}
|
||||||
|
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutions.toArray(new TypeSubstitution[substitutions.size()]));
|
||||||
|
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
|
||||||
|
|
||||||
|
assert superFunctionSubstituted != null : "Couldn't substitute super function: " + superFunction + ", substitutor = " + substitutor;
|
||||||
|
|
||||||
|
OverridingUtil.OverrideCompatibilityInfo.Result overridableResult = isOverridableBy(superFunctionSubstituted, function).getResult();
|
||||||
|
boolean paramsOk = overridableResult == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
|
||||||
|
boolean returnTypeOk = isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, function);
|
||||||
|
if (!paramsOk || !returnTypeOk) {
|
||||||
|
LOG.error("Loaded Java method overrides another, but resolved as Kotlin function, doesn't.\n"
|
||||||
|
+ "super function = " + superFunction + "\n"
|
||||||
|
+ "super class = " + superFunction.getContainingDeclaration() + "\n"
|
||||||
|
+ "sub function = " + function + "\n"
|
||||||
|
+ "sub class = " + function.getContainingDeclaration() + "\n"
|
||||||
|
+ "sub method = " + JavaSignatureFormatter.getExternalName(method) + "\n"
|
||||||
|
+ "@KotlinSignature = " + SignaturesUtil.getKotlinSignature(method));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containsErrorType(@NotNull List<FunctionDescriptor> superFunctions, @NotNull FunctionDescriptor function) {
|
||||||
|
if (ErrorUtils.containsErrorType(function)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (FunctionDescriptor superFunction : superFunctions) {
|
||||||
|
if (ErrorUtils.containsErrorType(superFunction)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil
|
||||||
|
private static boolean isMethodReturnTypeCompatible(@NotNull JavaMethod method) {
|
||||||
|
if (method.isStatic()) return true;
|
||||||
|
|
||||||
|
HierarchicalMethodSignature methodSignature = method.getPsi().getHierarchicalMethodSignature();
|
||||||
|
List<HierarchicalMethodSignature> superSignatures = methodSignature.getSuperSignatures();
|
||||||
|
|
||||||
|
PsiType returnType = methodSignature.getSubstitutor().substitute(method.getPsi().getReturnType());
|
||||||
|
if (returnType == null) return true;
|
||||||
|
|
||||||
|
for (MethodSignatureBackedByPsiMethod superMethodSignature : superSignatures) {
|
||||||
|
PsiMethod superMethod = superMethodSignature.getMethod();
|
||||||
|
PsiType declaredReturnType = superMethod.getReturnType();
|
||||||
|
PsiType superReturnType = superMethodSignature.isRaw() ? TypeConversionUtil.erasure(declaredReturnType) : declaredReturnType;
|
||||||
|
if (superReturnType == null || method == superMethod || superMethod.getContainingClass() == null) continue;
|
||||||
|
if (!areMethodsReturnTypesCompatible(superMethodSignature, superReturnType, methodSignature, returnType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil
|
||||||
|
private static boolean areMethodsReturnTypesCompatible(
|
||||||
|
@NotNull MethodSignatureBackedByPsiMethod superMethodSignature,
|
||||||
|
@NotNull PsiType superReturnType,
|
||||||
|
@NotNull MethodSignatureBackedByPsiMethod methodSignature,
|
||||||
|
@NotNull PsiType returnType
|
||||||
|
) {
|
||||||
|
PsiType substitutedSuperReturnType;
|
||||||
|
boolean isJdk15 = PsiUtil.isLanguageLevel5OrHigher(methodSignature.getMethod());
|
||||||
|
if (isJdk15 && !superMethodSignature.isRaw() && superMethodSignature.equals(methodSignature)) { //see 8.4.5
|
||||||
|
PsiSubstitutor unifyingSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature,
|
||||||
|
superMethodSignature);
|
||||||
|
substitutedSuperReturnType = unifyingSubstitutor == null
|
||||||
|
? superReturnType
|
||||||
|
: unifyingSubstitutor.substitute(superReturnType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
substitutedSuperReturnType = TypeConversionUtil.erasure(superMethodSignature.getSubstitutor().substitute(superReturnType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnType.equals(substitutedSuperReturnType)) return true;
|
||||||
|
if (!(returnType instanceof PsiPrimitiveType) && substitutedSuperReturnType.getDeepComponentType() instanceof PsiClassType) {
|
||||||
|
if (isJdk15 && TypeConversionUtil.isAssignable(substitutedSuperReturnType, returnType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkSignature(
|
||||||
|
@NotNull JavaMethod method,
|
||||||
|
boolean reportSignatureErrors,
|
||||||
|
@NotNull SimpleFunctionDescriptor descriptor,
|
||||||
|
@NotNull List<String> signatureErrors,
|
||||||
|
@NotNull List<FunctionDescriptor> superFunctions
|
||||||
|
) {
|
||||||
|
if (!RawTypesCheck.hasRawTypesInHierarchicalSignature(method) &&
|
||||||
|
isMethodReturnTypeCompatible(method) &&
|
||||||
|
!containsErrorType(superFunctions, descriptor)) {
|
||||||
|
if (signatureErrors.isEmpty()) {
|
||||||
|
for (FunctionDescriptor superFunction : superFunctions) {
|
||||||
|
checkFunctionOverridesCorrectly(method, descriptor, superFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reportSignatureErrors) {
|
||||||
|
externalSignatureResolver.reportSignatureErrors(descriptor, signatureErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RawTypesCheck {
|
||||||
|
private static boolean isPartiallyRawType(@NotNull JavaType type) {
|
||||||
|
if (type instanceof JavaPrimitiveType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (type instanceof JavaClassifierType) {
|
||||||
|
JavaClassifierType classifierType = (JavaClassifierType) type;
|
||||||
|
|
||||||
|
if (classifierType.isRaw()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JavaType argument : classifierType.getTypeArguments()) {
|
||||||
|
if (isPartiallyRawType(argument)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (type instanceof JavaArrayType) {
|
||||||
|
return isPartiallyRawType(((JavaArrayType) type).getComponentType());
|
||||||
|
}
|
||||||
|
else if (type instanceof JavaWildcardType) {
|
||||||
|
JavaType bound = ((JavaWildcardType) type).getBound();
|
||||||
|
return bound != null && isPartiallyRawType(bound);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException("Unexpected type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasRawTypesInSignature(@NotNull JavaMethod method) {
|
||||||
|
JavaType returnType = method.getReturnType();
|
||||||
|
if (returnType != null && isPartiallyRawType(returnType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JavaValueParameter parameter : method.getValueParameters()) {
|
||||||
|
if (isPartiallyRawType(parameter.getType())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JavaTypeParameter typeParameter : method.getTypeParameters()) {
|
||||||
|
for (JavaClassifierType upperBound : typeParameter.getUpperBounds()) {
|
||||||
|
if (isPartiallyRawType(upperBound)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasRawTypesInHierarchicalSignature(@NotNull JavaMethod method) {
|
||||||
|
// This is a very important optimization: package-classes are big and full of static methods
|
||||||
|
// building method hierarchies for such classes takes a very long time
|
||||||
|
if (method.isStatic()) return false;
|
||||||
|
|
||||||
|
if (hasRawTypesInSignature(method)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HierarchicalMethodSignature superSignature : method.getPsi().getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||||
|
JavaMethod superMethod = new JavaMethod(superSignature.getMethod());
|
||||||
|
if (superSignature.isRaw() || typeParameterIsErased(method, superMethod) || hasRawTypesInSignature(superMethod)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean typeParameterIsErased(@NotNull JavaMethod method, @NotNull JavaMethod superMethod) {
|
||||||
|
// Java allows you to write
|
||||||
|
// <T extends Foo> T foo(), in the superclass and then
|
||||||
|
// Foo foo(), in the subclass
|
||||||
|
// this is a valid Java override, but in fact it is an erasure
|
||||||
|
return method.getTypeParameters().size() != superMethod.getTypeParameters().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RawTypesCheck() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-107
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 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.resolver;
|
|
||||||
|
|
||||||
import com.intellij.psi.HierarchicalMethodSignature;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.*;
|
|
||||||
|
|
||||||
public class RawTypesCheck {
|
|
||||||
private static boolean isPartiallyRawType(@NotNull JavaType type) {
|
|
||||||
if (type instanceof JavaPrimitiveType) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (type instanceof JavaClassifierType) {
|
|
||||||
JavaClassifierType classifierType = (JavaClassifierType) type;
|
|
||||||
|
|
||||||
if (classifierType.isRaw()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JavaType argument : classifierType.getTypeArguments()) {
|
|
||||||
if (isPartiallyRawType(argument)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (type instanceof JavaArrayType) {
|
|
||||||
return isPartiallyRawType(((JavaArrayType) type).getComponentType());
|
|
||||||
}
|
|
||||||
else if (type instanceof JavaWildcardType) {
|
|
||||||
JavaType bound = ((JavaWildcardType) type).getBound();
|
|
||||||
return bound != null && isPartiallyRawType(bound);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalStateException("Unexpected type: " + type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean hasRawTypesInSignature(@NotNull JavaMethod method) {
|
|
||||||
JavaType returnType = method.getReturnType();
|
|
||||||
if (returnType != null && isPartiallyRawType(returnType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JavaValueParameter parameter : method.getValueParameters()) {
|
|
||||||
if (isPartiallyRawType(parameter.getType())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JavaTypeParameter typeParameter : method.getTypeParameters()) {
|
|
||||||
for (JavaClassifierType upperBound : typeParameter.getUpperBounds()) {
|
|
||||||
if (isPartiallyRawType(upperBound)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean hasRawTypesInHierarchicalSignature(@NotNull JavaMethod method) {
|
|
||||||
// This is a very important optimization: package-classes are big and full of static methods
|
|
||||||
// building method hierarchies for such classes takes a very long time
|
|
||||||
if (method.isStatic()) return false;
|
|
||||||
|
|
||||||
if (hasRawTypesInSignature(method)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (HierarchicalMethodSignature superSignature : method.getPsi().getHierarchicalMethodSignature().getSuperSignatures()) {
|
|
||||||
JavaMethod superMethod = new JavaMethod(superSignature.getMethod());
|
|
||||||
if (superSignature.isRaw() || typeParameterIsErased(method, superMethod) || hasRawTypesInSignature(superMethod)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean typeParameterIsErased(@NotNull JavaMethod method, @NotNull JavaMethod superMethod) {
|
|
||||||
// Java allows you to write
|
|
||||||
// <T extends Foo> T foo(), in the superclass and then
|
|
||||||
// Foo foo(), in the subclass
|
|
||||||
// this is a valid Java override, but in fact it is an erasure
|
|
||||||
return method.getTypeParameters().size() != superMethod.getTypeParameters().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private RawTypesCheck() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -37,10 +37,7 @@ import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl;
|
import org.jetbrains.jet.lang.resolve.java.JavaClassFinderImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl;
|
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.FakeOverrideVisibilityResolverImpl;
|
import org.jetbrains.jet.lang.resolve.java.resolver.*;
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedExternalSignatureResolver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
|
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
|
||||||
@@ -113,6 +110,7 @@ public class GenerateInjectors {
|
|||||||
generator.addField(TraceBasedJavaResolverCache.class);
|
generator.addField(TraceBasedJavaResolverCache.class);
|
||||||
generator.addField(FakeOverrideVisibilityResolverImpl.class);
|
generator.addField(FakeOverrideVisibilityResolverImpl.class);
|
||||||
generator.addField(TraceBasedErrorReporter.class);
|
generator.addField(TraceBasedErrorReporter.class);
|
||||||
|
generator.addField(PsiBasedMethodSignatureChecker.class);
|
||||||
generator.addPublicField(NamespaceFactoryImpl.class);
|
generator.addPublicField(NamespaceFactoryImpl.class);
|
||||||
generator.addField(false, VirtualFileFinder.class, "virtualFileFinder",
|
generator.addField(false, VirtualFileFinder.class, "virtualFileFinder",
|
||||||
new GivenExpression(
|
new GivenExpression(
|
||||||
@@ -134,6 +132,7 @@ public class GenerateInjectors {
|
|||||||
generator.addField(TraceBasedJavaResolverCache.class);
|
generator.addField(TraceBasedJavaResolverCache.class);
|
||||||
generator.addField(FakeOverrideVisibilityResolverImpl.class);
|
generator.addField(FakeOverrideVisibilityResolverImpl.class);
|
||||||
generator.addField(TraceBasedErrorReporter.class);
|
generator.addField(TraceBasedErrorReporter.class);
|
||||||
|
generator.addField(PsiBasedMethodSignatureChecker.class);
|
||||||
generator.addPublicField(JavaDescriptorResolver.class);
|
generator.addPublicField(JavaDescriptorResolver.class);
|
||||||
generator.addPublicField(PsiClassFinderImpl.class);
|
generator.addPublicField(PsiClassFinderImpl.class);
|
||||||
generator.addField(false, VirtualFileFinder.class, "virtualFileFinder",
|
generator.addField(false, VirtualFileFinder.class, "virtualFileFinder",
|
||||||
|
|||||||
Reference in New Issue
Block a user