diff --git a/plugins/android-extensions/android-extensions-idea/build.gradle.kts b/plugins/android-extensions/android-extensions-idea/build.gradle.kts deleted file mode 100644 index 9dfb3042742..00000000000 --- a/plugins/android-extensions/android-extensions-idea/build.gradle.kts +++ /dev/null @@ -1,90 +0,0 @@ - -description = "Kotlin Android Extensions IDEA" - -plugins { - kotlin("jvm") - id("jps-compatible") -} - -dependencies { - compile(project(":plugins:android-extensions-compiler")) - - testRuntime(intellijDep()) - - compileOnly(project(":compiler:util")) - compileOnly(project(":compiler:light-classes")) - compileOnly(project(":idea:idea-core")) - compileOnly(project(":idea")) - compileOnly(project(":idea:idea-jvm")) - compileOnly(project(":idea:idea-gradle")) - compileOnly(project(":kotlin-android-extensions-runtime")) - compileOnly(intellijPluginDep("android")) - compileOnly(intellijPluginDep("gradle")) - compileOnly(intellijPluginDep("Groovy")) - compileOnly(intellijDep()) - - testApi(project(":compiler:cli")) - testApi(project(":compiler:frontend.java")) - testApi(projectTests(":idea:idea-test-framework")) { isTransitive = false } - testApi(project(":plugins:kapt3-idea")) - testApi(projectTests(":compiler:tests-common")) - testApi(projectTests(":idea")) - testApi(projectTests(":idea:idea-android")) - testApi(project(":kotlin-test:kotlin-test-jvm")) - testApi(commonDependency("junit:junit")) - testApi(project(":idea:idea-native")) { isTransitive = false } - testApi(project(":idea:idea-gradle-native")) { isTransitive = false } - testRuntime(project(":native:frontend.native")) - testRuntime(project(":kotlin-reflect")) - testApi(intellijPluginDep("android")) - testApi(intellijPluginDep("Groovy")) - testApi(intellijDep()) - - testRuntime(project(":idea:idea-jvm")) - testRuntime(project(":sam-with-receiver-ide-plugin")) - testRuntime(project(":noarg-ide-plugin")) - testRuntime(project(":allopen-ide-plugin")) - testRuntime(project(":kotlin-scripting-idea")) - testRuntime(project(":kotlinx-serialization-ide-plugin")) - testRuntime(project(":plugins:lint")) - testRuntime(project(":plugins:parcelize:parcelize-ide")) - testRuntime(project(":plugins:lombok:lombok-ide-plugin")) - testRuntime(intellijPluginDep("junit")) - testRuntime(intellijPluginDep("IntelliLang")) - testRuntime(intellijPluginDep("properties")) - testRuntime(intellijPluginDep("java-i18n")) - testRuntime(intellijPluginDep("gradle")) - testRuntime(intellijPluginDep("Groovy")) - testRuntime(intellijPluginDep("java-decompiler")) - Ide.IJ { - testRuntime(intellijPluginDep("maven")) - testRuntime(intellijPluginDep("repository-search")) - } - testRuntime(intellijPluginDep("android")) - testRuntime(intellijPluginDep("smali")) - - Ide.AS { - testRuntime(intellijPluginDep("android-layoutlib")) - testRuntime(intellijPluginDep("platform-images")) - } -} - -sourceSets { - "main" { } - "test" { } -} - -testsJar {} - -projectTest(parallel = true) { - dependsOn(":dist") - workingDir = rootDir - useAndroidSdk() - useAndroidJar() -} - -runtimeJar() - -sourcesJar() - -javadocJar() diff --git a/plugins/android-extensions/android-extensions-idea/resources/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService b/plugins/android-extensions/android-extensions-idea/resources/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService deleted file mode 100644 index e7801906f5b..00000000000 --- a/plugins/android-extensions/android-extensions-idea/resources/META-INF/services/org.jetbrains.plugins.gradle.tooling.ModelBuilderService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.kotlin.android.synthetic.idea.AndroidExtensionsModelBuilderService \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt deleted file mode 100644 index c3a61b01141..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsCompletionInformationProvider.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin - -import com.intellij.psi.xml.XmlAttributeValue -import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.idea.completion.CompletionInformationProvider -import org.jetbrains.kotlin.renderer.DescriptorRenderer -import org.jetbrains.kotlin.resolve.source.PsiSourceElement - -class AndroidExtensionsCompletionInformationProvider : CompletionInformationProvider { - override fun getContainerAndReceiverInformation(descriptor: DeclarationDescriptor): String? { - if (descriptor !is AndroidSyntheticProperty) { - return null - } - - val propertyDescriptor = (descriptor as? PropertyDescriptor) ?: return null - val attributeValue = (propertyDescriptor.source as? PsiSourceElement)?.psi as? XmlAttributeValue ?: return null - val extensionReceiverType = propertyDescriptor.original.extensionReceiverParameter?.type - - return buildString { - append(" from ${attributeValue.containingFile.name}") - extensionReceiverType?.let { append(" for " + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(it)) } - append(" (Android Extensions)") - } - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsReferenceSearchExecutor.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsReferenceSearchExecutor.kt deleted file mode 100644 index 4adb66fd699..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/AndroidExtensionsReferenceSearchExecutor.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin - -import com.intellij.openapi.application.QueryExecutorBase -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiReference -import com.intellij.psi.search.LocalSearchScope -import com.intellij.psi.search.searches.ReferencesSearch -import com.intellij.psi.xml.XmlAttributeValue -import com.intellij.util.Processor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall -import org.jetbrains.kotlin.idea.references.KtSimpleNameReference -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.KtSimpleNameExpression -import org.jetbrains.kotlin.psi.KtTreeVisitorVoid -import org.jetbrains.kotlin.resolve.source.getPsi - - -class AndroidExtensionsReferenceSearchExecutor : QueryExecutorBase(true) { - override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: Processor) { - val elementToSearch = queryParameters.elementToSearch as? XmlAttributeValue ?: return - val scopeElements = (queryParameters.effectiveSearchScope as? LocalSearchScope)?.scope ?: return - val referenceName = elementToSearch.value?.substringAfterLast("/") ?: return - - scopeElements.filterIsInstance().forEach { - it.accept(object : KtTreeVisitorVoid() { - override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { - if (expression.text == referenceName && expression.isReferenceTo(elementToSearch)) { - expression.references.firstOrNull { it is KtSimpleNameReference }?.let { - consumer.process(it) - } - } - super.visitReferenceExpression(expression) - } - }) - } - } - - private fun KtReferenceExpression.isReferenceTo(element: PsiElement): Boolean = - getTargetPropertyDescriptor()?.source?.getPsi() == element - - private fun KtReferenceExpression.getTargetPropertyDescriptor(): PropertyDescriptor? = - resolveToCall()?.resultingDescriptor as? PropertyDescriptor -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/AndroidModuleInfoProvider.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/AndroidModuleInfoProvider.kt deleted file mode 100644 index ca5b4093502..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/AndroidModuleInfoProvider.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.android.model - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.extensions.ExtensionPointName -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleUtilCore -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiElement -import java.io.File - -val Module.isAndroidModule - - get() = AndroidModuleInfoProvider.getInstance(this)?.isAndroidModule() ?: false - -interface AndroidModuleInfoProvider { - companion object { - val EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.android.model.androidModuleInfoProvider") - - fun getInstance(module: Module): AndroidModuleInfoProvider? { - val extensionArea = Extensions.getArea(module) - if (!extensionArea.hasExtensionPoint(EP_NAME.name)) { - return null - } - return extensionArea.getExtensionPoint(EP_NAME).extension - } - - fun getInstance(element: PsiElement): AndroidModuleInfoProvider? { - val module = ApplicationManager.getApplication().runReadAction { - ModuleUtilCore.findModuleForPsiElement(element) - } - return getInstance(module) - } - } - - val module: Module - - fun isAndroidModule(): Boolean - fun isGradleModule(): Boolean - - fun getApplicationPackage(): String? - - // For old Android Extensions - fun getMainSourceProvider(): SourceProviderMirror? - fun getFlavorSourceProviders(): List - fun getAllResourceDirectories(): List - - // For experimental Android Extensions - fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection - fun getAllSourceProviders(): List - fun getActiveSourceProviders(): List - - - interface SourceProviderMirror { - val name: String - val resDirectories: Collection - } -} - diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/impl/AndroidModuleInfoProviderImpl.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/impl/AndroidModuleInfoProviderImpl.kt deleted file mode 100644 index 7349215f4cb..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/model/impl/AndroidModuleInfoProviderImpl.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.android.model.impl - -import com.android.builder.model.SourceProvider -import com.android.tools.idea.gradle.project.GradleProjectInfo -import com.android.tools.idea.gradle.project.model.AndroidModuleModel -import com.android.tools.idea.res.ResourceRepositoryManager -import com.intellij.openapi.module.Module -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.android.facet.AndroidFacet -import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider -import java.io.File - -class AndroidModuleInfoProviderImpl(override val module: Module) : AndroidModuleInfoProvider { - private val androidFacet: AndroidFacet? - get() = AndroidFacet.getInstance(module) - - private val androidModuleModel: AndroidModuleModel? - get() = AndroidModuleModel.get(module) - - override fun isAndroidModule() = androidFacet != null - override fun isGradleModule() = GradleProjectInfo.getInstance(module.project).isBuildWithGradle - - override fun getAllResourceDirectories(): List { - return androidFacet?.allResourceDirectories ?: emptyList() - } - - override fun getApplicationPackage() = androidFacet?.manifest?.`package`?.toString() - - override fun getMainSourceProvider(): AndroidModuleInfoProvider.SourceProviderMirror? { - return androidFacet?.mainSourceProvider?.let(::SourceProviderMirrorImpl) - } - - override fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection { - return ResourceRepositoryManager.getOrCreateInstance(module)?.getAppResources(createIfNecessary)?.resourceDirs ?: emptyList() - } - - override fun getAllSourceProviders(): List { - val androidModuleModel = this.androidModuleModel ?: return emptyList() - return androidModuleModel.allSourceProviders.map(::SourceProviderMirrorImpl) - } - - override fun getActiveSourceProviders(): List { - val androidModuleModel = this.androidModuleModel ?: return emptyList() - return androidModuleModel.activeSourceProviders.map(::SourceProviderMirrorImpl) - } - - override fun getFlavorSourceProviders(): List { - val androidModuleModel = this.androidModuleModel ?: return emptyList() - - val getFlavorSourceProvidersMethod = try { - AndroidFacet::class.java.getMethod("getFlavorSourceProviders") - } catch (e: NoSuchMethodException) { - null - } - - return if (getFlavorSourceProvidersMethod != null) { - @Suppress("UNCHECKED_CAST") - val sourceProviders = getFlavorSourceProvidersMethod.invoke(androidFacet) as? List - sourceProviders?.map(::SourceProviderMirrorImpl) ?: emptyList() - } else { - androidModuleModel.flavorSourceProviders.map(::SourceProviderMirrorImpl) - } - } - - private class SourceProviderMirrorImpl(val sourceProvider: SourceProvider) : - AndroidModuleInfoProvider.SourceProviderMirror { - override val name: String - get() = sourceProvider.name - - override val resDirectories: Collection - get() = sourceProvider.resDirectories - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableCodegenExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableCodegenExtension.kt deleted file mode 100644 index 50d9c66c709..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableCodegenExtension.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.android.parcel - -import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental -import org.jetbrains.kotlin.idea.caches.project.getModuleInfo -import org.jetbrains.kotlin.psi.KtElement - -class IDEParcelableCodegenExtension : ParcelableCodegenExtension() { - override fun isExperimental(element: KtElement): Boolean { - val moduleInfo = element.getModuleInfo() - return moduleInfo.androidExtensionsIsExperimental - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableResolveExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableResolveExtension.kt deleted file mode 100644 index 0a2b3fbcf21..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/IDEParcelableResolveExtension.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel - -import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental -import org.jetbrains.kotlin.idea.caches.project.getModuleInfo -import org.jetbrains.kotlin.psi.KtElement - -class IDEParcelableResolveExtension : ParcelableResolveExtension() { - override fun isExperimental(element: KtElement): Boolean { - val moduleInfo = element.getModuleInfo() - return moduleInfo.androidExtensionsIsExperimental - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/ParcelableUltraLightClassModifierExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/ParcelableUltraLightClassModifierExtension.kt deleted file mode 100644 index 3283c11ab97..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/ParcelableUltraLightClassModifierExtension.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.android.parcel - -import com.intellij.psi.impl.light.LightFieldBuilder -import org.jetbrains.kotlin.android.parcel.serializers.ParcelableExtensionBase -import org.jetbrains.kotlin.asJava.UltraLightClassModifierExtension -import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass -import org.jetbrains.kotlin.asJava.classes.createGeneratedMethodFromDescriptor -import org.jetbrains.kotlin.asJava.elements.KtLightField -import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl -import org.jetbrains.kotlin.asJava.elements.KtLightMethod -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.util.isAnnotated -import org.jetbrains.kotlin.util.isOrdinaryClass - -class ParcelableUltraLightClassModifierExtension : ParcelableExtensionBase, UltraLightClassModifierExtension { - - private fun tryGetParcelableClass( - declaration: KtDeclaration, - descriptor: Lazy - ): ClassDescriptor? { - - if (!declaration.isOrdinaryClass || !declaration.isAnnotated) return null - - val descriptorValue = descriptor.value ?: return null - - val parcelableClass = (descriptorValue as? ClassDescriptor) - ?: descriptorValue.containingDeclaration as? ClassDescriptor - ?: return null - - if (!parcelableClass.isParcelableClassDescriptor) return null - - return parcelableClass - } - - override fun interceptFieldsBuilding( - declaration: KtDeclaration, - descriptor: Lazy, - containingDeclaration: KtUltraLightClass, - fieldsList: MutableList - ) { - - val parcelableClass = tryGetParcelableClass( - declaration = declaration, - descriptor = descriptor - ) ?: return - - if (parcelableClass.hasCreatorField()) return - - val fieldWrapper = KtLightFieldImpl.KtLightFieldForSourceDeclaration( - origin = null, - computeDelegate = { - LightFieldBuilder("CREATOR", "android.os.Parcelable.Creator", containingDeclaration).also { - it.setModifiers("public", "static", "final") - } - }, - containingClass = containingDeclaration, - dummyDelegate = null - ) - - fieldsList.add(fieldWrapper) - } - - override fun interceptMethodsBuilding( - declaration: KtDeclaration, - descriptor: Lazy, - containingDeclaration: KtUltraLightClass, - methodsList: MutableList - ) { - - val parcelableClass = tryGetParcelableClass( - declaration = declaration, - descriptor = descriptor - ) ?: return - - with(parcelableClass) { - if (hasSyntheticDescribeContents()) { - findFunction(ParcelableSyntheticComponent.ComponentKind.DESCRIBE_CONTENTS)?.let { - methodsList.add( - containingDeclaration.createGeneratedMethodFromDescriptor(it) - ) - } - } - - if (hasSyntheticWriteToParcel()) { - findFunction(ParcelableSyntheticComponent.ComponentKind.WRITE_TO_PARCEL)?.let { - methodsList.add( - containingDeclaration.createGeneratedMethodFromDescriptor(it) - ) - } - } - } - } - -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AbstractParcelableQuickFix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AbstractParcelableQuickFix.kt deleted file mode 100644 index 70a84de0891..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AbstractParcelableQuickFix.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import com.intellij.codeInsight.intention.IntentionAction -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.idea.core.ShortenReferences -import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction -import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType - -abstract class AbstractParcelableQuickFix(element: T) : KotlinQuickFixAction(element) { - protected companion object { - fun T.shortenReferences() = ShortenReferences.DEFAULT.process(this) - } - - override fun getFamilyName() = text - - abstract fun invoke(ktPsiFactory: KtPsiFactory, element: T) - - final override fun invoke(project: Project, editor: Editor?, file: KtFile) { - val clazz = element ?: return - val ktPsiFactory = KtPsiFactory(project, markGenerated = true) - invoke(ktPsiFactory, clazz) - } - - abstract class AbstractFactory(private val f: Diagnostic.() -> IntentionAction?) : KotlinSingleIntentionActionFactory() { - companion object { - inline fun Diagnostic.findElement() = psiElement.getNonStrictParentOfType() - } - - override fun createAction(diagnostic: Diagnostic) = f(diagnostic) - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AnnotateWithParcelizeQuickFix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AnnotateWithParcelizeQuickFix.kt deleted file mode 100644 index a7dd34e7f5d..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/AnnotateWithParcelizeQuickFix.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import kotlinx.android.parcel.Parcelize -import org.jetbrains.kotlin.android.synthetic.diagnostic.ErrorsAndroid -import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.idea.util.addAnnotation -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtPsiFactory - -class AnnotateWithParcelizeQuickFix(clazz: KtClassOrObject) : AbstractParcelableQuickFix(clazz) { - object Factory : AbstractFactory({ - val diagnostic = Errors.PLUGIN_ERROR.cast(this).a - val targetClass = ErrorsAndroid.CLASS_SHOULD_BE_PARCELIZE.cast(diagnostic.diagnostic).a - AnnotateWithParcelizeQuickFix(targetClass) - }) - - override fun getText() = "Annotate containing class with ''@Parcelize''" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtClassOrObject) { - element.addAnnotation(FqName(Parcelize::class.java.name)) - } -} diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelMigrateToParcelizeQuickFix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelMigrateToParcelizeQuickFix.kt deleted file mode 100644 index 2fefb684cd7..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelMigrateToParcelizeQuickFix.kt +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import com.intellij.openapi.diagnostic.Logger -import kotlinx.android.parcel.Parceler -import org.jetbrains.kotlin.android.parcel.ANDROID_PARCELABLE_CREATOR_CLASS_FQNAME -import org.jetbrains.kotlin.android.parcel.ANDROID_PARCEL_CLASS_FQNAME -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.analyze -import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.core.getOrCreateCompanionObject -import org.jetbrains.kotlin.idea.intentions.branchedTransformations.unwrapBlockOrParenthesis -import org.jetbrains.kotlin.idea.util.findAnnotation -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.addRemoveModifier.setModifierList -import org.jetbrains.kotlin.psi.psiUtil.containingClass -import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.resolve.source.KotlinSourceElement -import org.jetbrains.kotlin.types.TypeUtils - -class ParcelMigrateToParcelizeQuickFix(function: KtClass) : AbstractParcelableQuickFix(function) { - companion object { - private val PARCELER_FQNAME = FqName(Parceler::class.java.name) - private val PARCELER_WRITE_FUNCTION_NAME = Name.identifier("write") - private val PARCELER_CREATE_FUNCTION_NAME = Name.identifier("create") - private val LOG = Logger.getInstance(ParcelMigrateToParcelizeQuickFix::class.java) - - private fun KtClass.findParcelerCompanionObject(): Pair? { - for (obj in companionObjects) { - val objDescriptor = obj.resolveToDescriptorIfAny() ?: continue - for (superClassifier in objDescriptor.getAllSuperClassifiers()) { - val superClass = superClassifier as? ClassDescriptor ?: continue - if (superClass.fqNameSafe == PARCELER_FQNAME) return Pair(obj, objDescriptor) - } - } - - return null - } - - private fun KtNamedFunction.doesLookLikeWriteToParcelOverride(): Boolean { - return name == "writeToParcel" - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference == null - && valueParameters.size == 2 - && typeParameters.size == 0 - && valueParameters[0].typeReference?.getFqName() == ANDROID_PARCEL_CLASS_FQNAME.asString() - && valueParameters[1].typeReference?.getFqName() == KotlinBuiltIns.FQ_NAMES._int.asString() - } - - private fun KtNamedFunction.doesLookLikeNewArrayOverride(): Boolean { - return name == "newArray" - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference == null - && valueParameters.size == 1 - && typeParameters.size == 0 - && valueParameters[0].typeReference?.getFqName() == KotlinBuiltIns.FQ_NAMES._int.asString() - } - - private fun KtNamedFunction.doesLookLikeDescribeContentsOverride(): Boolean { - return name == "describeContents" - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference == null - && valueParameters.size == 0 - && typeParameters.size == 0 - && typeReference?.getFqName() == KotlinBuiltIns.FQ_NAMES._int.asString() - } - - private fun KtClass.findWriteToParcelOverride() = findFunction { doesLookLikeWriteToParcelOverride() } - private fun KtClass.findDescribeContentsOverride() = findFunction { doesLookLikeDescribeContentsOverride() } - private fun KtObjectDeclaration.findNewArrayOverride() = findFunction { doesLookLikeNewArrayOverride() } - - private fun KtClass.findCreatorClass(): KtClassOrObject? { - for (companion in companionObjects) { - if (companion.name == "CREATOR") { - return companion - } - - val creatorProperty = companion.declarations.asSequence() - .filterIsInstance() - .firstOrNull { it.name == "CREATOR" } - ?: continue - - creatorProperty.findAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) ?: continue - - val initializer = creatorProperty.initializer ?: continue - when (initializer) { - is KtObjectLiteralExpression -> return initializer.objectDeclaration - is KtCallExpression -> { - val constructedClass = (initializer.resolveToCall() - ?.resultingDescriptor as? ConstructorDescriptor)?.constructedClass - if (constructedClass != null) { - val sourceElement = constructedClass.source as? KotlinSourceElement - (sourceElement?.psi as? KtClassOrObject)?.let { return it } - } - } - } - } - - return null - } - - private fun KtNamedFunction.doesLookLikeCreateFromParcelOverride(): Boolean { - return name == "createFromParcel" - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference == null - && valueParameters.size == 1 - && typeParameters.size == 0 - && valueParameters[0].typeReference?.getFqName() == ANDROID_PARCEL_CLASS_FQNAME.asString() - } - - private fun findCreateFromParcel(creator: KtClassOrObject) = creator.findFunction { doesLookLikeCreateFromParcelOverride() } - - private fun KtNamedFunction.doesLookLikeWriteImplementation(): Boolean { - val containingParcelableClassFqName = containingClassOrObject?.containingClass()?.fqName?.asString() - - return name == PARCELER_WRITE_FUNCTION_NAME.asString() - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference?.getFqName() == containingParcelableClassFqName - && valueParameters.size == 2 - && typeParameters.size == 0 - && valueParameters[0].typeReference?.getFqName() == ANDROID_PARCEL_CLASS_FQNAME.asString() - && valueParameters[1].typeReference?.getFqName() == KotlinBuiltIns.FQ_NAMES._int.asString() - } - - private fun KtNamedFunction.doesLookLikeCreateImplementation(): Boolean { - return name == PARCELER_CREATE_FUNCTION_NAME.asString() - && hasModifier(KtTokens.OVERRIDE_KEYWORD) - && receiverTypeReference == null - && valueParameters.size == 1 - && typeParameters.size == 0 - && valueParameters[0].typeReference?.getFqName() == ANDROID_PARCEL_CLASS_FQNAME.asString() - } - - private fun KtObjectDeclaration.findCreateImplementation() = findFunction { doesLookLikeCreateImplementation() } - private fun KtObjectDeclaration.findWriteImplementation() = findFunction { doesLookLikeWriteImplementation() } - - private fun KtClassOrObject.findFunction(f: KtNamedFunction.() -> Boolean) - = declarations.asSequence().filterIsInstance().firstOrNull(f) - - private fun KtTypeReference.getFqName(): String? = analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this] - ?.constructor?.declarationDescriptor?.fqNameSafe?.asString() - } - - object FactoryForWrite : AbstractFactory({ findElement()?.let { ParcelMigrateToParcelizeQuickFix(it) } }) - - object FactoryForCREATOR : AbstractFactory({ - findElement()?.getStrictParentOfType()?.let { ParcelMigrateToParcelizeQuickFix(it) } - }) - - override fun getText() = "Migrate to ''Parceler'' companion object" - - @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") - override fun invoke(ktPsiFactory: KtPsiFactory, parcelableClass: KtClass) { - val parcelerObject = parcelableClass.findParcelerCompanionObject()?.first ?: parcelableClass.getOrCreateCompanionObject() - val bindingContext = parcelerObject.analyze(BodyResolveMode.PARTIAL) - - val parcelerTypeArg = parcelableClass.name ?: run { - LOG.error("Parceler class should not be an anonymous class") - return - } - - val parcelerObjectDescriptor = bindingContext[BindingContext.CLASS, parcelerObject] ?: run { - LOG.error("Unable to resolve parceler object for ${parcelableClass.name ?: ""}") - return - } - - if (!parcelerObjectDescriptor.getAllSuperClassifiers().any { it.fqNameSafe == PARCELER_FQNAME }) { - val entryText = PARCELER_FQNAME.asString() + "<" + parcelerTypeArg + ">" - parcelerObject.addSuperTypeListEntry(ktPsiFactory.createSuperTypeEntry(entryText)).shortenReferences() - } - - val oldWriteToParcelFunction = parcelableClass.findWriteToParcelOverride() - val oldCreateFromParcelFunction = parcelableClass.findCreatorClass()?.let { findCreateFromParcel(it) } - - for (superTypeEntry in parcelerObject.superTypeListEntries) { - val superClass = bindingContext[BindingContext.TYPE, superTypeEntry.typeReference]?.constructor?.declarationDescriptor ?: continue - if (superClass.getAllSuperClassifiers().any { it.fqNameSafe == ANDROID_PARCELABLE_CREATOR_CLASS_FQNAME }) { - parcelerObject.removeSuperTypeListEntry(superTypeEntry) - } - } - - if (parcelerObject.name == "CREATOR") { - parcelerObject.nameIdentifier?.delete() - } - - if (oldWriteToParcelFunction != null) { - parcelerObject.findWriteImplementation()?.delete() // Remove old implementation - - val newFunction = oldWriteToParcelFunction.copy() as KtFunction - oldWriteToParcelFunction.delete() - - newFunction.setName(PARCELER_WRITE_FUNCTION_NAME.asString()) - newFunction.setModifierList(ktPsiFactory.createModifierList(KtTokens.OVERRIDE_KEYWORD)) - newFunction.setReceiverTypeReference(ktPsiFactory.createType(parcelerTypeArg)) - newFunction.valueParameterList?.apply { - assert(parameters.size == 2) - val parcelParameterName = parameters[0].name ?: "parcel" - val flagsParameterName = parameters[1].name ?: "flags" - - repeat(parameters.size) { removeParameter(0) } - addParameter(ktPsiFactory.createParameter("$parcelParameterName : ${ANDROID_PARCEL_CLASS_FQNAME.asString()}")) - addParameter(ktPsiFactory.createParameter("$flagsParameterName : Int")) - } - - parcelerObject.addDeclaration(newFunction).valueParameterList?.shortenReferences() - } else if (parcelerObject.findWriteImplementation() == null) { - val writeFunction = "fun $parcelerTypeArg.write(parcel: ${ANDROID_PARCEL_CLASS_FQNAME.asString()}, flags: Int) = TODO()" - parcelerObject.addDeclaration(ktPsiFactory.createFunction(writeFunction)).valueParameterList?.shortenReferences() - } - - if (oldCreateFromParcelFunction != null) { - parcelerObject.findCreateImplementation()?.delete() // Remove old implementation - - val newFunction = oldCreateFromParcelFunction.copy() as KtFunction - if (oldCreateFromParcelFunction.containingClassOrObject == parcelerObject) { - oldCreateFromParcelFunction.delete() - } - - newFunction.setName(PARCELER_CREATE_FUNCTION_NAME.asString()) - newFunction.setModifierList(ktPsiFactory.createModifierList(KtTokens.OVERRIDE_KEYWORD)) - newFunction.setReceiverTypeReference(null) - newFunction.valueParameterList?.apply { - assert(parameters.size == 1) - val parcelParameterName = parameters[0].name ?: "parcel" - - removeParameter(0) - addParameter(ktPsiFactory.createParameter("$parcelParameterName : ${ANDROID_PARCEL_CLASS_FQNAME.asString()}")) - } - - parcelerObject.addDeclaration(newFunction).valueParameterList?.shortenReferences() - } else if (parcelerObject.findCreateImplementation() == null) { - val createFunction = "override fun create(parcel: ${ANDROID_PARCEL_CLASS_FQNAME.asString()}): $parcelerTypeArg = TODO()" - parcelerObject.addDeclaration(ktPsiFactory.createFunction(createFunction)).valueParameterList?.shortenReferences() - } - - // Always use the default newArray() implementation - parcelerObject.findNewArrayOverride()?.delete() - - parcelableClass.findDescribeContentsOverride()?.let { describeContentsFunction -> - val returnExpr = describeContentsFunction.bodyExpression?.unwrapBlockOrParenthesis() - if (returnExpr is KtReturnExpression && returnExpr.getTargetLabel() == null) { - val returnValue = returnExpr.analyze()[BindingContext.COMPILE_TIME_VALUE, returnExpr.returnedExpression] - ?.getValue(TypeUtils.NO_EXPECTED_TYPE) - if (returnValue == 0) { - // There are no additional overrides in the hierarchy - if (bindingContext[BindingContext.FUNCTION, describeContentsFunction]?.overriddenDescriptors?.size == 1) { - describeContentsFunction.delete() - } - } - } - } - - for (property in parcelerObject.declarations.asSequence().filterIsInstance().filter { it.name == "CREATOR" }) { - if (property.findAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) != null) { - property.delete() - } - } - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomCreatorProperty.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomCreatorProperty.kt deleted file mode 100644 index 6336691256c..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomCreatorProperty.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPsiFactory - -class ParcelRemoveCustomCreatorProperty(property: KtProperty) : AbstractParcelableQuickFix(property) { - object Factory : AbstractFactory(f@ { - // KtProperty or its name identifier - psiElement as? KtProperty ?: (psiElement.parent as? KtProperty) ?: return@f null - findElement()?.let(::ParcelRemoveCustomCreatorProperty) - }) - - override fun getText() = "Remove custom ''CREATOR'' property" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtProperty) { - element.delete() - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomWriteToParcel.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomWriteToParcel.kt deleted file mode 100644 index 8ebab691eea..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelRemoveCustomWriteToParcel.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtPsiFactory - -class ParcelRemoveCustomWriteToParcel(function: KtFunction) : AbstractParcelableQuickFix(function) { - object Factory : AbstractFactory({ findElement()?.let(::ParcelRemoveCustomWriteToParcel) }) - override fun getText() = "Remove custom ''writeToParcel()'' function" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtFunction) { - element.delete() - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddIgnoreOnParcelAnnotationQuickfix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddIgnoreOnParcelAnnotationQuickfix.kt deleted file mode 100644 index e3e3341740a..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddIgnoreOnParcelAnnotationQuickfix.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import kotlinx.android.parcel.IgnoredOnParcel -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPsiFactory - -class ParcelableAddIgnoreOnParcelAnnotationQuickfix(property: KtProperty) : AbstractParcelableQuickFix(property) { - object Factory : AbstractFactory({ findElement()?.let(::ParcelableAddIgnoreOnParcelAnnotationQuickfix) }) - override fun getText() = "Add ''@IgnoredOnParcel'' annotation" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtProperty) { - element.addAnnotationEntry(ktPsiFactory.createAnnotationEntry("@" + IgnoredOnParcel::class.java.name)).shortenReferences() - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddPrimaryConstructorQuickfix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddPrimaryConstructorQuickfix.kt deleted file mode 100644 index dd8d38d1827..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddPrimaryConstructorQuickfix.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.createPrimaryConstructorIfAbsent - -class ParcelableAddPrimaryConstructorQuickfix(clazz: KtClass) : AbstractParcelableQuickFix(clazz) { - object Factory : AbstractFactory({ findElement()?.let(::ParcelableAddPrimaryConstructorQuickfix) }) - override fun getText() = "Add empty primary constructor" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtClass) { - element.createPrimaryConstructorIfAbsent() - - for (secondaryConstructor in element.secondaryConstructors) { - if (secondaryConstructor.getDelegationCall().isImplicit) { - val parameterList = secondaryConstructor.valueParameterList ?: return - val colon = secondaryConstructor.addAfter(ktPsiFactory.createColon(), parameterList) - secondaryConstructor.addAfter(ktPsiFactory.createExpression("this()"), colon) - } - } - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddSupertypeQuickfix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddSupertypeQuickfix.kt deleted file mode 100644 index a9a766a0b2c..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableAddSupertypeQuickfix.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.android.parcel.ANDROID_PARCELABLE_CLASS_FQNAME -import org.jetbrains.kotlin.psi.* - -class ParcelableAddSupertypeQuickfix(clazz: KtClassOrObject) : AbstractParcelableQuickFix(clazz) { - object Factory : AbstractFactory({ findElement()?.let(::ParcelableAddSupertypeQuickfix) }) - override fun getText() = "Add ''Parcelable'' supertype" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtClassOrObject) { - val supertypeName = ANDROID_PARCELABLE_CLASS_FQNAME.asString() - element.addSuperTypeListEntry(ktPsiFactory.createSuperTypeEntry(supertypeName)).shortenReferences() - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt deleted file mode 100644 index a0366b07c87..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.android.synthetic.diagnostic.ErrorsAndroid -import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor -import org.jetbrains.kotlin.idea.quickfix.QuickFixes -import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix -import org.jetbrains.kotlin.lexer.KtTokens - -class ParcelableQuickFixContributor : QuickFixContributor { - override fun registerQuickFixes(quickFixes: QuickFixes) { - quickFixes.register(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS, - RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(KtTokens.INNER_KEYWORD, false)) - - quickFixes.register(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE, ParcelableAddSupertypeQuickfix.Factory) - quickFixes.register(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR, ParcelableAddPrimaryConstructorQuickfix.Factory) - quickFixes.register(ErrorsAndroid.PROPERTY_WONT_BE_SERIALIZED, ParcelableAddIgnoreOnParcelAnnotationQuickfix.Factory) - - quickFixes.register(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED, ParcelMigrateToParcelizeQuickFix.FactoryForWrite) - quickFixes.register(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED, ParcelRemoveCustomWriteToParcel.Factory) - - quickFixes.register(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED, ParcelMigrateToParcelizeQuickFix.FactoryForCREATOR) - quickFixes.register(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED, ParcelRemoveCustomCreatorProperty.Factory) - - quickFixes.register(ErrorsAndroid.REDUNDANT_TYPE_PARCELER, ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix.Factory) - quickFixes.register(ErrorsAndroid.CLASS_SHOULD_BE_PARCELIZE, AnnotateWithParcelizeQuickFix.Factory) - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix.kt deleted file mode 100644 index 47c64b98cf8..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.parcel.quickfixes - -import org.jetbrains.kotlin.psi.KtAnnotationEntry -import org.jetbrains.kotlin.psi.KtPsiFactory - -class ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix(anno: KtAnnotationEntry) : AbstractParcelableQuickFix(anno) { - object Factory : AbstractFactory({ findElement()?.let(::ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix) }) - - override fun getText() = "Remove redundant ''@TypeParceler'' annotation" - - override fun invoke(ktPsiFactory: KtPsiFactory, element: KtAnnotationEntry) { - element.delete() - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsProjectResolverExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsProjectResolverExtension.kt deleted file mode 100644 index 2b32c338cae..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsProjectResolverExtension.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.synthetic.idea - -import com.intellij.openapi.externalSystem.model.DataNode -import com.intellij.openapi.externalSystem.model.ProjectKeys -import com.intellij.openapi.externalSystem.model.project.ModuleData -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil -import com.intellij.openapi.util.Key -import org.gradle.api.Project -import org.gradle.tooling.model.idea.IdeaModule -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.ANDROID_COMPILER_PLUGIN_ID -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.DEFAULT_CACHE_IMPL_OPTION -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.ENABLED_OPTION -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.EXPERIMENTAL_OPTION -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler -import org.jetbrains.kotlin.idea.facet.KotlinFacet -import org.jetbrains.kotlin.idea.util.NotNullableCopyableDataNodeUserDataProperty -import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData -import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension -import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder -import org.jetbrains.plugins.gradle.tooling.ModelBuilderService -import java.io.Serializable -import java.lang.Exception - -var DataNode.hasAndroidExtensionsPlugin: Boolean - by NotNullableCopyableDataNodeUserDataProperty(Key.create("HAS_ANDROID_EXTENSIONS_PLUGIN"), false) - -var DataNode.isExperimental: Boolean - by NotNullableCopyableDataNodeUserDataProperty(Key.create("ANDROID_EXTENSIONS_IS_EXPERIMENTAL"), false) - -private const val DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE = "hashMap" - -var DataNode.defaultCacheImplementation: String - by NotNullableCopyableDataNodeUserDataProperty(Key.create("ANDROID_EXTENSIONS_DEFAULT_CACHE_IMPL"), - DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE) - -interface AndroidExtensionsGradleModel : Serializable { - val hasAndroidExtensionsPlugin: Boolean - val isExperimental: Boolean - val defaultCacheImplementation: String -} - -class AndroidExtensionsGradleModelImpl( - override val hasAndroidExtensionsPlugin: Boolean, - override val isExperimental: Boolean, - override val defaultCacheImplementation: String -) : AndroidExtensionsGradleModel - -@Suppress("unused") -class AndroidExtensionsProjectResolverExtension : AbstractProjectResolverExtension() { - override fun getExtraProjectModelClasses() = setOf(AndroidExtensionsGradleModel::class.java) - override fun getToolingExtensionsClasses() = setOf(AndroidExtensionsModelBuilderService::class.java) - - override fun populateModuleExtraModels(gradleModule: IdeaModule, ideModule: DataNode) { - val androidExtensionsModel = resolverCtx.getExtraProject(gradleModule, AndroidExtensionsGradleModel::class.java) ?: return - - ideModule.hasAndroidExtensionsPlugin = androidExtensionsModel.hasAndroidExtensionsPlugin - ideModule.isExperimental = androidExtensionsModel.isExperimental - ideModule.defaultCacheImplementation = androidExtensionsModel.defaultCacheImplementation - - super.populateModuleExtraModels(gradleModule, ideModule) - } -} - -class AndroidExtensionsModelBuilderService : ModelBuilderService { - override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder { - return ErrorMessageBuilder.create(project, e, "Gradle import errors") - .withDescription("Unable to build Android Extensions plugin configuration") - } - - override fun canBuild(modelName: String?): Boolean = modelName == AndroidExtensionsGradleModel::class.java.name - - override fun buildAll(modelName: String?, project: Project): Any { - val androidExtensionsPlugin = project.plugins.findPlugin("kotlin-android-extensions") - - val androidExtensionsExtension = project.extensions.findByName("androidExtensions") - - val isExperimental = androidExtensionsExtension?.let { ext -> - val isExperimentalMethod = ext::class.java.methods - .firstOrNull { it.name == "isExperimental" && it.parameterCount == 0 } - ?: return@let false - - isExperimentalMethod.invoke(ext) as? Boolean - } ?: false - - val defaultCacheImplementation = androidExtensionsExtension?.let { ext -> - val defaultCacheImplementationMethod = ext::class.java.methods.firstOrNull { - it.name == "getDefaultCacheImplementation" && it.parameterCount == 0 - } ?: return@let DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE - - val enumValue = defaultCacheImplementationMethod.invoke(ext) ?: return@let DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE - - val optionNameMethod = enumValue::class.java.methods.firstOrNull { it.name == "getOptionName" && it.parameterCount == 0 } - ?: return@let DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE - - optionNameMethod.invoke(enumValue) as? String - } ?: DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE - - return AndroidExtensionsGradleModelImpl(androidExtensionsPlugin != null, isExperimental, defaultCacheImplementation) - } -} - -@Suppress("unused") -class AndroidExtensionsGradleImportHandler : GradleProjectImportHandler { - override fun importBySourceSet(facet: KotlinFacet, sourceSetNode: DataNode) { - val module = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE) ?: return - importByModule(facet, module) - } - - override fun importByModule(facet: KotlinFacet, moduleNode: DataNode) { - val facetSettings = facet.configuration.settings - val commonArguments = facetSettings.compilerArguments ?: CommonCompilerArguments.DummyImpl() - - fun makePluginOption(key: String, value: String) = "plugin:$ANDROID_COMPILER_PLUGIN_ID:$key=$value" - - val newPluginOptions = (commonArguments.pluginOptions ?: emptyArray()) - .filterTo(mutableListOf()) { !it.startsWith("plugin:$ANDROID_COMPILER_PLUGIN_ID:") } // Filter out old options - - if (moduleNode.hasAndroidExtensionsPlugin) { - newPluginOptions += makePluginOption(EXPERIMENTAL_OPTION.optionName, moduleNode.isExperimental.toString()) - newPluginOptions += makePluginOption(ENABLED_OPTION.optionName, moduleNode.hasAndroidExtensionsPlugin.toString()) - newPluginOptions += makePluginOption(DEFAULT_CACHE_IMPL_OPTION.optionName, moduleNode.defaultCacheImplementation) - } - - commonArguments.pluginOptions = newPluginOptions.toTypedArray() - facetSettings.compilerArguments = commonArguments - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsReportSubmitter.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsReportSubmitter.kt deleted file mode 100644 index 39fa8740d8c..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidExtensionsReportSubmitter.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import com.intellij.diagnostic.ITNReporter -import com.intellij.openapi.diagnostic.IdeaLoggingEvent - -class AndroidExtensionsReportSubmitter : ITNReporter() { - override fun showErrorInRelease(event: IdeaLoggingEvent) = true -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidGotoDeclarationHandler.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidGotoDeclarationHandler.kt deleted file mode 100644 index 4f9a6420101..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidGotoDeclarationHandler.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler -import com.intellij.openapi.actionSystem.DataContext -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.module.ModuleServiceManager -import com.intellij.psi.PsiElement -import com.intellij.psi.impl.source.tree.LeafPsiElement -import com.intellij.psi.xml.XmlAttribute -import org.jetbrains.kotlin.android.synthetic.res.AndroidLayoutXmlFileManager -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.idea.caches.project.getModuleInfo -import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall -import org.jetbrains.kotlin.psi.KtSimpleNameExpression - -class AndroidGotoDeclarationHandler : GotoDeclarationHandler { - override fun getGotoDeclarationTargets(sourceElement: PsiElement?, offset: Int, editor: Editor?): Array? { - if (sourceElement is LeafPsiElement && sourceElement.parent is KtSimpleNameExpression) { - val simpleNameExpression = sourceElement.parent as? KtSimpleNameExpression ?: return null - val layoutManager = getLayoutManager(sourceElement) ?: return null - val propertyDescriptor = resolvePropertyDescriptor(simpleNameExpression) ?: return null - - val psiElements = layoutManager.propertyToXmlAttributes(propertyDescriptor) - val valueElements = psiElements.mapNotNull { (it as? XmlAttribute)?.valueElement as? PsiElement } - if (valueElements.isNotEmpty()) return valueElements.toTypedArray() - } - - return null - } - - private fun resolvePropertyDescriptor(simpleNameExpression: KtSimpleNameExpression): PropertyDescriptor? { - val resolvedCall = simpleNameExpression.resolveToCall() - return resolvedCall?.resultingDescriptor as? PropertyDescriptor - } - - private fun getLayoutManager(sourceElement: PsiElement): AndroidLayoutXmlFileManager? { - val moduleInfo = sourceElement.getModuleInfo().findAndroidModuleInfo() ?: return null - return ModuleServiceManager.getService(moduleInfo.module, AndroidLayoutXmlFileManager::class.java) - } - - override fun getActionText(context: DataContext): String? { - return null - } -} diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt deleted file mode 100644 index f2906a8288b..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidIndicesHelperExtension.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import org.jetbrains.kotlin.android.synthetic.AndroidConst -import org.jetbrains.kotlin.android.synthetic.descriptors.PredefinedPackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.idea.core.extension.KotlinIndicesHelperExtension -import org.jetbrains.kotlin.incremental.components.LookupLocation -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf - -class AndroidIndicesHelperExtension : KotlinIndicesHelperExtension { - override fun appendExtensionCallables( - consumer: MutableList, - moduleDescriptor: ModuleDescriptor, - receiverTypes: Collection, - nameFilter: (String) -> Boolean, - lookupLocation: LookupLocation - ) { - for (packageFragment in moduleDescriptor.getPackage(FqName(AndroidConst.SYNTHETIC_PACKAGE)).fragments) { - if (packageFragment !is PredefinedPackageFragmentDescriptor) continue - - fun handleScope(scope: MemberScope) { - val descriptors = scope.getContributedDescriptors(DescriptorKindFilter.CALLABLES) { nameFilter(it.asString()) } - for (descriptor in descriptors) { - val receiverType = (descriptor as CallableDescriptor).extensionReceiverParameter?.type ?: continue - if (receiverTypes.any { it.isSubtypeOf(receiverType) }) { - consumer += descriptor - } - } - } - - handleScope(packageFragment.getMemberScope()) - for (fragment in packageFragment.lazySubpackages) { - if (fragment.isDeprecated) continue - handleScope(fragment.descriptor().getMemberScope()) - } - } - } - - override fun appendExtensionCallables( - consumer: MutableList, - moduleDescriptor: ModuleDescriptor, - receiverTypes: Collection, - nameFilter: (String) -> Boolean - ) { - throw IllegalStateException("Should not be called") - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidPsiTreeChangePreprocessor.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidPsiTreeChangePreprocessor.kt deleted file mode 100644 index 10bc73c7076..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidPsiTreeChangePreprocessor.kt +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import com.intellij.ide.highlighter.XmlFileType -import com.intellij.openapi.roots.ProjectRootManager -import com.intellij.openapi.util.SimpleModificationTracker -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.psi.PsiDirectory -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.impl.PsiTreeChangeEventImpl -import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.xml.XmlAttribute -import com.intellij.psi.xml.XmlAttributeValue -import com.intellij.psi.xml.XmlFile -import com.intellij.psi.xml.XmlToken -import org.jetbrains.kotlin.android.synthetic.res.AndroidLayoutXmlFileManager - -class AndroidPsiTreeChangePreprocessor : PsiTreeChangePreprocessor, SimpleModificationTracker() { - - override fun treeChanged(event: PsiTreeChangeEventImpl) { - if (event.code in HANDLED_EVENTS) { - val child = event.child - - // We should get more precise event notification (not just "that file was changed somehow") - if (child == null && event.code == PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED) { - return - } - - // Layout file was renamed - val element = event.element - if (element != null - && event.code == PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED - && event.propertyName == "fileName") { - if (checkIfLayoutFile(element)) { - incModificationCount() - return - } - } - - if (child != null && checkIfLayoutFile(child)) { - incModificationCount() - return - } - - val file = event.file ?: return - if (!checkIfLayoutFile(file)) return - - val xmlAttribute = findXmlAttribute(child) ?: return - val name = xmlAttribute.name - if (name != "android:id" && name != "class") return - incModificationCount() - } - } - - private companion object { - private val HANDLED_EVENTS = setOf( - PsiTreeChangeEventImpl.PsiEventType.CHILD_ADDED, - PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED, - PsiTreeChangeEventImpl.PsiEventType.CHILD_REMOVED, - PsiTreeChangeEventImpl.PsiEventType.CHILD_REPLACED, - PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED, - PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED) - - private fun checkIfLayoutFile(element: PsiElement): Boolean { - val xmlFile = element as? XmlFile ?: return false - - val projectFileIndex = ProjectRootManager.getInstance(xmlFile.project).fileIndex - val module = projectFileIndex.getModuleForFile(xmlFile.virtualFile) - ?: element.getContainingDirectorySafe()?.let { projectFileIndex.getModuleForFile(it.virtualFile) } - - if (module != null && !module.isDisposed) { - val resourceManager = AndroidLayoutXmlFileManager.getInstance(module) ?: return false - val resDirectories = resourceManager.getAllModuleResDirectories() - val baseDirectory = xmlFile.parent?.parent?.virtualFile - - if (baseDirectory != null && baseDirectory in resDirectories && xmlFile.isLayoutXmlFile()) { - return true - } - } - - return false - } - - private fun PsiFile.getContainingDirectorySafe(): PsiDirectory? { - val virtualFile = this.viewProvider.virtualFile.takeIf { it.isValid } ?: return null - val parentDirectory = virtualFile.parent?.takeIf { it.isValid } ?: return null - return this.manager.findDirectory(parentDirectory) - } - - private fun findXmlAttribute(element: PsiElement?): XmlAttribute? { - return when (element) { - is XmlToken, is XmlAttributeValue -> findXmlAttribute(element.parent) - is XmlAttribute -> element - else -> null - } - } - - private fun AndroidLayoutXmlFileManager.getAllModuleResDirectories(): List { - val module = androidModule ?: return listOf() - val fileManager = VirtualFileManager.getInstance() - - return module.variants.fold(arrayListOf()) { list, variant -> - for (dir in variant.resDirectories) { - fileManager.findFileByUrl("file://$dir")?.let { list += it } - } - list - } - } - - private fun PsiFile.isLayoutXmlFile(): Boolean { - if (fileType != XmlFileType.INSTANCE) return false - return parent?.name?.startsWith("layout") ?: false - } - } - -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidSimpleNameReferenceExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidSimpleNameReferenceExtension.kt deleted file mode 100644 index 78857656b01..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidSimpleNameReferenceExtension.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import com.intellij.psi.PsiElement -import com.intellij.psi.xml.XmlAttributeValue -import com.intellij.psi.xml.XmlFile -import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider -import org.jetbrains.kotlin.android.synthetic.AndroidConst -import org.jetbrains.kotlin.android.synthetic.androidIdToName -import org.jetbrains.kotlin.idea.references.KtSimpleNameReference -import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension -import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -import org.jetbrains.kotlin.psi.KtPsiFactory - -class AndroidSimpleNameReferenceExtension : SimpleNameReferenceExtension { - - override fun isReferenceTo(reference: KtSimpleNameReference, element: PsiElement): Boolean = - element is XmlFile && reference.isReferenceToXmlFile(element) - - private fun isLayoutPackageIdentifier(reference: KtSimpleNameReference): Boolean { - val probablyVariant = reference.element.parent as? KtDotQualifiedExpression ?: return false - val probablyKAS = probablyVariant.receiverExpression as? KtDotQualifiedExpression ?: return false - return probablyKAS.receiverExpression.text == AndroidConst.SYNTHETIC_PACKAGE - } - - override fun handleElementRename(reference: KtSimpleNameReference, psiFactory: KtPsiFactory, newElementName: String): PsiElement? { - val resolvedElement = reference.resolve() - if (resolvedElement is XmlAttributeValue && isIdDeclaration(resolvedElement)) { - val newSyntheticPropertyName = androidIdToName(newElementName) ?: return null - return psiFactory.createNameIdentifier(newSyntheticPropertyName.name) - } - else if (isLayoutPackageIdentifier(reference)) { - return psiFactory.createSimpleName(newElementName.removeSuffix(".xml")).getIdentifier() - } - - return null - } - - private fun isIdDeclaration(declaration: XmlAttributeValue) = declaration.value?.startsWith("@+id/") ?: false - - private fun KtSimpleNameReference.isReferenceToXmlFile(xmlFile: XmlFile): Boolean { - if (!isLayoutPackageIdentifier(this)) { - return false - } - - if (xmlFile.name.removeSuffix(".xml") != element.getReferencedName()) { - return false - } - - val virtualFile = xmlFile.virtualFile ?: return false - val layoutDir = virtualFile.parent - if (layoutDir.name != "layout" && !layoutDir.name.startsWith("layout-")) { - return false - } - - val resourceDirectories = AndroidModuleInfoProvider.getInstance(element)?.getAllResourceDirectories() ?: return false - val resourceDirectory = virtualFile.parent?.parent ?: return false - return resourceDirectories.any { it == resourceDirectory } - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidXmlVisitor.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidXmlVisitor.kt deleted file mode 100644 index 20c02294edd..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/AndroidXmlVisitor.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea - -import com.intellij.psi.PsiElement -import com.intellij.psi.XmlElementVisitor -import com.intellij.psi.xml.XmlAttribute -import com.intellij.psi.xml.XmlElement -import com.intellij.psi.xml.XmlTag -import org.jetbrains.kotlin.android.synthetic.AndroidConst -import org.jetbrains.kotlin.android.synthetic.androidIdToName -import org.jetbrains.kotlin.android.synthetic.isWidgetTypeIgnored -import org.jetbrains.kotlin.android.synthetic.res.ResourceIdentifier - -class AndroidXmlVisitor(val elementCallback: (ResourceIdentifier, String, XmlAttribute) -> Unit) : XmlElementVisitor() { - - override fun visitElement(element: PsiElement) { - element.acceptChildren(this) - } - - override fun visitXmlElement(element: XmlElement?) { - element?.acceptChildren(this) - } - - override fun visitXmlTag(tag: XmlTag?) { - val localName = tag?.localName ?: "" - if (isWidgetTypeIgnored(localName)) { - tag?.acceptChildren(this) - return - } - - val idAttribute = tag?.getAttribute(AndroidConst.ID_ATTRIBUTE_NO_NAMESPACE, AndroidConst.ANDROID_NAMESPACE) - if (idAttribute != null) { - val idAttributeValue = idAttribute.value - if (idAttributeValue != null) { - val xmlType = tag.getAttribute(AndroidConst.CLASS_ATTRIBUTE_NO_NAMESPACE)?.value ?: localName - val name = androidIdToName(idAttributeValue) - if (name != null) elementCallback(name, xmlType, idAttribute) - } - } - - tag?.acceptChildren(this) - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/ExperimentalUtils.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/ExperimentalUtils.kt deleted file mode 100644 index cba19870c6d..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/ExperimentalUtils.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.synthetic.idea - -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.module.Module -import kotlinx.android.extensions.CacheImplementation -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.android.model.isAndroidModule -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.ANDROID_COMPILER_PLUGIN_ID -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.EXPERIMENTAL_OPTION -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.ENABLED_OPTION -import org.jetbrains.kotlin.android.synthetic.AndroidCommandLineProcessor.Companion.DEFAULT_CACHE_IMPL_OPTION -import org.jetbrains.kotlin.android.synthetic.AndroidComponentRegistrar.Companion.parseCacheImplementationType -import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption -import org.jetbrains.kotlin.idea.core.unwrapModuleSourceInfo -import org.jetbrains.kotlin.idea.facet.KotlinFacet -import org.jetbrains.kotlin.platform.jvm.isJvm - -private val ANNOTATION_OPTION_PREFIX = "plugin:$ANDROID_COMPILER_PLUGIN_ID:" - -private fun Module.getOptionValueInFacet(option: AbstractCliOption): String? { - val kotlinFacet = KotlinFacet.get(this) ?: return null - val commonArgs = kotlinFacet.configuration.settings.compilerArguments ?: return null - - val prefix = ANNOTATION_OPTION_PREFIX + option.optionName + "=" - - val optionValue = commonArgs.pluginOptions - ?.firstOrNull { it.startsWith(prefix) } - ?.substring(prefix.length) - - return optionValue -} - -private fun isTestMode(module: Module): Boolean { - return ApplicationManager.getApplication().isUnitTestMode && module.isAndroidModule -} - -internal val Module.androidExtensionsIsEnabled: Boolean - get() = isTestMode(this) || getOptionValueInFacet(ENABLED_OPTION) == "true" - -internal fun ModuleInfo.findAndroidModuleInfo() = unwrapModuleSourceInfo()?.takeIf { it.platform.isJvm() } - -internal val ModuleInfo.androidExtensionsIsEnabled: Boolean - get() { - val module = this.findAndroidModuleInfo()?.module ?: return false - return module.androidExtensionsIsEnabled - } - -internal val ModuleInfo.androidExtensionsIsExperimental: Boolean - get() { - val module = this.findAndroidModuleInfo()?.module ?: return false - return module.androidExtensionsIsExperimental - } - -internal val Module.androidExtensionsIsExperimental: Boolean - get() { - if (isTestMode(this)) return true - return getOptionValueInFacet(EXPERIMENTAL_OPTION) == "true" - } - -val ModuleInfo.androidExtensionsGlobalCacheImpl: CacheImplementation - get() { - val module = this.findAndroidModuleInfo()?.module ?: return CacheImplementation.NO_CACHE - return parseCacheImplementationType(module.getOptionValueInFacet(DEFAULT_CACHE_IMPL_OPTION)) - } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidExtensionsExpressionCodegenExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidExtensionsExpressionCodegenExtension.kt deleted file mode 100644 index e253ed0760e..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidExtensionsExpressionCodegenExtension.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.synthetic.idea - -import kotlinx.android.extensions.CacheImplementation -import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension -import org.jetbrains.kotlin.idea.caches.project.getModuleInfo -import org.jetbrains.kotlin.psi.KtElement - -class IDEAndroidExtensionsExpressionCodegenExtension : AbstractAndroidExtensionsExpressionCodegenExtension() { - override fun isExperimental(element: KtElement?) = - element?.getModuleInfo()?.androidExtensionsIsExperimental ?: false - - override fun isEnabled(element: KtElement?) = - element?.getModuleInfo()?.androidExtensionsIsEnabled ?: false - - override fun getGlobalCacheImpl(element: KtElement?) = - element?.getModuleInfo()?.androidExtensionsGlobalCacheImpl ?: CacheImplementation.DEFAULT -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidOnDestroyClassBuilderInterceptorExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidOnDestroyClassBuilderInterceptorExtension.kt deleted file mode 100644 index f8dd4ebd7c4..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/IDEAndroidOnDestroyClassBuilderInterceptorExtension.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2017 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.kotlin.android.synthetic.idea - -import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidOnDestroyClassBuilderInterceptorExtension -import org.jetbrains.kotlin.idea.caches.project.getModuleInfo -import org.jetbrains.kotlin.psi.KtElement - -class IDEAndroidOnDestroyClassBuilderInterceptorExtension : AbstractAndroidOnDestroyClassBuilderInterceptorExtension() { - override fun getGlobalCacheImpl(element: KtElement) = element.getModuleInfo().androidExtensionsGlobalCacheImpl -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt deleted file mode 100644 index 84eee6c5c43..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidLayoutXmlFileManager.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea.res - -import com.intellij.openapi.module.Module -import com.intellij.openapi.roots.ProjectRootModificationTracker -import com.intellij.openapi.vfs.LocalFileSystem -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiManager -import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.util.CachedValue -import com.intellij.psi.util.CachedValueProvider -import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider -import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider.SourceProviderMirror -import org.jetbrains.kotlin.android.synthetic.AndroidConst.SYNTHETIC_PACKAGE_PATH_LENGTH -import org.jetbrains.kotlin.android.synthetic.idea.AndroidPsiTreeChangePreprocessor -import org.jetbrains.kotlin.android.synthetic.idea.AndroidXmlVisitor -import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental -import org.jetbrains.kotlin.android.synthetic.res.* -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance -import java.io.File - -class IDEAndroidLayoutXmlFileManager(val module: Module) : AndroidLayoutXmlFileManager(module.project) { - override val androidModule: AndroidModule? - get() = AndroidModuleInfoProvider.getInstance(module)?.let { getAndroidModuleInfo(it) } - - @Volatile - private var _moduleData: CachedValue? = null - - override fun getModuleData(): AndroidModuleData { - if (androidModule == null) { - _moduleData = null - } - else { - if (_moduleData == null) { - _moduleData = cachedValue(project) { - CachedValueProvider.Result.create( - super.getModuleData(), - getPsiTreeChangePreprocessor(), ProjectRootModificationTracker.getInstance(project)) - } - } - } - return _moduleData?.value ?: AndroidModuleData.EMPTY - } - - private fun getPsiTreeChangePreprocessor(): PsiTreeChangePreprocessor { - return project.getExtensions(PsiTreeChangePreprocessor.EP_NAME).firstIsInstance() - } - - override fun doExtractResources(layoutGroup: AndroidLayoutGroupData, module: ModuleDescriptor): AndroidLayoutGroup { - val psiManager = PsiManager.getInstance(project) - val layouts = layoutGroup.layouts.map { psiFile -> - // Sometimes due to a race of later-invoked runnables, the PsiFile can be invalidated; make sure to refresh if possible, - val layout = if (psiFile.isValid) psiFile else psiManager.findFileSafe(psiFile.virtualFile) - - val resources = arrayListOf() - layout?.accept(AndroidXmlVisitor { id, widgetType, attribute -> - resources += parseAndroidResource(id, widgetType, attribute.valueElement) - }) - AndroidLayout(resources) - } - - return AndroidLayoutGroup(layoutGroup.name, layouts) - } - - private fun PsiManager.findFileSafe(virtualFile: VirtualFile): PsiFile? { - if (virtualFile.isValid) - return findFile(virtualFile) - - return null - } - - override fun propertyToXmlAttributes(propertyDescriptor: PropertyDescriptor): List { - val fqPath = propertyDescriptor.fqNameUnsafe.pathSegments() - if (fqPath.size <= SYNTHETIC_PACKAGE_PATH_LENGTH) return listOf() - - fun handle(variantData: AndroidVariantData, defaultVariant: Boolean = false): List? { - val layoutNamePosition = SYNTHETIC_PACKAGE_PATH_LENGTH + (if (defaultVariant) 0 else 1) - val layoutName = fqPath[layoutNamePosition].asString() - - val layoutFiles = variantData.layouts[layoutName] ?: return null - if (layoutFiles.isEmpty()) return null - - val propertyName = propertyDescriptor.name.asString() - - val attributes = arrayListOf() - val visitor = AndroidXmlVisitor { retId, _, valueElement -> - if (retId.name == propertyName) attributes.add(valueElement) - } - - layoutFiles.forEach { it.accept(visitor) } - return attributes - } - - for (variantData in getModuleData().variants) { - if (variantData.variant.isMainVariant && fqPath.size == SYNTHETIC_PACKAGE_PATH_LENGTH + 2) { - handle(variantData, true)?.let { return it } - } - else if (fqPath[SYNTHETIC_PACKAGE_PATH_LENGTH].asString() == variantData.variant.name) { - handle(variantData)?.let { return it } - } - } - - return listOf() - } - - private fun SourceProviderMirror.toVariant() = AndroidVariant(name, resDirectories.map { it.canonicalPath }) - - private fun getAndroidModuleInfo(androidInfoProvider: AndroidModuleInfoProvider): AndroidModule? { - if (androidInfoProvider.module.androidExtensionsIsExperimental) { - return getAndroidModuleInfoExperimental(androidInfoProvider) - } - - val applicationPackage = androidInfoProvider.getApplicationPackage() - - if (applicationPackage != null) { - val mainVariant = androidInfoProvider.getMainSourceProvider()?.toVariant() - val variantsForFlavorts = androidInfoProvider.getFlavorSourceProviders().map { it.toVariant() } - val allVariants = listOfNotNull(mainVariant) + variantsForFlavorts - - if (allVariants.isNotEmpty()) { - return AndroidModule(applicationPackage, allVariants) - } - } - return null - } - - private fun getAndroidModuleInfoExperimental(androidFacet: AndroidModuleInfoProvider): AndroidModule? { - val applicationPackage = androidFacet.getApplicationPackage() ?: return null - val appResourceDirectories = androidFacet.getApplicationResourceDirectories(true).mapNotNull { it.canonicalPath } - - val resDirectoriesForMainVariant = androidFacet.run { - val resDirsFromSourceProviders = androidFacet.getAllSourceProviders() - .filter { it.name != "main" } - .flatMap { it.resDirectories } - .map { it.canonicalPath } - - appResourceDirectories - resDirsFromSourceProviders - } - - val variants = mutableListOf(AndroidVariant("main", resDirectoriesForMainVariant)) - - androidFacet.getActiveSourceProviders() - .filter { it.name != "main" } - .forEach { sourceProvider -> variants += sourceProvider.toVariant() } - - return AndroidModule(applicationPackage, variants) - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidPackageFragmentProviderExtension.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidPackageFragmentProviderExtension.kt deleted file mode 100644 index cd558ebdc91..00000000000 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/synthetic/idea/res/IDEAndroidPackageFragmentProviderExtension.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.android.synthetic.idea.res - -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleServiceManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.ClearableLazyValue -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider -import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsEnabled -import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental -import org.jetbrains.kotlin.android.synthetic.idea.findAndroidModuleInfo -import org.jetbrains.kotlin.android.synthetic.res.AndroidLayoutXmlFileManager -import org.jetbrains.kotlin.android.synthetic.res.AndroidPackageFragmentProviderExtension - -class IDEAndroidPackageFragmentProviderExtension(val project: Project) : AndroidPackageFragmentProviderExtension() { - override fun isExperimental(moduleInfo: ModuleInfo?): Boolean { - return moduleInfo?.androidExtensionsIsExperimental ?: false - } - - override fun getLayoutXmlFileManager(project: Project, moduleInfo: ModuleInfo?): AndroidLayoutXmlFileManager? { - val module = moduleInfo?.findAndroidModuleInfo()?.module ?: return null - if (!isAndroidExtensionsEnabled(module)) return null - return ModuleServiceManager.getService(module, AndroidLayoutXmlFileManager::class.java) - } - - private fun isAndroidExtensionsEnabled(module: Module): Boolean { - // Android Extensions should be always enabled for Android/JPS - if (isLegacyIdeaAndroidModule(module)) return true - return module.androidExtensionsIsEnabled - } - - private fun isLegacyIdeaAndroidModule(module: Module): Boolean { - val infoProvider = AndroidModuleInfoProvider.getInstance(module) ?: return false - return infoProvider.isAndroidModule() && !infoProvider.isGradleModule() - } - - override fun createLazyValue(value: () -> T): () -> T { - return { ClearableLazyValue.create { value() }.value } - } -} \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/AndroidManifest.xml b/plugins/android-extensions/android-extensions-idea/testData/android/AndroidManifest.xml deleted file mode 100644 index c82007dcc87..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt deleted file mode 100644 index 3dcff3a1875..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/fqNameInAttr.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.myapp - -import android.app.Activity -import kotlinx.android.synthetic.main.layout.* - -class MyActivity: Activity() { - val button = this.MyBu -} - -// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/res/layout/layout.xml b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/res/layout/layout.xml deleted file mode 100644 index a0ef9f3a1ed..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttr/res/layout/layout.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt deleted file mode 100644 index b5b2448af2f..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/fqNameInAttrFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.myapp - -import android.app.Fragment -import kotlinx.android.synthetic.main.layout.* - -class MyFragment: Fragment() { - val button = this.MyBu -} - -// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/res/layout/layout.xml b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/res/layout/layout.xml deleted file mode 100644 index a0ef9f3a1ed..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInAttrFragment/res/layout/layout.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt deleted file mode 100644 index 3dcff3a1875..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/fqNameInTag.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.myapp - -import android.app.Activity -import kotlinx.android.synthetic.main.layout.* - -class MyActivity: Activity() { - val button = this.MyBu -} - -// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/res/layout/layout.xml b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/res/layout/layout.xml deleted file mode 100644 index 2ec85364e74..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTag/res/layout/layout.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt deleted file mode 100644 index b5b2448af2f..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/fqNameInTagFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.myapp - -import android.app.Fragment -import kotlinx.android.synthetic.main.layout.* - -class MyFragment: Fragment() { - val button = this.MyBu -} - -// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/res/layout/layout.xml b/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/res/layout/layout.xml deleted file mode 100644 index 2ec85364e74..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/fqNameInTagFragment/res/layout/layout.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt deleted file mode 100644 index 4a169c10800..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/multiFile.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.myapp - -import android.app.Activity -import kotlinx.android.synthetic.main.layout.* -import kotlinx.android.synthetic.main.layout1.* - -class MyActivity: Activity() { - val button = log -} - -// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" } -// EXIST: { lookupString:"loginButton", tailText: " from layout1.xml for Activity (Android Extensions)", typeText:"Button!" } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/res/layout/layout.xml b/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/res/layout/layout.xml deleted file mode 100644 index f4736f6937b..00000000000 --- a/plugins/android-extensions/android-extensions-idea/testData/android/completion/multiFile/res/layout/layout.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -