Reference resolve from synthetic extension usages to get/set-methods
This commit is contained in:
@@ -130,7 +130,7 @@ public fun JetElement.getQualifiedExpressionForSelector(): JetQualifiedExpressio
|
||||
return if (parent is JetQualifiedExpression && parent.getSelectorExpression() == this) parent else null
|
||||
}
|
||||
|
||||
public fun JetElement.getQualifiedExpressionForSelectorOrThis(): JetElement {
|
||||
public fun JetExpression.getQualifiedExpressionForSelectorOrThis(): JetExpression {
|
||||
return getQualifiedExpressionForSelector() ?: this
|
||||
}
|
||||
|
||||
|
||||
+64
-17
@@ -16,34 +16,81 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.changeQualifiedName
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.lexer.JetToken
|
||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import com.intellij.psi.impl.light.LightElement
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.changeQualifiedName
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.lexer.JetToken
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticExtensionPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.constant
|
||||
|
||||
public class JetSimpleNameReference(
|
||||
jetSimpleNameExpression: JetSimpleNameExpression
|
||||
) : JetSimpleReference<JetSimpleNameExpression>(jetSimpleNameExpression) {
|
||||
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
val targets = super.getTargetDescriptors(context)
|
||||
if (targets.none { it is SyntheticExtensionPropertyDescriptor }) return targets
|
||||
|
||||
val newTargets = SmartList<DeclarationDescriptor>()
|
||||
for (target in targets) {
|
||||
if (!(target !is SyntheticExtensionPropertyDescriptor)) {
|
||||
val access = access()
|
||||
if (access == Access.READ || access == Access.READ_WRITE) {
|
||||
newTargets.add(target.getMethod)
|
||||
}
|
||||
if (access == Access.WRITE || access == Access.READ_WRITE) {
|
||||
newTargets.addIfNotNull(target.setMethod)
|
||||
}
|
||||
}
|
||||
else {
|
||||
newTargets.add(target)
|
||||
}
|
||||
}
|
||||
return newTargets
|
||||
}
|
||||
|
||||
//TODO: there should be some common util for that
|
||||
private enum class Access {
|
||||
READ, WRITE, READ_WRITE
|
||||
}
|
||||
|
||||
private fun access(): Access {
|
||||
var expression = myElement.getQualifiedExpressionForSelectorOrThis()
|
||||
while (expression.getParent() is JetParenthesizedExpression) {
|
||||
expression = expression.getParent() as JetParenthesizedExpression
|
||||
}
|
||||
|
||||
val assignment = expression.getAssignmentByLHS()
|
||||
if (assignment != null) {
|
||||
return if (assignment.getOperationToken() == JetTokens.EQ) Access.WRITE else Access.READ_WRITE
|
||||
}
|
||||
|
||||
return if ((expression.getParent() as? JetUnaryExpression)?.getOperationToken() in constant { setOf(JetTokens.PLUSPLUS, JetTokens.MINUSMINUS) })
|
||||
Access.READ_WRITE
|
||||
else
|
||||
Access.READ
|
||||
}
|
||||
|
||||
override fun isReferenceTo(element: PsiElement?): Boolean {
|
||||
if (element != null) {
|
||||
if (!canBeReferenceTo(element)) return false
|
||||
|
||||
+2
-1
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -82,7 +83,7 @@ class RenameReplacement(override val parameter: Parameter): ParameterReplacement
|
||||
override fun copy(parameter: Parameter) = RenameReplacement(parameter)
|
||||
|
||||
override fun invoke(e: JetElement): JetElement {
|
||||
var expressionToReplace = (e.getParent() as? JetThisExpression ?: e).getQualifiedExpressionForSelectorOrThis()
|
||||
var expressionToReplace = (e.getParent() as? JetThisExpression ?: e).let { it.getQualifiedExpressionForSelector() ?: it }
|
||||
val parameterName = JetPsiUtil.unquoteIdentifier(parameter.nameForRef)
|
||||
val replacingName =
|
||||
if (e.getText().startsWith('`') || !KotlinNameSuggester.isIdentifier(parameterName)) "`$parameterName`" else parameterName
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
class JavaClass {
|
||||
public int getSomething() { return 1; }
|
||||
public void setSomething(int value) {}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
fun JavaClass.foo(javaClass: JavaClass) {
|
||||
print(javaClass.<caret>something)
|
||||
javaClass.<caret>something = 1
|
||||
javaClass.<caret>something += 1
|
||||
javaClass.<caret>something++
|
||||
--javaClass.<caret>something
|
||||
|
||||
<caret>something++
|
||||
(<caret>something)++
|
||||
(<caret>something) = 1
|
||||
(javaClass.<caret>something) = 1
|
||||
}
|
||||
|
||||
// MULTIRESOLVE
|
||||
// REF1: (in JavaClass).getSomething()
|
||||
// REF2: (in JavaClass).setSomething(int)
|
||||
// REF3: (in JavaClass).getSomething()
|
||||
// REF3: (in JavaClass).setSomething(int)
|
||||
// REF4: (in JavaClass).getSomething()
|
||||
// REF4: (in JavaClass).setSomething(int)
|
||||
// REF5: (in JavaClass).getSomething()
|
||||
// REF5: (in JavaClass).setSomething(int)
|
||||
// REF6: (in JavaClass).getSomething()
|
||||
// REF6: (in JavaClass).setSomething(int)
|
||||
// REF7: (in JavaClass).getSomething()
|
||||
// REF7: (in JavaClass).setSomething(int)
|
||||
// REF8: (in JavaClass).setSomething(int)
|
||||
// REF9: (in JavaClass).setSomething(int)
|
||||
+1
-1
@@ -34,7 +34,7 @@ public abstract class AbstractReferenceResolveInLibrarySourcesTest : JetLightCod
|
||||
|
||||
fixture.configureByFile(path)
|
||||
|
||||
val expectedResolveData = AbstractReferenceResolveTest.readResolveData(fixture.getFile()!!.getText())
|
||||
val expectedResolveData = AbstractReferenceResolveTest.readResolveData(fixture.getFile()!!.getText(), 0)
|
||||
|
||||
val gotoData = NavigationTestUtils.invokeGotoImplementations(fixture.getEditor(), fixture.getFile())!!
|
||||
Assert.assertEquals("Single target expected for origianl file", 1, gotoData.targets.size())
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightPlatformCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.jetbrains.kotlin.test.ReferenceUtils;
|
||||
import org.jetbrains.kotlin.test.util.UtilPackage;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractReferenceResolveTest extends KotlinLightPlatformCodeInsightFixtureTestCase {
|
||||
public static class ExpectedResolveData {
|
||||
private final Boolean shouldBeUnresolved;
|
||||
private final String referenceToString;
|
||||
|
||||
public ExpectedResolveData(Boolean shouldBeUnresolved, String referenceToString) {
|
||||
this.shouldBeUnresolved = shouldBeUnresolved;
|
||||
this.referenceToString = referenceToString;
|
||||
}
|
||||
|
||||
public boolean shouldBeUnresolved() {
|
||||
return shouldBeUnresolved;
|
||||
}
|
||||
|
||||
public String getReferenceString() {
|
||||
return referenceToString;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String MULTIRESOLVE = "MULTIRESOLVE";
|
||||
public static final String REF_EMPTY = "REF_EMPTY";
|
||||
|
||||
protected void doTest(@NotNull String path) {
|
||||
assert path.endsWith(".kt") : path;
|
||||
UtilPackage.configureWithExtraFile(myFixture, path, ".Data");
|
||||
performChecks();
|
||||
}
|
||||
|
||||
protected void performChecks() {
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(myFixture.getFile().getText(), MULTIRESOLVE)) {
|
||||
doMultiResolveTest();
|
||||
}
|
||||
else {
|
||||
doSingleResolveTest();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doSingleResolveTest() {
|
||||
ExpectedResolveData expectedResolveData = readResolveData(myFixture.getFile().getText());
|
||||
|
||||
int offset = myFixture.getEditor().getCaretModel().getOffset();
|
||||
PsiReference psiReference = myFixture.getFile().findReferenceAt(offset);
|
||||
|
||||
checkReferenceResolve(expectedResolveData, offset, psiReference);
|
||||
}
|
||||
|
||||
protected void doMultiResolveTest() {
|
||||
List<String> expectedReferences = ReferenceUtils.getExpectedReferences(myFixture.getFile().getText());
|
||||
|
||||
PsiReference psiReference = myFixture.getFile().findReferenceAt(myFixture.getEditor().getCaretModel().getOffset());
|
||||
|
||||
assertTrue(psiReference instanceof PsiPolyVariantReference);
|
||||
|
||||
PsiPolyVariantReference variantReference = (PsiPolyVariantReference) psiReference;
|
||||
|
||||
ResolveResult[] results = variantReference.multiResolve(true);
|
||||
|
||||
List<String> actualResolvedTo = Lists.newArrayList();
|
||||
for (ResolveResult result : results) {
|
||||
PsiElement resolvedToElement = result.getElement();
|
||||
assertNotNull(resolvedToElement);
|
||||
|
||||
actualResolvedTo.add(ReferenceUtils.renderAsGotoImplementation(resolvedToElement));
|
||||
}
|
||||
|
||||
assertOrderedEquals(Ordering.natural().sortedCopy(actualResolvedTo), Ordering.natural().sortedCopy(expectedReferences));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ExpectedResolveData readResolveData(String fileText) {
|
||||
boolean shouldBeUnresolved = InTextDirectivesUtils.isDirectiveDefined(fileText, REF_EMPTY);
|
||||
List<String> refs = ReferenceUtils.getExpectedReferences(fileText);
|
||||
|
||||
String referenceToString;
|
||||
if (shouldBeUnresolved) {
|
||||
Assert.assertTrue("REF: directives will be ignored for " + REF_EMPTY + " test: " + refs, refs.isEmpty());
|
||||
referenceToString = "<empty>";
|
||||
}
|
||||
else {
|
||||
assertTrue("Must be a single ref: " + refs + ".\n" +
|
||||
"Use " + MULTIRESOLVE + " if you need multiple refs\n" +
|
||||
"Use "+ REF_EMPTY + " for an unresolved reference",
|
||||
refs.size() == 1);
|
||||
referenceToString = refs.get(0);
|
||||
Assert.assertNotNull("Test data wasn't found, use \"// REF: \" directive", referenceToString);
|
||||
}
|
||||
|
||||
return new ExpectedResolveData(shouldBeUnresolved, referenceToString);
|
||||
}
|
||||
|
||||
public static void checkReferenceResolve(ExpectedResolveData expectedResolveData, int offset, PsiReference psiReference) {
|
||||
if (psiReference != null) {
|
||||
PsiElement resolvedTo = psiReference.resolve();
|
||||
if (resolvedTo != null) {
|
||||
String resolvedToElementStr = ReferenceUtils.renderAsGotoImplementation(resolvedTo);
|
||||
String notEqualMessage = String.format("Found reference to '%s', but '%s' was expected",
|
||||
resolvedToElementStr, expectedResolveData.getReferenceString());
|
||||
assertEquals(notEqualMessage, expectedResolveData.getReferenceString(), resolvedToElementStr);
|
||||
}
|
||||
else {
|
||||
if (!expectedResolveData.shouldBeUnresolved()) {
|
||||
Assert.assertNull(
|
||||
String.format("Element %s wasn't resolved to anything, but %s was expected",
|
||||
psiReference, expectedResolveData.getReferenceString()),
|
||||
expectedResolveData.getReferenceString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Assert.assertNull(
|
||||
String.format("No reference found at offset: %s, but one resolved to %s was expected",
|
||||
offset, expectedResolveData.getReferenceString()),
|
||||
expectedResolveData.getReferenceString());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "./";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea.resolve
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import com.google.common.collect.Ordering
|
||||
import com.intellij.psi.PsiPolyVariantReference
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.util.PathUtil
|
||||
import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightPlatformCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.ReferenceUtils
|
||||
import org.jetbrains.kotlin.test.util.configureWithExtraFile
|
||||
import org.junit.Assert
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
public abstract class AbstractReferenceResolveTest : KotlinLightPlatformCodeInsightFixtureTestCase() {
|
||||
public class ExpectedResolveData(private val shouldBeUnresolved: Boolean?, public val referenceString: String) {
|
||||
|
||||
public fun shouldBeUnresolved(): Boolean {
|
||||
return shouldBeUnresolved!!
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun doTest(path: String) {
|
||||
assert(path.endsWith(".kt")) { path }
|
||||
myFixture.configureWithExtraFile(path, ".Data")
|
||||
performChecks()
|
||||
}
|
||||
|
||||
protected fun performChecks() {
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(myFixture.getFile().getText(), MULTIRESOLVE)) {
|
||||
doMultiResolveTest()
|
||||
}
|
||||
else {
|
||||
doSingleResolveTest()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doSingleResolveTest() {
|
||||
forEachCaret { index, offset ->
|
||||
val expectedResolveData = readResolveData(myFixture.getFile().getText(), index)
|
||||
val psiReference = myFixture.getFile().findReferenceAt(offset)
|
||||
checkReferenceResolve(expectedResolveData, offset, psiReference)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doMultiResolveTest() {
|
||||
forEachCaret { index, offset ->
|
||||
val expectedReferences = getExpectedReferences(myFixture.getFile().getText(), index)
|
||||
|
||||
val psiReference = myFixture.getFile().findReferenceAt(offset)
|
||||
assertTrue(psiReference is PsiPolyVariantReference)
|
||||
psiReference as PsiPolyVariantReference
|
||||
|
||||
val results = psiReference.multiResolve(true)
|
||||
|
||||
val actualResolvedTo = Lists.newArrayList<String>()
|
||||
for (result in results) {
|
||||
actualResolvedTo.add(ReferenceUtils.renderAsGotoImplementation(result.getElement()!!))
|
||||
}
|
||||
|
||||
UsefulTestCase.assertOrderedEquals("Not matching for reference #$index", actualResolvedTo.sort(), expectedReferences.sort())
|
||||
}
|
||||
}
|
||||
|
||||
private fun forEachCaret(action: (index: Int, offset: Int) -> Unit) {
|
||||
val offsets = myFixture.getEditor().getCaretModel().getAllCarets().map { it.getOffset() }
|
||||
val singleCaret = offsets.size() == 1
|
||||
for ((index, offset) in offsets.withIndex()) {
|
||||
action(if (singleCaret) -1 else index + 1, offset)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor? = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
override fun getTestDataPath() = "./"
|
||||
|
||||
companion object {
|
||||
public val MULTIRESOLVE: String = "MULTIRESOLVE"
|
||||
public val REF_EMPTY: String = "REF_EMPTY"
|
||||
|
||||
public fun readResolveData(fileText: String, index: Int): ExpectedResolveData {
|
||||
val shouldBeUnresolved = InTextDirectivesUtils.isDirectiveDefined(fileText, REF_EMPTY)
|
||||
val refs = getExpectedReferences(fileText, index)
|
||||
|
||||
val referenceToString: String
|
||||
if (shouldBeUnresolved) {
|
||||
Assert.assertTrue("REF: directives will be ignored for $REF_EMPTY test: $refs", refs.isEmpty())
|
||||
referenceToString = "<empty>"
|
||||
}
|
||||
else {
|
||||
assertTrue(refs.size() == 1, "Must be a single ref: $refs.\nUse $MULTIRESOLVE if you need multiple refs\nUse $REF_EMPTY for an unresolved reference")
|
||||
referenceToString = refs.get(0)
|
||||
Assert.assertNotNull("Test data wasn't found, use \"// REF: \" directive", referenceToString)
|
||||
}
|
||||
|
||||
return ExpectedResolveData(shouldBeUnresolved, referenceToString)
|
||||
}
|
||||
|
||||
// purpose of this helper is to deal with the case when navigation element is a file
|
||||
// see ReferenceResolveInJavaTestGenerated.testPackageFacade()
|
||||
private fun getExpectedReferences(text: String, index: Int): List<String> {
|
||||
val prefix = if (index > 0) "// REF$index:" else "// REF:"
|
||||
val prefixes = InTextDirectivesUtils.findLinesWithPrefixesRemoved(text, prefix)
|
||||
return prefixes.map {
|
||||
val replaced = it.replace("<test dir>", PluginTestCaseBase.getTestDataPathBase())
|
||||
PathUtil.toSystemDependentName(replaced).replace("//", "/") //happens on Unix
|
||||
}
|
||||
}
|
||||
|
||||
public fun checkReferenceResolve(expectedResolveData: ExpectedResolveData, offset: Int, psiReference: PsiReference?) {
|
||||
if (psiReference != null) {
|
||||
val resolvedTo = psiReference.resolve()
|
||||
if (resolvedTo != null) {
|
||||
val resolvedToElementStr = ReferenceUtils.renderAsGotoImplementation(resolvedTo)
|
||||
assertEquals(expectedResolveData.referenceString, resolvedToElementStr, "Found reference to '$resolvedToElementStr', but '${expectedResolveData.referenceString}' was expected")
|
||||
}
|
||||
else {
|
||||
if (!expectedResolveData.shouldBeUnresolved()) {
|
||||
assertNull(expectedResolveData.referenceString, "Element $psiReference wasn't resolved to anything, but ${expectedResolveData.referenceString} was expected")
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assertNull(expectedResolveData.referenceString, "No reference found at offset: $offset, but one resolved to ${expectedResolveData.referenceString} was expected")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,6 +347,12 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SyntheticProperty.kt")
|
||||
public void testSyntheticProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/SyntheticProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameterInAnonymousObject.kt")
|
||||
public void testTypeParameterInAnonymousObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/references/TypeParameterInAnonymousObject.kt");
|
||||
|
||||
@@ -21,17 +21,11 @@ import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.PathUtil;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
||||
import org.jetbrains.kotlin.psi.JetClass;
|
||||
import org.jetbrains.kotlin.psi.JetObjectDeclaration;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class ReferenceUtils {
|
||||
private ReferenceUtils() {
|
||||
}
|
||||
@@ -60,18 +54,4 @@ public final class ReferenceUtils {
|
||||
? presentableText
|
||||
: locationString + "." + presentableText;
|
||||
}
|
||||
|
||||
// purpose of this helper is to deal with the case when navigation element is a file
|
||||
// see ReferenceResolveInJavaTestGenerated.testPackageFacade()
|
||||
@NotNull
|
||||
public static List<String> getExpectedReferences(@NotNull String text) {
|
||||
List<String> prefixes = InTextDirectivesUtils.findLinesWithPrefixesRemoved(text, "// REF:");
|
||||
return KotlinPackage.map(prefixes, new Function1<String, String>() {
|
||||
@Override
|
||||
public String invoke(String s) {
|
||||
String replaced = s.replace("<test dir>", PluginTestCaseBase.getTestDataPathBase());
|
||||
return PathUtil.toSystemDependentName(replaced).replace("//", "/"); //happens on Unix
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user