Fix memory leak in gradle import
#KT-30076 Fixed
This commit is contained in:
+6
-9
@@ -29,10 +29,7 @@ import com.intellij.openapi.util.Key
|
|||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.tooling.model.idea.IdeaModule
|
import org.gradle.tooling.model.idea.IdeaModule
|
||||||
import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet
|
import org.jetbrains.kotlin.gradle.*
|
||||||
import org.jetbrains.kotlin.gradle.KotlinGradleModel
|
|
||||||
import org.jetbrains.kotlin.gradle.KotlinGradleModelBuilder
|
|
||||||
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel
|
|
||||||
import org.jetbrains.kotlin.idea.inspections.gradle.getDependencyModules
|
import org.jetbrains.kotlin.idea.inspections.gradle.getDependencyModules
|
||||||
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||||
import org.jetbrains.kotlin.idea.util.DataNodeUserDataProperty
|
import org.jetbrains.kotlin.idea.util.DataNodeUserDataProperty
|
||||||
@@ -203,8 +200,8 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
if (mppModel != null) {
|
if (mppModel != null) {
|
||||||
mppModel.targets.forEach { target ->
|
mppModel.targets.forEach { target ->
|
||||||
KotlinStatisticsTrigger.trigger(
|
KotlinStatisticsTrigger.trigger(
|
||||||
KotlinEventTrigger.KotlinGradleTargetTrigger,
|
KotlinEventTrigger.KotlinGradleTargetTrigger,
|
||||||
"MPP.${target.platform.id + (target.presetName?.let { ".$it"} ?: "")}"
|
"MPP.${target.platform.id + (target.presetName?.let { ".$it" } ?: "")}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return super.populateModuleDependencies(gradleModule, ideModule, ideProject)
|
return super.populateModuleDependencies(gradleModule, ideModule, ideProject)
|
||||||
@@ -222,13 +219,13 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
|
|
||||||
ideModule.isResolved = true
|
ideModule.isResolved = true
|
||||||
ideModule.hasKotlinPlugin = gradleModel.hasKotlinPlugin
|
ideModule.hasKotlinPlugin = gradleModel.hasKotlinPlugin
|
||||||
ideModule.compilerArgumentsBySourceSet = gradleModel.compilerArgumentsBySourceSet
|
ideModule.compilerArgumentsBySourceSet = gradleModel.compilerArgumentsBySourceSet.deepCopy()
|
||||||
ideModule.coroutines = gradleModel.coroutines
|
ideModule.coroutines = gradleModel.coroutines
|
||||||
ideModule.platformPluginId = gradleModel.platformPluginId
|
ideModule.platformPluginId = gradleModel.platformPluginId
|
||||||
|
|
||||||
KotlinStatisticsTrigger.trigger(
|
KotlinStatisticsTrigger.trigger(
|
||||||
KotlinEventTrigger.KotlinGradleTargetTrigger,
|
KotlinEventTrigger.KotlinGradleTargetTrigger,
|
||||||
gradleModel.kotlinTarget ?: "unknown"
|
gradleModel.kotlinTarget ?: "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
addImplementedModuleNames(gradleModule, ideModule, ideProject, gradleModel)
|
addImplementedModuleNames(gradleModule, ideModule, ideProject, gradleModel)
|
||||||
|
|||||||
+9
-7
@@ -613,7 +613,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
resolverCtx: ProjectResolverContext
|
resolverCtx: ProjectResolverContext
|
||||||
): KotlinSourceSetInfo? {
|
): KotlinSourceSetInfo? {
|
||||||
if (sourceSet.platform.isNotSupported()) return null
|
if (sourceSet.platform.isNotSupported()) return null
|
||||||
return KotlinSourceSetInfo(sourceSet).also { info ->
|
return KotlinSourceSetInfo(KotlinSourceSetImpl(sourceSet)).also { info ->
|
||||||
val languageSettings = sourceSet.languageSettings
|
val languageSettings = sourceSet.languageSettings
|
||||||
info.moduleId = getKotlinModuleId(gradleModule, sourceSet, resolverCtx)
|
info.moduleId = getKotlinModuleId(gradleModule, sourceSet, resolverCtx)
|
||||||
info.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
info.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
||||||
@@ -643,16 +643,18 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
resolverCtx: ProjectResolverContext
|
resolverCtx: ProjectResolverContext
|
||||||
): KotlinSourceSetInfo? {
|
): KotlinSourceSetInfo? {
|
||||||
if (compilation.platform.isNotSupported()) return null
|
if (compilation.platform.isNotSupported()) return null
|
||||||
return KotlinSourceSetInfo(compilation).also { sourceSetInfo ->
|
return KotlinSourceSetInfo(KotlinCompilationImpl(compilation)).also { sourceSetInfo ->
|
||||||
sourceSetInfo.moduleId = getKotlinModuleId(gradleModule, compilation, resolverCtx)
|
sourceSetInfo.moduleId = getKotlinModuleId(gradleModule, compilation, resolverCtx)
|
||||||
sourceSetInfo.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
sourceSetInfo.gradleModuleId = getModuleId(resolverCtx, gradleModule)
|
||||||
sourceSetInfo.platform = compilation.platform
|
sourceSetInfo.platform = compilation.platform
|
||||||
sourceSetInfo.isTestModule = compilation.isTestModule
|
sourceSetInfo.isTestModule = compilation.isTestModule
|
||||||
sourceSetInfo.compilerArguments = createCompilerArguments(compilation.arguments.currentArguments, compilation.platform).also {
|
sourceSetInfo.compilerArguments =
|
||||||
it.multiPlatform = true
|
createCompilerArguments(compilation.arguments.currentArguments, compilation.platform).also {
|
||||||
}
|
it.multiPlatform = true
|
||||||
|
}
|
||||||
sourceSetInfo.dependencyClasspath = compilation.dependencyClasspath
|
sourceSetInfo.dependencyClasspath = compilation.dependencyClasspath
|
||||||
sourceSetInfo.defaultCompilerArguments = createCompilerArguments(compilation.arguments.defaultArguments, compilation.platform)
|
sourceSetInfo.defaultCompilerArguments =
|
||||||
|
createCompilerArguments(compilation.arguments.defaultArguments, compilation.platform)
|
||||||
sourceSetInfo.addSourceSets(compilation.sourceSets, compilation.fullName(), gradleModule, resolverCtx)
|
sourceSetInfo.addSourceSets(compilation.sourceSets, compilation.fullName(), gradleModule, resolverCtx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -679,7 +681,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinModule.fullName(simpleName: String = name) = when (this) {
|
private fun KotlinModule.fullName(simpleName: String = name) = when (this) {
|
||||||
is KotlinCompilation -> compilationFullName(simpleName, target.disambiguationClassifier)
|
is KotlinCompilation -> compilationFullName(simpleName, disambiguationClassifier)
|
||||||
else -> simpleName
|
else -> simpleName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+71
-29
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle;
|
|||||||
import com.intellij.openapi.application.AccessToken;
|
import com.intellij.openapi.application.AccessToken;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.components.ServiceManager;
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
|
||||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||||
@@ -49,9 +50,13 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
|
||||||
// part of com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase
|
// part of com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase
|
||||||
public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
|
public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
|
||||||
|
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Module getModule(String name) {
|
protected Module getModule(String name) {
|
||||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||||
@@ -74,16 +79,26 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
doImportProject();
|
doImportProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ensureIsNotGradleProxyObject(Object o, Map<Object, Object> referencingObjects) {
|
public boolean ensureIsNotGradleProxyObject(
|
||||||
if (o instanceof Proxy) {
|
Object o,
|
||||||
StringBuilder errMessage = new StringBuilder();
|
Map<Object, Object> referencingObjects,
|
||||||
errMessage.append(String.format("Object [%s] seems to be a referenced gradle tooling api object. (it may lead to memory leaks during import) Referencing path: ", o));
|
Map<Object, String> referencingFieldNames
|
||||||
while (o != null) {
|
) {
|
||||||
errMessage.append(String.format("[%s] type: %s <-\r\n", o, o.getClass().toString()));
|
if (!(o instanceof Proxy)) {
|
||||||
o = referencingObjects.get(o);
|
return true;
|
||||||
}
|
|
||||||
//TODO fail(errMessage.toString());
|
|
||||||
}
|
}
|
||||||
|
StringBuilder errMessage = new StringBuilder();
|
||||||
|
errMessage.append(String.format(
|
||||||
|
"Object [%s] seems to be a referenced gradle tooling api object. (it may lead to memory leaks during import) Referencing path: ",
|
||||||
|
o));
|
||||||
|
while (o != null) {
|
||||||
|
errMessage.append(String.format("[%s].[%s] type: %s <-\r\n", o, referencingFieldNames.get(o), o.getClass().toString()));
|
||||||
|
o = referencingObjects.get(o);
|
||||||
|
}
|
||||||
|
System.err.println(errMessage.toString());
|
||||||
|
//TODO uncomment after fixing IDEA-207782
|
||||||
|
//fail(errMessage.toString());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldBeProcessed(Object toProcess, Set<Object> processed) {
|
private boolean shouldBeProcessed(Object toProcess, Set<Object> processed) {
|
||||||
@@ -91,56 +106,83 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void inspectForGradleMemoryLeaks(DataNode<ProjectData> externalProject) {
|
public void inspectForGradleMemoryLeaks(DataNode<ProjectData> externalProject) {
|
||||||
|
// Static logger initialisation should not be used because logger factory may be changed on test.setUp
|
||||||
|
if (logger == null) {
|
||||||
|
logger = Logger.getInstance(this.getClass().getName());
|
||||||
|
logger.setLevel(Level.INFO);//not required
|
||||||
|
}
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Set<Object> processed = new HashSet<>();
|
Set<Object> processed = new HashSet<>();
|
||||||
Queue<Object> toProcess = new LinkedList<>();
|
Queue<Object> toProcess = new LinkedList<>();
|
||||||
Map<Object, Object> referencingObjects = new HashMap<>();
|
Map<Object, Object> referencingObjects = new HashMap<>();
|
||||||
|
Map<Object, String> referencingFieldNames = new HashMap<>();
|
||||||
|
Set<Field> modifiedFields = new HashSet<>();
|
||||||
toProcess.add(externalProject);
|
toProcess.add(externalProject);
|
||||||
try {
|
try {
|
||||||
while (! toProcess.isEmpty()) {
|
while (!toProcess.isEmpty()) {
|
||||||
Object nextObject = toProcess.poll();
|
Object nextObject = toProcess.poll();
|
||||||
processed.add(nextObject);
|
processed.add(nextObject);
|
||||||
ensureIsNotGradleProxyObject(nextObject, referencingObjects);
|
if (!ensureIsNotGradleProxyObject(nextObject, referencingObjects, referencingFieldNames)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (Field field : nextObject.getClass().getDeclaredFields()) {
|
for (Field field : nextObject.getClass().getDeclaredFields()) {
|
||||||
try {
|
try {
|
||||||
final Object fieldValue;
|
|
||||||
boolean isAccessible = field.isAccessible();
|
if (!field.isAccessible()) {
|
||||||
try {
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
fieldValue = field.get(nextObject);
|
modifiedFields.add(field);
|
||||||
} finally {
|
|
||||||
field.setAccessible(isAccessible);
|
|
||||||
}
|
}
|
||||||
if (fieldValue == null) {
|
final Object fieldValue = field.get(nextObject);
|
||||||
|
if (fieldValue == null || fieldValue.getClass().isPrimitive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fieldValue instanceof Collection) {
|
if (fieldValue instanceof Collection) {
|
||||||
for (Object o : (Collection)fieldValue) {
|
for (Object o : (Collection) fieldValue) {
|
||||||
saveToProcessIfRequired(processed, toProcess, referencingObjects, nextObject, o);
|
saveToProcessIfRequired(processed, toProcess, referencingObjects, referencingFieldNames, nextObject, o,
|
||||||
|
field.getName());
|
||||||
}
|
}
|
||||||
} else if (fieldValue.getClass().isArray()) {
|
}
|
||||||
|
else if (fieldValue.getClass().isArray()) {
|
||||||
for (int i = 0; i < Array.getLength(fieldValue); i++) {
|
for (int i = 0; i < Array.getLength(fieldValue); i++) {
|
||||||
Object o = Array.get(fieldValue, i);
|
Object o = Array.get(fieldValue, i);
|
||||||
saveToProcessIfRequired(processed, toProcess, referencingObjects, nextObject, o);
|
saveToProcessIfRequired(processed, toProcess, referencingObjects, referencingFieldNames, nextObject, o,
|
||||||
|
field.getName());
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
saveToProcessIfRequired(processed, toProcess, referencingObjects, nextObject, fieldValue);
|
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
else {
|
||||||
|
saveToProcessIfRequired(processed, toProcess, referencingObjects, referencingFieldNames, nextObject, fieldValue,
|
||||||
|
field.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
System.out.println("Processed size = " + processed.size() + " Duration: " + (System.currentTimeMillis() - start));
|
finally {
|
||||||
|
for (Field f : modifiedFields) {
|
||||||
|
f.setAccessible(false);
|
||||||
|
}
|
||||||
|
logger.info(
|
||||||
|
String.format("Memory leak tracker has finished. Number of processed objects = %s. Duration = %s ms.", processed.size(),
|
||||||
|
(System.currentTimeMillis() - start)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveToProcessIfRequired(Set<Object> processed, Queue<Object> toProcess, Map<Object, Object> referrers, Object referringObject, Object o) {
|
private void saveToProcessIfRequired(
|
||||||
|
Set<Object> processed,
|
||||||
|
Queue<Object> toProcess,
|
||||||
|
Map<Object, Object> referrers,
|
||||||
|
Map<Object, String> referencingFieldNames,
|
||||||
|
Object referringObject,
|
||||||
|
Object o,
|
||||||
|
String fieldName
|
||||||
|
) {
|
||||||
if (shouldBeProcessed(o, processed)) {
|
if (shouldBeProcessed(o, processed)) {
|
||||||
toProcess.add(o);
|
toProcess.add(o);
|
||||||
|
referencingFieldNames.put(o, fieldName);
|
||||||
referrers.put(o, referringObject);
|
referrers.put(o, referringObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,14 +34,30 @@ interface ArgsInfo : Serializable {
|
|||||||
val dependencyClasspath: List<String>
|
val dependencyClasspath: List<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArgsInfoImpl(
|
data class ArgsInfoImpl(
|
||||||
override val currentArguments: List<String>,
|
override val currentArguments: List<String>,
|
||||||
override val defaultArguments: List<String>,
|
override val defaultArguments: List<String>,
|
||||||
override val dependencyClasspath: List<String>
|
override val dependencyClasspath: List<String>
|
||||||
) : ArgsInfo
|
) : ArgsInfo {
|
||||||
|
|
||||||
|
constructor(argsInfo: ArgsInfo) : this(
|
||||||
|
ArrayList(argsInfo.currentArguments),
|
||||||
|
ArrayList(argsInfo.defaultArguments),
|
||||||
|
ArrayList(argsInfo.dependencyClasspath)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
typealias CompilerArgumentsBySourceSet = Map<String, ArgsInfo>
|
typealias CompilerArgumentsBySourceSet = Map<String, ArgsInfo>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates deep copy in order to avoid holding links to Proxy objects created by gradle tooling api
|
||||||
|
*/
|
||||||
|
fun CompilerArgumentsBySourceSet.deepCopy(): CompilerArgumentsBySourceSet {
|
||||||
|
val result = HashMap<String, ArgsInfo>()
|
||||||
|
this.forEach { key, value -> result[key] = ArgsInfoImpl(value) }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
interface KotlinGradleModel : Serializable {
|
interface KotlinGradleModel : Serializable {
|
||||||
val hasKotlinPlugin: Boolean
|
val hasKotlinPlugin: Boolean
|
||||||
val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
|
val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
|
||||||
@@ -51,7 +67,7 @@ interface KotlinGradleModel : Serializable {
|
|||||||
val kotlinTarget: String?
|
val kotlinTarget: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinGradleModelImpl(
|
data class KotlinGradleModelImpl(
|
||||||
override val hasKotlinPlugin: Boolean,
|
override val hasKotlinPlugin: Boolean,
|
||||||
override val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
|
override val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
|
||||||
override val coroutines: String?,
|
override val coroutines: String?,
|
||||||
|
|||||||
@@ -6,11 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import org.jetbrains.plugins.gradle.model.ExternalDependency
|
import org.jetbrains.plugins.gradle.model.ExternalDependency
|
||||||
|
import org.jetbrains.plugins.gradle.model.ModelFactory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
typealias KotlinDependency = ExternalDependency
|
typealias KotlinDependency = ExternalDependency
|
||||||
|
|
||||||
|
fun KotlinDependency.deepCopy(): KotlinDependency = ModelFactory.createCopy(this)
|
||||||
|
|
||||||
interface KotlinModule : Serializable {
|
interface KotlinModule : Serializable {
|
||||||
val name: String
|
val name: String
|
||||||
val platform: KotlinPlatform
|
val platform: KotlinPlatform
|
||||||
@@ -55,10 +58,10 @@ interface KotlinCompilationArguments : Serializable {
|
|||||||
|
|
||||||
interface KotlinCompilation : KotlinModule {
|
interface KotlinCompilation : KotlinModule {
|
||||||
val sourceSets: Collection<KotlinSourceSet>
|
val sourceSets: Collection<KotlinSourceSet>
|
||||||
val target: KotlinTarget
|
|
||||||
val output: KotlinCompilationOutput
|
val output: KotlinCompilationOutput
|
||||||
val arguments: KotlinCompilationArguments
|
val arguments: KotlinCompilationArguments
|
||||||
val dependencyClasspath: List<String>
|
val dependencyClasspath: List<String>
|
||||||
|
val disambiguationClassifier: String?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MAIN_COMPILATION_NAME = "main"
|
const val MAIN_COMPILATION_NAME = "main"
|
||||||
|
|||||||
@@ -194,7 +194,10 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
|
|||||||
}
|
}
|
||||||
val jar = buildTargetJar(gradleTarget, project)
|
val jar = buildTargetJar(gradleTarget, project)
|
||||||
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, jar)
|
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, jar)
|
||||||
compilations.forEach { it.target = target }
|
compilations.forEach {
|
||||||
|
it.disambiguationClassifier = target.disambiguationClassifier
|
||||||
|
it.platform = target.platform
|
||||||
|
}
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,10 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
|
|||||||
}
|
}
|
||||||
val jar = buildTargetJar(gradleTarget, project)
|
val jar = buildTargetJar(gradleTarget, project)
|
||||||
val target = KotlinTargetImpl(gradleTarget.name, null, disambiguationClassifier, platform, compilations, jar)
|
val target = KotlinTargetImpl(gradleTarget.name, null, disambiguationClassifier, platform, compilations, jar)
|
||||||
compilations.forEach { it.target = target }
|
compilations.forEach {
|
||||||
|
it.disambiguationClassifier = target.disambiguationClassifier
|
||||||
|
it.platform = target.platform
|
||||||
|
}
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle
|
|||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class KotlinSourceSetImpl(
|
data class KotlinSourceSetImpl(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val languageSettings: KotlinLanguageSettings,
|
override val languageSettings: KotlinLanguageSettings,
|
||||||
override val sourceDirs: Set<File>,
|
override val sourceDirs: Set<File>,
|
||||||
@@ -15,6 +15,16 @@ class KotlinSourceSetImpl(
|
|||||||
override val dependencies: Set<KotlinDependency>,
|
override val dependencies: Set<KotlinDependency>,
|
||||||
override val dependsOnSourceSets: Set<String>
|
override val dependsOnSourceSets: Set<String>
|
||||||
) : KotlinSourceSet {
|
) : KotlinSourceSet {
|
||||||
|
|
||||||
|
constructor(kotlinSourceSet: KotlinSourceSet) : this(
|
||||||
|
kotlinSourceSet.name,
|
||||||
|
KotlinLanguageSettingsImpl(kotlinSourceSet.languageSettings),
|
||||||
|
HashSet(kotlinSourceSet.sourceDirs),
|
||||||
|
HashSet(kotlinSourceSet.resourceDirs),
|
||||||
|
kotlinSourceSet.dependencies.map { it.deepCopy() }.toSet(),
|
||||||
|
HashSet(kotlinSourceSet.dependsOnSourceSets)
|
||||||
|
)
|
||||||
|
|
||||||
override var platform: KotlinPlatform = KotlinPlatform.COMMON
|
override var platform: KotlinPlatform = KotlinPlatform.COMMON
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
@@ -24,7 +34,7 @@ class KotlinSourceSetImpl(
|
|||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinLanguageSettingsImpl(
|
data class KotlinLanguageSettingsImpl(
|
||||||
override val languageVersion: String?,
|
override val languageVersion: String?,
|
||||||
override val apiVersion: String?,
|
override val apiVersion: String?,
|
||||||
override val isProgressiveMode: Boolean,
|
override val isProgressiveMode: Boolean,
|
||||||
@@ -32,20 +42,38 @@ class KotlinLanguageSettingsImpl(
|
|||||||
override val experimentalAnnotationsInUse: Set<String>,
|
override val experimentalAnnotationsInUse: Set<String>,
|
||||||
override val compilerPluginArguments: List<String>,
|
override val compilerPluginArguments: List<String>,
|
||||||
override val compilerPluginClasspath: Set<File>
|
override val compilerPluginClasspath: Set<File>
|
||||||
) : KotlinLanguageSettings
|
) : KotlinLanguageSettings {
|
||||||
|
constructor(settings: KotlinLanguageSettings) : this(
|
||||||
|
settings.languageVersion,
|
||||||
|
settings.apiVersion,
|
||||||
|
settings.isProgressiveMode,
|
||||||
|
settings.enabledLanguageFeatures,
|
||||||
|
settings.experimentalAnnotationsInUse,
|
||||||
|
settings.compilerPluginArguments,
|
||||||
|
settings.compilerPluginClasspath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
class KotlinCompilationOutputImpl(
|
data class KotlinCompilationOutputImpl(
|
||||||
override val classesDirs: Set<File>,
|
override val classesDirs: Set<File>,
|
||||||
override val effectiveClassesDir: File?,
|
override val effectiveClassesDir: File?,
|
||||||
override val resourcesDir: File?
|
override val resourcesDir: File?
|
||||||
) : KotlinCompilationOutput
|
) : KotlinCompilationOutput {
|
||||||
|
constructor(output: KotlinCompilationOutput) : this(
|
||||||
|
HashSet(output.classesDirs),
|
||||||
|
output.effectiveClassesDir,
|
||||||
|
output.resourcesDir
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
class KotlinCompilationArgumentsImpl(
|
data class KotlinCompilationArgumentsImpl(
|
||||||
override val defaultArguments: List<String>,
|
override val defaultArguments: List<String>,
|
||||||
override val currentArguments: List<String>
|
override val currentArguments: List<String>
|
||||||
) : KotlinCompilationArguments
|
) : KotlinCompilationArguments {
|
||||||
|
constructor(arguments: KotlinCompilationArguments) : this(ArrayList(arguments.defaultArguments), ArrayList(arguments.currentArguments))
|
||||||
|
}
|
||||||
|
|
||||||
class KotlinCompilationImpl(
|
data class KotlinCompilationImpl(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val sourceSets: Collection<KotlinSourceSet>,
|
override val sourceSets: Collection<KotlinSourceSet>,
|
||||||
override val dependencies: Set<KotlinDependency>,
|
override val dependencies: Set<KotlinDependency>,
|
||||||
@@ -53,11 +81,25 @@ class KotlinCompilationImpl(
|
|||||||
override val arguments: KotlinCompilationArguments,
|
override val arguments: KotlinCompilationArguments,
|
||||||
override val dependencyClasspath: List<String>
|
override val dependencyClasspath: List<String>
|
||||||
) : KotlinCompilation {
|
) : KotlinCompilation {
|
||||||
override lateinit var target: KotlinTarget
|
|
||||||
|
// create deep copy
|
||||||
|
constructor(kotlinCompilation: KotlinCompilation) : this(
|
||||||
|
kotlinCompilation.name,
|
||||||
|
kotlinCompilation.sourceSets.map { KotlinSourceSetImpl(it) }.toList(),
|
||||||
|
kotlinCompilation.dependencies.map { it.deepCopy() }.toSet(),
|
||||||
|
KotlinCompilationOutputImpl(kotlinCompilation.output),
|
||||||
|
KotlinCompilationArgumentsImpl(kotlinCompilation.arguments),
|
||||||
|
ArrayList(kotlinCompilation.dependencyClasspath)
|
||||||
|
) {
|
||||||
|
disambiguationClassifier = kotlinCompilation.disambiguationClassifier
|
||||||
|
platform = kotlinCompilation.platform
|
||||||
|
}
|
||||||
|
|
||||||
|
override var disambiguationClassifier: String? = null
|
||||||
|
internal set
|
||||||
|
override lateinit var platform: KotlinPlatform
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
override val platform: KotlinPlatform
|
|
||||||
get() = target.platform
|
|
||||||
|
|
||||||
override val isTestModule: Boolean
|
override val isTestModule: Boolean
|
||||||
get() = name == KotlinCompilation.TEST_COMPILATION_NAME
|
get() = name == KotlinCompilation.TEST_COMPILATION_NAME
|
||||||
@@ -66,11 +108,11 @@ class KotlinCompilationImpl(
|
|||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinTargetJarImpl(
|
data class KotlinTargetJarImpl(
|
||||||
override val archiveFile: File?
|
override val archiveFile: File?
|
||||||
) : KotlinTargetJar
|
) : KotlinTargetJar
|
||||||
|
|
||||||
class KotlinTargetImpl(
|
data class KotlinTargetImpl(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val presetName: String?,
|
override val presetName: String?,
|
||||||
override val disambiguationClassifier: String?,
|
override val disambiguationClassifier: String?,
|
||||||
@@ -81,11 +123,11 @@ class KotlinTargetImpl(
|
|||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExtraFeaturesImpl(
|
data class ExtraFeaturesImpl(
|
||||||
override val coroutinesState: String?
|
override val coroutinesState: String?
|
||||||
) : ExtraFeatures
|
) : ExtraFeatures
|
||||||
|
|
||||||
class KotlinMPPGradleModelImpl(
|
data class KotlinMPPGradleModelImpl(
|
||||||
override val sourceSets: Map<String, KotlinSourceSet>,
|
override val sourceSets: Map<String, KotlinSourceSet>,
|
||||||
override val targets: Collection<KotlinTarget>,
|
override val targets: Collection<KotlinTarget>,
|
||||||
override val extraFeatures: ExtraFeatures,
|
override val extraFeatures: ExtraFeatures,
|
||||||
|
|||||||
Reference in New Issue
Block a user