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:
Alexey Kudravtsev
2013-08-05 13:14:55 +04:00
parent f541853c60
commit 181ae2e0f5
62 changed files with 757 additions and 538 deletions
@@ -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();
@@ -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();
}
@@ -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) {
@@ -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++;
}
}
@@ -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());
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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));
@@ -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);
}
@@ -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;
@@ -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);
}
}
@@ -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
@@ -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;
@@ -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;
}
}
@@ -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();
@@ -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) {
@@ -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();
}
@@ -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){
@@ -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>() {
@@ -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;
}
}
@@ -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
@@ -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
@@ -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);
@@ -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
@@ -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
@@ -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) {
@@ -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);
}
@@ -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);
@@ -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);
}
@@ -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);
}
@@ -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 {
@@ -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);
}
}
@@ -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);
}
});
}
}
@@ -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());
}
@@ -522,4 +522,9 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
public String toString() {
return result.toString();
}
@NotNull
public PsiFile getHostPsiFile() {
return myHostPsiFile;
}
}
@@ -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);
}
@@ -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);
}
}
@@ -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);
@@ -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