add android manifest support

This commit is contained in:
Mikhail Mutcianko
2014-07-23 18:45:58 +04:00
committed by Yan Zhulanow
parent a4fb49c3dd
commit 7536170e1d
4 changed files with 45 additions and 1 deletions
@@ -15,17 +15,30 @@ import com.intellij.openapi.vfs.VirtualFileAdapter
import com.intellij.openapi.vfs.VirtualFileEvent
import com.intellij.openapi.project.Project
import java.util.concurrent.ConcurrentLinkedQueue
import com.intellij.openapi.util.Key
import com.intellij.testFramework.LightVirtualFile
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.psi.PsiManager
import java.io.FileInputStream
import org.xml.sax.helpers.DefaultHandler
import org.xml.sax.Attributes
import org.jetbrains.kotlin.resolve.android.AndroidConst.*
import com.intellij.psi.PsiFileFactory
abstract class AndroidUIXmlParser {
inner class NoUIXMLsFound: Exception("No android UI xmls found in $searchPath")
class NoAndroidManifestFound: Exception("No android manifest file found in project root")
class ManifestParsingFailed
enum class CacheAction { HIT; MISS }
val androidImports = arrayListOf("android.app.Activity",
"android.view.View",
"android.widget.*")
abstract val searchPath: String?
abstract val androidAppPackage: String
val saxParser = initSAX()
@@ -48,7 +61,10 @@ abstract class AndroidUIXmlParser {
if (cacheState == null) return null
return if (cacheState == CacheAction.MISS || lastCachedPsi == null) {
try {
val psiFile = JetPsiFactory(project).createFile(renderString())
val vf = LightVirtualFile("ANDROIDXML.kt", renderString())
val psiFile = PsiManager.getInstance(project).findFile(vf) as JetFile
psiFile.putUserData(ANDROID_SYNTHETIC, "OK")
psiFile.putUserData(ANDROID_USER_PACKAGE, androidAppPackage)
lastCachedPsi = psiFile
psiFile
} catch (e: Exception) {
@@ -87,6 +103,7 @@ abstract class AndroidUIXmlParser {
}
private fun writeImports(kw: KotlinStringWriter): KotlinWriter {
kw.writePackage(androidAppPackage)
for (elem in androidImports)
kw.writeImport(elem)
kw.writeEmptyLine()
@@ -146,6 +163,26 @@ abstract class AndroidUIXmlParser {
protected abstract fun lazySetup()
protected 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()
}
}
private fun produceKotlinProperties(kw: KotlinStringWriter, ids: Collection<AndroidWidget>): StringBuffer {
for (id in ids) {
val body = arrayListOf("return findViewById(0) as ${id.className}")
@@ -16,3 +16,5 @@ class AndroidID(val rawID: String): AndroidResource {
}
class AndroidWidget(val id: String, val className: String): AndroidResource
class AndroidManifest(val _package: String): AndroidResource
@@ -6,10 +6,13 @@ import com.intellij.openapi.project.Project
class CliAndroidUIXmlParser(val project: Project, override val searchPath: String?): AndroidUIXmlParser() {
override var androidAppPackage: String = ""
override fun lazySetup() {
val fileManager = VirtualFileManager.getInstance()
val watchDir = fileManager.findFileByUrl("file://" + searchPath)
filesToProcess.addAll(watchDir?.getChildren()?.toArrayList() ?: ArrayList(0))
androidAppPackage = readManifest()._package
}
}
@@ -9,9 +9,11 @@ import com.intellij.openapi.vfs.VirtualFileEvent
class IDEAndroidUIXmlParser(project: Project): AndroidUIXmlParser() {
override val searchPath: String? = project.getBasePath() + "/res/layout/"
override var androidAppPackage: String = ""
override protected fun lazySetup() {
if (listenerSetUp) return
androidAppPackage = readManifest()._package
val fileManager = VirtualFileManager.getInstance()
val watchDir = fileManager.findFileByUrl("file://" + searchPath)
filesToProcess.addAll(watchDir?.getChildren()?.toArrayList() ?: ArrayList(0))