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