Kapt3: Add simple AP test with Kotlin
This commit is contained in:
committed by
Yan Zhulanow
parent
5b780ec56c
commit
64046f1e40
@@ -137,6 +137,7 @@ import org.jetbrains.kotlin.jvm.compiler.*
|
|||||||
import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest
|
import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest
|
||||||
import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest
|
import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest
|
||||||
import org.jetbrains.kotlin.kapt3.test.AbstractJCTreeConverterTest
|
import org.jetbrains.kotlin.kapt3.test.AbstractJCTreeConverterTest
|
||||||
|
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptRunnerTest
|
||||||
import org.jetbrains.kotlin.kdoc.AbstractKDocLexerTest
|
import org.jetbrains.kotlin.kdoc.AbstractKDocLexerTest
|
||||||
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBoxTest
|
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBoxTest
|
||||||
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBytecodeShapeTest
|
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBytecodeShapeTest
|
||||||
@@ -1142,6 +1143,10 @@ fun main(args: Array<String>) {
|
|||||||
testClass<AbstractJCTreeConverterTest> {
|
testClass<AbstractJCTreeConverterTest> {
|
||||||
model("converter")
|
model("converter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractKotlinKaptRunnerTest> {
|
||||||
|
model("kotlinRunner")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
|
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.sun.tools.javac.main.Option
|
|||||||
import com.sun.tools.javac.processing.AnnotationProcessingError
|
import com.sun.tools.javac.processing.AnnotationProcessingError
|
||||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment
|
import com.sun.tools.javac.processing.JavacProcessingEnvironment
|
||||||
import com.sun.tools.javac.tree.JCTree
|
import com.sun.tools.javac.tree.JCTree
|
||||||
|
import com.sun.tools.javac.tree.TreeMaker
|
||||||
import com.sun.tools.javac.util.Context
|
import com.sun.tools.javac.util.Context
|
||||||
import com.sun.tools.javac.util.Options
|
import com.sun.tools.javac.util.Options
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -51,6 +52,7 @@ class KaptError : RuntimeException {
|
|||||||
class KaptRunner {
|
class KaptRunner {
|
||||||
val context = Context()
|
val context = Context()
|
||||||
val compiler: KaptJavaCompiler
|
val compiler: KaptJavaCompiler
|
||||||
|
val fileManager: JavacFileManager
|
||||||
private val options: Options
|
private val options: Options
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -58,11 +60,17 @@ class KaptRunner {
|
|||||||
KaptTreeMaker.preRegister(context)
|
KaptTreeMaker.preRegister(context)
|
||||||
KaptJavaCompiler.preRegister(context)
|
KaptJavaCompiler.preRegister(context)
|
||||||
|
|
||||||
|
fileManager = context.get(JavaFileManager::class.java) as JavacFileManager
|
||||||
compiler = JavaCompiler.instance(context) as KaptJavaCompiler
|
compiler = JavaCompiler.instance(context) as KaptJavaCompiler
|
||||||
|
|
||||||
options = Options.instance(context)
|
options = Options.instance(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun close() {
|
||||||
|
compiler.close()
|
||||||
|
fileManager.close()
|
||||||
|
}
|
||||||
|
|
||||||
fun parseJavaFiles(
|
fun parseJavaFiles(
|
||||||
javaSourceFiles: List<File>,
|
javaSourceFiles: List<File>,
|
||||||
classpath: List<File>
|
classpath: List<File>
|
||||||
@@ -85,7 +93,8 @@ class KaptRunner {
|
|||||||
processors: List<Processor>,
|
processors: List<Processor>,
|
||||||
classpath: List<File>,
|
classpath: List<File>,
|
||||||
sourceOutputDir: File,
|
sourceOutputDir: File,
|
||||||
classOutputDir: File
|
classOutputDir: File,
|
||||||
|
additionalSources: JavacList<JCTree.JCCompilationUnit> = JavacList.nil()
|
||||||
) {
|
) {
|
||||||
options.put(Option.PROC, "only") // Only process annotations
|
options.put(Option.PROC, "only") // Only process annotations
|
||||||
classpath.forEach { options.put(Option.CLASSPATH, it.canonicalPath) }
|
classpath.forEach { options.put(Option.CLASSPATH, it.canonicalPath) }
|
||||||
@@ -106,7 +115,7 @@ class KaptRunner {
|
|||||||
|
|
||||||
val compilerAfterAnnotationProcessing: JavaCompiler? = null
|
val compilerAfterAnnotationProcessing: JavaCompiler? = null
|
||||||
try {
|
try {
|
||||||
compiler.processAnnotations(compiler.enterTrees(parsedJavaFiles))
|
compiler.processAnnotations(compiler.enterTrees(parsedJavaFiles + additionalSources))
|
||||||
} catch (e: AnnotationProcessingError) {
|
} catch (e: AnnotationProcessingError) {
|
||||||
throw KaptError(KaptError.Kind.EXCEPTION, e.cause ?: e)
|
throw KaptError(KaptError.Kind.EXCEPTION, e.cause ?: e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,20 @@ class SyntheticJavaFileObject(
|
|||||||
|
|
||||||
override fun inferBinaryName(path: MutableIterable<File>?) = throw UnsupportedOperationException()
|
override fun inferBinaryName(path: MutableIterable<File>?) = throw UnsupportedOperationException()
|
||||||
|
|
||||||
override fun isNameCompatible(simpleName: String?, kind: JavaFileObject.Kind?) = true
|
override fun isNameCompatible(simpleName: String?, kind: JavaFileObject.Kind?): Boolean {
|
||||||
|
if (simpleName == null || kind == null) return false
|
||||||
|
return this.kind == kind && simpleName == clazz.simpleName.toString()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getKind() = JavaFileObject.Kind.SOURCE
|
override fun getKind() = JavaFileObject.Kind.SOURCE
|
||||||
|
|
||||||
override fun getName() = compilationUnit.packageName.toString().replace('.', '/') + clazz.name + ".java"
|
override fun getName(): String {
|
||||||
|
val packageName = compilationUnit.packageName
|
||||||
|
if (packageName == null || packageName.toString() == "") {
|
||||||
|
return clazz.name.toString() + ".java"
|
||||||
|
}
|
||||||
|
return packageName.toString().replace('.', '/') + '/' + clazz.simpleName.toString() + ".java"
|
||||||
|
}
|
||||||
|
|
||||||
override fun getAccessLevel(): Modifier? {
|
override fun getAccessLevel(): Modifier? {
|
||||||
val flags = clazz.modifiers.getFlags()
|
val flags = clazz.modifiers.getFlags()
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 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.kapt3.test
|
|
||||||
|
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
|
||||||
import com.sun.tools.javac.comp.CompileStates
|
|
||||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
|
||||||
import org.jetbrains.kotlin.codegen.CodegenTestUtil
|
|
||||||
import org.jetbrains.kotlin.kapt3.JCTreeConverter
|
|
||||||
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
|
|
||||||
import org.jetbrains.kotlin.kapt3.KaptRunner
|
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
|
||||||
import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
abstract class AbstractJCTreeConverterTest : CodegenTestCase() {
|
|
||||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
|
||||||
val javaSources = javaFilesDir?.let { arrayOf(it) } ?: emptyArray()
|
|
||||||
|
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
|
||||||
loadMultiFiles(files)
|
|
||||||
|
|
||||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
|
||||||
val classBuilderFactory = Kapt3BuilderFactory()
|
|
||||||
val factory = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
|
||||||
val typeMapper = factory.generationState.typeMapper
|
|
||||||
|
|
||||||
val kaptRunner = KaptRunner()
|
|
||||||
try {
|
|
||||||
val converter = JCTreeConverter(kaptRunner.context, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
|
||||||
val javaFiles = converter.convert()
|
|
||||||
|
|
||||||
kaptRunner.compiler.enterTrees(javaFiles)
|
|
||||||
|
|
||||||
val actualRaw = javaFiles.joinToString ("\n\n////////////////////\n\n")
|
|
||||||
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
|
||||||
|
|
||||||
if (kaptRunner.compiler.shouldStop(CompileStates.CompileState.ENTER)) {
|
|
||||||
error("There were errors during analysis. See errors above. Stubs:\n\n$actual")
|
|
||||||
}
|
|
||||||
|
|
||||||
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
|
||||||
} finally {
|
|
||||||
kaptRunner.compiler.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 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.kapt3.test
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import com.sun.tools.javac.comp.CompileStates
|
||||||
|
import com.sun.tools.javac.tree.JCTree
|
||||||
|
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||||
|
import org.jetbrains.kotlin.codegen.CodegenTestUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
|
import org.jetbrains.kotlin.kapt3.JCTreeConverter
|
||||||
|
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
|
||||||
|
import org.jetbrains.kotlin.kapt3.KaptRunner
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
||||||
|
import com.sun.tools.javac.util.List as JavacList
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
|
||||||
|
protected companion object {
|
||||||
|
val FILE_SEPARATOR = "\n\n////////////////////\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||||
|
val javaSources = javaFilesDir?.let { arrayOf(it) } ?: emptyArray()
|
||||||
|
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
||||||
|
loadMultiFiles(files)
|
||||||
|
|
||||||
|
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||||
|
val classBuilderFactory = Kapt3BuilderFactory()
|
||||||
|
val factory = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||||
|
val typeMapper = factory.generationState.typeMapper
|
||||||
|
|
||||||
|
val kaptRunner = KaptRunner()
|
||||||
|
try {
|
||||||
|
check(kaptRunner, typeMapper, classBuilderFactory, txtFile)
|
||||||
|
} finally {
|
||||||
|
kaptRunner.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun convert(
|
||||||
|
kaptRunner: KaptRunner,
|
||||||
|
typeMapper: KotlinTypeMapper,
|
||||||
|
compiledClasses: List<ClassNode>,
|
||||||
|
origins: Map<Any, JvmDeclarationOrigin>
|
||||||
|
): JavacList<JCTree.JCCompilationUnit> {
|
||||||
|
val converter = JCTreeConverter(kaptRunner.context, typeMapper, compiledClasses, origins)
|
||||||
|
return converter.convert()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun check(
|
||||||
|
kaptRunner: KaptRunner,
|
||||||
|
typeMapper: KotlinTypeMapper,
|
||||||
|
classBuilderFactory: Kapt3BuilderFactory,
|
||||||
|
txtFile: File)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractJCTreeConverterTest : AbstractKotlinKapt3Test() {
|
||||||
|
override fun check(kaptRunner: KaptRunner, typeMapper: KotlinTypeMapper, classBuilderFactory: Kapt3BuilderFactory, txtFile: File) {
|
||||||
|
val javaFiles = convert(kaptRunner, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||||
|
kaptRunner.compiler.enterTrees(javaFiles)
|
||||||
|
|
||||||
|
val actualRaw = javaFiles.joinToString (FILE_SEPARATOR)
|
||||||
|
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||||
|
|
||||||
|
if (kaptRunner.compiler.shouldStop(CompileStates.CompileState.ENTER)) {
|
||||||
|
error("There were errors during analysis. See errors above. Stubs:\n\n$actual")
|
||||||
|
}
|
||||||
|
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractKotlinKaptRunnerTest : AbstractKotlinKapt3Test() {
|
||||||
|
override fun check(kaptRunner: KaptRunner, typeMapper: KotlinTypeMapper, classBuilderFactory: Kapt3BuilderFactory, txtFile: File) {
|
||||||
|
val compilationUnits = convert(kaptRunner, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||||
|
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
|
||||||
|
try {
|
||||||
|
kaptRunner.doAnnotationProcessing(emptyList(), listOf(KaptRunnerTest.SIMPLE_PROCESSOR),
|
||||||
|
classpath = listOf(), sourceOutputDir = sourceOutputDir, classOutputDir = sourceOutputDir,
|
||||||
|
additionalSources = compilationUnits)
|
||||||
|
|
||||||
|
val javaFiles = sourceOutputDir.walkTopDown().filter { it.isFile && it.extension == "java" }
|
||||||
|
val actualRaw = javaFiles.sortedBy { it.name }.joinToString(FILE_SEPARATOR) { it.name + ":\n\n" + it.readText() }
|
||||||
|
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })).trimTrailingWhitespacesAndAddNewlineAtEOF()
|
||||||
|
KotlinTestUtils.assertEqualsToFile(txtFile, actual)
|
||||||
|
} finally {
|
||||||
|
sourceOutputDir.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,8 +43,8 @@ import javax.lang.model.element.TypeElement
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class KaptRunnerTest {
|
class KaptRunnerTest {
|
||||||
private companion object {
|
companion object {
|
||||||
val TEST_DATA_DIR = File("plugins/kapt3/testData/runner")
|
private val TEST_DATA_DIR = File("plugins/kapt3/testData/runner")
|
||||||
|
|
||||||
val SIMPLE_PROCESSOR = object : AbstractProcessor() {
|
val SIMPLE_PROCESSOR = object : AbstractProcessor() {
|
||||||
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
|
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 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.kapt3.test;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("plugins/kapt3/testData/kotlinRunner")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class KotlinKaptRunnerTestGenerated extends AbstractKotlinKaptRunnerTest {
|
||||||
|
public void testAllFilesPresentInKotlinRunner() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/testData/kotlinRunner"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/kotlinRunner/Simple.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal class Simple {
|
||||||
|
@MyAnnotation
|
||||||
|
fun myMethod() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal annotation class MyAnnotation
|
||||||
|
|
||||||
|
internal enum class EnumClass {
|
||||||
|
BLACK, WHITE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal enum class EnumClass2 private constructor(private val blah: String) {
|
||||||
|
WHITE("A"), RED("B")
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
MyMethodMyAnnotation.java:
|
||||||
|
|
||||||
|
package generated;
|
||||||
|
class MyMethodMyAnnotation {}
|
||||||
@@ -36,5 +36,6 @@
|
|||||||
<orderEntry type="module" module-name="annotation-processing" scope="TEST" />
|
<orderEntry type="module" module-name="annotation-processing" scope="TEST" />
|
||||||
<orderEntry type="module" module-name="build-common" scope="TEST" />
|
<orderEntry type="module" module-name="build-common" scope="TEST" />
|
||||||
<orderEntry type="module" module-name="jps-tests" scope="TEST" />
|
<orderEntry type="module" module-name="jps-tests" scope="TEST" />
|
||||||
|
<orderEntry type="module" module-name="kapt3" scope="TEST" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
Reference in New Issue
Block a user