Do not use JavaPsiFacade in android-compiler-plugin

This commit is contained in:
Yan Zhulanow
2015-08-20 19:45:01 +03:00
parent d0d846ccfc
commit 0f5d87957d
5 changed files with 47 additions and 43 deletions
@@ -18,14 +18,14 @@ package org.jetbrains.kotlin.android.synthetic.res
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiFile
import java.io.ByteArrayInputStream
import com.intellij.psi.impl.PsiElementFinderImpl
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.android.synthetic.AndroidXmlHandler
import org.jetbrains.kotlin.android.synthetic.parseAndroidResource
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.psi.JetFile
import kotlin.properties.Delegates
public open class CliSyntheticFileGenerator(
project: Project,
@@ -33,32 +33,30 @@ public open class CliSyntheticFileGenerator(
private val resDirectories: List<String>
) : 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 {
val supportV4 = supportV4Available(javaPsiFacade, projectScope)
generateSyntheticJetFiles(generateSyntheticFiles(true, projectScope, supportV4))
val supportV4 = supportV4Available()
generateSyntheticJetFiles(generateSyntheticFiles(true, supportV4))
}
override val layoutXmlFileManager: CliAndroidLayoutXmlFileManager by Delegates.lazy {
override val layoutXmlFileManager: CliAndroidLayoutXmlFileManager by lazy {
CliAndroidLayoutXmlFileManager(project, manifestPath, resDirectories)
}
public override fun getSyntheticFiles(): List<JetFile> = cachedJetFiles
override fun extractLayoutResources(files: List<PsiFile>, scope: GlobalSearchScope): List<AndroidResource> {
override fun extractLayoutResources(files: List<PsiFile>): List<AndroidResource> {
val resources = arrayListOf<AndroidResource>()
val handler = AndroidXmlHandler { id, tag ->
resources += parseAndroidResource(id, tag) { tag ->
resolveFqClassNameForView(javaPsiFacade, scope, tag)
resolveFqClassNameForView(tag)
}
}
for (file in files) {
try {
val inputStream = ByteArrayInputStream(file.getVirtualFile().contentsToByteArray())
val inputStream = ByteArrayInputStream(file.virtualFile.contentsToByteArray())
layoutXmlFileManager.saxParser.parse(inputStream, handler)
} catch (e: Throwable) {
LOG.error(e)
@@ -68,6 +66,17 @@ public open class CliSyntheticFileGenerator(
return filterDuplicates(resources)
}
override fun checkIfClassExist(fqName: String): Boolean {
val scope = GlobalSearchScope.allScope(project)
val psiElementFinders = project.getExtensions(PsiElementFinder.EP_NAME).filter { it is PsiElementFinderImpl }
for (finder in psiElementFinders) {
val clazz = finder.findClass(fqName, scope)
if (clazz != null) return true
}
return false
}
private companion object {
private val LOG: Logger = Logger.getInstance(javaClass)
}
@@ -17,10 +17,9 @@
package org.jetbrains.kotlin.android.synthetic.res
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider.Result
import com.intellij.psi.util.CachedValuesManager
@@ -46,16 +45,12 @@ public abstract class SyntheticFileGenerator(protected val project: Project) {
public abstract fun getSyntheticFiles(): List<JetFile>
protected fun generateSyntheticFiles(
generateCommonFiles: Boolean,
scope: GlobalSearchScope,
supportV4: Boolean
): List<AndroidSyntheticFile> {
protected fun generateSyntheticFiles(generateCommonFiles: Boolean, supportV4: Boolean): List<AndroidSyntheticFile> {
val commonFiles = if (generateCommonFiles) generateCommonFiles(supportV4) else listOf()
return layoutXmlFileManager.getLayoutXmlFiles().flatMap { entry ->
val files = entry.getValue()
val resources = extractLayoutResources(files, scope)
val resources = extractLayoutResources(files)
val layoutName = entry.getKey()
@@ -81,7 +76,9 @@ public abstract class SyntheticFileGenerator(protected val project: Project) {
return listOf(clearCacheFile, TOOLS_FILE)
}
protected abstract fun extractLayoutResources(files: List<PsiFile>, scope: GlobalSearchScope): List<AndroidResource>
protected abstract fun extractLayoutResources(files: List<PsiFile>): List<AndroidResource>
protected abstract fun checkIfClassExist(fqName: String): Boolean
private fun renderMainLayoutFile(layoutName: String, resources: List<AndroidResource>, supportV4: Boolean): AndroidSyntheticFile {
return renderLayoutFile(layoutName + AndroidConst.LAYOUT_POSTFIX, escapeAndroidIdentifier(layoutName), resources) {
@@ -152,25 +149,23 @@ public abstract class SyntheticFileGenerator(protected val project: Project) {
return fqName.startsWith(AndroidConst.SUPPORT_V4_PACKAGE)
}
protected fun resolveFqClassNameForView(javaPsiFacade: JavaPsiFacade, scope: GlobalSearchScope, tag: String): String? {
protected fun resolveFqClassNameForView(tag: String): String? {
if (tag.contains('.')) {
if (javaPsiFacade.findClass(tag, scope) == null) {
if (!checkIfClassExist(tag)) {
return null
}
return tag
}
for (pkg in AndroidConst.FQNAME_RESOLVE_PACKAGES) {
val fqName = "$pkg.$tag"
if (javaPsiFacade.findClass(fqName, scope) != null) {
if (checkIfClassExist(fqName)) {
return fqName
}
}
return null
}
protected fun supportV4Available(javaPsiFacade: JavaPsiFacade, scope: GlobalSearchScope): Boolean {
return javaPsiFacade.findClasses(AndroidConst.SUPPORT_FRAGMENT_FQNAME, scope).isNotEmpty()
}
protected fun supportV4Available(): Boolean = checkIfClassExist(AndroidConst.SUPPORT_FRAGMENT_FQNAME)
protected fun filterDuplicates(resources: List<AndroidResource>): List<AndroidResource> {
val resourceMap = linkedMapOf<String, AndroidResource>()