mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
resolve/highlighting performance:
- propagate PsiFile parameter to reduce psiElement.getContainingFile() and psiElement.getManager() calls - store and propagate LanguageLevel and JdkVersion to avoid tree walking
This commit is contained in:
+3
-1
@@ -40,6 +40,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.sun.jdi.Value;
|
||||
@@ -963,7 +964,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
|
||||
@Override
|
||||
public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
final HighlightInfo parsingError = HighlightUtil.checkLiteralExpressionParsingError(expression);
|
||||
final HighlightInfo parsingError = HighlightUtil.checkLiteralExpressionParsingError(expression, PsiUtil.getLanguageLevel(expression),
|
||||
expression.getContainingFile());
|
||||
if (parsingError != null) {
|
||||
throwEvaluateException(parsingError.getDescription());
|
||||
return;
|
||||
|
||||
@@ -940,7 +940,7 @@ public class ExpectedTypesProvider {
|
||||
}
|
||||
|
||||
ParameterTypeInferencePolicy policy = forCompletion ? CompletionParameterTypeInferencePolicy.INSTANCE : DefaultParameterTypeInferencePolicy.INSTANCE;
|
||||
|
||||
|
||||
Set<ExpectedTypeInfo> array = new LinkedHashSet<ExpectedTypeInfo>();
|
||||
for (CandidateInfo candidateInfo : methodCandidates) {
|
||||
PsiMethod method = (PsiMethod)candidateInfo.getElement();
|
||||
|
||||
+9
-8
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
@@ -295,7 +296,7 @@ public class AnnotationsHighlightUtil {
|
||||
);
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation) {
|
||||
public static HighlightInfo checkApplicability(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
if (ANY_ANNOTATION_ALLOWED.accepts(annotation)) {
|
||||
return null;
|
||||
}
|
||||
@@ -311,7 +312,7 @@ public class AnnotationsHighlightUtil {
|
||||
}
|
||||
|
||||
if (!(owner instanceof PsiModifierList)) {
|
||||
HighlightInfo info = HighlightUtil.checkTypeAnnotationFeature(annotation);
|
||||
HighlightInfo info = HighlightUtil.checkTypeAnnotationFeature(annotation, languageLevel,containingFile);
|
||||
if (info != null) return info;
|
||||
}
|
||||
|
||||
@@ -465,23 +466,23 @@ public class AnnotationsHighlightUtil {
|
||||
LOG.assertTrue(aClass.isAnnotationType());
|
||||
PsiType type = typeElement.getType();
|
||||
final Set<PsiClass> checked = new HashSet<PsiClass>();
|
||||
if (cyclicDependencies(aClass, type, checked)) {
|
||||
if (cyclicDependencies(aClass, type, checked, aClass.getManager())) {
|
||||
String description = JavaErrorMessages.message("annotation.cyclic.element.type");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean cyclicDependencies(PsiClass aClass, PsiType type, Set<PsiClass> checked) {
|
||||
private static boolean cyclicDependencies(PsiClass aClass, PsiType type, @NotNull Set<PsiClass> checked,@NotNull PsiManager manager) {
|
||||
final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
|
||||
if (resolvedClass != null && resolvedClass.isAnnotationType()) {
|
||||
if (aClass == resolvedClass) {
|
||||
return true;
|
||||
}
|
||||
if (!checked.add(resolvedClass) || !resolvedClass.getManager().isInProject(resolvedClass)) return false;
|
||||
if (!checked.add(resolvedClass) || !manager.isInProject(resolvedClass)) return false;
|
||||
final PsiMethod[] methods = resolvedClass.getMethods();
|
||||
for (PsiMethod method : methods) {
|
||||
if (cyclicDependencies(aClass, method.getReturnType(), checked)) return true;
|
||||
if (cyclicDependencies(aClass, method.getReturnType(), checked,manager)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -572,8 +573,8 @@ public class AnnotationsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkFunctionalInterface(PsiAnnotation annotation) {
|
||||
final String errorMessage = LambdaUtil.checkFunctionalInterface(annotation);
|
||||
public static HighlightInfo checkFunctionalInterface(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel) {
|
||||
final String errorMessage = LambdaUtil.checkFunctionalInterface(annotation, languageLevel);
|
||||
if (errorMessage != null) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(annotation).descriptionAndTooltip(errorMessage).create();
|
||||
}
|
||||
|
||||
+24
-19
@@ -110,17 +110,19 @@ public class GenericsHighlightUtil {
|
||||
@Nullable
|
||||
public static HighlightInfo checkParameterizedReferenceTypeArguments(final PsiElement resolved,
|
||||
final PsiJavaCodeReferenceElement referenceElement,
|
||||
final PsiSubstitutor substitutor) {
|
||||
final PsiSubstitutor substitutor,
|
||||
@NotNull JavaSdkVersion javaSdkVersion) {
|
||||
if (!(resolved instanceof PsiTypeParameterListOwner)) return null;
|
||||
final PsiTypeParameterListOwner typeParameterListOwner = (PsiTypeParameterListOwner)resolved;
|
||||
return checkReferenceTypeArgumentList(typeParameterListOwner, referenceElement.getParameterList(), substitutor, true);
|
||||
return checkReferenceTypeArgumentList(typeParameterListOwner, referenceElement.getParameterList(), substitutor, true, javaSdkVersion);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkReferenceTypeArgumentList(final PsiTypeParameterListOwner typeParameterListOwner,
|
||||
final PsiReferenceParameterList referenceParameterList,
|
||||
final PsiSubstitutor substitutor,
|
||||
boolean registerIntentions) {
|
||||
boolean registerIntentions,
|
||||
@NotNull JavaSdkVersion javaSdkVersion) {
|
||||
PsiDiamondType.DiamondInferenceResult inferenceResult = null;
|
||||
PsiTypeElement[] referenceElements = null;
|
||||
if (referenceParameterList != null) {
|
||||
@@ -150,7 +152,7 @@ public class GenericsHighlightUtil {
|
||||
if (targetParametersNum == 0) {
|
||||
if (PsiTreeUtil.getParentOfType(referenceParameterList, PsiCall.class) != null &&
|
||||
typeParameterListOwner instanceof PsiMethod &&
|
||||
JavaVersionService.getInstance().isAtLeast(referenceParameterList, JavaSdkVersion.JDK_1_7)) {
|
||||
javaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) {
|
||||
description = null;
|
||||
}
|
||||
else {
|
||||
@@ -388,7 +390,8 @@ public class GenericsHighlightUtil {
|
||||
public static HighlightInfo checkElementInTypeParameterExtendsList(@NotNull PsiReferenceList referenceList,
|
||||
@NotNull PsiClass aClass,
|
||||
@NotNull JavaResolveResult resolveResult,
|
||||
@NotNull PsiElement element) {
|
||||
@NotNull PsiElement element,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final PsiJavaCodeReferenceElement[] referenceElements = referenceList.getReferenceElements();
|
||||
PsiClass extendFrom = (PsiClass)resolveResult.getElement();
|
||||
if (extendFrom == null) return null;
|
||||
@@ -408,7 +411,7 @@ public class GenericsHighlightUtil {
|
||||
IntentionAction fix = QUICK_FIX_FACTORY.createExtendsListFix(aClass, type, false);
|
||||
QuickFixAction.registerQuickFixAction(errorResult, fix, null);
|
||||
}
|
||||
if (errorResult == null && JavaVersionService.getInstance().isAtLeast(referenceList, JavaSdkVersion.JDK_1_7) &&
|
||||
if (errorResult == null && languageLevel.isAtLeast(LanguageLevel.JDK_1_7) &&
|
||||
referenceElements.length > 1) {
|
||||
//todo suppress erased methods which come from the same class
|
||||
return checkOverrideEquivalentMethods(aClass);
|
||||
@@ -736,7 +739,7 @@ public class GenericsHighlightUtil {
|
||||
|
||||
//http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
|
||||
@Nullable
|
||||
public static HighlightInfo checkAccessStaticFieldFromEnumConstructor(PsiReferenceExpression expr, JavaResolveResult result) {
|
||||
public static HighlightInfo checkAccessStaticFieldFromEnumConstructor(@NotNull PsiReferenceExpression expr, @NotNull JavaResolveResult result) {
|
||||
final PsiElement resolved = result.getElement();
|
||||
|
||||
if (!(resolved instanceof PsiField)) return null;
|
||||
@@ -806,10 +809,10 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkTypeParametersList(PsiTypeParameterList parameterList) {
|
||||
public static HighlightInfo checkTypeParametersList(PsiTypeParameterList parameterList, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
PsiTypeParameter[] typeParameters = parameterList.getTypeParameters();
|
||||
if (typeParameters.length == 0) return null;
|
||||
HighlightInfo info = HighlightUtil.checkGenericsFeature(parameterList, typeParameters.length);
|
||||
HighlightInfo info = HighlightUtil.checkGenericsFeature(parameterList, typeParameters.length, languageLevel, containingFile);
|
||||
if (info != null) return info;
|
||||
|
||||
final PsiElement parent = parameterList.getParent();
|
||||
@@ -839,7 +842,7 @@ public class GenericsHighlightUtil {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeParameter2).descriptionAndTooltip(message).create();
|
||||
}
|
||||
}
|
||||
if (!JavaVersionService.getInstance().isAtLeast(parameterList, JavaSdkVersion.JDK_1_7)) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7)) {
|
||||
for (PsiJavaCodeReferenceElement referenceElement : typeParameter1.getExtendsList().getReferenceElements()) {
|
||||
final PsiElement resolve = referenceElement.resolve();
|
||||
if (resolve instanceof PsiTypeParameter && ArrayUtilRt.find(typeParameters, resolve) > i) {
|
||||
@@ -941,7 +944,7 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkOverrideAnnotation(PsiMethod method) {
|
||||
public static HighlightInfo checkOverrideAnnotation(PsiMethod method, final LanguageLevel languageLevel) {
|
||||
PsiModifierList list = method.getModifierList();
|
||||
final PsiAnnotation overrideAnnotation = list.findAnnotation("java.lang.Override");
|
||||
if (overrideAnnotation == null) {
|
||||
@@ -962,7 +965,6 @@ public class GenericsHighlightUtil {
|
||||
PullAsAbstractUpFix.registerQuickFix(highlightInfo, method);
|
||||
return highlightInfo;
|
||||
}
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(method);
|
||||
PsiClass superClass = superMethod.getMethod().getContainingClass();
|
||||
if (languageLevel.equals(LanguageLevel.JDK_1_5) &&
|
||||
superClass != null &&
|
||||
@@ -1023,7 +1025,9 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static void checkEnumConstantForConstructorProblems(PsiEnumConstant enumConstant, final HighlightInfoHolder holder) {
|
||||
static void checkEnumConstantForConstructorProblems(PsiEnumConstant enumConstant,
|
||||
final HighlightInfoHolder holder,
|
||||
@NotNull JavaSdkVersion javaSdkVersion) {
|
||||
PsiClass containingClass = enumConstant.getContainingClass();
|
||||
if (enumConstant.getInitializingClass() == null) {
|
||||
HighlightInfo highlightInfo = HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, enumConstant.getNameIdentifier());
|
||||
@@ -1040,7 +1044,7 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
PsiClassType type = JavaPsiFacade.getInstance(holder.getProject()).getElementFactory().createType(containingClass);
|
||||
|
||||
HighlightMethodUtil.checkConstructorCall(type.resolveGenerics(), enumConstant, type, null, holder);
|
||||
HighlightMethodUtil.checkConstructorCall(type.resolveGenerics(), enumConstant, type, null, holder, javaSdkVersion);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1061,12 +1065,12 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkVarArgParameterIsLast(PsiParameter parameter) {
|
||||
public static HighlightInfo checkVarArgParameterIsLast(@NotNull PsiParameter parameter, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
PsiElement declarationScope = parameter.getDeclarationScope();
|
||||
if (declarationScope instanceof PsiMethod) {
|
||||
PsiParameter[] params = ((PsiMethod)declarationScope).getParameterList().getParameters();
|
||||
if (parameter.isVarArgs()) {
|
||||
HighlightInfo info = HighlightUtil.checkVarargFeature(parameter);
|
||||
HighlightInfo info = HighlightUtil.checkVarargFeature(parameter, languageLevel,containingFile);
|
||||
if (info != null) return info;
|
||||
|
||||
if (params[params.length - 1] != parameter) {
|
||||
@@ -1097,8 +1101,9 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkParametersAllowed(PsiReferenceParameterList refParamList) {
|
||||
HighlightInfo info = HighlightUtil.checkGenericsFeature(refParamList, refParamList.getTypeParameterElements().length);
|
||||
public static HighlightInfo checkParametersAllowed(PsiReferenceParameterList refParamList, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
HighlightInfo info = HighlightUtil.checkGenericsFeature(refParamList, refParamList.getTypeParameterElements().length,
|
||||
languageLevel, containingFile);
|
||||
if (info != null) return info;
|
||||
|
||||
if (refParamList.getTextLength() != 0) {
|
||||
@@ -1148,7 +1153,7 @@ public class GenericsHighlightUtil {
|
||||
if (qualifier instanceof PsiReferenceExpression){
|
||||
final PsiClass typeParameter = PsiUtil.resolveClassInType(((PsiReferenceExpression)qualifier).getType());
|
||||
if (typeParameter instanceof PsiTypeParameter) {
|
||||
if (JavaVersionService.getInstance().isAtLeast(element, JavaSdkVersion.JDK_1_7)) return null;
|
||||
if (JavaVersionService.getInstance().isAtLeast(containingClass, JavaSdkVersion.JDK_1_7)) return null;
|
||||
for (PsiClassType classType : typeParameter.getExtendsListTypes()) {
|
||||
final PsiClass resolve = classType.resolve();
|
||||
if (resolve != null) {
|
||||
|
||||
+3
-2
@@ -626,7 +626,7 @@ public class HighlightClassUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkExtendsDuplicate(PsiJavaCodeReferenceElement element, PsiElement resolved) {
|
||||
public static HighlightInfo checkExtendsDuplicate(PsiJavaCodeReferenceElement element, PsiElement resolved, @NotNull PsiFile containingFile) {
|
||||
if (!(element.getParent() instanceof PsiReferenceList)) return null;
|
||||
PsiReferenceList list = (PsiReferenceList)element.getParent();
|
||||
if (!(list.getParent() instanceof PsiClass)) return null;
|
||||
@@ -634,9 +634,10 @@ public class HighlightClassUtil {
|
||||
PsiClass aClass = (PsiClass)resolved;
|
||||
PsiClassType[] referencedTypes = list.getReferencedTypes();
|
||||
int dupCount = 0;
|
||||
PsiManager manager = containingFile.getManager();
|
||||
for (PsiClassType referencedType : referencedTypes) {
|
||||
PsiClass resolvedElement = referencedType.resolve();
|
||||
if (resolvedElement != null && list.getManager().areElementsEquivalent(resolvedElement, aClass)) {
|
||||
if (resolvedElement != null && manager.areElementsEquivalent(resolvedElement, aClass)) {
|
||||
dupCount++;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-16
@@ -248,7 +248,7 @@ public class HighlightControlFlowUtil {
|
||||
@Nullable
|
||||
public static HighlightInfo checkVariableInitializedBeforeUsage(PsiReferenceExpression expression,
|
||||
PsiVariable variable,
|
||||
Map<PsiElement, Collection<PsiReferenceExpression>> uninitializedVarProblems) {
|
||||
Map<PsiElement, Collection<PsiReferenceExpression>> uninitializedVarProblems, @NotNull PsiFile containingFile) {
|
||||
if (variable instanceof ImplicitVariable) return null;
|
||||
if (!PsiUtil.isAccessedForReading(expression)) return null;
|
||||
final int startOffset = expression.getTextRange().getStartOffset();
|
||||
@@ -276,14 +276,14 @@ public class HighlightControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
// access to final fields from inner classes always allowed
|
||||
if (inInnerClass(expression, ((PsiField)variable).getContainingClass())) return null;
|
||||
if (inInnerClass(expression, ((PsiField)variable).getContainingClass(),containingFile)) return null;
|
||||
if (topBlock == null) return null;
|
||||
final PsiElement parent = topBlock.getParent();
|
||||
final PsiCodeBlock block;
|
||||
final PsiClass aClass;
|
||||
if (parent instanceof PsiMethod) {
|
||||
PsiMethod constructor = (PsiMethod)parent;
|
||||
if (!parent.getManager().areElementsEquivalent(constructor.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
|
||||
if (!containingFile.getManager().areElementsEquivalent(constructor.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
|
||||
// static variables already initialized in class initializers
|
||||
if (variable.hasModifierProperty(PsiModifier.STATIC)) return null;
|
||||
// as a last chance, field may be initialized in this() call
|
||||
@@ -303,7 +303,7 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
else if (parent instanceof PsiClassInitializer) {
|
||||
final PsiClassInitializer classInitializer = (PsiClassInitializer)parent;
|
||||
if (!parent.getManager().areElementsEquivalent(classInitializer.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
|
||||
if (!containingFile.getManager().areElementsEquivalent(classInitializer.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
|
||||
block = classInitializer.getBody();
|
||||
aClass = classInitializer.getContainingClass();
|
||||
}
|
||||
@@ -385,9 +385,9 @@ public class HighlightControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean inInnerClass(PsiElement element, PsiClass containingClass) {
|
||||
private static boolean inInnerClass(PsiElement element, PsiClass containingClass, @NotNull PsiFile containingFile) {
|
||||
while (element != null) {
|
||||
if (element instanceof PsiClass) return !element.getManager().areElementsEquivalent(element, containingClass);
|
||||
if (element instanceof PsiClass) return !containingFile.getManager().areElementsEquivalent(element, containingClass);
|
||||
element = element.getParent();
|
||||
}
|
||||
return false;
|
||||
@@ -543,7 +543,7 @@ public class HighlightControlFlowUtil {
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkCannotWriteToFinal(PsiExpression expression) {
|
||||
public static HighlightInfo checkCannotWriteToFinal(PsiExpression expression, @NotNull PsiFile containingFile) {
|
||||
PsiReferenceExpression reference = null;
|
||||
if (expression instanceof PsiAssignmentExpression) {
|
||||
final PsiExpression left = ((PsiAssignmentExpression)expression).getLExpression();
|
||||
@@ -568,7 +568,7 @@ public class HighlightControlFlowUtil {
|
||||
final PsiElement resolved = reference == null ? null : reference.resolve();
|
||||
PsiVariable variable = resolved instanceof PsiVariable ? (PsiVariable)resolved : null;
|
||||
if (variable == null || !variable.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
if (!canWriteToFinal(variable, expression, reference)) {
|
||||
if (!canWriteToFinal(variable, expression, reference,containingFile)) {
|
||||
final String name = variable.getName();
|
||||
String description = JavaErrorMessages.message("assignment.to.final.variable", name);
|
||||
final HighlightInfo highlightInfo =
|
||||
@@ -587,7 +587,7 @@ public class HighlightControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean canWriteToFinal(PsiVariable variable, PsiExpression expression, final PsiReferenceExpression reference) {
|
||||
private static boolean canWriteToFinal(PsiVariable variable, PsiExpression expression, final PsiReferenceExpression reference, @NotNull PsiFile containingFile) {
|
||||
if (variable.hasInitializer()) return false;
|
||||
if (variable instanceof PsiParameter) return false;
|
||||
PsiClass innerClass = getInnerClassVariableReferencedFrom(variable, expression);
|
||||
@@ -596,9 +596,9 @@ public class HighlightControlFlowUtil {
|
||||
if (HighlightUtil.findEnclosingFieldInitializer(expression) != null) return true;
|
||||
// assignment from within inner class is illegal always
|
||||
PsiField field = (PsiField)variable;
|
||||
if (innerClass != null && !innerClass.getManager().areElementsEquivalent(innerClass, field.getContainingClass())) return false;
|
||||
if (innerClass != null && !containingFile.getManager().areElementsEquivalent(innerClass, field.getContainingClass())) return false;
|
||||
final PsiMember enclosingCtrOrInitializer = PsiUtil.findEnclosingConstructorOrInitializer(expression);
|
||||
return enclosingCtrOrInitializer != null && isSameField(variable, enclosingCtrOrInitializer, field, reference);
|
||||
return enclosingCtrOrInitializer != null && isSameField(variable, enclosingCtrOrInitializer, field, reference,containingFile);
|
||||
}
|
||||
if (variable instanceof PsiLocalVariable) {
|
||||
boolean isAccessedFromOtherClass = innerClass != null;
|
||||
@@ -612,16 +612,18 @@ public class HighlightControlFlowUtil {
|
||||
private static boolean isSameField(final PsiVariable variable,
|
||||
final PsiMember enclosingCtrOrInitializer,
|
||||
final PsiField field,
|
||||
final PsiReferenceExpression reference) {
|
||||
final PsiReferenceExpression reference, @NotNull PsiFile containingFile) {
|
||||
|
||||
if (!variable.getManager().areElementsEquivalent(enclosingCtrOrInitializer.getContainingClass(), field.getContainingClass())) return false;
|
||||
if (!containingFile.getManager().areElementsEquivalent(enclosingCtrOrInitializer.getContainingClass(), field.getContainingClass())) return false;
|
||||
PsiExpression qualifierExpression = reference.getQualifierExpression();
|
||||
return qualifierExpression == null || qualifierExpression instanceof PsiThisExpression;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkVariableMustBeFinal(PsiVariable variable, PsiJavaCodeReferenceElement context) {
|
||||
static HighlightInfo checkVariableMustBeFinal(PsiVariable variable,
|
||||
PsiJavaCodeReferenceElement context,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
final PsiClass innerClass = getInnerClassVariableReferencedFrom(variable, context);
|
||||
if (innerClass != null) {
|
||||
@@ -632,8 +634,7 @@ public class HighlightControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (PsiUtil.getLanguageLevel(variable).isAtLeast(LanguageLevel.JDK_1_8) &&
|
||||
isEffectivelyFinal(variable, innerClass, context)) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && isEffectivelyFinal(variable, innerClass, context)) {
|
||||
return null;
|
||||
}
|
||||
final String description = JavaErrorMessages.message("variable.must.be.final", context.getText());
|
||||
|
||||
+28
-23
@@ -26,9 +26,11 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
@@ -312,7 +314,10 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkMethodCall(PsiMethodCallExpression methodCall, PsiResolveHelper resolveHelper) {
|
||||
static HighlightInfo checkMethodCall(@NotNull PsiMethodCallExpression methodCall,
|
||||
@NotNull PsiResolveHelper resolveHelper,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull JavaSdkVersion javaSdkVersion) {
|
||||
PsiExpressionList list = methodCall.getArgumentList();
|
||||
PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression();
|
||||
JavaResolveResult[] results = referenceToMethod.multiResolve(true);
|
||||
@@ -327,7 +332,7 @@ public class HighlightMethodUtil {
|
||||
if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
|
||||
TextRange fixRange = getFixRange(methodCall);
|
||||
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
|
||||
if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression())) {
|
||||
if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression(), languageLevel)) {
|
||||
highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
|
||||
}
|
||||
}
|
||||
@@ -364,7 +369,7 @@ public class HighlightMethodUtil {
|
||||
highlightInfo = GenericsHighlightUtil.checkInferredTypeArguments(resolvedMethod, methodCall, substitutor);
|
||||
}
|
||||
else {
|
||||
highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, methodExpression, substitutor);
|
||||
highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, methodExpression, substitutor, javaSdkVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,7 +389,8 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
}
|
||||
if (highlightInfo == null) {
|
||||
highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, referenceToMethod, substitutor);
|
||||
highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, referenceToMethod, substitutor,
|
||||
javaSdkVersion);
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
@@ -860,7 +866,7 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkMethodCanHaveBody(PsiMethod method) {
|
||||
static HighlightInfo checkMethodCanHaveBody(PsiMethod method, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
boolean hasNoBody = method.getBody() == null;
|
||||
boolean isInterface = aClass != null && aClass.isInterface();
|
||||
@@ -887,7 +893,7 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
}
|
||||
else if (isExtension) {
|
||||
return HighlightUtil.checkExtensionMethodsFeature(method);
|
||||
return HighlightUtil.checkExtensionMethodsFeature(method, languageLevel,containingFile);
|
||||
}
|
||||
}
|
||||
else if (isExtension) {
|
||||
@@ -983,7 +989,7 @@ public class HighlightMethodUtil {
|
||||
* @return error if static method overrides instance method or
|
||||
* instance method overrides static. see JLS 8.4.6.1, 8.4.6.2
|
||||
*/
|
||||
static HighlightInfo checkStaticMethodOverride(PsiMethod method) {
|
||||
static HighlightInfo checkStaticMethodOverride(@NotNull PsiMethod method,@NotNull PsiFile containingFile) {
|
||||
// constructors are not members and therefor don't override class methods
|
||||
if (method.isConstructor()) {
|
||||
return null;
|
||||
@@ -997,7 +1003,7 @@ public class HighlightMethodUtil {
|
||||
: MethodSignatureUtil.findMethodBySignature(superClass, method, true);
|
||||
|
||||
boolean isStatic = method.hasModifierProperty(PsiModifier.STATIC);
|
||||
HighlightInfo highlightInfo = checkStaticMethodOverride(aClass, method, isStatic,superClass, superMethod);
|
||||
HighlightInfo highlightInfo = checkStaticMethodOverride(aClass, method, isStatic,superClass, superMethod,containingFile);
|
||||
if (highlightInfo != null) return highlightInfo;
|
||||
if (!isStatic) {
|
||||
// all methods in interface are instance, so no possible errors in this case
|
||||
@@ -1007,15 +1013,15 @@ public class HighlightMethodUtil {
|
||||
for (PsiClass aInterfaces : interfaces) {
|
||||
superClass = aInterfaces;
|
||||
superMethod = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(aClass, superClass, method.getSignature(PsiSubstitutor.EMPTY), true);
|
||||
highlightInfo = checkStaticMethodOverride(aClass, method, true, superClass, superMethod);
|
||||
highlightInfo = checkStaticMethodOverride(aClass, method, true, superClass, superMethod,containingFile);
|
||||
if (highlightInfo != null) return highlightInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static HighlightInfo checkStaticMethodOverride(PsiClass aClass, PsiMethod method, boolean isMethodStatic, PsiClass superClass, PsiMethod superMethod) {
|
||||
private static HighlightInfo checkStaticMethodOverride(PsiClass aClass, PsiMethod method, boolean isMethodStatic, PsiClass superClass, PsiMethod superMethod,@NotNull PsiFile containingFile) {
|
||||
if (superMethod == null) return null;
|
||||
PsiManager manager = superMethod.getManager();
|
||||
PsiManager manager = containingFile.getManager();
|
||||
PsiModifierList superModifierList = superMethod.getModifierList();
|
||||
PsiModifierList modifierList = method.getModifierList();
|
||||
if (superModifierList.hasModifierProperty(PsiModifier.PRIVATE)) return null;
|
||||
@@ -1208,7 +1214,7 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
|
||||
|
||||
static void checkNewExpression(@NotNull PsiNewExpression expression, @NotNull HighlightInfoHolder holder) {
|
||||
static void checkNewExpression(@NotNull PsiNewExpression expression, @NotNull HighlightInfoHolder holder, @NotNull JavaSdkVersion javaSdkVersion) {
|
||||
PsiType type = expression.getType();
|
||||
if (!(type instanceof PsiClassType)) return;
|
||||
PsiClassType.ClassResolveResult typeResult = ((PsiClassType)type).resolveGenerics();
|
||||
@@ -1222,15 +1228,16 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
|
||||
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
checkConstructorCall(typeResult, expression, type, classReference, holder);
|
||||
checkConstructorCall(typeResult, expression, type, classReference, holder, javaSdkVersion);
|
||||
}
|
||||
|
||||
|
||||
public static void checkConstructorCall(PsiClassType.ClassResolveResult typeResolveResult,
|
||||
PsiConstructorCall constructorCall,
|
||||
PsiType type,
|
||||
PsiJavaCodeReferenceElement classReference,
|
||||
final HighlightInfoHolder holder) {
|
||||
PsiConstructorCall constructorCall,
|
||||
PsiType type,
|
||||
PsiJavaCodeReferenceElement classReference,
|
||||
final HighlightInfoHolder holder,
|
||||
@NotNull JavaSdkVersion javaSdkVersion) {
|
||||
PsiExpressionList list = constructorCall.getArgumentList();
|
||||
if (list == null) return;
|
||||
PsiClass aClass = typeResolveResult.getElement();
|
||||
@@ -1343,12 +1350,10 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
else {
|
||||
if (constructorCall instanceof PsiNewExpression) {
|
||||
HighlightInfo highlightInfo = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor,
|
||||
((PsiNewExpression)constructorCall)
|
||||
.getTypeArgumentList(),
|
||||
result.getSubstitutor(), false);
|
||||
if (highlightInfo != null) {
|
||||
holder.add(highlightInfo);
|
||||
PsiReferenceParameterList typeArgumentList = ((PsiNewExpression)constructorCall).getTypeArgumentList();
|
||||
HighlightInfo info = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor, typeArgumentList, result.getSubstitutor(), false, javaSdkVersion);
|
||||
if (info != null) {
|
||||
holder.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+82
-51
@@ -34,7 +34,6 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
@@ -46,7 +45,9 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.jsp.JspFile;
|
||||
import com.intellij.psi.scope.processor.VariablesNotProcessor;
|
||||
@@ -336,7 +337,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkAssignmentOperatorApplicable(@NotNull PsiAssignmentExpression assignment) {
|
||||
static HighlightInfo checkAssignmentOperatorApplicable(@NotNull PsiAssignmentExpression assignment,@NotNull PsiFile containingFile) {
|
||||
PsiJavaToken operationSign = assignment.getOperationSign();
|
||||
IElementType eqOpSign = operationSign.getTokenType();
|
||||
IElementType opSign = TypeConversionUtil.convertEQtoOperation(eqOpSign);
|
||||
@@ -347,7 +348,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
final PsiType rType = rExpression.getType();
|
||||
HighlightInfo errorResult = null;
|
||||
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true) ||
|
||||
PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
|
||||
PsiType.getJavaLangObject(containingFile.getManager(), assignment.getResolveScope()).equals(lType)) {
|
||||
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
|
||||
String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
|
||||
JavaHighlightUtil.formatType(lType),
|
||||
@@ -845,7 +846,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkLiteralExpressionParsingError(@NotNull final PsiLiteralExpression expression) {
|
||||
public static HighlightInfo checkLiteralExpressionParsingError(@NotNull final PsiLiteralExpression expression,
|
||||
@NotNull LanguageLevel languageLevel, @NotNull PsiFile containingFile) {
|
||||
PsiElement literal = expression.getFirstChild();
|
||||
assert literal instanceof PsiJavaToken : literal;
|
||||
IElementType type = ((PsiJavaToken)literal).getTokenType();
|
||||
@@ -860,19 +862,19 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
if (isFP) {
|
||||
if (text.startsWith(PsiLiteralExpressionImpl.HEX_PREFIX)) {
|
||||
final HighlightInfo info = checkFeature(expression, Feature.HEX_FP_LITERALS);
|
||||
final HighlightInfo info = checkFeature(expression, Feature.HEX_FP_LITERALS, languageLevel, containingFile);
|
||||
if (info != null) return info;
|
||||
}
|
||||
}
|
||||
if (isInt) {
|
||||
if (text.startsWith(PsiLiteralExpressionImpl.BIN_PREFIX)) {
|
||||
final HighlightInfo info = checkFeature(expression, Feature.BIN_LITERALS);
|
||||
final HighlightInfo info = checkFeature(expression, Feature.BIN_LITERALS, languageLevel, containingFile);
|
||||
if (info != null) return info;
|
||||
}
|
||||
}
|
||||
if (isInt || isFP) {
|
||||
if (text.contains("_")) {
|
||||
HighlightInfo info = checkFeature(expression, Feature.UNDERSCORES);
|
||||
HighlightInfo info = checkFeature(expression, Feature.UNDERSCORES, languageLevel, containingFile);
|
||||
if (info != null) return info;
|
||||
info = checkUnderscores(expression, text, isInt);
|
||||
if (info != null) return info;
|
||||
@@ -1176,7 +1178,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
@Nullable
|
||||
static Collection<HighlightInfo> checkWithImprovedCatchAnalysis(@NotNull final PsiParameter parameter,
|
||||
@NotNull final Collection<PsiClassType> thrownInTryStatement) {
|
||||
@NotNull final Collection<PsiClassType> thrownInTryStatement,@NotNull PsiFile containingFile) {
|
||||
final PsiElement scope = parameter.getDeclarationScope();
|
||||
if (!(scope instanceof PsiCatchSection)) return null;
|
||||
|
||||
@@ -1186,8 +1188,10 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
if (idx <= 0) return null;
|
||||
|
||||
final Collection<PsiClassType> thrownTypes = ContainerUtil.newHashSet(thrownInTryStatement);
|
||||
thrownTypes.add(PsiType.getJavaLangError(parameter.getManager(), parameter.getResolveScope()));
|
||||
thrownTypes.add(PsiType.getJavaLangRuntimeException(parameter.getManager(), parameter.getResolveScope()));
|
||||
PsiManager manager = containingFile.getManager();
|
||||
GlobalSearchScope parameterResolveScope = parameter.getResolveScope();
|
||||
thrownTypes.add(PsiType.getJavaLangError(manager, parameterResolveScope));
|
||||
thrownTypes.add(PsiType.getJavaLangRuntimeException(manager, parameterResolveScope));
|
||||
final Collection<HighlightInfo> result = ContainerUtil.newArrayList();
|
||||
|
||||
final List<PsiTypeElement> parameterTypeElements = PsiUtil.getParameterTypeElements(parameter);
|
||||
@@ -1805,7 +1809,9 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkMemberReferencedBeforeConstructorCalled(@NotNull PsiElement expression, PsiElement resolved) {
|
||||
public static HighlightInfo checkMemberReferencedBeforeConstructorCalled(@NotNull PsiElement expression,
|
||||
PsiElement resolved,
|
||||
@NotNull PsiFile containingFile) {
|
||||
PsiClass referencedClass;
|
||||
@NonNls String resolvedName;
|
||||
PsiType type;
|
||||
@@ -1903,13 +1909,14 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
return null;
|
||||
}
|
||||
if (referencedClass == null) return null;
|
||||
return checkReferenceToOurInstanceInsideThisOrSuper(expression, referencedClass, resolvedName);
|
||||
return checkReferenceToOurInstanceInsideThisOrSuper(expression, referencedClass, resolvedName, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper(@NotNull final PsiElement expression,
|
||||
@NotNull PsiClass referencedClass,
|
||||
final String resolvedName) {
|
||||
final String resolvedName,
|
||||
@NotNull PsiFile containingFile) {
|
||||
if (PsiTreeUtil.getParentOfType(expression, PsiReferenceParameterList.class) != null) return null;
|
||||
PsiElement element = expression.getParent();
|
||||
while (element != null) {
|
||||
@@ -1958,7 +1965,16 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolve = ((PsiReferenceExpression)element).resolve();
|
||||
final PsiElement resolve;
|
||||
if (element instanceof PsiReferenceExpressionImpl) {
|
||||
PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl)element;
|
||||
JavaResolveResult[] results = JavaResolveUtil
|
||||
.resolveWithContainingFile(referenceExpression, PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, false, containingFile);
|
||||
resolve = results.length == 1 ? results[0].getElement() : null;
|
||||
}
|
||||
else {
|
||||
resolve = ((PsiReferenceExpression)element).resolve();
|
||||
}
|
||||
if (resolve instanceof PsiField && ((PsiField)resolve).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1976,8 +1992,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkImplicitThisReferenceBeforeSuper(@NotNull PsiClass aClass) {
|
||||
if (JavaVersionService.getInstance().isAtLeast(aClass, JavaSdkVersion.JDK_1_7)) return null;
|
||||
public static HighlightInfo checkImplicitThisReferenceBeforeSuper(@NotNull PsiClass aClass, @NotNull JavaSdkVersion javaSdkVersion) {
|
||||
if (javaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7)) return null;
|
||||
if (aClass instanceof PsiAnonymousClass || aClass instanceof PsiTypeParameter) return null;
|
||||
PsiClass superClass = aClass.getSuperClass();
|
||||
if (superClass == null || !PsiUtil.isInnerClass(superClass)) return null;
|
||||
@@ -2205,13 +2221,13 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkSynchronizedExpressionType(@NotNull PsiExpression expression, @Nullable PsiType type) {
|
||||
public static HighlightInfo checkSynchronizedExpressionType(@NotNull PsiExpression expression, @Nullable PsiType type,@NotNull PsiFile containingFile) {
|
||||
if (type == null) return null;
|
||||
if (expression.getParent() instanceof PsiSynchronizedStatement) {
|
||||
PsiSynchronizedStatement synchronizedStatement = (PsiSynchronizedStatement)expression.getParent();
|
||||
if (expression == synchronizedStatement.getLockExpression() &&
|
||||
(type instanceof PsiPrimitiveType || TypeConversionUtil.isNullType(type))) {
|
||||
PsiClassType objectType = PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope());
|
||||
PsiClassType objectType = PsiType.getJavaLangObject(containingFile.getManager(), expression.getResolveScope());
|
||||
return createIncompatibleTypeHighlightInfo(objectType, type, expression.getTextRange(), 0);
|
||||
}
|
||||
}
|
||||
@@ -2308,14 +2324,14 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkSingleImportClassConflict(@NotNull PsiImportStatement statement,
|
||||
@NotNull Map<String, Pair<PsiImportStaticReferenceElement, PsiClass>> importedClasses) {
|
||||
@NotNull Map<String, Pair<PsiImportStaticReferenceElement, PsiClass>> importedClasses,@NotNull PsiFile containingFile) {
|
||||
if (statement.isOnDemand()) return null;
|
||||
PsiElement element = statement.resolve();
|
||||
if (element instanceof PsiClass) {
|
||||
String name = ((PsiClass)element).getName();
|
||||
Pair<PsiImportStaticReferenceElement, PsiClass> imported = importedClasses.get(name);
|
||||
PsiClass importedClass = imported == null ? null : imported.getSecond();
|
||||
if (importedClass != null && !element.getManager().areElementsEquivalent(importedClass, element)) {
|
||||
if (importedClass != null && !containingFile.getManager().areElementsEquivalent(importedClass, element)) {
|
||||
String description = JavaErrorMessages.message("single.import.class.conflict", formatClass(importedClass));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
@@ -2378,13 +2394,16 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkReference(@NotNull final PsiJavaCodeReferenceElement ref, @NotNull final JavaResolveResult result) {
|
||||
static HighlightInfo checkReference(@NotNull final PsiJavaCodeReferenceElement ref,
|
||||
@NotNull final JavaResolveResult result,
|
||||
@NotNull PsiFile containingFile,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final PsiElement refName = ref.getReferenceNameElement();
|
||||
|
||||
if (!(refName instanceof PsiIdentifier) && !(refName instanceof PsiKeyword)) return null;
|
||||
final PsiElement resolved = result.getElement();
|
||||
|
||||
HighlightInfo highlightInfo = checkMemberReferencedBeforeConstructorCalled(ref, resolved);
|
||||
HighlightInfo highlightInfo = checkMemberReferencedBeforeConstructorCalled(ref, resolved, containingFile);
|
||||
if (highlightInfo != null) return highlightInfo;
|
||||
|
||||
PsiElement refParent = ref.getParent();
|
||||
@@ -2454,7 +2473,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
}
|
||||
if ((resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter) && !(resolved instanceof ImplicitVariable)) {
|
||||
highlightInfo = HighlightControlFlowUtil.checkVariableMustBeFinal((PsiVariable)resolved, ref);
|
||||
highlightInfo = HighlightControlFlowUtil.checkVariableMustBeFinal((PsiVariable)resolved, ref,
|
||||
languageLevel);
|
||||
}
|
||||
else if (resolved instanceof PsiClass) {
|
||||
if (Comparing.strEqual(((PsiClass)resolved).getQualifiedName(), ((PsiClass)resolved).getName())) {
|
||||
@@ -2508,7 +2528,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
@Nullable
|
||||
static HighlightInfo checkElementInReferenceList(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
@NotNull PsiReferenceList referenceList,
|
||||
@NotNull JavaResolveResult resolveResult) {
|
||||
@NotNull JavaResolveResult resolveResult,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
PsiElement resolved = resolveResult.getElement();
|
||||
HighlightInfo highlightInfo = null;
|
||||
PsiElement refGrandParent = referenceList.getParent();
|
||||
@@ -2516,7 +2537,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
PsiClass aClass = (PsiClass)resolved;
|
||||
if (refGrandParent instanceof PsiClass) {
|
||||
if (refGrandParent instanceof PsiTypeParameter) {
|
||||
highlightInfo = GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, (PsiClass)refGrandParent, resolveResult, ref);
|
||||
highlightInfo = GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, (PsiClass)refGrandParent, resolveResult, ref, languageLevel);
|
||||
}
|
||||
else {
|
||||
highlightInfo = HighlightClassUtil.checkExtendsClassAndImplementsInterface(referenceList, resolveResult, ref);
|
||||
@@ -2630,8 +2651,11 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkFeature(@Nullable final PsiElement element, @NotNull final Feature feature) {
|
||||
if (element != null && element.getManager().isInProject(element) && !PsiUtil.getLanguageLevel(element).isAtLeast(feature.level)) {
|
||||
private static HighlightInfo checkFeature(@NotNull final PsiElement element,
|
||||
@NotNull Feature feature,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull PsiFile containingFile) {
|
||||
if (containingFile.getManager().isInProject(containingFile) && !languageLevel.isAtLeast(feature.level)) {
|
||||
String message = JavaErrorMessages.message("insufficient.language.level", JavaErrorMessages.message(feature.key));
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(message).create();
|
||||
QuickFixAction.registerQuickFixAction(info, new IncreaseLanguageLevelFix(feature.level));
|
||||
@@ -2643,62 +2667,69 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkGenericsFeature(PsiElement parameterList, int listSize) {
|
||||
return listSize > 0 ? checkFeature(parameterList, Feature.GENERICS) : null;
|
||||
public static HighlightInfo checkGenericsFeature(@NotNull PsiElement parameterList,
|
||||
int listSize,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull PsiFile containingFile) {
|
||||
return listSize > 0 ? checkFeature(parameterList, Feature.GENERICS, languageLevel, containingFile) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkAnnotationFeature(PsiElement element) {
|
||||
return checkFeature(element, Feature.ANNOTATIONS);
|
||||
public static HighlightInfo checkAnnotationFeature(@NotNull PsiElement element,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull PsiFile containingFile) {
|
||||
return checkFeature(element, Feature.ANNOTATIONS, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkForEachFeature(PsiForeachStatement statement) {
|
||||
return checkFeature(statement, Feature.FOR_EACH);
|
||||
public static HighlightInfo checkForEachFeature(@NotNull PsiForeachStatement statement, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(statement, Feature.FOR_EACH, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkStaticImportFeature(PsiImportStaticStatement statement) {
|
||||
return checkFeature(statement, Feature.STATIC_IMPORTS);
|
||||
public static HighlightInfo checkStaticImportFeature(@NotNull PsiImportStaticStatement statement, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(statement, Feature.STATIC_IMPORTS, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkVarargFeature(PsiParameter parameter) {
|
||||
return checkFeature(parameter, Feature.VARARGS);
|
||||
public static HighlightInfo checkVarargFeature(@NotNull PsiParameter parameter, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(parameter, Feature.VARARGS, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkDiamondFeature(PsiTypeElement typeElement) {
|
||||
return typeElement.getType() instanceof PsiDiamondType ? checkFeature(typeElement.getParent(), Feature.DIAMOND_TYPES) : null;
|
||||
public static HighlightInfo checkDiamondFeature(@NotNull PsiTypeElement typeElement, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return typeElement.getType() instanceof PsiDiamondType ? checkFeature(typeElement.getParent(), Feature.DIAMOND_TYPES,
|
||||
languageLevel, containingFile) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkMultiCatchFeature(PsiParameter parameter) {
|
||||
return parameter.getType() instanceof PsiDisjunctionType ? checkFeature(parameter, Feature.MULTI_CATCH) : null;
|
||||
public static HighlightInfo checkMultiCatchFeature(@NotNull PsiParameter parameter, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return parameter.getType() instanceof PsiDisjunctionType ? checkFeature(parameter, Feature.MULTI_CATCH,
|
||||
languageLevel, containingFile) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkTryWithResourcesFeature(PsiResourceVariable resourceVariable) {
|
||||
return checkFeature(resourceVariable.getParent(), Feature.TRY_WITH_RESOURCES);
|
||||
public static HighlightInfo checkTryWithResourcesFeature(@NotNull PsiResourceVariable resourceVariable, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(resourceVariable.getParent(), Feature.TRY_WITH_RESOURCES, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkExtensionMethodsFeature(PsiMethod method) {
|
||||
return checkFeature(method, Feature.EXTENSION_METHODS);
|
||||
public static HighlightInfo checkExtensionMethodsFeature(@NotNull PsiMethod method, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(method, Feature.EXTENSION_METHODS, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkMethodReferencesFeature(PsiMethodReferenceExpression expression) {
|
||||
return checkFeature(expression, Feature.METHOD_REFERENCES);
|
||||
public static HighlightInfo checkMethodReferencesFeature(@NotNull PsiMethodReferenceExpression expression, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(expression, Feature.METHOD_REFERENCES, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkLambdaFeature(PsiLambdaExpression expression) {
|
||||
return checkFeature(expression, Feature.LAMBDA_EXPRESSIONS);
|
||||
public static HighlightInfo checkLambdaFeature(@NotNull PsiLambdaExpression expression, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(expression, Feature.LAMBDA_EXPRESSIONS, languageLevel, containingFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkTypeAnnotationFeature(PsiAnnotation annotation) {
|
||||
return checkFeature(annotation, Feature.TYPE_ANNOTATIONS);
|
||||
public static HighlightInfo checkTypeAnnotationFeature(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel,@NotNull PsiFile containingFile) {
|
||||
return checkFeature(annotation, Feature.TYPE_ANNOTATIONS, languageLevel, containingFile);
|
||||
}
|
||||
}
|
||||
|
||||
+144
-81
@@ -23,25 +23,28 @@ import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.SetupJDKFix;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesScheme;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersionUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.ControlFlowUtil;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
@@ -82,6 +85,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
};
|
||||
private final Map<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>> myDuplicateMethods = new THashMap<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>>();
|
||||
private LanguageLevel myLanguageLevel;
|
||||
private JavaSdkVersion myJavaSdkVersion;
|
||||
|
||||
public HighlightVisitorImpl(@NotNull PsiResolveHelper resolveHelper) {
|
||||
myResolveHelper = resolveHelper;
|
||||
@@ -142,6 +147,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myHolder = holder;
|
||||
boolean success = true;
|
||||
try {
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(file);
|
||||
myJavaSdkVersion = ObjectUtils.notNull(JavaSdkVersionUtil.getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
|
||||
if (updateWholeFile) {
|
||||
Project project = file.getProject();
|
||||
DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
|
||||
@@ -194,14 +201,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override
|
||||
public void visitAnnotation(PsiAnnotation annotation) {
|
||||
super.visitAnnotation(annotation);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationFeature(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationFeature(annotation, myLanguageLevel, myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation));
|
||||
}
|
||||
|
||||
@@ -227,7 +234,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitAnnotationMethod(PsiAnnotationMethod method) {
|
||||
@Override
|
||||
public void visitAnnotationMethod(PsiAnnotationMethod method) {
|
||||
PsiType returnType = method.getReturnType();
|
||||
PsiAnnotationMemberValue value = method.getDefaultValue();
|
||||
if (returnType != null && value != null) {
|
||||
@@ -239,7 +247,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method));
|
||||
}
|
||||
|
||||
@Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
super.visitArrayInitializerExpression(expression);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkArrayInitializerApplicable(expression));
|
||||
if (!(expression.getParent() instanceof PsiNewExpression)) {
|
||||
@@ -247,9 +256,10 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentCompatibleTypes(assignment));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment,myFile));
|
||||
if (!myHolder.hasErrorResults()) visitExpression(assignment);
|
||||
}
|
||||
|
||||
@@ -261,7 +271,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
myHolder.add(HighlightUtil.checkLambdaFeature(expression));
|
||||
myHolder.add(HighlightUtil.checkLambdaFeature(expression, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
if (LambdaUtil.isValidLambdaContext(expression.getParent())) {
|
||||
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
|
||||
@@ -356,11 +366,12 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass));
|
||||
}
|
||||
|
||||
@Override public void visitClassInitializer(PsiClassInitializer initializer) {
|
||||
@Override
|
||||
public void visitClassInitializer(PsiClassInitializer initializer) {
|
||||
super.visitClassInitializer(initializer);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkInitializerCompleteNormally(initializer));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(initializer.getBody()));
|
||||
@@ -369,25 +380,29 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
super.visitClassObjectAccessExpression(expression);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkClassObjectAccessExpression(expression));
|
||||
}
|
||||
|
||||
@Override public void visitComment(PsiComment comment) {
|
||||
@Override
|
||||
public void visitComment(PsiComment comment) {
|
||||
super.visitComment(comment);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
|
||||
if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(comment);
|
||||
}
|
||||
|
||||
@Override public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
@Override
|
||||
public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
super.visitContinueStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findContinuedStatement()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitJavaToken(PsiJavaToken token) {
|
||||
@Override
|
||||
public void visitJavaToken(PsiJavaToken token) {
|
||||
super.visitJavaToken(token);
|
||||
if (!myHolder.hasErrorResults()
|
||||
&& token.getTokenType() == JavaTokenType.RBRACE
|
||||
@@ -400,24 +415,27 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
PsiMethod method = (PsiMethod)gParent;
|
||||
codeBlock = method.getBody();
|
||||
returnType = method.getReturnType();
|
||||
} else if (gParent instanceof PsiLambdaExpression) {
|
||||
}
|
||||
else if (gParent instanceof PsiLambdaExpression) {
|
||||
final PsiElement body = ((PsiLambdaExpression)gParent).getBody();
|
||||
if (!(body instanceof PsiCodeBlock)) return;
|
||||
codeBlock = (PsiCodeBlock)body;
|
||||
returnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)gParent);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(codeBlock, returnType));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override public void visitDocComment(PsiDocComment comment) {
|
||||
@Override
|
||||
public void visitDocComment(PsiDocComment comment) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
|
||||
}
|
||||
|
||||
@Override public void visitDocTagValue(PsiDocTagValue value) {
|
||||
@Override
|
||||
public void visitDocTagValue(PsiDocTagValue value) {
|
||||
PsiReference reference = value.getReference();
|
||||
if (reference != null) {
|
||||
PsiElement element = reference.resolve();
|
||||
@@ -432,13 +450,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitEnumConstant(PsiEnumConstant enumConstant) {
|
||||
@Override
|
||||
public void visitEnumConstant(PsiEnumConstant enumConstant) {
|
||||
super.visitEnumConstant(enumConstant);
|
||||
if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder);
|
||||
if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder, myJavaSdkVersion);
|
||||
if (!myHolder.hasErrorResults()) registerConstructorCall(enumConstant);
|
||||
}
|
||||
|
||||
@Override public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) {
|
||||
@Override
|
||||
public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) {
|
||||
super.visitEnumConstantInitializer(enumConstantInitializer);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(enumConstantInitializer);
|
||||
@@ -446,29 +466,30 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitExpression(PsiExpression expression) {
|
||||
@Override
|
||||
public void visitExpression(PsiExpression expression) {
|
||||
ProgressManager.checkCanceled(); // visitLiteralExpression is invoked very often in array initializers
|
||||
|
||||
super.visitExpression(expression);
|
||||
PsiType type = expression.getType();
|
||||
if (myHolder.add(HighlightUtil.checkMustBeBoolean(expression, type))) return;
|
||||
|
||||
if(expression instanceof PsiArrayAccessExpression) {
|
||||
if (expression instanceof PsiArrayAccessExpression) {
|
||||
myHolder.add(HighlightUtil.checkValidArrayAccessExpression((PsiArrayAccessExpression)expression));
|
||||
}
|
||||
|
||||
if (expression.getParent() instanceof PsiNewExpression
|
||||
&& ((PsiNewExpression)expression.getParent()).getQualifier() != expression
|
||||
&& ((PsiNewExpression)expression.getParent()).getArrayInitializer() != expression) {
|
||||
&& ((PsiNewExpression)expression.getParent()).getQualifier() != expression
|
||||
&& ((PsiNewExpression)expression.getParent()).getArrayInitializer() != expression) {
|
||||
// like in 'new String["s"]'
|
||||
myHolder.add(HighlightUtil.checkAssignability(PsiType.INT, expression.getType(), expression, expression));
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableExpected(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkArrayInitializer(expression, type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression, type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression, type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression, type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression, type,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression, type));
|
||||
if (!myHolder.hasErrorResults()
|
||||
&& expression.getParent() instanceof PsiThrowStatement
|
||||
@@ -494,12 +515,12 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitForeachStatement(final PsiForeachStatement statement) {
|
||||
myHolder.add(HighlightUtil.checkForEachFeature(statement));
|
||||
myHolder.add(HighlightUtil.checkForEachFeature(statement, myLanguageLevel,myFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitImportStaticStatement(final PsiImportStaticStatement statement) {
|
||||
myHolder.add(HighlightUtil.checkStaticImportFeature(statement));
|
||||
myHolder.add(HighlightUtil.checkStaticImportFeature(statement, myLanguageLevel,myFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -530,7 +551,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
else if (parent instanceof PsiClass) {
|
||||
PsiClass aClass = (PsiClass)parent;
|
||||
if (aClass.isAnnotationType()) {
|
||||
myHolder.add(HighlightUtil.checkAnnotationFeature(identifier));
|
||||
myHolder.add(HighlightUtil.checkAnnotationFeature(identifier, myLanguageLevel, myFile));
|
||||
}
|
||||
|
||||
myHolder.add(HighlightClassUtil.checkClassAlreadyImported(aClass, identifier));
|
||||
@@ -562,7 +583,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
catch (IndexNotReadyException e) {
|
||||
return;
|
||||
}
|
||||
myHolder.add(HighlightUtil.checkReference(ref, result));
|
||||
myHolder.add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel));
|
||||
if (myRefCountHolder != null) {
|
||||
myRefCountHolder.registerReference(ref, result);
|
||||
}
|
||||
@@ -572,7 +593,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override
|
||||
public void visitImportStatement(final PsiImportStatement statement) {
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses));
|
||||
myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses,myFile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,13 +647,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
|
||||
@Override
|
||||
public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
|
||||
super.visitInstanceOfExpression(expression);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInstanceOfApplicable(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(expression));
|
||||
}
|
||||
|
||||
@Override public void visitKeyword(PsiKeyword keyword) {
|
||||
@Override
|
||||
public void visitKeyword(PsiKeyword keyword) {
|
||||
super.visitKeyword(keyword);
|
||||
PsiElement parent = keyword.getParent();
|
||||
String text = keyword.getText();
|
||||
@@ -670,25 +693,28 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitLabeledStatement(PsiLabeledStatement statement) {
|
||||
@Override
|
||||
public void visitLabeledStatement(PsiLabeledStatement statement) {
|
||||
super.visitLabeledStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelWithoutStatement(statement));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelAlreadyInUse(statement));
|
||||
}
|
||||
|
||||
@Override public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
@Override
|
||||
public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
super.visitLiteralExpression(expression);
|
||||
if (myHolder.hasErrorResults()) return;
|
||||
myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression));
|
||||
myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel,myFile));
|
||||
if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(expression);
|
||||
}
|
||||
|
||||
@Override public void visitMethod(PsiMethod method) {
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody()));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkOverrideAnnotation(method));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkOverrideAnnotation(method, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method));
|
||||
if (!myHolder.hasErrorResults() && method.isConstructor()) {
|
||||
myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, method.getContainingClass()));
|
||||
@@ -753,13 +779,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression));
|
||||
// in case of JSP synthetic method call, do not check
|
||||
if (expression.getMethodExpression().isPhysical() && !myHolder.hasErrorResults()) {
|
||||
if (myFile.isPhysical() && !myHolder.hasErrorResults()) {
|
||||
try {
|
||||
myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper));
|
||||
myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel,myJavaSdkVersion));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
@@ -774,7 +801,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
PsiElement parent = list.getParent();
|
||||
if (parent instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)parent;
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel,myFile));
|
||||
MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
|
||||
if (!method.isConstructor()) {
|
||||
try {
|
||||
@@ -795,7 +822,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method,myFile));
|
||||
}
|
||||
else if (parent instanceof PsiClass) {
|
||||
PsiClass aClass = (PsiClass)parent;
|
||||
@@ -820,7 +847,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitNameValuePair(PsiNameValuePair pair) {
|
||||
@Override
|
||||
public void visitNameValuePair(PsiNameValuePair pair) {
|
||||
myHolder.add(AnnotationsHighlightUtil.checkNameValuePair(pair));
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
PsiIdentifier nameId = pair.getNameIdentifier();
|
||||
@@ -831,14 +859,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitNewExpression(PsiNewExpression expression) {
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, myHolder);
|
||||
if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, myHolder, myJavaSdkVersion);
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
@@ -861,13 +890,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
final PsiElement parent = parameter.getParent();
|
||||
if (parent instanceof PsiParameterList) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter,
|
||||
myLanguageLevel,myFile));
|
||||
}
|
||||
else if (parent instanceof PsiForeachStatement) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkForeachLoopParameterType((PsiForeachStatement)parent));
|
||||
}
|
||||
else if (parent instanceof PsiCatchSection) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMultiCatchFeature(parameter));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMultiCatchFeature(parameter, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
|
||||
if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
|
||||
if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkCatchTypeIsDisjoint(parameter));
|
||||
@@ -880,14 +910,16 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationMethodParameters(list));
|
||||
}
|
||||
|
||||
@Override public void visitPostfixExpression(PsiPostfixExpression expression) {
|
||||
@Override
|
||||
public void visitPostfixExpression(PsiPostfixExpression expression) {
|
||||
super.visitPostfixExpression(expression);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitPrefixExpression(PsiPrefixExpression expression) {
|
||||
@Override
|
||||
public void visitPrefixExpression(PsiPrefixExpression expression) {
|
||||
super.visitPrefixExpression(expression);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
|
||||
@@ -912,7 +944,17 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
|
||||
JavaResolveResult result;
|
||||
try {
|
||||
result = ref.advancedResolve(true);
|
||||
if (ref instanceof PsiReferenceExpressionImpl) {
|
||||
PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl)ref;
|
||||
JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(referenceExpression,
|
||||
PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE,
|
||||
true, true,
|
||||
myFile);
|
||||
result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
}
|
||||
else {
|
||||
result = ref.advancedResolve(true);
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
return null;
|
||||
@@ -924,9 +966,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (myRefCountHolder != null) {
|
||||
myRefCountHolder.registerReference(ref, result);
|
||||
}
|
||||
myHolder.add(HighlightUtil.checkReference(ref, result));
|
||||
myHolder.add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults() && resolved instanceof PsiTypeParameter) {
|
||||
boolean cannotSelectFromTypeParameter = !JavaVersionService.getInstance().isAtLeast(ref, JavaSdkVersion.JDK_1_7);
|
||||
boolean cannotSelectFromTypeParameter = !myJavaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7);
|
||||
if (!cannotSelectFromTypeParameter) {
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
|
||||
if (containingClass != null) {
|
||||
@@ -942,17 +984,18 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAbstractInstantiation(ref, resolved));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsForeignInnerClass(ref, resolved));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref,
|
||||
result.getSubstitutor()));
|
||||
result.getSubstitutor(),
|
||||
myJavaSdkVersion));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
|
||||
|
||||
if (resolved != null && parent instanceof PsiReferenceList) {
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
PsiReferenceList referenceList = (PsiReferenceList)parent;
|
||||
myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result));
|
||||
myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result, myLanguageLevel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,7 +1072,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
visitExpression(expression);
|
||||
@@ -1038,7 +1082,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
JavaResolveResult result;
|
||||
JavaResolveResult[] results;
|
||||
try {
|
||||
results = expression.multiResolve(true);
|
||||
if (expression instanceof PsiReferenceExpressionImpl) {
|
||||
PsiReferenceExpressionImpl referenceExpression = (PsiReferenceExpressionImpl)expression;
|
||||
results = JavaResolveUtil.resolveWithContainingFile(referenceExpression,
|
||||
PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true,
|
||||
myFile);
|
||||
}
|
||||
else {
|
||||
results = expression.multiResolve(true);
|
||||
}
|
||||
result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
@@ -1048,7 +1100,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
try {
|
||||
myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems));
|
||||
myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems,myFile));
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
@@ -1091,7 +1143,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
|
||||
myHolder.add(HighlightUtil.checkMethodReferencesFeature(expression));
|
||||
myHolder.add(HighlightUtil.checkMethodReferencesFeature(expression, myLanguageLevel,myFile));
|
||||
JavaResolveResult result;
|
||||
try {
|
||||
result = expression.advancedResolve(true);
|
||||
@@ -1166,51 +1218,59 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitReferenceParameterList(PsiReferenceParameterList list) {
|
||||
myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list));
|
||||
myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(list));
|
||||
}
|
||||
|
||||
@Override public void visitReturnStatement(PsiReturnStatement statement) {
|
||||
@Override
|
||||
public void visitReturnStatement(PsiReturnStatement statement) {
|
||||
try {
|
||||
myHolder.add(HighlightUtil.checkReturnStatementType(statement));
|
||||
}
|
||||
catch (IndexNotReadyException ignore) { }
|
||||
catch (IndexNotReadyException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitStatement(PsiStatement statement) {
|
||||
@Override
|
||||
public void visitStatement(PsiStatement statement) {
|
||||
super.visitStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAStatement(statement));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkStatementPrependedWithCaseInsideSwitch(statement));
|
||||
}
|
||||
|
||||
@Override public void visitSuperExpression(PsiSuperExpression expr) {
|
||||
@Override
|
||||
public void visitSuperExpression(PsiSuperExpression expr) {
|
||||
myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkAbstractMethodDirectCall(expr));
|
||||
if (!myHolder.hasErrorResults()) visitExpression(expr);
|
||||
}
|
||||
|
||||
@Override public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
|
||||
@Override
|
||||
public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
|
||||
super.visitSwitchLabelStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCaseStatement(statement));
|
||||
}
|
||||
|
||||
@Override public void visitSwitchStatement(PsiSwitchStatement statement) {
|
||||
@Override
|
||||
public void visitSwitchStatement(PsiSwitchStatement statement) {
|
||||
super.visitSwitchStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement));
|
||||
}
|
||||
|
||||
@Override public void visitThisExpression(PsiThisExpression expr) {
|
||||
@Override
|
||||
public void visitThisExpression(PsiThisExpression expr) {
|
||||
myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null));
|
||||
myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile));
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
visitExpression(expr);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitThrowStatement(PsiThrowStatement statement) {
|
||||
@Override
|
||||
public void visitThrowStatement(PsiThrowStatement statement) {
|
||||
myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
|
||||
if (!myHolder.hasErrorResults()) visitStatement(statement);
|
||||
}
|
||||
@@ -1226,7 +1286,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
added = myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter, thrownTypes));
|
||||
}
|
||||
if (!added) {
|
||||
myHolder.addAll(HighlightUtil.checkWithImprovedCatchAnalysis(parameter, thrownTypes));
|
||||
myHolder.addAll(HighlightUtil.checkWithImprovedCatchAnalysis(parameter, thrownTypes,myFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1235,20 +1295,21 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override
|
||||
public void visitResourceVariable(final PsiResourceVariable resourceVariable) {
|
||||
visitVariable(resourceVariable);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryWithResourcesFeature(resourceVariable));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryWithResourcesFeature(resourceVariable, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resourceVariable));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resourceVariable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeElement(final PsiTypeElement type) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkDiamondFeature(type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkDiamondFeature(type, myLanguageLevel,myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
|
||||
}
|
||||
|
||||
@Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
|
||||
@Override
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
|
||||
super.visitTypeCastExpression(typeCast);
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
|
||||
@@ -1257,11 +1318,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitTypeParameterList(PsiTypeParameterList list) {
|
||||
myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list));
|
||||
@Override
|
||||
public void visitTypeParameterList(PsiTypeParameterList list) {
|
||||
myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list, myLanguageLevel,myFile));
|
||||
}
|
||||
|
||||
@Override public void visitVariable(PsiVariable variable) {
|
||||
@Override
|
||||
public void visitVariable(PsiVariable variable) {
|
||||
super.visitVariable(variable);
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public class BringVariableIntoScopeFix implements IntentionAction {
|
||||
myOutOfScopeVariable.delete();
|
||||
}
|
||||
|
||||
if (HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(myUnresolvedReference, addedVar, new THashMap<PsiElement, Collection<PsiReferenceExpression>>()) != null) {
|
||||
if (HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(myUnresolvedReference, addedVar, new THashMap<PsiElement, Collection<PsiReferenceExpression>>(),file) != null) {
|
||||
initialize(addedVar);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -312,7 +312,8 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
|
||||
Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems = new THashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>();
|
||||
for (PsiReferenceExpression expression : references) {
|
||||
if (ControlFlowUtil.isVariableAssignedInLoop(expression, variable)) return false;
|
||||
HighlightInfo highlightInfo = HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, variable, uninitializedVarProblems);
|
||||
HighlightInfo highlightInfo = HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, variable, uninitializedVarProblems,
|
||||
variable.getContainingFile());
|
||||
if (highlightInfo != null) return false;
|
||||
highlightInfo = HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, finalVarProblems);
|
||||
if (highlightInfo != null) return false;
|
||||
|
||||
+5
-2
@@ -18,10 +18,12 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersionUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -38,8 +40,9 @@ public class VariableParameterizedTypeFix {
|
||||
PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(parameterList.getProject());
|
||||
PsiClass[] classes = shortNamesCache.getClassesByName(shortName, GlobalSearchScope.allScope(manager.getProject()));
|
||||
PsiElementFactory factory = facade.getElementFactory();
|
||||
JavaSdkVersion version = JavaSdkVersionUtil.getJavaSdkVersion(parameterList);
|
||||
for (PsiClass aClass : classes) {
|
||||
if (GenericsHighlightUtil.checkReferenceTypeArgumentList(aClass, parameterList, PsiSubstitutor.EMPTY, false) == null) {
|
||||
if (GenericsHighlightUtil.checkReferenceTypeArgumentList(aClass, parameterList, PsiSubstitutor.EMPTY, false, version) == null) {
|
||||
PsiType[] actualTypeParameters = parameterList.getTypeArguments();
|
||||
PsiTypeParameter[] classTypeParameters = aClass.getTypeParameters();
|
||||
HashMap<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
|
||||
|
||||
@@ -15,36 +15,16 @@
|
||||
*/
|
||||
package com.intellij.openapi.projectRoots;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
* @since 3/28/12
|
||||
*/
|
||||
public class JavaVersionServiceImpl extends JavaVersionService {
|
||||
private JavaSdkVersion myTestVersion = JavaSdkVersion.JDK_1_7;
|
||||
|
||||
@TestOnly
|
||||
public void setTestVersion(@Nullable JavaSdkVersion testVersion, Disposable parentDisposable) {
|
||||
myTestVersion = testVersion;
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myTestVersion = JavaSdkVersion.JDK_1_7;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAtLeast(PsiElement element, JavaSdkVersion version) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return myTestVersion != null && myTestVersion.isAtLeast(version);
|
||||
}
|
||||
public boolean isAtLeast(@NotNull PsiElement element, @NotNull JavaSdkVersion version) {
|
||||
return JavaSdkVersionUtil.isAtLeast(element, version);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -72,7 +72,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
return myModificationCounter;
|
||||
}
|
||||
|
||||
private static Pair<PsiElement,PsiElement[]> computeAnchorAndOperandsImpl(PsiElement context) {
|
||||
private static Pair<PsiElement,PsiElement[]> computeAnchorAndOperandsImpl(@NotNull PsiElement context) {
|
||||
PsiElement element = context;
|
||||
PsiElement parent = context.getParent();
|
||||
while (parent instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)parent).getOperationTokenType() == JavaTokenType.PLUS
|
||||
@@ -102,8 +102,12 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
|
||||
return Pair.create(anchor, operands);
|
||||
}
|
||||
private static MultiHostRegistrarImpl doCompute(PsiElement context, Project project, PsiElement anchor, PsiElement[] operands) {
|
||||
MultiHostRegistrarImpl registrar = new MultiHostRegistrarImpl(project, context.getContainingFile(), anchor);
|
||||
|
||||
private static MultiHostRegistrarImpl doCompute(@NotNull PsiFile containingFile,
|
||||
@NotNull Project project,
|
||||
@NotNull PsiElement anchor,
|
||||
@NotNull PsiElement[] operands) {
|
||||
MultiHostRegistrarImpl registrar = new MultiHostRegistrarImpl(project, containingFile, anchor);
|
||||
JavaConcatenationInjectorManager concatenationInjectorManager = getInstance(project);
|
||||
for (ConcatenationAwareInjector concatenationInjector : concatenationInjectorManager.myConcatenationInjectors) {
|
||||
concatenationInjector.getLanguagesToInject(registrar, operands);
|
||||
@@ -119,7 +123,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
private static final Key<ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement>> INJECTED_PSI_IN_CONCATENATION = Key.create("INJECTED_PSI_IN_CONCATENATION");
|
||||
private static final Key<Integer> NO_CONCAT_INJECTION_TIMESTAMP = Key.create("NO_CONCAT_INJECTION_TIMESTAMP");
|
||||
|
||||
public static abstract class BaseConcatenation2InjectorAdapter implements MultiHostInjector {
|
||||
public abstract static class BaseConcatenation2InjectorAdapter implements MultiHostInjector {
|
||||
private final JavaConcatenationInjectorManager myManager;
|
||||
|
||||
public BaseConcatenation2InjectorAdapter(Project project) {
|
||||
@@ -130,7 +134,8 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
|
||||
if (myManager.myConcatenationInjectors.isEmpty()) return;
|
||||
|
||||
Project project = context.getProject();
|
||||
final PsiFile containingFile = ((MultiHostRegistrarImpl)registrar).getHostPsiFile();
|
||||
Project project = containingFile.getProject();
|
||||
long modificationCount = PsiManager.getInstance(project).getModificationTracker().getModificationCount();
|
||||
Pair<PsiElement, PsiElement[]> pair = computeAnchorAndOperands(context);
|
||||
PsiElement anchor = pair.first;
|
||||
@@ -146,7 +151,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
data = anchor.getUserData(INJECTED_PSI_IN_CONCATENATION);
|
||||
|
||||
if (data == null) {
|
||||
result = doCompute(context, project, anchor, operands);
|
||||
result = doCompute(containingFile, project, anchor, operands);
|
||||
}
|
||||
else {
|
||||
result = data.getValue(context);
|
||||
@@ -164,10 +169,11 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
new ParameterizedCachedValueProvider<MultiHostRegistrarImpl, PsiElement>() {
|
||||
@Override
|
||||
public CachedValueProvider.Result<MultiHostRegistrarImpl> compute(PsiElement context) {
|
||||
Project project = context.getProject();
|
||||
PsiFile containingFile1 = context.getContainingFile();
|
||||
Project project1 = containingFile1.getProject();
|
||||
Pair<PsiElement, PsiElement[]> pair = computeAnchorAndOperands(context);
|
||||
MultiHostRegistrarImpl registrar = doCompute(context, project, pair.first, pair.second);
|
||||
return registrar == null ? null : CachedValueProvider.Result.create(registrar, PsiModificationTracker.MODIFICATION_COUNT, getInstance(project));
|
||||
MultiHostRegistrarImpl registrar = doCompute(containingFile1, project1, pair.first, pair.second);
|
||||
return registrar == null ? null : CachedValueProvider.Result.create(registrar, PsiModificationTracker.MODIFICATION_COUNT, getInstance(project1));
|
||||
}
|
||||
}, false);
|
||||
((PsiParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement>)data).setValue(cachedResult);
|
||||
@@ -187,7 +193,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Pair<PsiElement, PsiElement[]> computeAnchorAndOperands(PsiElement context);
|
||||
protected abstract Pair<PsiElement, PsiElement[]> computeAnchorAndOperands(@NotNull PsiElement context);
|
||||
}
|
||||
|
||||
public static class Concatenation2InjectorAdapter extends BaseConcatenation2InjectorAdapter implements MultiHostInjector {
|
||||
@@ -197,7 +203,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<PsiElement, PsiElement[]> computeAnchorAndOperands(PsiElement context) {
|
||||
public Pair<PsiElement, PsiElement[]> computeAnchorAndOperands(@NotNull PsiElement context) {
|
||||
return computeAnchorAndOperandsImpl(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,11 +47,12 @@ public class JavaMethodResolveHelper {
|
||||
private final MethodCandidatesProcessor myProcessor;
|
||||
@Nullable private final PsiType[] myArgumentTypes;
|
||||
|
||||
public JavaMethodResolveHelper(final PsiElement argumentList, @Nullable final PsiType[] argumentTypes) {
|
||||
public JavaMethodResolveHelper(@NotNull final PsiElement argumentList, PsiFile containingFile, @Nullable final PsiType[] argumentTypes) {
|
||||
myArgumentTypes = argumentTypes;
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(argumentList);
|
||||
final PsiConflictResolver resolver = argumentTypes == null ? DuplicateConflictResolver.INSTANCE : new JavaMethodsConflictResolver(argumentList, argumentTypes);
|
||||
myProcessor = new MethodResolverProcessor(argumentList, new PsiConflictResolver[]{resolver}) {
|
||||
final PsiConflictResolver resolver = argumentTypes == null ? DuplicateConflictResolver.INSTANCE : new JavaMethodsConflictResolver(argumentList, argumentTypes,
|
||||
languageLevel);
|
||||
myProcessor = new MethodResolverProcessor(argumentList, containingFile, new PsiConflictResolver[]{resolver}) {
|
||||
@Override
|
||||
protected MethodCandidateInfo createCandidateInfo(final PsiMethod method, final PsiSubstitutor substitutor,
|
||||
final boolean staticProblem,
|
||||
@@ -74,7 +75,8 @@ public class JavaMethodResolveHelper {
|
||||
PsiElement currentFileContext,
|
||||
boolean accessProblem,
|
||||
PsiElement argumentList,
|
||||
PsiType[] argumentTypes, LanguageLevel languageLevel) {
|
||||
PsiType[] argumentTypes,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
return new MethodCandidateInfo(method, substitutor, accessProblem, staticProblem, argumentList, currentFileContext, argumentTypes,
|
||||
PsiType.EMPTY_ARRAY, languageLevel);
|
||||
}
|
||||
|
||||
@@ -71,4 +71,17 @@ public enum JavaSdkVersion {
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JavaSdkVersion fromLanguageLevel(@NotNull LanguageLevel languageLevel) throws IllegalArgumentException {
|
||||
JavaSdkVersion[] values = values();
|
||||
for (int i = values.length - 1; i >= 0; i--) {
|
||||
JavaSdkVersion version = values[i];
|
||||
if (version.getMaxLanguageLevel().isAtLeast(languageLevel)) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Can't map Java SDK by language level "+languageLevel+". Available values: "+ Arrays.toString(values())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class LambdaUtil {
|
||||
public static PsiType getFunctionalInterfaceReturnType(PsiLambdaExpression expr) {
|
||||
return getFunctionalInterfaceReturnType(expr.getFunctionalInterfaceType());
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static PsiType getFunctionalInterfaceReturnType(@Nullable PsiType functionalInterfaceType) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
@@ -416,7 +416,7 @@ public class LambdaUtil {
|
||||
PsiElement parent = expression.getParent();
|
||||
PsiElement element = expression;
|
||||
while (parent instanceof PsiParenthesizedExpression || parent instanceof PsiConditionalExpression) {
|
||||
if (parent instanceof PsiConditionalExpression &&
|
||||
if (parent instanceof PsiConditionalExpression &&
|
||||
((PsiConditionalExpression)parent).getThenExpression() != element &&
|
||||
((PsiConditionalExpression)parent).getElseExpression() != element) break;
|
||||
element = parent;
|
||||
@@ -679,7 +679,7 @@ public class LambdaUtil {
|
||||
enum TypeKind {
|
||||
PRIMITIVE, REFERENCE, NONE_DETERMINED
|
||||
}
|
||||
|
||||
|
||||
private static int isMoreSpecific(PsiType returnType, PsiType returnType1, PsiType lambdaType) {
|
||||
if (returnType == PsiType.VOID || returnType1 == PsiType.VOID) return 0;
|
||||
TypeKind typeKind = TypeKind.PRIMITIVE;
|
||||
@@ -776,8 +776,8 @@ public class LambdaUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String checkFunctionalInterface(PsiAnnotation annotation) {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(annotation) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) {
|
||||
public static String checkFunctionalInterface(@NotNull PsiAnnotation annotation, @NotNull LanguageLevel languageLevel) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) {
|
||||
final PsiAnnotationOwner owner = annotation.getOwner();
|
||||
if (owner instanceof PsiModifierList) {
|
||||
final PsiElement parent = ((PsiModifierList)owner).getParent();
|
||||
@@ -789,8 +789,10 @@ public class LambdaUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression) {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(methodReferenceExpression)) {
|
||||
public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method,
|
||||
@NotNull PsiReferenceExpression methodReferenceExpression,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
@@ -800,7 +802,7 @@ public class LambdaUtil {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
|
||||
private PsiMethod myMethod;
|
||||
private final PsiClass myClass;
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PsiMethodReferenceUtil {
|
||||
public static ThreadLocal<Map<PsiMethodReferenceExpression, PsiType>> ourRefs = new ThreadLocal<Map<PsiMethodReferenceExpression, PsiType>>();
|
||||
|
||||
public static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceUtil.class.getName());
|
||||
|
||||
|
||||
public static class QualifierResolveResult {
|
||||
private final PsiClass myContainingClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
@@ -72,7 +72,8 @@ public class PsiMethodReferenceUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static QualifierResolveResult getQualifierResolveResult(PsiMethodReferenceExpression methodReferenceExpression) {
|
||||
@NotNull
|
||||
public static QualifierResolveResult getQualifierResolveResult(@NotNull PsiMethodReferenceExpression methodReferenceExpression) {
|
||||
PsiClass containingClass = null;
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final PsiExpression expression = methodReferenceExpression.getQualifierExpression();
|
||||
@@ -106,7 +107,7 @@ public class PsiMethodReferenceUtil {
|
||||
}
|
||||
return new QualifierResolveResult(containingClass, substitutor, false);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
|
||||
if (methodReferenceExpression == null) return false;
|
||||
if (left instanceof PsiIntersectionType) {
|
||||
@@ -145,7 +146,7 @@ public class PsiMethodReferenceUtil {
|
||||
final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(subst);
|
||||
|
||||
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left);
|
||||
|
||||
|
||||
PsiType returnType = PsiTypesUtil.patchMethodGetClassReturnType(methodReferenceExpression, methodReferenceExpression,
|
||||
(PsiMethod)resolve, null,
|
||||
PsiUtil.getLanguageLevel(methodReferenceExpression));
|
||||
@@ -209,7 +210,7 @@ public class PsiMethodReferenceUtil {
|
||||
resolveResult.getSubstitutor().equals(psiSubstitutor) ||
|
||||
emptyOrRaw(containingClass, psiSubstitutor) ||
|
||||
emptyOrRaw(receiverClass, resolveResult.getSubstitutor());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -245,7 +246,7 @@ public class PsiMethodReferenceUtil {
|
||||
public static boolean areAcceptable(MethodSignature signature1,
|
||||
MethodSignature signature2,
|
||||
PsiClass psiClass,
|
||||
PsiSubstitutor psiSubstitutor,
|
||||
PsiSubstitutor psiSubstitutor,
|
||||
boolean isVarargs) {
|
||||
int offset = 0;
|
||||
final PsiType[] signatureParameterTypes1 = signature1.getParameterTypes();
|
||||
@@ -271,7 +272,7 @@ public class PsiMethodReferenceUtil {
|
||||
if (!(signatureParameterTypes2[i] instanceof PsiArrayType)) {
|
||||
return false;
|
||||
}
|
||||
if (!TypeConversionUtil.isAssignable(((PsiArrayType)signatureParameterTypes2[i]).getComponentType(), type1) &&
|
||||
if (!TypeConversionUtil.isAssignable(((PsiArrayType)signatureParameterTypes2[i]).getComponentType(), type1) &&
|
||||
!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public interface PsiResolveHelper {
|
||||
* @return the result of the resolve, or {@link JavaResolveResult#EMPTY} if the resolve failed.
|
||||
*/
|
||||
@NotNull
|
||||
JavaResolveResult[] multiResolveConstructor(PsiClassType type, PsiExpressionList argumentList, PsiElement place);
|
||||
JavaResolveResult[] multiResolveConstructor(@NotNull PsiClassType type, @NotNull PsiExpressionList argumentList, @NotNull PsiElement place);
|
||||
|
||||
/**
|
||||
* Resolves a call expression and returns an array of possible resolve results.
|
||||
@@ -78,7 +78,7 @@ public interface PsiResolveHelper {
|
||||
* @return the array of resolve results.
|
||||
*/
|
||||
@NotNull
|
||||
CandidateInfo[] getReferencedMethodCandidates(PsiCallExpression call, boolean dummyImplicitConstructor);
|
||||
CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression call, boolean dummyImplicitConstructor);
|
||||
|
||||
/**
|
||||
* Resolves a reference to a class, given the text of the reference and the context
|
||||
@@ -128,7 +128,7 @@ public interface PsiResolveHelper {
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@Nullable PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy);
|
||||
@NotNull ParameterTypeInferencePolicy policy);
|
||||
|
||||
@NotNull
|
||||
PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@@ -136,9 +136,17 @@ public interface PsiResolveHelper {
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@NotNull PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy);
|
||||
@NotNull ParameterTypeInferencePolicy policy);
|
||||
@NotNull
|
||||
PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@NotNull PsiElement parent,
|
||||
@NotNull ParameterTypeInferencePolicy policy,
|
||||
@NotNull LanguageLevel languageLevel);
|
||||
|
||||
@NotNull
|
||||
@NotNull
|
||||
PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiType[] leftTypes,
|
||||
@NotNull PsiType[] rightTypes,
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.psi.infos;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author ik,dsl
|
||||
@@ -34,7 +35,13 @@ public class CandidateInfo implements JavaResolveResult {
|
||||
private final PsiElement myCurrentFileResolveContext;
|
||||
private boolean myPackagePrefixPackageReference;
|
||||
|
||||
private CandidateInfo(PsiElement candidate, PsiSubstitutor substitutor, Boolean accessProblem, boolean staticsProblem, PsiElement currFileContext, PsiElement place, PsiClass accessClass) {
|
||||
private CandidateInfo(PsiElement candidate,
|
||||
PsiSubstitutor substitutor,
|
||||
Boolean accessProblem,
|
||||
boolean staticsProblem,
|
||||
PsiElement currFileContext,
|
||||
PsiElement place,
|
||||
PsiClass accessClass) {
|
||||
myCandidate = candidate;
|
||||
myAccessProblem = accessProblem;
|
||||
myStaticsProblem = staticsProblem;
|
||||
@@ -68,7 +75,7 @@ public class CandidateInfo implements JavaResolveResult {
|
||||
this(candidate, substitutor, null, null, false, null);
|
||||
}
|
||||
|
||||
public CandidateInfo(CandidateInfo candidate, PsiSubstitutor newSubstitutor){
|
||||
public CandidateInfo(@NotNull CandidateInfo candidate, PsiSubstitutor newSubstitutor){
|
||||
this(candidate.myCandidate, newSubstitutor, candidate.myPlace, null, candidate.myStaticsProblem, candidate.myCurrentFileResolveContext);
|
||||
myAccessProblem = candidate.myAccessProblem;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.infos;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -26,6 +27,7 @@ import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.containers.ConcurrentWeakHashMap;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -62,7 +64,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
PsiElement currFileContext,
|
||||
@Nullable PsiType[] argumentTypes,
|
||||
PsiType[] typeArguments,
|
||||
final LanguageLevel languageLevel) {
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
super(candidate, substitutor, accessProblem, staticsProblem, currFileContext);
|
||||
myArgumentList = argumentList;
|
||||
myArgumentTypes = argumentTypes;
|
||||
@@ -145,13 +147,13 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return (PsiMethod)super.getElement();
|
||||
}
|
||||
|
||||
public PsiSubstitutor inferTypeArguments(final ParameterTypeInferencePolicy policy) {
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy) {
|
||||
return inferTypeArguments(policy, myArgumentList instanceof PsiExpressionList
|
||||
? ((PsiExpressionList)myArgumentList).getExpressions()
|
||||
: PsiExpression.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
public PsiSubstitutor inferSubstitutorFromArgs(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) {
|
||||
public PsiSubstitutor inferSubstitutorFromArgs(@NotNull ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) {
|
||||
if (myTypeArguments == null) {
|
||||
return inferTypeArguments(policy, arguments);
|
||||
}
|
||||
@@ -167,8 +169,9 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return incompleteSubstitutor;
|
||||
}
|
||||
}
|
||||
|
||||
public PsiSubstitutor inferTypeArguments(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) {
|
||||
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy,
|
||||
@NotNull PsiExpression[] arguments) {
|
||||
Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>();
|
||||
@@ -179,18 +182,21 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
try {
|
||||
PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject());
|
||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) {
|
||||
Project project = containingClass.getProject();
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
return javaPsiFacade.getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters);
|
||||
}
|
||||
}
|
||||
|
||||
final PsiElement parent = getParent();
|
||||
if (parent == null) return PsiSubstitutor.EMPTY;
|
||||
Project project = method.getProject();
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
return javaPsiFacade.getResolveHelper()
|
||||
.inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy);
|
||||
.inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy, myLanguageLevel);
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) map.remove(myArgumentList);
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
@@ -403,7 +401,8 @@ public class ExceptionUtil {
|
||||
boolean includeSelfCalls) {
|
||||
final JavaResolveResult result = methodCall.resolveMethodGenerics();
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (!includeSelfCalls && method == PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class)) {
|
||||
PsiMethod containingMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class);
|
||||
if (!includeSelfCalls && method == containingMethod) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -411,7 +410,8 @@ public class ExceptionUtil {
|
||||
if (method != null && !isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) {
|
||||
final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes();
|
||||
if (thrownExceptions.length > 0) {
|
||||
final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall);
|
||||
PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile();
|
||||
final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile);
|
||||
try {
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false);
|
||||
final List<CandidateInfo> results = processor.getResults();
|
||||
|
||||
@@ -429,6 +429,7 @@ public class PsiClassImplUtil {
|
||||
@Nullable Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
@NotNull PsiElement place,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
boolean isRaw) {
|
||||
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) {
|
||||
return true; //TypeParameterList and ModifierList do not see our declarations
|
||||
@@ -440,7 +441,6 @@ public class PsiClassImplUtil {
|
||||
|
||||
ParameterizedCachedValue<MembersMap, PsiClass> cache = getValues(aClass); //aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
boolean upToDate = cache.hasUpToDateValue();
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(place);
|
||||
if (/*true || */upToDate) {
|
||||
final NameHint nameHint = processor.getHint(NameHint.KEY);
|
||||
if (nameHint != null) {
|
||||
@@ -692,7 +692,7 @@ public class PsiClassImplUtil {
|
||||
if (superClass == null) continue;
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass,
|
||||
state.get(PsiSubstitutor.KEY), factory, languageLevel);
|
||||
if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place, isRaw)) {
|
||||
if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place, languageLevel, isRaw)) {
|
||||
resolved = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.InheritanceImplUtil;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
@@ -31,7 +32,9 @@ import com.intellij.psi.impl.java.stubs.PsiClassStub;
|
||||
import com.intellij.psi.impl.source.*;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.scope.processor.MethodsProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -445,7 +448,8 @@ public class ClsClassImpl extends ClsMemberImpl<PsiClassStub<?>> implements PsiE
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
LanguageLevel languageLevel = processor instanceof MethodsProcessor ? ((MethodsProcessor)processor).getLanguageLevel() : PsiUtil.getLanguageLevel(place);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, languageLevel, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -153,7 +154,7 @@ public class ClsTypeParameterImpl extends ClsRepositoryPsiElement<PsiTypeParamet
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, PsiUtil.getLanguageLevel(place), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -206,7 +207,7 @@ public abstract class AbstractLightClass extends LightElement implements PsiClas
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, PsiUtil.getLanguageLevel(place), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.PsiFileStub;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -515,7 +516,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
|
||||
}
|
||||
}
|
||||
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, PsiUtil.getLanguageLevel(place), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-11
@@ -321,14 +321,15 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
public JavaResolveResult[] resolve(@NotNull PsiJavaReference ref, boolean incompleteCode) {
|
||||
PsiJavaCodeReferenceElementImpl referenceElement = (PsiJavaCodeReferenceElementImpl)ref;
|
||||
int kind = referenceElement.getKind();
|
||||
JavaResolveResult[] result = referenceElement.resolve(kind);
|
||||
PsiFile containingFile = referenceElement.getContainingFile();
|
||||
JavaResolveResult[] result = referenceElement.resolve(kind, containingFile);
|
||||
|
||||
if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND) {
|
||||
VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement);
|
||||
VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement, containingFile);
|
||||
PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode);
|
||||
result = processor.getResult();
|
||||
if (result.length == 0 && kind == CLASS_NAME_KIND) {
|
||||
result = referenceElement.resolve(PACKAGE_NAME_KIND);
|
||||
result = referenceElement.resolve(PACKAGE_NAME_KIND, containingFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,7 +380,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
return subst;
|
||||
}
|
||||
|
||||
private JavaResolveResult[] resolve(final int kind) {
|
||||
private JavaResolveResult[] resolve(final int kind, PsiFile containingFile) {
|
||||
switch (kind) {
|
||||
case CLASS_FQ_NAME_KIND: {
|
||||
// TODO: support type parameters in FQ names
|
||||
@@ -390,8 +391,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
if (aClass == null) return JavaResolveResult.EMPTY_ARRAY;
|
||||
|
||||
if (!isQualified() && text.equals(aClass.getQualifiedName())) {
|
||||
PsiFile file = getContainingFile();
|
||||
if (file instanceof PsiJavaFile && !((PsiJavaFile)file).getPackageName().isEmpty()) {
|
||||
if (containingFile instanceof PsiJavaFile && !((PsiJavaFile)containingFile).getPackageName().isEmpty()) {
|
||||
// classes in default (unnamed) package cannot be referenced from other packages
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
@@ -431,7 +431,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY;
|
||||
final String className = classNameElement.getText();
|
||||
|
||||
final ClassResolverProcessor processor = new ClassResolverProcessor(className, this, getContainingFile());
|
||||
final ClassResolverProcessor processor = new ClassResolverProcessor(className, this, containingFile);
|
||||
resultElement.processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, result.getSubstitutor()), this, this);
|
||||
return processor.getResult();
|
||||
}
|
||||
@@ -439,7 +439,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
final PsiElement classNameElement = getReferenceNameElement();
|
||||
if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY;
|
||||
final String className = classNameElement.getText();
|
||||
final ClassResolverProcessor processor = new ClassResolverProcessor(className, this, getContainingFile());
|
||||
final ClassResolverProcessor processor = new ClassResolverProcessor(className, this, containingFile);
|
||||
PsiScopesUtil.resolveAndWalk(processor, this, null);
|
||||
return processor.getResult();
|
||||
}
|
||||
@@ -456,16 +456,16 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
|
||||
case CLASS_OR_PACKAGE_NAME_KIND: {
|
||||
int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND;
|
||||
JavaResolveResult[] result = resolve(classKind);
|
||||
JavaResolveResult[] result = resolve(classKind,containingFile);
|
||||
|
||||
if (result.length == 1 && !result[0].isAccessible()) {
|
||||
JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND);
|
||||
JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND,containingFile);
|
||||
if (packageResult.length != 0) {
|
||||
result = packageResult;
|
||||
}
|
||||
}
|
||||
else if (result.length == 0) {
|
||||
result = resolve(PACKAGE_NAME_KIND);
|
||||
result = resolve(PACKAGE_NAME_KIND,containingFile);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
+3
-2
@@ -59,7 +59,7 @@ public class GraphInferencePolicy extends ProcessCandidateParameterTypeInference
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JavaResolveResult[] getResults(PsiCallExpression contextCall, final int exprIdx)
|
||||
protected JavaResolveResult[] getResults(@NotNull PsiCallExpression contextCall, final int exprIdx)
|
||||
throws MethodProcessorSetupFailedException {
|
||||
Map<JavaResolveResult, PsiSubstitutor> map = ourResults.get().get(contextCall);
|
||||
if (map != null) {
|
||||
@@ -67,7 +67,8 @@ public class GraphInferencePolicy extends ProcessCandidateParameterTypeInference
|
||||
return results.toArray(new JavaResolveResult[results.size()]);
|
||||
}
|
||||
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall) {
|
||||
PsiFile containingFile = contextCall.getContainingFile();
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall, containingFile) {
|
||||
@Override
|
||||
protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) {
|
||||
if (argumentList != null) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.psi.*;
|
||||
@@ -129,7 +130,7 @@ public class JavaResolveUtil {
|
||||
PsiClass topAccessClass = getTopLevelClass(accessObjectClass, memberClass);
|
||||
if (!manager.areElementsEquivalent(topMemberClass, topAccessClass)) return false;
|
||||
if (accessObjectClass instanceof PsiAnonymousClass && accessObjectClass.isInheritor(memberClass, true)) {
|
||||
if (place instanceof PsiMethodCallExpression &&
|
||||
if (place instanceof PsiMethodCallExpression &&
|
||||
((PsiMethodCallExpression)place).getMethodExpression().getQualifierExpression() instanceof PsiThisExpression) {
|
||||
return false;
|
||||
}
|
||||
@@ -194,11 +195,11 @@ public class JavaResolveUtil {
|
||||
if (isTypeParameter && isAtLeast17 == null) {
|
||||
isAtLeast17 = JavaVersionService.getInstance().isAtLeast(place, JavaSdkVersion.JDK_1_7);
|
||||
}
|
||||
if (!isTypeParameter || (isAtLeast17 != null && isAtLeast17)) {
|
||||
if (!isTypeParameter || isAtLeast17) {
|
||||
PsiClass aClass = (PsiClass)placeParent;
|
||||
|
||||
|
||||
if (memberClass != null && aClass.isInheritor(memberClass, true)) return aClass;
|
||||
|
||||
|
||||
lastClass = aClass;
|
||||
}
|
||||
}
|
||||
@@ -236,4 +237,20 @@ public class JavaResolveUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PsiPolyVariantReference> JavaResolveResult[] resolveWithContainingFile(@NotNull T ref,
|
||||
@NotNull ResolveCache.PolyVariantResolver<T> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode,
|
||||
@NotNull PsiFile containingFile) {
|
||||
boolean valid = containingFile.isValid();
|
||||
if (!valid) {
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
Project project = containingFile.getProject();
|
||||
ResolveResult[] results = ResolveCache.getInstance(project).resolveWithCaching(ref, resolver, needToPreventRecursion, incompleteCode,
|
||||
containingFile);
|
||||
return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results;
|
||||
}
|
||||
}
|
||||
+10
-8
@@ -23,7 +23,7 @@ import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -35,19 +35,19 @@ import java.util.List;
|
||||
*/
|
||||
public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParameterTypeInferencePolicy {
|
||||
public static final ProcessCandidateParameterTypeInferencePolicy INSTANCE = new ProcessCandidateParameterTypeInferencePolicy();
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall,
|
||||
PsiExpressionList expressionList,
|
||||
PsiCallExpression contextCall,
|
||||
@NotNull PsiCallExpression contextCall,
|
||||
PsiTypeParameter typeParameter) {
|
||||
PsiExpression[] expressions = expressionList.getExpressions();
|
||||
PsiElement parent = innerMethodCall;
|
||||
while (parent.getParent() instanceof PsiParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
int i = ArrayUtil.find(expressions, parent);
|
||||
int i = ArrayUtilRt.find(expressions, parent);
|
||||
if (i < 0) return null;
|
||||
PsiMethod owner = (PsiMethod)typeParameter.getOwner();
|
||||
if (owner == null) return null;
|
||||
@@ -108,8 +108,9 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
|
||||
return substitutor.substitute(finalParameter.getType());
|
||||
}
|
||||
});
|
||||
PsiResolveHelperImpl resolveHelper = (PsiResolveHelperImpl)JavaPsiFacade.getInstance(method.getProject()).getResolveHelper();
|
||||
final Pair<PsiType, ConstraintType> constraint =
|
||||
PsiResolveHelperImpl.getSubstitutionForTypeParameterConstraint(typeParameter, innerReturnType, type, false,
|
||||
resolveHelper.getSubstitutionForTypeParameterConstraint(typeParameter, innerReturnType, type, false,
|
||||
PsiUtil.getLanguageLevel(finalParameter));
|
||||
if (constraint != null) return constraint;
|
||||
}
|
||||
@@ -118,8 +119,9 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected JavaResolveResult[] getResults(PsiCallExpression contextCall, final int exprIdx) throws MethodProcessorSetupFailedException {
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall);
|
||||
protected JavaResolveResult[] getResults(@NotNull PsiCallExpression contextCall, final int exprIdx) throws MethodProcessorSetupFailedException {
|
||||
PsiFile containingFile = contextCall.getContainingFile();
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall, containingFile);
|
||||
//can't call resolve() since it obtains full substitution, that may result in infinite recursion
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false);
|
||||
return processor.getResult();
|
||||
|
||||
+64
-56
@@ -62,7 +62,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult[] multiResolveConstructor(PsiClassType type, PsiExpressionList argumentList, PsiElement place) {
|
||||
public JavaResolveResult[] multiResolveConstructor(@NotNull PsiClassType type, @NotNull PsiExpressionList argumentList, @NotNull PsiElement place) {
|
||||
PsiClassType.ClassResolveResult classResolveResult = type.resolveGenerics();
|
||||
PsiClass aClass = classResolveResult.getElement();
|
||||
if (aClass == null) {
|
||||
@@ -72,13 +72,13 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
PsiSubstitutor substitutor = classResolveResult.getSubstitutor();
|
||||
if (argumentList.getParent() instanceof PsiAnonymousClass) {
|
||||
final PsiAnonymousClass anonymous = (PsiAnonymousClass)argumentList.getParent();
|
||||
processor = new MethodResolverProcessor(anonymous, argumentList, place);
|
||||
processor = new MethodResolverProcessor(anonymous, argumentList, place, place.getContainingFile());
|
||||
aClass = anonymous.getBaseClassType().resolve();
|
||||
if (aClass == null) return JavaResolveResult.EMPTY_ARRAY;
|
||||
substitutor = substitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(aClass, anonymous, substitutor));
|
||||
}
|
||||
else {
|
||||
processor = new MethodResolverProcessor(aClass, argumentList, place);
|
||||
processor = new MethodResolverProcessor(aClass, argumentList, place, place.getContainingFile());
|
||||
}
|
||||
|
||||
ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
|
||||
@@ -143,8 +143,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CandidateInfo[] getReferencedMethodCandidates(PsiCallExpression expr, boolean dummyImplicitConstructor) {
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr);
|
||||
public CandidateInfo[] getReferencedMethodCandidates(@NotNull PsiCallExpression expr, boolean dummyImplicitConstructor) {
|
||||
PsiFile containingFile = expr.getContainingFile();
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(expr, containingFile);
|
||||
try {
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, expr, dummyImplicitConstructor);
|
||||
}
|
||||
@@ -154,12 +155,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return processor.getCandidates();
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
|
||||
private Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
final PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy) {
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
PsiType[] paramTypes = new PsiType[arguments.length];
|
||||
PsiType[] argTypes = new PsiType[arguments.length];
|
||||
if (parameters.length > 0) {
|
||||
@@ -191,12 +192,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return inferTypeForMethodTypeParameterInner(typeParameter, paramTypes, argTypes, partialSubstitutor, parent, policy);
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
|
||||
private Pair<PsiType, ConstraintType> inferTypeForMethodTypeParameterInner(@NotNull PsiTypeParameter typeParameter,
|
||||
@NotNull PsiType[] paramTypes,
|
||||
@NotNull PsiType[] argTypes,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@Nullable PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy) {
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
PsiWildcardType wildcardToCapture = null;
|
||||
Pair<PsiType, ConstraintType> rawInference = null;
|
||||
PsiType lowerBound = PsiType.NULL;
|
||||
@@ -233,7 +234,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
lambdaRaw = true;
|
||||
}
|
||||
if (currentSubstitution == null && lambdaRaw) {
|
||||
return new Pair<PsiType, ConstraintType>(PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()), ConstraintType.EQUALS);
|
||||
return new Pair<PsiType, ConstraintType>(PsiType.getJavaLangObject(myManager, typeParameter.getResolveScope()), ConstraintType.EQUALS);
|
||||
}
|
||||
} else if (argumentType instanceof PsiMethodReferenceType) {
|
||||
final PsiMethodReferenceExpression referenceExpression = ((PsiMethodReferenceType)argumentType).getExpression();
|
||||
@@ -265,7 +266,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
lowerBound = type;
|
||||
}
|
||||
else if (!lowerBound.equals(type)) {
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, typeParameter.getManager());
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, myManager);
|
||||
if (lowerBound == null) return getFailedInferenceConstraint(typeParameter);
|
||||
}
|
||||
break;
|
||||
@@ -283,7 +284,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
if (wildcardToCapture.isSuper()) {
|
||||
return new Pair<PsiType, ConstraintType>(wildcardToCapture, ConstraintType.SUPERTYPE);
|
||||
}
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, wildcardToCapture, typeParameter.getManager());
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, wildcardToCapture, myManager);
|
||||
}
|
||||
else {
|
||||
if (upperBound != PsiType.NULL && !upperBound.isAssignableFrom(wildcardToCapture)) return getFailedInferenceConstraint(typeParameter);
|
||||
@@ -341,7 +342,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy) {
|
||||
@NotNull final ParameterTypeInferencePolicy policy) {
|
||||
|
||||
final Pair<PsiType, ConstraintType> constraint =
|
||||
inferTypeForMethodTypeParameterInner(typeParameter, parameters, arguments, partialSubstitutor, parent, policy);
|
||||
@@ -349,19 +350,18 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return constraint.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@NotNull PsiElement parent,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
@NotNull ParameterTypeInferencePolicy policy,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
PsiType[] substitutions = new PsiType[typeParameters.length];
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<PsiType, ConstraintType>[] constraints = new Pair[typeParameters.length];
|
||||
final PsiManager manager = parent.getManager();
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(parent);
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
if (substitutions[i] != null) continue;
|
||||
final Pair<PsiType, ConstraintType> constraint =
|
||||
@@ -407,7 +407,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
substitutionFromBounds = currentSubstitution;
|
||||
}
|
||||
else {
|
||||
substitutionFromBounds = GenericsUtil.getLeastUpperBound(substitutionFromBounds, currentSubstitution, manager);
|
||||
substitutionFromBounds = GenericsUtil.getLeastUpperBound(substitutionFromBounds, currentSubstitution, myManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -451,7 +451,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
if (substitution == null) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
|
||||
return factory.createRawSubstitutor(partialSubstitutor, typeParameters);
|
||||
}
|
||||
if (substitution != PsiType.NULL) {
|
||||
@@ -465,6 +465,17 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return partialSubstitutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@NotNull PsiSubstitutor partialSubstitutor,
|
||||
@NotNull PsiElement parent,
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
return inferTypeArguments(typeParameters, parameters, arguments, partialSubstitutor, parent, policy, PsiUtil.getLanguageLevel(parent));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull PsiTypeParameter[] typeParameters,
|
||||
@@ -493,7 +504,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
substitution = current;
|
||||
}
|
||||
else {
|
||||
substitution = GenericsUtil.getLeastUpperBound(substitution, current, typeParameter.getManager());
|
||||
substitution = GenericsUtil.getLeastUpperBound(substitution, current, myManager);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -501,7 +512,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
lowerBound = current;
|
||||
}
|
||||
else {
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, current, typeParameter.getManager());
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, current, myManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -532,10 +543,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(final PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
PsiElement parent,
|
||||
final ParameterTypeInferencePolicy policy) {
|
||||
private Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(@NotNull PsiTypeParameter typeParameter,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@NotNull PsiElement parent,
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
PsiTypeParameterListOwner owner = typeParameter.getOwner();
|
||||
Pair<PsiType, ConstraintType> substitution = null;
|
||||
if (owner instanceof PsiMethod && parent instanceof PsiCallExpression) {
|
||||
@@ -557,18 +568,18 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterConstraint(PsiTypeParameter typeParam,
|
||||
PsiType param,
|
||||
PsiType arg,
|
||||
boolean isContraVariantPosition,
|
||||
final LanguageLevel languageLevel) {
|
||||
public Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterConstraint(PsiTypeParameter typeParam,
|
||||
PsiType param,
|
||||
PsiType arg,
|
||||
boolean isContraVariantPosition,
|
||||
final LanguageLevel languageLevel) {
|
||||
if (param instanceof PsiArrayType && arg instanceof PsiArrayType) {
|
||||
return getSubstitutionForTypeParameterConstraint(typeParam, ((PsiArrayType)param).getComponentType(), ((PsiArrayType)arg).getComponentType(),
|
||||
isContraVariantPosition, languageLevel);
|
||||
}
|
||||
|
||||
if (!(param instanceof PsiClassType)) return null;
|
||||
PsiManager manager = typeParam.getManager();
|
||||
PsiManager manager = myManager;
|
||||
if (arg instanceof PsiPrimitiveType) {
|
||||
if (!JavaVersionService.getInstance().isAtLeast(typeParam, JavaSdkVersion.JDK_1_7) && !isContraVariantPosition) return null;
|
||||
arg = ((PsiPrimitiveType)arg).getBoxedType(typeParam);
|
||||
@@ -616,7 +627,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<PsiType, ConstraintType> inferSubstitutionFromLambda(PsiTypeParameter typeParam,
|
||||
private Pair<PsiType, ConstraintType> inferSubstitutionFromLambda(PsiTypeParameter typeParam,
|
||||
PsiLambdaExpressionType arg,
|
||||
PsiType lowerBound,
|
||||
PsiSubstitutor partialSubstitutor) {
|
||||
@@ -646,7 +657,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(final PsiTypeParameter typeParam,
|
||||
private Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(final PsiTypeParameter typeParam,
|
||||
final PsiMethodReferenceExpression methodReferenceExpression,
|
||||
final PsiType functionalInterfaceType,
|
||||
final PsiSubstitutor partialSubstitutor,
|
||||
@@ -726,7 +737,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(PsiTypeParameter typeParam,
|
||||
private Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(PsiTypeParameter typeParam,
|
||||
final PsiLambdaExpression lambdaExpression,
|
||||
final PsiType functionalInterfaceType,
|
||||
PsiType lowerBound) {
|
||||
@@ -783,7 +794,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
if (returnExprConstraint != null) {
|
||||
if (returnExprConstraint == FAILED_INFERENCE) return returnExprConstraint;
|
||||
if (constraint != null) {
|
||||
final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(constraint.getFirst(), returnExprConstraint.getFirst(), typeParam.getManager());
|
||||
final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(constraint.getFirst(), returnExprConstraint.getFirst(), myManager);
|
||||
constraint = new Pair<PsiType, ConstraintType>(leastUpperBound, ConstraintType.SUPERTYPE);
|
||||
} else {
|
||||
constraint = returnExprConstraint;
|
||||
@@ -809,7 +820,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<PsiType, ConstraintType> inferConstraintFromLambdaFormalParams(PsiTypeParameter typeParam,
|
||||
private Pair<PsiType, ConstraintType> inferConstraintFromLambdaFormalParams(PsiTypeParameter typeParam,
|
||||
PsiSubstitutor subst,
|
||||
PsiMethod method, PsiLambdaExpression lambdaExpression) {
|
||||
final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters();
|
||||
@@ -847,7 +858,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
private static final Pair<PsiType, ConstraintType> FAILED_INFERENCE = new Pair<PsiType, ConstraintType>(PsiType.NULL, ConstraintType.EQUALS);
|
||||
|
||||
@Nullable
|
||||
private static Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterInner(PsiType param,
|
||||
private Pair<PsiType, ConstraintType> getSubstitutionForTypeParameterInner(PsiType param,
|
||||
PsiType arg,
|
||||
PsiType patternType,
|
||||
final ConstraintType constraintType,
|
||||
@@ -974,7 +985,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
lowerBound = type;
|
||||
}
|
||||
else if (!lowerBound.equals(type)) {
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, typeParameter.getManager());
|
||||
lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, myManager);
|
||||
if (lowerBound == null) return FAILED_INFERENCE;
|
||||
}
|
||||
break;
|
||||
@@ -997,7 +1008,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
private static final Key<Boolean> inferSubtyping = Key.create("infer.subtyping.marker");
|
||||
private static Pair<PsiType, ConstraintType> inferBySubtypingConstraint(PsiType patternType,
|
||||
private Pair<PsiType, ConstraintType> inferBySubtypingConstraint(PsiType patternType,
|
||||
ConstraintType constraintType,
|
||||
int depth,
|
||||
PsiClass paramClass,
|
||||
@@ -1041,11 +1052,11 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(final PsiElement parent,
|
||||
PsiExpression methodCall,
|
||||
final PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
private Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(@NotNull final PsiElement parent,
|
||||
@NotNull PsiExpression methodCall,
|
||||
@NotNull PsiTypeParameter typeParameter,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
Pair<PsiType, ConstraintType> constraint = null;
|
||||
PsiType expectedType = PsiTypesUtil.getExpectedTypeByParent(methodCall);
|
||||
|
||||
@@ -1096,7 +1107,6 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
}
|
||||
|
||||
final PsiManager manager = typeParameter.getManager();
|
||||
final GlobalSearchScope scope = parent.getResolveScope();
|
||||
PsiType returnType = null;
|
||||
if (constraint == null) {
|
||||
@@ -1124,7 +1134,6 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
}
|
||||
|
||||
final Pair<PsiType, ConstraintType> result;
|
||||
if (constraint == null) {
|
||||
if (methodCall instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)methodCall).getArgumentList();
|
||||
@@ -1160,14 +1169,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
if (superType instanceof PsiClassType && ((PsiClassType)superType).isRaw()) {
|
||||
superType = TypeConversionUtil.erasure(superType);
|
||||
}
|
||||
if (superType == null) superType = PsiType.getJavaLangObject(manager, scope);
|
||||
if (superType == null) superType = PsiType.getJavaLangObject(myManager, scope);
|
||||
if (superType == null) return null;
|
||||
return policy.getInferredTypeWithNoConstraint(manager, superType);
|
||||
return policy.getInferredTypeWithNoConstraint(myManager, superType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
PsiType guess = constraint.getFirst();
|
||||
guess = policy.adjustInferredType(manager, guess, constraint.getSecond());
|
||||
guess = policy.adjustInferredType(myManager, guess, constraint.getSecond());
|
||||
|
||||
//The following code is the result of deep thought, do not shit it out before discussing with [ven]
|
||||
if (returnType instanceof PsiClassType && typeParameter.equals(((PsiClassType)returnType).resolve())) {
|
||||
@@ -1187,8 +1196,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
}
|
||||
|
||||
result = new Pair<PsiType, ConstraintType>(guess, constraint.getSecond());
|
||||
return result;
|
||||
return new Pair<PsiType, ConstraintType>(guess, constraint.getSecond());
|
||||
}
|
||||
|
||||
private static boolean checkSameExpression(PsiExpression templateExpr, final PsiExpression expression) {
|
||||
@@ -1244,11 +1252,11 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferFromConditionalExpression(PsiElement parent,
|
||||
PsiExpression methodCall,
|
||||
PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
private Pair<PsiType, ConstraintType> inferFromConditionalExpression(@NotNull PsiElement parent,
|
||||
@NotNull PsiExpression methodCall,
|
||||
@NotNull PsiTypeParameter typeParameter,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
@NotNull ParameterTypeInferencePolicy policy) {
|
||||
Pair<PsiType, ConstraintType> pair =
|
||||
inferMethodTypeParameterFromParent(PsiUtil.skipParenthesizedExprUp(parent.getParent()), (PsiExpression)parent, typeParameter, substitutor, policy);
|
||||
if (pair == null) {
|
||||
|
||||
+10
-11
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
@@ -20,19 +19,19 @@ import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.psi.JavaResolveResult;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ResolveVariableUtil {
|
||||
public static PsiVariable resolveVariable(
|
||||
PsiJavaCodeReferenceElement ref,
|
||||
boolean[] problemWithAccess,
|
||||
boolean[] problemWithStatic
|
||||
) {
|
||||
public static PsiVariable resolveVariable(@NotNull PsiJavaCodeReferenceElement ref,
|
||||
boolean[] problemWithAccess,
|
||||
boolean[] problemWithStatic
|
||||
) {
|
||||
|
||||
/*
|
||||
long time1 = System.currentTimeMillis();
|
||||
*/
|
||||
|
||||
final VariableResolverProcessor processor = new VariableResolverProcessor(ref);
|
||||
final VariableResolverProcessor processor = new VariableResolverProcessor(ref, ref.getContainingFile());
|
||||
PsiScopesUtil.resolveAndWalk(processor, ref, null);
|
||||
|
||||
/*
|
||||
@@ -41,13 +40,13 @@ public class ResolveVariableUtil {
|
||||
Statistics.resolveVariableCount++;
|
||||
*/
|
||||
final JavaResolveResult[] result = processor.getResult();
|
||||
if(result.length != 1) return null;
|
||||
final PsiVariable refVar = (PsiVariable) result[0].getElement();
|
||||
if (result.length != 1) return null;
|
||||
final PsiVariable refVar = (PsiVariable)result[0].getElement();
|
||||
|
||||
if (problemWithAccess != null){
|
||||
if (problemWithAccess != null) {
|
||||
problemWithAccess[0] = !result[0].isAccessible();
|
||||
}
|
||||
if (problemWithStatic != null){
|
||||
if (problemWithStatic != null) {
|
||||
problemWithStatic[0] = !result[0].isStaticsScopeCorrect();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -41,8 +41,8 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
|
||||
private final PsiClass myAccessClass;
|
||||
private PsiElement myCurrentFileContext = null;
|
||||
|
||||
public VariableResolverProcessor(PsiJavaCodeReferenceElement place) {
|
||||
super(place.getText(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList<CandidateInfo>(), place);
|
||||
public VariableResolverProcessor(@NotNull PsiJavaCodeReferenceElement place, PsiFile placeFile) {
|
||||
super(place.getText(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList<CandidateInfo>(), place, placeFile);
|
||||
|
||||
PsiElement referenceName = place.getReferenceNameElement();
|
||||
if (referenceName instanceof PsiIdentifier){
|
||||
|
||||
+6
-3
@@ -151,8 +151,9 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
PsiType theOnly = null;
|
||||
final JavaResolveResult[] results = methodExpression.multiResolve(false);
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(call);
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
final PsiType type = getResultType(call, methodExpression, results[i]);
|
||||
final PsiType type = getResultType(call, methodExpression, results[i], languageLevel);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -169,11 +170,13 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getResultType(PsiExpression call, PsiReferenceExpression methodExpression, JavaResolveResult result) {
|
||||
private static PsiType getResultType(PsiExpression call,
|
||||
PsiReferenceExpression methodExpression,
|
||||
JavaResolveResult result,
|
||||
@NotNull final LanguageLevel languageLevel) {
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method == null) return null;
|
||||
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(call);
|
||||
boolean is15OrHigher = languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0;
|
||||
final PsiType getClassReturnType = PsiTypesUtil.patchMethodGetClassReturnType(call, methodExpression, method,
|
||||
new Condition<IElementType>() {
|
||||
|
||||
+14
-13
@@ -45,7 +45,6 @@ import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -57,7 +56,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression {
|
||||
private static Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
|
||||
|
||||
public PsiMethodReferenceExpressionImpl() {
|
||||
super(JavaElementType.METHOD_REF_EXPRESSION);
|
||||
@@ -147,7 +146,6 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
LOG.error("invalid!");
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
Project project = manager.getProject();
|
||||
final MethodReferenceResolver resolver = new MethodReferenceResolver();
|
||||
final Map<PsiMethodReferenceExpression, PsiType> map = PsiMethodReferenceUtil.ourRefs.get();
|
||||
if (map != null && map.containsKey(this)) {
|
||||
@@ -284,15 +282,17 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)) : null;
|
||||
final PsiType interfaceMethodReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(PsiMethodReferenceExpressionImpl.this);
|
||||
PsiFile containingFile = getContainingFile();
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(containingFile);
|
||||
if (isConstructor && interfaceMethod != null) {
|
||||
final PsiTypeParameter[] typeParameters = containingClass.getTypeParameters();
|
||||
final boolean isRawSubst = PsiUtil.isRawSubstitutor(containingClass, substitutor);
|
||||
final PsiClassType returnType = JavaPsiFacade.getElementFactory(getProject()).createType(containingClass,
|
||||
Project project = containingClass.getProject();
|
||||
final PsiClassType returnType = JavaPsiFacade.getElementFactory(project).createType(containingClass,
|
||||
isRawSubst ? PsiSubstitutor.EMPTY : substitutor);
|
||||
|
||||
substitutor = LambdaUtil.inferFromReturnType(typeParameters, returnType, interfaceMethodReturnType, substitutor, languageLevel,
|
||||
PsiMethodReferenceExpressionImpl.this.getProject());
|
||||
project);
|
||||
|
||||
if (containingClass.getConstructors().length == 0) {
|
||||
ClassCandidateInfo candidateInfo = null;
|
||||
@@ -309,13 +309,13 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiConflictResolver[] resolvers;
|
||||
if (signature != null) {
|
||||
final PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
resolvers = new PsiConflictResolver[]{conflictResolver, new MethodRefsSpecificResolver(parameterTypes)};
|
||||
resolvers = new PsiConflictResolver[]{conflictResolver, new MethodRefsSpecificResolver(parameterTypes, languageLevel)};
|
||||
}
|
||||
else {
|
||||
resolvers = new PsiConflictResolver[]{conflictResolver};
|
||||
}
|
||||
final MethodCandidatesProcessor processor =
|
||||
new MethodCandidatesProcessor(PsiMethodReferenceExpressionImpl.this, resolvers, new SmartList<CandidateInfo>()) {
|
||||
new MethodCandidatesProcessor(PsiMethodReferenceExpressionImpl.this, containingFile, resolvers, new SmartList<CandidateInfo>()) {
|
||||
@Override
|
||||
protected MethodCandidateInfo createCandidateInfo(final PsiMethod method,
|
||||
final PsiSubstitutor substitutor,
|
||||
@@ -326,7 +326,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
argumentList != null ? argumentList.getExpressionTypes() : null, getTypeArguments(),
|
||||
getLanguageLevel()) {
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(ParameterTypeInferencePolicy policy) {
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy) {
|
||||
return inferTypeArgumentsFromInterfaceMethod(signature, interfaceMethodReturnType, method, substitutor, languageLevel);
|
||||
}
|
||||
};
|
||||
@@ -389,7 +389,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
psiSubstitutor.substitute(method.getReturnType()),
|
||||
interfaceMethodReturnType,
|
||||
psiSubstitutor,
|
||||
languageLevel, PsiMethodReferenceExpressionImpl.this.getProject());
|
||||
languageLevel, getProject());
|
||||
}
|
||||
|
||||
private PsiSubstitutor getSubstitutor(PsiType type) {
|
||||
@@ -497,8 +497,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
}
|
||||
|
||||
private class MethodRefsSpecificResolver extends JavaMethodsConflictResolver {
|
||||
public MethodRefsSpecificResolver(PsiType[] parameterTypes) {
|
||||
super(PsiMethodReferenceExpressionImpl.this, parameterTypes);
|
||||
public MethodRefsSpecificResolver(@NotNull PsiType[] parameterTypes, @NotNull LanguageLevel languageLevel) {
|
||||
super(PsiMethodReferenceExpressionImpl.this, parameterTypes, languageLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -512,7 +512,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
}
|
||||
}
|
||||
checkSpecifics(conflicts,
|
||||
varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY);
|
||||
varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY,
|
||||
myLanguageLevel);
|
||||
return conflicts.size() == 1 ? conflicts.get(0) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-29
@@ -45,9 +45,9 @@ import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -181,16 +181,8 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
super.clearCaches();
|
||||
}
|
||||
|
||||
private static final class OurGenericsResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> {
|
||||
private static final OurGenericsResolver INSTANCE = new OurGenericsResolver();
|
||||
|
||||
@SuppressWarnings("SSBasedInspection")
|
||||
private static final ThreadLocal<Stack<Object>> ourQualifiers = new ThreadLocal<Stack<Object>>() {
|
||||
@Override
|
||||
protected Stack<Object> initialValue() {
|
||||
return new Stack<Object>();
|
||||
}
|
||||
};
|
||||
public static final class OurGenericsResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> {
|
||||
public static final OurGenericsResolver INSTANCE = new OurGenericsResolver();
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@@ -200,8 +192,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
IElementType parentType = treeParent == null ? null : treeParent.getElementType();
|
||||
PsiFile file = expression.getContainingFile();
|
||||
|
||||
List<ResolveResult[]> qualifierResults = resolveAllQualifiers(expression, file);
|
||||
ourQualifiers.get().push(qualifierResults);
|
||||
List<PsiElement> qualifiers = resolveAllQualifiers(expression, file);
|
||||
try {
|
||||
JavaResolveResult[] result = expression.resolve(parentType, file);
|
||||
|
||||
@@ -214,16 +205,20 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
ourQualifiers.get().pop();
|
||||
PsiElement item = qualifiers.isEmpty() ? PsiUtilCore.NULL_PSI_ELEMENT : qualifiers.get(qualifiers.size()-1);
|
||||
qualifiers.clear(); // hold qualifiers list until this moment to avoid psi elements inside to GC
|
||||
if (item == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ResolveResult[]> resolveAllQualifiers(@NotNull PsiReferenceExpressionImpl expression, final PsiFile containingFile) {
|
||||
private static List<PsiElement> resolveAllQualifiers(@NotNull PsiReferenceExpressionImpl expression, @NotNull final PsiFile containingFile) {
|
||||
// to avoid SOE, resolve all qualifiers starting from the innermost
|
||||
PsiElement qualifier = expression.getQualifier();
|
||||
if (qualifier == null) return Collections.emptyList();
|
||||
|
||||
final List<ResolveResult[]> qualifierResults = new SmartList<ResolveResult[]>();
|
||||
final List<PsiElement> qualifiers = new SmartList<PsiElement>();
|
||||
final ResolveCache resolveCache = ResolveCache.getInstance(containingFile.getProject());
|
||||
qualifier.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
@@ -232,10 +227,9 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
return;
|
||||
}
|
||||
ResolveResult[] cachedResults = resolveCache.getCachedResults(expression, true, false, true);
|
||||
if (cachedResults == null) {
|
||||
if (cachedResults != null) {
|
||||
return;
|
||||
}
|
||||
qualifierResults.add(cachedResults);
|
||||
visitElement(expression);
|
||||
}
|
||||
|
||||
@@ -243,10 +237,11 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
protected void elementFinished(PsiElement element) {
|
||||
if (!(element instanceof PsiReferenceExpressionImpl)) return;
|
||||
PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element;
|
||||
qualifierResults.add(resolveCache.resolveWithCaching(expression, INSTANCE, false, false, containingFile));
|
||||
resolveCache.resolveWithCaching(expression, INSTANCE, false, false, containingFile);
|
||||
qualifiers.add(expression);
|
||||
}
|
||||
});
|
||||
return qualifierResults;
|
||||
return qualifiers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +273,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
|
||||
if (parentType == JavaElementType.METHOD_CALL_EXPRESSION) {
|
||||
return resolveToMethod();
|
||||
return resolveToMethod(containingFile);
|
||||
}
|
||||
|
||||
if (parentType == JavaElementType.METHOD_REF_EXPRESSION) {
|
||||
@@ -289,9 +284,9 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JavaResolveResult[] resolveToMethod() {
|
||||
private JavaResolveResult[] resolveToMethod(@NotNull PsiFile containingFile) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)getParent();
|
||||
final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall);
|
||||
final MethodResolverProcessor processor = new MethodResolverProcessor(methodCall, containingFile);
|
||||
try {
|
||||
PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false);
|
||||
}
|
||||
@@ -331,7 +326,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
|
||||
@NotNull
|
||||
private JavaResolveResult[] resolveToVariable() {
|
||||
final VariableResolverProcessor processor = new VariableResolverProcessor(this);
|
||||
final VariableResolverProcessor processor = new VariableResolverProcessor(this, getContainingFile());
|
||||
PsiScopesUtil.resolveAndWalk(processor, this, null);
|
||||
return processor.getResult();
|
||||
}
|
||||
@@ -379,8 +374,12 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
private static class TypeEvaluator implements NullableFunction<PsiReferenceExpressionImpl, PsiType> {
|
||||
@Override
|
||||
public PsiType fun(final PsiReferenceExpressionImpl expr) {
|
||||
JavaResolveResult result = expr.advancedResolve(false);
|
||||
PsiElement resolve = result.getElement();
|
||||
PsiFile file = expr.getContainingFile();
|
||||
Project project = file.getProject();
|
||||
ResolveResult[] results = ResolveCache.getInstance(project).resolveWithCaching(expr, OurGenericsResolver.INSTANCE, true, false, file);
|
||||
JavaResolveResult result = results.length == 1 ? (JavaResolveResult)results[0] : null;
|
||||
|
||||
PsiElement resolve = result == null ? null : result.getElement();
|
||||
if (resolve == null) {
|
||||
ASTNode refName = expr.findChildByRole(ChildRole.REFERENCE_NAME);
|
||||
if (refName != null && "length".equals(refName.getText())) {
|
||||
@@ -417,7 +416,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
if (ret == null) return null;
|
||||
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expr);
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
|
||||
if (ret instanceof PsiClassType) {
|
||||
ret = ((PsiClassType)ret).setLanguageLevel(languageLevel);
|
||||
}
|
||||
@@ -468,7 +467,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processVariants(PsiScopeProcessor processor) {
|
||||
public void processVariants(@NotNull PsiScopeProcessor processor) {
|
||||
OrFilter filter = new OrFilter();
|
||||
filter.addFilter(ElementClassFilter.CLASS);
|
||||
if (isQualified()) {
|
||||
@@ -477,7 +476,8 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter()), new ElementFilter() {
|
||||
@Override
|
||||
public boolean isAcceptable(Object element, @Nullable PsiElement context) {
|
||||
return LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)element, PsiReferenceExpressionImpl.this);
|
||||
return LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)element, PsiReferenceExpressionImpl.this,
|
||||
PsiUtil.getLanguageLevel(PsiReferenceExpressionImpl.this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -201,7 +202,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, PsiUtil.getLanguageLevel(place), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+33
-24
@@ -49,14 +49,18 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
private final PsiElement myArgumentsList;
|
||||
private final PsiType[] myActualParameterTypes;
|
||||
protected LanguageLevel myLanguageLevel;
|
||||
|
||||
public JavaMethodsConflictResolver(@NotNull PsiExpressionList list) {
|
||||
this(list, list.getExpressionTypes());
|
||||
public JavaMethodsConflictResolver(@NotNull PsiExpressionList list, @NotNull LanguageLevel languageLevel) {
|
||||
this(list, list.getExpressionTypes(), languageLevel);
|
||||
}
|
||||
|
||||
public JavaMethodsConflictResolver(final PsiElement argumentsList, final PsiType[] actualParameterTypes) {
|
||||
public JavaMethodsConflictResolver(@NotNull PsiElement argumentsList,
|
||||
@NotNull PsiType[] actualParameterTypes,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
myArgumentsList = argumentsList;
|
||||
myActualParameterTypes = actualParameterTypes;
|
||||
myLanguageLevel = languageLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +71,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
boolean atLeastOneMatch = checkParametersNumber(conflicts, myActualParameterTypes.length, true);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkSameSignatures(conflicts);
|
||||
checkSameSignatures(conflicts, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkAccessStaticLevels(conflicts, true);
|
||||
@@ -83,10 +87,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
// then noone can be more specific
|
||||
if (!atLeastOneMatch) return null;
|
||||
|
||||
checkLambdaApplicable(conflicts);
|
||||
checkLambdaApplicable(conflicts, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkSpecifics(conflicts, applicabilityLevel);
|
||||
checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
|
||||
@@ -95,13 +99,13 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkAccessStaticLevels(conflicts, false);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
THashSet<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
|
||||
Set<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
|
||||
if (uniques.size() == 1) return uniques.iterator().next();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkLambdaApplicable(List<CandidateInfo> conflicts) {
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(myArgumentsList)) return;
|
||||
private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
|
||||
for (int i = 0; i < myActualParameterTypes.length; i++) {
|
||||
PsiType parameterType = myActualParameterTypes[i];
|
||||
if (parameterType instanceof PsiLambdaExpressionType) {
|
||||
@@ -137,7 +141,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
LambdaUtil.checkMoreSpecificReturnType(conflicts, myActualParameterTypes);
|
||||
}
|
||||
|
||||
public void checkSpecifics(List<CandidateInfo> conflicts, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel) {
|
||||
public void checkSpecifics(@NotNull List<CandidateInfo> conflicts,
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final boolean applicable = applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
|
||||
int conflictsCount = conflicts.size();
|
||||
@@ -150,7 +156,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
ProgressManager.checkCanceled();
|
||||
final CandidateInfo conflict = newConflictsArray[j];
|
||||
assert conflict != method;
|
||||
switch (isMoreSpecific(method, conflict, applicabilityLevel)) {
|
||||
switch (isMoreSpecific(method, conflict, applicabilityLevel, languageLevel)) {
|
||||
case FIRST:
|
||||
conflicts.remove(conflict);
|
||||
break;
|
||||
@@ -187,7 +193,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSameSignatures(final List<CandidateInfo> conflicts) {
|
||||
private void checkSameSignatures(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
|
||||
// candidates should go in order of class hierarchy traversal
|
||||
// in order for this to work
|
||||
Map<MethodSignature, CandidateInfo> signatures = new THashMap<MethodSignature, CandidateInfo>(conflicts.size());
|
||||
@@ -450,9 +456,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return allowUncheckedConversion ? Specifics.NEITHER : null;
|
||||
}
|
||||
|
||||
private boolean isBoxingHappened(PsiType argType, PsiType parameterType) {
|
||||
private static boolean isBoxingHappened(PsiType argType, PsiType parameterType, @NotNull LanguageLevel languageLevel) {
|
||||
if (argType == null) return parameterType instanceof PsiPrimitiveType;
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(myArgumentsList);
|
||||
if (parameterType instanceof PsiClassType) {
|
||||
parameterType = ((PsiClassType)parameterType).setLanguageLevel(languageLevel);
|
||||
}
|
||||
@@ -460,7 +465,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return TypeConversionUtil.boxingConversionApplicable(parameterType, argType);
|
||||
}
|
||||
|
||||
private Specifics isMoreSpecific(final CandidateInfo info1, final CandidateInfo info2, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel) {
|
||||
private Specifics isMoreSpecific(final CandidateInfo info1,
|
||||
final CandidateInfo info2,
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
PsiMethod method1 = (PsiMethod)info1.getElement();
|
||||
PsiMethod method2 = (PsiMethod)info2.getElement();
|
||||
final PsiClass class1 = method1.getContainingClass();
|
||||
@@ -504,8 +512,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiType type2 = classSubstitutor2.substitute(types2[i]);
|
||||
PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
|
||||
|
||||
boxingHappened[0] += isBoxingHappened(argType, type1) ? 1 : 0;
|
||||
boxingHappened[1] += isBoxingHappened(argType, type2) ? 1 : 0;
|
||||
boxingHappened[0] += isBoxingHappened(argType, type1, languageLevel) ? 1 : 0;
|
||||
boxingHappened[1] += isBoxingHappened(argType, type2, languageLevel) ? 1 : 0;
|
||||
}
|
||||
if (boxingHappened[0] == 0 && boxingHappened[1] > 0) return Specifics.FIRST;
|
||||
if (boxingHappened[0] > 0 && boxingHappened[1] == 0) return Specifics.SECOND;
|
||||
@@ -520,11 +528,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (typeParameters1.length == 0 || typeParameters2.length == 0) {
|
||||
if (typeParameters1.length > 0) {
|
||||
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(myArgumentsList.getProject()).getResolveHelper();
|
||||
methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, types1, types2, resolveHelper);
|
||||
methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, types1, types2, resolveHelper, languageLevel);
|
||||
}
|
||||
else if (typeParameters2.length > 0) {
|
||||
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(myArgumentsList.getProject()).getResolveHelper();
|
||||
methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, types2, types1, resolveHelper);
|
||||
methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, types2, types1, resolveHelper, languageLevel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -706,11 +714,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return null;
|
||||
}
|
||||
|
||||
private PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
|
||||
final PsiType[] types1,
|
||||
final PsiType[] types2,
|
||||
final PsiResolveHelper resolveHelper) {
|
||||
PsiSubstitutor substitutor = resolveHelper.inferTypeArguments(typeParameters, types1, types2, PsiUtil.getLanguageLevel(myArgumentsList));
|
||||
private static PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
|
||||
final PsiType[] types1,
|
||||
final PsiType[] types2,
|
||||
final PsiResolveHelper resolveHelper,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
PsiSubstitutor substitutor = resolveHelper.inferTypeArguments(typeParameters, types1, types2, languageLevel);
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
ProgressManager.checkCanceled();
|
||||
LOG.assertTrue(typeParameter != null);
|
||||
|
||||
+3
-2
@@ -43,12 +43,13 @@ public class ConflictFilterProcessor extends FilterScopeProcessor<CandidateInfo>
|
||||
@NotNull ElementFilter filter,
|
||||
@NotNull PsiConflictResolver[] resolvers,
|
||||
@NotNull List<CandidateInfo> container,
|
||||
@NotNull PsiElement place) {
|
||||
@NotNull PsiElement place,
|
||||
PsiFile placeFile) {
|
||||
super(filter, container);
|
||||
myResolvers = resolvers;
|
||||
myName = name;
|
||||
myPlace = place;
|
||||
myPlaceFile = place.getContainingFile();
|
||||
myPlaceFile = placeFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -33,12 +33,12 @@ import java.util.List;
|
||||
public class MethodCandidatesProcessor extends MethodsProcessor{
|
||||
protected boolean myHasAccessibleStaticCorrectCandidate = false;
|
||||
|
||||
public MethodCandidatesProcessor(@NotNull PsiElement place, @NotNull PsiConflictResolver[] resolvers, @NotNull List<CandidateInfo> container) {
|
||||
super(resolvers, container, place);
|
||||
public MethodCandidatesProcessor(@NotNull PsiElement place, PsiFile placeFile, @NotNull PsiConflictResolver[] resolvers, @NotNull List<CandidateInfo> container) {
|
||||
super(resolvers, container, place, placeFile);
|
||||
}
|
||||
|
||||
public MethodCandidatesProcessor(@NotNull PsiElement place) {
|
||||
super(new PsiConflictResolver[]{DuplicateConflictResolver.INSTANCE}, new SmartList<CandidateInfo>(), place);
|
||||
public MethodCandidatesProcessor(@NotNull PsiElement place, PsiFile placeFile) {
|
||||
super(new PsiConflictResolver[]{DuplicateConflictResolver.INSTANCE}, new SmartList<CandidateInfo>(), place, placeFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-6
@@ -20,27 +20,30 @@ import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MethodResolverProcessor extends MethodCandidatesProcessor {
|
||||
private boolean myStopAcceptingCandidates = false;
|
||||
|
||||
public MethodResolverProcessor(@NotNull PsiMethodCallExpression place){
|
||||
this(place, new PsiConflictResolver[]{new JavaMethodsConflictResolver(place.getArgumentList())});
|
||||
public MethodResolverProcessor(@NotNull PsiMethodCallExpression place, @NotNull PsiFile placeFile){
|
||||
this(place, placeFile, new PsiConflictResolver[]{new JavaMethodsConflictResolver(place.getArgumentList(),
|
||||
PsiUtil.getLanguageLevel(placeFile))});
|
||||
setArgumentList(place.getArgumentList());
|
||||
obtainTypeArguments(place);
|
||||
}
|
||||
|
||||
public MethodResolverProcessor(PsiClass classConstr, @NotNull PsiExpressionList argumentList, @NotNull PsiElement place) {
|
||||
super(place, new PsiConflictResolver[]{new JavaMethodsConflictResolver(argumentList)}, new SmartList<CandidateInfo>());
|
||||
public MethodResolverProcessor(PsiClass classConstr, @NotNull PsiExpressionList argumentList, @NotNull PsiElement place, @NotNull PsiFile placeFile) {
|
||||
super(place, placeFile, new PsiConflictResolver[]{new JavaMethodsConflictResolver(argumentList,
|
||||
PsiUtil.getLanguageLevel(placeFile))}, new SmartList<CandidateInfo>());
|
||||
setIsConstructor(true);
|
||||
setAccessClass(classConstr);
|
||||
setArgumentList(argumentList);
|
||||
}
|
||||
|
||||
public MethodResolverProcessor(@NotNull PsiElement place, @NotNull PsiConflictResolver[] resolvers) {
|
||||
super(place, resolvers, new SmartList<CandidateInfo>());
|
||||
public MethodResolverProcessor(@NotNull PsiElement place, @NotNull PsiFile placeFile, @NotNull PsiConflictResolver[] resolvers) {
|
||||
super(place, placeFile, resolvers, new SmartList<CandidateInfo>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,10 +46,14 @@ public abstract class MethodsProcessor extends ConflictFilterProcessor implement
|
||||
protected PsiClass myAccessClass = null;
|
||||
private PsiExpressionList myArgumentList;
|
||||
private PsiType[] myTypeArguments;
|
||||
private LanguageLevel myLanguageLevel;
|
||||
private final LanguageLevel myLanguageLevel;
|
||||
|
||||
public MethodsProcessor(@NotNull PsiConflictResolver[] resolvers, @NotNull List<CandidateInfo> container, @NotNull PsiElement place) {
|
||||
super(null, ourFilter, resolvers, container, place);
|
||||
public MethodsProcessor(@NotNull PsiConflictResolver[] resolvers,
|
||||
@NotNull List<CandidateInfo> container,
|
||||
@NotNull PsiElement place,
|
||||
@NotNull PsiFile placeFile) {
|
||||
super(null, ourFilter, resolvers, container, place, placeFile);
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(placeFile);
|
||||
}
|
||||
|
||||
public PsiExpressionList getArgumentList() {
|
||||
@@ -58,14 +62,14 @@ public abstract class MethodsProcessor extends ConflictFilterProcessor implement
|
||||
|
||||
public void setArgumentList(@Nullable PsiExpressionList argList) {
|
||||
myArgumentList = argList;
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(argList == null ? myPlace : argList);
|
||||
}
|
||||
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
@NotNull
|
||||
public LanguageLevel getLanguageLevel() {
|
||||
return myLanguageLevel;
|
||||
}
|
||||
|
||||
public void obtainTypeArguments(PsiCallExpression callExpression) {
|
||||
public void obtainTypeArguments(@NotNull PsiCallExpression callExpression) {
|
||||
final PsiType[] typeArguments = callExpression.getTypeArguments();
|
||||
if (typeArguments.length > 0) {
|
||||
setTypeArguments(typeArguments);
|
||||
|
||||
@@ -217,12 +217,15 @@ public class PsiScopesUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void setupAndRunProcessor(MethodsProcessor processor, PsiCallExpression call, boolean dummyImplicitConstructor)
|
||||
throws MethodProcessorSetupFailedException {
|
||||
public static void setupAndRunProcessor(@NotNull MethodsProcessor processor,
|
||||
@NotNull PsiCallExpression call,
|
||||
boolean dummyImplicitConstructor)
|
||||
throws MethodProcessorSetupFailedException {
|
||||
if (call instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)call;
|
||||
final PsiJavaCodeReferenceElement ref = methodCall.getMethodExpression();
|
||||
|
||||
|
||||
processor.setArgumentList(methodCall.getArgumentList());
|
||||
processor.obtainTypeArguments(methodCall);
|
||||
if (!ref.isQualified() || ref.getReferenceNameElement() instanceof PsiKeyword) {
|
||||
@@ -403,9 +406,9 @@ public class PsiScopesUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean processQualifierResult(JavaResolveResult qualifierResult,
|
||||
final MethodsProcessor processor,
|
||||
PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException {
|
||||
private static boolean processQualifierResult(@NotNull JavaResolveResult qualifierResult,
|
||||
@NotNull MethodsProcessor processor,
|
||||
@NotNull PsiMethodCallExpression methodCall) throws MethodProcessorSetupFailedException {
|
||||
PsiElement resolve = qualifierResult.getElement();
|
||||
|
||||
if (resolve == null) {
|
||||
|
||||
+3
-4
@@ -18,13 +18,12 @@ package com.intellij.codeInsight.daemon;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.defUse.DefUseInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* This class intended for "heavily-loaded" tests only, e.g. those need to setup separate project directory structure to run.
|
||||
@@ -70,9 +69,9 @@ public class AdvHighlightingJdk7Test extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
//ambiguous method calls
|
||||
private void doTestAmbiguous(JavaSdkVersion javaSdkVersion) throws Exception {
|
||||
private void doTestAmbiguous(@NotNull JavaSdkVersion javaSdkVersion) throws Exception {
|
||||
final String name = getTestName(true);
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(javaSdkVersion, myTestRootDisposable);
|
||||
IdeaTestUtil.setTestVersion(javaSdkVersion, getModule(), myTestRootDisposable);
|
||||
doTest(BASE_PATH + name + "/pck/AmbiguousMethodCall.java", BASE_PATH + "/" + name, false, false);
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -20,8 +20,6 @@ import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspec
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -45,9 +43,9 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
return getTestName(false).contains("Jdk14") ? IdeaTestUtil.getMockJdk14() : super.getProjectJDK();
|
||||
}
|
||||
|
||||
private void doTest(LanguageLevel languageLevel, JavaSdkVersion sdkVersion, boolean checkWarnings) {
|
||||
private void doTest(@NotNull LanguageLevel languageLevel, @NotNull JavaSdkVersion sdkVersion, boolean checkWarnings) {
|
||||
LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(languageLevel);
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(sdkVersion, myTestRootDisposable);
|
||||
IdeaTestUtil.setTestVersion(sdkVersion, getModule(), myTestRootDisposable);
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
private void doTest5(boolean checkWarnings) { doTest(LanguageLevel.JDK_1_5, JavaSdkVersion.JDK_1_6, checkWarnings); }
|
||||
@@ -180,7 +178,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testTypeArgumentsGivenOnRawType() { doTest7Incompatibility(false); }
|
||||
public void testSelectFromTypeParameter() { doTest5(false); }
|
||||
public void testTypeArgumentsGivenOnAnonymousClassCreation() { doTest5(false); }
|
||||
|
||||
|
||||
public void testIDEA94011() { doTest5(false); }
|
||||
public void testDifferentTypeParamsInOverloadedMethods() { doTest5(true); }
|
||||
public void testIDEA91626() { doTest5(true); }
|
||||
@@ -309,7 +307,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA109556() { doTest5(false); }
|
||||
public void testIDEA107440() { doTest5(false); }
|
||||
public void testIDEA57289() { doTest5(false); }
|
||||
|
||||
|
||||
public void testJavaUtilCollections_NoVerify() throws Exception {
|
||||
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
|
||||
assertNotNull(collectionsClass);
|
||||
|
||||
+2
-3
@@ -21,9 +21,8 @@ import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -36,7 +35,7 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
private void doTest(boolean checkWarnings, boolean checkInfos, Class<?>... classes) {
|
||||
setLanguageLevel(LanguageLevel.JDK_1_6);
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_6, myTestRootDisposable);
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_6, getModule(), myTestRootDisposable);
|
||||
enableInspectionTools(classes);
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
|
||||
}
|
||||
|
||||
+2
-3
@@ -30,10 +30,9 @@ import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -49,7 +48,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
private void doTest(boolean checkWarnings, boolean checkInfos, Class<?>... classes) {
|
||||
setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_7, myTestRootDisposable);
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_7, getModule(), myTestRootDisposable);
|
||||
enableInspectionTools(classes);
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
|
||||
}
|
||||
|
||||
+3
-4
@@ -39,8 +39,6 @@ import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -50,6 +48,7 @@ import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlToken;
|
||||
import com.intellij.psi.xml.XmlTokenType;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -185,8 +184,8 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testUnused() { doTest(true, false); }
|
||||
public void testQualifierBeforeClassName() { doTest(false, false); }
|
||||
public void testQualifiedSuper() {
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_6, myTestRootDisposable);
|
||||
doTest(false, false);
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_6, getModule(), myTestRootDisposable);
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testIgnoreImplicitThisReferenceBeforeSuperSinceJdk7() throws Exception {
|
||||
|
||||
+3
-4
@@ -17,8 +17,7 @@ package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
@@ -27,7 +26,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
public void testNestedCalls() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
public void testNestedCallsSameMethod() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
@@ -85,7 +84,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkWarnings) throws Exception {
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_8, getTestRootDisposable());
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -19,8 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -89,7 +88,7 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
private void doTest(boolean warnings) {
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_8, getTestRootDisposable());
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ package com.intellij.codeInspection;
|
||||
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.InspectionTestCase;
|
||||
|
||||
public class RedundantCast15Test extends InspectionTestCase {
|
||||
@@ -14,9 +14,9 @@ public class RedundantCast15Test extends InspectionTestCase {
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(), getTestProjectSdk());
|
||||
}
|
||||
|
||||
|
||||
private void doTest() throws Exception {
|
||||
final LocalInspectionToolWrapper toolWrapper = new LocalInspectionToolWrapper(new RedundantCastInspection());
|
||||
doTest("redundantCast/generics/" + getTestName(false), toolWrapper, "java 1.5");
|
||||
@@ -49,7 +49,7 @@ public class RedundantCast15Test extends InspectionTestCase {
|
||||
public void testGetClassProcessing() throws Exception { doTest();}
|
||||
|
||||
public void testTypeParameterAccessChecksJava7() throws Exception {
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_7, getTestRootDisposable());
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_7, getModule(), getTestRootDisposable());
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
package com.intellij.psi.resolve;
|
||||
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionServiceImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.ResolveTestCase;
|
||||
|
||||
/**
|
||||
@@ -21,7 +20,7 @@ public abstract class Resolve15TestCase extends ResolveTestCase {
|
||||
super.setUp();
|
||||
myOldLanguageLevel = LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).getLanguageLevel();
|
||||
LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
|
||||
((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_5, getTestRootDisposable());
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_5, getModule(), getTestRootDisposable());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
@@ -26,14 +27,18 @@ import com.intellij.psi.PsiElement;
|
||||
*/
|
||||
public class JavaSdkVersionUtil {
|
||||
public static boolean isAtLeast(PsiElement element, JavaSdkVersion minVersion) {
|
||||
JavaSdkVersion version = getJavaSdkVersion(element);
|
||||
return version == null || version.isAtLeast(minVersion);
|
||||
}
|
||||
|
||||
public static JavaSdkVersion getJavaSdkVersion(@NotNull PsiElement element) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
|
||||
if (module != null) {
|
||||
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
|
||||
final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
|
||||
return version != null && version.isAtLeast(minVersion);
|
||||
return JavaSdk.getInstance().getVersion(sdk);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,25 @@
|
||||
*/
|
||||
package com.intellij.testFramework;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.SdkModificator;
|
||||
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
|
||||
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -109,4 +115,19 @@ public class IdeaTestUtil extends PlatformTestUtil {
|
||||
assert jar != null : "no .jar for: " + path;
|
||||
return jar;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static void setTestVersion(@NotNull final JavaSdkVersion testVersion, @NotNull Module module, @NotNull Disposable parentDisposable) {
|
||||
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
|
||||
final Sdk sdk = rootManager.getSdk();
|
||||
final String oldVersionString = sdk.getVersionString();
|
||||
((ProjectJdkImpl)sdk).setVersionString(testVersion.getDescription());
|
||||
assert JavaSdk.getInstance().getVersion(sdk) == testVersion;
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
((ProjectJdkImpl)sdk).setVersionString(oldVersionString);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -16,11 +16,15 @@ public class CompletionUtilCoreImpl {
|
||||
@Nullable
|
||||
public static <T extends PsiElement> T getOriginalElement(@NotNull T psi) {
|
||||
final PsiFile file = psi.getContainingFile();
|
||||
if (file != null && file != file.getOriginalFile() && psi.getTextRange() != null) {
|
||||
return getOriginalElement(psi, file);
|
||||
}
|
||||
|
||||
public static <T extends PsiElement> T getOriginalElement(@NotNull T psi, PsiFile containingFile) {
|
||||
if (containingFile != null && containingFile != containingFile.getOriginalFile() && psi.getTextRange() != null) {
|
||||
TextRange range = psi.getTextRange();
|
||||
Integer start = range.getStartOffset();
|
||||
Integer end = range.getEndOffset();
|
||||
final Document document = file.getViewProvider().getDocument();
|
||||
final Document document = containingFile.getViewProvider().getDocument();
|
||||
if (document != null) {
|
||||
Document hostDocument = document instanceof DocumentWindow ? ((DocumentWindow)document).getDelegate() : document;
|
||||
OffsetTranslator translator = hostDocument.getUserData(OffsetTranslator.RANGE_TRANSLATION);
|
||||
@@ -44,7 +48,7 @@ public class CompletionUtilCoreImpl {
|
||||
}
|
||||
}
|
||||
//noinspection unchecked
|
||||
return (T)PsiTreeUtil.findElementOfClassAtRange(file.getOriginalFile(), start, end, psi.getClass());
|
||||
return (T)PsiTreeUtil.findElementOfClassAtRange(containingFile.getOriginalFile(), start, end, psi.getClass());
|
||||
}
|
||||
|
||||
return psi;
|
||||
|
||||
@@ -139,18 +139,12 @@ public class ResolveCache {
|
||||
return reference == null ? null : reference.get();
|
||||
}
|
||||
|
||||
public PsiElement resolveWithCaching(@NotNull PsiReference ref,
|
||||
@NotNull Resolver resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
return resolve(ref, resolver, needToPreventRecursion, incompleteCode, false, ref.getElement().isPhysical());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <TRef extends PsiReference, TResult>TResult resolveWithCaching(@NotNull TRef ref,
|
||||
@NotNull AbstractResolver<TRef, TResult> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
public <TRef extends PsiReference, TResult>
|
||||
TResult resolveWithCaching(@NotNull TRef ref,
|
||||
@NotNull AbstractResolver<TRef, TResult> resolver,
|
||||
boolean needToPreventRecursion,
|
||||
boolean incompleteCode) {
|
||||
return resolve(ref, resolver, needToPreventRecursion, incompleteCode, false, ref.getElement().isPhysical());
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -522,4 +522,9 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
|
||||
public String toString() {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiFile getHostPsiFile() {
|
||||
return myHostPsiFile;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -124,23 +124,28 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
|
||||
if (operands.length == 0) return;
|
||||
boolean hasLiteral = false;
|
||||
InjectedLanguage tempInjectedLanguage = null;
|
||||
PsiFile containingFile = null;
|
||||
for (PsiElement operand : operands) {
|
||||
if (PsiUtilEx.isStringOrCharacterLiteral(operand)) {
|
||||
tempInjectedLanguage = myTemporaryPlacesRegistry.getLanguageFor((PsiLanguageInjectionHost)operand);
|
||||
if (containingFile == null) {
|
||||
containingFile = operands[0].getContainingFile();
|
||||
}
|
||||
|
||||
tempInjectedLanguage = myTemporaryPlacesRegistry.getLanguageFor((PsiLanguageInjectionHost)operand, containingFile);
|
||||
hasLiteral = true;
|
||||
if (tempInjectedLanguage != null) break;
|
||||
}
|
||||
}
|
||||
if (!hasLiteral) return;
|
||||
final Language tempLanguage = tempInjectedLanguage == null ? null : tempInjectedLanguage.getLanguage();
|
||||
final PsiFile containingFile = operands[0].getContainingFile();
|
||||
final PsiFile finalContainingFile = containingFile;
|
||||
InjectionProcessor injectionProcessor = new InjectionProcessor(myConfiguration, operands) {
|
||||
@Override
|
||||
protected void processInjection(Language language,
|
||||
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> list,
|
||||
boolean settingsAvailable,
|
||||
boolean unparsable) {
|
||||
InjectorUtils.registerInjection(language, list, containingFile, registrar);
|
||||
InjectorUtils.registerInjection(language, list, finalContainingFile, registrar);
|
||||
InjectorUtils.registerSupport(mySupport, settingsAvailable, registrar);
|
||||
InjectorUtils.putInjectedFileUserData(registrar, InjectedLanguageUtil.FRANKENSTEIN_INJECTION, unparsable ? Boolean.TRUE : null);
|
||||
}
|
||||
|
||||
+5
-7
@@ -22,10 +22,7 @@ import com.intellij.lang.injection.MultiHostRegistrar;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.psi.ElementManipulator;
|
||||
import com.intellij.psi.ElementManipulators;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -37,7 +34,7 @@ import java.util.List;
|
||||
public class TemporaryPlacesInjector implements MultiHostInjector {
|
||||
|
||||
public static final Logger LOG = Logger.getInstance("org.intellij.plugins.intelliLang.inject.TemporaryPlacesInjector");
|
||||
|
||||
|
||||
private final TemporaryPlacesRegistry myRegistry;
|
||||
|
||||
public TemporaryPlacesInjector(TemporaryPlacesRegistry registry) {
|
||||
@@ -51,14 +48,15 @@ public class TemporaryPlacesInjector implements MultiHostInjector {
|
||||
|
||||
public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) {
|
||||
PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context;
|
||||
InjectedLanguage injectedLanguage = myRegistry.getLanguageFor(host);
|
||||
PsiFile containingFile = context.getContainingFile();
|
||||
InjectedLanguage injectedLanguage = myRegistry.getLanguageFor(host, containingFile);
|
||||
Language language = injectedLanguage != null ? injectedLanguage.getLanguage() : null;
|
||||
if (language != null) {
|
||||
final ElementManipulator<PsiLanguageInjectionHost> manipulator = ElementManipulators.getManipulator(host);
|
||||
if (manipulator == null) return;
|
||||
List<Trinity<PsiLanguageInjectionHost, InjectedLanguage,TextRange>> trinities =
|
||||
Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host)));
|
||||
InjectorUtils.registerInjection(language, trinities, context.getContainingFile(), registrar);
|
||||
InjectorUtils.registerInjection(language, trinities, containingFile, registrar);
|
||||
InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -16,15 +16,12 @@
|
||||
|
||||
package org.intellij.plugins.intelliLang.inject;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionUtil;
|
||||
import com.intellij.codeInsight.completion.CompletionUtilCoreImpl;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PairProcessor;
|
||||
@@ -159,8 +156,8 @@ public class TemporaryPlacesRegistry {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InjectedLanguage getLanguageFor(@NotNull PsiLanguageInjectionHost host) {
|
||||
PsiLanguageInjectionHost originalHost = CompletionUtil.getOriginalElement(host);
|
||||
public InjectedLanguage getLanguageFor(@NotNull PsiLanguageInjectionHost host, PsiFile containingFile) {
|
||||
PsiLanguageInjectionHost originalHost = CompletionUtilCoreImpl.getOriginalElement(host, containingFile);
|
||||
PsiLanguageInjectionHost injectionHost = originalHost == null ? host : originalHost;
|
||||
getInjectionPlacesSafe();
|
||||
return injectionHost.getUserData(LanguageInjectionSupport.TEMPORARY_INJECTED_LANGUAGE);
|
||||
|
||||
+3
-1
@@ -29,6 +29,7 @@ import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -381,7 +382,8 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet
|
||||
@NotNull final ResolveState state,
|
||||
@Nullable PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, ContainerUtil.<PsiClass>newHashSet(), lastParent, place, false);
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, ContainerUtil.<PsiClass>newHashSet(), lastParent, place,
|
||||
PsiUtil.getLanguageLevel(place), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user