Implement light classes for Kotlin scripts
This commit is contained in:
+24
-10
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -92,10 +93,18 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
)
|
||||
}
|
||||
|
||||
private fun getContext(): LightClassConstructionContext {
|
||||
return LightClassConstructionContext(bindingContext, module)
|
||||
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
||||
val (stub, _, diagnostics) = builder(getContext())
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
override fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript {
|
||||
val (stub, _, diagnostics) = builder(getContext())
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
private fun getContext(): LightClassConstructionContext = LightClassConstructionContext(bindingContext, module)
|
||||
|
||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(module, fqName).mapNotNull {
|
||||
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
||||
@@ -143,9 +152,9 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
})
|
||||
}
|
||||
|
||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? {
|
||||
return KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
}
|
||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||
|
||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||
return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
@@ -163,6 +172,16 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade))
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
if (scriptFqName.isRoot) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
|
||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
//
|
||||
return emptyList()
|
||||
@@ -176,11 +195,6 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
}
|
||||
}
|
||||
|
||||
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
||||
val (stub, _, diagnostics) = builder(getContext())
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
override fun createTrace(): BindingTraceContext {
|
||||
return NoScopeRecordCliBindingTrace()
|
||||
}
|
||||
|
||||
+8
-4
@@ -22,12 +22,10 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
|
||||
@@ -38,6 +36,8 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade
|
||||
|
||||
abstract fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript
|
||||
|
||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
|
||||
/*
|
||||
@@ -61,6 +61,8 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun getLightClass(classOrObject: KtClassOrObject): KtLightClass?
|
||||
|
||||
abstract fun getLightClassForScript(script: KtScript): KtLightClassForScript?
|
||||
|
||||
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
||||
|
||||
abstract fun analyze(element: KtElement): BindingContext
|
||||
@@ -69,6 +71,8 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
+5
-1
@@ -53,6 +53,10 @@ interface LightClassDataHolder {
|
||||
interface ForFacade : LightClassDataHolder {
|
||||
fun findDataForFacade(classFqName: FqName): LightClassData = findData { it.findDelegate(classFqName) }
|
||||
}
|
||||
|
||||
interface ForScript : ForClass {
|
||||
fun findDataForScript(scriptFqName: FqName): LightClassData = findData { it.findDelegate(scriptFqName) }
|
||||
}
|
||||
}
|
||||
|
||||
interface LightClassData {
|
||||
@@ -85,7 +89,7 @@ object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
|
||||
class LightClassDataHolderImpl(
|
||||
override val javaFileStub: PsiJavaFileStub,
|
||||
override val extraDiagnostics: Diagnostics
|
||||
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade {
|
||||
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript {
|
||||
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = findDelegate(javaFileStub).let(::LightClassDataImpl)
|
||||
}
|
||||
|
||||
|
||||
+39
@@ -128,6 +128,31 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
||||
}
|
||||
|
||||
|
||||
class LightClassDataProviderForScript(private val script: KtScript) : CachedValueProvider<LightClassDataHolder.ForScript> {
|
||||
private fun computeLightClassData(): LightClassDataHolder.ForScript {
|
||||
return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) {
|
||||
constructionContext ->
|
||||
buildLightClass(
|
||||
script.fqName.parent(),
|
||||
listOf(script.containingKtFile),
|
||||
ClassFilterForScript(script),
|
||||
constructionContext
|
||||
) generate@ {
|
||||
state, files ->
|
||||
val scriptFile = files.first()
|
||||
val codegen = state.factory.forPackage(scriptFile.packageFqName, files)
|
||||
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
|
||||
state.factory.done()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun compute(): CachedValueProvider.Result<LightClassDataHolder.ForScript>? =
|
||||
CachedValueProvider.Result.create(computeLightClassData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
|
||||
|
||||
override fun toString(): String = this::class.java.name + " for ${script.fqName}"
|
||||
}
|
||||
|
||||
interface StubComputationTracker {
|
||||
fun onStubComputed(javaFileStub: PsiJavaFileStub, context: LightClassConstructionContext)
|
||||
}
|
||||
@@ -181,3 +206,17 @@ object ClassFilterForFacade : GenerationState.GenerateClassFilter() {
|
||||
override fun shouldGeneratePackagePart(ktFile: KtFile) = true
|
||||
override fun shouldGenerateScript(script: KtScript) = false
|
||||
}
|
||||
|
||||
private class ClassFilterForScript(val script: KtScript) : GenerationState.GenerateClassFilter() {
|
||||
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean =
|
||||
shouldGenerateClass(processingClassOrObject)
|
||||
|
||||
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean =
|
||||
processingClassOrObject.isAncestor(script, true)
|
||||
|
||||
override fun shouldGenerateClassMembers(processingClassOrObject: KtClassOrObject): Boolean = true
|
||||
|
||||
override fun shouldGeneratePackagePart(ktFile: KtFile): Boolean = script.containingKtFile === ktFile
|
||||
|
||||
override fun shouldGenerateScript(script: KtScript): Boolean = this.script === script
|
||||
}
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.kotlin.asJava.classes
|
||||
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightEmptyImplementsList
|
||||
import com.intellij.psi.impl.light.LightModifierList
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForScript
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import javax.swing.Icon
|
||||
|
||||
class KtLightClassForScript private constructor(
|
||||
val script: KtScript,
|
||||
private val lightClassDataCache: CachedValue<LightClassDataHolder.ForScript>
|
||||
) : KtLazyLightClass(script.manager) {
|
||||
|
||||
private val hashCode: Int = computeHashCode()
|
||||
|
||||
private val packageFqName: FqName = script.fqName.parent()
|
||||
|
||||
private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC)
|
||||
|
||||
private val implementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager)
|
||||
|
||||
private val _containingFile by lazyPub {
|
||||
FakeFileForLightClass(
|
||||
script.containingKtFile,
|
||||
lightClass = { this },
|
||||
stub = { lightClassDataCache.value.javaFileStub },
|
||||
packageFqName = packageFqName)
|
||||
}
|
||||
|
||||
override val kotlinOrigin: KtClassOrObject? get() = null
|
||||
|
||||
val fqName: FqName = script.fqName
|
||||
|
||||
override fun getModifierList() = modifierList
|
||||
|
||||
override fun hasModifierProperty(@NonNls name: String) = modifierList.hasModifierProperty(name)
|
||||
|
||||
override fun isDeprecated() = false
|
||||
|
||||
override fun isInterface() = false
|
||||
|
||||
override fun isAnnotationType() = false
|
||||
|
||||
override fun isEnum() = false
|
||||
|
||||
override fun getContainingClass() = null
|
||||
|
||||
override fun getContainingFile() = _containingFile
|
||||
|
||||
override fun hasTypeParameters() = false
|
||||
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
|
||||
|
||||
override fun getTypeParameterList() = null
|
||||
|
||||
override fun getDocComment() = null
|
||||
|
||||
override fun getImplementsList() = implementsList
|
||||
|
||||
override fun getImplementsListTypes(): Array<PsiClassType> = PsiClassType.EMPTY_ARRAY
|
||||
|
||||
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
||||
|
||||
override fun getOwnInnerClasses(): List<PsiClass> {
|
||||
return script.declarations.filterIsInstance<KtClassOrObject>()
|
||||
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
|
||||
// inner classes with null names can't be searched for and can't be used from java anyway
|
||||
// we can't prohibit creating light classes with null names either since they can contain members
|
||||
.filter { it.name != null }
|
||||
.mapNotNull { KtLightClassForSourceDeclaration.create(it) }
|
||||
}
|
||||
|
||||
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
||||
|
||||
override fun getName() = script.fqName.shortName().asString()
|
||||
|
||||
override fun getQualifiedName() = script.fqName.asString()
|
||||
|
||||
override fun isValid() = script.isValid
|
||||
|
||||
override fun copy() = KtLightClassForScript(script, lightClassDataCache)
|
||||
|
||||
override val lightClassData = lightClassDataCache.value.findDataForScript(script.fqName)
|
||||
|
||||
override fun getNavigationElement() = script
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
||||
another is PsiClass && Comparing.equal(another.qualifiedName, qualifiedName)
|
||||
|
||||
override fun getElementIcon(flags: Int): Icon? = throw UnsupportedOperationException("This should be done by JetIconProvider")
|
||||
|
||||
override fun hashCode() = hashCode
|
||||
|
||||
private fun computeHashCode(): Int {
|
||||
var result = manager.hashCode()
|
||||
result = 31 * result + script.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other == null || this::class.java != other::class.java) {
|
||||
return false
|
||||
}
|
||||
|
||||
val lightClass = other as KtLightClassForScript
|
||||
if (this === other) return true
|
||||
|
||||
if (this.hashCode != lightClass.hashCode) return false
|
||||
if (manager != lightClass.manager) return false
|
||||
if (script != lightClass.script) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun toString() = "${KtLightClassForScript::class.java.simpleName}:${script.fqName}"
|
||||
|
||||
companion object {
|
||||
|
||||
private val JAVA_API_STUB_FOR_SCRIPT = Key.create<CachedValue<LightClassDataHolder.ForScript>>("JAVA_API_STUB_FOR_SCRIPT")
|
||||
|
||||
fun create(script: KtScript): KtLightClassForScript = KtLightClassForScript(script, getLightClassCachedValue(script))
|
||||
|
||||
fun getLightClassCachedValue(script: KtScript): CachedValue<LightClassDataHolder.ForScript> {
|
||||
return script.getUserData(JAVA_API_STUB_FOR_SCRIPT) ?:
|
||||
createCachedValueForScript(script).also { script.putUserData(JAVA_API_STUB_FOR_SCRIPT, it) }
|
||||
}
|
||||
|
||||
private fun createCachedValueForScript(script: KtScript): CachedValue<LightClassDataHolder.ForScript> =
|
||||
CachedValuesManager.getManager(script.project).createCachedValue(LightClassDataProviderForScript(script), false)
|
||||
}
|
||||
|
||||
override val originKind: LightClassOriginKind get() = LightClassOriginKind.SOURCE
|
||||
}
|
||||
+5
-7
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||
@@ -334,7 +331,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
|
||||
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||
if (classOrObject.containingKtFile.isScript() || classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
||||
if (classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -366,10 +363,11 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
}
|
||||
|
||||
fun getLightClassDataHolder(classOrObject: KtClassOrObject): LightClassDataHolder.ForClass {
|
||||
return getLightClassCachedValue(classOrObject).value
|
||||
return classOrObject.containingKtFile.script?.let { KtLightClassForScript.getLightClassCachedValue(it).value } ?:
|
||||
getLightClassCachedValue(classOrObject).value
|
||||
}
|
||||
|
||||
fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
|
||||
private fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
|
||||
var value =
|
||||
getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) // stub computed for outer class can be used for inner/nested
|
||||
?: classOrObject.getUserData(JAVA_API_STUB)
|
||||
|
||||
+1
-5
@@ -33,10 +33,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -90,7 +87,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
FqName qualifiedName = new FqName(qualifiedNameString);
|
||||
|
||||
findClassesAndObjects(qualifiedName, scope, answer);
|
||||
|
||||
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
|
||||
answer.addAll(lightClassGenerationSupport.getKotlinInternalClasses(qualifiedName, scope));
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||
@@ -52,6 +53,8 @@ fun KtFile.findFacadeClass(): KtLightClass? {
|
||||
.firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass
|
||||
}
|
||||
|
||||
fun KtScript.toLightClass(): KtLightClassForScript? = LightClassGenerationSupport.getInstance(project).getLightClassForScript(this)
|
||||
|
||||
fun KtElement.toLightElements(): List<PsiNamedElement> =
|
||||
when (this) {
|
||||
is KtClassOrObject -> listOfNotNull(toLightClass())
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
public class HelloWorld extends kotlin.script.templates.standard.ScriptTemplateWithArgs {
|
||||
public HelloWorld(java.lang.String[] p) { /* compiled code */ }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// HelloWorld
|
||||
|
||||
println("Hello world!")
|
||||
@@ -0,0 +1,22 @@
|
||||
public class InnerClasses extends kotlin.script.templates.standard.ScriptTemplateWithArgs {
|
||||
public InnerClasses(java.lang.String[] p) { /* compiled code */ }
|
||||
|
||||
public static final class Bar {
|
||||
private final int b = 0;
|
||||
private final int a;
|
||||
|
||||
public final int getB() { /* compiled code */ }
|
||||
|
||||
public final int getAPlusB() { /* compiled code */ }
|
||||
|
||||
public final int getA() { /* compiled code */ }
|
||||
|
||||
public Bar(int a) { /* compiled code */ }
|
||||
|
||||
public static final class Baz {
|
||||
public final void doSomething() { /* compiled code */ }
|
||||
|
||||
public Baz() { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// InnerClasses
|
||||
|
||||
class Bar(val a: Int) {
|
||||
val b: Int = 0
|
||||
|
||||
fun getAPlusB() = a + b
|
||||
|
||||
class Baz {
|
||||
fun doSomething() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ object LightClassTestCommon {
|
||||
expectedFile: File,
|
||||
testDataFile: File,
|
||||
findLightClass: (String) -> PsiClass?,
|
||||
normalizeText: (String) -> String = { it }
|
||||
normalizeText: (String) -> String
|
||||
) {
|
||||
val text = FileUtil.loadFile(testDataFile, true)
|
||||
val matcher = SUBJECT_FQ_NAME_PATTERN.matcher(text)
|
||||
@@ -57,8 +57,8 @@ object LightClassTestCommon {
|
||||
|
||||
val buffer = StringBuilder()
|
||||
(delegate as ClsElementImpl).appendMirrorText(0, buffer)
|
||||
val actual = normalizeText(buffer.toString())
|
||||
return actual
|
||||
|
||||
return normalizeText(buffer.toString())
|
||||
}
|
||||
|
||||
// Actual text for light class is generated with ClsElementImpl.appendMirrorText() that can find empty DefaultImpl inner class in stubs
|
||||
|
||||
+2
-2
@@ -81,7 +81,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
|
||||
CollectionsKt.plus(Collections.singletonList(KotlinTestUtils.getAnnotationsJar()), getExtraClasspath()),
|
||||
isJavaSourceRootNeeded() ? Collections.singletonList(javaFilesDir) : Collections.emptyList()
|
||||
);
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
|
||||
if (isKotlinSourceRootNeeded()) {
|
||||
ContentRootsKt.addKotlinSourceRoot(configuration, kotlinSourceRoot.getPath());
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
|
||||
writeSourceFile(fileName, text, javaFilesDir);
|
||||
}
|
||||
|
||||
if (fileName.endsWith(".kt") && kotlinSourceRoot != null) {
|
||||
if ((fileName.endsWith(".kt") || fileName.endsWith(".kts")) && kotlinSourceRoot != null) {
|
||||
writeSourceFile(fileName, text, kotlinSourceRoot);
|
||||
}
|
||||
|
||||
|
||||
@@ -563,7 +563,7 @@ public class KotlinTestUtils {
|
||||
else {
|
||||
//noinspection ConstantConditions
|
||||
for (File childFile : file.listFiles()) {
|
||||
if (childFile.getName().endsWith(".kt")) {
|
||||
if (childFile.getName().endsWith(".kt") || childFile.getName().endsWith(".kts")) {
|
||||
ktFiles.add(loadJetFile(environment.getProject(), childFile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -14,63 +14,50 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava;
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder;
|
||||
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava<Void, Void>() {
|
||||
override fun getConfigurationKind(): ConfigurationKind = ConfigurationKind.ALL
|
||||
|
||||
public abstract class AbstractCompilerLightClassTest extends KotlinMultiFileTestWithJava<Void, Void> {
|
||||
@NotNull
|
||||
@Override
|
||||
protected ConfigurationKind getConfigurationKind() {
|
||||
return ConfigurationKind.ALL;
|
||||
override fun isKotlinSourceRootNeeded(): Boolean = true
|
||||
|
||||
override fun doMultiFileTest(file: File, modules: MutableMap<String, ModuleAndDependencies>, files: MutableList<Void>) {
|
||||
val environment = createEnvironment(file)
|
||||
val expectedFile = KotlinTestUtils.replaceExtension(file, "java")
|
||||
LightClassTestCommon.testLightClass(
|
||||
expectedFile,
|
||||
file,
|
||||
{ fqname -> findLightClass(environment, fqname) },
|
||||
LightClassTestCommon::removeEmptyDefaultImpls
|
||||
)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isKotlinSourceRootNeeded() {
|
||||
return true;
|
||||
}
|
||||
override fun createTestModule(name: String): Void? = null
|
||||
|
||||
@NotNull
|
||||
public static JavaElementFinder createFinder(@NotNull KotlinCoreEnvironment environment) throws IOException {
|
||||
// We need to resolve all the files in order too fill in the trace that sits inside LightClassGenerationSupport
|
||||
KotlinTestUtils.resolveAllKotlinFiles(environment);
|
||||
override fun createTestFile(module: Void?, fileName: String, text: String, directives: Map<String, String>): Void? = null
|
||||
|
||||
return JavaElementFinder.getInstance(environment.getProject());
|
||||
}
|
||||
companion object {
|
||||
fun findLightClass(environment: KotlinCoreEnvironment, fqname: String): PsiClass? {
|
||||
KotlinTestUtils.resolveAllKotlinFiles(environment)
|
||||
|
||||
@Override
|
||||
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<Void> files) throws IOException {
|
||||
KotlinCoreEnvironment environment = createEnvironment(file);
|
||||
File expectedFile = KotlinTestUtils.replaceExtension(file, "java");
|
||||
LightClassTestCommon.INSTANCE.testLightClass(expectedFile, file, s -> {
|
||||
try {
|
||||
return createFinder(environment).findClass(s, GlobalSearchScope.allScope(environment.getProject()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}, LightClassTestCommon.INSTANCE::removeEmptyDefaultImpls);
|
||||
}
|
||||
val lightCLassForScript = LightClassGenerationSupport
|
||||
.getInstance(environment.project)
|
||||
.getScriptClasses(FqName(fqname), GlobalSearchScope.allScope(environment.project))
|
||||
.firstOrNull()
|
||||
|
||||
@Override
|
||||
protected Void createTestModule(@NotNull String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void createTestFile(Void module, String fileName, String text, Map<String, String> directives) {
|
||||
return null;
|
||||
return lightCLassForScript ?: JavaElementFinder
|
||||
.getInstance(environment.project)
|
||||
.findClass(fqname, GlobalSearchScope.allScope(environment.project))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true, "local", "ideRegression");
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "local", "ideRegression");
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationClass.kt")
|
||||
@@ -155,7 +155,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CompilationErrors extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInCompilationErrors() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationModifiers.kt")
|
||||
@@ -206,7 +206,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Delegation extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInDelegation() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Function.kt")
|
||||
@@ -220,12 +220,6 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Property.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("WithPlatformTypes.NoCompile.kt")
|
||||
public void testWithPlatformTypes_NoCompile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/WithPlatformTypes.NoCompile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/facades")
|
||||
@@ -233,13 +227,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Facades extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInFacades() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyFile.NoCompile.kt")
|
||||
public void testEmptyFile_NoCompile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/facades/EmptyFile.NoCompile.kt");
|
||||
doTest(fileName);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiFile.kt")
|
||||
@@ -266,7 +254,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NullabilityAnnotations extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Class.kt")
|
||||
@@ -383,7 +371,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Object extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInObject() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleObject.kt")
|
||||
@@ -398,7 +386,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PublicField extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInPublicField() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObject.kt")
|
||||
@@ -413,4 +401,25 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/script")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Script extends AbstractCompilerLightClassTest {
|
||||
public void testAllFilesPresentInScript() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("HelloWorld.kts")
|
||||
public void testHelloWorld() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClasses.kts")
|
||||
public void testInnerClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,9 @@ public abstract class KotlinAsJavaTestBase extends KotlinTestWithEnvironment {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
finder = AbstractCompilerLightClassTest.createFinder(getEnvironment());
|
||||
KotlinCoreEnvironment environment = getEnvironment();
|
||||
KotlinTestUtils.resolveAllKotlinFiles(environment);
|
||||
finder = JavaElementFinder.getInstance(environment.getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -197,6 +197,8 @@ import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@Language("RegExp") private val KT_OR_KTS = """^(.+)\.(kt|kts)$"""
|
||||
@Language("RegExp") private val KT_OR_KTS_WITHOUT_DOTS_IN_NAME = """^([^.]+)\.(kt|kts)$"""
|
||||
|
||||
@Language("RegExp") private val KT_WITHOUT_DOTS_IN_NAME = """^([^.]+)\.kt$"""
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -467,7 +469,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractCompilerLightClassTest> {
|
||||
model("asJava/lightClasses", excludeDirs = listOf("local", "ideRegression"))
|
||||
model("asJava/lightClasses", excludeDirs = listOf("local", "ideRegression"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
|
||||
testClass<AbstractTypeBindingTest> {
|
||||
@@ -1129,11 +1131,11 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractIdeLightClassTest> {
|
||||
model("asJava/lightClasses", excludeDirs = listOf("delegation"), pattern = KT_WITHOUT_DOTS_IN_NAME)
|
||||
model("asJava/lightClasses", excludeDirs = listOf("delegation"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
|
||||
testClass<AbstractIdeCompiledLightClassTest> {
|
||||
model("asJava/lightClasses", excludeDirs = listOf("local", "compilationErrors", "ideRegression"), pattern = KT_WITHOUT_DOTS_IN_NAME)
|
||||
model("asJava/lightClasses", excludeDirs = listOf("local", "compilationErrors", "ideRegression"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-4
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.asJava.LightClassBuilder
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
@@ -84,6 +81,14 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
)
|
||||
}
|
||||
|
||||
override fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript {
|
||||
return LazyLightClassDataHolder.ForScript(
|
||||
builder,
|
||||
exactContextProvider = { IDELightClassContexts.contextForScript(script) },
|
||||
dummyContextProvider = { IDELightClassContexts.lightContextForScript(script) }
|
||||
)
|
||||
}
|
||||
|
||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
return runReadAction {
|
||||
KotlinFullClassNameIndex.getInstance().get(fqName.asString(), project, sourceAndClassFiles(searchScope, project))
|
||||
@@ -131,6 +136,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||
|
||||
private fun withFakeLightClasses(
|
||||
lightClassForFacade: KtLightClassForFacade?,
|
||||
facadeFiles: List<KtFile>
|
||||
@@ -155,6 +162,12 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
}
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return KotlinScriptFqnIndex.instance.get(scriptFqName.asString(), project, scope).mapNotNull {
|
||||
getLightClassForScript(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
if (fqName.isRoot) return emptyList()
|
||||
|
||||
|
||||
+35
-9
@@ -129,6 +129,21 @@ object IDELightClassContexts {
|
||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, EXACT)
|
||||
}
|
||||
|
||||
fun contextForScript(script: KtScript): LightClassConstructionContext {
|
||||
val resolutionFacade = script.getResolutionFacade()
|
||||
val bindingContext = resolutionFacade.analyze(script)
|
||||
|
||||
val descriptor = bindingContext[BindingContext.SCRIPT, script]
|
||||
if (descriptor == null) {
|
||||
LOG.warn("No script descriptor in context for script: " + script.getElementTextWithContext())
|
||||
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, EXACT)
|
||||
}
|
||||
|
||||
ForceResolveUtil.forceResolveAllContents(descriptor)
|
||||
|
||||
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, EXACT)
|
||||
}
|
||||
|
||||
fun lightContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext? {
|
||||
if (!isDummyResolveApplicable(classOrObject)) return null
|
||||
|
||||
@@ -139,6 +154,26 @@ object IDELightClassContexts {
|
||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
|
||||
}
|
||||
|
||||
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
|
||||
val representativeFile = files.first()
|
||||
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files)
|
||||
|
||||
forceResolvePackageDeclarations(files, resolveSession)
|
||||
|
||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
|
||||
}
|
||||
|
||||
fun lightContextForScript(script: KtScript): LightClassConstructionContext {
|
||||
val resolveSession = setupAdHocResolve(
|
||||
script.project,
|
||||
script.getResolutionFacade().moduleDescriptor,
|
||||
listOf(script.containingKtFile))
|
||||
|
||||
ForceResolveUtil.forceResolveAllContents(resolveSession.resolveToDescriptor(script))
|
||||
|
||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
|
||||
}
|
||||
|
||||
private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean {
|
||||
if (classOrObject.hasLightClassMatchingErrors) return false
|
||||
|
||||
@@ -193,15 +228,6 @@ object IDELightClassContexts {
|
||||
return result
|
||||
}
|
||||
|
||||
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
|
||||
val representativeFile = files.first()
|
||||
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files)
|
||||
|
||||
forceResolvePackageDeclarations(files, resolveSession)
|
||||
|
||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
|
||||
}
|
||||
|
||||
fun forceResolvePackageDeclarations(files: Collection<KtFile>, session: ResolveSession) {
|
||||
for (file in files) {
|
||||
if (file.isScript()) continue
|
||||
|
||||
+4
@@ -74,6 +74,10 @@ sealed class LazyLightClassDataHolder(
|
||||
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
|
||||
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForFacade
|
||||
|
||||
class ForScript(
|
||||
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
|
||||
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForScript
|
||||
|
||||
private inner class LazyLightClassData(
|
||||
findDelegate: (LightClassBuilderResult) -> PsiClass
|
||||
) : LightClassData {
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.Tracker.Level.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstructionContext
|
||||
@@ -53,9 +54,13 @@ import kotlin.test.assertTrue
|
||||
|
||||
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun doTest(testDataPath: String) {
|
||||
val extraFilePath = testDataPath.replace(".kt", ".extra.kt")
|
||||
val testFiles = if (File(extraFilePath).isFile) listOf(testDataPath, extraFilePath) else listOf(testDataPath)
|
||||
val extraFilePath = when {
|
||||
testDataPath.endsWith(".kt") -> testDataPath.replace(".kt", ".extra.kt")
|
||||
testDataPath.endsWith(".kts") -> testDataPath.replace(".kts", ".extra.kts")
|
||||
else -> error("Invalid test data extension")
|
||||
}
|
||||
|
||||
val testFiles = if (File(extraFilePath).isFile) listOf(testDataPath, extraFilePath) else listOf(testDataPath)
|
||||
|
||||
val lazinessMode = lazinessModeByFileText(testDataPath)
|
||||
myFixture.configureByFiles(*testFiles.toTypedArray())
|
||||
@@ -91,11 +96,13 @@ abstract class AbstractIdeCompiledLightClassTest : KotlinDaemonAnalyzerTestCase(
|
||||
val testName = getTestName(false)
|
||||
if (KotlinTestUtils.isAllFilesPresentTest(testName)) return
|
||||
|
||||
val filePath = "${KotlinTestUtils.getTestsRoot(this::class.java)}/${getTestName(false)}.kt"
|
||||
val filePathWithoutExtension = "${KotlinTestUtils.getTestsRoot(this::class.java)}/${getTestName(false)}"
|
||||
val testFile = File("$filePathWithoutExtension.kt").takeIf { it.exists() } ?:
|
||||
File("$filePathWithoutExtension.kts").takeIf { it.exists() }
|
||||
|
||||
Assert.assertTrue("File doesn't exist $filePath", File(filePath).exists())
|
||||
Assert.assertNotNull("Test file not found!", testFile)
|
||||
|
||||
val libraryJar = MockLibraryUtil.compileJvmLibraryToJar(filePath, libName())
|
||||
val libraryJar = MockLibraryUtil.compileJvmLibraryToJar(testFile!!.canonicalPath, libName())
|
||||
val jarUrl = "jar://" + FileUtilRt.toSystemIndependentName(libraryJar.absolutePath) + "!/"
|
||||
ModuleRootModificationUtil.addModuleLibrary(module, jarUrl)
|
||||
}
|
||||
@@ -128,6 +135,7 @@ private fun testLightClass(expected: File, testData: File, normalize: (String) -
|
||||
.replace("java.lang.String s1", "java.lang.String p1")
|
||||
.replace("java.lang.String s2", "java.lang.String p2")
|
||||
.replace("java.lang.Object o)", "java.lang.Object p)")
|
||||
.replace("java.lang.String[] strings", "java.lang.String[] p")
|
||||
.removeLinesStartingWith("@" + JvmAnnotationNames.METADATA_FQ_NAME.asString())
|
||||
.run(normalize)
|
||||
}
|
||||
@@ -135,6 +143,10 @@ private fun testLightClass(expected: File, testData: File, normalize: (String) -
|
||||
}
|
||||
|
||||
private fun findClass(fqName: String, ktFile: KtFile?, project: Project): PsiClass? {
|
||||
ktFile?.script?.let {
|
||||
return it.toLightClass()
|
||||
}
|
||||
|
||||
return JavaPsiFacade.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)) ?:
|
||||
PsiTreeUtil.findChildrenOfType(ktFile, KtClassOrObject::class.java)
|
||||
.find { fqName.endsWith(it.nameAsName!!.asString()) }
|
||||
|
||||
+27
-6
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true, "local", "compilationErrors", "ideRegression");
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "local", "compilationErrors", "ideRegression");
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationClass.kt")
|
||||
@@ -155,7 +155,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Delegation extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInDelegation() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Function.kt")
|
||||
@@ -176,7 +176,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Facades extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInFacades() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiFile.kt")
|
||||
@@ -203,7 +203,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NullabilityAnnotations extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Class.kt")
|
||||
@@ -320,7 +320,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Object extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInObject() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleObject.kt")
|
||||
@@ -335,7 +335,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PublicField extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInPublicField() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObject.kt")
|
||||
@@ -350,4 +350,25 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/script")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Script extends AbstractIdeCompiledLightClassTest {
|
||||
public void testAllFilesPresentInScript() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("HelloWorld.kts")
|
||||
public void testHelloWorld() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClasses.kts")
|
||||
public void testInnerClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-8
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true, "delegation");
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "delegation");
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationClass.kt")
|
||||
@@ -155,7 +155,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CompilationErrors extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInCompilationErrors() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationModifiers.kt")
|
||||
@@ -206,7 +206,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Facades extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInFacades() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("MultiFile.kt")
|
||||
@@ -233,7 +233,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IdeRegression extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInIdeRegression() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AllOpenAnnotatedClasses.kt")
|
||||
@@ -290,7 +290,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Local extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInLocal() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/local"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/local"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("DollarsInNameLocal.kt")
|
||||
@@ -305,7 +305,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NullabilityAnnotations extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Class.kt")
|
||||
@@ -422,7 +422,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Object extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInObject() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleObject.kt")
|
||||
@@ -437,7 +437,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PublicField extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInPublicField() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObject.kt")
|
||||
@@ -452,4 +452,25 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/script")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Script extends AbstractIdeLightClassTest {
|
||||
public void testAllFilesPresentInScript() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("HelloWorld.kts")
|
||||
public void testHelloWorld() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClasses.kts")
|
||||
public void testInnerClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user