diff --git a/annotations/com/intellij/codeInsight/navigation/annotations.xml b/annotations/com/intellij/codeInsight/navigation/annotations.xml new file mode 100644 index 00000000000..0c047681c6c --- /dev/null +++ b/annotations/com/intellij/codeInsight/navigation/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index 180aeb4b0fd..f2f1aca580a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -44,10 +44,12 @@ import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.SpecialNames; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.storage.MemoizedFunctionToNullable; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import static org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve; @@ -205,13 +207,19 @@ public class ResolveSession implements KotlinCodeAnalyzer { // class A {} class A { fun foo(): A} // and if we find the class by name only, we may b-not get the right one. // This call is only needed to make sure the classes are written to trace - resolutionScope.getClassifier(name); - DeclarationDescriptor declaration = getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject); + ClassifierDescriptor scopeDescriptor = resolutionScope.getClassifier(name); + DeclarationDescriptor descriptor = getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject); - if (declaration == null) { - throw new IllegalArgumentException("Could not find a classifier for " + classOrObject + " " + classOrObject.getText()); + if (descriptor == null) { + throw new IllegalArgumentException( + String.format("Could not find a classifier for %s.\n" + + "Found descriptor: %s (%s).\n", + JetPsiUtil.getElementTextWithContext(classOrObject), + scopeDescriptor != null ? DescriptorRenderer.DEBUG_TEXT.render(scopeDescriptor) : "null", + scopeDescriptor != null ? (scopeDescriptor.getContainingDeclaration().getClass()) : null)); } - return (ClassDescriptor) declaration; + + return (ClassDescriptor) descriptor; } @NotNull diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index df8fb1116ca..b0759939e00 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -84,6 +84,7 @@ import org.jetbrains.jet.plugin.conversion.copy.AbstractJavaToKotlinCopyPasteCon import org.jetbrains.jet.shortenRefs.AbstractShortenRefsTest import org.jetbrains.jet.completion.handlers.AbstractSmartCompletionHandlerTest import org.jetbrains.jet.resolve.AbstractAdditionalLazyResolveDescriptorRendererTest +import org.jetbrains.jet.resolve.AbstractReferenceResolveInLibrarySourcesTest fun main(args: Array) { System.setProperty("java.awt.headless", "true") @@ -393,6 +394,10 @@ fun main(args: Array) { model("resolve/referenceWithLib", recursive = false) } + testClass(javaClass()) { + model("resolve/referenceInLib", recursive = false) + } + testClass(javaClass()) { model("findUsages/kotlin", pattern = """^(.+)\.0\.kt$""") model("findUsages/java", pattern = """^(.+)\.0\.java$""") diff --git a/idea/testData/resolve/referenceInLib/builtInNumber.kt b/idea/testData/resolve/referenceInLib/builtInNumber.kt new file mode 100644 index 00000000000..bca8e42af70 --- /dev/null +++ b/idea/testData/resolve/referenceInLib/builtInNumber.kt @@ -0,0 +1,6 @@ +val a: Number? = null + +// CONTEXT: public abstract fun toDouble() : Double +// RUNTIME + +// REF: (jet).Double \ No newline at end of file diff --git a/idea/testData/resolve/referenceInLib/inLibrarySource.kt b/idea/testData/resolve/referenceInLib/inLibrarySource.kt new file mode 100644 index 00000000000..16b84db2938 --- /dev/null +++ b/idea/testData/resolve/referenceInLib/inLibrarySource.kt @@ -0,0 +1,8 @@ +import inlibrary.test.* + +val a: ReferenceTest? = null + +// CONTEXT: val test: Test? = null +// WITH_LIBRARY: /resolve/referenceInLib/inLibrarySource + +// REF: (inlibrary.test).Test \ No newline at end of file diff --git a/idea/testData/resolve/referenceInLib/inLibrarySource/reference.kt b/idea/testData/resolve/referenceInLib/inLibrarySource/reference.kt new file mode 100644 index 00000000000..a312a5085c7 --- /dev/null +++ b/idea/testData/resolve/referenceInLib/inLibrarySource/reference.kt @@ -0,0 +1,5 @@ +package inlibrary.test + +class ReferenceTest { + val test: Test? = null +} \ No newline at end of file diff --git a/idea/testData/resolve/referenceInLib/inLibrarySource/test.kt b/idea/testData/resolve/referenceInLib/inLibrarySource/test.kt new file mode 100644 index 00000000000..4d84691c956 --- /dev/null +++ b/idea/testData/resolve/referenceInLib/inLibrarySource/test.kt @@ -0,0 +1,3 @@ +package inlibrary.test + +trait Test \ No newline at end of file diff --git a/idea/testData/resolve/referenceWithLib/sameNameInLib.kt b/idea/testData/resolve/referenceWithLib/sameNameInLib.kt new file mode 100644 index 00000000000..c5e032d8ac7 --- /dev/null +++ b/idea/testData/resolve/referenceWithLib/sameNameInLib.kt @@ -0,0 +1,7 @@ +package test + +class Foo { + val s: String = "" +} + +// REF: (jet).String \ No newline at end of file diff --git a/idea/testData/resolve/referenceWithLib/sameNameInLibSrc/libFile.kt b/idea/testData/resolve/referenceWithLib/sameNameInLibSrc/libFile.kt new file mode 100644 index 00000000000..ab9e2e14368 --- /dev/null +++ b/idea/testData/resolve/referenceWithLib/sameNameInLibSrc/libFile.kt @@ -0,0 +1,3 @@ +package test + +class Foo \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java index 4826bcb4353..ba238e9b22f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java +++ b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.utils.ExceptionUtils; import java.io.File; import java.io.IOException; +import java.util.List; public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsightFixtureTestCase { @Override @@ -46,7 +47,11 @@ public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsigh try { String fileText = FileUtil.loadFile(new File(getTestDataPath(), fileName())); - if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME")) { + List withLibraryDirective = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "WITH_LIBRARY:"); + if (!withLibraryDirective.isEmpty()) { + return new JdkAndMockLibraryProjectDescriptor(PluginTestCaseBase.getTestDataPathBase() + "/" + withLibraryDirective.get(0), true); + } + else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME")) { return JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE; } else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "JS")) { diff --git a/idea/tests/org/jetbrains/jet/resolve/AbstractReferenceResolveInLibrarySourcesTest.kt b/idea/tests/org/jetbrains/jet/resolve/AbstractReferenceResolveInLibrarySourcesTest.kt new file mode 100644 index 00000000000..8b1cceb1ad4 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/resolve/AbstractReferenceResolveInLibrarySourcesTest.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2014 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.jet.resolve + +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase +import org.jetbrains.jet.plugin.navigation.NavigationTestUtils +import org.jetbrains.jet.InTextDirectivesUtils +import java.io.File +import org.jetbrains.jet.plugin.PluginTestCaseBase +import org.junit.Assert +import junit.framework.AssertionFailedError + +public abstract class AbstractReferenceResolveInLibrarySourcesTest : JetLightCodeInsightFixtureTestCase() { + class object { + val CARET_MARKER = "" + } + + fun doTest(path: String) { + val fixture = myFixture!! + + fixture.configureByFile(path) + + val expectedResolveData = AbstractReferenceResolveTest.readResolveData(fixture.getFile()!!.getText()) + + val gotoData = NavigationTestUtils.invokeGotoImplementations(fixture.getEditor(), fixture.getFile())!! + Assert.assertEquals("Single target expected for origianl file", 1, gotoData.targets.size) + + val testedPsiElement = gotoData.targets[0] + val testedElementFile = testedPsiElement.getContainingFile()!! + + val lineContext = InTextDirectivesUtils.findStringWithPrefixes(fixture.getFile()!!.getText(), "CONTEXT:") + if (lineContext == null) { + throw AssertionFailedError("'CONTEXT: ' directive is expected to set up position in library file: ${testedElementFile.getName()}") + } + + val inContextOffset = lineContext.indexOf(CARET_MARKER) + if (inContextOffset == -1) throw IllegalStateException("No '$CARET_MARKER' marker found in 'CONTEXT: $lineContext'") + + val contextStr = lineContext.replace(CARET_MARKER, "") + val offsetInFile = testedElementFile.getText()!!.indexOf(contextStr) + if (offsetInFile == -1) throw IllegalStateException("Context '$contextStr' wasn't found in file ${testedElementFile.getName()}") + + val offset = offsetInFile + inContextOffset + + val reference = testedElementFile.findReferenceAt(offset)!! + + AbstractReferenceResolveTest.checkReferenceResolve(expectedResolveData, offset, reference) + } + + override fun getTestDataPath() : String = File(PluginTestCaseBase.getTestDataPathBase(), "/resolve/referenceInLib").getPath() + File.separator + override fun fileName(): String = getTestName(true) + ".kt" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveInLibrarySourcesTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveInLibrarySourcesTestGenerated.java new file mode 100644 index 00000000000..38ee25c8a1a --- /dev/null +++ b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveInLibrarySourcesTestGenerated.java @@ -0,0 +1,49 @@ +/* + * Copyright 2010-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 org.jetbrains.jet.resolve; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.resolve.AbstractReferenceResolveInLibrarySourcesTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/resolve/referenceInLib") +public class ReferenceResolveInLibrarySourcesTestGenerated extends AbstractReferenceResolveInLibrarySourcesTest { + public void testAllFilesPresentInReferenceInLib() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/resolve/referenceInLib"), Pattern.compile("^(.+)\\.kt$"), false); + } + + @TestMetadata("builtInNumber.kt") + public void testBuiltInNumber() throws Exception { + doTest("idea/testData/resolve/referenceInLib/builtInNumber.kt"); + } + + @TestMetadata("inLibrarySource.kt") + public void testInLibrarySource() throws Exception { + doTest("idea/testData/resolve/referenceInLib/inLibrarySource.kt"); + } + +} diff --git a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveWithLibTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveWithLibTestGenerated.java index 0d79be5cf4b..888ceed83b4 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveWithLibTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/resolve/ReferenceResolveWithLibTestGenerated.java @@ -46,4 +46,9 @@ public class ReferenceResolveWithLibTestGenerated extends AbstractReferenceResol doTest("idea/testData/resolve/referenceWithLib/fakeOverride2.kt"); } + @TestMetadata("sameNameInLib.kt") + public void testSameNameInLib() throws Exception { + doTest("idea/testData/resolve/referenceWithLib/sameNameInLib.kt"); + } + }