[AA FIR] fix contract violation for Target annotation
^KT-57849
This commit is contained in:
committed by
Space Team
parent
d66b919c12
commit
0caaca45ae
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
|
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
|
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
|
||||||
|
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
|
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
|
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
@@ -71,14 +72,15 @@ internal fun ConeDiagnostic.getCandidateSymbols(): Collection<FirBasedSymbol<*>>
|
|||||||
internal fun FirAnnotation.toKtAnnotationApplication(
|
internal fun FirAnnotation.toKtAnnotationApplication(
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
arguments: List<KtNamedAnnotationValue> = FirAnnotationValueConverter.toNamedConstantValue(
|
||||||
|
mapAnnotationParameters(this),
|
||||||
|
useSiteSession,
|
||||||
|
)
|
||||||
): KtAnnotationApplicationWithArgumentsInfo = KtAnnotationApplicationWithArgumentsInfo(
|
): KtAnnotationApplicationWithArgumentsInfo = KtAnnotationApplicationWithArgumentsInfo(
|
||||||
classId = toAnnotationClassId(useSiteSession),
|
classId = toAnnotationClassId(useSiteSession),
|
||||||
psi = psi as? KtCallElement,
|
psi = psi as? KtCallElement,
|
||||||
useSiteTarget = useSiteTarget,
|
useSiteTarget = useSiteTarget,
|
||||||
arguments = FirAnnotationValueConverter.toNamedConstantValue(
|
arguments = arguments,
|
||||||
mapAnnotationParameters(this),
|
|
||||||
useSiteSession,
|
|
||||||
),
|
|
||||||
index = index,
|
index = index,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+77
-6
@@ -8,13 +8,18 @@ package org.jetbrains.kotlin.analysis.api.fir.annotations
|
|||||||
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
|
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
|
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
|
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
|
||||||
|
import org.jetbrains.kotlin.analysis.api.annotations.KtArrayAnnotationValue
|
||||||
|
import org.jetbrains.kotlin.analysis.api.annotations.KtEnumEntryAnnotationValue
|
||||||
|
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
|
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
|
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry
|
import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.resolved
|
import org.jetbrains.kotlin.fir.declarations.resolved
|
||||||
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
|
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
|
||||||
@@ -31,6 +36,13 @@ import org.jetbrains.kotlin.fir.symbols.resolvedCompilerRequiredAnnotations
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.fir.declarations.resolvePhase
|
import org.jetbrains.kotlin.fir.declarations.resolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.unwrapAndFlattenArgument
|
||||||
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.ParameterNames
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||||
|
|
||||||
internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirExpression> {
|
internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirExpression> {
|
||||||
if (annotation is FirAnnotationCall && annotation.arguments.isEmpty()) return emptyMap()
|
if (annotation is FirAnnotationCall && annotation.arguments.isEmpty()) return emptyMap()
|
||||||
@@ -50,13 +62,72 @@ internal fun annotationsByClassId(
|
|||||||
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
||||||
): List<KtAnnotationApplicationWithArgumentsInfo> {
|
): List<KtAnnotationApplicationWithArgumentsInfo> =
|
||||||
return annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
|
if (classId == StandardClassIds.Annotations.Target && firSymbol.fir.resolvePhase < FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) {
|
||||||
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
|
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol)
|
||||||
return@mapIndexedNotNull null
|
.mapIndexedToAnnotationApplication(useSiteTargetFilter, useSiteSession, classId) { index, annotation ->
|
||||||
}
|
annotation.asKtAnnotationApplicationForTargetAnnotation(useSiteSession, index)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
annotationContainer.resolvedAnnotationsWithArguments(firSymbol)
|
||||||
|
.mapIndexedToAnnotationApplication(useSiteTargetFilter, useSiteSession, classId) { index, annotation ->
|
||||||
|
annotation.toKtAnnotationApplication(useSiteSession, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
annotation.toKtAnnotationApplication(useSiteSession, index)
|
private inline fun List<FirAnnotation>.mapIndexedToAnnotationApplication(
|
||||||
|
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
||||||
|
useSiteSession: FirSession,
|
||||||
|
classId: ClassId,
|
||||||
|
transformer: (index: Int, annotation: FirAnnotation) -> KtAnnotationApplicationWithArgumentsInfo?,
|
||||||
|
): List<KtAnnotationApplicationWithArgumentsInfo> = mapIndexedNotNull { index, annotation ->
|
||||||
|
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
|
||||||
|
return@mapIndexedNotNull null
|
||||||
|
}
|
||||||
|
|
||||||
|
transformer(index, annotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirAnnotation.asKtAnnotationApplicationForTargetAnnotation(
|
||||||
|
useSiteSession: FirSession,
|
||||||
|
index: Int,
|
||||||
|
): KtAnnotationApplicationWithArgumentsInfo {
|
||||||
|
val arguments = findAllowedTargets().ifNotEmpty {
|
||||||
|
listOf(
|
||||||
|
KtNamedAnnotationValue(
|
||||||
|
name = StandardClassIds.Annotations.ParameterNames.targetAllowedTargets,
|
||||||
|
expression = KtArrayAnnotationValue(
|
||||||
|
values = map {
|
||||||
|
KtEnumEntryAnnotationValue(
|
||||||
|
callableId = CallableId(
|
||||||
|
classId = StandardClassIds.AnnotationTarget,
|
||||||
|
callableName = Name.identifier(it.name),
|
||||||
|
),
|
||||||
|
sourcePsi = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
sourcePsi = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}.orEmpty()
|
||||||
|
|
||||||
|
return toKtAnnotationApplication(useSiteSession, index, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirAnnotation.findAllowedTargets(): Set<KotlinTarget> = buildSet {
|
||||||
|
fun addIfMatching(arg: FirExpression) {
|
||||||
|
if (arg !is FirQualifiedAccessExpression) return
|
||||||
|
val callableSymbol = arg.calleeReference.toResolvedCallableSymbol() ?: return
|
||||||
|
if (callableSymbol.containingClassLookupTag()?.classId != StandardClassIds.AnnotationTarget) return
|
||||||
|
val identifier = callableSymbol.callableId.callableName.identifier
|
||||||
|
KotlinTarget.values().firstOrNull { identifier == it.name }?.let(::add)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this@findAllowedTargets is FirAnnotationCall) {
|
||||||
|
for (arg in argumentList.arguments) {
|
||||||
|
arg.unwrapAndFlattenArgument().forEach(::addIfMatching)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// SKIP_WHEN_OUT_OF_CONTENT_ROOT
|
||||||
|
// DISABLE_SEALED_INHERITOR_CALCULATOR
|
||||||
|
// FILE: main.kt
|
||||||
|
fun resolveMe(i: JavaInterface) = i.id
|
||||||
|
|
||||||
|
// FILE: JavaClass.java
|
||||||
|
public interface JavaInterface {
|
||||||
|
@KotlinAnnotation
|
||||||
|
default int getId() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: KotlinAnnotation.kt
|
||||||
|
@Target(
|
||||||
|
AnnotationTarget.TYPE
|
||||||
|
)
|
||||||
|
annotation class KotlinAnnotation
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] fun resolveMe([ResolvedTo(RAW_FIR)] i: JavaInterface): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] fun resolveMe([ResolvedTo(RAW_FIR)] i: JavaInterface): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] fun resolveMe([ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] i: JavaInterface): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(COMPANION_GENERATION)] fun resolveMe([ResolvedTo(COMPANION_GENERATION)] i: JavaInterface): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] fun resolveMe([ResolvedTo(SUPER_TYPES)] i: JavaInterface): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(TYPES)] fun resolveMe([ResolvedTo(TYPES)] i: R|JavaInterface|): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(STATUS)] fun resolveMe([ResolvedTo(STATUS)] i: R|JavaInterface|): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(EXPECT_ACTUAL_MATCHING)] fun resolveMe([ResolvedTo(EXPECT_ACTUAL_MATCHING)] i: R|JavaInterface|): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] fun resolveMe([ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] i: R|JavaInterface|): <implicit> { LAZY_BLOCK }
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(CONTRACTS)] fun resolveMe([ResolvedTo(CONTRACTS)] i: R|JavaInterface|): <implicit> {
|
||||||
|
^resolveMe i#.id#
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun resolveMe([ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] i: R|JavaInterface|): R|@R|KotlinAnnotation|() kotlin/Int| {
|
||||||
|
^resolveMe R|<local>/i|.R|/JavaInterface.id|
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] fun resolveMe([ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] i: R|JavaInterface|): R|@R|KotlinAnnotation|() kotlin/Int| {
|
||||||
|
^resolveMe R|<local>/i|.R|/JavaInterface.id|
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe([ResolvedTo(BODY_RESOLVE)] i: R|JavaInterface|): R|@R|KotlinAnnotation|() kotlin/Int| {
|
||||||
|
^resolveMe R|<local>/i|.R|/JavaInterface.id|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] main.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public final [ResolvedTo(BODY_RESOLVE)] fun resolveMe([ResolvedTo(BODY_RESOLVE)] i: R|JavaInterface|): R|@R|KotlinAnnotation|() kotlin/Int| {
|
||||||
|
^resolveMe R|<local>/i|.R|/JavaInterface.id|
|
||||||
|
}
|
||||||
+6
@@ -24,6 +24,12 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("annotationFromImplicitJavaType.kt")
|
||||||
|
public void testAnnotationFromImplicitJavaType() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/annotationFromImplicitJavaType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("annotationParameters.kt")
|
@TestMetadata("annotationParameters.kt")
|
||||||
public void testAnnotationParameters() throws Exception {
|
public void testAnnotationParameters() throws Exception {
|
||||||
|
|||||||
+6
@@ -24,6 +24,12 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("annotationFromImplicitJavaType.kt")
|
||||||
|
public void testAnnotationFromImplicitJavaType() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/annotationFromImplicitJavaType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("annotationParameters.kt")
|
@TestMetadata("annotationParameters.kt")
|
||||||
public void testAnnotationParameters() throws Exception {
|
public void testAnnotationParameters() throws Exception {
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
abstract class AbstractLowLevelApiSingleFileTest : AbstractAnalysisApiBasedTest() {
|
abstract class AbstractLowLevelApiSingleFileTest : AbstractAnalysisApiBasedTest() {
|
||||||
final override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
final override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||||
val singleModule = moduleStructure.modules.single()
|
val singleModule = moduleStructure.modules.single()
|
||||||
val singleFile = testServices.ktModuleProvider.getModuleFiles(singleModule).filterIsInstance<KtFile>().single()
|
val singleFile = testServices.ktModuleProvider.getModuleFiles(singleModule).filterIsInstance<KtFile>().first()
|
||||||
doTestByFileStructure(singleFile, moduleStructure, testServices)
|
doTestByFileStructure(singleFile, moduleStructure, testServices)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ private class KtOutOfContentRootModuleFactory : KtModuleFactory {
|
|||||||
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
||||||
val psiFiles = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project)
|
val psiFiles = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project)
|
||||||
val platform = testModule.targetPlatform
|
val platform = testModule.targetPlatform
|
||||||
val module = KtNotUnderContentRootModuleForTest(testModule.name, psiFiles.single(), platform)
|
val module = KtNotUnderContentRootModuleForTest(testModule.name, psiFiles.first(), platform)
|
||||||
return KtModuleWithFiles(module, psiFiles)
|
return KtModuleWithFiles(module, psiFiles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user