diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt
index f2568da47f2..84917df3f38 100755
--- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt
+++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt
@@ -68,6 +68,15 @@ open class ApiDetector : Detector(), UastScanner {
return super.visitCallExpression(node)
}
+ override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
+ val typeRef = node.typeReference
+ if (typeRef != null) {
+ checkVersion(context, typeRef, node.type.resolve(context))
+ }
+
+ return super.visitBinaryExpressionWithType(node)
+ }
+
override fun visitSimpleReferenceExpression(node: USimpleReferenceExpression): Boolean {
checkVersion(context, node, node.resolve(context) as? UVariable)
return super.visitSimpleReferenceExpression(node)
diff --git a/plugins/uast-common/src/org/jetbrains/uast/expressions/UBinaryExpressionWithType.kt b/plugins/uast-common/src/org/jetbrains/uast/expressions/UBinaryExpressionWithType.kt
index 8d9fd5be3a7..be033e82305 100644
--- a/plugins/uast-common/src/org/jetbrains/uast/expressions/UBinaryExpressionWithType.kt
+++ b/plugins/uast-common/src/org/jetbrains/uast/expressions/UBinaryExpressionWithType.kt
@@ -36,6 +36,11 @@ interface UBinaryExpressionWithType : UExpression {
*/
val type: UType
+ /**
+ * Returns the type reference.
+ */
+ val typeReference: UTypeReference?
+
override fun logString() = log("UBinaryExpressionWithType (${getExpressionType()?.name}, ${operationKind.name})", operand)
override fun renderString() = "${operand.renderString()} ${operationKind.name} ${type.name}"
diff --git a/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUInstanceCheckExpression.kt b/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUInstanceCheckExpression.kt
index 981aaf5433d..791ac5cde4c 100644
--- a/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUInstanceCheckExpression.kt
+++ b/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUInstanceCheckExpression.kt
@@ -18,6 +18,7 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiInstanceOfExpression
import org.jetbrains.uast.UBinaryExpressionWithType
import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UTypeReference
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
import org.jetbrains.uast.psi.PsiElementBacked
@@ -27,6 +28,9 @@ class JavaUInstanceCheckExpression(
) : JavaAbstractUElement(), UBinaryExpressionWithType, PsiElementBacked, JavaUElementWithType, JavaEvaluatableUElement {
override val operand by lz { JavaConverter.convertOrEmpty(psi.operand, this) }
override val type by lz { JavaConverter.convert(psi.checkType?.type, this) }
+
+ override val typeReference: UTypeReference?
+ get() = null
override val operationKind: UastBinaryExpressionWithTypeKind.InstanceCheck
get() = UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
diff --git a/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUTypeCastExpression.kt b/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUTypeCastExpression.kt
index b27b955e3bb..7a6e759f3e1 100644
--- a/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUTypeCastExpression.kt
+++ b/plugins/uast-java/src/org/jetbrains/uast/java/expressions/JavaUTypeCastExpression.kt
@@ -18,6 +18,7 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiTypeCastExpression
import org.jetbrains.uast.UBinaryExpressionWithType
import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UTypeReference
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
import org.jetbrains.uast.psi.PsiElementBacked
@@ -28,6 +29,9 @@ class JavaUTypeCastExpression(
override val operand by lz { JavaConverter.convertOrEmpty(psi.operand, this) }
override val type by lz { JavaConverter.convert(psi.castType?.type, this) }
+ override val typeReference: UTypeReference?
+ get() = null
+
override val operationKind: UastBinaryExpressionWithTypeKind.TypeCast
get() = UastBinaryExpressionWithTypeKind.TYPE_CAST
}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt
index 5f632ef2c44..7e6f229bc2f 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt
@@ -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
diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUTypeReference.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUTypeReference.kt
new file mode 100644
index 00000000000..7b5cdd730ef
--- /dev/null
+++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/declarations/KotlinUTypeReference.kt
@@ -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()
+}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt
index f71fbaa7b6b..36688f681de 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUBinaryExpressionWithType.kt
@@ -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
}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt
index 1004c563971..346fdd9196c 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUSwitchExpression.kt
@@ -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)
diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt
index 19de370ded2..88a24702976 100644
--- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt
+++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/expressions/KotlinUTypeCheckExpression.kt
@@ -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
}
\ No newline at end of file
diff --git a/plugins/uast-kotlin/testData/lint/apiCheck.kt b/plugins/uast-kotlin/testData/lint/apiCheck.kt
index 6ddd00f8cde..74a6a6b3dcb 100644
--- a/plugins/uast-kotlin/testData/lint/apiCheck.kt
+++ b/plugins/uast-kotlin/testData/lint/apiCheck.kt
@@ -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 GridLayout) {}
+ layout as? GridLayout
+
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged
} else {