Skip to content

Commit

Permalink
refactor(compiler): move LayoutParser
Browse files Browse the repository at this point in the history
Signed-off-by: Haruue Icymoon <[email protected]>
  • Loading branch information
haruue committed Apr 3, 2018
1 parent 5521864 commit 8e4a91f
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 71 deletions.
1 change: 1 addition & 0 deletions compiler/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies {
implementation "com.google.auto.service:auto-service:1.0-rc4"
kapt "com.google.auto.service:auto-service:1.0-rc4"
implementation "com.squareup:javapoet:1.9.0"
implementation "org.ogce:xpp3:1.1.6"
implementation project(':annotation')
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package moe.haruue.gradle.plugin.test
package moe.haruue.layoutparser.compiler

import com.squareup.javapoet.*
import moe.haruue.layoutparser.compiler.tools.cnActivity
import moe.haruue.layoutparser.compiler.tools.cnContext
import moe.haruue.layoutparser.compiler.tools.toClassName
import moe.haruue.layoutparser.compiler.tools.underlineToUpperCamel
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParser.*
import java.util.*
Expand All @@ -18,15 +22,15 @@ class LayoutParser(

companion object {
// fuck kotlin string format
val S = "${'$'}S"
val T = "${'$'}T"
val N = "${'$'}N"
val L = "\$L"
val S = "\$S"
val T = "\$T"
val N = "\$N"
// prefixes
val PREFIX = "__view_"
val PREFIX_NOID = "${PREFIX}noid_"
val ROOT_VIEW_NAME = "${PREFIX}root"
fun paramNameOf(fieldName: String) = "${PREFIX}param$fieldName"
val CONTEXT_CLASS_NAME = ClassName.get("android.content", "Context")
val ACTIVITY_CLASSNAME = ClassName.get("android.app", "Activity")
fun layoutParamsNameOf(fieldName: String) = "${PREFIX}lp$fieldName"
}

object DimensionUnit {
Expand Down Expand Up @@ -66,7 +70,7 @@ class LayoutParser(
initToolsMethods()
constructorBuilder = MethodSpec.constructorBuilder().apply {
addModifiers(Modifier.PRIVATE)
addParameter(CONTEXT_CLASS_NAME, "context")
addParameter(cnContext, "context")
}
with(xml) {
read@ while (true) {
Expand Down Expand Up @@ -120,53 +124,54 @@ class LayoutParser(

private fun generateJavaCodeForTag(name: String, type: String, hasId: Boolean, attrs: Map<String, String>,
width: Dimension, height: Dimension, isRoot: Boolean, parent: ViewType) {
val typeClassName = type.parseClassName()
val typeClassName = type.toClassName()
val field = FieldSpec.builder(typeClassName, name,
if (hasId) Modifier.PUBLIC else Modifier.PRIVATE,
Modifier.FINAL).build()
fields.add(field)

constructorBuilder.addComment("===== init $name: $type =====")

val parentClassName = parent.type.parseClassName()
val layoutParamsName = paramNameOf(name)
val parentClassName = parent.type.toClassName()
val layoutParamsName = layoutParamsNameOf(name)

constructorBuilder.addCode("""
this.$name = new $T(context);
$T.LayoutParams $layoutParamsName = new $T.LayoutParams(${width.value}, ${height.value});
""".trimIndent(), typeClassName,
parentClassName, parentClassName)
constructorBuilder.addStatement("""
this.$name = new $T(context)
""".trimIndent(), typeClassName)
constructorBuilder.addStatement("""
$T.LayoutParams $layoutParamsName = new $T.LayoutParams(${width.value}, ${height.value})
""".trimIndent(), parentClassName, parentClassName)

// parse other attrs here...

constructorBuilder.addCode("""
this.$name.setLayoutParams($layoutParamsName);
constructorBuilder.addStatement("""
this.$name.setLayoutParams($layoutParamsName)
""".trimIndent())

if (!isRoot) {
constructorBuilder.addCode("""
this.${parent.id}.addView(this.$name);
constructorBuilder.addStatement("""
this.${parent.id}.addView(this.$name)
""".trimIndent())
}

constructorBuilder.addComment("===== end $name: $type =====")
}

private fun setRoot(node: ViewType) {
val rootViewClassName = node.type.parseClassName()
val rootViewClassName = node.type.toClassName()
val root = FieldSpec.builder(rootViewClassName, ROOT_VIEW_NAME,
Modifier.PRIVATE, Modifier.FINAL).build()
fields.add(root)

constructorBuilder.addCode("""
this.$ROOT_VIEW_NAME = this.${node.id};
constructorBuilder.addStatement("""
this.$ROOT_VIEW_NAME = this.${node.id}
""".trimIndent())

val getRootView = MethodSpec.methodBuilder("getRootView").apply {
addModifiers(Modifier.PUBLIC)
returns(rootViewClassName)
addCode("""
return $ROOT_VIEW_NAME;
addStatement("""
return $ROOT_VIEW_NAME
""".trimIndent())
}.build()
methods.add(getRootView)
Expand Down Expand Up @@ -195,22 +200,26 @@ class LayoutParser(
private fun initToolsMethods() {
val create = MethodSpec.methodBuilder("create").apply {
addModifiers(Modifier.PUBLIC, Modifier.STATIC)
addParameter(CONTEXT_CLASS_NAME, "context")
addParameter(cnContext, "context")
returns(generateClassName)
addCode("""
return new $T(context);
addStatement("""
return new $T(context)
""".trimIndent(), generateClassName)
}.build()
methods.add(create)
val setContentView = MethodSpec.methodBuilder("setContentView").apply {
addModifiers(Modifier.PUBLIC, Modifier.STATIC)
addParameter(ACTIVITY_CLASSNAME, "activity")
addParameter(cnActivity, "activity")
returns(generateClassName)
addCode("""
$T layout = $T.create(activity);
activity.setContentView(layout.$ROOT_VIEW_NAME);
return layout;
addStatement("""
$T layout = $T.create(activity)
""".trimIndent(), generateClassName, generateClassName)
addStatement("""
activity.setContentView(layout.$ROOT_VIEW_NAME)
""".trimIndent())
addStatement("""
return layout
""".trimIndent())
}.build()
methods.add(setContentView)
}
Expand All @@ -223,37 +232,4 @@ class LayoutParser(

private fun String.findNumber() = split("\\D").joinToString(separator = "").toInt()
private fun String.findNonNumber() = split("\\d").joinToString(separator = "")
private fun String.parsePackageName(): String {
var packageName = this
val dot = packageName.lastIndexOf(".")
if (dot > 0) {
packageName = packageName.substring(0, dot)
} else {
packageName = ""
}
return packageName
}
private fun String.parseSimpleClassName(): String {
var simpleName = this
val dot = simpleName.lastIndexOf(".")
if (dot > 0) {
simpleName = simpleName.substring(dot + 1)
}
return simpleName
}
private fun String.parseClassName() = ClassName.get(parsePackageName(), parseSimpleClassName())
private fun String.underlineToUpperCamel(): String {
val words = split("_")
return words.joinToString(separator = "") { it.upperCaseFirst() }
}
private fun String.upperCaseFirst(): String {
val sb = StringBuilder()
if (length > 0) {
sb.append(substring(0, 1).toUpperCase())
if (length > 1) {
sb.append(substring(1))
}
}
return sb.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package moe.haruue.layoutparser.compiler
import com.google.auto.service.AutoService
import moe.haruue.annotation.LayoutAdapter
import moe.haruue.annotation.ViewCreator
import org.xmlpull.mxp1.MXParserFactory
import java.io.File
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
Expand All @@ -24,17 +25,28 @@ class LayoutProcessor : AbstractProcessor() {

lateinit var rootDir: File
lateinit var projectDir: File
lateinit var packageName: File
lateinit var packageName: String
lateinit var buildDir: File
lateinit var resDirs: List<File>
lateinit var layouts: List<File>
var complete = false


val xmlPullParser by lazy {
val factory = MXParserFactory.newInstance()
with(factory) {
isNamespaceAware = true
}
factory.newPullParser()
}


override fun init(processingEnv: ProcessingEnvironment) {
super.init(processingEnv)

rootDir = File(processingEnv.options["layoutinflater.rootDir"])
projectDir = File(processingEnv.options["layoutinflater.projectDir"])
packageName = File(processingEnv.options["layoutinflater.packageName"])
packageName = processingEnv.options["layoutinflater.packageName"]!!
buildDir = File(processingEnv.options["layoutinflater.buildDir"])
resDirs = processingEnv.options["layoutinflater.resDirs"]!!.split(",").map { File(it) }
layouts = processingEnv.options["layoutinflater.layouts"]!!.split(",").map { File(it) }
Expand Down Expand Up @@ -66,6 +78,18 @@ class LayoutProcessor : AbstractProcessor() {
}
}

if (!complete) {
log("===== processing layout files =====")
val xml = xmlPullParser
for (layout in layouts) {
log("layout: $layout")
xml.setInput(layout.reader())
LayoutParser(packageName, layout.nameWithoutExtension, xml)
.toJavaFile().writeTo(processingEnv.filer)
}
complete = true
log("===== processed layout files =====")
}

log(">>>>> process() end")
return false
Expand All @@ -74,7 +98,8 @@ class LayoutProcessor : AbstractProcessor() {
override fun getSupportedAnnotationTypes(): MutableSet<String> {
return mutableSetOf(
LayoutAdapter::class.java.name,
ViewCreator::class.java.name
ViewCreator::class.java.name,
"*"
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package moe.haruue.layoutparser.compiler.tools

import com.squareup.javapoet.ClassName

/**
*
* @author Haruue Icymoon [email protected]
*/
val cnContext = ClassName.get("android.content", "Context")
val cnActivity = ClassName.get("android.app", "Activity")
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fun String.parseSimpleClassName(): String {
return simpleName
}

fun String.parseClassName() = ClassName.get(parsePackageName(), parseSimpleClassName())
fun String.toClassName(): ClassName = ClassName.get(parsePackageName(), parseSimpleClassName())

fun String.underlineToUpperCamel(): String {
val words = split("_")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class TestPlugin : Plugin<Project> {
it.javaCompileOptions.annotationProcessorOptions.arguments["layoutinflater.packageName"] = packageName
it.javaCompileOptions.annotationProcessorOptions.arguments["layoutinflater.buildDir"] = buildDir.absolutePath
it.javaCompileOptions.annotationProcessorOptions.arguments["layoutinflater.resDirs"] = resDirs.joinToString(separator = ",")
it.javaCompileOptions.annotationProcessorOptions.arguments["layoutinflater.layouts"] = resDirs.joinToString(separator = ",")
it.javaCompileOptions.annotationProcessorOptions.arguments["layoutinflater.layouts"] = layouts.joinToString(separator = ",")

}
}
Expand Down

0 comments on commit 8e4a91f

Please sign in to comment.