From 376886a9c3ae8a83afcabe139561a70f3a1a392a Mon Sep 17 00:00:00 2001 From: Mikhail Mutcianko Date: Wed, 13 Aug 2014 17:54:53 +0400 Subject: [PATCH] add configuration key to pass android manifest file --- .../arguments/K2JVMCompilerArguments.java | 4 ++ .../kotlin/cli/jvm/JVMConfigurationKeys.java | 3 + .../kotlin/cli/jvm/K2JVMCompiler.java | 4 ++ .../cli/jvm/compiler/JetCoreEnvironment.java | 5 +- .../android/AndroidResourceManagerBase.kt | 38 +----------- .../resolve/android/AndroidUIXmlProcessor.kt | 3 +- .../android/CliAndroidResourceManager.kt | 58 +++++++++++++++++++ .../android/CliAndroidUIXmlProcessor.kt | 4 +- .../lang/resolve/android/AndroidXmlTest.java | 13 +++-- 9 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidResourceManager.kt diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java index 5f74aa80938..8b5654fe674 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java @@ -70,6 +70,10 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments { @ValueDescription("") public String androidRes; + @Argument(value = "androidManifest", description = "Android manifest file") + @ValueDescription("") + public String androidManifest; + @Override @NotNull public String executableScriptFileName() { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/JVMConfigurationKeys.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/JVMConfigurationKeys.java index 5c9bdc0ccc5..2bf8b65f7a3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/JVMConfigurationKeys.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/JVMConfigurationKeys.java @@ -54,4 +54,7 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey ANDROID_RES_PATH = CompilerConfigurationKey.create("android resources search path"); + + public static final CompilerConfigurationKey ANDROID_MANIFEST = + CompilerConfigurationKey.create("android manifest file"); } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java index a9a299207bf..6ca4fcd69ff 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java @@ -94,6 +94,10 @@ public class K2JVMCompiler extends CLICompiler { configuration.put(JVMConfigurationKeys.ANDROID_RES_PATH, arguments.androidRes); } + if (arguments.androidManifest != null) { + configuration.put(JVMConfigurationKeys.ANDROID_MANIFEST, arguments.androidManifest); + } + if (arguments.script) { if (arguments.freeArgs.isEmpty()) { messageCollector.report(CompilerMessageSeverity.ERROR, "Specify script source path to evaluate", diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java index 3bc28a6dfc5..e10bba89c98 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java @@ -295,8 +295,9 @@ public class JetCoreEnvironment { configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY) ); - String s = configuration.get(JVMConfigurationKeys.ANDROID_RES_PATH); - project.registerService(AndroidUIXmlProcessor.class, new CliAndroidUIXmlProcessor(project, s)); + String androidResPath = configuration.get(JVMConfigurationKeys.ANDROID_RES_PATH); + String androidManifest = configuration.get(JVMConfigurationKeys.ANDROID_MANIFEST); + project.registerService(AndroidUIXmlProcessor.class, new CliAndroidUIXmlProcessor(project, androidResPath, androidManifest)); project.registerService(VirtualFileFinderFactory.class, new CliVirtualFileFinderFactory(classPath)); } diff --git a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidResourceManagerBase.kt b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidResourceManagerBase.kt index a218d822468..3caac163b65 100644 --- a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidResourceManagerBase.kt +++ b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidResourceManagerBase.kt @@ -21,17 +21,10 @@ import com.intellij.psi.PsiFile import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiManager -import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor.NoAndroidManifestFound import java.util.ArrayList -import java.io.File -import java.io.FileInputStream -import javax.xml.parsers.SAXParser -import javax.xml.parsers.SAXParserFactory -import org.xml.sax.helpers.DefaultHandler -import org.xml.sax.Attributes import com.intellij.openapi.vfs.VirtualFile -open class AndroidResourceManagerBase(project: Project, searchPath: String?) : AndroidResourceManager(project, searchPath) { +abstract class AndroidResourceManagerBase(project: Project, searchPath: String?) : AndroidResourceManager(project, searchPath) { override fun getLayoutXmlFiles(): Collection { val fileManager = VirtualFileManager.getInstance() val watchDir = fileManager.findFileByUrl("file://" + searchPath) @@ -55,33 +48,4 @@ open class AndroidResourceManagerBase(project: Project, searchPath: String?) : A override fun renameProperty(oldName: String, newName: String) { } - val saxParser: SAXParser = initSAX() - - protected fun initSAX(): SAXParser { - val saxFactory = SAXParserFactory.newInstance() - saxFactory?.setNamespaceAware(true) - return saxFactory!!.newSAXParser() - } - - override fun readManifest(): AndroidManifest { - try { - val manifestXml = File(searchPath!!).getParentFile()!!.getParentFile()!!.listFiles { it.name == "AndroidManifest.xml" }!!.first() - var _package: String = "" - try { - saxParser.parse(FileInputStream(manifestXml), object : DefaultHandler() { - override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) { - if (localName == "manifest") - _package = attributes.toMap()["package"] ?: "" - } - }) - } - catch (e: Exception) { - throw e - } - return AndroidManifest(_package) - } - catch (e: Exception) { - throw NoAndroidManifestFound() - } - } } diff --git a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUIXmlProcessor.kt b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUIXmlProcessor.kt index c106841b305..ed1b2db8bee 100644 --- a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUIXmlProcessor.kt +++ b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/AndroidUIXmlProcessor.kt @@ -73,12 +73,13 @@ abstract class AndroidUIXmlProcessor(val project: Project) { protected val LOG: Logger = Logger.getInstance(this.javaClass) public fun parseToString(): String? { + populateQueue() val cacheState = doParse() if (cacheState == null) return null return renderString() } - public open val resourceManager: AndroidResourceManager = AndroidResourceManagerBase(project, searchPath) + public abstract val resourceManager: AndroidResourceManager public fun parseToPsi(project: Project): JetFile? { populateQueue() diff --git a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidResourceManager.kt b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidResourceManager.kt new file mode 100644 index 00000000000..c6da0393573 --- /dev/null +++ b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidResourceManager.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2014 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.jet.lang.resolve.android + +import com.intellij.openapi.project.Project +import java.io.File +import java.io.FileInputStream +import org.xml.sax.helpers.DefaultHandler +import org.xml.sax.Attributes +import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor.NoAndroidManifestFound +import javax.xml.parsers.SAXParser +import javax.xml.parsers.SAXParserFactory + +public class CliAndroidResourceManager(project: Project, searchPath: String?, val manifestPath: String?) : AndroidResourceManagerBase(project, searchPath) { + + val saxParser: SAXParser = initSAX() + + protected fun initSAX(): SAXParser { + val saxFactory = SAXParserFactory.newInstance() + saxFactory?.setNamespaceAware(true) + return saxFactory!!.newSAXParser() + } + override fun readManifest(): AndroidManifest { + try { + val manifestXml = File(manifestPath!!) + var _package: String = "" + try { + saxParser.parse(FileInputStream(manifestXml), object : DefaultHandler() { + override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) { + if (localName == "manifest") + _package = attributes.toMap()["package"] ?: "" + } + }) + } + catch (e: Exception) { + throw e + } + return AndroidManifest(_package) + } + catch (e: Exception) { + throw NoAndroidManifestFound() + } + } +} diff --git a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidUIXmlProcessor.kt b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidUIXmlProcessor.kt index 82f85e36d8d..c4b1a89da7d 100644 --- a/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidUIXmlProcessor.kt +++ b/compiler/frontend.android/src/org/jetbrains/jet/lang/resolve/android/CliAndroidUIXmlProcessor.kt @@ -20,11 +20,11 @@ import java.util.ArrayList import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile -class CliAndroidUIXmlProcessor(project: Project, override val searchPath: String?) : AndroidUIXmlProcessor(project) { +class CliAndroidUIXmlProcessor(project: Project, override val searchPath: String?, val manifestPath: String?) : AndroidUIXmlProcessor(project) { override var androidAppPackage: String = "" - override val resourceManager: AndroidResourceManagerBase = AndroidResourceManagerBase(project, searchPath) + override val resourceManager = CliAndroidResourceManager(project, searchPath, manifestPath) override fun lazySetup() { populateQueue() diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/android/AndroidXmlTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/android/AndroidXmlTest.java index 2253f6dd09e..bca280f22d2 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/android/AndroidXmlTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/android/AndroidXmlTest.java @@ -36,12 +36,14 @@ import java.util.*; public class AndroidXmlTest extends TestCaseWithTmpdir { - private final File singleFileDir = new File(getTestDataPath() + "/converter/singleFile/res/layout/"); + private static final String singleFilePrefix = getTestDataPath() + "/converter/singleFile/"; + public static final String singleFileManifestPath = singleFilePrefix + "AndroidManifest.xml"; + private final File singleFileDir = new File(singleFilePrefix + "res/layout/"); private final File fakeActivitySrc = new File(getTestDataPath() + "/fakeHelpers/Activity.kt"); private final File fakeViewSrc = new File(getTestDataPath() + "/fakeHelpers/View.kt"); private final File fakeWidgetsSrc = new File(getTestDataPath() + "/fakeHelpers/Widgets.kt"); - private final File fakeMyActivitySrc = new File(getTestDataPath() + "/converter/singleFile/MyActivity.kt"); - private final String singleFileResPath = getTestDataPath() + "/converter/singleFile/res/layout/"; + private final File fakeMyActivitySrc = new File(singleFilePrefix + "MyActivity.kt"); + private final String singleFileResPath = singleFilePrefix + "res/layout/"; @Override public void setUp() throws Exception { @@ -83,6 +85,7 @@ public class AndroidXmlTest extends TestCaseWithTmpdir { CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK); configuration.put(JVMConfigurationKeys.ANDROID_RES_PATH, resPath); + configuration.put(JVMConfigurationKeys.ANDROID_MANIFEST, singleFileManifestPath); return JetCoreEnvironment.createForTests(getTestRootDisposable(), configuration); } @@ -106,7 +109,9 @@ public class AndroidXmlTest extends TestCaseWithTmpdir { public void testConverterOneFile() throws Exception { JetCoreEnvironment jetCoreEnvironment = getEnvironment(singleFileResPath); - AndroidUIXmlProcessor parser = new CliAndroidUIXmlProcessor(jetCoreEnvironment.getProject(), singleFileDir.getAbsolutePath()); + AndroidUIXmlProcessor parser = new CliAndroidUIXmlProcessor(jetCoreEnvironment.getProject(), + singleFileDir.getAbsolutePath(), + singleFileManifestPath); String actual = parser.parseToString(); String expected = loadOrCreate(new File(getTestDataPath() + "/converter/singleFile/layout.kt"), actual);