From e518fc39e498e3e36c1ff6e9d81c2ef04bb7eb7a Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 26 Feb 2013 13:55:56 +0400 Subject: [PATCH] IDEA-99587 fix resolve & testdata --- .../groovy/annotator/GroovyAnnotator.java | 2 +- .../blocks/GrClosableBlockImpl.java | 34 ++++++++++--------- .../lang/resolve/DeclarationCacheKey.java | 19 +++++++---- .../groovy/lang/resolve/ResolveUtil.java | 13 +++---- .../codeBlock/anonymousFromMap.java | 2 +- .../codeBlock/closure.java | 2 +- .../methodParamInClosureImplicitReturn.java | 4 +-- .../file/refInClosureInScript.java | 2 +- 8 files changed, 43 insertions(+), 35 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index bc09365a7ce3..a1ec3e409b5a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -636,7 +636,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @SuppressWarnings({"ConstantConditions"}) final PsiElement context = variable.getContext().getContext(); if (context instanceof GrClosableBlock) { - duplicate = ResolveUtil.resolveExistingElement((GroovyPsiElement)context, new DuplicateVariablesProcessor(variable), + duplicate = ResolveUtil.resolveExistingElement((GroovyPsiElement)context.getParent(), new DuplicateVariablesProcessor(variable), GrVariable.class, GrReferenceExpression.class); } else if (context instanceof GrMethod && !(context.getParent() instanceof GroovyFile)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java index 4981b0732ab2..a6c1799efc07 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java @@ -87,8 +87,8 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock if (!super.processDeclarations(processor, _state, lastParent, place)) return false; if (!processParameters(processor, _state, state, place)) return false; if (!ResolveUtil.processElement(processor, getOwner(), _state)) return false; - if (!processOwnerAndDelegate(processor, state, place)) return false; if (!processClosureClassMembers(processor, state, lastParent, place)) return false; + if (!processOwnerAndDelegate(processor, state, place)) return false; return true; } @@ -97,7 +97,7 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock Boolean result = processDelegatesTo(processor, state, place); if (result != null) return result.booleanValue(); - if (!processOwner(processor, state)) return false; + if (!processOwner(processor, state, place)) return false; return true; } @@ -110,15 +110,15 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock switch (info.getStrategy()) { case Closure.OWNER_FIRST: - if (!processOwner(processor, state)) return false; + if (!processOwner(processor, state, place)) return false; if (!processDelegate(processor, state, place, info.getTypeToDelegate())) return false; return true; case Closure.DELEGATE_FIRST: if (!processDelegate(processor, state, place, info.getTypeToDelegate())) return false; - if (!processOwner(processor, state)) return false; + if (!processOwner(processor, state, place)) return false; return true; case Closure.OWNER_ONLY: - if (!processOwner(processor, state)) return false; + if (!processOwner(processor, state, place)) return false; return true; case Closure.DELEGATE_ONLY: if (!processDelegate(processor, state, place, info.getTypeToDelegate())) return false; @@ -130,11 +130,14 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock } } - private static boolean processDelegate(@NotNull PsiScopeProcessor processor, - @NotNull ResolveState state, - @NotNull PsiElement place, - @Nullable final PsiType classToDelegate) { + private boolean processDelegate(@NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + @NotNull PsiElement place, + @Nullable final PsiType classToDelegate) { if (classToDelegate != null) { + if (state.get(ResolverProcessor.RESOLVE_CONTEXT) == null) { + state = state.put(ResolverProcessor.RESOLVE_CONTEXT, this); + } return ResolveUtil.processAllDeclarations(classToDelegate, processor, state, place); } @@ -177,14 +180,13 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock return true; } - private boolean processOwner(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state) { - final PsiElement parent = this.getParent(); - if (parent instanceof GroovyPsiElement) { - return ResolveUtil.treeWalkUp((GroovyPsiElement)parent, processor, true, state); - } - else { - return true; + private boolean processOwner(@NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + @NotNull PsiElement place) { + if (state.get(ResolverProcessor.RESOLVE_CONTEXT) == null) { + state = state.put(ResolverProcessor.RESOLVE_CONTEXT, this); } + return ResolveUtil.treeWalkUp(getParent(), place, processor, true, state); } private boolean isItAlreadyDeclared(@Nullable PsiElement place) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java index 8c17a19a3acf..55a9e7af8be7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java @@ -28,7 +28,6 @@ import com.intellij.util.PairProcessor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; @@ -54,11 +53,13 @@ class DeclarationCacheKey { @Nullable private final String name; @NotNull private final EnumSet kinds; private final boolean nonCode; + @NotNull private final PsiElement place; - DeclarationCacheKey(@Nullable String name, ClassHint hint, boolean nonCode) { + DeclarationCacheKey(@Nullable String name, ClassHint hint, boolean nonCode, @NotNull PsiElement place) { this.name = name; this.kinds = getResolveKinds(hint); this.nonCode = nonCode; + this.place = place; } private static EnumSet getResolveKinds(ClassHint hint) { @@ -93,6 +94,8 @@ class DeclarationCacheKey { return false; } + if (place != key.place) return false; + return true; } @@ -101,6 +104,7 @@ class DeclarationCacheKey { int result = name != null ? name.hashCode() : 0; result = 31 * result + kinds.hashCode(); result = 31 * result + (nonCode ? 1 : 0); + result = 31* result + place.hashCode(); return result; } @@ -110,15 +114,16 @@ class DeclarationCacheKey { "name='" + name + '\'' + ", kinds=" + kinds + ", nonCode=" + nonCode + + ", place=" + place.toString() + '}'; } - private List collectDeclarations(final GroovyPsiElement place) { + private List collectDeclarations(final PsiElement place) { final ArrayList result = new ArrayList(); PsiTreeUtil.treeWalkUp(place, null, new PairProcessor() { @Override public boolean process(PsiElement scope, PsiElement lastParent) { - result.add(collectScopeDeclarations(scope, lastParent, place)); + result.add(collectScopeDeclarations(scope, lastParent)); if (scope instanceof GrClosableBlock) return false; //closures tree walk up themselves return true; } @@ -126,14 +131,14 @@ class DeclarationCacheKey { return result; } - private DeclarationHolder collectScopeDeclarations(PsiElement scope, PsiElement lastParent, GroovyPsiElement place) { + private DeclarationHolder collectScopeDeclarations(PsiElement scope, PsiElement lastParent) { MyCollectProcessor plainCollector = new MyCollectProcessor(scope); MyCollectProcessor nonCodeCollector = new MyCollectProcessor(scope); ResolveUtil.doProcessDeclarations(place, lastParent, scope, plainCollector, nonCode ? nonCodeCollector : null, ResolveState.initial()); return new DeclarationHolder(scope, plainCollector.declarations, nonCodeCollector.declarations); } - private List getAllDeclarations(GroovyPsiElement place) { + private List getAllDeclarations(PsiElement place) { ConcurrentMap> cache = CachedValuesManager.getManager(place.getProject()).getCachedValue(place, VALUE_PROVIDER); List declarations = cache.get(this); @@ -144,7 +149,7 @@ class DeclarationCacheKey { return declarations; } - boolean processCachedDeclarations(GroovyPsiElement place, PsiScopeProcessor processor) { + boolean processCachedDeclarations(PsiElement place, PsiScopeProcessor processor) { for (DeclarationHolder holder : getAllDeclarations(place)) { if (!holder.processCachedDeclarations(processor)) { return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 786aa5595ba4..a9beffbe8a10 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -95,7 +95,7 @@ public class ResolveUtil { public static boolean treeWalkUp(@NotNull final GroovyPsiElement place, @NotNull final PsiScopeProcessor processor, boolean processNonCodeMethods) { - return treeWalkUp(place, processor, processNonCodeMethods, ResolveState.initial()); + return treeWalkUp(place, place, processor, processNonCodeMethods, ResolveState.initial()); } /** @@ -106,20 +106,21 @@ public class ResolveUtil { * @param state * @return */ - public static boolean treeWalkUp(@NotNull final GroovyPsiElement place, + public static boolean treeWalkUp(@NotNull final PsiElement place, + @NotNull final PsiElement originalPlace, @NotNull final PsiScopeProcessor processor, boolean processNonCodeMethods, @NotNull final ResolveState state) { ClassHint hint = processor.getHint(ClassHint.KEY); if (hint != null) { - return new DeclarationCacheKey(getNameHint(processor), hint, processNonCodeMethods).processCachedDeclarations(place, processor); + return new DeclarationCacheKey(getNameHint(processor), hint, processNonCodeMethods, originalPlace).processCachedDeclarations(place, processor); } final PsiScopeProcessor nonCodeProcessor = processNonCodeMethods ? processor : null; return PsiTreeUtil.treeWalkUp(place, null, new PairProcessor() { @Override public boolean process(PsiElement scope, PsiElement lastParent) { - if (!doProcessDeclarations(place, lastParent, scope, substituteProcessor(processor, scope), nonCodeProcessor, state)) { + if (!doProcessDeclarations(originalPlace, lastParent, scope, substituteProcessor(processor, scope), nonCodeProcessor, state)) { return false; } if (scope instanceof GrClosableBlock) return false; //closures tree walk up themselves @@ -129,7 +130,7 @@ public class ResolveUtil { }); } - static boolean doProcessDeclarations(@NotNull GroovyPsiElement place, + static boolean doProcessDeclarations(@NotNull PsiElement place, @Nullable PsiElement lastParent, @NotNull PsiElement scope, @NotNull PsiScopeProcessor plainProcessor, @@ -158,7 +159,7 @@ public class ResolveUtil { return processor; } - static boolean processScopeNonCodeMethods(GroovyPsiElement place, PsiElement lastParent, PsiScopeProcessor processor, PsiElement scope) { + static boolean processScopeNonCodeMethods(PsiElement place, PsiElement lastParent, PsiScopeProcessor processor, PsiElement scope) { if (scope instanceof GrTypeDefinition) { if (!processNonCodeMembers(createPsiType((GrTypeDefinition)scope), processor, place, ResolveState.initial())) return false; diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/anonymousFromMap.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/anonymousFromMap.java index d656375ed55f..1cb3b2258ab6 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/anonymousFromMap.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/anonymousFromMap.java @@ -1,5 +1,5 @@ print(new java.lang.Runnable() { -public void run(java.lang.Object it) {org.codehaus.groovy.runtime.DefaultGroovyMethods.print(anonymousFromMap.this, "foo}");} +public void run(java.lang.Object it) {print("foo}");} public void run() { this.run(null); } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java index 15d0b91c2466..4b7cb1b3b6c4 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/closure.java @@ -1,7 +1,7 @@ java.util.ArrayList list = new java.util.ArrayList(java.util.Arrays.asList(1, 2, 3)); org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure(this, this) { public void doCall(java.lang.Object it) { -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(closure.this, it); +print(it); } public void doCall() { diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/methodParamInClosureImplicitReturn.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/methodParamInClosureImplicitReturn.java index 201a3785f2b0..22d7b56914b2 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/methodParamInClosureImplicitReturn.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/methodParamInClosureImplicitReturn.java @@ -13,7 +13,7 @@ public void foo(int x) {final groovy.lang.Reference i = new g org.codehaus.groovy.runtime.DefaultGroovyMethods.each(new java.util.ArrayList(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure(this, this) { public java.lang.Integer doCall(java.lang.Object it) { -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(methodParamInClosureImplicitReturn.this, i.get()); +print(i.get()); return setGroovyRef(i, i.get() + 1); } @@ -25,7 +25,7 @@ return doCall(null); org.codehaus.groovy.runtime.DefaultGroovyMethods.each(new java.util.ArrayList(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure(this, this) { public java.lang.Integer doCall(java.lang.Object it) { -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(methodParamInClosureImplicitReturn.this, i.get()); +print(i.get()); i.set(i.get()++); return i.get(); } diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java index 8c2d245862ec..f2960f8113f4 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/refInClosureInScript.java @@ -12,7 +12,7 @@ foo.set(foo.get()++); foo.set(foo.get() + 2); foo.set(foo.get() - 1); foo.set(4); -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(refInClosureInScript.this, foo.get()); +print(foo.get()); } public void doCall() {