idea: cleanup code

This commit is contained in:
Dmitry Gridin
2019-12-13 22:11:25 +07:00
parent e77d8657f4
commit 8dbbd64beb
897 changed files with 13161 additions and 18514 deletions
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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
@@ -63,8 +52,7 @@ fun parse(lineText: String, reader: OutputLineReader, messages: MutableList<Mess
}
return addMessage(createMessage(getMessageKind(severity), message), messages)
}
else {
} else {
return addMessage(createMessage(getMessageKind(severity), lineWoSeverity.amendNextLinesIfNeeded(reader)), messages)
}
}
@@ -91,8 +79,7 @@ private fun String.amendNextLinesIfNeeded(reader: OutputLineReader): String {
// This code is needed for compatibility with AS 2.0 and IDEA 15.0, because of difference in android plugins
val positionField = try {
reader::class.java.getDeclaredField("myPosition")
}
catch(e: Throwable) {
} catch (e: Throwable) {
null
}
if (positionField != null) {
@@ -107,9 +94,9 @@ private fun String.amendNextLinesIfNeeded(reader: OutputLineReader): String {
private fun String.isNextMessage(): Boolean {
val colonIndex1 = indexOf(COLON)
return colonIndex1 == 0
|| (colonIndex1 >= 0 && substring(0, colonIndex1).startsWithSeverityPrefix()) // Next Kotlin message
|| StringUtil.containsIgnoreCase(this, "FAILURE")
|| StringUtil.containsIgnoreCase(this, "FAILED")
|| (colonIndex1 >= 0 && substring(0, colonIndex1).startsWithSeverityPrefix()) // Next Kotlin message
|| StringUtil.containsIgnoreCase(this, "FAILURE")
|| StringUtil.containsIgnoreCase(this, "FAILED")
}
private fun String.startsWithSeverityPrefix() = getMessageKind(this) != Message.Kind.UNKNOWN
@@ -130,7 +117,7 @@ private fun Int.skipDriveOnWin(line: String): Int {
}
private val KAPT_ERROR_WHILE_ANNOTATION_PROCESSING_MARKER_TEXT =
KaptError::class.java.canonicalName + ": " + KaptError.Kind.ERROR_RAISED.message
KaptError::class.java.canonicalName + ": " + KaptError.Kind.ERROR_RAISED.message
private fun isKaptErrorWhileAnnotationProcessing(message: Message): Boolean {
if (message.kind != Message.Kind.ERROR) return false
@@ -138,7 +125,7 @@ private fun isKaptErrorWhileAnnotationProcessing(message: Message): Boolean {
val messageText = message.text
return messageText.startsWith(IllegalStateException::class.java.name)
&& messageText.contains(KAPT_ERROR_WHILE_ANNOTATION_PROCESSING_MARKER_TEXT)
&& messageText.contains(KAPT_ERROR_WHILE_ANNOTATION_PROCESSING_MARKER_TEXT)
}
private fun addMessage(message: Message, messages: MutableList<Message>): Boolean {
@@ -1,17 +1,6 @@
/*
* 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.
* 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
@@ -45,11 +34,13 @@ class AndroidResourceReferenceAnnotator : Annotator {
val referenceType = referenceTarget.getResourceReferenceType()
val configuration = pickConfiguration(androidFacet, androidFacet.module, element.containingFile) ?: return
val resourceValue = findResourceValue(resourceType,
reference.text,
referenceType == FRAMEWORK,
androidFacet.module,
configuration) ?: return
val resourceValue = findResourceValue(
resourceType,
reference.text,
referenceType == FRAMEWORK,
androidFacet.module,
configuration
) ?: return
val resourceResolver = configuration.resourceResolver ?: return
@@ -59,8 +50,7 @@ class AndroidResourceReferenceAnnotator : Annotator {
val annotation = holder.createInfoAnnotation(element, null)
annotation.gutterIconRenderer = ColorRenderer(element, color)
}
}
else {
} else {
var file = ResourceHelper.resolveDrawable(resourceResolver, resourceValue, element.project)
if (file != null && file.path.endsWith(SdkConstants.DOT_XML)) {
file = pickBitmapFromXml(file, resourceResolver, element.project)
@@ -74,5 +64,5 @@ class AndroidResourceReferenceAnnotator : Annotator {
}
private fun KtReferenceExpression.getResourceReferenceTargetDescriptor(): JavaPropertyDescriptor? =
resolveToCall()?.resultingDescriptor as? JavaPropertyDescriptor
resolveToCall()?.resultingDescriptor as? JavaPropertyDescriptor
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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
@@ -86,8 +75,7 @@ internal fun JavaPropertyDescriptor.getResourceReferenceType(): AndroidPsiUtils.
if (R_CLASS == rClass.name.asString()) {
return if ((rClass.containingDeclaration as? PackageFragmentDescriptor)?.fqName?.asString() == ANDROID_PKG) {
FRAMEWORK
}
else {
} else {
APP
}
}
@@ -95,11 +83,13 @@ internal fun JavaPropertyDescriptor.getResourceReferenceType(): AndroidPsiUtils.
return NONE
}
internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression: KtSimpleNameExpression, localOnly: Boolean)
= getReferredResourceOrManifestField(facet, expression, null, localOnly)
internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression: KtSimpleNameExpression, localOnly: Boolean) =
getReferredResourceOrManifestField(facet, expression, null, localOnly)
internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression: KtSimpleNameExpression,
className: String?, localOnly: Boolean): AndroidResourceUtil.MyReferredResourceFieldInfo? {
internal fun getReferredResourceOrManifestField(
facet: AndroidFacet, expression: KtSimpleNameExpression,
className: String?, localOnly: Boolean
): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val resFieldName = expression.getReferencedName()
val resClassReference = expression.getPreviousInQualifiedChain() as? KtSimpleNameExpression ?: return null
val resClassName = resClassReference.getReferencedName()
@@ -110,7 +100,7 @@ internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression:
val rClassReference = resClassReference.getPreviousInQualifiedChain() as? KtSimpleNameExpression ?: return null
val rClassDescriptor = rClassReference.analyze(BodyResolveMode.PARTIAL)
.get(BindingContext.REFERENCE_TARGET, rClassReference) as? ClassDescriptor ?: return null
.get(BindingContext.REFERENCE_TARGET, rClassReference) as? ClassDescriptor ?: return null
val rClassShortName = rClassDescriptor.name.asString()
val fromManifest = AndroidUtils.MANIFEST_CLASS_NAME == rClassShortName
@@ -1,17 +1,6 @@
/*
* 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.
* 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
@@ -62,24 +51,26 @@ class KotlinAndroidLineMarkerProvider : LineMarkerProvider {
}
return LineMarkerInfo(
nameIdentifier,
nameIdentifier.textRange,
AllIcons.FileTypes.Xml,
Pass.LINE_MARKERS,
Function { "Related XML file" },
GutterIconNavigationHandler { e: MouseEvent, _: PsiElement ->
NavigationUtil
.getRelatedItemsPopup(
manifestItems + collectGoToRelatedLayoutItems(androidFacet),
"Go to Related Files")
.show(RelativePoint(e))
},
GutterIconRenderer.Alignment.RIGHT)
nameIdentifier,
nameIdentifier.textRange,
AllIcons.FileTypes.Xml,
Pass.LINE_MARKERS,
Function { "Related XML file" },
GutterIconNavigationHandler { e: MouseEvent, _: PsiElement ->
NavigationUtil
.getRelatedItemsPopup(
manifestItems + collectGoToRelatedLayoutItems(androidFacet),
"Go to Related Files"
)
.show(RelativePoint(e))
},
GutterIconRenderer.Alignment.RIGHT
)
}
private fun KtClass.collectGoToRelatedLayoutItems(androidFacet: AndroidFacet): List<GotoRelatedItem> {
val resources = mutableSetOf<PsiFile>()
accept(object: KtVisitorVoid() {
accept(object : KtVisitorVoid() {
override fun visitKtElement(element: KtElement) {
element.acceptChildren(this)
}
@@ -96,11 +87,8 @@ class KotlinAndroidLineMarkerProvider : LineMarkerProvider {
return
}
val files = ModuleResourceManagers
.getInstance(androidFacet)
.localResourceManager
.findResourcesByFieldName(resClassName, info.fieldName)
.filterIsInstance<PsiFile>()
val files = ModuleResourceManagers.getInstance(androidFacet).localResourceManager
.findResourcesByFieldName(resClassName, info.fieldName).filterIsInstance<PsiFile>()
resources.addAll(files)
}
@@ -110,7 +98,7 @@ class KotlinAndroidLineMarkerProvider : LineMarkerProvider {
}
private fun KtClass.collectGoToRelatedManifestItems(manifest: Manifest): List<GotoRelatedItem> =
findComponentDeclarationInManifest(manifest)?.xmlAttributeValue?.let { listOf(GotoManifestItem(it)) } ?: emptyList()
findComponentDeclarationInManifest(manifest)?.xmlAttributeValue?.let { listOf(GotoManifestItem(it)) } ?: emptyList()
private class GotoManifestItem(attributeValue: XmlAttributeValue) : GotoRelatedItem(attributeValue) {
override fun getCustomName(): String? = "AndroidManifest.xml"
@@ -124,10 +112,11 @@ class KotlinAndroidLineMarkerProvider : LineMarkerProvider {
companion object {
private val CLASSES_WITH_LAYOUT_XML = arrayOf(
SdkConstants.CLASS_ACTIVITY,
SdkConstants.CLASS_FRAGMENT,
SdkConstants.CLASS_V4_FRAGMENT,
"android.widget.Adapter")
SdkConstants.CLASS_ACTIVITY,
SdkConstants.CLASS_FRAGMENT,
SdkConstants.CLASS_V4_FRAGMENT,
"android.widget.Adapter"
)
private fun KtClass.isClassWithLayoutXml(): Boolean {
val type = (unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) as? ClassDescriptor)?.defaultType ?: return false
@@ -1,17 +1,6 @@
/*
* 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.
* 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
@@ -44,8 +33,7 @@ import org.jetbrains.kotlin.types.KotlinType
private val CREATOR_NAME = "CREATOR"
private val PARCEL_NAME = "parcel"
private val CREATOR_TEXT =
"companion object $CREATOR_NAME : android.os.Parcelable.Creator<%1\$s> {\n" +
private val CREATOR_TEXT = "companion object $CREATOR_NAME : android.os.Parcelable.Creator<%1\$s> {\n" +
" override fun createFromParcel($PARCEL_NAME: $CLASS_PARCEL): %1\$s {\n" +
" return %1\$s($PARCEL_NAME)\n" +
" }\n\n" +
@@ -56,7 +44,7 @@ private val CREATOR_TEXT =
private val WRITE_TO_PARCEL_TEXT = "override fun writeToParcel($PARCEL_NAME: $CLASS_PARCEL, flags: Int) {\n}"
private val WRITE_TO_PARCEL_SUPER_CALL_TEXT = "super.writeToParcel($PARCEL_NAME, flags)"
private val WRITE_TO_PARCEL_WITH_SUPER_TEXT =
"override fun writeToParcel($PARCEL_NAME: $CLASS_PARCEL, flags: Int) {\n$WRITE_TO_PARCEL_SUPER_CALL_TEXT\n}"
"override fun writeToParcel($PARCEL_NAME: $CLASS_PARCEL, flags: Int) {\n$WRITE_TO_PARCEL_SUPER_CALL_TEXT\n}"
private val DESCRIBE_CONTENTS_TEXT = "override fun describeContents(): Int {\nreturn 0\n}"
private val CONSTRUCTOR_TEXT = "constructor($PARCEL_NAME: $CLASS_PARCEL)"
@@ -65,8 +53,7 @@ private val PARCELIZE_FQNAME = FqName(Parcelize::class.java.name)
//TODO add test
fun KtClass.isParcelize() = findAnnotation(PARCELIZE_FQNAME) != null
fun KtClass.canAddParcelable(): Boolean =
findParcelableSupertype() == null
fun KtClass.canAddParcelable(): Boolean = findParcelableSupertype() == null
|| findCreator() == null
|| findConstructorFromParcel() == null
|| findWriteToParcel() == null
@@ -74,8 +61,7 @@ fun KtClass.canAddParcelable(): Boolean =
fun KtClass.canRedoParcelable(): Boolean = canRemoveParcelable()
fun KtClass.canRemoveParcelable(): Boolean =
findParcelableSupertype()?.takeIf { it.typeReference?.isParcelableReference() ?: false }
fun KtClass.canRemoveParcelable(): Boolean = findParcelableSupertype()?.takeIf { it.typeReference?.isParcelableReference() ?: false }
?: findCreator()
?: findConstructorFromParcel()
?: findWriteToParcel()
@@ -130,7 +116,7 @@ private fun KtClass.findParcelableSupertype(): KtSuperTypeListEntry? = getSuperT
private fun KtSuperTypeList.findParcelable() = entries?.find { it.typeReference?.isParcelableSuccessorReference() ?: false }
private fun KtTypeReference.isParcelableSuccessorReference() =
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.isSubclassOfParcelable() ?: false
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.isSubclassOfParcelable() ?: false
private fun KtClass.superExtendsParcelable() = superTypeListEntries.find { it.typeReference?.extendsParcelable() ?: false } != null
@@ -161,7 +147,8 @@ private fun KtExpression.isReadFromParcelPropertyAssignment(): Boolean {
private fun KtExpression.isReadFromParcel(): Boolean {
val reference = firstChild as? KtReferenceExpression
?: (firstChild as? KtDotQualifiedExpression)?.getLeftMostReceiverExpression() as? KtReferenceExpression ?: return false
?: (firstChild as? KtDotQualifiedExpression)?.getLeftMostReceiverExpression() as? KtReferenceExpression
?: return false
val target = reference.resolveToCall()?.resultingDescriptor ?: return false
return (target as? ParameterDescriptor)?.type?.fqNameEquals(CLASS_PARCEL) ?: false
}
@@ -174,21 +161,17 @@ private fun KtClass.addFieldWrites(function: KtFunction, factory: KtPsiFactory,
val propertyParameterDescriptors = primaryConstructor?.valueParameters?.mapNotNull { it.propertyDescriptor } ?: emptyList()
val propertyDescriptors = declarations
.filter { it.isParcelableProperty() }
.mapNotNull { it.descriptor as? PropertyDescriptor }
val propertyDescriptors = declarations.filter { it.isParcelableProperty() }.mapNotNull { it.descriptor as? PropertyDescriptor }
val parcelName = function.valueParameters[0].name ?: return
val flagsName = function.valueParameters[1].name ?: return
val blockText =
(propertyParameterDescriptors + propertyDescriptors)
.mapNotNull { it.formatWriteToParcel(parcelName, flagsName) }
.joinToString(separator = "\n")
val blockText = (propertyParameterDescriptors + propertyDescriptors).mapNotNull { it.formatWriteToParcel(parcelName, flagsName) }
.joinToString(separator = "\n")
val block = factory.createBlock(
if (callSuper)
WRITE_TO_PARCEL_SUPER_CALL_TEXT + if (blockText.isNotBlank()) "\n$blockText" else ""
else blockText
if (callSuper)
WRITE_TO_PARCEL_SUPER_CALL_TEXT + if (blockText.isNotBlank()) "\n$blockText" else ""
else blockText
)
bodyExpression.replace(block)
@@ -201,16 +184,14 @@ private fun KtClass.addFieldReads(constructor: KtConstructor<*>, factory: KtPsiF
}
val parcelName = constructor.getValueParameters().firstOrNull()?.name ?: return
val parcelableProperties = declarations
.filter { it.isParcelableProperty() }
.mapNotNull { it.descriptor as? PropertyDescriptor }
val parcelableProperties = declarations.filter { it.isParcelableProperty() }.mapNotNull { it.descriptor as? PropertyDescriptor }
if (parcelableProperties.isEmpty()) {
return
}
val blockText = parcelableProperties
.mapNotNull { descriptor -> descriptor.formatReadFromParcel(parcelName)?.let { "${descriptor.name} = $it" } }
val blockText =
parcelableProperties.mapNotNull { descriptor -> descriptor.formatReadFromParcel(parcelName)?.let { "${descriptor.name} = $it" } }
.joinToString(separator = "\n")
val block = factory.createBlock(blockText)
@@ -222,32 +203,28 @@ private fun KtClass.addFieldReads(constructor: KtConstructor<*>, factory: KtPsiF
addNewLineBeforeDeclaration()
addToShorteningWaitSet()
}
}
else {
} else {
bodyExpression?.replace(block) ?: constructor.add(block)
}
}
private fun KtDeclaration.isParcelableProperty(): Boolean =
this is KtProperty && isVar && !hasDelegate() && !isTransient() && getter == null && setter == null
private fun KtDeclaration.isParcelableProperty(): Boolean =
this is KtProperty && isVar && !hasDelegate() && !isTransient() && getter == null && setter == null
private fun KtProperty.isTransient() = annotationEntries.find { it.isTransientAnnotation() } != null
private fun KtAnnotationEntry.isTransientAnnotation(): Boolean =
typeReference?.analyze(BodyResolveMode.PARTIAL)?.get(BindingContext.TYPE, typeReference)?.fqNameEquals("kotlin.jvm.Transient") ?: false
private fun KtExpression.isCallToSuperWriteToParcel() =
this is KtDotQualifiedExpression
private fun KtExpression.isCallToSuperWriteToParcel() = this is KtDotQualifiedExpression
&& receiverExpression is KtSuperExpression
&& (selectorExpression as? KtCallExpression)?.calleeExpression?.text == "writeToParcel"
private fun KtBlockExpression.isEmptyWriteToParcel(callSuper: Boolean): Boolean =
if (callSuper) {
statements.isEmpty() || statements.size == 1 && statements.first().isCallToSuperWriteToParcel()
}
else {
statements.isEmpty()
}
private fun KtBlockExpression.isEmptyWriteToParcel(callSuper: Boolean): Boolean = if (callSuper) {
statements.isEmpty() || statements.size == 1 && statements.first().isCallToSuperWriteToParcel()
} else {
statements.isEmpty()
}
private fun PropertyDescriptor.formatReadFromParcel(parcelName: String): String? {
val type = returnType ?: return null
@@ -301,8 +278,7 @@ private fun PropertyDescriptor.formatWriteToParcel(parcelName: String, flagsName
if (type.isMarkedNullable) {
if (KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType(type)) {
return "$parcelName.writeValue($name)"
}
else if (KotlinBuiltIns.isCharSequenceOrNullableCharSequence(type)) {
} else if (KotlinBuiltIns.isCharSequenceOrNullableCharSequence(type)) {
return "$parcelName.writeString($name?.toString())"
}
}
@@ -373,26 +349,26 @@ private fun KtClass.createSecondaryConstructor(factory: KtPsiFactory): KtConstru
}
val argumentList = arguments.joinToString(
prefix = if (arguments.size > 1) "(\n" else "(",
postfix = ")",
separator = if (arguments.size > 1) ",\n" else ", ")
prefix = if (arguments.size > 1) "(\n" else "(",
postfix = ")",
separator = if (arguments.size > 1) ",\n" else ", "
)
"$CONSTRUCTOR_TEXT :this$argumentList {\n}"
} ?: "$CONSTRUCTOR_TEXT {\n}"
val constructor = factory.createSecondaryConstructor(constructorText)
val constructor = factory.createSecondaryConstructor(constructorText)
val lastProperty = declarations.findLast { it is KtProperty }
return if (lastProperty != null) {
addDeclarationAfter(constructor, lastProperty).apply { addNewLineBeforeDeclaration() }
}
else {
} else {
val firstFunction = declarations.find { it is KtFunction }
addDeclarationBefore(constructor, firstFunction).apply { addNewLineBeforeDeclaration() }
}
}
private fun KtTypeReference.extendsParcelable(): Boolean =
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.isSubclassOfParcelable(true) ?: false
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.isSubclassOfParcelable(true) ?: false
private fun KtClass.findWriteToParcel() = declarations.find { it.isWriteToParcel() }
@@ -415,8 +391,8 @@ private fun KtClass.findOrCreateWriteToParcel(factory: KtPsiFactory, callSuper:
private fun KtClass.findDescribeContents() = declarations.find { it.isDescribeContents() }
private fun KtDeclaration.isDescribeContents(): Boolean = this is KtFunction &&
name == "describeContents" &&
valueParameters.isEmpty()
name == "describeContents" &&
valueParameters.isEmpty()
private fun KtClass.findOrCreateDescribeContents(factory: KtPsiFactory): KtFunction {
findDescribeContents()?.let {
@@ -442,7 +418,7 @@ private fun KtParameter.isParcelParameter(): Boolean = typeReference?.fqNameEqua
private fun KtTypeReference.isParcelableReference() = fqNameEquals(CLASS_PARCELABLE)
private fun KtTypeReference.fqNameEquals(fqName: String) =
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.fqNameEquals(fqName) ?: false
analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, this]?.fqNameEquals(fqName) ?: false
private fun KotlinType.getName() = constructor.declarationDescriptor?.name
@@ -453,25 +429,25 @@ private fun KotlinType.isSubclassOfParcelable(strict: Boolean = false): Boolean
private fun KotlinType.isIBinder(): Boolean = fqNameEquals("android.os.IBinder")
private fun KotlinType.isArrayOfParcelable(): Boolean =
KotlinBuiltIns.isArray(this) && arguments.singleOrNull()?.type?.isSubclassOfParcelable(true) ?: false
KotlinBuiltIns.isArray(this) && arguments.singleOrNull()?.type?.isSubclassOfParcelable(true) ?: false
private fun KotlinType.isArrayOfIBinder(): Boolean =
KotlinBuiltIns.isArray(this) && arguments.singleOrNull()?.type?.isIBinder() ?: false
KotlinBuiltIns.isArray(this) && arguments.singleOrNull()?.type?.isIBinder() ?: false
private fun KotlinType.isArrayOfString(): Boolean =
KotlinBuiltIns.isArray(this) && KotlinBuiltIns.isStringOrNullableString(arguments.singleOrNull()?.type)
KotlinBuiltIns.isArray(this) && KotlinBuiltIns.isStringOrNullableString(arguments.singleOrNull()?.type)
private fun KotlinType.isListOfString(): Boolean =
KotlinBuiltIns.isListOrNullableList(this) && KotlinBuiltIns.isStringOrNullableString(arguments.singleOrNull()?.type)
KotlinBuiltIns.isListOrNullableList(this) && KotlinBuiltIns.isStringOrNullableString(arguments.singleOrNull()?.type)
private fun KotlinType.isListOfParcelable(): Boolean =
KotlinBuiltIns.isListOrNullableList(this) && arguments.singleOrNull()?.type?.isSubclassOfParcelable(true) ?: false
KotlinBuiltIns.isListOrNullableList(this) && arguments.singleOrNull()?.type?.isSubclassOfParcelable(true) ?: false
private fun KotlinType.isListOfIBinder(): Boolean =
KotlinBuiltIns.isListOrNullableList(this) && arguments.singleOrNull()?.type?.isIBinder() ?: false
KotlinBuiltIns.isListOrNullableList(this) && arguments.singleOrNull()?.type?.isIBinder() ?: false
private fun KotlinType.isSparseBooleanArray(): Boolean = fqNameEquals("android.util.SparseBooleanArray")
private fun KotlinType.isBundle(): Boolean = fqNameEquals("android.os.Bundle")
private fun <T: KtDeclaration> T.addNewLineBeforeDeclaration() = parent.addBefore(KtPsiFactory(this).createNewLine(), this)
private fun <T : KtDeclaration> T.addNewLineBeforeDeclaration() = parent.addBefore(KtPsiFactory(this).createNewLine(), this)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -56,8 +56,8 @@ class AndroidGradleModelFacade : KotlinGradleModelFacade {
// com.android.builder.model.Library.getProject() is not present in 2.1.0
private val Library.projectSafe: String?
get() = try {
project
} catch(e: UnsupportedMethodException) {
null
}
get() = try {
project
} catch (e: UnsupportedMethodException) {
null
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.configure
@@ -37,10 +26,10 @@ class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaMod
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_MODULE_MODEL
override fun postProcess(
toImport: MutableCollection<DataNode<JavaModuleModel>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
toImport: MutableCollection<DataNode<JavaModuleModel>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (dataNode in toImport) {
@Suppress("UNCHECKED_CAST")
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -91,11 +91,13 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
val androidModel = getAndroidModuleModel(nodeToImport) ?: continue
val variantName = androidModel.selectedVariant.name
val activeSourceSetInfos = nodeToImport.kotlinAndroidSourceSets?.filter { it.kotlinModule.name.startsWith(variantName) } ?: emptyList()
val activeSourceSetInfos = nodeToImport.kotlinAndroidSourceSets?.filter {
it.kotlinModule.name.startsWith(variantName)
} ?: emptyList()
for (activeSourceSetInfo in activeSourceSetInfos) {
val activeCompilation = activeSourceSetInfo.kotlinModule as? KotlinCompilation ?: continue
for (sourceSet in activeCompilation.sourceSets) {
if (! sourceSet.actualPlatforms.supports(KotlinPlatform.ANDROID)) {
if (!sourceSet.actualPlatforms.supports(KotlinPlatform.ANDROID)) {
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
(it.data as? ModuleData)?.id == sourceSetId
@@ -192,7 +194,8 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
)
addIfNotNull(
relevantNodes.firstOrNull {
(it.kotlinSourceSet?.actualPlatforms?.supports(KotlinPlatform.COMMON) ?: false) && it.kotlinSourceSet?.kotlinModule?.name == commonSourceSetName
(it.kotlinSourceSet?.actualPlatforms?.supports(KotlinPlatform.COMMON) ?: false) && it.kotlinSourceSet
?.kotlinModule?.name == commonSourceSetName
}
)
} else {
@@ -204,15 +207,16 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
}
addAll(
relevantNodes.filter {
(it.kotlinSourceSet?.actualPlatforms?.supports(KotlinPlatform.COMMON) ?: false) && it.kotlinSourceSet?.kotlinModule?.name == commonSourceSetName
(it.kotlinSourceSet?.actualPlatforms?.supports(KotlinPlatform.COMMON) ?: false) && it.kotlinSourceSet
?.kotlinModule?.name == commonSourceSetName
}
)
}
}
val testKotlinModules =
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
.toSet()
val testKotlinModules = gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }
.mapNotNull { modelsProvider.findIdeModule(it.data) }
.toSet()
gradleSourceSetDataNodes.forEach { node ->
val module = modelsProvider.findIdeModule(node.data) ?: return
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2000-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.
*/
@@ -44,8 +44,7 @@ class KotlinAndroidGradleModuleConfigurator internal constructor() : KotlinWithG
val jvmTarget = getJvmTarget(sdk, version)
return if (isTopLevelProjectFile) {
manipulator.configureProjectBuildScript(kotlinPluginName, version)
}
else {
} else {
manipulator.configureModuleBuildScript(
kotlinPluginName,
getKotlinPluginExpression(file.isKtDsl()),
@@ -1,17 +1,6 @@
/*
* 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.
* 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.debugger
@@ -30,23 +19,26 @@ import java.net.URLClassLoader
import java.security.ProtectionDomain
class AndroidDexerImpl(val project: Project) : AndroidDexer {
private val cachedDexWrapper = CachedValuesManager.getManager(project).createCachedValue({
val dexWrapper = doGetAndroidDexFile()?.let { dexJarFile ->
val androidDexWrapperName = AndroidDexWrapper::class.java.canonicalName
val classBytes = this.javaClass.classLoader.getResource(
androidDexWrapperName.replace('.', '/') + ".class").readBytes()
private val cachedDexWrapper = CachedValuesManager.getManager(project).createCachedValue(
{
val dexWrapper = doGetAndroidDexFile()?.let { dexJarFile ->
val androidDexWrapperName = AndroidDexWrapper::class.java.canonicalName
val classBytes = this.javaClass.classLoader.getResource(
androidDexWrapperName.replace('.', '/') + ".class"
).readBytes()
val dexClassLoader = object : URLClassLoader(arrayOf(dexJarFile.toURI().toURL()), this::class.java.classLoader) {
init {
defineClass(androidDexWrapperName, classBytes, 0, classBytes.size, null as ProtectionDomain?)
val dexClassLoader = object : URLClassLoader(arrayOf(dexJarFile.toURI().toURL()), this::class.java.classLoader) {
init {
defineClass(androidDexWrapperName, classBytes, 0, classBytes.size, null as ProtectionDomain?)
}
}
Class.forName(androidDexWrapperName, true, dexClassLoader).newInstance()
}
Class.forName(androidDexWrapperName, true, dexClassLoader).newInstance()
}
CachedValueProvider.Result.createSingleDependency(dexWrapper, ProjectRootModificationTracker.getInstance(project))
}, /* trackValue = */ false)
CachedValueProvider.Result.createSingleDependency(dexWrapper, ProjectRootModificationTracker.getInstance(project))
}, /* trackValue = */ false
)
override fun dex(classes: Collection<ClassToLoad>): ByteArray? {
val dexWrapper = cachedDexWrapper.value
@@ -59,8 +51,8 @@ class AndroidDexerImpl(val project: Project) : AndroidDexer {
val androidFacet = AndroidFacet.getInstance(module) ?: continue
val sdkData = AndroidSdkData.getSdkData(androidFacet) ?: continue
val latestBuildTool = sdkData.getLatestBuildTool(/* allowPreview = */ false)
?: sdkData.getLatestBuildTool(/* allowPreview = */ true)
?: continue
?: sdkData.getLatestBuildTool(/* allowPreview = */ true)
?: continue
val dxJar = File(latestBuildTool.location, "lib/dx.jar")
if (dxJar.exists()) {
@@ -1,17 +1,6 @@
/*
* 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.
* 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.folding
@@ -48,10 +37,12 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
private val FORMAT = Pattern.compile("%(\\d+\\$)?([-+#, 0(<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])")
private val FOLD_MAX_LENGTH = 60
private val UNIT_TEST_MODE: Boolean = ApplicationManager.getApplication().isUnitTestMode
private val RESOURCE_TYPES = listOf(ResourceType.STRING,
ResourceType.DIMEN,
ResourceType.INTEGER,
ResourceType.PLURALS)
private val RESOURCE_TYPES = listOf(
ResourceType.STRING,
ResourceType.DIMEN,
ResourceType.INTEGER,
ResourceType.PLURALS
)
}
private val isFoldingEnabled = AndroidFoldingSettings.getInstance().isCollapseAndroidStrings
@@ -115,10 +106,10 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
private fun UCallExpression.isFoldableGetResourceValueCall(): Boolean {
return methodName == "getString" ||
methodName == "getText" ||
methodName == "getInteger" ||
methodName?.startsWith("getDimension") ?: false ||
methodName?.startsWith("getQuantityString") ?: false
methodName == "getText" ||
methodName == "getInteger" ||
methodName?.startsWith("getDimension") ?: false ||
methodName?.startsWith("getQuantityString") ?: false
}
private fun PsiElement.getAndroidResourceType(): ResourceType? {
@@ -141,8 +132,7 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
if (resourceType == ResourceType.STRING || resourceType == ResourceType.PLURALS) {
return '"' + StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH - 2, 0) + '"'
}
else if (text.length <= 1) {
} else if (text.length <= 1) {
// Don't just inline empty or one-character replacements: they can't be expanded by a mouse click
// so are hard to use without knowing about the folding keyboard shortcut to toggle folding.
// This is similar to how IntelliJ 14 handles call parameters
@@ -153,9 +143,10 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
}
private tailrec fun LocalResourceRepository.getResourceValue(
type: ResourceType,
name: String,
referenceConfig: FolderConfiguration): String? {
type: ResourceType,
name: String,
referenceConfig: FolderConfiguration
): String? {
val value = getConfiguredValue(type, name, referenceConfig)?.value ?: return null
if (!value.startsWith('@')) {
return value
@@ -215,8 +206,7 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
numberString = numberString.substring(0, numberString.length - 1)
number = Integer.parseInt(numberString)
nextNumber = number + 1
}
else {
} else {
number = nextNumber++
}
@@ -237,8 +227,7 @@ class ResourceFoldingBuilder : FoldingBuilderEx() {
sb.append('}')
start = index
}
}
else {
} else {
var i = start
val n = formatString.length
while (i < n) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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.inspection
@@ -82,7 +71,7 @@ class IllegalIdentifierInspection : AbstractKotlinInspection() {
val currentGenerationId = ProjectRootModificationTracker.getInstance(module.project).modificationCount
val junitTestPaths = module.getUserData(JunitPaths)
?.takeIf { it.generationId == currentGenerationId }
?: JunitPaths(getJunitTestPaths(module), currentGenerationId).also { module.putUserData(JunitPaths, it) }
?: JunitPaths(getJunitTestPaths(module), currentGenerationId).also { module.putUserData(JunitPaths, it) }
if (junitTestPaths.paths.any { containingFile.startsWith(it) }) {
return true
@@ -1,17 +1,6 @@
/*
* 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.
* 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.inspection
@@ -30,9 +19,9 @@ import org.jetbrains.kotlin.psi.psiUtil.addTypeArgument
class TypeParameterFindViewByIdInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
val compileSdk = AndroidFacet.getInstance(session.file)
?.let { facet -> AndroidModuleInfo.getInstance(facet) }
?.buildSdkVersion
?.apiLevel
?.let { facet -> AndroidModuleInfo.getInstance(facet) }
?.buildSdkVersion
?.apiLevel
if (compileSdk == null || compileSdk < 26) {
return KtVisitorVoid()
@@ -53,9 +42,10 @@ class TypeParameterFindViewByIdInspection : AbstractKotlinInspection(), CleanupL
}
holder.registerProblem(
parentCast,
"Can be converted to findViewById<$typeText>(...)",
ConvertCastToFindViewByIdWithTypeParameter())
parentCast,
"Can be converted to findViewById<$typeText>(...)",
ConvertCastToFindViewByIdWithTypeParameter()
)
}
}
}
@@ -78,6 +68,6 @@ class TypeParameterFindViewByIdInspection : AbstractKotlinInspection(), CleanupL
companion object {
fun KtTypeReference.getTypeTextWithoutQuestionMark(): String? =
(typeElement as? KtNullableType)?.innerType?.text ?: typeElement?.text
(typeElement as? KtNullableType)?.innerType?.text ?: typeElement?.text
}
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -37,13 +26,13 @@ abstract class AbstractRegisterComponentAction(text: String) : SelfTargetingInte
val androidFacet = AndroidFacet.getInstance(element.containingFile) ?: return false
val manifest = androidFacet.manifest ?: return false
return !element.isLocal &&
!element.isAbstract() &&
!element.isPrivate() &&
!element.isProtected() &&
!element.isInner() &&
!element.name.isNullOrEmpty() &&
!element.insideBody(caretOffset) &&
isApplicableTo(element, manifest)
!element.isAbstract() &&
!element.isPrivate() &&
!element.isProtected() &&
!element.isInner() &&
!element.name.isNullOrEmpty() &&
!element.insideBody(caretOffset) &&
isApplicableTo(element, manifest)
}
final override fun applyTo(element: KtClass, editor: Editor?) {
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -29,7 +18,7 @@ import org.jetbrains.kotlin.asJava.toLightClass
class AddActivityToManifest : AbstractRegisterComponentAction("Add activity to manifest") {
override fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean =
element.isSubclassOfActivity() && !element.isRegisteredActivity(manifest)
element.isSubclassOfActivity() && !element.isRegisteredActivity(manifest)
override fun applyTo(element: KtClass, manifest: Manifest) = runWriteAction {
val psiClass = element.toLightClass() ?: return@runWriteAction
@@ -41,5 +30,5 @@ class AddActivityToManifest : AbstractRegisterComponentAction("Add activity to m
}
private fun KtClass.isSubclassOfActivity() =
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_ACTIVITY, true) ?: false
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_ACTIVITY, true) ?: false
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -41,5 +30,5 @@ class AddBroadcastReceiverToManifest : AbstractRegisterComponentAction("Add broa
}
private fun KtClass.isSubclassOfBroadcastReceiver() =
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_BROADCASTRECEIVER, true) ?: false
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_BROADCASTRECEIVER, true) ?: false
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -29,7 +18,7 @@ import org.jetbrains.kotlin.psi.KtClass
class AddServiceToManifest : AbstractRegisterComponentAction("Add service to manifest") {
override fun isApplicableTo(element: KtClass, manifest: Manifest): Boolean =
element.isSubclassOfService() && !element.isRegisteredService(manifest)
element.isSubclassOfService() && !element.isRegisteredService(manifest)
override fun applyTo(element: KtClass, manifest: Manifest) = runWriteAction {
val psiClass = element.toLightClass() ?: return@runWriteAction
@@ -41,5 +30,5 @@ class AddServiceToManifest : AbstractRegisterComponentAction("Add service to man
}
private fun KtClass.isSubclassOfService() =
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_SERVICE, true) ?: false
(descriptor as? ClassDescriptor)?.defaultType?.isSubclassOf(SdkConstants.CLASS_SERVICE, true) ?: false
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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.intention
@@ -22,8 +11,10 @@ import com.intellij.openapi.vfs.VirtualFile
val CREATE_XML_RESOURCE_PARAMETERS_NAME_KEY = Key<String>("CREATE_XML_RESOURCE_PARAMETERS_NAME_KEY")
class CreateXmlResourceParameters(val name: String,
val value: String,
val fileName: String,
val resourceDirectory: VirtualFile,
val directoryNames: List<String>)
class CreateXmlResourceParameters(
val name: String,
val value: String,
val fileName: String,
val resourceDirectory: VirtualFile,
val directoryNames: List<String>
)
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -29,10 +18,9 @@ import org.jetbrains.kotlin.psi.KtClass
class ImplementParcelableAction :
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("implement.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean =
AndroidFacet.getInstance(element) != null &&
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("implement.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null &&
!element.insideBody(caretOffset) &&
!element.isParcelize() &&
element.canAddParcelable()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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.intention
@@ -53,8 +42,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTemplateEntry>(KtLiteralStringTemplateEntry::class.java,
"Extract string resource") {
class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTemplateEntry>(
KtLiteralStringTemplateEntry::class.java,
"Extract string resource"
) {
private companion object {
private val CLASS_CONTEXT = "android.content.Context"
private val CLASS_FRAGMENT = "android.app.Fragment"
@@ -102,8 +93,16 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
val parameters = getCreateXmlResourceParameters(facet.module, element, file.virtualFile) ?: return
runWriteAction {
if (!AndroidResourceUtil.createValueResource(project, parameters.resourceDirectory, parameters.name, ResourceType.STRING,
parameters.fileName, parameters.directoryNames, parameters.value)) {
if (!AndroidResourceUtil.createValueResource(
project,
parameters.resourceDirectory,
parameters.name,
ResourceType.STRING,
parameters.fileName,
parameters.directoryNames,
parameters.value
)
) {
return@runWriteAction
}
@@ -113,8 +112,10 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
}
}
private fun getCreateXmlResourceParameters(module: Module, element: KtLiteralStringTemplateEntry,
contextFile: VirtualFile): CreateXmlResourceParameters? {
private fun getCreateXmlResourceParameters(
module: Module, element: KtLiteralStringTemplateEntry,
contextFile: VirtualFile
): CreateXmlResourceParameters? {
val stringValue = element.text
val showDialog = !ApplicationManager.getApplication().isUnitTestMode
@@ -126,8 +127,7 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
if (!dialog.showAndGet()) {
return null
}
}
else {
} else {
dialog.close(0)
}
@@ -137,23 +137,31 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
return null
}
return CreateXmlResourceParameters(dialog.resourceName,
dialog.value,
dialog.fileName,
resourceDirectory,
dialog.dirNames)
return CreateXmlResourceParameters(
dialog.resourceName,
dialog.value,
dialog.fileName,
resourceDirectory,
dialog.dirNames
)
}
private fun createResourceReference(module: Module, editor: Editor, file: KtFile, element: PsiElement, aPackage: String,
resName: String, resType: ResourceType) {
private fun createResourceReference(
module: Module,
editor: Editor,
file: KtFile,
element: PsiElement,
aPackage: String,
resName: String,
resType: ResourceType
) {
val rFieldName = AndroidResourceUtil.getRJavaFieldName(resName)
val fieldName = "$aPackage.R.$resType.$rFieldName"
val template: TemplateImpl
if (!needContextReceiver(element)) {
template = TemplateImpl("", "$GET_STRING_METHOD($fieldName)", "")
}
else {
} else {
template = TemplateImpl("", "\$context\$.$GET_STRING_METHOD($fieldName)", "")
val marker = MacroCallNode(VariableOfTypeMacro())
marker.addParameter(ConstantNode(CLASS_CONTEXT))
@@ -189,8 +197,7 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
return false
}
if (parent.isSubclassOrSubclassExtension(viewClass) ||
(parent is KtClassOrObject && !parent.isInnerClass() && !parent.isObjectLiteral())) {
if (parent.isSubclassOrSubclassExtension(viewClass) || (parent is KtClassOrObject && !parent.isInnerClass() && !parent.isObjectLiteral())) {
return true
}
@@ -203,13 +210,11 @@ class KotlinAndroidAddStringResource : SelfTargetingIntention<KtLiteralStringTem
private fun getManifestPackage(facet: AndroidFacet) = facet.manifest?.`package`?.value
private fun PsiElement.isSubclassOrSubclassExtension(baseClasses: Collection<String>) =
(this as? KtClassOrObject)?.isSubclassOfAny(baseClasses) ?:
this.isSubclassExtensionOfAny(baseClasses)
(this as? KtClassOrObject)?.isSubclassOfAny(baseClasses) ?: this.isSubclassExtensionOfAny(baseClasses)
private fun PsiElement.isSubclassExtensionOfAny(baseClasses: Collection<String>) =
(this as? KtLambdaExpression)?.isSubclassExtensionOfAny(baseClasses) ?:
(this as? KtFunction)?.isSubclassExtensionOfAny(baseClasses) ?:
false
(this as? KtLambdaExpression)?.isSubclassExtensionOfAny(baseClasses) ?: (this as? KtFunction)?.isSubclassExtensionOfAny(baseClasses)
?: false
private fun KtClassOrObject.isObjectLiteral() = (this as? KtObjectDeclaration)?.isObjectLiteral() ?: false
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -29,10 +18,9 @@ import org.jetbrains.kotlin.psi.KtClass
class RedoParcelableAction :
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("redo.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean =
AndroidFacet.getInstance(element) != null &&
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("redo.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null &&
!element.insideBody(caretOffset) &&
!element.isParcelize() &&
element.canRedoParcelable()
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -29,10 +18,9 @@ import org.jetbrains.kotlin.psi.KtClass
class RemoveParcelableAction :
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("remove.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean =
AndroidFacet.getInstance(element) != null &&
SelfTargetingIntention<KtClass>(KtClass::class.java, AndroidBundle.message("remove.parcelable.intention.text")),
HighPriorityAction {
override fun isApplicableTo(element: KtClass, caretOffset: Int): Boolean = AndroidFacet.getInstance(element) != null &&
!element.insideBody(caretOffset) &&
!element.isParcelize() &&
element.canRemoveParcelable()
@@ -1,17 +1,6 @@
/*
* 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.
* 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.navigation
@@ -37,8 +26,8 @@ fun getReferenceExpression(element: PsiElement?): KtSimpleNameExpression? {
// given 'R.a.b' returns info for all three parts of the expression 'a', 'b', 'R'
fun getInfo(
referenceExpression: KtSimpleNameExpression,
facet: AndroidFacet
referenceExpression: KtSimpleNameExpression,
facet: AndroidFacet
): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val info = getReferredInfo(referenceExpression, facet)
if (info != null) return info
@@ -54,8 +43,8 @@ private fun KtExpression?.getParentQualified(): KtDotQualifiedExpression? {
// returns info if passed expression is 'b' in 'R.a.b'
private fun getReferredInfo(
lastPart: KtSimpleNameExpression,
facet: AndroidFacet
lastPart: KtSimpleNameExpression,
facet: AndroidFacet
): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val resFieldName = lastPart.getReferencedName()
if (resFieldName.isEmpty()) return null
@@ -87,9 +76,10 @@ private fun getReferredInfo(
}
val containingFile = resolvedClass.containingFile ?: return null
val isFromCorrectFile =
if (fromManifest) AndroidResourceUtil.isManifestJavaFile(facet, containingFile)
else AndroidResourceUtil.isRJavaFile(facet, containingFile)
val isFromCorrectFile = if (fromManifest)
AndroidResourceUtil.isManifestJavaFile(facet, containingFile)
else
AndroidResourceUtil.isRJavaFile(facet, containingFile)
if (!isFromCorrectFile) {
return null
@@ -98,9 +88,8 @@ private fun getReferredInfo(
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, resolvedModule, false, fromManifest)
}
private fun getReceiverAsSimpleNameExpression(exp: KtSimpleNameExpression): KtSimpleNameExpression? {
val receiver = exp.getReceiverExpression()
return when (receiver) {
private fun getReceiverAsSimpleNameExpression(exp: KtSimpleNameExpression): KtSimpleNameExpression? =
when (val receiver = exp.getReceiverExpression()) {
is KtSimpleNameExpression -> {
receiver
}
@@ -109,5 +98,3 @@ private fun getReceiverAsSimpleNameExpression(exp: KtSimpleNameExpression): KtSi
}
else -> null
}
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.quickfix
@@ -31,8 +20,8 @@ import org.jetbrains.kotlin.psi.*
class AddTargetApiQuickFix(
val api: Int,
val useRequiresApi: Boolean
val api: Int,
val useRequiresApi: Boolean
) : AndroidLintQuickFix {
private companion object {
@@ -41,7 +30,7 @@ class AddTargetApiQuickFix(
}
override fun isApplicable(startElement: PsiElement, endElement: PsiElement, contextType: AndroidQuickfixContexts.ContextType): Boolean =
getAnnotationContainer(startElement, useRequiresApi) != null
getAnnotationContainer(startElement, useRequiresApi) != null
override fun getName(): String = getAnnotationValue(false).let {
if (useRequiresApi) {
@@ -60,10 +49,11 @@ class AddTargetApiQuickFix(
}
if (annotationContainer is KtModifierListOwner) {
annotationContainer.addAnnotation(
if (useRequiresApi) FQNAME_REQUIRES_API else FQNAME_TARGET_API,
getAnnotationValue(true),
whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ")
annotationContainer.addAnnotation(
if (useRequiresApi) FQNAME_REQUIRES_API else FQNAME_TARGET_API,
getAnnotationValue(true),
whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " "
)
}
}
@@ -82,14 +72,14 @@ class AddTargetApiQuickFix(
private fun PsiElement.isRequiresApiAnnotationValidTarget(): Boolean {
return this is KtClassOrObject ||
(this is KtFunction && this !is KtFunctionLiteral) ||
(this is KtProperty && !isLocal && hasBackingField()) ||
this is KtPropertyAccessor
(this is KtFunction && this !is KtFunctionLiteral) ||
(this is KtProperty && !isLocal && hasBackingField()) ||
this is KtPropertyAccessor
}
private fun PsiElement.isTargetApiAnnotationValidTarget(): Boolean {
return this is KtClassOrObject ||
(this is KtFunction && this !is KtFunctionLiteral) ||
this is KtPropertyAccessor
(this is KtFunction && this !is KtFunctionLiteral) ||
this is KtPropertyAccessor
}
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.quickfix
@@ -52,9 +41,11 @@ class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
document.replaceString(conditionRange.startOffset, conditionRange.endOffset, conditionText)
documentManager.commitDocument(document)
ShortenReferences.DEFAULT.process(documentManager.getPsiFile(document) as KtFile,
conditionRange.startOffset,
conditionRange.startOffset + conditionText.length)
ShortenReferences.DEFAULT.process(
documentManager.getPsiFile(document) as KtFile,
conditionRange.startOffset,
conditionRange.startOffset + conditionText.length
)
}
override fun isApplicable(startElement: PsiElement, endElement: PsiElement, contextType: AndroidQuickfixContexts.ContextType): Boolean =
@@ -72,7 +63,8 @@ class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
current.parent is KtPropertyAccessor ||
current.parent is KtProperty ||
current.parent is KtReturnExpression ||
current.parent is KtDestructuringDeclaration) {
current.parent is KtDestructuringDeclaration
) {
break
}
current = PsiTreeUtil.getParentOfType(current, KtExpression::class.java, true)
@@ -1,17 +1,6 @@
/*
* 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.
* 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.quickfix
@@ -31,11 +20,11 @@ import java.util.regex.Pattern
class KotlinAndroidQuickFixProvider : AndroidLintQuickFixProvider {
override fun getQuickFixes(
issue: Issue,
startElement: PsiElement,
endElement: PsiElement,
message: String,
data: Any?
issue: Issue,
startElement: PsiElement,
endElement: PsiElement,
message: String,
data: Any?
): Array<AndroidLintQuickFix> {
val fixes: Array<AndroidLintQuickFix> = when (issue) {
ApiDetector.UNSUPPORTED, ApiDetector.INLINED -> getApiQuickFixes(issue, startElement, message)
@@ -1,17 +1,6 @@
/*
* 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.
* 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.quickfix
@@ -43,10 +32,10 @@ class SuppressLintQuickFix(id: String) : AndroidLintQuickFix {
when (annotationContainer) {
is KtModifierListOwner -> {
annotationContainer.addAnnotation(
FQNAME_SUPPRESS_LINT,
argument,
whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ",
addToExistingAnnotation = { entry -> addArgumentToAnnotation(entry, argument) })
FQNAME_SUPPRESS_LINT,
argument,
whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ",
addToExistingAnnotation = { entry -> addArgumentToAnnotation(entry, argument) })
}
}
}
@@ -54,9 +43,9 @@ class SuppressLintQuickFix(id: String) : AndroidLintQuickFix {
override fun getName(): String = AndroidBundle.message(SUPPRESS_LINT_MESSAGE, lintId)
override fun isApplicable(
startElement: PsiElement,
endElement: PsiElement,
contextType: AndroidQuickfixContexts.ContextType
startElement: PsiElement,
endElement: PsiElement,
contextType: AndroidQuickfixContexts.ContextType
): Boolean = true
private fun addArgumentToAnnotation(entry: KtAnnotationEntry, argument: String): Boolean {
@@ -77,20 +66,21 @@ class SuppressLintQuickFix(id: String) : AndroidLintQuickFix {
}
private fun getLintId(intentionId: String) =
if (intentionId.startsWith(INTENTION_NAME_PREFIX)) intentionId.substring(INTENTION_NAME_PREFIX.length) else intentionId
if (intentionId.startsWith(INTENTION_NAME_PREFIX)) intentionId.substring(INTENTION_NAME_PREFIX.length) else intentionId
private fun KtElement.isNewLineNeededForAnnotation(): Boolean {
return !(this is KtParameter ||
this is KtTypeParameter ||
this is KtPropertyAccessor)
this is KtTypeParameter ||
this is KtPropertyAccessor)
}
private fun PsiElement.isSuppressLintTarget(): Boolean {
return this is KtDeclaration &&
(this as? KtProperty)?.hasBackingField() ?: true &&
this !is KtFunctionLiteral &&
this !is KtDestructuringDeclaration
(this as? KtProperty)?.hasBackingField() ?: true &&
this !is KtFunctionLiteral &&
this !is KtDestructuringDeclaration
}
private companion object {
val INTENTION_NAME_PREFIX = "AndroidLint"
val SUPPRESS_LINT_MESSAGE = "android.lint.fix.suppress.lint.api.annotation"
@@ -1,17 +1,6 @@
/*
* 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.
* 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.annotator
@@ -61,8 +50,7 @@ abstract class AbstractAndroidGutterIconTest : KotlinAndroidTestCase() {
}
TestCase.assertNotNull(gutter)
}
finally {
} finally {
if (withRuntime) {
ConfigLibraryUtil.unConfigureKotlinRuntime(myFixture.module)
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.intention
@@ -31,15 +20,17 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() {
val testFile = File(path)
val testFileText = FileUtil.loadFile(testFile)
val intentionClassName = InTextDirectivesUtils.findStringWithPrefixes(testFileText, "// INTENTION_CLASS: ")
?: error("Intention class not found!")
?: error("Intention class not found!")
val notAvailable = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// NOT_AVAILABLE")
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// WITH_RUNTIME")
val checkManifest = InTextDirectivesUtils.isDirectiveDefined(testFileText, "// CHECK_MANIFEST")
try {
ConfigLibraryUtil.addLibrary(myModule, "androidExtensionsRuntime",
"dist/kotlinc/lib", arrayOf("android-extensions-runtime.jar"))
ConfigLibraryUtil.addLibrary(
myModule, "androidExtensionsRuntime",
"dist/kotlinc/lib", arrayOf("android-extensions-runtime.jar")
)
if (withRuntime) {
ConfigLibraryUtil.configureKotlinRuntime(myFixture.module)
}
@@ -70,12 +61,10 @@ abstract class AbstractAndroidIntentionTest : KotlinAndroidTestCase() {
if (checkManifest) {
myFixture.checkResultByFile("AndroidManifest.xml", "$customManifestPath.expected", true)
}
else {
} else {
myFixture.checkResultByFile("$path.expected")
}
}
finally {
} finally {
ConfigLibraryUtil.removeLibrary(myModule, "androidExtensionsRuntime")
if (withRuntime) {
ConfigLibraryUtil.unConfigureKotlinRuntime(myFixture.module)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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.intention
@@ -52,8 +41,7 @@ abstract class AbstractAndroidResourceIntentionTest : KotlinAndroidTestCase() {
if (rFile != null) {
myFixture.copyFileToProject(rFile, "gen/$COM_MYAPP_PACKAGE_PATH" + PathUtil.getFileName(rFile))
}
else {
} else {
if (File(testDataPath + "/R.java").isFile) {
myFixture.copyFileToProject("R.java", "gen/${COM_MYAPP_PACKAGE_PATH}R.java")
}
@@ -61,8 +49,7 @@ abstract class AbstractAndroidResourceIntentionTest : KotlinAndroidTestCase() {
if (resDirectory != null) {
myFixture.copyDirectoryToProject(resDirectory, "res")
}
else {
} else {
if (File(testDataPath + "/res").isDirectory) {
myFixture.copyDirectoryToProject("res", "res")
}
@@ -74,14 +61,12 @@ abstract class AbstractAndroidResourceIntentionTest : KotlinAndroidTestCase() {
val intentionAction: IntentionAction?
if (intentionClass != null) {
intentionAction = Class.forName(intentionClass).newInstance() as IntentionAction
}
else if (intentionText != null) {
} else if (intentionText != null) {
intentionAction = myFixture.getAvailableIntention(intentionText)
if (intentionAction != null && !isApplicableExpected) {
TestCase.fail("Intention action should not be available")
}
}
else {
} else {
intentionAction = null
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* 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.lint
@@ -78,8 +67,7 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
for (file in additionalResourcesDir.listFiles()) {
if (file.isFile) {
myFixture.copyFileToProject(file.absolutePath, file.name)
}
else if (file.isDirectory) {
} else if (file.isDirectory) {
myFixture.copyDirectoryToProject(file.absolutePath, file.name)
}
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.quickfix
@@ -35,7 +24,8 @@ abstract class AbstractAndroidLintQuickfixTest : KotlinAndroidTestCase() {
fun doTest(path: String) {
val fileText = FileUtil.loadFile(File(path), true)
val intentionText = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// INTENTION_TEXT: ") ?: error("Empty intention text")
val mainInspectionClassName = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// INSPECTION_CLASS: ") ?: error("Empty inspection class name")
val mainInspectionClassName =
InTextDirectivesUtils.findStringWithPrefixes(fileText, "// INSPECTION_CLASS: ") ?: error("Empty inspection class name")
val dependency = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// DEPENDENCY: ")
val intentionAvailable = !InTextDirectivesUtils.isDirectiveDefined(fileText, "// INTENTION_NOT_AVAILABLE")
@@ -54,8 +44,7 @@ abstract class AbstractAndroidLintQuickfixTest : KotlinAndroidTestCase() {
val intention = myFixture.getAvailableIntention(intentionText) ?: error("Failed to find intention")
myFixture.launchAction(intention)
myFixture.checkResultByFile(path + ".expected")
}
else {
} else {
assertNull("Intention should not be available", myFixture.availableIntentions.find { it.text == intentionText })
}
}