From b44704397a56734239a1e58516aaafa0493487f0 Mon Sep 17 00:00:00 2001 From: Ievgen Degtiarenko Date: Wed, 30 Sep 2015 20:34:20 -0400 Subject: [PATCH] Resolve variables with multiple declarations (hello reuse variable lovers!) --- .../concordion/ConcordionVariableUsage.java | 6 ++---- .../AbstractConcordionReference.java | 2 +- testData/reference/ReuseVariable.html | 13 ++++++++++++ testData/reference/ReuseVariable.java | 11 ++++++++++ .../reference/ReferenceResolverTest.java | 20 +++++++++++++++++++ 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 testData/reference/ReuseVariable.html create mode 100644 testData/reference/ReuseVariable.java diff --git a/src/com/gman/idea/plugin/concordion/ConcordionVariableUsage.java b/src/com/gman/idea/plugin/concordion/ConcordionVariableUsage.java index e805e88..d182fc7 100644 --- a/src/com/gman/idea/plugin/concordion/ConcordionVariableUsage.java +++ b/src/com/gman/idea/plugin/concordion/ConcordionVariableUsage.java @@ -39,12 +39,10 @@ public static ConcordionVariableUsage findDeclaration(@NotNull ConcordionVariabl if (varName == null) { return null; } - + int varNameLength = varName.length(); int endOfScopePosition = findEndOfScopePosition(variable); - for (int pos = text.indexOf(varName); - pos != -1 && pos <= endOfScopePosition; - pos = text.indexOf(varName, pos+1)) { + for (int pos = text.lastIndexOf(varName, endOfScopePosition); pos >= 0; pos = text.lastIndexOf(varName, pos - varNameLength)) { PsiElement elementAt = htmlSpec.findElementAt(pos); if (elementAt != null) { ConcordionVariableUsage usage = fromTokenAt(elementAt, pos); diff --git a/src/com/gman/idea/plugin/concordion/reference/AbstractConcordionReference.java b/src/com/gman/idea/plugin/concordion/reference/AbstractConcordionReference.java index f235d2f..af3d489 100644 --- a/src/com/gman/idea/plugin/concordion/reference/AbstractConcordionReference.java +++ b/src/com/gman/idea/plugin/concordion/reference/AbstractConcordionReference.java @@ -37,7 +37,7 @@ public String getCanonicalText() { @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { owner.setName(newElementName); - return resolve(); + return owner; } @Override diff --git a/testData/reference/ReuseVariable.html b/testData/reference/ReuseVariable.html new file mode 100644 index 0000000..b0a78da --- /dev/null +++ b/testData/reference/ReuseVariable.html @@ -0,0 +1,13 @@ + + + Test spec + + + +var + + nested + + + + \ No newline at end of file diff --git a/testData/reference/ReuseVariable.java b/testData/reference/ReuseVariable.java new file mode 100644 index 0000000..340f05b --- /dev/null +++ b/testData/reference/ReuseVariable.java @@ -0,0 +1,11 @@ +package com.test; + +import org.concordion.integration.junit4.ConcordionRunner; +import org.junit.runner.RunWith; + +@RunWith(ConcordionRunner.class) +public class ReuseVariable { + + public void consumeString(String s) { + } +} diff --git a/tests/com/gman/idea/plugin/concordion/reference/ReferenceResolverTest.java b/tests/com/gman/idea/plugin/concordion/reference/ReferenceResolverTest.java index 52901af..d418845 100644 --- a/tests/com/gman/idea/plugin/concordion/reference/ReferenceResolverTest.java +++ b/tests/com/gman/idea/plugin/concordion/reference/ReferenceResolverTest.java @@ -7,6 +7,7 @@ import com.gman.idea.plugin.concordion.lang.psi.ConcordionVariable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import static org.assertj.core.api.Assertions.assertThat; @@ -222,6 +223,25 @@ public void testShouldResolveReservedVariable() { assertThat(declaration).isEqualTo(variable); } + public void testShouldResolveLastAssignmentInCaseOfVariableReuse() { + //Should resolve inner var set as it executed last before method run + copyJavaRunnerToConcordionProject("ReuseVariable.java"); + VirtualFile htmlSpec = copyHtmlSpecToConcordionProject("ReuseVariable.html"); + + myFixture.configureFromExistingVirtualFile(htmlSpec); + + ConcordionVariable variable = elementUnderCaret(); + ConcordionVariable declaration = resolveReferences(variable); + + assertThat(declaration).isNotNull(); + assertThat(declaration.getName()).isEqualTo("var"); + + //In this case variable declared on inner level after it is actually used on outer + assertThat(InjectedLanguageUtil.findInjectionHost(declaration).getTextOffset()) + .isGreaterThan(InjectedLanguageUtil.findInjectionHost(variable).getTextOffset()); + + } + private T elementUnderCaret() { return (T) myFixture.getFile().findElementAt(myFixture.getCaretOffset() - 1).getParent(); }