diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt index 5fa7c856abf..afac851eea0 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt @@ -104,8 +104,6 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC } private val _containingFile: PsiFile by lazyPub { - classOrObject.containingFile.virtualFile ?: error("No virtual file for " + classOrObject.text) - object : FakeFileForLightClass( classOrObject.containingKtFile, { if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! }, diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/FakeFileForLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/FakeFileForLightClass.kt index 2fb42b02499..53b0cc673d2 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/FakeFileForLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/FakeFileForLightClass.kt @@ -33,7 +33,7 @@ open class FakeFileForLightClass( private val lightClass: () -> KtLightClass, private val stub: () -> PsiClassHolderFileStub<*>, private val packageFqName: FqName = ktFile.packageFqName -) : ClsFileImpl(ClassFileViewProvider(ktFile.manager, ktFile.virtualFile)) { +) : ClsFileImpl(ClassFileViewProvider(ktFile.manager, ktFile.viewProvider.virtualFile)) { override fun getPackageName() = packageFqName.asString() override fun getStub() = stub() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index c81f2f36346..8ee35ea826e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -129,7 +129,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG return SourceNavigationHelper.getOriginalClass(classOrObject) as? KtLightClass } } - if ((classOrObject.containingFile as? KtFile)?.analysisContext != null) { + if ((classOrObject.containingFile as? KtFile)?.analysisContext != null || + classOrObject.containingFile.originalFile.virtualFile != null) { // explicit request to create light class from dummy.kt return KtLightClassForSourceDeclaration.create(classOrObject) } diff --git a/plugins/uast-kotlin/build.gradle.kts b/plugins/uast-kotlin/build.gradle.kts index e5b43a2d86a..bedc34c2033 100644 --- a/plugins/uast-kotlin/build.gradle.kts +++ b/plugins/uast-kotlin/build.gradle.kts @@ -14,8 +14,20 @@ dependencies { testCompile(commonDep("junit:junit")) testCompile(project(":compiler:util")) testCompile(project(":compiler:cli")) - testCompile(project(":idea:idea-android")) + testCompile(project(":idea:idea-test-framework")) testRuntime(ideaSdkDeps("*.jar")) + testRuntime(ideaPluginDeps("*.jar", plugin = "junit")) + testRuntime(ideaPluginDeps("*.jar", plugin = "gradle")) + testRuntime(ideaPluginDeps("*.jar", plugin = "Groovy")) + testRuntime(ideaPluginDeps("*.jar", plugin = "android")) + testRuntime(ideaPluginDeps("*.jar", plugin = "maven")) + testRuntime(ideaPluginDeps("resources_en", plugin = "properties")) + testRuntime(project(":idea:idea-android")) + testRuntime(project(":idea:idea-gradle")) + testRuntime(project(":sam-with-receiver-ide-plugin")) + testRuntime(project(":allopen-ide-plugin")) + testRuntime(project(":noarg-ide-plugin")) + testRuntime(project(":plugins:android-extensions-ide")) } sourceSets { diff --git a/plugins/uast-kotlin/tests/KotlinDetachedUastTest.kt b/plugins/uast-kotlin/tests/KotlinDetachedUastTest.kt new file mode 100644 index 00000000000..c75a1df7437 --- /dev/null +++ b/plugins/uast-kotlin/tests/KotlinDetachedUastTest.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2017 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.uast.test.kotlin + +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiLanguageInjectionHost +import com.intellij.testFramework.LightProjectDescriptor +import junit.framework.TestCase +import org.jetbrains.kotlin.idea.core.copied +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.psi.psiUtil.getParentOfType +import org.jetbrains.uast.UClass +import org.jetbrains.uast.getParentOfType +import org.jetbrains.uast.toUElement + +class KotlinDetachedUastTest : KotlinLightCodeInsightFixtureTestCase() { + + override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + + + fun testStringAnnotationWithEmpty() { + + val psiFile = myFixture.configureByText("AnnotatedClass.kt", """ + class AnnotatedClass { + @JvmName(name = "") + fun bar(param: String) = null + } + """.trimIndent()) + + fun psiElement(file: PsiFile): Any? = (file.findElementAt(file.text.indexOf("\"\"")) ?: error("not found")) + .getParentOfType(false).orFail("host") + .toUElement().orFail("uelement").getParentOfType(false) + .orFail("UClass").psi.orFail("psi").also { + } + + TestCase.assertNotNull("base", psiElement(psiFile)) + val copied = psiFile.copied() + TestCase.assertNull("vf for $copied", copied.virtualFile) + TestCase.assertNotNull("copy", psiElement(copied)) + } +} + +fun T?.orFail(msg: String): T = this ?: error(msg) \ No newline at end of file