From a2096ab0bec17530cd17e5b8f08e1e4f48a05e06 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 20 Aug 2015 15:35:52 +0300 Subject: [PATCH] Check supportv4 library presence on the spot --- .../kotlin/android/AndroidSubplugin.kt | 36 ++++++------------- .../synthetic/AndroidComponentRegistrar.kt | 8 ++--- .../res/CliSyntheticFileGenerator.kt | 10 ++---- .../synthetic/res/SyntheticFileGenerator.kt | 29 +++++++++------ .../resolve/android/test/CompilerTestUtils.kt | 10 +++--- .../idea/res/IDESyntheticFileGenerator.kt | 12 ++----- .../AbstractParserResultEqualityTest.kt | 2 +- .../src/KotlinAndroidJpsPlugin.kt | 20 +---------- 8 files changed, 42 insertions(+), 85 deletions(-) diff --git a/libraries/tools/kotlin-android-extensions/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt b/libraries/tools/kotlin-android-extensions/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt index 2cb9ed853e8..db773378daa 100644 --- a/libraries/tools/kotlin-android-extensions/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt +++ b/libraries/tools/kotlin-android-extensions/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt @@ -19,50 +19,34 @@ package org.jetbrains.kotlin.android import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin import org.gradle.api import com.android.build.gradle.BaseExtension -import java.io.File import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.plugin.SubpluginOption public class AndroidSubplugin : KotlinGradleSubplugin { override fun getExtraArguments(project: api.Project, task: AbstractCompile): List? { - val androidExtension = project.getExtensions().getByName("android") as? BaseExtension + val androidExtension = project.extensions.getByName("android") as? BaseExtension ?: return null - if (androidExtension == null) return null - - val sourceSets = androidExtension.getSourceSets() + val sourceSets = androidExtension.sourceSets val mainSourceSet = sourceSets.getByName("main") - val resourceDirs = mainSourceSet.getRes().getSrcDirs() - val manifestFile = mainSourceSet.getManifest().getSrcFile() - - val compileDependencies = project.getConfigurations().getByName("compile").getFiles() - val supportV4 = compileDependencies?.filter { it.name.startsWith("support-v4-") }?.isNotEmpty() ?: false - val supportV4Property = if (supportV4) "true" else "false" + val resourceDirs = mainSourceSet.res.srcDirs + val manifestFile = mainSourceSet.manifest.srcFile if (resourceDirs.isNotEmpty()) { val resourceDirOptions = resourceDirs.map { resourceDir -> - resourceDir.listFiles { it.isDirectory() && it.name.startsWith("layout") }?.forEach { task.source(it) } - SubpluginOption("androidRes", resourceDir.getAbsolutePath()) + resourceDir.listFiles { it.isDirectory && it.name.startsWith("layout") }?.forEach { task.source(it) } + SubpluginOption("androidRes", resourceDir.absolutePath) } - return listOf( - SubpluginOption("androidManifest", manifestFile.getAbsolutePath()), - SubpluginOption("supportV4", supportV4Property) - ) + resourceDirOptions + return listOf(SubpluginOption("androidManifest", manifestFile.absolutePath)) + resourceDirOptions } return null } - override fun getPluginName(): String { - return "org.jetbrains.kotlin.android" - } + override fun getPluginName() = "org.jetbrains.kotlin.android" - override fun getGroupName(): String { - return "org.jetbrains.kotlin" - } + override fun getGroupName() = "org.jetbrains.kotlin" - override fun getArtifactName(): String { - return "kotlin-android-extensions" - } + override fun getArtifactName() = "kotlin-android-extensions" } \ No newline at end of file diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt index bb73f75be9a..fd0ca0eddb4 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt @@ -38,7 +38,6 @@ import org.jetbrains.kotlin.psi.JetFile public object AndroidConfigurationKeys { public val ANDROID_RES_PATH: CompilerConfigurationKey> = CompilerConfigurationKey.create>("android resources search path") public val ANDROID_MANIFEST: CompilerConfigurationKey = CompilerConfigurationKey.create("android manifest file") - public val SUPPORT_V4: CompilerConfigurationKey = CompilerConfigurationKey.create("'true' if compiled with support-v4 library") } public class AndroidCommandLineProcessor : CommandLineProcessor { @@ -47,12 +46,11 @@ public class AndroidCommandLineProcessor : CommandLineProcessor { public val RESOURCE_PATH_OPTION: CliOption = CliOption("androidRes", "", "Android resources path", allowMultipleOccurrences = true) public val MANIFEST_FILE_OPTION: CliOption = CliOption("androidManifest", "", "Android manifest file") - public val SUPPORT_V4_OPTION: CliOption = CliOption("supportV4", "", "Support android-v4 library", required = false) } override val pluginId: String = ANDROID_COMPILER_PLUGIN_ID - override val pluginOptions: Collection = listOf(RESOURCE_PATH_OPTION, MANIFEST_FILE_OPTION, SUPPORT_V4_OPTION) + override val pluginOptions: Collection = listOf(RESOURCE_PATH_OPTION, MANIFEST_FILE_OPTION) override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) { when (option) { @@ -62,7 +60,6 @@ public class AndroidCommandLineProcessor : CommandLineProcessor { configuration.put(AndroidConfigurationKeys.ANDROID_RES_PATH, paths) } MANIFEST_FILE_OPTION -> configuration.put(AndroidConfigurationKeys.ANDROID_MANIFEST, value) - SUPPORT_V4_OPTION -> configuration.put(AndroidConfigurationKeys.SUPPORT_V4, value) else -> throw CliOptionProcessingException("Unknown option: ${option.name}") } } @@ -80,10 +77,9 @@ public class AndroidComponentRegistrar : ComponentRegistrar { public override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { val androidResPath = configuration.get(AndroidConfigurationKeys.ANDROID_RES_PATH) val androidManifest = configuration.get(AndroidConfigurationKeys.ANDROID_MANIFEST) - val supportV4 = configuration.get(AndroidConfigurationKeys.SUPPORT_V4) ?: "false" if (androidResPath != null && androidManifest != null) { - val xmlProcessor = CliSyntheticFileGenerator(project, androidManifest, androidResPath, supportV4 == "true") + val xmlProcessor = CliSyntheticFileGenerator(project, androidManifest, androidResPath) project.registerService(javaClass(), xmlProcessor) project.registerService(javaClass(), CliAndroidLayoutXmlFileManager(project, androidManifest, androidResPath)) diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/CliSyntheticFileGenerator.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/CliSyntheticFileGenerator.kt index 8e6f6531124..48a6910be57 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/CliSyntheticFileGenerator.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/CliSyntheticFileGenerator.kt @@ -30,19 +30,15 @@ import kotlin.properties.Delegates public open class CliSyntheticFileGenerator( project: Project, private val manifestPath: String, - private val resDirectories: List, - private val supportV4: Boolean + private val resDirectories: List ) : SyntheticFileGenerator(project) { private val javaPsiFacade: JavaPsiFacade by lazy { JavaPsiFacade.getInstance(project) } private val projectScope: GlobalSearchScope by lazy { GlobalSearchScope.allScope(project) } private val cachedJetFiles by lazy { - generateSyntheticJetFiles(generateSyntheticFiles(true, projectScope)) - } - - override fun supportV4(): Boolean { - return supportV4 + val supportV4 = supportV4Available(javaPsiFacade, projectScope) + generateSyntheticJetFiles(generateSyntheticFiles(true, projectScope, supportV4)) } override val layoutXmlFileManager: CliAndroidLayoutXmlFileManager by Delegates.lazy { diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/SyntheticFileGenerator.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/SyntheticFileGenerator.kt index 90131f1cd56..b41aa615f60 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/SyntheticFileGenerator.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/android/synthetic/res/SyntheticFileGenerator.kt @@ -39,12 +39,14 @@ public abstract class SyntheticFileGenerator(protected val project: Project) { public abstract val layoutXmlFileManager: AndroidLayoutXmlFileManager - protected abstract fun supportV4(): Boolean - public abstract fun getSyntheticFiles(): List - protected fun generateSyntheticFiles(generateCommonFiles: Boolean = true, scope: GlobalSearchScope): List { - val commonFiles = if (generateCommonFiles) generateCommonFiles() else listOf() + protected fun generateSyntheticFiles( + generateCommonFiles: Boolean, + scope: GlobalSearchScope, + supportV4: Boolean + ): List { + val commonFiles = if (generateCommonFiles) generateCommonFiles(supportV4) else listOf() return layoutXmlFileManager.getLayoutXmlFiles().flatMap { entry -> val files = entry.getValue() @@ -52,20 +54,22 @@ public abstract class SyntheticFileGenerator(protected val project: Project) { val layoutName = entry.getKey() - val mainLayoutFile = renderMainLayoutFile(layoutName, resources) + val mainLayoutFile = renderMainLayoutFile(layoutName, resources, supportV4) val viewLayoutFile = renderViewLayoutFile(layoutName, resources) listOf(mainLayoutFile, viewLayoutFile) }.filterNotNull() + commonFiles } - private fun generateCommonFiles(): List { + private fun generateCommonFiles(supportV4: Boolean): List { val renderSyntheticFile = renderSyntheticFile("clearCache") { writePackage(AndroidConst.SYNTHETIC_PACKAGE) writeAndroidImports() writeClearCacheFunction(AndroidConst.ACTIVITY_FQNAME) writeClearCacheFunction(AndroidConst.FRAGMENT_FQNAME) - if (supportV4()) writeClearCacheFunction(AndroidConst.SUPPORT_FRAGMENT_FQNAME) + if (supportV4) { + writeClearCacheFunction(AndroidConst.SUPPORT_FRAGMENT_FQNAME) + } } val clearCacheFile = renderSyntheticFile @@ -74,11 +78,10 @@ public abstract class SyntheticFileGenerator(protected val project: Project) { protected abstract fun extractLayoutResources(files: List, scope: GlobalSearchScope): List - private fun renderMainLayoutFile(layoutName: String, resources: List): AndroidSyntheticFile { - return renderLayoutFile(layoutName + AndroidConst.LAYOUT_POSTFIX, - escapeAndroidIdentifier(layoutName), resources) { + private fun renderMainLayoutFile(layoutName: String, resources: List, supportV4: Boolean): AndroidSyntheticFile { + return renderLayoutFile(layoutName + AndroidConst.LAYOUT_POSTFIX, escapeAndroidIdentifier(layoutName), resources) { val properties = it.mainProperties.toArrayList() - if (supportV4()) properties.addAll(it.mainPropertiesForSupportV4) + if (supportV4) properties.addAll(it.mainPropertiesForSupportV4) properties } } @@ -155,6 +158,10 @@ public abstract class SyntheticFileGenerator(protected val project: Project) { return null } + protected fun supportV4Available(javaPsiFacade: JavaPsiFacade, scope: GlobalSearchScope): Boolean { + return javaPsiFacade.findClasses(AndroidConst.SUPPORT_FRAGMENT_FQNAME, scope).isNotEmpty() + } + protected fun filterDuplicates(resources: List): List { val resourceMap = linkedMapOf() val resourcesToExclude = hashSetOf() diff --git a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/CompilerTestUtils.kt b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/CompilerTestUtils.kt index 8469347fcae..0bcf85b5d4f 100644 --- a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/CompilerTestUtils.kt +++ b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/CompilerTestUtils.kt @@ -47,9 +47,9 @@ class CliSyntheticFileGeneratorForConversionTest( project: Project, manifestPath: String, resDirectories: List, - supportV4: Boolean -) : CliSyntheticFileGenerator(project, manifestPath, resDirectories, supportV4) { - fun gen(scope: GlobalSearchScope) = generateSyntheticFiles(false, scope) + private val supportV4: Boolean +) : CliSyntheticFileGenerator(project, manifestPath, resDirectories) { + fun gen(scope: GlobalSearchScope) = generateSyntheticFiles(false, scope, supportV4) } fun UsefulTestCase.createAndroidTestEnvironment( @@ -61,7 +61,7 @@ fun UsefulTestCase.createAndroidTestEnvironment( configuration.put(AndroidConfigurationKeys.ANDROID_RES_PATH, resPaths) configuration.put(AndroidConfigurationKeys.ANDROID_MANIFEST, manifestPath) - val myEnvironment = KotlinCoreEnvironment.createForTests(getTestRootDisposable()!!, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + val myEnvironment = KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) val project = myEnvironment.project val declarationsProvider = AndroidTestExternalDeclarationsProvider(project, resPaths, manifestPath, supportV4) @@ -72,5 +72,5 @@ fun UsefulTestCase.createAndroidTestEnvironment( } fun getResPaths(path: String): List { - return File(path).listFiles { it.name.startsWith("res") && it.isDirectory() }!!.map { "$path${it.name}/" } + return File(path).listFiles { it.name.startsWith("res") && it.isDirectory }!!.map { "$path${it.name}/" } } \ No newline at end of file diff --git a/plugins/android-idea-plugin/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDESyntheticFileGenerator.kt b/plugins/android-idea-plugin/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDESyntheticFileGenerator.kt index ce87c4464ac..46ed94d2854 100644 --- a/plugins/android-idea-plugin/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDESyntheticFileGenerator.kt +++ b/plugins/android-idea-plugin/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDESyntheticFileGenerator.kt @@ -23,7 +23,6 @@ import com.intellij.psi.impl.PsiTreeChangePreprocessor import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider.Result -import org.jetbrains.kotlin.android.synthetic.AndroidConst import org.jetbrains.kotlin.android.synthetic.idea.AndroidPsiTreeChangePreprocessor import org.jetbrains.kotlin.android.synthetic.idea.AndroidXmlVisitor import org.jetbrains.kotlin.android.synthetic.parseAndroidResource @@ -33,23 +32,16 @@ import org.jetbrains.kotlin.psi.JetFile class IDESyntheticFileGenerator(val module: Module) : SyntheticFileGenerator(module.project) { - private val supportV4: Boolean - private val javaPsiFacade: JavaPsiFacade by lazy { JavaPsiFacade.getInstance(module.project) } private val moduleScope: GlobalSearchScope by lazy { module.getModuleWithDependenciesAndLibrariesScope(false) } private val cachedJetFiles: CachedValue> by lazy { cachedValue { - Result.create(generateSyntheticJetFiles(generateSyntheticFiles(true, moduleScope)), psiTreeChangePreprocessor) + val supportV4 = supportV4Available(javaPsiFacade, moduleScope) + Result.create(generateSyntheticJetFiles(generateSyntheticFiles(true, moduleScope, supportV4)), psiTreeChangePreprocessor) } } - init { - supportV4 = javaPsiFacade.findClasses(AndroidConst.SUPPORT_FRAGMENT_FQNAME, moduleScope).isNotEmpty() - } - - override fun supportV4() = supportV4 - override val layoutXmlFileManager: IDEAndroidLayoutXmlFileManager = IDEAndroidLayoutXmlFileManager(module) private val psiTreeChangePreprocessor by lazy { diff --git a/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AbstractParserResultEqualityTest.kt b/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AbstractParserResultEqualityTest.kt index 4fdd161d83a..b951c753635 100644 --- a/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AbstractParserResultEqualityTest.kt +++ b/plugins/android-idea-plugin/tests/org/jetbrains/kotlin/android/AbstractParserResultEqualityTest.kt @@ -31,7 +31,7 @@ public abstract class AbstractParserResultEqualityTest : KotlinAndroidTestCase() "$path${it.name}/" } - val cliParser = CliSyntheticFileGenerator(project, "$path../AndroidManifest.xml", resDirs, false) + val cliParser = CliSyntheticFileGenerator(project, "$path../AndroidManifest.xml", resDirs) val ideParser = IDESyntheticFileGenerator(ModuleManager.getInstance(project).getModules()[0]) val cliResult = cliParser.getSyntheticFiles().joinToString("\n\n") diff --git a/plugins/android-jps-plugin/src/KotlinAndroidJpsPlugin.kt b/plugins/android-jps-plugin/src/KotlinAndroidJpsPlugin.kt index a4ec2391754..0bd08c62912 100644 --- a/plugins/android-jps-plugin/src/KotlinAndroidJpsPlugin.kt +++ b/plugins/android-jps-plugin/src/KotlinAndroidJpsPlugin.kt @@ -23,9 +23,6 @@ import org.jetbrains.jps.model.module.JpsModule import java.io.File import org.jetbrains.jps.android.AndroidJpsUtil import com.intellij.util.PathUtil -import org.jetbrains.jps.model.library.JpsOrderRootType -import org.jetbrains.jps.model.module.JpsLibraryDependency -import org.jetbrains.jps.model.module.JpsModuleDependency public class KotlinAndroidJpsPlugin : KotlinJpsCompilerArgumentsProvider { override fun getExtraArguments(moduleBuildTarget: ModuleBuildTarget, context: CompileContext): List { @@ -33,27 +30,13 @@ public class KotlinAndroidJpsPlugin : KotlinJpsCompilerArgumentsProvider { val pluginId = ANDROID_COMPILER_PLUGIN_ID val resPath = getAndroidResPath(module) val manifestFile = getAndroidManifest(module) - val supportV4 = if (isSupportV4LibraryAttached(module)) "true" else "false" return if (resPath != null && manifestFile != null) listOf( getPluginOptionString(pluginId, RESOURCE_PATH_OPTION_NAME, resPath), - getPluginOptionString(pluginId, MANIFEST_FILE_OPTION_NAME, manifestFile), - getPluginOptionString(pluginId, SUPPORT_V4_OPTION_NAME, supportV4)) + getPluginOptionString(pluginId, MANIFEST_FILE_OPTION_NAME, manifestFile)) else listOf() } - private fun isSupportV4LibraryAttached(module: JpsModule): Boolean { - return module.getDependenciesList().getDependencies().any { dep -> - when (dep) { - is JpsLibraryDependency -> - dep.getLibrary()?.getFiles(JpsOrderRootType.COMPILED)?.any { - it.name.startsWith("support-v4") && it.extension.toUpperCase() == "JAR" - } ?: false - else -> false - } - } - } - override fun getClasspath(moduleBuildTarget: ModuleBuildTarget, context: CompileContext): List { val inJar = File(PathUtil.getJarPathForClass(javaClass)).isFile() val manifestFile = getAndroidManifest(moduleBuildTarget.getModule()) @@ -88,7 +71,6 @@ public class KotlinAndroidJpsPlugin : KotlinJpsCompilerArgumentsProvider { private val RESOURCE_PATH_OPTION_NAME = "androidRes" private val MANIFEST_FILE_OPTION_NAME = "androidManifest" - private val SUPPORT_V4_OPTION_NAME = "supportV4" private fun getPluginOptionString(pluginId: String, key: String, value: String): String { return "plugin:$pluginId:$key=$value"