diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt
index 01d38440e40..6abedf73d55 100644
--- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt
+++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidConst.kt
@@ -47,3 +47,8 @@ public fun isResourceIdDeclaration(str: String?): Boolean = str?.startsWith(Andr
public fun isResourceIdUsage(str: String?): Boolean = str?.startsWith(AndroidConst.ID_USAGE_PREFIX) ?: false
public fun isResourceDeclarationOrUsage(id: String?): Boolean = isResourceIdDeclaration(id) || isResourceIdUsage(id)
+
+public fun getRealWidgetType(xmlType: String): String = when (xmlType) {
+ "fragment", "include", "merge" -> "View"
+ else -> xmlType
+}
\ No newline at end of file
diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidXmlHandler.kt b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidXmlHandler.kt
index ddb74151bf6..8e6ab406e4b 100644
--- a/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidXmlHandler.kt
+++ b/plugins/android-compiler-plugin/src/org/jetbrains/kotlin/lang/resolve/android/AndroidXmlHandler.kt
@@ -32,11 +32,11 @@ class AndroidXmlHandler(private val elementCallback: (String, String) -> Unit) :
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
val attributesMap = attributes.toMap()
- val idAttr = attributesMap[AndroidConst.ID_ATTRIBUTE_NO_NAMESPACE]
- val classNameAttr = attributesMap[AndroidConst.CLASS_ATTRIBUTE_NO_NAMESPACE] ?: localName
- if (isResourceDeclarationOrUsage(idAttr)) {
- val name = idToName(idAttr)
- if (name != null) elementCallback(name, classNameAttr)
+ val idAttribute = attributesMap[AndroidConst.ID_ATTRIBUTE_NO_NAMESPACE]
+ val widgetType = getRealWidgetType(attributesMap[AndroidConst.CLASS_ATTRIBUTE_NO_NAMESPACE] ?: localName)
+ if (isResourceDeclarationOrUsage(idAttribute)) {
+ val name = idToName(idAttribute)
+ if (name != null) elementCallback(name, widgetType)
}
}
diff --git a/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/AndroidManifest.xml b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/AndroidManifest.xml
new file mode 100644
index 00000000000..580c474f5de
--- /dev/null
+++ b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/AndroidManifest.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout.kt b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout.kt
new file mode 100644
index 00000000000..50662a47f3c
--- /dev/null
+++ b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout.kt
@@ -0,0 +1,26 @@
+package kotlinx.android.synthetic.layout
+
+import android.app.Activity
+import android.app.Fragment
+import android.view.View
+import android.widget.*
+import kotlin.internal.flexible.ft
+
+val Activity.includeTag: ft
+ get() = findViewById(0) as View
+
+val Fragment.includeTag: ft
+ get() = getView().findViewById(0) as View
+
+val Activity.mergeTag: ft
+ get() = findViewById(0) as View
+
+val Fragment.mergeTag: ft
+ get() = getView().findViewById(0) as View
+
+val Activity.fragmentTag: ft
+ get() = findViewById(0) as View
+
+val Fragment.fragmentTag: ft
+ get() = getView().findViewById(0) as View
+
diff --git a/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout1.kt b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout1.kt
new file mode 100644
index 00000000000..d58b635d302
--- /dev/null
+++ b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/layout1.kt
@@ -0,0 +1,17 @@
+package kotlinx.android.synthetic.layout.view
+
+import android.app.Activity
+import android.app.Fragment
+import android.view.View
+import android.widget.*
+import kotlin.internal.flexible.ft
+
+val View.includeTag: ft
+ get() = findViewById(0) as View
+
+val View.mergeTag: ft
+ get() = findViewById(0) as View
+
+val View.fragmentTag: ft
+ get() = findViewById(0) as View
+
diff --git a/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/res/layout/layout.xml b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/res/layout/layout.xml
new file mode 100644
index 00000000000..0198b69b328
--- /dev/null
+++ b/plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/res/layout/layout.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidXml2KConversionTestGenerated.java b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidXml2KConversionTestGenerated.java
index 03e6a19eb56..d2a657c4017 100644
--- a/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidXml2KConversionTestGenerated.java
+++ b/plugins/android-compiler-plugin/tests/org/jetbrains/kotlin/lang/resolve/android/test/AndroidXml2KConversionTestGenerated.java
@@ -71,6 +71,12 @@ public class AndroidXml2KConversionTestGenerated extends AbstractAndroidXml2KCon
String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/android/converter/simple/singleFile/");
doTest(fileName);
}
+
+ @TestMetadata("specialTags")
+ public void testSpecialTags() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("plugins/android-compiler-plugin/testData/android/converter/simple/specialTags/");
+ doTest(fileName);
+ }
}
@TestMetadata("plugins/android-compiler-plugin/testData/android/converter/exceptions")
diff --git a/plugins/android-idea-plugin/src/org/jetbrains/kotlin/plugin/android/AndroidXmlVisitor.kt b/plugins/android-idea-plugin/src/org/jetbrains/kotlin/plugin/android/AndroidXmlVisitor.kt
index 36e6fb73762..e262e0bcca6 100644
--- a/plugins/android-idea-plugin/src/org/jetbrains/kotlin/plugin/android/AndroidXmlVisitor.kt
+++ b/plugins/android-idea-plugin/src/org/jetbrains/kotlin/plugin/android/AndroidXmlVisitor.kt
@@ -16,15 +16,13 @@
package org.jetbrains.kotlin.plugin.android
-import org.jetbrains.kotlin.lang.resolve.android.AndroidResourceManager
import com.intellij.psi.xml.XmlAttribute
import com.intellij.psi.XmlElementVisitor
import com.intellij.psi.PsiElement
import com.intellij.psi.xml.XmlElement
import com.intellij.psi.xml.XmlTag
-import org.jetbrains.kotlin.lang.resolve.android.AndroidConst
import org.jetbrains.kotlin.lang.resolve.android
-import org.jetbrains.kotlin.lang.resolve.android.idToName
+import org.jetbrains.kotlin.lang.resolve.android.*
class AndroidXmlVisitor(val elementCallback: (String, String, XmlAttribute) -> Unit) : XmlElementVisitor() {
@@ -37,14 +35,16 @@ class AndroidXmlVisitor(val elementCallback: (String, String, XmlAttribute) -> U
}
override fun visitXmlTag(tag: XmlTag?) {
- val attribute = tag?.getAttribute(AndroidConst.ID_ATTRIBUTE)
- if (attribute != null) {
- val attributeValue = attribute.getValue()
- if (attributeValue != null) {
- val classNameAttr = tag?.getAttribute(AndroidConst.CLASS_ATTRIBUTE_NO_NAMESPACE)?.getValue() ?: tag?.getLocalName()
- if (classNameAttr != null) {
- val name = idToName(attributeValue)
- if (name != null) elementCallback(name, classNameAttr!!, attribute)
+ val idAttribute = tag?.getAttribute(AndroidConst.ID_ATTRIBUTE)
+ if (idAttribute != null) {
+ val idAttributeValue = idAttribute.getValue()
+ if (idAttributeValue != null) {
+ val classAttributeValue = tag?.getAttribute(AndroidConst.CLASS_ATTRIBUTE_NO_NAMESPACE)?.getValue()
+ val xmlType = classAttributeValue ?: tag?.getLocalName()
+ val widgetType = xmlType?.let { getRealWidgetType(it) }
+ if (widgetType != null && isResourceDeclarationOrUsage(idAttributeValue)) {
+ val name = idToName(idAttributeValue)
+ if (name != null) elementCallback(name, widgetType, idAttribute)
}
}
}