IDEA-99587 fix resolve & testdata

This commit is contained in:
Max Medvedev
2013-02-26 13:56:58 +04:00
parent 97e663ce1e
commit e518fc39e4
8 changed files with 43 additions and 35 deletions
@@ -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)) {
@@ -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) {
@@ -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<ClassHint.ResolveKind> 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<ClassHint.ResolveKind> 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<DeclarationHolder> collectDeclarations(final GroovyPsiElement place) {
private List<DeclarationHolder> collectDeclarations(final PsiElement place) {
final ArrayList<DeclarationHolder> result = new ArrayList<DeclarationHolder>();
PsiTreeUtil.treeWalkUp(place, null, new PairProcessor<PsiElement, PsiElement>() {
@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<DeclarationHolder> getAllDeclarations(GroovyPsiElement place) {
private List<DeclarationHolder> getAllDeclarations(PsiElement place) {
ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>> cache =
CachedValuesManager.getManager(place.getProject()).getCachedValue(place, VALUE_PROVIDER);
List<DeclarationHolder> 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;
@@ -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<PsiElement, PsiElement>() {
@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;
@@ -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);
}
@@ -1,7 +1,7 @@
java.util.ArrayList<java.lang.Integer> list = new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3));
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure<java.lang.Void>(this, this) {
public void doCall(java.lang.Object it) {
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(closure.this, it);
print(it);
}
public void doCall() {
@@ -13,7 +13,7 @@ public void foo(int x) {final groovy.lang.Reference<java.lang.Integer> i = new g
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure<java.lang.Integer>(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.lang.Integer>(java.util.Arrays.asList(1, 2, 3)), new groovy.lang.Closure<java.lang.Integer>(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();
}
@@ -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() {