Move shared code between build and compiler to a separate project
This CL encapsulates the shared code between build time and annotation
processing into a separate project. This project has no dependency on
kotlin so we can easily use it in gradle plugin.
Bug: 21815393
Change-Id: I9fd2e88885d06ff5423121747817ffcd056e8c74
diff --git a/compiler/build.gradle b/compiler/build.gradle
index 2dddd03..6337d71 100644
--- a/compiler/build.gradle
+++ b/compiler/build.gradle
@@ -1,5 +1,3 @@
-import android.databinding.LicenseCollector
-
/*
* Copyright (C) 2014 The Android Open Source Project
*
@@ -15,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+import android.databinding.LicenseCollector
apply plugin: 'java'
apply plugin: "kotlin"
@@ -33,17 +31,8 @@
}
}
-sourceSets {
- main {
- java {
- srcDir 'src/main/java'
- srcDir 'src/main/grammar-gen'
- srcDir 'src/main/xml-gen'
- }
- }
-}
-
dependencies {
+ compile project(":compilerCommon")
compile project(':baseLibrary')
compile 'org.apache.commons:commons-lang3:3.3.2'
compile 'commons-io:commons-io:2.4'
@@ -77,19 +66,6 @@
tasks['compileTestKotlin'].dependsOn libProject.tasks['uploadJarArchives']
}
-project.tasks.create(name : "generateXmlParser", type : JavaExec) {
- classpath configurations.runtime
- main "org.antlr.v4.Tool"
- workingDir projectDir
- args "XMLParser.g4", "-visitor", "-o", "src/main/java/android/databinding/parser", "-package", "android.databinding.parser", "-lib", "."
-}
-
-project.tasks.create(name : "generateGrammar", type : JavaExec) {
- classpath configurations.runtime
- main "org.antlr.v4.Tool"
- args "BindingExpression.g4", "-visitor", "-o", "src/main/grammar-gen/android/databinding/parser", "-package", "android.databinding.parser"
-}
-
task fatJar(type: Jar) {
baseName = project.name + '-all'
doFirst {
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
index 52947a8..01aa88f 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java
@@ -32,6 +32,7 @@
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
public class AnnotationAnalyzer extends ModelAnalyzer {
@@ -52,6 +53,12 @@
public AnnotationAnalyzer(ProcessingEnvironment processingEnvironment) {
mProcessingEnv = processingEnvironment;
setInstance(this);
+ L.setClient(new L.Client() {
+ @Override
+ public void printMessage(Diagnostic.Kind kind, String message) {
+ mProcessingEnv.getMessager().printMessage(kind, message);
+ }
+ });
}
public static AnnotationAnalyzer get() {
diff --git a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
index 4f07546..d5911ea 100644
--- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
+++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
@@ -15,6 +15,7 @@
*/
package android.databinding.tool.store;
+import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
@@ -35,7 +36,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
@@ -796,7 +796,7 @@
@Override
public int hashCode() {
- return Objects.hash(viewType, attributeIndices.keySet());
+ return Objects.hashCode(viewType, attributeIndices.keySet());
}
}
@@ -833,7 +833,7 @@
@Override
public int hashCode() {
- return Objects.hash(type, method);
+ return Objects.hashCode(type, method);
}
@Override
@@ -857,7 +857,7 @@
@Override
public int hashCode() {
- return Objects.hash(viewType, valueType);
+ return Objects.hashCode(viewType, valueType);
}
@Override
diff --git a/compiler/src/main/kotlin/android/databinding/tool/util/ParserHelper.kt b/compiler/src/main/kotlin/android/databinding/tool/util/ParserHelper.kt
deleted file mode 100644
index 772349e..0000000
--- a/compiler/src/main/kotlin/android/databinding/tool/util/ParserHelper.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * 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 android.databinding.tool.util
-
-object ParserHelper {
- public fun toClassName(name:String) : String {
- return stripExtension(name).split("[_-]".toRegex()).map { it.capitalize() }.join("")
- }
-
-
- public fun stripExtension(name : String) : String {
- val dot = name.indexOf(".")
- return if (dot == -1) name else name.substring(0, name.indexOf("."))
- }
-}
\ No newline at end of file
diff --git a/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt b/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt
deleted file mode 100644
index f5bc143..0000000
--- a/compiler/src/main/kotlin/android/databinding/tool/util/XmlEditor.kt
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * 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 android.databinding.tool.util
-
-import android.databinding.parser.BindingExpressionLexer
-import android.databinding.parser.BindingExpressionParser
-import android.databinding.parser.XMLParser
-import android.databinding.parser.XMLLexer
-import android.databinding.tool.ext
-import java.io.File
-import org.antlr.v4.runtime.ANTLRInputStream
-import java.io.FileReader
-import org.antlr.v4.runtime.CommonTokenStream
-import java.util.Comparator
-import com.google.common.base.Preconditions
-import org.antlr.v4.runtime.Token
-import org.apache.commons.lang3.StringEscapeUtils
-import java.util.ArrayList
-import java.util.regex.Pattern
-
-fun Token.toS() : String = "[L:${getLine()} CH:${getCharPositionInLine()}]"
-
-fun Token.toPosition() : Position = Position(getLine() -1 , getCharPositionInLine())
-
-fun Token.toEndPosition() : Position = Position(getLine() - 1 , getCharPositionInLine() + getText().length())
-
-data class Position(var line : Int, var charIndex : Int) {
-}
-
-/**
- * Ugly inefficient class to strip unwanted tags from XML.
- * Band-aid solution to unblock development
- */
-object XmlEditor {
- fun XMLParser.ElementContext.nodeName() = this.elmName.getText()
-
- fun XMLParser.ElementContext.attributes() =
- if (attribute() == null) {
- arrayListOf<XMLParser.AttributeContext>()
- } else {
- attribute()
- }
-
- fun XMLParser.ElementContext.hasExpressionAttributes() : kotlin.Boolean {
- val expressions = expressionAttributes()
- return expressions.size() > 1 || (expressions.size() == 1 &&
- !expressions.get(0).attrName.getText().equals("android:tag"))
- }
-
- fun XMLParser.ElementContext.expressionAttributes() = attributes().filter {
- val attrName = it.attrName.getText();
- val value = it.attrValue.getText()
- attrName.equals("android:tag") ||
- (value.startsWith("\"@{") && value.endsWith("}\"")) ||
- (value.startsWith("\'@{") && value.endsWith("}\'"))
- }
-
- fun XMLParser.ElementContext.endTagPosition(): Position {
- if (content() == null) {
- // no content, so just subtract from the "/>"
- val endTag = getStop().toEndPosition()
- Preconditions.checkState(endTag.charIndex > 0)
- endTag.charIndex -= 2
- return endTag
- } else {
- // tag with no attributes, but with content
- val position = content().getStart().toPosition()
- Preconditions.checkState(position.charIndex > 0)
- position.charIndex--
- return position
- }
- }
-
- fun XMLParser.ElementContext.elements() : List<XMLParser.ElementContext> {
- if (content() != null && content().element() != null) {
- return content().element()
- } else {
- return arrayListOf<XMLParser.ElementContext>()
- }
- }
-
- fun strip(f: File, newTag: String? = null): String? {
- val inputStream = ANTLRInputStream(FileReader(f))
- val lexer = XMLLexer(inputStream)
- val tokenStream = CommonTokenStream(lexer)
- val parser = XMLParser(tokenStream)
- val expr = parser.document()
- val root = expr.element()
-
- if (root == null || !"layout".equals(root.nodeName())) {
- return null; // not a binding layout
- }
-
- val dataNodes = root.elements().filter { "data".equals(it.nodeName()) }
- Preconditions.checkState(dataNodes.size() < 2,
- "Multiple binding data tags. Expecting a maximum of one.");
-
- val lines = arrayListOf<String>()
- lines.addAll(f.readLines("utf-8"))
-
- dataNodes.forEach {
- replace(lines, it.getStart().toPosition(), it.getStop().toEndPosition(), "")
- }
-
- val layoutNodes = root.elements().filter { !"data".equals(it.nodeName()) }
- Preconditions.checkState(layoutNodes.size() == 1,
- "Only one layout element and one data element are allowed")
-
- val layoutNode = layoutNodes.get(0)
-
- val noTag = arrayListOf<Pair<String, XMLParser.ElementContext>>()
-
- recurseReplace(layoutNode, lines, noTag, newTag, 0)
-
- // Remove the <layout>
- val rootStartTag = root.getStart().toPosition()
- val rootEndTag = root.content().getStart().toPosition();
- replace(lines, rootStartTag, rootEndTag, "")
-
- // Remove the </layout>
- val endLayoutPositions = findTerminalPositions(root, lines)
- replace(lines, endLayoutPositions.first, endLayoutPositions.second, "")
-
- val rootAttributes = StringBuilder()
- root.attributes().fold(rootAttributes) {
- str : StringBuilder, attr -> str.append(' ').append(attr.getText())
- }
-
- val noTagRoot = noTag.firstOrNull() { it.second == layoutNode }
- if (noTagRoot != null) {
- val newRootTag = Pair(noTagRoot.first + rootAttributes.toString(), layoutNode)
- val index = noTag.indexOf(noTagRoot)
- noTag.set(index, newRootTag)
- } else {
- val newRootTag = Pair(rootAttributes.toString(), layoutNode)
- noTag.add(newRootTag)
- }
-
- noTag.sortBy(object : Comparator<Pair<String, XMLParser.ElementContext>> {
- override fun compare(o1: Pair<String, XMLParser.ElementContext>,
- o2: Pair<String, XMLParser.ElementContext>): Int {
- val start1 = o1.second.getStart().toPosition()
- val start2 = o2.second.getStart().toPosition()
- val lineCmp = start2.line.compareTo(start1.line)
- if (lineCmp != 0) {
- return lineCmp
- }
- return start2.charIndex.compareTo(start2.charIndex)
- }
- }).forEach {
- val element = it.second
- val tag = it.first;
- val endTagPosition = element.endTagPosition()
- fixPosition(lines, endTagPosition)
- val line = lines.get(endTagPosition.line)
- val newLine = line.substring(0, endTagPosition.charIndex) +
- " ${tag}" + line.substring(endTagPosition.charIndex)
- lines.set(endTagPosition.line, newLine)
- }
-
- return lines.fold(StringBuilder()) { sb, line ->
- sb.append(line).append(System.getProperty("line.separator"))
- }.toString()
- }
-
- fun findTerminalPositions(node : XMLParser.ElementContext, lines : ArrayList<String>) :
- Pair<Position, Position> {
- val endPosition = node.getStop().toEndPosition()
- val startPosition = node.getStop().toPosition()
- var index : kotlin.Int
- do {
- index = lines.get(startPosition.line).lastIndexOf("</")
- startPosition.line--
- } while (index < 0)
- startPosition.line++
- startPosition.charIndex = index
- return Pair(startPosition, endPosition)
- }
-
- fun recurseReplace(node : XMLParser.ElementContext, lines : ArrayList<String>,
- noTag : ArrayList<Pair<String, XMLParser.ElementContext>>,
- newTag : String?, bindingIndex : kotlin.Int) : kotlin.Int {
- var nextBindingIndex = bindingIndex
- val isMerge = "merge".equals(node.nodeName())
- if (!isMerge && (node.hasExpressionAttributes() || newTag != null)) {
- var tag = ""
- if (newTag != null) {
- tag = "android:tag=\"${newTag}_${bindingIndex}\""
- nextBindingIndex++
- } else if (!"include".equals(node.nodeName())) {
- tag = "android:tag=\"binding_${bindingIndex}\""
- nextBindingIndex++
- }
- node.expressionAttributes().forEach {
- val start = it.getStart().toPosition()
- val end = it.getStop().toEndPosition()
- val defaultVal = defaultReplacement(it)
- if (defaultVal != null) {
- replace(lines, start, end, "${it.attrName.getText()}=\"${defaultVal}\"")
- } else if (replace(lines, start, end, tag)) {
- tag = ""
- }
- }
- if (tag.length() != 0) {
- noTag.add(Pair(tag, node))
- }
- }
-
- val nextTag : String?
- if (bindingIndex == 0 && isMerge) {
- nextTag = newTag
- } else {
- nextTag = null
- }
- node.elements().forEach {
- nextBindingIndex = recurseReplace(it, lines, noTag, nextTag, nextBindingIndex)
- }
- return nextBindingIndex
- }
-
- fun defaultReplacement(attr : XMLParser.AttributeContext) : String? {
- val textWithQuotes = attr.attrValue.getText()
- val escapedText = textWithQuotes.substring(1, textWithQuotes.length() - 1)
- if (!escapedText.startsWith("@{") || !escapedText.endsWith("}")) {
- return null;
- }
- val text = StringEscapeUtils.unescapeXml(escapedText.substring(2, escapedText.length() - 1))
- val inputStream = ANTLRInputStream(text)
- val lexer = BindingExpressionLexer(inputStream)
- val tokenStream = CommonTokenStream(lexer)
- val parser = BindingExpressionParser(tokenStream)
- val root = parser.bindingSyntax()
- val defaults = root.defaults()
- if (defaults != null) {
- val constantValue = defaults.constantValue()
- val literal = constantValue.literal()
- if (literal != null) {
- val stringLiteral = literal.stringLiteral()
- if (stringLiteral != null) {
- val doubleQuote = stringLiteral.DoubleQuoteString()
- if (doubleQuote != null) {
- val quotedStr = doubleQuote.getText()
- val unquoted = quotedStr.substring(1, quotedStr.length() - 1)
- return StringEscapeUtils.escapeXml10(unquoted)
- } else {
- val quotedStr = stringLiteral.SingleQuoteString().getText()
- val unquoted = quotedStr.substring(1, quotedStr.length() - 1)
- val unescaped = unquoted.replace("\"", "\\\"").replace("\\`", "`")
- return StringEscapeUtils.escapeXml10(unescaped)
- }
- }
- }
- return constantValue.getText()
- }
- return null
- }
-
- fun replace(lines : ArrayList<String>, start: Position, end: Position, text: String) :
- kotlin.Boolean {
- fixPosition(lines, start)
- fixPosition(lines, end)
- if (start.line != end.line) {
- val startLine = lines.get(start.line)
- val newStartLine = startLine.substring(0, start.charIndex) +
- text;
- lines.set(start.line, newStartLine)
- for (i in start.line + 1 .. end.line - 1) {
- val line = lines.get(i)
- lines.set(i, replaceWithSpaces(line, 0, line.length() - 1))
- }
- val endLine = lines.get(end.line)
- val newEndLine = replaceWithSpaces(endLine, 0, end.charIndex - 1)
- lines.set(end.line, newEndLine)
- return true
- } else if (end.charIndex - start.charIndex >= text.length()) {
- val line = lines.get(start.line)
- val endTextIndex = start.charIndex + text.length()
- val replacedText = line.replaceRange(start.charIndex, endTextIndex, text)
- val spacedText = replaceWithSpaces(replacedText, endTextIndex, end.charIndex - 1)
- lines.set(start.line, spacedText)
- return true
- } else {
- val line = lines.get(start.line)
- val newLine = replaceWithSpaces(line, start.charIndex, end.charIndex - 1)
- lines.set(start.line, newLine)
- return false;
- }
- }
-
- fun replaceWithSpaces(line : String, start : kotlin.Int, end : kotlin.Int) : String {
- val lineBuilder = StringBuilder(line)
- for (i in start..end) {
- lineBuilder.setCharAt(i, ' ')
- }
- return lineBuilder.toString()
- }
-
- fun fixPosition(lines : ArrayList<String>, pos : Position) {
- val line = lines.get(pos.line)
- while (pos.charIndex > line.length()) {
- pos.charIndex--
- }
- }
-}
diff --git a/compiler/BindingExpression.g4 b/compilerCommon/BindingExpression.g4
similarity index 100%
rename from compiler/BindingExpression.g4
rename to compilerCommon/BindingExpression.g4
diff --git a/compiler/XMLLexer.g4 b/compilerCommon/XMLLexer.g4
similarity index 100%
rename from compiler/XMLLexer.g4
rename to compilerCommon/XMLLexer.g4
diff --git a/compiler/XMLParser.g4 b/compilerCommon/XMLParser.g4
similarity index 100%
rename from compiler/XMLParser.g4
rename to compilerCommon/XMLParser.g4
diff --git a/compilerCommon/build.gradle b/compilerCommon/build.gradle
new file mode 100644
index 0000000..2531c02
--- /dev/null
+++ b/compilerCommon/build.gradle
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+apply plugin: 'java'
+
+
+version = '1.0'
+sourceCompatibility = config.javaTargetCompatibility
+targetCompatibility = config.javaSourceCompatibility
+repositories {
+ mavenCentral()
+}
+
+sourceSets {
+ main {
+ java {
+ srcDir 'src/main/java'
+ srcDir 'src/main/xml-gen'
+ srcDir 'src/main/grammar-gen'
+ }
+ }
+}
+
+dependencies {
+ testCompile group: 'junit', name: 'junit', version: '4.11'
+ compile project(':baseLibrary')
+ compile 'org.apache.commons:commons-lang3:3.3.2'
+ compile 'com.google.guava:guava:17.0'
+ compile 'com.tunnelvisionlabs:antlr4:4.5'
+ compile 'commons-io:commons-io:2.4'
+}
+
+project.tasks.create(name : "generateXmlParser", type : JavaExec) {
+ classpath configurations.runtime
+ main "org.antlr.v4.Tool"
+ workingDir projectDir
+ args "XMLParser.g4", "-visitor", "-o", "src/main/java/android/databinding/parser", "-package", "android.databinding.parser", "-lib", "."
+}
+
+project.tasks.create(name : "generateGrammar", type : JavaExec) {
+ classpath configurations.runtime
+ main "org.antlr.v4.Tool"
+ args "BindingExpression.g4", "-visitor", "-o", "src/main/grammar-gen/android/databinding/parser", "-package", "android.databinding.parser"
+}
+
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens
similarity index 100%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
similarity index 99%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
index db87538..400c422 100644
--- a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
@@ -2,7 +2,6 @@
package android.databinding.parser;
import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
similarity index 99%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
index d7d426e..a664007 100644
--- a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
@@ -1,6 +1,5 @@
// Generated from BindingExpression.g4 by ANTLR 4.4
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java
similarity index 100%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens
similarity index 100%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
similarity index 99%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
index 020be83..80e4a78 100644
--- a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
@@ -1,6 +1,5 @@
// Generated from BindingExpression.g4 by ANTLR 4.4
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeListener;
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
similarity index 99%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
index 0d41591..8463e9f 100644
--- a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
@@ -1,13 +1,9 @@
// Generated from BindingExpression.g4 by ANTLR 4.4
package android.databinding.parser;
import org.antlr.v4.runtime.atn.*;
-import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
public class BindingExpressionParser extends Parser {
public static final int
diff --git a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
similarity index 99%
rename from compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
rename to compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
index d589a7d..1f80a34 100644
--- a/compiler/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
@@ -1,6 +1,5 @@
// Generated from BindingExpression.g4 by ANTLR 4.4
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
diff --git a/compiler/src/main/java/android/databinding/tool/LayoutXmlProcessor.java b/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
similarity index 100%
rename from compiler/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
rename to compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
diff --git a/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java b/compilerCommon/src/main/java/android/databinding/tool/store/LayoutFileParser.java
similarity index 98%
rename from compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java
rename to compilerCommon/src/main/java/android/databinding/tool/store/LayoutFileParser.java
index 2c9ad19..6cfbd96 100644
--- a/compiler/src/main/java/android/databinding/tool/store/LayoutFileParser.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/store/LayoutFileParser.java
@@ -64,7 +64,7 @@
public ResourceBundle.LayoutFileBundle parseXml(File xml, String pkg, int minSdk)
throws ParserConfigurationException, IOException, SAXException,
XPathExpressionException {
- final String xmlNoExtension = ParserHelper.INSTANCE$.stripExtension(xml.getName());
+ final String xmlNoExtension = ParserHelper.stripExtension(xml.getName());
final String newTag = xml.getParentFile().getName() + '/' + xmlNoExtension;
File original = stripFileAndGetOriginal(xml, newTag);
if (original == null) {
@@ -256,7 +256,7 @@
}
private void stripBindingTags(File xml, String newTag) throws IOException {
- String res = XmlEditor.INSTANCE$.strip(xml, newTag);
+ String res = XmlEditor.strip(xml, newTag);
if (res != null) {
L.d("file %s has changed, overwriting %s", xml.getName(), xml.getAbsolutePath());
FileUtils.writeStringToFile(xml, res);
diff --git a/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java b/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
similarity index 98%
rename from compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java
rename to compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
index 732cc9b..b426170 100644
--- a/compiler/src/main/java/android/databinding/tool/store/ResourceBundle.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
@@ -237,7 +237,7 @@
if ("layout".equals(parentFileName)) {
configName = "";
} else {
- configName = ParserHelper.INSTANCE$.toClassName(parentFileName.substring("layout-".length()));
+ configName = ParserHelper.toClassName(parentFileName.substring("layout-".length()));
}
} else {
configName = "";
@@ -383,7 +383,7 @@
if (mFullBindingClass == null) {
if (mBindingClass == null) {
mFullBindingClass = getModulePackage() + ".databinding." +
- ParserHelper.INSTANCE$.toClassName(getFileName()) + "Binding";
+ ParserHelper.toClassName(getFileName()) + "Binding";
} else if (mBindingClass.startsWith(".")) {
mFullBindingClass = getModulePackage() + mBindingClass;
} else if (mBindingClass.indexOf('.') < 0) {
diff --git a/compiler/src/main/java/android/databinding/tool/util/L.java b/compilerCommon/src/main/java/android/databinding/tool/util/L.java
similarity index 72%
rename from compiler/src/main/java/android/databinding/tool/util/L.java
rename to compilerCommon/src/main/java/android/databinding/tool/util/L.java
index aee1fea..478ff58 100644
--- a/compiler/src/main/java/android/databinding/tool/util/L.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/L.java
@@ -18,14 +18,28 @@
import org.apache.commons.lang3.exception.ExceptionUtils;
-import android.databinding.tool.reflection.ModelAnalyzer;
-import android.databinding.tool.reflection.annotation.AnnotationAnalyzer;
-
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
public class L {
- static boolean sEnableDebug = false;
+ private static boolean sEnableDebug = false;
+ private static final Client sSystemClient = new Client() {
+ @Override
+ public void printMessage(Kind kind, String message) {
+ if (kind == Kind.ERROR) {
+ System.err.println(message);
+ } else {
+ System.out.println(message);
+ }
+ }
+ };
+
+ private static Client sClient = sSystemClient;
+
+ public static void setClient(Client systemClient) {
+ L.sClient = systemClient;
+ }
+
public static void setDebugLog(boolean enabled) {
sEnableDebug = enabled;
}
@@ -62,20 +76,13 @@
}
private static void printMessage(Diagnostic.Kind kind, String message) {
- ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
- System.out.println("[" + kind.name() + "]: " + message);
- if (modelAnalyzer instanceof AnnotationAnalyzer) {
- ((AnnotationAnalyzer) modelAnalyzer).getProcessingEnv().getMessager()
- .printMessage(kind, message);
- if (kind == Diagnostic.Kind.ERROR) {
- throw new RuntimeException("failure, see logs for details.\n" + message);
- }
- } else {
-
- if (kind == Diagnostic.Kind.ERROR) {
- throw new RuntimeException(message);
- }
+ sClient.printMessage(kind, message);
+ if (kind == Diagnostic.Kind.ERROR) {
+ throw new RuntimeException("failure, see logs for details.\n" + message);
}
}
+ public static interface Client {
+ public void printMessage(Diagnostic.Kind kind, String message);
+ }
}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/util/ParserHelper.java b/compilerCommon/src/main/java/android/databinding/tool/util/ParserHelper.java
new file mode 100644
index 0000000..c3740e5
--- /dev/null
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/ParserHelper.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.databinding.tool.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class ParserHelper {
+ public static String toClassName(String name) {
+ StringBuilder builder = new StringBuilder();
+ for (String item : name.split("[_-]")) {
+ builder.append(StringUtils.capitalize(item));
+ }
+ return builder.toString();
+ }
+
+ public static String stripExtension(String name) {
+ final int dot = name.lastIndexOf('.');
+ return dot < 0 ? name : name.substring(0, dot);
+ }
+}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java b/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java
new file mode 100644
index 0000000..ff2896d
--- /dev/null
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.databinding.tool.util;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+import android.databinding.parser.BindingExpressionLexer;
+import android.databinding.parser.BindingExpressionParser;
+import android.databinding.parser.XMLLexer;
+import android.databinding.parser.XMLParser;
+import android.databinding.parser.XMLParser.AttributeContext;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Ugly inefficient class to strip unwanted tags from XML.
+ * Band-aid solution to unblock development
+ */
+public class XmlEditor {
+
+ public static String strip(File f, String newTag) throws IOException {
+ ANTLRInputStream inputStream = new ANTLRInputStream(new FileReader(f));
+ XMLLexer lexer = new XMLLexer(inputStream);
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ XMLParser parser = new XMLParser(tokenStream);
+ XMLParser.DocumentContext expr = parser.document();
+ XMLParser.ElementContext root = expr.element();
+
+ if (root == null || !"layout".equals(nodeName(root))) {
+ return null; // not a binding layout
+ }
+
+ Iterable<? extends XMLParser.ElementContext> dataNodes = Iterables
+ .filter(elements(root), new Predicate<XMLParser.ElementContext>() {
+ @Override
+ public boolean apply(XMLParser.ElementContext input) {
+ return "data".equals(nodeName(input));
+ }
+ });
+ Preconditions.checkState(Iterables.size(dataNodes) < 2,
+ "Multiple binding data tags. Expecting a maximum of one.");
+
+ ArrayList<String> lines = Lists.newArrayList();
+ lines.addAll(FileUtils.readLines(f, "utf-8"));
+
+ for (android.databinding.parser.XMLParser.ElementContext it : dataNodes) {
+ replace(lines, toPosition(it.getStart()), toEndPosition(it.getStop()), "");
+ }
+ Iterable<? extends XMLParser.ElementContext> layoutNodes = Iterables
+ .filter(elements(root), new Predicate<XMLParser.ElementContext>() {
+ @Override
+ public boolean apply(XMLParser.ElementContext input) {
+ return !"data".equals(nodeName(input));
+ }
+ });
+ Preconditions.checkState(Iterables.size(layoutNodes) == 1,
+ "Only one layout element and one data element are allowed");
+
+ final XMLParser.ElementContext layoutNode = Iterables.getFirst(layoutNodes, null);
+
+ ArrayList<Pair<String, android.databinding.parser.XMLParser.ElementContext>> noTag = Lists
+ .newArrayList();
+
+ recurseReplace(layoutNode, lines, noTag, newTag, 0);
+
+ // Remove the <layout>
+ Position rootStartTag = toPosition(root.getStart());
+ Position rootEndTag = toPosition(root.content().getStart());
+ replace(lines, rootStartTag, rootEndTag, "");
+
+ // Remove the </layout>
+ ImmutablePair<Position, Position> endLayoutPositions = findTerminalPositions(root, lines);
+ replace(lines, endLayoutPositions.left, endLayoutPositions.right, "");
+
+ StringBuilder rootAttributes = new StringBuilder();
+ for (AttributeContext attr : attributes(root)) {
+ rootAttributes.append(' ').append(attr.getText());
+ }
+ Optional<Pair<String, XMLParser.ElementContext>> pairOptional = Iterables
+ .tryFind(noTag, new Predicate<Pair<String, XMLParser.ElementContext>>() {
+ @Override
+ public boolean apply(Pair<String, XMLParser.ElementContext> input) {
+ return input.getRight() == layoutNode;
+ }
+ });
+ if (pairOptional.isPresent()) {
+ Pair<String, XMLParser.ElementContext> noTagRoot = pairOptional.get();
+ ImmutablePair<String, XMLParser.ElementContext>
+ newRootTag = new ImmutablePair<>(
+ noTagRoot.getLeft() + rootAttributes.toString(), layoutNode);
+ int index = noTag.indexOf(noTagRoot);
+ noTag.set(index, newRootTag);
+ } else {
+ ImmutablePair<String, XMLParser.ElementContext> newRootTag =
+ new ImmutablePair<>(rootAttributes.toString(), layoutNode);
+ noTag.add(newRootTag);
+ }
+ //noinspection NullableProblems
+ Collections.sort(noTag, new Comparator<Pair<String, XMLParser.ElementContext>>() {
+ @Override
+ public int compare(Pair<String, XMLParser.ElementContext> o1,
+ Pair<String, XMLParser.ElementContext> o2) {
+ Position start1 = toPosition(o1.getRight().getStart());
+ Position start2 = toPosition(o2.getRight().getStart());
+ int lineCmp = Integer.compare(start2.line, start1.line);
+ if (lineCmp != 0) {
+ return lineCmp;
+ }
+ return Integer.compare(start2.charIndex, start1.charIndex);
+ }
+ });
+ for (Pair<String, android.databinding.parser.XMLParser.ElementContext> it : noTag) {
+ XMLParser.ElementContext element = it.getRight();
+ String tag = it.getLeft();
+ Position endTagPosition = endTagPosition(element);
+ fixPosition(lines, endTagPosition);
+ String line = lines.get(endTagPosition.line);
+ String newLine = line.substring(0, endTagPosition.charIndex) + " " + tag +
+ line.substring(endTagPosition.charIndex);
+ lines.set(endTagPosition.line, newLine);
+ }
+ return StringUtils.join(lines, System.getProperty("line.separator"));
+ }
+
+ private static Position toPosition(Token token) {
+ return new Position(token.getLine() - 1, token.getCharPositionInLine());
+ }
+
+ private static Position toEndPosition(Token token) {
+ return new Position(token.getLine() - 1,
+ token.getCharPositionInLine() + token.getText().length());
+ }
+
+ private static String nodeName(XMLParser.ElementContext elementContext) {
+ return elementContext.elmName.getText();
+ }
+
+ private static List<? extends AttributeContext> attributes(XMLParser.ElementContext elementContext) {
+ if (elementContext.attribute() == null) {
+ return Lists.newArrayList();
+ } else {
+ return elementContext.attribute();
+ }
+ }
+
+ private static Iterable<? extends AttributeContext> expressionAttributes(
+ XMLParser.ElementContext elementContext) {
+ return Iterables.filter(attributes(elementContext), new Predicate<AttributeContext>() {
+ @Override
+ public boolean apply(AttributeContext input) {
+ String attrName = input.attrName.getText();
+ String value = input.attrValue.getText();
+ return attrName.equals("android:tag") ||
+ (value.startsWith("\"@{") && value.endsWith("}\"")) ||
+ (value.startsWith("'@{") && value.endsWith("}'"));
+ }
+ });
+ }
+
+ private static Position endTagPosition(XMLParser.ElementContext context) {
+ if (context.content() == null) {
+ // no content, so just subtract from the "/>"
+ Position endTag = toEndPosition(context.getStop());
+ Preconditions.checkState(endTag.charIndex > 0);
+ endTag.charIndex -= 2;
+ return endTag;
+ } else {
+ // tag with no attributes, but with content
+ Position position = toPosition(context.content().getStart());
+ Preconditions.checkState(position.charIndex > 0);
+ position.charIndex--;
+ return position;
+ }
+ }
+
+ private static List<? extends android.databinding.parser.XMLParser.ElementContext> elements(
+ XMLParser.ElementContext context) {
+ if (context.content() != null && context.content().element() != null) {
+ return context.content().element();
+ }
+ return Lists.newArrayList();
+ }
+
+ private static boolean replace(ArrayList<String> lines, Position start, Position end,
+ String text) {
+ fixPosition(lines, start);
+ fixPosition(lines, end);
+ if (start.line != end.line) {
+ String startLine = lines.get(start.line);
+ String newStartLine = startLine.substring(0, start.charIndex) + text;
+ lines.set(start.line, newStartLine);
+ for (int i = start.line + 1; i < end.line; i++) {
+ String line = lines.get(i);
+ lines.set(i, replaceWithSpaces(line, 0, line.length() - 1));
+ }
+ String endLine = lines.get(end.line);
+ String newEndLine = replaceWithSpaces(endLine, 0, end.charIndex - 1);
+ lines.set(end.line, newEndLine);
+ return true;
+ } else if (end.charIndex - start.charIndex >= text.length()) {
+ String line = lines.get(start.line);
+ int endTextIndex = start.charIndex + text.length();
+ String replacedText = replaceRange(line, start.charIndex, endTextIndex, text);
+ String spacedText = replaceWithSpaces(replacedText, endTextIndex, end.charIndex - 1);
+ lines.set(start.line, spacedText);
+ return true;
+ } else {
+ String line = lines.get(start.line);
+ String newLine = replaceWithSpaces(line, start.charIndex, end.charIndex - 1);
+ lines.set(start.line, newLine);
+ return false;
+ }
+ }
+
+ private static String replaceRange(String line, int start, int end, String newText) {
+ return line.substring(0, start) + newText + line.substring(end);
+ }
+
+ private static boolean hasExpressionAttributes(XMLParser.ElementContext context) {
+ Iterable<? extends AttributeContext> expressions = expressionAttributes(context);
+ int size = Iterables.size(expressions);
+ //noinspection ConstantConditions
+ return size > 1 || (size == 1 &&
+ !Iterables.getFirst(expressions, null).attrName.getText().equals("android:tag"));
+ }
+
+ private static int recurseReplace(XMLParser.ElementContext node, ArrayList<String> lines,
+ ArrayList<Pair<String, XMLParser.ElementContext>> noTag,
+ String newTag, int bindingIndex) {
+ int nextBindingIndex = bindingIndex;
+ boolean isMerge = "merge".equals(nodeName(node));
+ if (!isMerge && (hasExpressionAttributes(node) || newTag != null)) {
+ String tag = "";
+ if (newTag != null) {
+ tag = "android:tag=\"" + newTag + "_" + bindingIndex + "\"";
+ nextBindingIndex++;
+ } else if (!"include".equals(nodeName(node))) {
+ tag = "android:tag=\"binding_" + bindingIndex + "\"";
+ nextBindingIndex++;
+ }
+ for (AttributeContext it : expressionAttributes(node)) {
+ Position start = toPosition(it.getStart());
+ Position end = toEndPosition(it.getStop());
+ String defaultVal = defaultReplacement(it);
+ if (defaultVal != null) {
+ replace(lines, start, end, it.attrName.getText() + "=\"" + defaultVal + "\"");
+ } else if (replace(lines, start, end, tag)) {
+ tag = "";
+ }
+ }
+ if (tag.length() != 0) {
+ noTag.add(new ImmutablePair<>(tag, node));
+ }
+ }
+
+ String nextTag;
+ if (bindingIndex == 0 && isMerge) {
+ nextTag = newTag;
+ } else {
+ nextTag = null;
+ }
+ for (XMLParser.ElementContext it : elements(node)) {
+ nextBindingIndex = recurseReplace(it, lines, noTag, nextTag, nextBindingIndex);
+ }
+ return nextBindingIndex;
+ }
+
+ private static String defaultReplacement(XMLParser.AttributeContext attr) {
+ String textWithQuotes = attr.attrValue.getText();
+ String escapedText = textWithQuotes.substring(1, textWithQuotes.length() - 1);
+ if (!escapedText.startsWith("@{") || !escapedText.endsWith("}")) {
+ return null;
+ }
+ String text = StringEscapeUtils
+ .unescapeXml(escapedText.substring(2, escapedText.length() - 1));
+ ANTLRInputStream inputStream = new ANTLRInputStream(text);
+ BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
+ BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax();
+ BindingExpressionParser.DefaultsContext defaults = root.defaults();
+ if (defaults != null) {
+ BindingExpressionParser.ConstantValueContext constantValue = defaults
+ .constantValue();
+ BindingExpressionParser.LiteralContext literal = constantValue.literal();
+ if (literal != null) {
+ BindingExpressionParser.StringLiteralContext stringLiteral = literal
+ .stringLiteral();
+ if (stringLiteral != null) {
+ TerminalNode doubleQuote = stringLiteral.DoubleQuoteString();
+ if (doubleQuote != null) {
+ String quotedStr = doubleQuote.getText();
+ String unquoted = quotedStr.substring(1, quotedStr.length() - 1);
+ return StringEscapeUtils.escapeXml10(unquoted);
+ } else {
+ String quotedStr = stringLiteral.SingleQuoteString().getText();
+ String unquoted = quotedStr.substring(1, quotedStr.length() - 1);
+ String unescaped = unquoted.replace("\"", "\\\"").replace("\\`", "`");
+ return StringEscapeUtils.escapeXml10(unescaped);
+ }
+ }
+ }
+ return constantValue.getText();
+ }
+ return null;
+ }
+
+ private static ImmutablePair<Position, Position> findTerminalPositions(
+ XMLParser.ElementContext node, ArrayList<String> lines) {
+ Position endPosition = toEndPosition(node.getStop());
+ Position startPosition = toPosition(node.getStop());
+ int index;
+ do {
+ index = lines.get(startPosition.line).lastIndexOf("</");
+ startPosition.line--;
+ } while (index < 0);
+ startPosition.line++;
+ startPosition.charIndex = index;
+ //noinspection unchecked
+ return new ImmutablePair<>(startPosition, endPosition);
+ }
+
+ private static String replaceWithSpaces(String line, int start, int end) {
+ StringBuilder lineBuilder = new StringBuilder(line);
+ for (int i = start; i <= end; i++) {
+ lineBuilder.setCharAt(i, ' ');
+ }
+ return lineBuilder.toString();
+ }
+
+ private static void fixPosition(ArrayList<String> lines, Position pos) {
+ String line = lines.get(pos.line);
+ while (pos.charIndex > line.length()) {
+ pos.charIndex--;
+ }
+ }
+
+ private static class Position {
+
+ int line;
+ int charIndex;
+
+ public Position(int line, int charIndex) {
+ this.line = line;
+ this.charIndex = charIndex;
+ }
+ }
+
+}
diff --git a/compiler/src/main/java/android/databinding/tool/writer/JavaFileWriter.java b/compilerCommon/src/main/java/android/databinding/tool/writer/JavaFileWriter.java
similarity index 100%
rename from compiler/src/main/java/android/databinding/tool/writer/JavaFileWriter.java
rename to compilerCommon/src/main/java/android/databinding/tool/writer/JavaFileWriter.java
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLLexer.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLLexer.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParser.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
similarity index 99%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParser.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
index f18a5f0..a375780 100644
--- a/compiler/src/main/xml-gen/android/databinding/parser/XMLParser.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
@@ -6,8 +6,6 @@
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
public class XMLParser extends Parser {
public static final int
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParser.tokens b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParserListener.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
diff --git a/compiler/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
similarity index 100%
rename from compiler/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
rename to compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
diff --git a/databinding.properties b/databinding.properties
index 02460f9..2fc8988 100644
--- a/databinding.properties
+++ b/databinding.properties
@@ -3,8 +3,8 @@
version = 1.0-rc1-SNAPSHOT
releaseVersion = 1.0-rc1-SNAPSHOT
androidPluginVersion = 1.2.3
-javaTargetCompatibility = 1.6
-javaSourceCompatibility = 1.6
+javaTargetCompatibility = 1.7
+javaSourceCompatibility = 1.7
prebuildFolderName=prebuilds
group=com.android.databinding
diff --git a/gradlePlugin/build.gradle b/gradlePlugin/build.gradle
index cd1099e..f22985b 100644
--- a/gradlePlugin/build.gradle
+++ b/gradlePlugin/build.gradle
@@ -37,7 +37,7 @@
dependencies {
compile "com.android.tools.build:gradle:${config.androidPluginVersion}"
compile gradleApi()
- compile project(":compiler")
+ compile project(":compilerCommon")
}
compileJava {
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
index ad64057..c400b98 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBinderPlugin.java
@@ -46,6 +46,7 @@
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.tasks.compile.AbstractCompile;
+import android.databinding.tool.util.L;
import android.databinding.tool.writer.JavaFileWriter;
import java.io.File;
@@ -56,6 +57,7 @@
import java.util.Arrays;
import java.util.List;
+import javax.tools.Diagnostic;
import javax.xml.bind.JAXBException;
public class DataBinderPlugin implements Plugin<Project> {
@@ -95,7 +97,7 @@
if (project == null) {
return;
}
- logger = project.getLogger();
+ setupLogger(project);
String myVersion = readMyVersion();
logD("data binding plugin version is %s", myVersion);
@@ -132,6 +134,20 @@
});
}
+ private void setupLogger(Project project) {
+ logger = project.getLogger();
+ L.setClient(new L.Client() {
+ @Override
+ public void printMessage(Diagnostic.Kind kind, String message) {
+ if (kind == Diagnostic.Kind.ERROR) {
+ logE(null, message);
+ } else {
+ logD(message);
+ }
+ }
+ });
+ }
+
String readMyVersion() {
try {
InputStream stream = getClass().getResourceAsStream("/data_binding_build_info");
@@ -148,6 +164,7 @@
private void createXmlProcessor(Project project)
throws NoSuchFieldException, IllegalAccessException {
+ L.d("creating xml processor for " + project);
Object androidExt = project.getExtensions().getByName("android");
if (!(androidExt instanceof BaseExtension)) {
return;
@@ -165,6 +182,7 @@
private void createXmlProcessorForLibrary(Project project, LibraryExtension lib)
throws NoSuchFieldException, IllegalAccessException {
File sdkDir = lib.getSdkDirectory();
+ L.d("create xml processor for " + lib);
for (TestVariant variant : lib.getTestVariants()) {
logD("test variant %s. dir name %s", variant, variant.getDirName());
BaseVariantData variantData = getVariantData(variant);
@@ -179,6 +197,7 @@
private void createXmlProcessorForApp(Project project, AppExtension appExt)
throws NoSuchFieldException, IllegalAccessException {
+ L.d("create xml processor for " + appExt);
File sdkDir = appExt.getSdkDirectory();
for (TestVariant testVariant : appExt.getTestVariants()) {
TestVariantData variantData = getVariantData(testVariant);
diff --git a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
index 5477467..4eb06b2 100644
--- a/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
+++ b/gradlePlugin/src/main/java/android/databinding/tool/DataBindingExportInfoTask.java
@@ -18,7 +18,6 @@
import android.databinding.tool.util.L;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;
-import kotlin.properties.Delegates;
import java.io.File;
/**
diff --git a/settings.gradle b/settings.gradle
index 4c1696d..0d4e57c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,3 +3,5 @@
include ':compiler'
include ':gradlePlugin'
include 'compilationTests'
+include 'compilerCommon'
+