Remove code that was migrated to android studio repo.
This commit is contained in:
committed by
Alexander Udalov
parent
6f17a8713c
commit
5147a9e42d
@@ -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()
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
org.jetbrains.kotlin.android.synthetic.idea.AndroidExtensionsModelBuilderService
|
|
||||||
-43
@@ -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)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-61
@@ -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<PsiReference, ReferencesSearch.SearchParameters>(true) {
|
|
||||||
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
|
|
||||||
val elementToSearch = queryParameters.elementToSearch as? XmlAttributeValue ?: return
|
|
||||||
val scopeElements = (queryParameters.effectiveSearchScope as? LocalSearchScope)?.scope ?: return
|
|
||||||
val referenceName = elementToSearch.value?.substringAfterLast("/") ?: return
|
|
||||||
|
|
||||||
scopeElements.filterIsInstance<KtElement>().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
|
|
||||||
}
|
|
||||||
-64
@@ -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<AndroidModuleInfoProvider>("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<Module> {
|
|
||||||
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<SourceProviderMirror>
|
|
||||||
fun getAllResourceDirectories(): List<VirtualFile>
|
|
||||||
|
|
||||||
// For experimental Android Extensions
|
|
||||||
fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection<VirtualFile>
|
|
||||||
fun getAllSourceProviders(): List<SourceProviderMirror>
|
|
||||||
fun getActiveSourceProviders(): List<SourceProviderMirror>
|
|
||||||
|
|
||||||
|
|
||||||
interface SourceProviderMirror {
|
|
||||||
val name: String
|
|
||||||
val resDirectories: Collection<File>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-78
@@ -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<VirtualFile> {
|
|
||||||
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<VirtualFile> {
|
|
||||||
return ResourceRepositoryManager.getOrCreateInstance(module)?.getAppResources(createIfNecessary)?.resourceDirs ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAllSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
|
|
||||||
val androidModuleModel = this.androidModuleModel ?: return emptyList()
|
|
||||||
return androidModuleModel.allSourceProviders.map(::SourceProviderMirrorImpl)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getActiveSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
|
|
||||||
val androidModuleModel = this.androidModuleModel ?: return emptyList()
|
|
||||||
return androidModuleModel.activeSourceProviders.map(::SourceProviderMirrorImpl)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFlavorSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
|
|
||||||
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<SourceProvider>
|
|
||||||
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<File>
|
|
||||||
get() = sourceProvider.resDirectories
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-17
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-28
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-101
@@ -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<DeclarationDescriptor?>
|
|
||||||
): 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<DeclarationDescriptor?>,
|
|
||||||
containingDeclaration: KtUltraLightClass,
|
|
||||||
fieldsList: MutableList<KtLightField>
|
|
||||||
) {
|
|
||||||
|
|
||||||
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<DeclarationDescriptor?>,
|
|
||||||
containingDeclaration: KtUltraLightClass,
|
|
||||||
methodsList: MutableList<KtLightMethod>
|
|
||||||
) {
|
|
||||||
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-53
@@ -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<T: KtElement>(element: T) : KotlinQuickFixAction<T>(element) {
|
|
||||||
protected companion object {
|
|
||||||
fun <T : KtElement> 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 <reified T: KtElement> Diagnostic.findElement() = psiElement.getNonStrictParentOfType<T>()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createAction(diagnostic: Diagnostic) = f(diagnostic)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-39
@@ -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<KtClassOrObject>(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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-287
@@ -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<KtClass>(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<KtObjectDeclaration, ClassDescriptor>? {
|
|
||||||
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<KtProperty>()
|
|
||||||
.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<KtNamedFunction>().firstOrNull(f)
|
|
||||||
|
|
||||||
private fun KtTypeReference.getFqName(): String? = analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]
|
|
||||||
?.constructor?.declarationDescriptor?.fqNameSafe?.asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
object FactoryForWrite : AbstractFactory({ findElement<KtClass>()?.let { ParcelMigrateToParcelizeQuickFix(it) } })
|
|
||||||
|
|
||||||
object FactoryForCREATOR : AbstractFactory({
|
|
||||||
findElement<KtObjectDeclaration>()?.getStrictParentOfType<KtClass>()?.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 ?: "<unnamed Parcelable class>"}")
|
|
||||||
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<KtProperty>().filter { it.name == "CREATOR" }) {
|
|
||||||
if (property.findAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) != null) {
|
|
||||||
property.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-34
@@ -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<KtProperty>(property) {
|
|
||||||
object Factory : AbstractFactory(f@ {
|
|
||||||
// KtProperty or its name identifier
|
|
||||||
psiElement as? KtProperty ?: (psiElement.parent as? KtProperty) ?: return@f null
|
|
||||||
findElement<KtProperty>()?.let(::ParcelRemoveCustomCreatorProperty)
|
|
||||||
})
|
|
||||||
|
|
||||||
override fun getText() = "Remove custom ''CREATOR'' property"
|
|
||||||
|
|
||||||
override fun invoke(ktPsiFactory: KtPsiFactory, element: KtProperty) {
|
|
||||||
element.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-29
@@ -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<KtFunction>(function) {
|
|
||||||
object Factory : AbstractFactory({ findElement<KtFunction>()?.let(::ParcelRemoveCustomWriteToParcel) })
|
|
||||||
override fun getText() = "Remove custom ''writeToParcel()'' function"
|
|
||||||
|
|
||||||
override fun invoke(ktPsiFactory: KtPsiFactory, element: KtFunction) {
|
|
||||||
element.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-30
@@ -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<KtProperty>(property) {
|
|
||||||
object Factory : AbstractFactory({ findElement<KtProperty>()?.let(::ParcelableAddIgnoreOnParcelAnnotationQuickfix) })
|
|
||||||
override fun getText() = "Add ''@IgnoredOnParcel'' annotation"
|
|
||||||
|
|
||||||
override fun invoke(ktPsiFactory: KtPsiFactory, element: KtProperty) {
|
|
||||||
element.addAnnotationEntry(ktPsiFactory.createAnnotationEntry("@" + IgnoredOnParcel::class.java.name)).shortenReferences()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-38
@@ -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<KtClass>(clazz) {
|
|
||||||
object Factory : AbstractFactory({ findElement<KtClass>()?.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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-30
@@ -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<KtClassOrObject>(clazz) {
|
|
||||||
object Factory : AbstractFactory({ findElement<KtClassOrObject>()?.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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-43
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-30
@@ -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<KtAnnotationEntry>(anno) {
|
|
||||||
object Factory : AbstractFactory({ findElement<KtAnnotationEntry>()?.let(::ParcelableRemoveDuplicatingTypeParcelerAnnotationQuickFix) })
|
|
||||||
|
|
||||||
override fun getText() = "Remove redundant ''@TypeParceler'' annotation"
|
|
||||||
|
|
||||||
override fun invoke(ktPsiFactory: KtPsiFactory, element: KtAnnotationEntry) {
|
|
||||||
element.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-144
@@ -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<ModuleData>.hasAndroidExtensionsPlugin: Boolean
|
|
||||||
by NotNullableCopyableDataNodeUserDataProperty(Key.create<Boolean>("HAS_ANDROID_EXTENSIONS_PLUGIN"), false)
|
|
||||||
|
|
||||||
var DataNode<ModuleData>.isExperimental: Boolean
|
|
||||||
by NotNullableCopyableDataNodeUserDataProperty(Key.create<Boolean>("ANDROID_EXTENSIONS_IS_EXPERIMENTAL"), false)
|
|
||||||
|
|
||||||
private const val DEFAULT_CACHE_IMPLEMENTATION_DEFAULT_VALUE = "hashMap"
|
|
||||||
|
|
||||||
var DataNode<ModuleData>.defaultCacheImplementation: String
|
|
||||||
by NotNullableCopyableDataNodeUserDataProperty(Key.create<String>("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<ModuleData>) {
|
|
||||||
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<GradleSourceSetData>) {
|
|
||||||
val module = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE) ?: return
|
|
||||||
importByModule(facet, module)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun importByModule(facet: KotlinFacet, moduleNode: DataNode<ModuleData>) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-24
@@ -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
|
|
||||||
}
|
|
||||||
-60
@@ -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<PsiElement>? {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-68
@@ -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<in CallableDescriptor>,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
receiverTypes: Collection<KotlinType>,
|
|
||||||
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<in CallableDescriptor>,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
receiverTypes: Collection<KotlinType>,
|
|
||||||
nameFilter: (String) -> Boolean
|
|
||||||
) {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-133
@@ -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<VirtualFile> {
|
|
||||||
val module = androidModule ?: return listOf()
|
|
||||||
val fileManager = VirtualFileManager.getInstance()
|
|
||||||
|
|
||||||
return module.variants.fold(arrayListOf<VirtualFile>()) { 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-75
@@ -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 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-58
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-80
@@ -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))
|
|
||||||
}
|
|
||||||
-33
@@ -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
|
|
||||||
}
|
|
||||||
-25
@@ -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
|
|
||||||
}
|
|
||||||
-168
@@ -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<AndroidModuleData>? = 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<AndroidPsiTreeChangePreprocessor>()
|
|
||||||
}
|
|
||||||
|
|
||||||
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<AndroidResource>()
|
|
||||||
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<PsiElement> {
|
|
||||||
val fqPath = propertyDescriptor.fqNameUnsafe.pathSegments()
|
|
||||||
if (fqPath.size <= SYNTHETIC_PACKAGE_PATH_LENGTH) return listOf()
|
|
||||||
|
|
||||||
fun handle(variantData: AndroidVariantData, defaultVariant: Boolean = false): List<PsiElement>? {
|
|
||||||
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<PsiElement>()
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-56
@@ -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 <T> createLazyValue(value: () -> T): () -> T {
|
|
||||||
return { ClearableLazyValue.create<T> { value() }.value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="com.myapp"
|
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0" >
|
|
||||||
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyBu<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" }
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyBu<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" }
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyBu<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"View!" }
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyBu<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"MyButton", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"View!" }
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-12
@@ -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<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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!" }
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
import kotlinx.android.synthetic.main.layout1.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = log<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"login", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"Button!" }
|
|
||||||
// EXIST: { lookupString:"loginButton", tailText: " from layout1.xml for Fragment (Android Extensions)", typeText:"Button!" }
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" }
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"login", tailText: " from layout.xml for Fragment (Android Extensions)", typeText:"Button!" }
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import kotlinx.android.synthetic.main.layout.view.*
|
|
||||||
|
|
||||||
fun View.a() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"login", tailText: " from layout.xml for View (Android Extensions)", typeText:"Button!" }
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" >
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXIST: { lookupString:"login", tailText: " from layout.xml for Activity (Android Extensions)", typeText:"Button!" }
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
// SUGGESTED_NAMES: view, getButton
|
|
||||||
// SUGGESTED_RETURN_TYPES: android.view.View?, android.view.View
|
|
||||||
// PARAM_DESCRIPTOR: public final class MyActivity : android.app.Activity defined in test in file toTopLevelFun.kt
|
|
||||||
// PARAM_TYPES: test.MyActivity, android.app.Activity
|
|
||||||
|
|
||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
// SIBLING:
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
fun test() {
|
|
||||||
val button = <selection>MyButton</selection>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
// SUGGESTED_NAMES: view, getButton
|
|
||||||
// SUGGESTED_RETURN_TYPES: android.view.View?, android.view.View
|
|
||||||
// PARAM_DESCRIPTOR: public final class MyActivity : android.app.Activity defined in test in file toTopLevelFun.kt
|
|
||||||
// PARAM_TYPES: test.MyActivity, android.app.Activity
|
|
||||||
|
|
||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.view.View
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
// SIBLING:
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
fun test() {
|
|
||||||
val button = view()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MyActivity.view(): View? = MyButton
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
val button1 = this.loginButton
|
|
||||||
}
|
|
||||||
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
val button1 = this.loginButton
|
|
||||||
}
|
|
||||||
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
Vendored
-14
@@ -1,14 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyActivity : Activity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {}
|
|
||||||
val button = login<caret>
|
|
||||||
|
|
||||||
fun f() = login.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyFragemnt : Fragment() {
|
|
||||||
override fun onResume() {}
|
|
||||||
val button = login<caret>
|
|
||||||
|
|
||||||
fun f() = login.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import kotlinx.android.synthetic.main.layout.view.*
|
|
||||||
|
|
||||||
fun View.a() {
|
|
||||||
val button = login<caret>
|
|
||||||
}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@android:id/text1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyActivity : Activity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {}
|
|
||||||
val button = login<caret>
|
|
||||||
|
|
||||||
fun f() = login.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyActivity : Activity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {}
|
|
||||||
val button = login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
a:id="@+id/item_detail_container"
|
|
||||||
a:layout_width="match_parent"
|
|
||||||
a:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
a:id="@+id/login"
|
|
||||||
a:layout_width="match_parent"
|
|
||||||
a:layout_height="wrap_content"
|
|
||||||
a:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="org.my.cool.Button"
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
Vendored
-9
@@ -1,9 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.MyButton<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
<org.my.cool.Button
|
|
||||||
android:id="@+id/MyButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
Vendored
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyActivity: Activity() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
val button1 = this.loginButton
|
|
||||||
}
|
|
||||||
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
class MyFragment: Fragment() {
|
|
||||||
val button = this.login<caret>
|
|
||||||
val button1 = this.loginButton
|
|
||||||
}
|
|
||||||
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/frameLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/passwordField"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Enter your password" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/passwordCaption"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPassword" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/loginButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyActivity : Activity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {}
|
|
||||||
val button = login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
package com.myapp
|
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import java.io.File
|
|
||||||
import kotlinx.android.synthetic.main.layout.*
|
|
||||||
|
|
||||||
public class MyFragment : Fragment() {
|
|
||||||
override fun onResume() {}
|
|
||||||
val button = login<caret>
|
|
||||||
}
|
|
||||||
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/item_detail_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ItemDetailActivity"
|
|
||||||
tools:ignore="MergeRootFrame" >
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/login"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Sign in" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user