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 48a6910be57..202228a9a35 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 @@ -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 ) : 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 = cachedJetFiles - override fun extractLayoutResources(files: List, scope: GlobalSearchScope): List { + override fun extractLayoutResources(files: List): List { val resources = arrayListOf() 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) } 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 c73d749bdc2..92c3b609801 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 @@ -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 - protected fun generateSyntheticFiles( - generateCommonFiles: Boolean, - scope: GlobalSearchScope, - supportV4: Boolean - ): List { + protected fun generateSyntheticFiles(generateCommonFiles: Boolean, supportV4: Boolean): List { 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, scope: GlobalSearchScope): List + protected abstract fun extractLayoutResources(files: List): List + + protected abstract fun checkIfClassExist(fqName: String): Boolean private fun renderMainLayoutFile(layoutName: String, resources: List, 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): List { val resourceMap = linkedMapOf() diff --git a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt index 252cb36ec91..52a3a80b20c 100644 --- a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt +++ b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AbstractAndroidXml2KConversionTest.kt @@ -40,10 +40,7 @@ public abstract class AbstractAndroidXml2KConversionTest : UsefulTestCase() { val parser = CliSyntheticFileGeneratorForConversionTest( jetCoreEnvironment.project, path + "AndroidManifest.xml", layoutPaths, supportV4) - val module = ModuleManager.getInstance(jetCoreEnvironment.project).modules.first() - val moduleScope = module.getModuleWithDependenciesAndLibrariesScope(false) - - val actual = parser.gen(moduleScope).toMap { it.name } + val actual = parser.gen().toMap { it.name } val expectedLayoutFiles = testDirectory.listFiles { it.isFile() && it.name.endsWith(".kt") 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 0bcf85b5d4f..12c353aad1b 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 @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.lang.resolve.android.test import com.intellij.openapi.project.Project -import com.intellij.psi.search.GlobalSearchScope import com.intellij.testFramework.UsefulTestCase import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.android.synthetic.AndroidConfigurationKeys @@ -49,7 +48,7 @@ class CliSyntheticFileGeneratorForConversionTest( resDirectories: List, private val supportV4: Boolean ) : CliSyntheticFileGenerator(project, manifestPath, resDirectories) { - fun gen(scope: GlobalSearchScope) = generateSyntheticFiles(false, scope, supportV4) + fun gen() = generateSyntheticFiles(false, supportV4) } fun UsefulTestCase.createAndroidTestEnvironment( 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 46ed94d2854..939a92c6a08 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 @@ -20,9 +20,9 @@ import com.intellij.openapi.module.Module import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiFile 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 @@ -32,13 +32,10 @@ import org.jetbrains.kotlin.psi.JetFile class IDESyntheticFileGenerator(val module: Module) : SyntheticFileGenerator(module.project) { - 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 { - val supportV4 = supportV4Available(javaPsiFacade, moduleScope) - Result.create(generateSyntheticJetFiles(generateSyntheticFiles(true, moduleScope, supportV4)), psiTreeChangePreprocessor) + val supportV4 = supportV4Available() + Result.create(generateSyntheticJetFiles(generateSyntheticFiles(true, supportV4)), psiTreeChangePreprocessor) } } @@ -48,13 +45,16 @@ class IDESyntheticFileGenerator(val module: Module) : SyntheticFileGenerator(mod module.project.getExtensions(PsiTreeChangePreprocessor.EP_NAME).first { it is AndroidPsiTreeChangePreprocessor } } - public override fun getSyntheticFiles(): List = cachedJetFiles.value + public override fun getSyntheticFiles(): List { + if (!checkIfClassExist(AndroidConst.VIEW_FQNAME)) return listOf() + return cachedJetFiles.value + } - override fun extractLayoutResources(files: List, scope: GlobalSearchScope): List { + override fun extractLayoutResources(files: List): List { val widgets = arrayListOf() val visitor = AndroidXmlVisitor { id, widgetType, attribute -> - widgets += parseAndroidResource(id, widgetType) { - resolveFqClassNameForView(javaPsiFacade, scope, it) + widgets += parseAndroidResource(id, widgetType) { tag -> + resolveFqClassNameForView(tag) } } @@ -62,4 +62,8 @@ class IDESyntheticFileGenerator(val module: Module) : SyntheticFileGenerator(mod return filterDuplicates(widgets) } + override fun checkIfClassExist(fqName: String): Boolean { + val moduleScope = module.getModuleWithDependenciesAndLibrariesScope(false) + return JavaPsiFacade.getInstance(module.project).findClass(fqName, moduleScope) != null + } } \ No newline at end of file