Support special Android layout XML tags: fragment, include, merge
This commit is contained in:
+5
@@ -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
|
||||
}
|
||||
+5
-5
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.myapp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="18" />
|
||||
<permission android:name="android"></permission>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.Sample" >
|
||||
<activity
|
||||
android:name="com.example.android.basiccontactables.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop">
|
||||
<meta-data
|
||||
android:name="android.app.searchable"
|
||||
android:resource="@xml/searchable" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEARCH" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
+26
@@ -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<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
val Fragment.includeTag: ft<View, View?>
|
||||
get() = getView().findViewById(0) as View
|
||||
|
||||
val Activity.mergeTag: ft<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
val Fragment.mergeTag: ft<View, View?>
|
||||
get() = getView().findViewById(0) as View
|
||||
|
||||
val Activity.fragmentTag: ft<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
val Fragment.fragmentTag: ft<View, View?>
|
||||
get() = getView().findViewById(0) as View
|
||||
|
||||
+17
@@ -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<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
val View.mergeTag: ft<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
val View.fragmentTag: ft<View, View?>
|
||||
get() = findViewById(0) as View
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
layout="@android:layout/simple_list_item_1"
|
||||
android:id="@+id/includeTag" />
|
||||
|
||||
<merge
|
||||
layout="@android:layout/simple_list_item_1"
|
||||
android:id="@+id/mergeTag" />
|
||||
|
||||
<fragment
|
||||
layout="@android:layout/simple_list_item_1"
|
||||
android:id="@+id/fragmentTag"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
</FrameLayout>
|
||||
+6
@@ -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")
|
||||
|
||||
+11
-11
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user