Fix NoSuchMethodError when try to access in test to internal member from production for gradle projects imported into IDEA 16 or higher

#KT-11993 Fixed

Original commit: ed0fa2c26c
This commit is contained in:
Zalim Bashorov
2016-04-28 22:47:42 +03:00
parent 38e2b1c91e
commit 03cb2f04fd
2 changed files with 21 additions and 8 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* 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.
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.jps.build.JpsUtils.getAllDependencies
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.alwaysNull
import java.io.File
@@ -42,7 +43,7 @@ object KotlinBuilderModuleScriptGenerator {
// TODO used reflection to be compatible with IDEA from both 143 and 144 branches,
// TODO switch to directly using when "since-build" will be >= 144.3357.4
private val getRelatedProductionModule: (JpsModule) -> JpsModule? = run {
internal val getRelatedProductionModule: (JpsModule) -> JpsModule? = run {
val klass =
try {
Class.forName("org.jetbrains.jps.model.module.JpsTestModuleProperties")
@@ -105,14 +106,15 @@ object KotlinBuilderModuleScriptGenerator {
val targetType = target.targetType
assert(targetType is JavaModuleBuildTargetType)
val targetId = TargetId(target)
builder.addModule(
target.id,
targetId.name,
outputDir.absolutePath,
moduleSources,
findSourceRoots(context, target),
findClassPathRoots(target),
(targetType as JavaModuleBuildTargetType).typeId,
targetType.isTests,
targetId.type,
(targetType as JavaModuleBuildTargetType).isTests,
// this excludes the output directories from the class path, to be removed for true incremental compilation
outputDirs,
friendDirs)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* 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.
@@ -17,6 +17,17 @@
package org.jetbrains.kotlin.modules
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.jps.build.KotlinBuilderModuleScriptGenerator.getRelatedProductionModule
fun TargetId(moduleBuildTarget: ModuleBuildTarget): TargetId =
TargetId(moduleBuildTarget.id, moduleBuildTarget.targetType.typeId)
fun TargetId(moduleBuildTarget: ModuleBuildTarget): TargetId {
// Since IDEA 2016 each gradle source root is imported as a separate module.
// One gradle module X is imported as two JPS modules:
// 1. X-production with one production target;
// 2. X-test with one test target.
// This breaks kotlin code since internal members' names are mangled using module name.
// For example, a declaration of a function 'f' in 'X-production' becomes 'fXProduction', but a call 'f' in 'X-test' becomes 'fXTest()'.
// The workaround is to replace a name of such test target with the name of corresponding production module.
// See KT-11993.
val name = getRelatedProductionModule(moduleBuildTarget.module)?.name ?: moduleBuildTarget.id
return TargetId(name, moduleBuildTarget.targetType.typeId)
}