summaryrefslogtreecommitdiff
path: root/java/java-psi-impl/src/com
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-08-07 11:11:08 -0700
committerTor Norbye <tnorbye@google.com>2013-08-07 11:11:08 -0700
commit6739a8f0977b70ddc8a8283b169902da3f2eecb3 (patch)
tree5c5573c2ac01544f02d9318671aa558769726289 /java/java-psi-impl/src/com
parentc1ace1f7e1e49c81bb4b75377c99f07be340abfe (diff)
downloadidea-6739a8f0977b70ddc8a8283b169902da3f2eecb3.tar.gz
Snapshot af729d01433bb5bbd6ca93c0fdf9778b36d624ce from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I214dd066d0d27444a26166c0eae1a5aaf3705d49
Diffstat (limited to 'java/java-psi-impl/src/com')
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java10
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/InheritanceImplUtil.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java36
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java34
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java1
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java52
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/LightClassReference.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/LightMemberReference.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/LightPackageReference.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java60
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/GraphInferencePolicy.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java29
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java167
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java21
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java10
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java31
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java74
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java60
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java27
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java313
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java313
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java38
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java34
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java60
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java35
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java646
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java54
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java54
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java45
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java425
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java42
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java32
-rw-r--r--java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java52
59 files changed, 467 insertions, 2466 deletions
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 4b245a060297..44055a7f08b0 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
@@ -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();
@@ -541,7 +541,7 @@ public class ExceptionUtil {
List<PsiClassType> result = ContainerUtil.newArrayList();
for (PsiClassType referencedType : referencedTypes) {
- final PsiType type = substitutor.substitute(referencedType);
+ final PsiType type = GenericsUtil.eliminateWildcards(substitutor.substitute(referencedType), false);
if (!(type instanceof PsiClassType)) continue;
PsiClassType classType = (PsiClassType)type;
PsiClass exceptionClass = ((PsiClassType)type).resolve();
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
index e8ca9d832771..a1b28c5c59a8 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowFactory.java
@@ -29,7 +29,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.PsiManagerEx;
-import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -163,10 +162,7 @@ public class ControlFlowFactory {
CopyOnWriteArrayList<ControlFlowContext> cached = cachedRef == null ? null : cachedRef.get();
if (cached == null) {
cached = ContainerUtil.createEmptyCOWList();
- Reference<CopyOnWriteArrayList<ControlFlowContext>> reference = new SoftReference<CopyOnWriteArrayList<ControlFlowContext>>(cached);
- cachedRef = ConcurrencyUtil.cacheOrGet(cachedFlows, element, reference);
- CopyOnWriteArrayList<ControlFlowContext> existing = cachedRef.get();
- if (existing != null) cached = existing;
+ cachedFlows.put(element, new SoftReference<CopyOnWriteArrayList<ControlFlowContext>>(cached));
}
return cached;
}
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 247477e20323..e9596f8dd96b 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
@@ -39,7 +39,8 @@ 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 (CommonClassNames.JAVA_LANG_OBJECT.equals(candidateClass.getQualifiedName())) return false;
if (CommonClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName())) return true;
Map<PsiClass, Boolean> map = CachedValuesManager.getManager(candidateClass.getProject()).
getCachedValue(candidateClass, new CachedValueProvider<Map<PsiClass, Boolean>>() {
@@ -50,7 +51,7 @@ public class InheritanceImplUtil {
return Result.create(map, candidateClass);
}
});
-
+
Boolean computed = map.get(baseClass);
if (computed == null) {
computed = isInheritor(candidateClass, baseClass, true, null);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
index 2bde13a67ae5..b805ef4cf8f0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
@@ -34,6 +34,7 @@ import com.intellij.psi.impl.source.JavaDummyHolderFactory;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.reference.SoftReference;
@@ -249,9 +250,12 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
}
- public boolean processPackageDirectories(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope, @NotNull Processor<PsiDirectory> consumer) {
+ public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
+ @NotNull GlobalSearchScope scope,
+ @NotNull Processor<PsiDirectory> consumer,
+ boolean includeLibrarySources) {
for (PsiElementFinder finder : filteredFinders()) {
- if (!finder.processPackageDirectories(psiPackage, scope, consumer)) {
+ if (!finder.processPackageDirectories(psiPackage, scope, consumer, includeLibrarySources)) {
return false;
}
}
@@ -371,7 +375,11 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
for (PsiFile file : dir.getFiles()) {
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
VirtualFile vFile = file.getVirtualFile();
- if (vFile != null && !facade.isInSourceContent(vFile) && !(file instanceof PsiCompiledElement)) {
+ if (vFile != null &&
+ !(file instanceof PsiCompiledElement) &&
+ !facade.isInSourceContent(vFile) &&
+ (!scope.isForceSearchingInLibrarySources() ||
+ !StubTreeLoader.getInstance().canHaveStub(vFile))) {
continue;
}
@@ -388,16 +396,20 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
}
@Override
- public boolean processPackageDirectories(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope, @NotNull final Processor<PsiDirectory> consumer) {
+ public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
+ @NotNull final GlobalSearchScope scope,
+ @NotNull final Processor<PsiDirectory> consumer,
+ boolean includeLibrarySources) {
final PsiManager psiManager = PsiManager.getInstance(getProject());
- return PackageIndex.getInstance(getProject()).getDirsByPackageName(psiPackage.getQualifiedName(), false).forEach(new ReadActionProcessor<VirtualFile>() {
- @Override
- public boolean processInReadAction(final VirtualFile dir) {
- if (!scope.contains(dir)) return true;
- PsiDirectory psiDir = psiManager.findDirectory(dir);
- return psiDir == null || consumer.process(psiDir);
- }
- });
+ return PackageIndex.getInstance(getProject()).getDirsByPackageName(psiPackage.getQualifiedName(), includeLibrarySources)
+ .forEach(new ReadActionProcessor<VirtualFile>() {
+ @Override
+ public boolean processInReadAction(final VirtualFile dir) {
+ if (!scope.contains(dir)) return true;
+ PsiDirectory psiDir = psiManager.findDirectory(dir);
+ return psiDir == null || consumer.process(psiDir);
+ }
+ });
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
index a0f3e9a3e045..831f7ad2112e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl;
-import com.intellij.lang.ASTNode;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
@@ -430,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
@@ -441,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) {
@@ -693,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;
}
}
@@ -1041,14 +1040,8 @@ public class PsiClassImplUtil {
@NotNull
private static PsiElement originalElement(@NotNull PsiClass aClass) {
final PsiElement originalElement = aClass.getOriginalElement();
- ASTNode node = originalElement.getNode();
- if (node != null) {
- final PsiCompiledElement compiled = node.getUserData(ClsElementImpl.COMPILED_ELEMENT);
- if (compiled != null) {
- return compiled;
- }
- }
- return originalElement;
+ final PsiCompiledElement compiled = originalElement.getUserData(ClsElementImpl.COMPILED_ELEMENT);
+ return compiled != null ? compiled : originalElement;
}
public static boolean isFieldEquivalentTo(@NotNull PsiField field, PsiElement another) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
index 9ac1dd20098a..5b659f0f4631 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
@@ -182,11 +182,12 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
public PsiTypeParameter createTypeParameter(String name, PsiClassType[] superTypes) {
@NonNls StringBuilder builder = new StringBuilder();
builder.append("public <").append(name);
- if (superTypes.length > 1) {
+ if (superTypes.length > 1 ||
+ superTypes.length == 1 && !superTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
builder.append(" extends ");
for (PsiClassType type : superTypes) {
if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) continue;
- builder.append(type.getCanonicalText()).append(',');
+ builder.append(type.getCanonicalText()).append('&');
}
builder.delete(builder.length() - 1, builder.length());
@@ -755,4 +756,33 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
GeneratedMarkerVisitor.markGenerated(catchSection);
return catchSection;
}
+
+ @Override
+ public boolean isValidClassName(@NotNull String name) {
+ return isIdentifier(name);
+ }
+
+ @Override
+ public boolean isValidMethodName(@NotNull String name) {
+ return isIdentifier(name);
+ }
+
+ @Override
+ public boolean isValidParameterName(@NotNull String name) {
+ return isIdentifier(name);
+ }
+
+ @Override
+ public boolean isValidFieldName(@NotNull String name) {
+ return isIdentifier(name);
+ }
+
+ @Override
+ public boolean isValidLocalVariableName(@NotNull String name) {
+ return isIdentifier(name);
+ }
+
+ private boolean isIdentifier(@NotNull String name) {
+ return JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isIdentifier(name);
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index 61e71bbb7270..c27bfdc68d62 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -168,6 +168,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
}
}
if (!wildcard.isBounded()) return PsiWildcardType.createUnbounded(wildcardType.getManager());
+ return newBound;
}
return rebound(wildcardType, newBound);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
index 466a53cb0514..68e5b0f02ec7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.compiled;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -29,6 +30,7 @@ import com.intellij.util.indexing.FileContent;
* @author max
*/
public class ClassFileStubBuilder implements BinaryFileStubBuilder {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClassFileStubBuilder");
public static final int STUB_VERSION = JavaFileElementType.STUB_VERSION + 6;
@Override
@@ -49,6 +51,9 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder {
if (stub != null) return stub;
}
}
+ if (!fileContent.getFileName().contains("$")) {
+ LOG.info("No stub built for file " + fileContent);
+ }
return null;
}
catch (ClsFormatException e) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
index e73ac2a3ccdf..60e343b188e7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsClassImpl.java
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
index 5f55a5bd0412..3fbfc4ba69c2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
@@ -288,7 +288,7 @@ public abstract class ClsElementImpl extends PsiElementBase implements PsiCompil
throw new InvalidMirrorException(element.getElementType() + " != " + type);
}
- element.putUserData(COMPILED_ELEMENT, this);
+ element.getPsi().putUserData(COMPILED_ELEMENT, this);
myMirror = element;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
index 05655345dbb7..a6820cd13164 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
@@ -421,13 +421,13 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
stubTree = (StubTree)StubTreeLoader.getInstance().readOrBuild(getProject(), getVirtualFile(), this);
if (stubTree == null) {
- LOG.warn("Class file is corrupted: " + getVirtualFile().getPresentableUrl());
+ LOG.warn("No stub for class file in index: " + getVirtualFile().getPresentableUrl());
stubTree = new StubTree(new PsiJavaFileStubImpl("corrupted.classfiles", true));
}
-
- myStub = new SoftReference<StubTree>(stubTree);
//noinspection unchecked
((PsiFileStubImpl)stubTree.getRoot()).setPsi(this);
+
+ myStub = new SoftReference<StubTree>(stubTree);
}
return stubTree;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
index 7c2e8e0e5068..3096f2485d6b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
@@ -199,7 +199,7 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
throw new RuntimeException("Variants are not available for light references");
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java
index bb2776b5f026..155e0daa7fc2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceExpressionImpl.java
@@ -169,7 +169,7 @@ public class ClsReferenceExpressionImpl extends ClsElementImpl implements PsiRef
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
myPatternExpression.processVariants(processor);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java
index 937def146dab..cf6e15928d59 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeParameterImpl.java
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
index 20ab20211c95..d023667ef063 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
@@ -29,6 +29,7 @@ import com.intellij.psi.impl.source.tree.java.PsiCompositeModifierList;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.NameHint;
import com.intellij.psi.scope.PsiScopeProcessor;
+import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.reference.SoftReference;
@@ -47,6 +48,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
public static boolean DEBUG = false;
private volatile CachedValue<PsiModifierList> myAnnotationList;
private volatile CachedValue<Collection<PsiDirectory>> myDirectories;
+ private volatile CachedValue<Collection<PsiDirectory>> myDirectoriesWithLibSources;
private volatile SoftReference<Set<String>> myPublicClassNamesCache;
public PsiPackageImpl(PsiManager manager, String qualifiedName) {
@@ -54,19 +56,31 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
}
@Override
- protected Collection<PsiDirectory> getAllDirectories() {
- if (myDirectories == null) {
- myDirectories = CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new CachedValueProvider<Collection<PsiDirectory>>() {
- @Override
- public Result<Collection<PsiDirectory>> compute() {
- final CommonProcessors.CollectProcessor<PsiDirectory> processor = new CommonProcessors.CollectProcessor<PsiDirectory>();
- getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor);
- return Result.create(processor.getResults(), PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(
- PsiPackageImpl.this));
- }
- }, false);
+ protected Collection<PsiDirectory> getAllDirectories(boolean includeLibrarySources) {
+ if (includeLibrarySources) {
+ if (myDirectoriesWithLibSources == null) {
+ myDirectoriesWithLibSources = createCachedDirectories(true);
+ }
+ return myDirectoriesWithLibSources.getValue();
+ }
+ else {
+ if (myDirectories == null) {
+ myDirectories = createCachedDirectories(false);
+ }
+ return myDirectories.getValue();
}
- return myDirectories.getValue();
+ }
+
+ private CachedValue<Collection<PsiDirectory>> createCachedDirectories(final boolean includeLibrarySources) {
+ return CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new CachedValueProvider<Collection<PsiDirectory>>() {
+ @Override
+ public Result<Collection<PsiDirectory>> compute() {
+ final CommonProcessors.CollectProcessor<PsiDirectory> processor = new CommonProcessors.CollectProcessor<PsiDirectory>();
+ getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor, includeLibrarySources);
+ return Result.create(processor.getResults(), PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(
+ PsiPackageImpl.this));
+ }
+ }, false);
}
@Override
@@ -103,7 +117,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
@Override
public boolean isValid() {
- return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories().isEmpty();
+ return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories(true).isEmpty();
}
@Override
@@ -165,7 +179,17 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
SoftReference<Set<String>> ref = myPublicClassNamesCache;
Set<String> cache = ref == null ? null : ref.get();
if (cache == null) {
- cache = getFacade().getClassNames(this, allScope());
+ GlobalSearchScope scope = allScope();
+
+ if (!scope.isForceSearchingInLibrarySources()) {
+ scope = new DelegatingGlobalSearchScope(scope) {
+ @Override
+ public boolean isForceSearchingInLibrarySources() {
+ return true;
+ }
+ };
+ }
+ cache = getFacade().getClassNames(this, scope);
myPublicClassNamesCache = new SoftReference<Set<String>>(cache);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java
index 2de3bc886f0c..baef0daece76 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClassReference.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClassReference.java
index e47d8965bfe3..163e0266d656 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClassReference.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClassReference.java
@@ -119,7 +119,7 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
}
@Override
- public void processVariants(PsiScopeProcessor processor){
+ public void processVariants(@NotNull PsiScopeProcessor processor){
throw new RuntimeException("Variants are not available for light references");
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMemberReference.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMemberReference.java
index f1f5d484135f..bc90ac135613 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMemberReference.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMemberReference.java
@@ -61,7 +61,7 @@ public class LightMemberReference extends LightElement implements PsiJavaCodeRef
}
@Override
- public void processVariants(PsiScopeProcessor processor){
+ public void processVariants(@NotNull PsiScopeProcessor processor){
throw new RuntimeException("Variants are not available for light references");
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightPackageReference.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightPackageReference.java
index 1f5abf5560f5..7aa6aaac83af 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightPackageReference.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightPackageReference.java
@@ -138,7 +138,7 @@ public class LightPackageReference extends LightElement implements PsiJavaCodeRe
}
@Override
- public void processVariants(PsiScopeProcessor processor){
+ public void processVariants(@NotNull PsiScopeProcessor processor){
throw new RuntimeException("Variants are not available for light references");
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java
index 3ce5161b4ff9..6d6229c32886 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java
index e05d5eb2d731..4b28435bf089 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java
@@ -260,7 +260,7 @@ public class PsiEnumConstantImpl extends JavaStubPsiElement<PsiFieldStub> implem
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java
index 2a71d6e6303d..a98412f5b0b5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java
@@ -239,8 +239,9 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
@Override
public boolean hasInitializer() {
- if (getStub() != null) {
- return getInitializerText() != null;
+ PsiFieldStub stub = getStub();
+ if (stub != null) {
+ return stub.getInitializerText() != null;
}
return getInitializer() != null;
@@ -327,16 +328,6 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
return JavaResolveCache.getInstance(getProject()).computeConstantValueWithCaching(this, OurConstValueComputer.INSTANCE, visitedVars);
}
- @Nullable
- private String getInitializerText() {
- final PsiFieldStub stub = getStub();
- if (stub != null) {
- return stub.getInitializerText();
- }
-
- throw new RuntimeException("Shall not be called when in stubless mode");
- }
-
@Override
public boolean isDeprecated() {
final PsiFieldStub stub = getStub();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java
index da73dcde6404..affc24678325 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStaticReferenceElementImpl.java
@@ -320,7 +320,7 @@ public class PsiImportStaticReferenceElementImpl extends CompositePsiElement imp
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
FilterScopeProcessor proc = new FilterScopeProcessor(new ClassFilter(PsiModifierListOwner.class), processor);
PsiScopesUtil.resolveAndWalk(proc, this, null, true);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index 9605d07b619c..48a0e0948132 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -24,7 +24,6 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
import com.intellij.psi.filters.*;
-import com.intellij.psi.filters.classes.AnnotationTypeFilter;
import com.intellij.psi.filters.element.ModifierFilter;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.DebugUtil;
@@ -55,7 +54,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl");
private volatile String myCachedQName = null;
- private volatile String myCachedTextSkipWhiteSpaceAndComments;
+ private volatile String myCachedNormalizedText;
private int myKindWhenDummy = CLASS_NAME_KIND;
public static final int CLASS_NAME_KIND = 1;
@@ -291,12 +290,12 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
else {
LOG.assertTrue(target == null, target);
- return getTextSkipWhiteSpaceAndComments();
+ return getNormalizedText();
}
case PACKAGE_NAME_KIND:
case CLASS_FQ_NAME_KIND:
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
- return getTextSkipWhiteSpaceAndComments();
+ return getNormalizedText();
default:
LOG.assertTrue(false);
@@ -322,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);
}
}
@@ -380,19 +380,18 @@ 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
- String text = getTextSkipWhiteSpaceAndComments();
+ String text = getNormalizedText();
if (StringUtil.isEmptyOrSpaces(text)) return JavaResolveResult.EMPTY_ARRAY;
PsiClass aClass = JavaPsiFacade.getInstance(getProject()).findClass(text, getResolveScope());
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;
}
@@ -432,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();
}
@@ -440,12 +439,12 @@ 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();
}
case PACKAGE_NAME_KIND: {
- String packageName = getTextSkipWhiteSpaceAndComments();
+ String packageName = getNormalizedText();
Project project = getManager().getProject();
PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName);
if (aPackage == null || !aPackage.isValid()) {
@@ -457,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;
@@ -712,10 +711,10 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
return name != null && referenceNameElement.getText().equals(name) && element.getManager().areElementsEquivalent(resolve(), element);
}
- private String getTextSkipWhiteSpaceAndComments() {
- String whiteSpaceAndComments = myCachedTextSkipWhiteSpaceAndComments;
+ private String getNormalizedText() {
+ String whiteSpaceAndComments = myCachedNormalizedText;
if (whiteSpaceAndComments == null) {
- myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
+ myCachedNormalizedText = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
}
return whiteSpaceAndComments;
}
@@ -724,7 +723,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
public String getClassNameText() {
String cachedQName = myCachedQName;
if (cachedQName == null) {
- myCachedQName = cachedQName = PsiNameHelper.getQualifiedClassName(getTextSkipWhiteSpaceAndComments(), false);
+ myCachedQName = cachedQName = PsiNameHelper.getQualifiedClassName(getNormalizedText(), false);
}
return cachedQName;
}
@@ -753,7 +752,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
public void clearCaches() {
super.clearCaches();
myCachedQName = null;
- myCachedTextSkipWhiteSpaceAndComments = null;
+ myCachedNormalizedText = null;
}
@Override
@@ -797,7 +796,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
@Override
- public void processVariants(final PsiScopeProcessor processor) {
+ public void processVariants(@NotNull final PsiScopeProcessor processor) {
final OrFilter filter = new OrFilter();
if (isInCode() && !(getParent() instanceof PsiImportStatement)) {
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
@@ -805,11 +804,11 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
switch (getKind()) {
case CLASS_OR_PACKAGE_NAME_KIND:
- addClassFilter(filter);
+ filter.addFilter(ElementClassFilter.CLASS);
filter.addFilter(ElementClassFilter.PACKAGE_FILTER);
break;
case CLASS_NAME_KIND:
- addClassFilter(filter);
+ filter.addFilter(ElementClassFilter.CLASS);
if (isQualified()) {
filter.addFilter(ElementClassFilter.PACKAGE_FILTER);
}
@@ -867,15 +866,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
return false;
}
- private void addClassFilter(final OrFilter filter) {
- if (getParent() instanceof PsiAnnotation) {
- filter.addFilter(new AnnotationTypeFilter());
- }
- else {
- filter.addFilter(ElementClassFilter.CLASS);
- }
- }
-
@Override
public PsiElement getReferenceNameElement() {
return SourceTreeToPsiMap.treeElementToPsi(getReferenceNameNode());
@@ -918,7 +908,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
case PACKAGE_NAME_KIND:
case CLASS_FQ_NAME_KIND:
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
- return getTextSkipWhiteSpaceAndComments(); // there cannot be any <...>
+ return getNormalizedText(); // there cannot be any <...>
default:
LOG.assertTrue(false);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java
index fccee00e96e2..ebc3168758e7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java
@@ -226,7 +226,7 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
for (final PsiElement element : getVariants()) {
if (!processor.execute(element, ResolveState.initial())) {
return;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java
index 36f7c61047f5..21e8c6cbbc38 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java
@@ -157,7 +157,7 @@ public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValu
}
@Override
- public void processVariants(PsiScopeProcessor processor) {
+ public void processVariants(@NotNull PsiScopeProcessor processor) {
for (final PsiElement element : getVariants()) {
if (!processor.execute(element, ResolveState.initial())) {
return;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/GraphInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/GraphInferencePolicy.java
index 0b895d74dc16..1b2ea842e46b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/GraphInferencePolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/GraphInferencePolicy.java
@@ -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) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
index 981739b7d815..6bb94b3d7a5c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
@@ -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;
}
@@ -148,7 +149,7 @@ public class JavaResolveUtil {
}
if (!facade.arePackagesTheSame(member, place)) return false;
- if (modifierList.hasModifierProperty(PsiModifier.STATIC)) return true;
+ //if (modifierList.hasModifierProperty(PsiModifier.STATIC)) return true;
// maybe inheritance lead through package local class in other package ?
final PsiClass placeClass = getContextClass(place);
if (memberClass == null || placeClass == null) return true;
@@ -192,13 +193,13 @@ public class JavaResolveUtil {
if (placeParent instanceof PsiClass && !(placeParent instanceof PsiAnonymousClass)) {
final boolean isTypeParameter = placeParent instanceof PsiTypeParameter;
if (isTypeParameter && isAtLeast17 == null) {
- isAtLeast17 = JavaVersionService.getInstance().isAtLeast(place, JavaSdkVersion.JDK_1_7);
+ isAtLeast17 = JavaVersionService.getInstance().isAtLeast(placeParent, 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;
+ }
} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
index 3509fd90a93c..1b33cfb196b6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
@@ -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();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index 6dd543993fb6..d24bfd9ff654 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -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,21 +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];
- PsiFile file = parent.getContainingFile();
- LOG.assertTrue(file != null, parent);
- final PsiManager manager = file.getManager();
- final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
for (int i = 0; i < typeParameters.length; i++) {
if (substitutions[i] != null) continue;
final Pair<PsiType, ConstraintType> constraint =
@@ -409,7 +407,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
substitutionFromBounds = currentSubstitution;
}
else {
- substitutionFromBounds = GenericsUtil.getLeastUpperBound(substitutionFromBounds, currentSubstitution, manager);
+ substitutionFromBounds = GenericsUtil.getLeastUpperBound(substitutionFromBounds, currentSubstitution, myManager);
}
}
}
@@ -453,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) {
@@ -470,6 +468,17 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
@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,
@NotNull PsiType[] leftTypes,
@NotNull PsiType[] rightTypes,
@NotNull LanguageLevel languageLevel) {
@@ -495,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 {
@@ -503,7 +512,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
lowerBound = current;
}
else {
- lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, current, typeParameter.getManager());
+ lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, current, myManager);
}
}
}
@@ -524,14 +533,20 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
private static Pair<PsiType, ConstraintType> processArgType(PsiType arg, final ConstraintType constraintType,
final boolean captureWildcard) {
if (arg instanceof PsiWildcardType && !captureWildcard) return FAILED_INFERENCE;
- if (arg != PsiType.NULL) return new Pair<PsiType, ConstraintType>(arg, constraintType);
+ if (arg != PsiType.NULL) {
+ if (arg instanceof PsiWildcardType) {
+ final PsiType bound = ((PsiWildcardType)arg).getBound();
+ if (bound instanceof PsiClassType && ((PsiClassType)bound).isRaw()) return Pair.create(null, constraintType);
+ }
+ return new Pair<PsiType, ConstraintType>(arg, constraintType);
+ }
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) {
@@ -553,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);
@@ -612,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) {
@@ -642,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,
@@ -722,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) {
@@ -779,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;
@@ -805,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();
@@ -843,12 +858,12 @@ 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,
final int depth) {
- if (arg instanceof PsiCapturedWildcardType) arg = ((PsiCapturedWildcardType)arg).getWildcard(); //reopen
+ if (arg instanceof PsiCapturedWildcardType && (depth < 2 || constraintType != ConstraintType.EQUALS)) arg = ((PsiCapturedWildcardType)arg).getWildcard(); //reopen
if (patternType.equals(param)) {
return processArgType(arg, constraintType, depth < 2);
@@ -905,7 +920,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
if (substituted != null) {
Pair<PsiType, ConstraintType> res = getSubstitutionForTypeParameterInner(
superSubstitutor.substitute(typeParameter), substituted, patternType, ConstraintType.EQUALS, depth + 1);
- if (res != null) return res;
+ if (res != null) {
+ if (res == FAILED_INFERENCE) continue;
+ return res;
+ }
}
}
}
@@ -931,6 +949,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
return inferBySubtypingConstraint(patternType, constraintType, depth, paramClass, argClass);
}
+ PsiType lowerBound = PsiType.NULL;
+ PsiType upperBound = PsiType.NULL;
Pair<PsiType,ConstraintType> wildcardCaptured = null;
for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(paramClass)) {
PsiType paramType = paramResult.getSubstitutor().substitute(typeParameter);
@@ -952,13 +972,35 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
Pair<PsiType,ConstraintType> res = getSubstitutionForTypeParameterInner(paramType, argType, patternType, ConstraintType.EQUALS, depth + 1);
if (res != null) {
- PsiType type = res.getFirst();
- if (!(type instanceof PsiWildcardType)) return res;
- if (wildcardCaptured != null) return FAILED_INFERENCE;
- wildcardCaptured = res;
+ final PsiType type = res.getFirst();
+ switch (res.getSecond()) {
+ case EQUALS:
+ if (!(type instanceof PsiWildcardType)) return res;
+ if (wildcardCaptured != null) return FAILED_INFERENCE;
+ wildcardCaptured = res;
+ break;
+ case SUPERTYPE:
+ wildcardCaptured = res;
+ if (PsiType.NULL.equals(lowerBound)) {
+ lowerBound = type;
+ }
+ else if (!lowerBound.equals(type)) {
+ lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, myManager);
+ if (lowerBound == null) return FAILED_INFERENCE;
+ }
+ break;
+ case SUBTYPE:
+ wildcardCaptured = res;
+ if (PsiType.NULL.equals(upperBound) || TypeConversionUtil.isAssignable(upperBound, type)) {
+ upperBound = type;
+ }
+ }
}
}
+ if (lowerBound != PsiType.NULL) return new Pair<PsiType, ConstraintType>(lowerBound, ConstraintType.SUPERTYPE);
+ if (upperBound != PsiType.NULL) return new Pair<PsiType, ConstraintType>(upperBound, ConstraintType.SUBTYPE);
+
return wildcardCaptured;
}
@@ -966,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,
@@ -1010,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);
@@ -1065,7 +1107,6 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
}
}
- final PsiManager manager = typeParameter.getManager();
final GlobalSearchScope scope = parent.getResolveScope();
PsiType returnType = null;
if (constraint == null) {
@@ -1093,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();
@@ -1129,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())) {
@@ -1156,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) {
@@ -1213,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) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java
index 09199569aaa0..02e025c98431 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ResolveVariableUtil.java
@@ -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();
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
index c544598b25c5..f72ee4f54427 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
@@ -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){
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java
index 83261a3bdcae..5e0865e0ec45 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java
@@ -46,7 +46,15 @@ public class SourceUtil {
@Override
public void visitLeaf(LeafElement leaf) {
if (!REF_FILTER.contains(leaf.getElementType())) {
- buffer.append(leaf.getText());
+ String leafText = leaf.getText();
+ if (buffer.length() > 0 && leafText.length() > 0 && Character.isJavaIdentifierPart(leafText.charAt(0))) {
+ char lastInBuffer = buffer.charAt(buffer.length() - 1);
+ if (lastInBuffer == '?' || Character.isJavaIdentifierPart(lastInBuffer)) {
+ buffer.append(" ");
+ }
+ }
+
+ buffer.append(leafText);
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
index 74d1350b3dc7..f6c790a362c9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
@@ -382,7 +382,8 @@ public class PsiLiteralExpressionImpl
@Override
@NotNull
public PsiReference[] getReferences() {
- return PsiReferenceService.getService().getContributedReferences(this);
+ PsiReference[] references = PsiReferenceService.getService().getContributedReferences(this);
+ return references;
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
index 699e33476b48..1dd74f133dcf 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
@@ -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>() {
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 109d32dccecf..2cd3f29c37bc 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
@@ -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);
@@ -93,7 +92,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
@Override
- public void processVariants(final PsiScopeProcessor processor) {
+ public void processVariants(@NotNull final PsiScopeProcessor processor) {
final FilterScopeProcessor proc = new FilterScopeProcessor(ElementClassFilter.METHOD, processor);
PsiScopesUtil.resolveAndWalk(proc, this, null, true);
}
@@ -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) {
@@ -446,7 +446,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final boolean validConstructorRef = psiMethod.isConstructor() && (myContainingClass.getContainingClass() == null || myContainingClass.hasModifierProperty(PsiModifier.STATIC));
final boolean staticOrValidConstructorRef = psiMethod.hasModifierProperty(PsiModifier.STATIC) || validConstructorRef;
- if ((parameterTypes.length == signatureParameterTypes2.length || varArgs) &&
+ if ((parameterTypes.length == signatureParameterTypes2.length || varArgs) &&
(!(myBeginsWithReferenceType ^ staticOrValidConstructorRef) || (psiMethod.isConstructor() && conflict.isStaticsScopeCorrect()))) {
boolean correct = true;
for (int i = 0; i < parameterTypes.length; i++) {
@@ -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;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
index 4b2dc0b96d3d..932bec004fb5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
@@ -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;
@@ -61,7 +61,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl");
private volatile String myCachedQName = null;
- private volatile String myCachedTextSkipWhiteSpaceAndComments = null;
+ private volatile String myCachedNormalizedText = null;
public PsiReferenceExpressionImpl() {
super(JavaElementType.REFERENCE_EXPRESSION);
@@ -177,20 +177,12 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
@Override
public void clearCaches() {
myCachedQName = null;
- myCachedTextSkipWhiteSpaceAndComments = null;
+ myCachedNormalizedText = null;
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);
}
@@ -303,7 +298,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
@NotNull
private JavaResolveResult[] resolveToPackage(PsiFile containingFile) {
- final String packageName = getCachedTextSkipWhiteSpaceAndComments();
+ final String packageName = getCachedNormalizedText();
Project project = containingFile.getProject();
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiPackage aPackage = psiFacade.findPackage(packageName);
@@ -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();
}
@@ -371,7 +366,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
" resolves to:" + LogUtil.objectAndClass(element) +
" parent:" + LogUtil.objectAndClass(element.getParent()));
}
- return getCachedTextSkipWhiteSpaceAndComments();
+ return getCachedNormalizedText();
}
private static final Function<PsiReferenceExpressionImpl, PsiType> TYPE_EVALUATOR = new TypeEvaluator();
@@ -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
@@ -727,7 +727,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
public String getClassNameText() {
String cachedQName = myCachedQName;
if (cachedQName == null) {
- myCachedQName = cachedQName = PsiNameHelper.getQualifiedClassName(getCachedTextSkipWhiteSpaceAndComments(), false);
+ myCachedQName = cachedQName = PsiNameHelper.getQualifiedClassName(getCachedNormalizedText(), false);
}
return cachedQName;
}
@@ -761,10 +761,10 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
}
}
- private String getCachedTextSkipWhiteSpaceAndComments() {
- String whiteSpaceAndComments = myCachedTextSkipWhiteSpaceAndComments;
+ private String getCachedNormalizedText() {
+ String whiteSpaceAndComments = myCachedNormalizedText;
if (whiteSpaceAndComments == null) {
- myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
+ myCachedNormalizedText = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
}
return whiteSpaceAndComments;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java
index bfd7482724d8..fccd07418045 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeCastExpressionImpl.java
@@ -18,6 +18,7 @@ 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.Constants;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.tree.IElementType;
@@ -46,7 +47,7 @@ public class PsiTypeCastExpressionImpl extends ExpressionPsiElement implements P
@Nullable public PsiType getType() {
final PsiTypeElement castType = getCastType();
if (castType == null) return null;
- return castType.getType();
+ return PsiImplUtil.normalizeWildcardTypeByPosition(castType.getType(), this);
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java
index 12bc9fb34ca2..f03b44e8adb9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterImpl.java
@@ -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
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 f74d883834cf..50218fe92adf 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
@@ -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());
@@ -302,6 +308,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
final PsiType returnType = eSubstitutor.substitute(existingMethod.getReturnType());
final PsiType returnType1 = cSubstitutor.substitute(method.getReturnType());
if (returnType != null && returnType1 != null && !returnType1.equals(returnType) && TypeConversionUtil.isAssignable(returnType, returnType1, false)) {
+ if (class1.isInterface() && !existingClass.isInterface()) continue;
conflicts.remove(existing);
} else {
conflicts.remove(i);
@@ -449,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);
}
@@ -459,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();
@@ -503,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;
@@ -519,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 {
@@ -625,6 +634,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
private static Specifics chooseHigherDimension(PsiType type1, PsiType type2) {
+ if (type1 != null && type1.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return null;
+ if (type2 != null && type2.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return null;
int d1 = type1 != null ? type1.getArrayDimensions() : 0;
int d2 = type2 != null ? type2.getArrayDimensions() : 0;
if (d1 > d2) {
@@ -703,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);
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java
index 6a226eb6ec9f..f46dd70fc398 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java
@@ -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
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 e38ba9808905..ad0e7358842c 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
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java
index 95ac928952de..736433a089c4 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java
@@ -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
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java
index 79873741a08a..47e8b8a6d81a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java
@@ -46,10 +46,14 @@ public abstract class MethodsProcessor extends ConflictFilterProcessor implement
protected PsiClass myAccessClass = null;
private PsiExpressionList myArgumentList;
private PsiType[] myTypeArguments;
- private LanguageLevel myLanguageLevel;
-
- public MethodsProcessor(@NotNull PsiConflictResolver[] resolvers, @NotNull List<CandidateInfo> container, @NotNull PsiElement place) {
- super(null, ourFilter, resolvers, container, place);
+ private final LanguageLevel myLanguageLevel;
+
+ 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);
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
index 46036ea6e6ff..8556ee13e513 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
@@ -81,9 +81,6 @@ public class PsiScopesUtil {
if (scope == maxScope) break;
prevParent = scope;
scope = prevParent.getContext();
- if (scope != null && scope != prevParent.getParent() && !scope.isValid()) {
- break;
- }
processor.handleEvent(JavaScopeProcessorEvent.CHANGE_LEVEL, null);
}
@@ -131,9 +128,7 @@ public class PsiScopesUtil {
}
else if (type instanceof PsiDisjunctionType) {
final PsiType lub = ((PsiDisjunctionType)type).getLeastUpperBound();
- if (lub != null) {
- processTypeDeclarations(lub, place, processor);
- }
+ processTypeDeclarations(lub, place, processor);
}
else {
final JavaResolveResult result = PsiUtil.resolveGenericsClassInType(type);
@@ -222,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) {
@@ -307,12 +305,15 @@ public class PsiScopesUtil {
final PsiElement referenceName = methodCall.getMethodExpression().getReferenceNameElement();
final PsiManager manager = call.getManager();
final PsiElement qualifier = ref.getQualifier();
-
+ if (referenceName == null) {
+ // e.g. "manager.(beginTransaction)"
+ throw new MethodProcessorSetupFailedException("Can't resolve method name for this expression");
+ }
if (referenceName instanceof PsiIdentifier && qualifier instanceof PsiExpression) {
PsiType type = ((PsiExpression)qualifier).getType();
if (type != null && qualifier instanceof PsiReferenceExpression) {
final PsiElement resolve = ((PsiReferenceExpression)qualifier).resolve();
- if (resolve instanceof PsiVariable && ((PsiVariable)resolve).hasModifierProperty(PsiModifier.FINAL)) {
+ if (resolve instanceof PsiVariable && ((PsiVariable)resolve).hasModifierProperty(PsiModifier.FINAL) && ((PsiVariable)resolve).hasInitializer()) {
final PsiExpression initializer = ((PsiVariable)resolve).getInitializer();
if (initializer instanceof PsiNewExpression) {
final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass();
@@ -405,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) {
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
deleted file mode 100644
index 369613c46040..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
+++ /dev/null
@@ -1,313 +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.
- */
-
-/*
- * User: anna
- * Date: 22-Jun-2009
- */
-package com.intellij.refactoring.extractMethod;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.controlFlow.ControlFlow;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.refactoring.util.VariableData;
-import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
-import com.intellij.util.ArrayUtil;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-public class InputVariables {
- private final List<VariableData> myInputVariables;
-
- private List<? extends PsiVariable> myInitialParameters;
- private final Project myProject;
- private final LocalSearchScope myScope;
-
- private ParametersFolder myFolding;
- private boolean myFoldingAvailable;
-
- public InputVariables(final List<? extends PsiVariable> inputVariables,
- Project project,
- LocalSearchScope scope,
- boolean foldingAvailable) {
- myInitialParameters = inputVariables;
- myProject = project;
- myScope = scope;
- myFoldingAvailable = foldingAvailable;
- myFolding = new ParametersFolder();
- myInputVariables = wrapInputVariables(inputVariables);
- }
-
- /**
- * copy use only
- */
- public InputVariables(List<VariableData> inputVariables,
- Project project,
- LocalSearchScope scope) {
- myProject = project;
- myScope = scope;
- myInputVariables = new ArrayList<VariableData>(inputVariables);
- }
-
- public boolean isFoldable() {
- return myFolding.isFoldable();
- }
-
- public ArrayList<VariableData> wrapInputVariables(final List<? extends PsiVariable> inputVariables) {
- final ArrayList<VariableData> inputData = new ArrayList<VariableData>(inputVariables.size());
- for (PsiVariable var : inputVariables) {
- String name = var.getName();
- if (!(var instanceof PsiParameter)) {
- JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
- VariableKind kind = codeStyleManager.getVariableKind(var);
- name = codeStyleManager.variableNameToPropertyName(name, kind);
- name = codeStyleManager.propertyNameToVariableName(name, VariableKind.PARAMETER);
- }
- PsiType type = var.getType();
- if (type instanceof PsiEllipsisType) {
- type = ((PsiEllipsisType)type).toArrayType();
- }
- final Map<PsiCodeBlock, PsiType> casts = new HashMap<PsiCodeBlock, PsiType>();
- for (PsiReference reference : ReferencesSearch.search(var, myScope)) {
- final PsiElement element = reference.getElement();
- final PsiElement parent = element.getParent();
- final PsiCodeBlock block = PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class);
- if (parent instanceof PsiTypeCastExpression) {
- final PsiType currentType = casts.get(block);
- final PsiType castType = ((PsiTypeCastExpression)parent).getType();
- casts.put(block, casts.containsKey(block) && currentType == null ? null : getBroaderType(currentType, castType));
- } else {
- casts.put(block, null);
- }
- }
- if (!casts.containsValue(null)) {
- PsiType currentType = null;
- for (PsiType psiType : casts.values()) {
- currentType = getBroaderType(currentType, psiType);
- if (currentType == null) {
- break;
- }
- }
- if (currentType != null) {
- currentType = checkTopLevelInstanceOf(currentType);
- if (currentType != null) {
- type = currentType;
- }
- }
- }
-
- VariableData data = new VariableData(var, type);
- data.name = name;
- data.passAsParameter = true;
- inputData.add(data);
-
- if (myFoldingAvailable) myFolding.isParameterFoldable(data, myScope, inputVariables);
- }
-
-
- if (myFoldingAvailable) {
- final Set<VariableData> toDelete = new HashSet<VariableData>();
- for (int i = inputData.size() - 1; i >=0; i--) {
- final VariableData data = inputData.get(i);
- if (myFolding.isParameterSafeToDelete(data, myScope)) {
- toDelete.add(data);
- }
- }
- inputData.removeAll(toDelete);
- }
-
-
- return inputData;
- }
-
- @Nullable
- private PsiType checkTopLevelInstanceOf(final PsiType currentType) {
- final PsiElement[] scope = myScope.getScope();
- if (scope.length == 1 && scope[0] instanceof PsiIfStatement) {
- final PsiExpression condition = ((PsiIfStatement)scope[0]).getCondition();
- if (condition != null) {
- class CheckInstanceOf {
- boolean check(PsiInstanceOfExpression expr) {
- final PsiTypeElement checkType = expr.getCheckType();
- return checkType == null || !checkType.getType().equals(currentType);
- }
- }
- CheckInstanceOf checker = new CheckInstanceOf();
- final PsiInstanceOfExpression[] expressions = PsiTreeUtil.getChildrenOfType(condition, PsiInstanceOfExpression.class);
- if (expressions != null) {
- for (PsiInstanceOfExpression instanceOfExpression : expressions) {
- if (!checker.check(instanceOfExpression)) return null;
- }
- } else if (condition instanceof PsiInstanceOfExpression) {
- if (!checker.check((PsiInstanceOfExpression)condition)) return null;
- }
- }
- }
- return currentType;
- }
-
- @Nullable
- private static PsiType getBroaderType(PsiType currentType, PsiType castType) {
- if (currentType != null) {
- if (castType != null) {
- if (TypeConversionUtil.isAssignable(castType, currentType)) {
- return castType;
- } else if (!TypeConversionUtil.isAssignable(currentType, castType)) {
- for (PsiType superType : castType.getSuperTypes()) {
- if (TypeConversionUtil.isAssignable(superType, currentType)) {
- return superType;
- }
- }
- return null;
- }
- }
- }
- else {
- return castType;
- }
- return currentType;
- }
-
- public List<VariableData> getInputVariables() {
- return myInputVariables;
- }
-
- public PsiExpression replaceWrappedReferences(PsiElement[] elements, PsiExpression expression) {
- if (!myFoldingAvailable) return expression;
-
- boolean update = elements[0] == expression;
- for (VariableData inputVariable : myInputVariables) {
- myFolding.foldParameterUsagesInBody(inputVariable, elements, myScope);
- }
- return update ? (PsiExpression)elements[0] : expression;
- }
-
- public boolean toDeclareInsideBody(PsiVariable variable) {
- final ArrayList<VariableData> knownVars = new ArrayList<VariableData>(myInputVariables);
- for (VariableData data : knownVars) {
- if (data.variable.equals(variable)) {
- return false;
- }
- }
- return !myFolding.wasExcluded(variable);
- }
-
- public boolean contains(PsiVariable variable) {
- for (VariableData data : myInputVariables) {
- if (data.variable.equals(variable)) return true;
- }
- return false;
- }
-
- public void removeParametersUsedInExitsOnly(PsiElement codeFragment,
- Collection<PsiStatement> exitStatements,
- ControlFlow controlFlow,
- int startOffset,
- int endOffset) {
- final LocalSearchScope scope = new LocalSearchScope(codeFragment);
- Variables:
- for (Iterator<VariableData> iterator = myInputVariables.iterator(); iterator.hasNext();) {
- final VariableData data = iterator.next();
- for (PsiReference ref : ReferencesSearch.search(data.variable, scope)) {
- PsiElement element = ref.getElement();
- int elementOffset = controlFlow.getStartOffset(element);
- if (elementOffset >= startOffset && elementOffset <= endOffset) {
- if (!isInExitStatements(element, exitStatements)) continue Variables;
- }
- }
- iterator.remove();
- }
- }
-
- private static boolean isInExitStatements(PsiElement element, Collection<PsiStatement> exitStatements) {
- for (PsiStatement exitStatement : exitStatements) {
- if (PsiTreeUtil.isAncestor(exitStatement, element, false)) return true;
- }
- return false;
- }
-
-
- public InputVariables copy() {
- final InputVariables inputVariables = new InputVariables(myInputVariables, myProject, myScope);
- inputVariables.myFoldingAvailable = myFoldingAvailable;
- inputVariables.myFolding = myFolding;
- inputVariables.myInitialParameters = myInitialParameters;
- return inputVariables;
- }
-
-
- public void appendCallArguments(VariableData data, StringBuilder buffer) {
- if (myFoldingAvailable) {
- buffer.append(myFolding.getGeneratedCallArgument(data));
- } else {
- if (!TypeConversionUtil.isAssignable(data.type, data.variable.getType())) {
- buffer.append("(").append(data.type.getCanonicalText()).append(")");
- }
- buffer.append(data.variable.getName());
- }
- }
-
- public void setFoldingAvailable(boolean foldingAvailable) {
- myFoldingAvailable = foldingAvailable;
-
- myFolding.clear();
- myInputVariables.clear();
- myInputVariables.addAll(wrapInputVariables(myInitialParameters));
- }
-
- public void annotateWithParameter(PsiJavaCodeReferenceElement reference) {
- for (VariableData data : myInputVariables) {
- final PsiElement element = reference.resolve();
- if (data.variable.equals(element)) {
- PsiType type = data.variable.getType();
- final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(reference, PsiMethodCallExpression.class);
- if (methodCallExpression != null) {
- int idx = ArrayUtil.find(methodCallExpression.getArgumentList().getExpressions(), reference);
- if (idx > -1) {
- final PsiMethod psiMethod = methodCallExpression.resolveMethod();
- if (psiMethod != null) {
- final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
- if (idx >= parameters.length) { //vararg parameter
- idx = parameters.length - 1;
- if (idx >= 0) { //incomplete code
- type = parameters[idx].getType();
- }
- }
- if (type instanceof PsiEllipsisType) {
- type = ((PsiEllipsisType)type).getComponentType();
- }
- }
- }
- }
- if (!myFoldingAvailable || !myFolding.annotateWithParameter(data, reference)) {
- reference.putUserData(DuplicatesFinder.PARAMETER, Pair.create(data.variable, type));
- }
- }
- }
- }
-
- public boolean isFoldingSelectedByDefault() {
- return myFolding.isFoldingSelectedByDefault();
- }
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
deleted file mode 100644
index eac9b18ac2fe..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
+++ /dev/null
@@ -1,313 +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.
- */
-
-/*
- * User: anna
- * Date: 23-Jun-2009
- */
-package com.intellij.refactoring.extractMethod;
-
-import com.intellij.codeInsight.PsiEquivalenceUtil;
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.codeStyle.SuggestedNameInfo;
-import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.SearchScope;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.refactoring.util.VariableData;
-import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-public class ParametersFolder {
- private final Map<PsiVariable, PsiExpression> myExpressions = new HashMap<PsiVariable, PsiExpression>();
- private final Map<PsiVariable, List<PsiExpression>> myMentionedInExpressions = new HashMap<PsiVariable, List<PsiExpression>>();
- private final Set<String> myUsedNames = new HashSet<String>();
-
- private final Set<PsiVariable> myDeleted = new HashSet<PsiVariable>();
- private boolean myFoldingSelectedByDefault = false;
-
-
- public void clear() {
- myExpressions.clear();
- myMentionedInExpressions.clear();
- myUsedNames.clear();
- myDeleted.clear();
- }
-
- public boolean isParameterSafeToDelete(@NotNull VariableData data, @NotNull LocalSearchScope scope) {
- Next:
- for (PsiReference reference : ReferencesSearch.search(data.variable, scope)) {
- PsiElement expression = reference.getElement();
- while (expression != null) {
- for (PsiExpression psiExpression : myExpressions.values()) {
- if (PsiEquivalenceUtil.areElementsEquivalent(expression, psiExpression)) {
- continue Next;
- }
- }
- expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class);
- }
- return false;
- }
- final PsiExpression psiExpression = myExpressions.get(data.variable);
- if (psiExpression == null) return true;
- for (PsiVariable variable : myExpressions.keySet()) {
- if (variable != data.variable && !myDeleted.contains(variable)) {
- final PsiExpression expr = myExpressions.get(variable);
- if (expr != null && PsiEquivalenceUtil.areElementsEquivalent(expr, psiExpression)) {
- myDeleted.add(data.variable);
- return true;
- }
- }
- }
- return false;
- }
-
- public void foldParameterUsagesInBody(@NotNull VariableData data, PsiElement[] elements, SearchScope scope) {
- if (myDeleted.contains(data.variable)) return;
- final PsiExpression psiExpression = myExpressions.get(data.variable);
- if (psiExpression == null) return;
- final Set<PsiExpression> eqExpressions = new HashSet<PsiExpression>();
- for (PsiReference reference : ReferencesSearch.search(data.variable, scope)) {
- final PsiExpression expression = findEquivalent(psiExpression, reference.getElement());
- if (expression != null && expression.isValid()) {
- eqExpressions.add(expression);
- }
- }
-
- for (PsiExpression expression : eqExpressions) {
- final PsiExpression refExpression =
- JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(data.variable.getName(), expression);
- final PsiElement replaced = expression.replace(refExpression);
- for (int i = 0, psiElementsLength = elements.length; i < psiElementsLength; i++) {
- PsiElement psiElement = elements[i];
- if (expression == psiElement) {
- elements[i] = replaced;
- break;
- }
- }
- }
- }
-
- public boolean isParameterFoldable(@NotNull VariableData data,
- @NotNull LocalSearchScope scope,
- @NotNull final List<? extends PsiVariable> inputVariables) {
- final List<PsiExpression> mentionedInExpressions = getMentionedExpressions(data.variable, scope, inputVariables);
- if (mentionedInExpressions == null) return false;
-
- int currentRank = 0;
- PsiExpression mostRanked = null;
- for (int i = mentionedInExpressions.size() - 1; i >= 0; i--) {
- PsiExpression expression = mentionedInExpressions.get(i);
- if (expression instanceof PsiArrayAccessExpression) {
- mostRanked = expression;
- if (!isConditional(expression, scope)) {
- myFoldingSelectedByDefault = true;
- break;
- }
- }
- final int r = findUsedVariables(data, inputVariables, expression).size();
- if (currentRank < r) {
- currentRank = r;
- mostRanked = expression;
- }
- }
-
- if (mostRanked != null) {
- myExpressions.put(data.variable, mostRanked);
- data.type = mostRanked.getType();
- final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(mostRanked.getProject());
- final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, mostRanked, data.type);
- if (nameInfo.names.length > 0) {
- data.name = nameInfo.names[0];
- }
- setUniqueName(data);
- }
-
- return mostRanked != null;
- }
-
- private static boolean isConditional(PsiElement expr, LocalSearchScope scope) {
- while (expr != null) {
- final PsiElement parent = expr.getParent();
- if (parent != null && scope.containsRange(parent.getContainingFile(), parent.getTextRange())) {
- if (parent instanceof PsiIfStatement) {
- if (((PsiIfStatement)parent).getCondition() != expr) return true;
- } else if (parent instanceof PsiConditionalExpression) {
- if (((PsiConditionalExpression)parent).getCondition() != expr) return true;
- } else if (parent instanceof PsiSwitchStatement) {
- if (((PsiSwitchStatement)parent).getExpression() != expr) return true;
- }
- } else {
- return false;
- }
- expr = parent;
- }
- return false;
- }
-
- private void setUniqueName(VariableData data) {
- int idx = 1;
- while (myUsedNames.contains(data.name)) {
- data.name += idx;
- }
- myUsedNames.add(data.name);
- }
-
- private static Set<PsiVariable> findUsedVariables(VariableData data, final List<? extends PsiVariable> inputVariables,
- PsiExpression expression) {
- final Set<PsiVariable> found = new HashSet<PsiVariable>();
- expression.accept(new JavaRecursiveElementVisitor() {
- @Override
- public void visitReferenceExpression(PsiReferenceExpression referenceExpression) {
- super.visitReferenceExpression(referenceExpression);
- PsiElement resolved = referenceExpression.resolve();
- if (resolved instanceof PsiVariable && inputVariables.contains(resolved)) {
- found.add((PsiVariable)resolved);
- }
- }
- });
- found.remove(data.variable);
- return found;
- }
-
- public boolean isFoldable() {
- return !myExpressions.isEmpty();
- }
-
- @Nullable
- private List<PsiExpression> getMentionedExpressions(PsiVariable var, LocalSearchScope scope, final List<? extends PsiVariable> inputVariables) {
- if (myMentionedInExpressions.containsKey(var)) return myMentionedInExpressions.get(var);
- final PsiElement[] scopeElements = scope.getScope();
- List<PsiExpression> expressions = null;
- for (PsiReference reference : ReferencesSearch.search(var, scope)) {
- PsiElement expression = reference.getElement();
- if (expressions == null) {
- expressions = new ArrayList<PsiExpression>();
- while (expression != null) {
- if (isAccessedForWriting((PsiExpression)expression)) return null;
- for (PsiElement scopeElement : scopeElements) {
- if (PsiTreeUtil.isAncestor(expression, scopeElement, true)) {
- expression = null;
- break;
- }
- }
- if (expression == null) break;
-
- final PsiType expressionType = ((PsiExpression)expression).getType();
- if (expressionType != null && expressionType != PsiType.VOID && !(expression.getParent() instanceof PsiExpressionStatement)) {
- if (dependsOnLocals(expression, inputVariables)) {
- break;
- }
- expressions.add((PsiExpression)expression);
- }
- expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class);
- }
- }
- else {
- for (Iterator<PsiExpression> iterator = expressions.iterator(); iterator.hasNext();) {
- if (findEquivalent(iterator.next(), expression) == null) {
- iterator.remove();
- }
- }
- }
- }
- myMentionedInExpressions.put(var, expressions);
- return expressions;
- }
-
- private static boolean isAccessedForWriting(PsiExpression expression) {
- final PsiExpression[] exprWithWriteAccessInside = new PsiExpression[1];
- expression.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override
- public void visitElement(PsiElement element) {
- if (exprWithWriteAccessInside[0] != null) return;
- super.visitElement(element);
- }
-
- @Override
- public void visitExpression(PsiExpression expression) {
- if (PsiUtil.isAccessedForWriting(expression)) {
- exprWithWriteAccessInside[0] = expression;
- }
- super.visitExpression(expression);
- }
- });
- return exprWithWriteAccessInside[0] != null;
- }
-
- private static boolean dependsOnLocals(final PsiElement expression, final List<? extends PsiVariable> inputVariables) {
- final boolean[] localVarsUsed = new boolean[]{false};
- expression.accept(new JavaRecursiveElementWalkingVisitor(){
- @Override
- public void visitReferenceExpression(PsiReferenceExpression expression) {
- final PsiElement resolved = expression.resolve();
- if (resolved instanceof PsiVariable) {
- final PsiVariable variable = (PsiVariable)resolved;
- if (!inputVariables.contains(variable)) {
- localVarsUsed[0] = true;
- return;
- }
- }
- super.visitReferenceExpression(expression);
- }
- });
- return localVarsUsed[0];
- }
-
- @NotNull
- public String getGeneratedCallArgument(@NotNull VariableData data) {
- return myExpressions.containsKey(data.variable) ? myExpressions.get(data.variable).getText() : data.variable.getName();
- }
-
- public boolean annotateWithParameter(@NotNull VariableData data, @NotNull PsiElement element) {
- final PsiExpression psiExpression = myExpressions.get(data.variable);
- if (psiExpression != null) {
- final PsiExpression expression = findEquivalent(psiExpression, element);
- if (expression != null) {
- expression.putUserData(DuplicatesFinder.PARAMETER, Pair.create(data.variable, expression.getType()));
- return true;
- }
- }
- return false;
- }
-
- @Nullable
- private static PsiExpression findEquivalent(PsiExpression expr, PsiElement element) {
- PsiElement expression = element;
- while (expression != null) {
- if (PsiEquivalenceUtil.areElementsEquivalent(expression, expr)) {
- return (PsiExpression)expression;
- }
- expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class);
- }
- return null;
- }
-
- public boolean wasExcluded(PsiVariable variable) {
- return myDeleted.contains(variable) || (myMentionedInExpressions.containsKey(variable) && myExpressions.get(variable) == null);
- }
-
- public boolean isFoldingSelectedByDefault() {
- return myFoldingSelectedByDefault;
- }
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java b/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
deleted file mode 100644
index 0fd6cc0569e4..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.refactoring.util;
-
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiVariable;
-import com.intellij.psi.SmartTypePointerManager;
-import org.jetbrains.annotations.NotNull;
-
-public class VariableData {
- public final PsiVariable variable;
- public PsiType type;
- public String name;
- public boolean passAsParameter;
-
- public VariableData(@NotNull PsiVariable var) {
- variable = var;
- type = var.getType();
- }
-
- public VariableData(@NotNull PsiVariable var, @NotNull PsiType type) {
- variable = var;
- this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
deleted file mode 100644
index 6b4652cccce3..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
+++ /dev/null
@@ -1,34 +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.
- */
-
-/*
- * User: anna
- * Date: 23-Oct-2008
- */
-package com.intellij.refactoring.util.duplicates;
-
-import org.jetbrains.annotations.NonNls;
-
-public class BreakReturnValue extends GotoReturnValue{
- public boolean isEquivalent(final ReturnValue other) {
- return other instanceof BreakReturnValue;
- }
-
- @NonNls
- public String getGotoStatement() {
- return "if(a) break;";
- }
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
deleted file mode 100644
index 3878619c6db9..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
+++ /dev/null
@@ -1,60 +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.refactoring.util.duplicates;
-
-import com.intellij.codeInsight.PsiEquivalenceUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * @author ven
- */
-public class ConditionalReturnStatementValue implements ReturnValue {
- PsiExpression myReturnValue;
-
- public ConditionalReturnStatementValue(final PsiExpression returnValue) {
- myReturnValue = returnValue;
- }
-
- public boolean isEquivalent(ReturnValue other) {
- if (!(other instanceof ConditionalReturnStatementValue)) return false;
- PsiExpression otherReturnValue = ((ConditionalReturnStatementValue) other).myReturnValue;
- if (otherReturnValue == null || myReturnValue == null) return myReturnValue == null && otherReturnValue == null;
- return PsiEquivalenceUtil.areElementsEquivalent(myReturnValue, otherReturnValue);
- }
-
- public PsiStatement createReplacement(final PsiMethod extractedMethod, PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException {
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- PsiIfStatement statement;
- if (myReturnValue == null) {
- statement = (PsiIfStatement)elementFactory.createStatementFromText("if(a) return;", null);
- }
- else {
- statement = (PsiIfStatement)elementFactory.createStatementFromText("if(a) return b;", null);
- final PsiReturnStatement thenBranch = (PsiReturnStatement)statement.getThenBranch();
- assert thenBranch != null;
- final PsiExpression returnValue = thenBranch.getReturnValue();
- assert returnValue != null;
- returnValue.replace(myReturnValue);
- }
-
- final PsiExpression condition = statement.getCondition();
- assert condition != null;
- condition.replace(methodCallExpression);
- return (PsiStatement)CodeStyleManager.getInstance(statement.getManager().getProject()).reformat(statement);
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
deleted file mode 100644
index 6bbf6321c835..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
+++ /dev/null
@@ -1,35 +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.
- */
-
-/*
- * User: anna
- * Date: 23-Oct-2008
- */
-package com.intellij.refactoring.util.duplicates;
-
-import org.jetbrains.annotations.NonNls;
-
-public class ContinueReturnValue extends GotoReturnValue {
- public boolean isEquivalent(final ReturnValue other) {
- return other instanceof ContinueReturnValue;
- }
-
-
- @NonNls
- public String getGotoStatement() {
- return "if (a) continue;";
- }
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
deleted file mode 100644
index 75403848cbe8..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
+++ /dev/null
@@ -1,646 +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.refactoring.util.duplicates;
-
-import com.intellij.codeInsight.PsiEquivalenceUtil;
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.controlFlow.*;
-import com.intellij.psi.impl.source.PsiImmediateClassType;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.*;
-import com.intellij.refactoring.extractMethod.InputVariables;
-import com.intellij.refactoring.util.RefactoringChangeUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.containers.IntArrayList;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- * @author dsl
- */
-public class DuplicatesFinder {
- private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.DuplicatesFinder");
- public static final Key<Pair<PsiVariable, PsiType>> PARAMETER = Key.create("PARAMETER");
- private final PsiElement[] myPattern;
- private InputVariables myParameters;
- private final List<? extends PsiVariable> myOutputParameters;
- private final List<PsiElement> myPatternAsList;
- private boolean myMultipleExitPoints = false;
- @Nullable private final ReturnValue myReturnValue;
-
- public DuplicatesFinder(PsiElement[] pattern,
- InputVariables parameters,
- @Nullable ReturnValue returnValue,
- @NotNull List<? extends PsiVariable> outputParameters
- ) {
- myReturnValue = returnValue;
- LOG.assertTrue(pattern.length > 0);
- myPattern = pattern;
- myPatternAsList = Arrays.asList(myPattern);
- myParameters = parameters;
- myOutputParameters = outputParameters;
-
- final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(pattern[0]);
- try {
- final ControlFlow controlFlow = ControlFlowFactory.getInstance(codeFragment.getProject()).getControlFlow(codeFragment, new LocalsControlFlowPolicy(codeFragment), false);
-
- int startOffset;
- int i = 0;
- do {
- startOffset = controlFlow.getStartOffset(pattern[i++]);
- } while(startOffset < 0 && i < pattern.length);
-
- int endOffset;
- int j = pattern.length - 1;
- do {
- endOffset = controlFlow.getEndOffset(pattern[j--]);
- } while(endOffset < 0 && j >= 0);
-
- IntArrayList exitPoints = new IntArrayList();
- final Collection<PsiStatement> exitStatements = ControlFlowUtil
- .findExitPointsAndStatements(controlFlow, startOffset, endOffset, exitPoints, ControlFlowUtil.DEFAULT_EXIT_STATEMENTS_CLASSES);
- myMultipleExitPoints = exitPoints.size() > 1;
-
- if (myMultipleExitPoints) {
- myParameters.removeParametersUsedInExitsOnly(codeFragment, exitStatements, controlFlow, startOffset, endOffset);
- }
- }
- catch (AnalysisCanceledException e) {
- }
- }
-
- public DuplicatesFinder(final PsiElement[] pattern,
- final InputVariables psiParameters,
- final List<? extends PsiVariable> psiVariables) {
- this(pattern, psiParameters, null, psiVariables);
- }
-
-
-
-
- public List<Match> findDuplicates(PsiElement scope) {
- annotatePattern();
- final ArrayList<Match> result = new ArrayList<Match>();
- findPatternOccurrences(result, scope);
- deannotatePattern();
- return result;
- }
-
- @Nullable
- public Match isDuplicate(PsiElement element, boolean ignoreParameterTypes) {
- annotatePattern();
- Match match = isDuplicateFragment(element, ignoreParameterTypes);
- deannotatePattern();
- return match;
- }
-
- private void annotatePattern() {
- for (final PsiElement patternComponent : myPattern) {
- patternComponent.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
- final PsiElement element = reference.resolve();
- if (element instanceof PsiVariable) {
- final PsiVariable variable = (PsiVariable)element;
- PsiType type = variable.getType();
- myParameters.annotateWithParameter(reference);
- if (myOutputParameters.contains(element)) {
- reference.putUserData(PARAMETER, Pair.create(variable, type));
- }
- }
- PsiElement qualifier = reference.getQualifier();
- if (qualifier != null) {
- qualifier.accept(this);
- }
- }
- });
- }
- }
-
- private void deannotatePattern() {
- for (final PsiElement patternComponent : myPattern) {
- patternComponent.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
- if (reference.getUserData(PARAMETER) != null) {
- reference.putUserData(PARAMETER, null);
- }
- }
- });
- }
- }
-
- private void findPatternOccurrences(List<Match> array, PsiElement scope) {
- PsiElement[] children = scope.getChildren();
- for (PsiElement child : children) {
- final Match match = isDuplicateFragment(child, false);
- if (match != null) {
- array.add(match);
- continue;
- }
- findPatternOccurrences(array, child);
- }
- }
-
-
- @Nullable
- private Match isDuplicateFragment(PsiElement candidate, boolean ignoreParameterTypes) {
- for (PsiElement pattern : myPattern) {
- if (PsiTreeUtil.isAncestor(pattern, candidate, false)) return null;
- }
- PsiElement sibling = candidate;
- ArrayList<PsiElement> candidates = new ArrayList<PsiElement>();
- for (final PsiElement element : myPattern) {
- if (sibling == null) return null;
- if (!canBeEquivalent(element, sibling)) return null;
- candidates.add(sibling);
- sibling = PsiTreeUtil.skipSiblingsForward(sibling, PsiWhiteSpace.class, PsiComment.class);
- }
- LOG.assertTrue(myPattern.length == candidates.size());
- if (myPattern.length == 1 && myPattern[0] instanceof PsiExpression) {
- if (candidates.get(0) instanceof PsiExpression) {
- final PsiExpression candidateExpression = (PsiExpression)candidates.get(0);
- if (PsiUtil.isAccessedForWriting(candidateExpression)) return null;
- final PsiType patternType = ((PsiExpression)myPattern[0]).getType();
- final PsiType candidateType = candidateExpression.getType();
- PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
- final PsiMethod method = PsiTreeUtil.getParentOfType(myPattern[0], PsiMethod.class);
- if (method != null) {
- final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(candidate.getProject()).getResolveHelper();
- substitutor = resolveHelper.inferTypeArguments(method.getTypeParameters(), new PsiType[]{patternType},
- new PsiType[]{candidateType}, PsiUtil.getLanguageLevel(method));
- }
- if (!canTypesBeEquivalent(substitutor.substitute(patternType), candidateType)) return null;
- }
- else {
- return null;
- }
-
- }
- final Match match = new Match(candidates.get(0), candidates.get(candidates.size() - 1), ignoreParameterTypes);
- for (int i = 0; i < myPattern.length; i++) {
- if (!matchPattern(myPattern[i], candidates.get(i), candidates, match)) return null;
- }
-
- if (checkPostVariableUsages(candidates, match)) return null;
-
- return match;
- }
-
- private boolean checkPostVariableUsages(final ArrayList<PsiElement> candidates, final Match match) {
- final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(candidates.get(0));
- try {
- final ControlFlow controlFlow = ControlFlowFactory.getInstance(codeFragment.getProject()).getControlFlow(codeFragment, new LocalsControlFlowPolicy(codeFragment), false);
-
- int startOffset;
- int i = 0;
- do {
- startOffset = controlFlow.getStartOffset(candidates.get(i++));
- } while(startOffset < 0 && i < candidates.size());
-
- int endOffset;
- int j = candidates.size() - 1;
- do {
- endOffset = controlFlow.getEndOffset(candidates.get(j--));
- } while(endOffset < 0 && j >= 0);
-
- final IntArrayList exitPoints = new IntArrayList();
- ControlFlowUtil.findExitPointsAndStatements(controlFlow, startOffset, endOffset, exitPoints, ControlFlowUtil.DEFAULT_EXIT_STATEMENTS_CLASSES);
- final PsiVariable[] outVariables = ControlFlowUtil.getOutputVariables(controlFlow, startOffset, endOffset, exitPoints.toArray());
-
- if (outVariables.length > 0) {
- if (outVariables.length == 1) {
- ReturnValue returnValue = match.getReturnValue();
- if (returnValue == null) {
- returnValue = myReturnValue;
- }
- if (returnValue instanceof VariableReturnValue) {
- final ReturnValue value = match.getOutputVariableValue(((VariableReturnValue)returnValue).getVariable());
- if (value != null) {
- if (value.isEquivalent(new VariableReturnValue(outVariables[0]))) return false;
- if (value instanceof ExpressionReturnValue) {
- final PsiExpression expression = ((ExpressionReturnValue)value).getExpression();
- if (expression instanceof PsiReferenceExpression) {
- final PsiElement variable = ((PsiReferenceExpression)expression).resolve();
- return variable == null || !PsiEquivalenceUtil.areElementsEquivalent(variable, outVariables[0]);
- }
- }
- }
- }
- }
- return true;
- }
- }
- catch (AnalysisCanceledException e) {
- }
- return false;
- }
-
- private static boolean canTypesBeEquivalent(PsiType type1, PsiType type2) {
- if (type1 == null || type2 == null) return false;
- if (!type2.isAssignableFrom(type1)) {
- if (type1 instanceof PsiImmediateClassType && type2 instanceof PsiImmediateClassType) {
- final PsiClass psiClass1 = ((PsiImmediateClassType)type1).resolve();
- final PsiClass psiClass2 = ((PsiImmediateClassType)type2).resolve();
- if (!(psiClass1 instanceof PsiAnonymousClass &&
- psiClass2 instanceof PsiAnonymousClass &&
- psiClass1.getManager().areElementsEquivalent(((PsiAnonymousClass)psiClass1).getBaseClassType().resolve(),
- ((PsiAnonymousClass)psiClass2).getBaseClassType().resolve()))) {
- return false;
- }
- }
- else {
- return false;
- }
- }
- return true;
- }
-
- private static boolean canBeEquivalent(final PsiElement pattern, PsiElement candidate) {
- if (pattern instanceof PsiReturnStatement && candidate instanceof PsiExpressionStatement) return true;
- if (pattern instanceof PsiReturnStatement && candidate instanceof PsiDeclarationStatement) return true;
- if (pattern instanceof PsiThisExpression && candidate instanceof PsiReferenceExpression) return true;
- final ASTNode node1 = pattern.getNode();
- final ASTNode node2 = candidate.getNode();
- if (node1 == null || node2 == null) return false;
- return node1.getElementType() == node2.getElementType();
- }
-
- private boolean matchPattern(PsiElement pattern,
- PsiElement candidate,
- List<PsiElement> candidates,
- Match match) {
- if (pattern == null || candidate == null) return pattern == candidate;
- if (pattern.getUserData(PARAMETER) != null) {
- final Pair<PsiVariable, PsiType> parameter = pattern.getUserData(PARAMETER);
- return match.putParameter(parameter, candidate);
- }
-
- if (!canBeEquivalent(pattern, candidate)) return false; // Q : is it correct to check implementation classes?
-
- if (pattern instanceof PsiExpressionList && candidate instanceof PsiExpressionList) { //check varargs
- final PsiExpression[] expressions = ((PsiExpressionList)pattern).getExpressions();
- final PsiExpression[] childExpressions = ((PsiExpressionList)candidate).getExpressions();
- if (expressions.length > 0 && expressions[expressions.length - 1] instanceof PsiReferenceExpression) {
- final PsiElement resolved = ((PsiReferenceExpression)expressions[expressions.length - 1]).resolve();
- if (resolved instanceof PsiParameter && ((PsiParameter)resolved).getType() instanceof PsiEllipsisType) {
- for(int i = 0; i < expressions.length - 1; i++) {
- final Pair<PsiVariable, PsiType> parameter = expressions[i].getUserData(PARAMETER);
- if (parameter == null) {
- if (!matchPattern(expressions[i], childExpressions[i], candidates, match)) {
- return false;
- }
- } else if (!match.putParameter(parameter, childExpressions[i])) return false;
- }
- final Pair<PsiVariable, PsiType> param = expressions[expressions.length - 1].getUserData(PARAMETER);
- if (param == null) return false;
- for(int i = expressions.length - 1; i < childExpressions.length; i++) {
- if (!match.putParameter(param, childExpressions[i])) return false;
- }
- return true;
- }
- }
- }
-
- if (pattern instanceof PsiAssignmentExpression) {
- final PsiExpression lExpression = ((PsiAssignmentExpression)pattern).getLExpression();
- if (lExpression.getType() instanceof PsiPrimitiveType &&
- lExpression instanceof PsiReferenceExpression &&
- ((PsiReferenceExpression)lExpression).resolve() instanceof PsiParameter) {
- return false;
- }
- } else if (pattern instanceof PsiPrefixExpression) {
- if (checkParameterModification(((PsiPrefixExpression)pattern).getOperand(), ((PsiPrefixExpression)pattern).getOperationTokenType(),
- ((PsiPrefixExpression)candidate).getOperand())) return false;
- } else if (pattern instanceof PsiPostfixExpression) {
- if (checkParameterModification(((PsiPostfixExpression)pattern).getOperand(), ((PsiPostfixExpression)pattern).getOperationTokenType(),
- ((PsiPostfixExpression)candidate).getOperand())) return false;
- }
-
- if (pattern instanceof PsiJavaCodeReferenceElement) {
- final PsiElement resolveResult1 = ((PsiJavaCodeReferenceElement)pattern).resolve();
- final PsiElement resolveResult2 = ((PsiJavaCodeReferenceElement)candidate).resolve();
- if (resolveResult1 instanceof PsiClass && resolveResult2 instanceof PsiClass) return true;
- if (isUnder(resolveResult1, myPatternAsList) && isUnder(resolveResult2, candidates)) {
- traverseParameter(resolveResult1, resolveResult2, match);
- return match.putDeclarationCorrespondence(resolveResult1, resolveResult2);
- }
- final PsiElement qualifier2 = ((PsiJavaCodeReferenceElement)candidate).getQualifier();
- if (!equivalentResolve(resolveResult1, resolveResult2, qualifier2)) {
- return false;
- }
- PsiElement qualifier1 = ((PsiJavaCodeReferenceElement)pattern).getQualifier();
- if (qualifier1 instanceof PsiReferenceExpression && qualifier2 instanceof PsiReferenceExpression &&
- !match.areCorrespond(((PsiReferenceExpression)qualifier1).resolve(), ((PsiReferenceExpression)qualifier2).resolve())) {
- return false;
- }
-
- }
-
- if (pattern instanceof PsiTypeCastExpression) {
- final PsiTypeElement castTypeElement1 = ((PsiTypeCastExpression)pattern).getCastType();
- final PsiTypeElement castTypeElement2 = ((PsiTypeCastExpression)candidate).getCastType();
- if (castTypeElement1 != null && castTypeElement2 != null) {
- final PsiType type1 = TypeConversionUtil.erasure(castTypeElement1.getType());
- final PsiType type2 = TypeConversionUtil.erasure(castTypeElement2.getType());
- if (!type1.equals(type2)) return false;
- }
- } else if (pattern instanceof PsiNewExpression) {
- final PsiType type1 = ((PsiNewExpression)pattern).getType();
- final PsiType type2 = ((PsiNewExpression)candidate).getType();
- if (type1 == null || type2 == null) return false;
- final PsiJavaCodeReferenceElement classReference1 = ((PsiNewExpression)pattern).getClassReference();
- final PsiJavaCodeReferenceElement classReference2 = ((PsiNewExpression)candidate).getClassReference();
- if (classReference1 != null && classReference2 != null) {
- final PsiElement resolved1 = classReference1.resolve();
- final PsiElement resolved2 = classReference2.resolve();
- if (!pattern.getManager().areElementsEquivalent(resolved1, resolved2)) return false;
- }
- else {
- if (!canTypesBeEquivalent(type1, type2)) return false;
- }
- } else if (pattern instanceof PsiClassObjectAccessExpression) {
- final PsiTypeElement operand1 = ((PsiClassObjectAccessExpression)pattern).getOperand();
- final PsiTypeElement operand2 = ((PsiClassObjectAccessExpression)candidate).getOperand();
- return operand1.getType().equals(operand2.getType());
- } else if (pattern instanceof PsiInstanceOfExpression) {
- final PsiTypeElement operand1 = ((PsiInstanceOfExpression)pattern).getCheckType();
- final PsiTypeElement operand2 = ((PsiInstanceOfExpression)candidate).getCheckType();
- if (operand1 == null || operand2 == null) return false;
- if (!operand1.getType().equals(operand2.getType())) return false;
- } else if (pattern instanceof PsiReturnStatement) {
- final PsiReturnStatement patternReturnStatement = (PsiReturnStatement)pattern;
- return matchReturnStatement(patternReturnStatement, candidate, candidates, match);
- } else if (pattern instanceof PsiContinueStatement) {
- match.registerReturnValue(new ContinueReturnValue());
- } else if (pattern instanceof PsiBreakStatement) {
- match.registerReturnValue(new BreakReturnValue());
- }else if (pattern instanceof PsiMethodCallExpression) {
- final PsiMethod patternMethod = ((PsiMethodCallExpression)pattern).resolveMethod();
- final PsiMethod candidateMethod = ((PsiMethodCallExpression)candidate).resolveMethod();
- if (patternMethod != null && candidateMethod != null) {
- if (!MethodSignatureUtil.areSignaturesEqual(patternMethod, candidateMethod)) return false;
- }
- } else if (pattern instanceof PsiReferenceExpression) {
- final PsiReferenceExpression patternRefExpr = (PsiReferenceExpression)pattern;
- final PsiReferenceExpression candidateRefExpr = (PsiReferenceExpression)candidate;
- final PsiExpression patternQualifier = patternRefExpr.getQualifierExpression();
- final PsiExpression candidateQualifier = candidateRefExpr.getQualifierExpression();
- if (patternQualifier == null) {
- PsiClass contextClass = PsiTreeUtil.getParentOfType(pattern, PsiClass.class);
- if (candidateQualifier instanceof PsiReferenceExpression) {
- final PsiElement resolved = ((PsiReferenceExpression)candidateQualifier).resolve();
- if (resolved instanceof PsiClass && contextClass != null && InheritanceUtil.isInheritorOrSelf(contextClass, (PsiClass)resolved, true)) {
- return true;
- }
- }
- return contextClass != null && match.registerInstanceExpression(candidateQualifier, contextClass);
- } else {
- if (candidateQualifier == null) {
- if (patternQualifier instanceof PsiThisExpression) {
- final PsiJavaCodeReferenceElement qualifier = ((PsiThisExpression)patternQualifier).getQualifier();
- if (candidate instanceof PsiReferenceExpression) {
- PsiElement contextClass = qualifier == null ? PsiTreeUtil.getParentOfType(pattern, PsiClass.class) : qualifier.resolve();
- return contextClass instanceof PsiClass && match.registerInstanceExpression(((PsiReferenceExpression)candidate).getQualifierExpression(),
- (PsiClass)contextClass);
- }
- } else {
- final PsiType type = patternQualifier.getType();
- PsiClass contextClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null;
- try {
- final Pair<PsiVariable, PsiType> parameter = patternQualifier.getUserData(PARAMETER);
-
- if (parameter != null) {
- final PsiClass thisClass = RefactoringChangeUtil.getThisClass(parameter.first);
-
- if (contextClass != null && InheritanceUtil.isInheritorOrSelf(thisClass, contextClass, true)) {
- contextClass = thisClass;
- }
- final PsiClass thisCandidate = RefactoringChangeUtil.getThisClass(candidate);
- if (thisCandidate != null && InheritanceUtil.isInheritorOrSelf(thisCandidate, contextClass, true)) {
- contextClass = thisCandidate;
- }
- return contextClass != null && match.putParameter(parameter, RefactoringChangeUtil
- .createThisExpression(patternQualifier.getManager(), contextClass));
- } else if (patternQualifier instanceof PsiReferenceExpression) {
- final PsiElement resolved = ((PsiReferenceExpression)patternQualifier).resolve();
- if (resolved instanceof PsiClass) {
- final PsiClass classContext = PsiTreeUtil.getParentOfType(candidate, PsiClass.class);
- if (classContext != null && InheritanceUtil.isInheritorOrSelf(classContext, (PsiClass)resolved, true)) {
- return true;
- }
- }
- }
-
- return false;
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
- }
- } else {
- if (patternQualifier instanceof PsiThisExpression && candidateQualifier instanceof PsiThisExpression) {
- final PsiJavaCodeReferenceElement thisPatternQualifier = ((PsiThisExpression)patternQualifier).getQualifier();
- final PsiElement patternContextClass = thisPatternQualifier == null ? PsiTreeUtil.getParentOfType(patternQualifier, PsiClass.class) : thisPatternQualifier.resolve();
- final PsiJavaCodeReferenceElement thisCandidateQualifier = ((PsiThisExpression)candidateQualifier).getQualifier();
- final PsiElement candidateContextClass = thisCandidateQualifier == null ? PsiTreeUtil.getParentOfType(candidateQualifier, PsiClass.class) : thisCandidateQualifier.resolve();
- return patternContextClass == candidateContextClass;
- }
- }
- }
- } else if (pattern instanceof PsiThisExpression) {
- final PsiJavaCodeReferenceElement qualifier = ((PsiThisExpression)pattern).getQualifier();
- final PsiElement contextClass = qualifier == null ? PsiTreeUtil.getParentOfType(pattern, PsiClass.class) : qualifier.resolve();
- if (candidate instanceof PsiReferenceExpression) {
- final PsiElement parent = candidate.getParent();
- return parent instanceof PsiReferenceExpression && contextClass instanceof PsiClass && match.registerInstanceExpression(((PsiReferenceExpression)parent).getQualifierExpression(),
- (PsiClass)contextClass);
- } else if (candidate instanceof PsiThisExpression) {
- final PsiJavaCodeReferenceElement candidateQualifier = ((PsiThisExpression)candidate).getQualifier();
- final PsiElement candidateContextClass = candidateQualifier == null ? PsiTreeUtil.getParentOfType(candidate, PsiClass.class) : candidateQualifier.resolve();
- return contextClass == candidateContextClass;
- }
- } else if (pattern instanceof PsiSuperExpression) {
- final PsiJavaCodeReferenceElement qualifier = ((PsiSuperExpression)pattern).getQualifier();
- final PsiElement contextClass = qualifier == null ? PsiTreeUtil.getParentOfType(pattern, PsiClass.class) : qualifier.resolve();
- if (candidate instanceof PsiSuperExpression) {
- final PsiJavaCodeReferenceElement candidateQualifier = ((PsiSuperExpression)candidate).getQualifier();
- return contextClass == (candidateQualifier != null ? candidateQualifier.resolve() : PsiTreeUtil.getParentOfType(candidate, PsiClass.class));
- }
- }
-
- PsiElement[] children1 = getFilteredChildren(pattern);
- PsiElement[] children2 = getFilteredChildren(candidate);
- if (children1.length != children2.length) return false;
-
-
- for (int i = 0; i < children1.length; i++) {
- PsiElement child1 = children1[i];
- PsiElement child2 = children2[i];
- if (!matchPattern(child1, child2, candidates, match)) return false;
- }
-
- if (children1.length == 0) {
- if (pattern.getParent() instanceof PsiVariable && ((PsiVariable)pattern.getParent()).getNameIdentifier() == pattern) {
- return match.putDeclarationCorrespondence(pattern.getParent(), candidate.getParent());
- }
- if (!pattern.textMatches(candidate)) return false;
- }
-
- return true;
- }
-
- private static boolean checkParameterModification(final PsiExpression expression,
- final IElementType sign,
- PsiExpression candidate) {
- if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() instanceof PsiParameter &&
- (sign.equals(JavaTokenType.MINUSMINUS)|| sign.equals(JavaTokenType.PLUSPLUS))) {
- if (candidate instanceof PsiReferenceExpression && ((PsiReferenceExpression)candidate).resolve() instanceof PsiParameter) {
- return false;
- }
- return true;
- }
- return false;
- }
-
- private static void traverseParameter(PsiElement pattern, PsiElement candidate, Match match) {
- if (pattern == null || candidate == null) return;
- if (pattern.getUserData(PARAMETER) != null) {
- final Pair<PsiVariable, PsiType> parameter = pattern.getUserData(PARAMETER);
- match.putParameter(parameter, candidate);
- return;
- }
-
- PsiElement[] children1 = getFilteredChildren(pattern);
- PsiElement[] children2 = getFilteredChildren(candidate);
- if (children1.length != children2.length) return;
-
- for (int i = 0; i < children1.length; i++) {
- PsiElement child1 = children1[i];
- PsiElement child2 = children2[i];
- traverseParameter(child1, child2, match);
- }
- }
-
- private boolean matchReturnStatement(final PsiReturnStatement patternReturnStatement,
- PsiElement candidate,
- List<PsiElement> candidates,
- Match match) {
- if (candidate instanceof PsiExpressionStatement) {
- final PsiExpression expression = ((PsiExpressionStatement)candidate).getExpression();
- if (expression instanceof PsiAssignmentExpression) {
- final PsiExpression returnValue = patternReturnStatement.getReturnValue();
- final PsiExpression rExpression = ((PsiAssignmentExpression)expression).getRExpression();
- if (!matchPattern(returnValue, rExpression, candidates, match)) return false;
- final PsiExpression lExpression = ((PsiAssignmentExpression)expression).getLExpression();
- return match.registerReturnValue(new ExpressionReturnValue(lExpression));
- }
- else return false;
- }
- else if (candidate instanceof PsiDeclarationStatement) {
- final PsiElement[] declaredElements = ((PsiDeclarationStatement)candidate).getDeclaredElements();
- if (declaredElements.length != 1) return false;
- if (!(declaredElements[0] instanceof PsiVariable)) return false;
- final PsiVariable variable = (PsiVariable)declaredElements[0];
- if (!matchPattern(patternReturnStatement.getReturnValue(), variable.getInitializer(), candidates, match)) return false;
- return match.registerReturnValue(new VariableReturnValue(variable));
- }
- else if (candidate instanceof PsiReturnStatement) {
- final PsiExpression returnValue = ((PsiReturnStatement)candidate).getReturnValue();
- if (myMultipleExitPoints) {
- return match.registerReturnValue(new ConditionalReturnStatementValue(returnValue));
- }
- else {
- final PsiElement classOrLambda = PsiTreeUtil.getParentOfType(returnValue, PsiClass.class, PsiLambdaExpression.class);
- final PsiElement commonParent = PsiTreeUtil.findCommonParent(match.getMatchStart(), match.getMatchEnd());
- if (classOrLambda == null || !PsiTreeUtil.isAncestor(commonParent, classOrLambda, false)) {
- if (returnValue != null && !match.registerReturnValue(ReturnStatementReturnValue.INSTANCE)) return false; //do not register return value for return; statement
- }
- return matchPattern(patternReturnStatement.getReturnValue(), returnValue, candidates, match);
- }
- }
- else return false;
- }
-
- private static boolean equivalentResolve(final PsiElement resolveResult1, final PsiElement resolveResult2, PsiElement qualifier2) {
- final boolean b = Comparing.equal(resolveResult1, resolveResult2);
- if (b) return b;
- if (resolveResult1 instanceof PsiMethod && resolveResult2 instanceof PsiMethod) {
- final PsiMethod method1 = (PsiMethod)resolveResult1;
- final PsiMethod method2 = (PsiMethod)resolveResult2;
- if (ArrayUtil.find(method1.findSuperMethods(), method2) >= 0) return true;
- if (ArrayUtil.find(method2.findSuperMethods(), method1) >= 0) return true;
-
- if (method1.getName().equals(method2.getName())) {
- PsiClass class2 = method2.getContainingClass();
- if (qualifier2 instanceof PsiReferenceExpression) {
- final PsiType type = ((PsiReferenceExpression)qualifier2).getType();
- if (type instanceof PsiClassType){
- final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
- if (!(resolvedClass instanceof PsiTypeParameter)) {
- class2 = resolvedClass;
- }
- }
- }
-
- if (class2 != null && PsiUtil.isAccessible(method1, class2, null)) {
- final PsiMethod[] methods = class2.getAllMethods();
- if (ArrayUtil.find(methods, method1) != -1) return true;
- }
- }
- return false;
- }
- else {
- return false;
- }
- }
-
- private static boolean isUnder(PsiElement element, List<PsiElement> parents) {
- if (element == null) return false;
- for (final PsiElement parent : parents) {
- if (PsiTreeUtil.isAncestor(parent, element, false)) return true;
- }
- return false;
- }
-
- private static PsiElement[] getFilteredChildren(PsiElement element1) {
- PsiElement[] children1 = element1.getChildren();
- ArrayList<PsiElement> array = new ArrayList<PsiElement>();
- for (PsiElement child : children1) {
- if (!(child instanceof PsiWhiteSpace) && !(child instanceof PsiComment)) {
- if (child instanceof PsiBlockStatement) {
- Collections.addAll(array, getFilteredChildren(child));
- continue;
- } else if (child instanceof PsiCodeBlock) {
- final PsiStatement[] statements = ((PsiCodeBlock)child).getStatements();
- if (statements.length == 1) {
- array.add(statements[0]);
- continue;
- }
- }
- array.add(child);
- }
- }
- return PsiUtilCore.toPsiElementArray(array);
- }
-
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
deleted file mode 100644
index d8555bd75b67..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
+++ /dev/null
@@ -1,54 +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.refactoring.util.duplicates;
-
-import com.intellij.codeInsight.PsiEquivalenceUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * @author dsl
- */
-public class ExpressionReturnValue implements ReturnValue {
- private final PsiExpression myExpression;
-
- public ExpressionReturnValue(PsiExpression expression) {
- myExpression = expression;
- }
-
- public PsiExpression getExpression() {
- return myExpression;
- }
-
- public boolean isEquivalent(ReturnValue other) {
- if (!(other instanceof ExpressionReturnValue)) return false;
- return PsiEquivalenceUtil.areElementsEquivalent(myExpression, ((ExpressionReturnValue)other).myExpression);
- }
-
- public PsiStatement createReplacement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression)
- throws IncorrectOperationException {
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject());
- PsiExpressionStatement expressionStatement;
- expressionStatement = (PsiExpressionStatement)elementFactory.createStatementFromText("x = y();", null);
- expressionStatement = (PsiExpressionStatement)styleManager.reformat(expressionStatement);
- final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expressionStatement.getExpression();
- assignmentExpression.getLExpression().replace(getExpression());
- assignmentExpression.getRExpression().replace(methodCallExpression);
- return expressionStatement;
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
deleted file mode 100644
index 6ddb9e6f403f..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
+++ /dev/null
@@ -1,54 +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.refactoring.util.duplicates;
-
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * @author dsl
- */
-public class FieldReturnValue implements ReturnValue {
- private final PsiField myField;
-
- public FieldReturnValue(PsiField psiField) {
- myField = psiField;
- }
-
- public boolean isEquivalent(ReturnValue other) {
- if (!(other instanceof FieldReturnValue)) return false;
- return myField == ((FieldReturnValue)other).myField;
- }
-
- public PsiField getField() {
- return myField;
- }
-
- public PsiStatement createReplacement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException {
-
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject());
- PsiExpressionStatement expressionStatement;
- expressionStatement = (PsiExpressionStatement)elementFactory.createStatementFromText("x = y();", null);
- expressionStatement = (PsiExpressionStatement)styleManager.reformat(expressionStatement);
- final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expressionStatement.getExpression();
- assignmentExpression.getLExpression().replace(elementFactory.createExpressionFromText(myField.getName(), myField));
- assignmentExpression.getRExpression().replace(methodCallExpression);
- return expressionStatement;
-
- }
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
deleted file mode 100644
index 7727411e3f1d..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
+++ /dev/null
@@ -1,45 +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.
- */
-
-/*
- * User: anna
- * Date: 24-Oct-2008
- */
-package com.intellij.refactoring.util.duplicates;
-
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
-
-public abstract class GotoReturnValue implements ReturnValue {
- @Nullable
- public PsiStatement createReplacement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression) throws
- IncorrectOperationException {
- if (!TypeConversionUtil.isBooleanType(extractedMethod.getReturnType())) return null;
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- final PsiIfStatement statement = (PsiIfStatement)elementFactory.createStatementFromText(getGotoStatement(), null);
- final PsiExpression condition = statement.getCondition();
- assert condition != null;
- condition.replace(methodCallExpression);
- return (PsiStatement)CodeStyleManager.getInstance(statement.getManager().getProject()).reformat(statement);
- }
-
- @NonNls
- public abstract String getGotoStatement();
-} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
deleted file mode 100644
index ef633f70fa50..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
+++ /dev/null
@@ -1,425 +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.refactoring.util.duplicates;
-
-import com.intellij.codeInsight.PsiEquivalenceUtil;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.controlFlow.*;
-import com.intellij.psi.util.InheritanceUtil;
-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.containers.HashMap;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author dsl
- */
-public final class Match {
- private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.duplicates.Match");
- private final PsiElement myMatchStart;
- private final PsiElement myMatchEnd;
- private final Map<PsiVariable, List<PsiElement>> myParameterValues = new HashMap<PsiVariable, List<PsiElement>>();
- private final Map<PsiVariable, ArrayList<PsiElement>> myParameterOccurrences = new HashMap<PsiVariable, ArrayList<PsiElement>>();
- private final Map<PsiElement, PsiElement> myDeclarationCorrespondence = new HashMap<PsiElement, PsiElement>();
- private ReturnValue myReturnValue = null;
- private Ref<PsiExpression> myInstanceExpression = null;
- final Map<PsiVariable, PsiType> myChangedParams = new HashMap<PsiVariable, PsiType>();
- private final boolean myIgnoreParameterTypes;
-
- Match(PsiElement start, PsiElement end, boolean ignoreParameterTypes) {
- LOG.assertTrue(start.getParent() == end.getParent());
- myMatchStart = start;
- myMatchEnd = end;
- myIgnoreParameterTypes = ignoreParameterTypes;
- }
-
-
- public PsiElement getMatchStart() {
- return myMatchStart;
- }
-
- public PsiElement getMatchEnd() {
- return myMatchEnd;
- }
-
- @Nullable
- public List<PsiElement> getParameterValues(PsiVariable parameter) {
- return myParameterValues.get(parameter);
- }
-
- /**
- * Returns either local variable declaration or expression
- * @param outputParameter
- * @return
- */
- public ReturnValue getOutputVariableValue(PsiVariable outputParameter) {
- final PsiElement decl = myDeclarationCorrespondence.get(outputParameter);
- if (decl instanceof PsiVariable) {
- return new VariableReturnValue((PsiVariable)decl);
- }
- final List<PsiElement> parameterValue = getParameterValues(outputParameter);
- if (parameterValue != null && parameterValue.size() == 1 && parameterValue.get(0) instanceof PsiExpression) {
- return new ExpressionReturnValue((PsiExpression) parameterValue.get(0));
- }
- else {
- return null;
- }
- }
-
-
- boolean putParameter(Pair<PsiVariable, PsiType> parameter, PsiElement value) {
- final PsiVariable psiVariable = parameter.first;
-
- if (myDeclarationCorrespondence.get(psiVariable) == null) {
- final boolean [] valueDependsOnReplacedScope = new boolean[1];
- value.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override
- public void visitReferenceExpression(final PsiReferenceExpression expression) {
- super.visitReferenceExpression(expression);
- final PsiElement resolved = expression.resolve();
- if (resolved != null && Comparing.equal(resolved.getContainingFile(), getMatchEnd().getContainingFile())) {
- final TextRange range = checkRange(resolved);
- final TextRange startRange = checkRange(getMatchStart());
- final TextRange endRange = checkRange(getMatchEnd());
- if (startRange.getStartOffset() <= range.getStartOffset() && range.getEndOffset() <= endRange.getEndOffset()) {
- valueDependsOnReplacedScope[0] = true;
- }
- }
- }
- });
- if (valueDependsOnReplacedScope[0]) return false;
- }
-
- final List<PsiElement> currentValue = myParameterValues.get(psiVariable);
- final boolean isVararg = psiVariable instanceof PsiParameter && ((PsiParameter)psiVariable).isVarArgs();
- if (!(value instanceof PsiExpression)) return false;
- final PsiType type = ((PsiExpression)value).getType();
- final PsiType parameterType = parameter.second;
- if (type == null) return false;
- if (currentValue == null) {
- if (parameterType instanceof PsiClassType && ((PsiClassType)parameterType).resolve() instanceof PsiTypeParameter) {
- final PsiTypeParameter typeParameter = (PsiTypeParameter)((PsiClassType)parameterType).resolve();
- LOG.assertTrue(typeParameter != null);
- for (PsiClassType classType : typeParameter.getExtendsListTypes()) {
- if (!classType.isAssignableFrom(type)) return false;
- }
- }
- else {
- if (isVararg) {
- if (!((PsiEllipsisType)psiVariable.getType()).getComponentType().isAssignableFrom(type) && !((PsiEllipsisType)psiVariable.getType()).toArrayType().equals(type)) {
- myChangedParams.put(psiVariable, new PsiEllipsisType(parameterType));
- }
- } else {
- if (!myIgnoreParameterTypes && !parameterType.isAssignableFrom(type)) return false; //todo
- }
- }
- final List<PsiElement> values = new ArrayList<PsiElement>();
- values.add(value);
- myParameterValues.put(psiVariable, values);
- final ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
- myParameterOccurrences.put(psiVariable, elements);
- return true;
- }
- else {
- for (PsiElement val : currentValue) {
- if (!isVararg && !PsiEquivalenceUtil.areElementsEquivalent(val, value)) {
- return false;
- }
- }
- if (isVararg) {
- if (!parameterType.isAssignableFrom(type)) return false;
- if (!((PsiEllipsisType)psiVariable.getType()).toArrayType().equals(type)){
- currentValue.add(value);
- }
- }
- myParameterOccurrences.get(psiVariable).add(value);
- return true;
- }
- }
-
- public ReturnValue getReturnValue() {
- return myReturnValue;
- }
-
- boolean registerReturnValue(ReturnValue returnValue) {
- if (myReturnValue == null) {
- myReturnValue = returnValue;
- return true;
- }
- else {
- return myReturnValue.isEquivalent(returnValue);
- }
- }
-
- boolean registerInstanceExpression(PsiExpression instanceExpression, final PsiClass contextClass) {
- if (myInstanceExpression == null) {
- if (instanceExpression != null) {
- final PsiType type = instanceExpression.getType();
- if (!(type instanceof PsiClassType)) return false;
- final PsiClass hisClass = ((PsiClassType) type).resolve();
- if (hisClass == null || !InheritanceUtil.isInheritorOrSelf(hisClass, contextClass, true)) return false;
- }
- myInstanceExpression = Ref.create(instanceExpression);
- return true;
- }
- else {
- if (myInstanceExpression.get() == null) {
- myInstanceExpression.set(instanceExpression);
-
- return instanceExpression == null;
- }
- else {
- if (instanceExpression != null) {
- return PsiEquivalenceUtil.areElementsEquivalent(instanceExpression, myInstanceExpression.get());
- }
- else {
- return myInstanceExpression.get() == null || myInstanceExpression.get() instanceof PsiThisExpression;
- }
- }
- }
- }
-
- boolean putDeclarationCorrespondence(PsiElement patternDeclaration, @NotNull PsiElement matchDeclaration) {
- PsiElement originalValue = myDeclarationCorrespondence.get(patternDeclaration);
- if (originalValue == null) {
- myDeclarationCorrespondence.put(patternDeclaration, matchDeclaration);
- return true;
- }
- else {
- return originalValue == matchDeclaration;
- }
- }
-
- boolean areCorrespond(PsiElement patternDeclaration, PsiElement matchDeclaration) {
- if (matchDeclaration == null || patternDeclaration == null) return false;
- PsiElement originalValue = myDeclarationCorrespondence.get(patternDeclaration);
- return originalValue == null || originalValue == matchDeclaration;
- }
-
- private PsiElement replaceWith(final PsiStatement statement) throws IncorrectOperationException {
- final PsiElement matchStart = getMatchStart();
- final PsiElement matchEnd = getMatchEnd();
- final PsiElement element = matchStart.getParent().addBefore(statement, matchStart);
- matchStart.getParent().deleteChildRange(matchStart, matchEnd);
- return element;
- }
-
- public PsiElement replaceByStatement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression, final PsiVariable outputVariable) throws IncorrectOperationException {
- PsiStatement statement = null;
- if (outputVariable != null) {
- ReturnValue returnValue = getOutputVariableValue(outputVariable);
- if (returnValue == null && outputVariable instanceof PsiField) {
- returnValue = new FieldReturnValue((PsiField)outputVariable);
- }
- if (returnValue == null) return null;
- statement = returnValue.createReplacement(extractedMethod, methodCallExpression);
- }
- else if (getReturnValue() != null) {
- statement = getReturnValue().createReplacement(extractedMethod, methodCallExpression);
- }
- if (statement == null) {
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- PsiExpressionStatement expressionStatement = (PsiExpressionStatement) elementFactory.createStatementFromText("x();", null);
- final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getManager());
- expressionStatement = (PsiExpressionStatement)styleManager.reformat(expressionStatement);
- expressionStatement.getExpression().replace(methodCallExpression);
- statement = expressionStatement;
- }
- return replaceWith(statement);
- }
-
- public PsiExpression getInstanceExpression() {
- if (myInstanceExpression == null) {
- return null;
- }
- else {
- return myInstanceExpression.get();
- }
- }
-
- public PsiElement replace(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression, PsiVariable outputVariable) throws IncorrectOperationException {
- declareLocalVariables();
- if (getMatchStart() == getMatchEnd() && getMatchStart() instanceof PsiExpression) {
- return replaceWithExpression(methodCallExpression);
- }
- else {
- return replaceByStatement(extractedMethod, methodCallExpression, outputVariable);
- }
- }
-
- private void declareLocalVariables() throws IncorrectOperationException {
- final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(getMatchStart());
- try {
- final Project project = getMatchStart().getProject();
- final ControlFlow controlFlow = ControlFlowFactory.getInstance(project)
- .getControlFlow(codeFragment, new LocalsControlFlowPolicy(codeFragment));
- final int endOffset = controlFlow.getEndOffset(getMatchEnd());
- final int startOffset = controlFlow.getStartOffset(getMatchStart());
- final List<PsiVariable> usedVariables = ControlFlowUtil.getUsedVariables(controlFlow, endOffset, controlFlow.getSize());
- Collection<ControlFlowUtil.VariableInfo> reassigned = ControlFlowUtil.getInitializedTwice(controlFlow, endOffset, controlFlow.getSize());
- final Collection<PsiVariable> outVariables = ControlFlowUtil.getWrittenVariables(controlFlow, startOffset, endOffset, false);
- for (PsiVariable variable : usedVariables) {
- if (!outVariables.contains(variable)) {
- final PsiIdentifier identifier = variable.getNameIdentifier();
- if (identifier != null) {
- final TextRange textRange = checkRange(identifier);
- final TextRange startRange = checkRange(getMatchStart());
- final TextRange endRange = checkRange(getMatchEnd());
- if (textRange.getStartOffset() >= startRange.getStartOffset() && textRange.getEndOffset() <= endRange.getEndOffset()) {
- final String name = variable.getName();
- LOG.assertTrue(name != null);
- PsiDeclarationStatement statement =
- JavaPsiFacade.getInstance(project).getElementFactory().createVariableDeclarationStatement(name, variable.getType(), null);
- if (reassigned.contains(new ControlFlowUtil.VariableInfo(variable, null))) {
- final PsiElement[] psiElements = statement.getDeclaredElements();
- final PsiModifierList modifierList = ((PsiVariable)psiElements[0]).getModifierList();
- LOG.assertTrue(modifierList != null);
- modifierList.setModifierProperty(PsiModifier.FINAL, false);
- }
- getMatchStart().getParent().addBefore(statement, getMatchStart());
- }
- }
- }
- }
- }
- catch (AnalysisCanceledException e) {
- //skip match
- }
- }
-
- private static TextRange checkRange(final PsiElement element) {
- final TextRange endRange = element.getTextRange();
- LOG.assertTrue(endRange != null, element);
- return endRange;
- }
-
- public PsiElement replaceWithExpression(final PsiExpression psiExpression) throws IncorrectOperationException {
- final PsiElement matchStart = getMatchStart();
- LOG.assertTrue(matchStart == getMatchEnd());
- if (psiExpression instanceof PsiMethodCallExpression && matchStart instanceof PsiReferenceExpression && matchStart.getParent() instanceof PsiMethodCallExpression) {
- return JavaCodeStyleManager.getInstance(matchStart.getProject()).shortenClassReferences(matchStart.replace(((PsiMethodCallExpression)psiExpression).getMethodExpression()));
- }
- return JavaCodeStyleManager.getInstance(matchStart.getProject()).shortenClassReferences(matchStart.replace(psiExpression));
- }
-
- TextRange getTextRange() {
- final TextRange startRange = checkRange(getMatchStart());
- final TextRange endRange = checkRange(getMatchEnd());
- return new TextRange(startRange.getStartOffset(), endRange.getEndOffset());
- }
-
- @Nullable
- public PsiType getChangedReturnType(final PsiMethod psiMethod) {
- final PsiType returnType = psiMethod.getReturnType();
- if (returnType != null) {
- PsiElement parent = getMatchEnd().getParent();
-
- if (parent instanceof PsiExpression) {
- if (parent instanceof PsiMethodCallExpression) {
- JavaResolveResult result = ((PsiMethodCallExpression)parent).resolveMethodGenerics();
- final PsiMethod method = (PsiMethod)result.getElement();
- if (method != null) {
- PsiType type = method.getReturnType();
- if (type != null) {
- type = result.getSubstitutor().substitute(type);
- if (weakerType(psiMethod, returnType, type)) {
- return type;
- }
- }
- }
- }
- else if (parent instanceof PsiReferenceExpression) {
- final JavaResolveResult result = ((PsiReferenceExpression)parent).advancedResolve(false);
- final PsiElement element = result.getElement();
- if (element instanceof PsiMember) {
- final PsiClass psiClass = ((PsiMember)element).getContainingClass();
- if (psiClass != null && psiClass.isPhysical()) {
- final JavaPsiFacade facade = JavaPsiFacade.getInstance(parent.getProject());
- final PsiClassType expressionType = facade.getElementFactory().createType(psiClass, result.getSubstitutor());
- if (weakerType(psiMethod, returnType, expressionType)) {
- return expressionType;
- }
- }
- }
- }
- }
- else if (parent instanceof PsiExpressionList) {
- final PsiExpression[] expressions = ((PsiExpressionList)parent).getExpressions();
- final PsiElement call = parent.getParent();
- if (call instanceof PsiMethodCallExpression) {
- final JavaResolveResult result = ((PsiMethodCallExpression)call).resolveMethodGenerics();
- final PsiMethod method = (PsiMethod)result.getElement();
- if (method != null) {
- final int idx = ArrayUtil.find(expressions, getMatchEnd());
- final PsiParameter[] psiParameters = method.getParameterList().getParameters();
- if (idx >= 0 && idx < psiParameters.length) {
- PsiType type = result.getSubstitutor().substitute(psiParameters[idx].getType());
- if (type instanceof PsiEllipsisType) {
- type = ((PsiEllipsisType)type).getComponentType();
- }
- if (weakerType(psiMethod, returnType, type)){
- return type;
- }
- }
- }
- }
- }
- else if (parent instanceof PsiLocalVariable) {
- final PsiType localVariableType = ((PsiLocalVariable)parent).getType();
- if (weakerType(psiMethod, returnType, localVariableType)) return localVariableType;
- }
- else if (parent instanceof PsiReturnStatement) {
- final PsiMethod replacedMethod = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
- LOG.assertTrue(replacedMethod != null);
- final PsiType replacedMethodReturnType = replacedMethod.getReturnType();
- if (weakerType(psiMethod, returnType, replacedMethodReturnType)) {
- return replacedMethodReturnType;
- }
- }
-
- }
- return null;
- }
-
- private static boolean weakerType(final PsiMethod psiMethod, final PsiType returnType, final PsiType currentType) {
- final PsiTypeParameter[] typeParameters = psiMethod.getTypeParameters();
- final PsiSubstitutor substitutor =
- JavaPsiFacade.getInstance(psiMethod.getProject()).getResolveHelper().inferTypeArguments(typeParameters, new PsiType[]{returnType}, new PsiType[]{currentType}, PsiUtil.getLanguageLevel(psiMethod));
-
- return !TypeConversionUtil.isAssignable(currentType, substitutor.substitute(returnType));
- }
-
- public PsiFile getFile() {
- return getMatchStart().getContainingFile();
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
deleted file mode 100644
index ea66c8636463..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
+++ /dev/null
@@ -1,42 +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.refactoring.util.duplicates;
-
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * @author dsl
- */
-public class ReturnStatementReturnValue implements ReturnValue {
- public static final ReturnStatementReturnValue INSTANCE = new ReturnStatementReturnValue();
-
- private ReturnStatementReturnValue() {}
-
- public boolean isEquivalent(ReturnValue other) {
- return other instanceof ReturnStatementReturnValue;
- }
-
- public PsiStatement createReplacement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException {
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject());
- PsiReturnStatement returnStatement = (PsiReturnStatement)elementFactory.createStatementFromText("return x;", null);
- returnStatement = (PsiReturnStatement) styleManager.reformat(returnStatement);
- returnStatement.getReturnValue().replace(methodCallExpression);
- return returnStatement;
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
deleted file mode 100644
index 896ea60c3f98..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
+++ /dev/null
@@ -1,32 +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.refactoring.util.duplicates;
-
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiMethodCallExpression;
-import com.intellij.psi.PsiStatement;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author dsl
- */
-public interface ReturnValue {
- boolean isEquivalent(ReturnValue other);
-
- @Nullable
- PsiStatement createReplacement(final PsiMethod extractedMethod, PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException;
-}
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
deleted file mode 100644
index 75edb10c4853..000000000000
--- a/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
+++ /dev/null
@@ -1,52 +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.refactoring.util.duplicates;
-
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * @author dsl
- */
-public class VariableReturnValue implements ReturnValue {
- private final PsiVariable myVariable;
-
- public VariableReturnValue(PsiVariable variable) {
- myVariable = variable;
- }
-
- public boolean isEquivalent(ReturnValue other) {
- if (!(other instanceof VariableReturnValue)) return false;
- return myVariable == ((VariableReturnValue)other).myVariable;
- }
-
- public PsiVariable getVariable() {
- return myVariable;
- }
-
- public PsiStatement createReplacement(final PsiMethod extractedMethod, final PsiMethodCallExpression methodCallExpression) throws IncorrectOperationException {
- final PsiDeclarationStatement statement;
-
- final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(methodCallExpression.getProject()).getElementFactory();
- final CodeStyleManager styleManager = CodeStyleManager.getInstance(methodCallExpression.getProject());
- statement = (PsiDeclarationStatement)styleManager.reformat(
- elementFactory.createVariableDeclarationStatement(myVariable.getName(), myVariable.getType(), methodCallExpression)
- );
- ((PsiVariable)statement.getDeclaredElements()[0]).getModifierList().replace(myVariable.getModifierList());
- return statement;
- }
-}