diff options
Diffstat (limited to 'java/java-psi-impl')
29 files changed, 481 insertions, 584 deletions
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java b/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java new file mode 100644 index 000000000000..7678390d0356 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/codeInsight/CustomExceptionHandler.java @@ -0,0 +1,13 @@ +package com.intellij.codeInsight; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class CustomExceptionHandler { + public static final ExtensionPointName<CustomExceptionHandler> KEY = ExtensionPointName.create("com.intellij.custom.exception.handler"); + + public abstract boolean isHandled(@Nullable PsiElement element, @NotNull PsiClassType exceptionType, PsiElement topElement); +} diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 552c7e2d9ff5..bb4e322a2eec 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; @@ -675,6 +676,10 @@ public class ExceptionUtil { // exceptions thrown in field initializers should be thrown in all class constructors return areAllConstructorsThrow(aClass, exceptionType); } + } else { + for (CustomExceptionHandler exceptionHandler : Extensions.getExtensions(CustomExceptionHandler.KEY)) { + if (exceptionHandler.isHandled(element, exceptionType, topElement)) return true; + } } return isHandled(parent, exceptionType, topElement); } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java index 5e008afb4797..e2de5a55e0b3 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java @@ -598,9 +598,15 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem Document document = method.getContainingFile().getViewProvider().getDocument(); PsiCodeBlock body = method.getBody(); - if (body == null || document == null) { + PsiIdentifier nameIdentifier = method.getNameIdentifier(); + if (body == null || document == null || nameIdentifier == null) { return false; } + if (document.getLineNumber(nameIdentifier.getTextRange().getStartOffset()) != + document.getLineNumber(method.getParameterList().getTextRange().getEndOffset())) { + return false; + } + PsiJavaToken lBrace = body.getLBrace(); PsiJavaToken rBrace = body.getRBrace(); PsiStatement[] statements = body.getStatements(); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java index aca4357f7e49..a8b2b40111ba 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java @@ -39,7 +39,8 @@ public class ParameterNameFoldingManager { Couple.of("first", "last"), Couple.of("first", "second"), Couple.of("from", "to"), - Couple.of("key", "value") + Couple.of("key", "value"), + Couple.of("min", "max") ); private final PsiCallExpression myCallExpression; @@ -58,7 +59,8 @@ public class ParameterNameFoldingManager { if (callArgument instanceof PsiPrefixExpression) { PsiPrefixExpression expr = (PsiPrefixExpression)callArgument; IElementType tokenType = expr.getOperationTokenType(); - return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression; + return (JavaTokenType.MINUS.equals(tokenType) + || JavaTokenType.PLUS.equals(tokenType)) && expr.getOperand() instanceof PsiLiteralExpression; } return false; diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java index f7094421b980..ac2fe33d0e43 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/ColorUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,10 @@ package com.intellij.codeInsight.javadoc; import com.intellij.psi.*; import com.intellij.util.ArrayUtil; +import com.intellij.util.ReflectionUtil; import org.jetbrains.annotations.NotNull; import java.awt.*; -import java.lang.reflect.Field; /** * @author spleaner @@ -98,14 +98,12 @@ public class ColorUtil { if (reference != null) { final PsiElement psiElement = reference.resolve(); if (psiElement instanceof PsiField) { - final PsiClass psiClass = ((PsiField) psiElement).getContainingClass(); + PsiField psiField = (PsiField)psiElement; + final PsiClass psiClass = psiField.getContainingClass(); if (psiClass != null && "java.awt.Color".equals(psiClass.getQualifiedName())) { - try { - Field field = Class.forName("java.awt.Color").getField(((PsiField)psiElement).getName()); - final Color c = (Color) field.get(null); + Color c = ReflectionUtil.getField(Color.class, null, Color.class, psiField.getName()); + if (c != null) { buffer.append(generatePreviewHtml(c)); - } catch (Exception e) { - // nothing } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java index e1116894f14f..5f3eee5c6be3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java @@ -34,6 +34,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -253,8 +254,9 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { PsiTypeParameter[] params, PsiJavaCodeReferenceElement reference) { final StringBuilder buf = new StringBuilder(); - buf.append(constructor != null ? constructor.getModifierList().getText() : containingClass.getModifierList().getText()); - if (buf.length() > 0) { + final String modifier = VisibilityUtil.getVisibilityModifier(constructor != null ? constructor.getModifierList() : containingClass.getModifierList()); + if (!PsiModifier.PACKAGE_LOCAL.equals(modifier)) { + buf.append(modifier); buf.append(" "); } buf.append("static "); @@ -262,8 +264,20 @@ public class PsiDiamondTypeImpl extends PsiDiamondType { buf.append(StringUtil.join(params, new Function<PsiTypeParameter, String>() { @Override public String fun(PsiTypeParameter psiTypeParameter) { - final String extendsList = psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE) ? psiTypeParameter.getExtendsList().getText() : null; - return psiTypeParameter.getName() + (StringUtil.isEmpty(extendsList) ? "" : " " + extendsList); + String extendsList = ""; + if (psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + final PsiClassType[] extendsListTypes = psiTypeParameter.getExtendsListTypes(); + if (extendsListTypes.length > 0) { + final Function<PsiClassType, String> canonicalTypePresentationFun = new Function<PsiClassType, String>() { + @Override + public String fun(PsiClassType type) { + return type.getCanonicalText(); + } + }; + extendsList = " extends " + StringUtil.join(extendsListTypes, canonicalTypePresentationFun, "&"); + } + } + return psiTypeParameter.getName() + extendsList; } }, ", ")); buf.append(">"); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java index f958555a3c45..9427551aacf8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java @@ -25,9 +25,7 @@ import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.containers.ConcurrentWeakHashMap; -import com.intellij.util.containers.HashSet; import gnu.trove.THashSet; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,10 +37,12 @@ public class InheritanceImplUtil { public static boolean isInheritor(@NotNull final PsiClass candidateClass, @NotNull PsiClass baseClass, final boolean checkDeep) { if (baseClass instanceof PsiAnonymousClass) return false; - if (!checkDeep) return isInheritor(candidateClass, baseClass, false, null); + if (!checkDeep) { + return isInheritor(candidateClass.getManager(), candidateClass, baseClass, false, null); + } - if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(candidateClass.getName()) && CommonClassNames.JAVA_LANG_OBJECT.equals(candidateClass.getQualifiedName())) return false; - if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(baseClass.getName()) && CommonClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName())) return true; + if (hasObjectQualifiedName(candidateClass)) return false; + if (hasObjectQualifiedName(baseClass)) return true; Map<PsiClass, Boolean> map = CachedValuesManager. getCachedValue(candidateClass, new CachedValueProvider<Map<PsiClass, Boolean>>() { @Nullable @@ -55,18 +55,29 @@ public class InheritanceImplUtil { Boolean computed = map.get(baseClass); if (computed == null) { - computed = isInheritor(candidateClass, baseClass, true, null); + computed = isInheritor(candidateClass.getManager(), candidateClass, baseClass, true, null); map.put(baseClass, computed); } return computed; } - private static boolean isInheritor(@NotNull PsiClass candidateClass, @NotNull PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) { + public static boolean hasObjectQualifiedName(@NotNull PsiClass candidateClass) { + if (!CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(candidateClass.getName())) { + return false; + } + PsiElement parent = candidateClass.getParent(); + return parent instanceof PsiJavaFile && CommonClassNames.DEFAULT_PACKAGE.equals(((PsiJavaFile)parent).getPackageName()); + } + + private static boolean isInheritor(@NotNull PsiManager manager, + @NotNull PsiClass candidateClass, + @NotNull PsiClass baseClass, + boolean checkDeep, + @Nullable Set<PsiClass> checkedClasses) { if (candidateClass instanceof PsiAnonymousClass) { final PsiClass baseCandidateClass = ((PsiAnonymousClass)candidateClass).getBaseClassType().resolve(); return baseCandidateClass != null && InheritanceUtil.isInheritorOrSelf(baseCandidateClass, baseClass, checkDeep); } - PsiManager manager = candidateClass.getManager(); /* //TODO fix classhashprovider so it doesn't use class qnames only final ClassHashProvider provider = getHashProvider((PsiManagerImpl) manager); if (checkDeep && provider != null) { @@ -81,8 +92,7 @@ public class InheritanceImplUtil { LOG.debug("Using uncached version for " + candidateClass.getQualifiedName() + " and " + baseClass); } - @NonNls final String baseName = baseClass.getName(); - if (CommonClassNames.JAVA_LANG_OBJECT_SHORT.equals(baseName)) { + if (hasObjectQualifiedName(baseClass)) { PsiClass objectClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, candidateClass.getResolveScope()); if (manager.areElementsEquivalent(baseClass, objectClass)) { if (manager.areElementsEquivalent(candidateClass, objectClass)) return false; @@ -103,6 +113,7 @@ public class InheritanceImplUtil { if (cInt == bInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getExtendsList(), manager, scope)) return true; return bInt && !cInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getImplementsList(), manager, scope); } + String baseName = baseClass.getName(); if (cInt == bInt) { for (PsiClassType type : candidateClass.getExtendsListTypes()) { if (Comparing.equal(type.getClassName(), baseName)) { @@ -125,7 +136,7 @@ public class InheritanceImplUtil { return false; } - return isInheritorWithoutCaching(candidateClass, baseClass, checkDeep, checkedClasses); + return isInheritorWithoutCaching(manager, candidateClass, baseClass, checkedClasses); } private static boolean checkReferenceListWithQualifiedNames(final String baseQName, final PsiReferenceList extList, final PsiManager manager, @@ -141,63 +152,50 @@ public class InheritanceImplUtil { return false; } - private static boolean isInheritorWithoutCaching(PsiClass aClass, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) { - PsiManager manager = aClass.getManager(); + private static boolean isInheritorWithoutCaching(@NotNull PsiManager manager, + @NotNull PsiClass aClass, + @NotNull PsiClass baseClass, + @Nullable Set<PsiClass> checkedClasses) { if (manager.areElementsEquivalent(aClass, baseClass)) return false; if (aClass.isInterface() && !baseClass.isInterface()) { return false; } - //if (PsiUtil.hasModifierProperty(baseClass, PsiModifier.FINAL)) { - // return false; - //} - - if (checkDeep) { - if (checkedClasses == null) { - checkedClasses = new THashSet<PsiClass>(); - } - checkedClasses.add(aClass); + if (checkedClasses == null) { + checkedClasses = new THashSet<PsiClass>(); } + checkedClasses.add(aClass); - if (!aClass.isInterface() && baseClass.isInterface()) { - if (checkDeep && checkInheritor(aClass.getSuperClass(), baseClass, checkDeep, checkedClasses)) { - return true; - } - return checkInheritor(aClass.getInterfaces(), baseClass, checkDeep, checkedClasses); - - } - else { - return checkInheritor(aClass.getSupers(), baseClass, checkDeep, checkedClasses); - } + return checkInheritor(manager, aClass.getExtendsListTypes(), baseClass, checkedClasses) || + checkInheritor(manager, aClass.getImplementsListTypes(), baseClass, checkedClasses); } - private static boolean checkInheritor(PsiClass[] supers, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) { - for (PsiClass aSuper : supers) { - if (checkInheritor(aSuper, baseClass, checkDeep, checkedClasses)) { + private static boolean checkInheritor(@NotNull PsiManager manager, + @NotNull PsiClassType[] supers, + @NotNull PsiClass baseClass, + @NotNull Set<PsiClass> checkedClasses) { + for (PsiClassType aSuper : supers) { + PsiClass aClass = aSuper.resolve(); + if (aClass != null && checkInheritor(manager, aClass, baseClass, checkedClasses)) { return true; } } return false; } - private static boolean checkInheritor(PsiClass aClass, PsiClass baseClass, boolean checkDeep, Set<PsiClass> checkedClasses) { + private static boolean checkInheritor(@NotNull PsiManager manager, + @NotNull PsiClass aClass, + @NotNull PsiClass baseClass, + @NotNull Set<PsiClass> checkedClasses) { ProgressIndicatorProvider.checkCanceled(); - if (aClass != null) { - PsiManager manager = baseClass.getManager(); - if (manager.areElementsEquivalent(baseClass, aClass)) { - return true; - } - if (checkedClasses != null && checkedClasses.contains(aClass)) { // to prevent infinite recursion - return false; - } - if (checkDeep) { - if (isInheritor(aClass, baseClass, checkDeep, checkedClasses)) { - return true; - } - } + if (manager.areElementsEquivalent(baseClass, aClass)) { + return true; } - return false; + if (checkedClasses.contains(aClass)) { // to prevent infinite recursion + return false; + } + return isInheritor(manager, aClass, baseClass, true, checkedClasses); } public static boolean isInheritorDeep(@NotNull PsiClass candidateClass, @NotNull PsiClass baseClass, @Nullable final PsiClass classToByPass) { @@ -207,9 +205,9 @@ public class InheritanceImplUtil { Set<PsiClass> checkedClasses = null; if (classToByPass != null) { - checkedClasses = new HashSet<PsiClass>(); + checkedClasses = new THashSet<PsiClass>(); checkedClasses.add(classToByPass); } - return isInheritor(candidateClass, baseClass, true, checkedClasses); + return isInheritor(candidateClass.getManager(), candidateClass, baseClass, true, checkedClasses); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 514087492300..938b40f51bb8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl; +import com.intellij.codeInsight.AnnotationTargetUtil; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -51,7 +52,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Set; @@ -60,22 +60,6 @@ import static com.intellij.psi.PsiAnnotation.TargetType; public class PsiImplUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiImplUtil"); - private static final Set<TargetType> DEFAULT_TARGETS = Collections.unmodifiableSet(ContainerUtil.newHashSet( - TargetType.PACKAGE, TargetType.TYPE, TargetType.ANNOTATION_TYPE, - TargetType.FIELD, TargetType.METHOD, TargetType.CONSTRUCTOR, - TargetType.PARAMETER, TargetType.LOCAL_VARIABLE)); - - private static final TargetType[] PACKAGE_TARGETS = {TargetType.PACKAGE}; - private static final TargetType[] TYPE_USE_TARGETS = {TargetType.TYPE_USE}; - private static final TargetType[] ANNOTATION_TARGETS = {TargetType.ANNOTATION_TYPE, TargetType.TYPE, TargetType.TYPE_USE}; - private static final TargetType[] TYPE_TARGETS = {TargetType.TYPE, TargetType.TYPE_USE}; - private static final TargetType[] TYPE_PARAMETER_TARGETS = {TargetType.TYPE_PARAMETER, TargetType.TYPE_USE}; - private static final TargetType[] CONSTRUCTOR_TARGETS = {TargetType.CONSTRUCTOR, TargetType.TYPE_USE}; - private static final TargetType[] METHOD_TARGETS = {TargetType.METHOD, TargetType.TYPE_USE}; - private static final TargetType[] FIELD_TARGETS = {TargetType.FIELD, TargetType.TYPE_USE}; - private static final TargetType[] PARAMETER_TARGETS = {TargetType.PARAMETER, TargetType.TYPE_USE}; - private static final TargetType[] LOCAL_VARIABLE_TARGETS ={TargetType.LOCAL_VARIABLE, TargetType.TYPE_USE}; - private PsiImplUtil() { } @NotNull @@ -376,93 +360,14 @@ public class PsiImplUtil { PsiModifierList modifierList = annotationType.getModifierList(); if (modifierList == null) return null; PsiAnnotation target = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET); - if (target == null) return DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 TYPE_USE/TYPE_PARAMETERS targets - - PsiAnnotationMemberValue value = target.findAttributeValue(null); - if (value instanceof PsiReference) { - TargetType targetType = translateTargetRef((PsiReference)value); - if (targetType != null) { - return Collections.singleton(targetType); - } - } - else if (value instanceof PsiArrayInitializerMemberValue) { - Set <TargetType> targets = ContainerUtil.newHashSet(); - for (PsiAnnotationMemberValue initializer : ((PsiArrayInitializerMemberValue)value).getInitializers()) { - if (initializer instanceof PsiReference) { - TargetType targetType = translateTargetRef((PsiReference)initializer); - if (targetType != null) { - targets.add(targetType); - } - } - } - return targets; - } + if (target == null) return AnnotationTargetUtil.DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 TYPE_USE/TYPE_PARAMETERS targets - return null; - } - - @Nullable - private static TargetType translateTargetRef(PsiReference reference) { - PsiElement field = reference.resolve(); - if (field instanceof PsiEnumConstant) { - String name = ((PsiEnumConstant)field).getName(); - try { - return TargetType.valueOf(name); - } - catch (IllegalArgumentException e) { - LOG.warn("Unknown target: " + name); - } - } - return null; + return AnnotationTargetUtil.extractRequiredAnnotationTargets(target.findAttributeValue(null)); } @NotNull public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) { - if (owner == null) { - return TargetType.EMPTY_ARRAY; - } - - if (owner instanceof PsiType || owner instanceof PsiTypeElement) { - return TYPE_USE_TARGETS; - } - - if (owner instanceof PsiTypeParameter) { - return TYPE_PARAMETER_TARGETS; - } - - if (owner instanceof PsiModifierList) { - PsiElement element = ((PsiModifierList)owner).getParent(); - if (element instanceof PsiPackageStatement) { - return PACKAGE_TARGETS; - } - if (element instanceof PsiClass) { - if (((PsiClass)element).isAnnotationType()) { - return ANNOTATION_TARGETS; - } - else { - return TYPE_TARGETS; - } - } - if (element instanceof PsiMethod) { - if (((PsiMethod)element).isConstructor()) { - return CONSTRUCTOR_TARGETS; - } - else { - return METHOD_TARGETS; - } - } - if (element instanceof PsiField) { - return FIELD_TARGETS; - } - if (element instanceof PsiParameter) { - return PARAMETER_TARGETS; - } - if (element instanceof PsiLocalVariable) { - return LOCAL_VARIABLE_TARGETS; - } - } - - return TargetType.EMPTY_ARRAY; + return AnnotationTargetUtil.getTargetsForLocation(owner); } @Nullable @@ -782,4 +687,33 @@ public class PsiImplUtil { return element instanceof LeafElement && tokenSet.contains(((LeafElement)element).getElementType()); } + public static PsiType buildTypeFromTypeString(@NotNull final String typeName, @NotNull final PsiElement context, @NotNull final PsiFile psiFile) { + PsiType resultType; + final PsiManager psiManager = psiFile.getManager(); + + if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) { + try { + return JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createTypeFromText(typeName, context); + } catch(Exception ex) {} // invalid syntax will produce unresolved class type + } + + PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(typeName, context.getResolveScope()); + + if (aClass == null) { + final LightClassReference ref = new LightClassReference( + psiManager, + PsiNameHelper.getShortClassName(typeName), + typeName, + PsiSubstitutor.EMPTY, + psiFile + ); + resultType = new PsiClassReferenceType(ref, null); + } else { + PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); + PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass); + resultType = factory.createType(aClass, substitutor); + } + + return resultType; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java index f1d847cb24c2..e0db7701574d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootModificationTracker; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; @@ -370,7 +371,12 @@ public class PsiSuperMethodImplUtil { if (result == null) { result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY)); } - return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + + Project project = aClass == null ? method.getProject() : aClass.getProject(); + // cache Cls method hierarchy until root changed + Object dependency = method instanceof PsiCompiledElement ? ProjectRootModificationTracker.getInstance(project) : + PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT; + return CachedValueProvider.Result.create(result, dependency); } }; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java index d2a66271353d..b356698428d8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java @@ -84,7 +84,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - String fqn, shortName; + String fqn; + String shortName; if (myShortName != null && name.endsWith(myShortName)) { shortName = myShortName; fqn = name.length() == shortName.length() @@ -338,7 +339,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor { if (fqn == null) return true; // impossible case, just ignore if (fqn.length() != signature.length()) return false; - int p = 0, dot; + int p = 0; + int dot; while ((dot = fqn.indexOf('.', p)) >= 0) { if (!signature.regionMatches(p, fqn, p, dot - p)) { return false; @@ -428,24 +430,10 @@ public class StubBuildingVisitor<T> extends ClassVisitor { List<String> args = new ArrayList<String>(); List<String> throwables = exceptions != null ? new ArrayList<String>() : null; - final PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null); + int modifiersMask = packMethodFlags(access, myResult.isInterface()); + final PsiMethodStubImpl stub = new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, signature, args, throwables, desc, modifiersMask); - final PsiModifierListStub modList = new PsiModifierListStubImpl(stub, packMethodFlags(access, myResult.isInterface())); - - String returnType = null; - boolean parsedViaGenericSignature = false; - if (signature != null) { - try { - returnType = parseMethodViaGenericSignature(signature, stub, args, throwables); - parsedViaGenericSignature = true; - } - catch (ClsFormatException ignored) { } - } - if (returnType == null) { - returnType = parseMethodViaDescription(desc, stub, args); - } - - stub.setReturnType(TypeInfo.fromString(returnType)); + PsiModifierListStub modList = (PsiModifierListStub)stub.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST); if (isEnum && isConstructor && signature == null && args.size() >= 2 && JAVA_LANG_STRING.equals(args.get(0)) && "int".equals(args.get(1))) { // exclude synthetic enum constructor parameters @@ -454,6 +442,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor { final boolean isNonStaticInnerClassConstructor = isConstructor && !(myParent instanceof PsiFileStub) && (myModList.getModifiersMask() & Opcodes.ACC_STATIC) == 0; + boolean parsedViaGenericSignature = stub.isParsedViaGenericSignature(); final boolean shouldSkipFirstParamForNonStaticInnerClassConstructor = !parsedViaGenericSignature && isNonStaticInnerClassConstructor; final PsiParameterListStubImpl parameterList = new PsiParameterListStubImpl(stub); @@ -502,7 +491,8 @@ public class StubBuildingVisitor<T> extends ClassVisitor { } } - private static String parseMethodViaDescription(final String desc, final PsiMethodStubImpl stub, final List<String> args) { + @NotNull + public static String parseMethodViaDescription(@NotNull String desc, @NotNull PsiMethodStubImpl stub, @NotNull List<String> args) { final String returnType = getTypeText(Type.getReturnType(desc)); final Type[] argTypes = Type.getArgumentTypes(desc); for (Type argType : argTypes) { @@ -512,10 +502,11 @@ public class StubBuildingVisitor<T> extends ClassVisitor { return returnType; } - private static String parseMethodViaGenericSignature(final String signature, - final PsiMethodStubImpl stub, - final List<String> args, - final List<String> throwables) throws ClsFormatException { + @NotNull + public static String parseMethodViaGenericSignature(@NotNull String signature, + @NotNull PsiMethodStubImpl stub, + @NotNull List<String> args, + @Nullable List<String> throwables) throws ClsFormatException { StringCharacterIterator iterator = new StringCharacterIterator(signature); SignatureParsing.parseTypeParametersDeclaration(iterator, stub); @@ -651,12 +642,12 @@ public class StubBuildingVisitor<T> extends ClassVisitor { private int myUsedParamSize = 0; private int myUsedParamCount = 0; - private AnnotationParamCollectingVisitor(final PsiMethodStub owner, - final PsiModifierListStub modList, + private AnnotationParamCollectingVisitor(@NotNull PsiMethodStub owner, + @NotNull PsiModifierListStub modList, final int ignoreCount, final int paramIgnoreCount, final int paramCount, - final PsiParameterStubImpl[] paramStubs) { + @NotNull PsiParameterStubImpl[] paramStubs) { super(ASM_API); myOwner = owner; myModList = modList; @@ -758,7 +749,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor { } if (value instanceof Double) { - final double d = ((Double)value).doubleValue(); + final double d = (Double)value; if (Double.isInfinite(d)) { return d > 0 ? DOUBLE_POSITIVE_INF : DOUBLE_NEGATIVE_INF; } @@ -769,7 +760,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor { } if (value instanceof Float) { - final float v = ((Float)value).floatValue(); + final float v = (Float)value; if (Float.isInfinite(v)) { return v > 0 ? FLOAT_POSITIVE_INF : FLOAT_NEGATIVE_INF; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java index 1463355455c2..13487c5514d0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +21,23 @@ package com.intellij.psi.impl.java.stubs.impl; import com.intellij.psi.PsiMethod; import com.intellij.psi.impl.cache.TypeInfo; +import com.intellij.psi.impl.compiled.StubBuildingVisitor; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.PsiMethodStub; import com.intellij.psi.impl.java.stubs.PsiParameterListStub; import com.intellij.psi.impl.java.stubs.PsiParameterStub; import com.intellij.psi.stubs.StubBase; import com.intellij.psi.stubs.StubElement; +import com.intellij.util.BitUtil; +import com.intellij.util.cls.ClsFormatException; import com.intellij.util.io.StringRef; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodStub { - private TypeInfo myReturnType; + private final TypeInfo myReturnType; private final byte myFlags; private final StringRef myName; private StringRef myDefaultValueText; @@ -43,15 +47,40 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS private static final int ANNOTATION = 0x04; private static final int DEPRECATED = 0x08; private static final int DEPRECATED_ANNOTATION = 0x10; - - public PsiMethodStubImpl(StubElement parent, StringRef name, byte flags, StringRef defaultValueText) { + private static final int PARSED_VIA_GENERIC_SIGNATURE = 0x20; + + public PsiMethodStubImpl(StubElement parent, + StringRef name, + byte flags, + String signature, + @NotNull List<String> args, + @Nullable List<String> throwables, + String desc, + int modifiersMask) { super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD); - myFlags = flags; myName = name; - myDefaultValueText = defaultValueText; + myDefaultValueText = null; + + new PsiModifierListStubImpl(this, modifiersMask); + + String returnType = null; + boolean parsedViaGenericSignature = false; + if (signature != null) { + try { + returnType = StubBuildingVisitor.parseMethodViaGenericSignature(signature, this, args, throwables); + parsedViaGenericSignature = true; + } + catch (ClsFormatException ignored) { } + } + if (returnType == null) { + returnType = StubBuildingVisitor.parseMethodViaDescription(desc, this, args); + } + + myReturnType = TypeInfo.fromString(returnType); + myFlags = (byte)(flags | (parsedViaGenericSignature ? PARSED_VIA_GENERIC_SIGNATURE : 0)); } - public PsiMethodStubImpl(StubElement parent, StringRef name, TypeInfo returnType, byte flags, StringRef defaultValueText) { + public PsiMethodStubImpl(StubElement parent, StringRef name, @NotNull TypeInfo returnType, byte flags, StringRef defaultValueText) { super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD); myReturnType = returnType; myFlags = flags; @@ -59,10 +88,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS myDefaultValueText = defaultValueText; } - public void setReturnType(TypeInfo returnType) { - myReturnType = returnType; - } - @Override public boolean isConstructor() { return (myFlags & CONSTRUCTOR) != 0; @@ -73,6 +98,9 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS return (myFlags & VARARGS) != 0; } + public boolean isParsedViaGenericSignature() { + return BitUtil.isSet(myFlags, PARSED_VIA_GENERIC_SIGNATURE); + } @Override public boolean isAnnotationMethod() { return isAnnotationMethod(myFlags); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java index 58b1e2253d14..b2c934ef9783 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java @@ -86,12 +86,13 @@ public class JavaResolveCache { @Nullable public <T extends PsiExpression> PsiType getType(@NotNull T expr, @NotNull Function<T, PsiType> f) { - PsiType type = getCachedType(expr); + final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck(); + PsiType type = !isOverloadCheck ? getCachedType(expr) : null; if (type == null) { final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack(); final RecursionGuard.StackStamp gStackStamp = PsiResolveHelper.ourGraphGuard.markStack(); type = f.fun(expr); - if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow() || !MethodCandidateInfo.ourOverloadGuard.currentStack().isEmpty()) { + if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow() || isOverloadCheck) { return type; } if (type == null) type = TypeConversionUtil.NULL_TYPE; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 6098199c591c..7d6166a7f95a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -349,13 +349,17 @@ public class InferenceSession { } public boolean initBounds(PsiTypeParameter... typeParameters) { + return initBounds(myContext, typeParameters); + } + + public boolean initBounds(PsiElement context, PsiTypeParameter... typeParameters) { boolean sameMethodCall = false; for (PsiTypeParameter parameter : typeParameters) { if (myInferenceVariables.containsKey(parameter)) { sameMethodCall = true; continue; } - InferenceVariable variable = new InferenceVariable(parameter); + InferenceVariable variable = new InferenceVariable(context, parameter); boolean added = false; final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes(); for (PsiType classType : extendsListTypes) { @@ -415,7 +419,7 @@ public class InferenceSession { for (int i = 0; i < typeParameters.length; i++) { PsiTypeParameter typeParameter = typeParameters[i]; copy[i] = elementFactory.createTypeParameterFromText("rCopy" + typeParameter.getName(), null); - initBounds(copy[i]); + initBounds(myContext, copy[i]); subst = subst.put(typeParameter, elementFactory.createType(copy[i])); } final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(subst.substitute(returnType), myContext); @@ -446,7 +450,7 @@ public class InferenceSession { } private static boolean hasPrimitiveWrapperBound(InferenceVariable inferenceVariable) { - final InferenceBound[] boundTypes = {InferenceBound.UPPER, InferenceBound.LOWER}; + final InferenceBound[] boundTypes = {InferenceBound.UPPER, InferenceBound.LOWER, InferenceBound.EQ}; for (InferenceBound inferenceBound : boundTypes) { final List<PsiType> bounds = inferenceVariable.getBounds(inferenceBound); for (PsiType bound : bounds) { @@ -701,7 +705,7 @@ public class InferenceSession { final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null); final PsiType lub = getLowerBound(var, substitutor); final PsiType glb = getUpperBound(var, substitutor); - final InferenceVariable zVariable = new InferenceVariable(copy); + final InferenceVariable zVariable = new InferenceVariable(var.getCallContext(), copy); zVariable.addBound(glb, InferenceBound.UPPER); if (lub != PsiType.NULL) { if (!TypeConversionUtil.isAssignable(glb, lub)) { @@ -1026,7 +1030,7 @@ public class InferenceSession { boolean varargs) { final InferenceSession session = new InferenceSession(PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, m2.getManager(), context); for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) { - session.initBounds(param); + session.initBounds(context, param); } final PsiParameter[] parameters1 = m1.getParameterList().getParameters(); @@ -1250,14 +1254,17 @@ public class InferenceSession { return myIncorporationPhase.hasCaptureConstraints(Arrays.asList(inferenceVariable)); } - public void liftBounds(Collection<InferenceVariable> variables) { + public void liftBounds(PsiElement context, Collection<InferenceVariable> variables) { for (InferenceVariable variable : variables) { final PsiTypeParameter parameter = variable.getParameter(); final InferenceVariable inferenceVariable = getInferenceVariable(parameter); if (inferenceVariable != null) { - for (InferenceBound boundType : InferenceBound.values()) { - for (PsiType bound : variable.getBounds(boundType)) { - inferenceVariable.addBound(bound, boundType); + final PsiElement callContext = inferenceVariable.getCallContext(); + if (context.equals(callContext) || myContext.equals(callContext)) { + for (InferenceBound boundType : InferenceBound.values()) { + for (PsiType bound : variable.getBounds(boundType)) { + inferenceVariable.addBound(bound, boundType); + } } } } else { @@ -1270,4 +1277,8 @@ public class InferenceSession { final Boolean erased = call.getUserData(ERASED); return erased != null && erased.booleanValue(); } + + public PsiElement getContext() { + return myContext; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java index a606e90e8a98..a19961f4c3a9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java @@ -26,6 +26,8 @@ import java.util.*; * User: anna */ public class InferenceVariable extends LightTypeParameter { + private PsiElement myContext; + public PsiTypeParameter getParameter() { return getDelegate(); } @@ -35,8 +37,9 @@ public class InferenceVariable extends LightTypeParameter { private PsiType myInstantiation = PsiType.NULL; - InferenceVariable(PsiTypeParameter parameter) { + InferenceVariable(PsiElement context, PsiTypeParameter parameter) { super(parameter); + myContext = context; } public PsiType getInstantiation() { @@ -129,4 +132,8 @@ public class InferenceVariable extends LightTypeParameter { public String toString() { return getDelegate().toString(); } + + public PsiElement getCallContext() { + return myContext; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java index c33e2c31fa12..82b320ae99f3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java @@ -110,7 +110,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm if (typeParams != null) { final Set<PsiTypeParameter> oldBounds = ContainerUtil.newHashSet(session.getParamsToInfer()); - final boolean sameMethodCall = session.initBounds(typeParams); + final boolean sameMethodCall = session.initBounds(myExpression, typeParams); PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final HashSet<InferenceVariable> variables = new HashSet<InferenceVariable>(); session.collectDependencies(returnType, variables); @@ -138,8 +138,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm } final Collection<PsiTypeParameter> params1 = session.getTypeParams(); - final InferenceSession callSession = new InferenceSession(params1.toArray(new PsiTypeParameter[params1.size()]), substitutor, myExpression.getManager(), myExpression); - callSession.initBounds(params); + final InferenceSession callSession = new InferenceSession(params, substitutor, myExpression.getManager(), myExpression); + callSession.initBounds(session.getContext(), params1.toArray(new PsiTypeParameter[params1.size()])); if (method != null) { final PsiExpression[] args = argumentList.getExpressions(); final PsiParameter[] parameters = method.getParameterList().getParameters(); @@ -163,7 +163,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm } } } - session.liftBounds(inferenceVariables); + session.liftBounds(myExpression, inferenceVariables); } else { return false; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java index 18d0c49e79d4..9516265a8cb5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java @@ -91,7 +91,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm } final PsiParameter[] parameters = applicableMember instanceof PsiMethod ? ((PsiMethod)applicableMember).getParameterList().getParameters() : PsiParameter.EMPTY_ARRAY; if (targetParameters.length == parameters.length + 1) { - specialCase(session, constraints, substitutor, targetParameters); + specialCase(session, constraints, substitutor, targetParameters, true); for (int i = 1; i < targetParameters.length; i++) { constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), substitutor.substitute(targetParameters[i].getType()))); } @@ -198,7 +198,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm final PsiParameter[] parameters = method.getParameterList().getParameters(); if (targetParameters.length == parameters.length + 1 && !method.isVarArgs() && PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug? - specialCase(session, constraints, substitutor, targetParameters); + specialCase(session, constraints, substitutor, targetParameters, false); } constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(referencedMethodReturnType))); } @@ -209,7 +209,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm private void specialCase(InferenceSession session, List<ConstraintFormula> constraints, PsiSubstitutor substitutor, - PsiParameter[] targetParameters) { + PsiParameter[] targetParameters, + boolean ignoreRaw) { final PsiElement qualifier = myExpression.getQualifier(); PsiType qualifierType = null; if (qualifier instanceof PsiTypeElement) { @@ -226,8 +227,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm final PsiElement res = resolveResult.getElement(); if (res instanceof PsiClass) { PsiClass containingClass = (PsiClass)res; - final boolean isRawSubst = !myExpression.isConstructor() && - PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor()); + final boolean isRawSubst = !ignoreRaw && !myExpression.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor()); qualifierType = JavaPsiFacade.getElementFactory(res.getProject()).createType(containingClass, isRawSubst ? PsiSubstitutor.EMPTY : resolveResult.getSubstitutor()); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java index e2af7b08df0d..d4d0f3f0c88d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java @@ -22,6 +22,7 @@ import com.intellij.lang.LighterASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.SourceJavaCodeReference; import com.intellij.psi.impl.source.SourceTreeToPsiMap; @@ -142,4 +143,41 @@ public class JavaSourceUtil { TreeUtil.clearCaches(TreeUtil.getFileElement(parenthExpr)); return parenthExpr; } + + public static void deleteSeparatingComma(@NotNull CompositeElement element, @NotNull ASTNode child) { + assert child.getElementType() != JavaTokenType.COMMA : child; + + ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); + if (next != null && next.getElementType() == JavaTokenType.COMMA) { + element.deleteChildInternal(next); + } + else { + ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); + if (prev != null && prev.getElementType() == JavaTokenType.COMMA) { + element.deleteChildInternal(prev); + } + } + } + + public static void addSeparatingComma(@NotNull CompositeElement element, @NotNull ASTNode child, @NotNull TokenSet listTypes) { + assert child.getElementType() != JavaTokenType.COMMA : child; + + scanChildren(element, child, listTypes, true); + scanChildren(element, child, listTypes, false); + } + + private static void scanChildren(CompositeElement element, ASTNode node, TokenSet listTypes, boolean forward) { + ASTNode child = node; + while (true) { + child = (forward ? child.getTreeNext() : child.getTreePrev()); + if (child == null || child.getElementType() == JavaTokenType.COMMA) break; + if (listTypes.contains(child.getElementType())) { + CharTable charTable = SharedImplUtil.findCharTableByTree(element); + PsiManager manager = element.getPsi().getManager(); + TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, charTable, manager); + element.addInternal(comma, comma, (forward ? node : child), Boolean.FALSE); + break; + } + } + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java index 4953bd2d3804..e1ffc8b91766 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/AnnotationParamListElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,9 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.*; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.ChildRoleBase; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.CharTable; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -28,47 +29,29 @@ import org.jetbrains.annotations.NotNull; /** * @author ven */ -public class AnnotationParamListElement extends PsiCommaSeparatedListImpl implements PsiAnnotationParameterList { +public class AnnotationParamListElement extends CompositeElement { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.AnnotationParamListElement"); - private volatile PsiNameValuePair[] myCachedMembers = null; + private static final TokenSet NAME_VALUE_PAIR_BIT_SET = TokenSet.create(JavaElementType.NAME_VALUE_PAIR); public AnnotationParamListElement() { - super(ANNOTATION_PARAMETER_LIST, NAME_VALUE_PAIR_BIT_SET); - } - - @Override - public void clearCaches() { - super.clearCaches(); - myCachedMembers = null; - } - - @Override - @NotNull - public PsiNameValuePair[] getAttributes() { - PsiNameValuePair[] cachedMembers = myCachedMembers; - if (cachedMembers == null) { - myCachedMembers = cachedMembers = getChildrenAsPsiElements(NAME_VALUE_PAIR_BIT_SET, PsiNameValuePair.ARRAY_FACTORY); - } - - return cachedMembers; + super(JavaElementType.ANNOTATION_PARAMETER_LIST); } @Override public int getChildRole(ASTNode child) { IElementType i = child.getElementType(); - if (i == COMMA) { + if (i == JavaTokenType.COMMA) { return ChildRole.COMMA; } - else if (i == LPARENTH) { + else if (i == JavaTokenType.LPARENTH) { return ChildRole.LPARENTH; } - else if (i == RPARENTH) { + else if (i == JavaTokenType.RPARENTH) { return ChildRole.RPARENTH; } - else if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType()) - || (i == NAME_VALUE_PAIR && child.getFirstChildNode() != null - && child.getFirstChildNode().getElementType() == ANNOTATION_ARRAY_INITIALIZER)) - { + else if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(i) || + (i == JavaElementType.NAME_VALUE_PAIR && child.getFirstChildNode() != null && + child.getFirstChildNode().getElementType() == JavaElementType.ANNOTATION_ARRAY_INITIALIZER)) { return ChildRole.ANNOTATION_VALUE; } else { @@ -83,65 +66,69 @@ public class AnnotationParamListElement extends PsiCommaSeparatedListImpl implem LOG.assertTrue(false); return null; case ChildRole.LPARENTH: - return findChildByType(LPARENTH); + return findChildByType(JavaTokenType.LPARENTH); case ChildRole.RPARENTH: - return findChildByType(RPARENTH); - } - } - - public String toString() { - return "PsiAnnotationParameterList"; - } - - @Override - public void accept(@NotNull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitAnnotationParameterList(this); - } - else { - visitor.visitElement(this); + return findChildByType(JavaTokenType.RPARENTH); } } @Override public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { - if (first.getElementType() == NAME_VALUE_PAIR && last.getElementType() == NAME_VALUE_PAIR) { - final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); - ASTNode lparenth = findChildByRole(ChildRole.LPARENTH); + if (first.getElementType() == JavaElementType.NAME_VALUE_PAIR && last.getElementType() == JavaElementType.NAME_VALUE_PAIR) { + ASTNode lparenth = findChildByType(JavaTokenType.LPARENTH); if (lparenth == null) { - LeafElement created = Factory.createSingleLeafElement(LPARENTH, "(", 0, 1, treeCharTab, getManager()); + CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + LeafElement created = Factory.createSingleLeafElement(JavaTokenType.LPARENTH, "(", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getFirstChildNode(), true); } - ASTNode rparenth = findChildByRole(ChildRole.RPARENTH); + + ASTNode rparenth = findChildByType(JavaTokenType.RPARENTH); if (rparenth == null) { - LeafElement created = Factory.createSingleLeafElement(RPARENTH, ")", 0, 1, treeCharTab, getManager()); + CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); + LeafElement created = Factory.createSingleLeafElement(JavaTokenType.RPARENTH, ")", 0, 1, treeCharTab, getManager()); super.addInternal(created, created, getLastChildNode(), false); } - final ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET); + ASTNode[] nodes = getChildren(NAME_VALUE_PAIR_BIT_SET); if (nodes.length == 1) { - final ASTNode node = nodes[0]; + ASTNode node = nodes[0]; if (node instanceof PsiNameValuePair) { - final PsiNameValuePair pair = (PsiNameValuePair)node; + PsiNameValuePair pair = (PsiNameValuePair)node; if (pair.getName() == null) { - final String text = pair.getValue().getText(); - try { - final PsiAnnotation annotation = JavaPsiFacade.getInstance(getProject()).getElementFactory().createAnnotationFromText("@AAA(value = " + text + ")", null); - replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode()); - } - catch (IncorrectOperationException e) { - LOG.error(e); + PsiAnnotationMemberValue value = pair.getValue(); + if (value != null) { + try { + PsiElementFactory factory = JavaPsiFacade.getInstance(getPsi().getProject()).getElementFactory(); + PsiAnnotation annotation = factory.createAnnotationFromText("@AAA(value = " + value.getText() + ")", null); + replaceChild(node, annotation.getParameterList().getAttributes()[0].getNode()); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } } } } } if (anchor == null && before != null) { - anchor = findChildByRole(before.booleanValue() ? ChildRole.RPARENTH : ChildRole.LPARENTH); + anchor = findChildByType(before ? JavaTokenType.RPARENTH : JavaTokenType.LPARENTH); } + + TreeElement firstAdded = super.addInternal(first, last, anchor, before); + JavaSourceUtil.addSeparatingComma(this, first, NAME_VALUE_PAIR_BIT_SET); + return firstAdded; } return super.addInternal(first, last, anchor, before); } + + @Override + public void deleteChildInternal(@NotNull ASTNode child) { + if (child.getElementType() == JavaElementType.NAME_VALUE_PAIR) { + JavaSourceUtil.deleteSeparatingComma(this, child); + } + + super.deleteChildInternal(child); + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java index 712b32ca6d5b..14d72a92da1c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ClassElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,15 @@ import org.jetbrains.annotations.Nullable; public class ClassElement extends CompositeElement implements Constants { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ClassElement"); + private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET = TokenSet.create( + PUBLIC_KEYWORD, ABSTRACT_KEYWORD, STATIC_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD); + private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET_18_METHOD = TokenSet.create( + PUBLIC_KEYWORD, ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD); + private static final TokenSet MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET = TokenSet.create( + PUBLIC_KEYWORD, FINAL_KEYWORD); + private static final TokenSet ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET = TokenSet.create( + ENUM_CONSTANT, COMMA, SEMICOLON); + public ClassElement(IElementType type) { super(type); } @@ -181,19 +190,8 @@ public class ClassElement extends CompositeElement implements Constants { @Override public void deleteChildInternal(@NotNull ASTNode child) { - if (isEnum()) { - if (child.getElementType() == ENUM_CONSTANT) { - ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == COMMA) { - deleteChildInternal(next); - } - else { - ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == COMMA) { - deleteChildInternal(prev); - } - } - } + if (isEnum() && child.getElementType() == ENUM_CONSTANT) { + JavaSourceUtil.deleteSeparatingComma(this, child); } if (child.getElementType() == FIELD) { @@ -233,27 +231,6 @@ public class ClassElement extends CompositeElement implements Constants { return findChildByRole(ChildRole.AT) != null; } - private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET = TokenSet.create( - PUBLIC_KEYWORD, ABSTRACT_KEYWORD, - STATIC_KEYWORD, FINAL_KEYWORD, - NATIVE_KEYWORD - ); - - private static final TokenSet MODIFIERS_TO_REMOVE_IN_INTERFACE_BIT_SET_18_METHOD = TokenSet.create( - PUBLIC_KEYWORD, ABSTRACT_KEYWORD, - FINAL_KEYWORD, - NATIVE_KEYWORD - ); - - private static final TokenSet MODIFIERS_TO_REMOVE_IN_ENUM_BIT_SET = TokenSet.create( - PUBLIC_KEYWORD, FINAL_KEYWORD - ); - - private static final TokenSet ENUM_CONSTANT_LIST_ELEMENTS_BIT_SET = TokenSet.create( - ENUM_CONSTANT, COMMA, SEMICOLON - ); - - @Override public ASTNode findChildByRole(int role) { assert ChildRole.isUnique(role); @@ -266,10 +243,7 @@ public class ClassElement extends CompositeElement implements Constants { return PsiImplUtil.findDocComment(this); case ChildRole.ENUM_CONSTANT_LIST_DELIMITER: - if (!isEnum()) { - return null; - } - return findEnumConstantListDelimiter(); + return isEnum() ? findEnumConstantListDelimiter() : null; case ChildRole.MODIFIER_LIST: return findChildByType(MODIFIER_LIST); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java index a5e32e9ce95b..20d504d8dbae 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterListElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,18 +18,21 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.Constants; -import com.intellij.psi.impl.source.tree.*; +import com.intellij.psi.impl.source.tree.ChildRole; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.impl.source.tree.JavaSourceUtil; +import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; -import com.intellij.util.CharTable; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ParameterListElement extends CompositeElement implements Constants { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterListElement"); + private static final TokenSet PARAMETER_SET = TokenSet.create(PARAMETER); public ParameterListElement() { super(PARAMETER_LIST); @@ -49,23 +52,7 @@ public class ParameterListElement extends CompositeElement implements Constants } TreeElement firstAdded = super.addInternal(first, last, anchor, before); if (first == last && first.getElementType() == PARAMETER) { - final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); - for (ASTNode child = ((ASTNode)first).getTreeNext(); child != null; child = child.getTreeNext()) { - if (child.getElementType() == COMMA) break; - if (child.getElementType() == PARAMETER) { - TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, first, Boolean.FALSE); - break; - } - } - for (ASTNode child = ((ASTNode)first).getTreePrev(); child != null; child = child.getTreePrev()) { - if (child.getElementType() == COMMA) break; - if (child.getElementType() == PARAMETER) { - TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, child, Boolean.FALSE); - break; - } - } + JavaSourceUtil.addSeparatingComma(this, first, PARAMETER_SET); } //todo[max] hack? @@ -83,16 +70,7 @@ public class ParameterListElement extends CompositeElement implements Constants final TreeElement oldLastNodeInsideParens = getLastNodeInsideParens(); final TreeElement oldFirstNodeInsideParens = getFirstNodeInsideParens(); if (child.getElementType() == PARAMETER) { - ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == COMMA) { - deleteChildInternal(next); - } - else { - ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == COMMA) { - deleteChildInternal(prev); - } - } + JavaSourceUtil.deleteSeparatingComma(this, child); } super.deleteChildInternal(child); @@ -135,20 +113,12 @@ public class ParameterListElement extends CompositeElement implements Constants return null; case ChildRole.LPARENTH: - if (getFirstChildNode().getElementType() == LPARENTH) { - return getFirstChildNode(); - } - else { - return null; - } + TreeElement firstNode = getFirstChildNode(); + return firstNode.getElementType() == LPARENTH ? firstNode : null; case ChildRole.RPARENTH: - if (getLastChildNode().getElementType() == RPARENTH) { - return getLastChildNode(); - } - else { - return null; - } + TreeElement lastNode = getLastChildNode(); + return lastNode.getElementType() == RPARENTH ? lastNode : null; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java index 5a3ccb23e420..0923d7cdd675 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationParamListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,20 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; +import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiAnnotationParameterList; +import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiNameValuePair; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.PsiAnnotationParameterListStub; import com.intellij.psi.impl.source.JavaStubPsiElement; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; /** * @author Dmitry Avdeev - * Date: 7/27/12 + * @since 27.07.2012 */ -public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotationParameterListStub> implements - PsiAnnotationParameterList { +public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotationParameterListStub> implements PsiAnnotationParameterList { public PsiAnnotationParamListImpl(@NotNull PsiAnnotationParameterListStub stub) { super(stub, JavaStubElementTypes.ANNOTATION_PARAMETER_LIST); } @@ -44,8 +44,18 @@ public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotation return getStubOrPsiChildren(JavaStubElementTypes.NAME_VALUE_PAIR, PsiNameValuePair.ARRAY_FACTORY); } - @NonNls - public String toString(){ - return "PsiAnnotationParameterList:" + getText(); + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitAnnotationParameterList(this); + } + else { + visitor.visitElement(this); + } + } + + @Override + public String toString() { + return "PsiAnnotationParameterList"; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java index dd64ed7e41fb..b03766f54d55 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiArrayInitializerMemberValueImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,68 +17,84 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.JavaElementVisitor; -import com.intellij.psi.PsiAnnotationMemberValue; -import com.intellij.psi.PsiArrayInitializerMemberValue; -import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.impl.source.tree.ChildRole; -import com.intellij.psi.tree.IElementType; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.ChildRoleBase; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; /** * @author ven */ -public class PsiArrayInitializerMemberValueImpl extends PsiCommaSeparatedListImpl implements PsiArrayInitializerMemberValue { - private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.source.tree.java.PsiArrayInitializerMemberValueImpl"); +public class PsiArrayInitializerMemberValueImpl extends CompositePsiElement implements PsiArrayInitializerMemberValue { + private static final Logger LOG = Logger.getInstance(PsiArrayInitializerMemberValueImpl.class); + private static final TokenSet MEMBER_SET = ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET; + public PsiArrayInitializerMemberValueImpl() { - super(ANNOTATION_ARRAY_INITIALIZER, ANNOTATION_MEMBER_VALUE_BIT_SET); + super(JavaElementType.ANNOTATION_ARRAY_INITIALIZER); } @Override @NotNull public PsiAnnotationMemberValue[] getInitializers() { - return getChildrenAsPsiElements(ANNOTATION_MEMBER_VALUE_BIT_SET, PsiAnnotationMemberValue.ARRAY_FACTORY); + return getChildrenAsPsiElements(MEMBER_SET, PsiAnnotationMemberValue.ARRAY_FACTORY); } @Override public ASTNode findChildByRole(int role) { LOG.assertTrue(ChildRole.isUnique(role)); - switch(role){ + + switch (role) { default: return null; case ChildRole.LBRACE: - return findChildByType(LBRACE); + return findChildByType(JavaTokenType.LBRACE); case ChildRole.RBRACE: - return findChildByType(RBRACE); + return findChildByType(JavaTokenType.RBRACE); } } @Override public int getChildRole(ASTNode child) { LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); - if (i == COMMA) { + if (i == JavaTokenType.COMMA) { return ChildRole.COMMA; } - else if (i == LBRACE) { + else if (i == JavaTokenType.LBRACE) { return ChildRole.LBRACE; } - else if (i == RBRACE) { + else if (i == JavaTokenType.RBRACE) { return ChildRole.RBRACE; } - else { - if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) { - return ChildRole.ANNOTATION_VALUE; - } - return ChildRoleBase.NONE; + else if (MEMBER_SET.contains(child.getElementType())) { + return ChildRole.ANNOTATION_VALUE; } + return ChildRoleBase.NONE; } - public String toString(){ - return "PsiArrayInitializerMemberValue:" + getText(); + @Override + public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { + if (MEMBER_SET.contains(first.getElementType()) && MEMBER_SET.contains(last.getElementType())) { + TreeElement firstAdded = super.addInternal(first, last, anchor, before); + JavaSourceUtil.addSeparatingComma(this, first, MEMBER_SET); + return firstAdded; + } + + return super.addInternal(first, last, anchor, before); + } + + @Override + public void deleteChildInternal(@NotNull ASTNode child) { + if (MEMBER_SET.contains(child.getElementType())) { + JavaSourceUtil.deleteSeparatingComma(this, child); + } + + super.deleteChildInternal(child); } @Override @@ -90,4 +106,9 @@ public class PsiArrayInitializerMemberValueImpl extends PsiCommaSeparatedListImp visitor.visitElement(this); } } + + @Override + public String toString() { + return "PsiArrayInitializerMemberValue:" + getText(); + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java deleted file mode 100644 index 475542fdc868..000000000000 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCommaSeparatedListImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.psi.impl.source.tree.java; - -import com.intellij.lang.ASTNode; -import com.intellij.psi.impl.PsiImplUtil; -import com.intellij.psi.impl.source.Constants; -import com.intellij.psi.impl.source.tree.*; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; -import com.intellij.util.CharTable; -import org.jetbrains.annotations.NotNull; - -/** - * Adds or removes comma - * - * @author ven - */ -public abstract class PsiCommaSeparatedListImpl extends CompositePsiElement implements Constants { - private final TokenSet myTypesOfElements; - - protected PsiCommaSeparatedListImpl(IElementType type, final TokenSet typeOfElements) { - super(type); - myTypesOfElements = typeOfElements; - } - - @Override - public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { - if (myTypesOfElements.contains(first.getElementType()) && myTypesOfElements.contains(last.getElementType())) { - final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this); - final TreeElement firstAdded = super.addInternal(first, last, anchor, before); - for (ASTNode child = ((ASTNode)first).getTreeNext(); child != null; child = child.getTreeNext()) { - if (child.getElementType() == COMMA) break; - if (myTypesOfElements.contains(child.getElementType())) { - TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, first, Boolean.FALSE); - break; - } - } - - for (ASTNode child = ((ASTNode)first).getTreePrev(); child != null; child = child.getTreePrev()) { - if (child.getElementType() == COMMA) break; - if (myTypesOfElements.contains(child.getElementType())) { - TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, child, Boolean.FALSE); - break; - } - } - return firstAdded; - } - - return super.addInternal(first, last, anchor, before); - } - - @Override - public void deleteChildInternal(@NotNull ASTNode child) { - if (myTypesOfElements.contains(child.getElementType())) { - ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == COMMA) { - deleteChildInternal(next); - } - else { - ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == COMMA) { - deleteChildInternal(prev); - } - } - } - super.deleteChildInternal(child); - } -} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java index ae45273b57f1..98df0baa4134 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiExpressionListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; @@ -123,7 +122,8 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp } TreeElement firstAdded = super.addInternal(first, last, anchor, before); if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) { - ASTNode element = first; + JavaSourceUtil.addSeparatingComma(this, first, ElementType.EXPRESSION_BIT_SET); + /*ASTNode element = first; for (ASTNode child = element.getTreeNext(); child != null; child = child.getTreeNext()) { if (child.getElementType() == JavaTokenType.COMMA) break; if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) { @@ -140,7 +140,7 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp super.addInternal(comma, comma, child, Boolean.FALSE); break; } - } + }*/ } return firstAdded; } @@ -148,17 +148,9 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp @Override public void deleteChildInternal(@NotNull ASTNode child) { if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) { - ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == JavaTokenType.COMMA) { - deleteChildInternal(next); - } - else { - ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == JavaTokenType.COMMA) { - deleteChildInternal(prev); - } - } + JavaSourceUtil.deleteSeparatingComma(this, child); } + super.deleteChildInternal(child); } @@ -172,6 +164,7 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp } } + @Override public String toString() { return "PsiExpressionList"; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index 95171ba30bc9..32ed1aac5c91 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -25,6 +25,7 @@ import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; +import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.psi.impl.source.tree.JavaElementType; @@ -39,13 +40,12 @@ import com.intellij.psi.scope.util.PsiScopesUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.*; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl"); @@ -153,7 +153,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase if (arrayClass == containingClass) { final PsiType componentType = qualifierResolveResult.getSubstitutor().substitute(arrayClass.getTypeParameters()[0]); LOG.assertTrue(componentType != null, qualifierResolveResult.getSubstitutor()); - methods = new PsiMethod[] {factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this)}; + //15.13.1 A method reference expression of the form ArrayType :: new is always exact. + return factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this); } else { methods = containingClass.getConstructors(); } @@ -172,25 +173,38 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase if (psiMethod.getTypeParameters().length > 0) { final PsiReferenceParameterList parameterList = getParameterList(); return parameterList != null && parameterList.getTypeParameterElements().length > 0 ? psiMethod : null; + } else { + final PsiSubstitutor classSubstitutor = TypeConversionUtil.getClassSubstitutor(psiMethod.getContainingClass(), containingClass, PsiSubstitutor.EMPTY); + final Set<PsiType> signature = new HashSet<PsiType>(Arrays.asList(psiMethod.getSignature(PsiSubstitutor.EMPTY).getParameterTypes())); + signature.add(psiMethod.getReturnType()); + boolean free = true; + for (PsiType type : signature) { + if (classSubstitutor != null) { + type = classSubstitutor.substitute(type); + } + if (type != null && PsiPolyExpressionUtil.mentionsTypeParameters(type, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { + free = false; + break; + } + } + if (free) return psiMethod; } } - if (containingClass.isPhysical() && containingClass.hasTypeParameters()) { + if (containingClass.hasTypeParameters()) { final PsiElement qualifier = getQualifier(); + PsiJavaCodeReferenceElement referenceElement = null; if (qualifier instanceof PsiTypeElement) { - final PsiJavaCodeReferenceElement referenceElement = ((PsiTypeElement)qualifier).getInnermostComponentReferenceElement(); - if (referenceElement != null) { - final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); - if (parameterList == null || parameterList.getTypeParameterElements().length == 0) { - return null; - } - } + referenceElement = ((PsiTypeElement)qualifier).getInnermostComponentReferenceElement(); } else if (qualifier instanceof PsiReferenceExpression) { final PsiReferenceExpression expression = (PsiReferenceExpression)qualifier; if (qualifierResolveResult.isReferenceTypeQualified()) { - final PsiReferenceParameterList parameterList = expression.getParameterList(); - if (parameterList == null || parameterList.getTypeParameterElements().length == 0) { - return null; - } + referenceElement = expression; + } + } + if (referenceElement != null) { + final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); + if (parameterList == null || parameterList.getTypeParameterElements().length == 0) { + return null; } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java index e85e81cb4bd8..743bd36abf5f 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceParameterListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,7 @@ import org.jetbrains.annotations.NotNull; */ public class PsiReferenceParameterListImpl extends CompositePsiElement implements PsiReferenceParameterList { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceParameterListImpl"); + private static final TokenSet TYPE_SET = TokenSet.create(JavaElementType.TYPE); public PsiReferenceParameterListImpl() { super(JavaElementType.REFERENCE_PARAMETER_LIST); @@ -124,23 +126,8 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement final TreeElement firstAdded = super.addInternal(first, last, anchor, before); - if (first == last && first.getElementType() == JavaElementType.TYPE){ - for(ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()){ - if (child.getElementType() == JavaTokenType.COMMA) break; - if (child.getElementType() == JavaElementType.TYPE){ - TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, first, Boolean.FALSE); - break; - } - } - for(ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()){ - if (child.getElementType() == JavaTokenType.COMMA) break; - if (child.getElementType() == JavaElementType.TYPE){ - TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, child, Boolean.FALSE); - break; - } - } + if (first == last && first.getElementType() == JavaElementType.TYPE) { + JavaSourceUtil.addSeparatingComma(this, first, TYPE_SET); } return firstAdded; @@ -148,17 +135,8 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement @Override public void deleteChildInternal(@NotNull ASTNode child) { - if (child.getElementType() == JavaElementType.TYPE){ - ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == JavaTokenType.COMMA){ - deleteChildInternal(next); - } - else{ - ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == JavaTokenType.COMMA){ - deleteChildInternal(prev); - } - } + if (child.getElementType() == JavaElementType.TYPE) { + JavaSourceUtil.deleteSeparatingComma(this, child); } super.deleteChildInternal(child); @@ -186,6 +164,7 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement } } + @Override public String toString() { return "PsiReferenceParameterList"; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java index 43d9d80c5742..2a3bdbaa2f4e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/TypeParameterListElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,7 @@ import org.jetbrains.annotations.NotNull; */ public class TypeParameterListElement extends CompositeElement { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.TypeParameterListElement"); + private static final TokenSet TYPE_PARAMETER_SET = TokenSet.create(JavaElementType.TYPE_PARAMETER); public TypeParameterListElement() { super(JavaElementType.TYPE_PARAMETER_LIST); @@ -82,25 +84,9 @@ public class TypeParameterListElement extends CompositeElement { } } - final TreeElement firstAdded = super.addInternal(first, last, anchor, before); - + TreeElement firstAdded = super.addInternal(first, last, anchor, before); if (first == last && first.getElementType() == JavaElementType.TYPE_PARAMETER) { - for(ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()){ - if (child.getElementType() == JavaTokenType.COMMA) break; - if (child.getElementType() == JavaElementType.TYPE_PARAMETER){ - final TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, first, Boolean.FALSE); - break; - } - } - for(ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()){ - if (child.getElementType() == JavaTokenType.COMMA) break; - if (child.getElementType() == JavaElementType.TYPE_PARAMETER){ - final TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager()); - super.addInternal(comma, comma, child, Boolean.FALSE); - break; - } - } + JavaSourceUtil.addSeparatingComma(this, first, TYPE_PARAMETER_SET); } return firstAdded; } @@ -108,18 +94,11 @@ public class TypeParameterListElement extends CompositeElement { @Override public void deleteChildInternal(@NotNull final ASTNode child) { if (child.getElementType() == JavaElementType.TYPE_PARAMETER){ - final ASTNode next = PsiImplUtil.skipWhitespaceAndComments(child.getTreeNext()); - if (next != null && next.getElementType() == JavaTokenType.COMMA){ - deleteChildInternal(next); - } - else{ - final ASTNode prev = PsiImplUtil.skipWhitespaceAndCommentsBack(child.getTreePrev()); - if (prev != null && prev.getElementType() == JavaTokenType.COMMA){ - deleteChildInternal(prev); - } - } + JavaSourceUtil.deleteSeparatingComma(this, child); } + super.deleteChildInternal(child); + if (child.getElementType() == JavaElementType.TYPE_PARAMETER) { final ASTNode lt = findChildByRole(ChildRole.LT_IN_TYPE_LIST); final ASTNode next = PsiImplUtil.skipWhitespaceAndComments(lt.getTreeNext()); diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index 59083c625f82..3d9ea08125a8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -316,7 +316,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ // prefer derived class signatures.put(signature, info); - } else { + } + else { final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class); if (methodCallExpression != null) { final PsiReferenceExpression expression = methodCallExpression.getMethodExpression(); @@ -324,14 +325,16 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ PsiClass currentClass; if (qualifierExpression != null) { currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType()); - } else { + } + else { currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); } - if (currentClass != null && InheritanceUtil.isInheritorOrSelf(currentClass, class1, true) && InheritanceUtil.isInheritorOrSelf(currentClass, existingClass, true)) { - final PsiSubstitutor eSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY); - final PsiSubstitutor cSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY); - if (MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) { + if (currentClass != null) { + final PsiSubstitutor eSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY, null); + final PsiSubstitutor cSubstitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY, null); + if (eSubstitutor != null && cSubstitutor != null && + MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(eSubstitutor), method.getSignature(cSubstitutor))) { final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType()); final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType()); if (returnType != null && returnType1 != null && !returnType1.equals(returnType)) { diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java index 2b36a9c49b47..c12972d354c7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java @@ -83,7 +83,7 @@ public class MethodCandidatesProcessor extends MethodsProcessor{ public PsiType[] getArgumentTypes() { if (myExpressionTypes == null && argumentList != null) { final PsiType[] expressionTypes = getExpressionTypes(argumentList); - if (!MethodCandidateInfo.ourOverloadGuard.currentStack().isEmpty()) { + if (MethodCandidateInfo.isOverloadCheck()) { return expressionTypes; } myExpressionTypes = expressionTypes; |