KT-12023 Kotlin Lint: Cast doesn't trigger minSdk error
Check Kotlin as/is types. (cherry picked from commit c0db8e0)
This commit is contained in:
@@ -188,6 +188,10 @@ internal object KotlinConverter : UastConverter {
|
||||
val type = bindingContext[BindingContext.TYPE, typeReference] ?: return UastErrorType
|
||||
return KotlinUType(type, typeReference.project, parent, typeReference.typeElement)
|
||||
}
|
||||
|
||||
internal fun convertTypeReference(typeReference: KtTypeReference, parent: UElement): UTypeReference {
|
||||
return KotlinUTypeReference(typeReference, parent)
|
||||
}
|
||||
|
||||
internal fun asSimpleReference(element: PsiElement?, parent: UElement): USimpleReferenceExpression? {
|
||||
if (element == null) return null
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
|
||||
class KotlinUTypeReference(
|
||||
override val psi: KtTypeReference,
|
||||
override val parent: UElement
|
||||
) : KotlinAbstractUElement(), UTypeReference, PsiElementBacked {
|
||||
override fun resolve(context: UastContext): UClass? {
|
||||
val descriptor = psi.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, psi]
|
||||
?.constructor?.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
return context.convert(descriptor.toSource()) as? UClass
|
||||
}
|
||||
|
||||
override val nameElement: UElement?
|
||||
get() = KotlinDumbUElement(psi, this)
|
||||
|
||||
override val name: String
|
||||
get() = psi.name.orAnonymous()
|
||||
}
|
||||
+4
@@ -28,6 +28,7 @@ class KotlinUBinaryExpressionWithType(
|
||||
) : KotlinAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convert(psi.left, this) }
|
||||
override val type by lz { KotlinConverter.convert(psi.right, this) }
|
||||
override val typeReference by lz { psi.right?.let { KotlinConverter.convertTypeReference(it, this) } }
|
||||
override val operationKind = when (psi.operationReference.getReferencedNameElementType()) {
|
||||
KtTokens.AS_KEYWORD -> UastBinaryExpressionWithTypeKind.TYPE_CAST
|
||||
KtTokens.AS_SAFE -> KotlinBinaryExpressionWithTypeKinds.SAFE_TYPE_CAST
|
||||
@@ -47,4 +48,7 @@ class KotlinCustomUBinaryExpressionWithType(
|
||||
|
||||
lateinit override var type: UType
|
||||
internal set
|
||||
|
||||
override var typeReference: UTypeReference? = null
|
||||
internal set
|
||||
}
|
||||
+3
-1
@@ -64,7 +64,9 @@ class KotlinUSwitchEntry(
|
||||
it.isNegated -> KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
|
||||
else -> UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
|
||||
}
|
||||
type = KotlinConverter.convert(it.typeReference, this)
|
||||
val typeRef = it.typeReference
|
||||
type = KotlinConverter.convert(typeRef, this)
|
||||
typeReference = typeRef?.let { KotlinConverter.convertTypeReference(it, this) }
|
||||
}
|
||||
is KtWhenConditionWithExpression -> KotlinConverter.convertOrEmpty(it.expression, this)
|
||||
else -> EmptyUExpression(this)
|
||||
|
||||
+1
@@ -27,5 +27,6 @@ class KotlinUTypeCheckExpression(
|
||||
) : KotlinAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val operand by lz { KotlinConverter.convert(psi.leftHandSide, this) }
|
||||
override val type by lz { KotlinConverter.convert(psi.typeReference, this) }
|
||||
override val typeReference by lz { psi.typeReference?.let { KotlinConverter.convertTypeReference(it, this) } }
|
||||
override val operationKind = KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
|
||||
}
|
||||
+5
-1
@@ -8,6 +8,7 @@ import org.w3c.dom.DOMError
|
||||
import org.w3c.dom.DOMErrorHandler
|
||||
import org.w3c.dom.DOMLocator
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.app.Activity
|
||||
import android.app.ApplicationErrorReport
|
||||
@@ -108,7 +109,10 @@ class ApiCallTest: Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun test(priority: Boolean) {
|
||||
fun test(priority: Boolean, layout: ViewGroup) {
|
||||
if (layout is <error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout</error>) {}
|
||||
layout as? <error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout</error>
|
||||
|
||||
if (android.os.Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
GridLayout(null).getOrientation(); // Not flagged
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user