[groovy] fix blinking test

This commit is contained in:
Daniil Ovchinnikov
2016-04-30 19:24:00 +03:00
parent beaeceef11
commit 4238d90f9f
2 changed files with 50 additions and 29 deletions
@@ -38,7 +38,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.ExpressionConverter;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.tree.IElementType;
@@ -97,12 +96,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.*;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ast.GrInheritConstructorContributor;
@@ -430,7 +426,6 @@ public class GroovyAnnotator extends GroovyElementVisitor {
}
checkTypeDefinition(myHolder, typeDefinition);
checkDuplicateMethod(typeDefinition, myHolder);
checkImplementedMethodsOfClass(myHolder, typeDefinition);
checkConstructors(myHolder, typeDefinition);
@@ -610,6 +605,7 @@ public class GroovyAnnotator extends GroovyElementVisitor {
@Override
public void visitMethod(GrMethod method) {
checkDuplicateMethod(method);
checkMethodWithTypeParamsShouldHaveReturnType(myHolder, method);
checkInnerMethod(myHolder, method);
checkOptionalParametersInAbstractMethod(myHolder, method);
@@ -1484,7 +1480,6 @@ public class GroovyAnnotator extends GroovyElementVisitor {
public void visitFile(GroovyFileBase file) {
final PsiClass scriptClass = file.getScriptClass();
if (scriptClass != null) {
checkDuplicateMethod(scriptClass, myHolder);
checkSameNameMethodsWithDifferentAccessModifiers(myHolder, file.getCodeMethods());
}
}
@@ -1992,31 +1987,31 @@ public class GroovyAnnotator extends GroovyElementVisitor {
}
}
private static void checkDuplicateMethod(PsiClass clazz, AnnotationHolder holder) {
MultiMap<MethodSignature, PsiMethod> map = GrClosureSignatureUtil.findRawMethodSignatures(clazz.getMethods(), clazz);
processMethodDuplicates(map, holder);
}
protected static void processMethodDuplicates(MultiMap<MethodSignature, PsiMethod> map, AnnotationHolder holder) {
for (MethodSignature signature : map.keySet()) {
Collection<PsiMethod> methods = map.get(signature);
if (methods.size() > 1) {
for (Iterator<PsiMethod> iterator = methods.iterator(); iterator.hasNext(); ) {
PsiMethod method = iterator.next();
if (method instanceof LightElement) iterator.remove();
}
if (methods.size() < 2) continue;
String signaturePresentation = GroovyPresentationUtil.getSignaturePresentation(signature);
for (PsiMethod method : methods) {
//noinspection ConstantConditions
holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method), GroovyBundle
.message("method.duplicate", signaturePresentation, method.getContainingClass().getName()));
}
private void checkDuplicateMethod(@NotNull GrMethod method) {
PsiClass clazz = method.getContainingClass();
if (clazz == null) return;
GrReflectedMethod[] reflectedMethods = method.getReflectedMethods();
if (reflectedMethods.length == 0) {
doCheckDuplicateMethod(method, clazz);
}
else {
for (GrReflectedMethod reflectedMethod : reflectedMethods) {
doCheckDuplicateMethod(reflectedMethod, clazz);
}
}
}
private void doCheckDuplicateMethod(@NotNull GrMethod method, @NotNull PsiClass clazz) {
MethodSignature signature = GrClassImplUtil.getDuplicatedMethods(clazz).get(method);
if (signature == null) return;
String signaturePresentation = GroovyPresentationUtil.getSignaturePresentation(signature);
GrMethod original = method instanceof GrReflectedMethod ? ((GrReflectedMethod)method).getBaseMethod() : method;
myHolder.createErrorAnnotation(
GrHighlightUtil.getMethodHeaderTextRange(original),
GroovyBundle.message("method.duplicate", signaturePresentation, clazz.getName())
);
}
private static void checkTypeDefinition(AnnotationHolder holder, GrTypeDefinition typeDefinition) {
final GroovyConfigUtils configUtils = GroovyConfigUtils.getInstance();
if (typeDefinition.isAnonymous()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -33,6 +33,7 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MostlySingularMultiMap;
import com.intellij.util.containers.hash.HashSet;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NonNls;
@@ -636,4 +637,29 @@ public class GrClassImplUtil {
}
});
}
@NotNull
public static Map<PsiMethod, MethodSignature> getDuplicatedMethods(@NotNull PsiClass clazz) {
return CachedValuesManager.getCachedValue(clazz, () -> {
PsiElementFactory factory = JavaPsiFacade.getInstance(clazz.getProject()).getElementFactory();
MostlySingularMultiMap<MethodSignature, PsiMethod> signatures = MostlySingularMultiMap.newMap();
for (PsiMethod method : clazz.getMethods()) {
MethodSignature signature = method.getSignature(factory.createRawSubstitutor(method));
signatures.add(signature, method);
}
Map<PsiMethod, MethodSignature> result = ContainerUtil.newHashMap();
for (MethodSignature signature : signatures.keySet()) {
if (signatures.valuesForKey(signature) > 1) {
signatures.processForKey(signature, m -> {
result.put(m, signature);
return true;
});
}
}
return CachedValueProvider.Result.create(result, clazz);
});
}
}