summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2016-04-21 13:27:52 -0700
committerGeorge Mount <mount@google.com>2016-05-05 10:00:13 -0700
commit78dc9ae6d67ae94bf3f637eeea0848e4f700b7a3 (patch)
tree80f71b808b614afe658fd2e2efbc532f82b8c102
parentc4befae8ade4e14e10a39c259228f142d624a801 (diff)
downloaddata-binding-78dc9ae6d67ae94bf3f637eeea0848e4f700b7a3.tar.gz
Fix problem where root View's style is used instead of bound View's
Bug 27808662 Change-Id: I870b0db47e3ed970a3bd67e602e873e503610028
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java2
-rw-r--r--compiler/src/main/java/android/databinding/tool/CompilerChef.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/ExpressionParser.java3
-rw-r--r--compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/LayoutBinder.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ExprModel.java6
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java47
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt26
-rw-r--r--compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java6
-rw-r--r--compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java6
-rw-r--r--compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java2
-rw-r--r--compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java6
-rw-r--r--extensions/library/src/main/java/android/databinding/ViewDataBinding.java18
13 files changed, 97 insertions, 44 deletions
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
index a4c7af9c..ee5467e2 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
@@ -396,7 +396,7 @@ public class SimpleCompilationTest extends BaseCompilationTest {
}
ModelMethod modelMethod = injectedClass.getMethod(
method.getName(), args, Modifier.isStatic(method.getModifiers()), false);
- assertNotNull(modelMethod);
+ assertNotNull("Method " + method + " not found", modelMethod);
}
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
index 611f3b8f..c167207a 100644
--- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java
+++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
@@ -135,6 +135,11 @@ public class CompilerChef {
"java.lang.Object");
injectedClass.addMethod(new InjectedMethod(injectedClass, true, "getColorFromResource",
"int", "android.view.View", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true,
+ "getColorStateListFromResource", "android.content.res.ColorStateList",
+ "android.view.View", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "getDrawableFromResource",
+ "android.graphics.drawable.Drawable", "android.view.View", "int"));
injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
"boolean", "java.lang.String", "boolean"));
injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
index 8deebc4d..18fb8399 100644
--- a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
+++ b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
@@ -50,11 +50,12 @@ public class ExpressionParser {
visitor = new ExpressionVisitor(mModel);
}
- public Expr parse(String input, @Nullable Location locationInFile) {
+ public Expr parse(String input, @Nullable Location locationInFile, BindingTarget target) {
ANTLRInputStream inputStream = new ANTLRInputStream(input);
BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
final BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
+ visitor.setBindingTarget(target);
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
index 87426c0f..d273f387 100644
--- a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
+++ b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
@@ -47,6 +47,7 @@ class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
private ExprModel mModel;
private ParseTreeListener mParseTreeListener;
private ArrayDeque<ExprModel> mModelStack = new ArrayDeque<ExprModel>();
+ private BindingTarget mTarget;
ExpressionVisitor(ExprModel model) {
mModel = model;
@@ -56,6 +57,10 @@ class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
mParseTreeListener = parseTreeListener;
}
+ public void setBindingTarget(BindingTarget bindingTarget) {
+ mTarget = bindingTarget;
+ }
+
private void onEnter(ParserRuleContext context) {
if (mParseTreeListener != null) {
mParseTreeListener.enterEveryRule(context);
@@ -398,7 +403,7 @@ class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
final int startIndex = Math.max(1, colonIndex + 1);
final String resourceType = resourceReference.substring(startIndex, slashIndex).trim();
final String resourceName = resourceReference.substring(slashIndex + 1).trim();
- return mModel.resourceExpr(packageName, resourceType, resourceName, args);
+ return mModel.resourceExpr(mTarget, packageName, resourceType, resourceName, args);
} finally {
onExit(ctx);
}
diff --git a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
index c7704682..bcbafda6 100644
--- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
@@ -222,7 +222,8 @@ public class LayoutBinder implements FileScopeProvider {
try {
Scope.enter(bindingBundle.getValueLocation());
Expr expr = parse(bindingBundle.getExpr(),
- bindingBundle.getValueLocation());
+ bindingBundle.getValueLocation(),
+ bindingTarget);
bindingTarget.addBinding(bindingBundle.getName(), expr);
if (bindingBundle.isTwoWay()) {
bindingTarget.addInverseBinding(bindingBundle.getName(), expr,
@@ -295,8 +296,8 @@ public class LayoutBinder implements FileScopeProvider {
return target;
}
- public Expr parse(String input, @Nullable Location locationInFile) {
- final Expr parsed = mExpressionParser.parse(input, locationInFile);
+ public Expr parse(String input, @Nullable Location locationInFile, BindingTarget target) {
+ final Expr parsed = mExpressionParser.parse(input, locationInFile, target);
parsed.setBindingExpression(true);
return parsed;
}
diff --git a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
index 87169cee..34b25690 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
@@ -273,9 +273,9 @@ public class ExprModel {
return register(new UnaryExpr(op, expr));
}
- public Expr resourceExpr(String packageName, String resourceType, String resourceName,
- List<Expr> args) {
- return register(new ResourceExpr(packageName, resourceType, resourceName, args));
+ public Expr resourceExpr(BindingTarget target, String packageName, String resourceType,
+ String resourceName, List<Expr> args) {
+ return register(new ResourceExpr(target, packageName, resourceType, resourceName, args));
}
public Expr bracketExpr(Expr variableExpr, Expr argExpr) {
diff --git a/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java
index 2ecf5fb0..df36cf63 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java
@@ -15,9 +15,11 @@
*/
package android.databinding.tool.expr;
+import android.databinding.tool.BindingTarget;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.writer.KCode;
+import android.databinding.tool.writer.LayoutBinderWriterKt;
import java.util.HashMap;
import java.util.List;
@@ -45,9 +47,12 @@ public class ResourceExpr extends Expr {
protected final String mResourceId;
- public ResourceExpr(String packageName, String resourceType, String resourceName,
- List<Expr> args) {
+ protected final BindingTarget mTarget;
+
+ public ResourceExpr(BindingTarget target, String packageName, String resourceType,
+ String resourceName, List<Expr> args) {
super(args);
+ mTarget = target;
if ("android".equals(packageName)) {
mPackage = "android.";
} else {
@@ -121,7 +126,11 @@ public class ResourceExpr extends Expr {
@Override
protected String computeUniqueKey() {
String base = toString();
- return join(base, computeChildrenKey());
+ String view = "";
+ if (requiresView()) {
+ view = LayoutBinderWriterKt.getFieldName(mTarget);
+ }
+ return join(base, view, computeChildrenKey());
}
@Override
@@ -132,7 +141,7 @@ public class ResourceExpr extends Expr {
@Override
public Expr cloneToModel(ExprModel model) {
String pkg = mPackage.isEmpty() ? "" : "android";
- return model.resourceExpr(pkg, mResourceType, mResourceId,
+ return model.resourceExpr(mTarget, pkg, mResourceType, mResourceId,
cloneToModel(model, getChildren()));
}
@@ -146,19 +155,31 @@ public class ResourceExpr extends Expr {
computeUniqueKey();
}
+ private boolean requiresView() {
+ return !mTarget.isBinder() && !("anim".equals(mResourceType) ||
+ "animator".equals(mResourceType) ||
+ "id".equals(mResourceType) ||
+ "interpolator".equals(mResourceType) ||
+ "layout".equals(mResourceType) ||
+ "stateListAnimator".equals(mResourceType) ||
+ "transition".equals(mResourceType));
+ }
+
public String toJava() {
final String context = "getRoot().getContext()";
- final String resources = "getRoot().getResources()";
+ final String viewName = requiresView() ? LayoutBinderWriterKt.getFieldName(mTarget) :
+ "getRoot()";
+ final String resources = viewName + ".getResources()";
final String resourceName = mPackage + "R." + getResourceObject() + "." + mResourceId;
if ("anim".equals(mResourceType)) return "android.view.animation.AnimationUtils.loadAnimation(" + context + ", " + resourceName + ")";
if ("animator".equals(mResourceType)) return "android.animation.AnimatorInflater.loadAnimator(" + context + ", " + resourceName + ")";
if ("bool".equals(mResourceType)) return resources + ".getBoolean(" + resourceName + ")";
- if ("color".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorFromResource(getRoot(), " + resourceName + ")";
- if ("colorStateList".equals(mResourceType)) return "getColorStateListFromResource(" + resourceName + ")";
+ if ("color".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorFromResource(" + viewName + ", " + resourceName + ")";
+ if ("colorStateList".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorStateListFromResource(" + viewName + ", " + resourceName + ")";
if ("dimen".equals(mResourceType)) return resources + ".getDimension(" + resourceName + ")";
if ("dimenOffset".equals(mResourceType)) return resources + ".getDimensionPixelOffset(" + resourceName + ")";
if ("dimenSize".equals(mResourceType)) return resources + ".getDimensionPixelSize(" + resourceName + ")";
- if ("drawable".equals(mResourceType)) return "getDrawableFromResource(" + resourceName + ")";
+ if ("drawable".equals(mResourceType)) return "android.databinding.DynamicUtil.getDrawableFromResource(" + viewName + ", " + resourceName + ")";
if ("fraction".equals(mResourceType)) {
String base = getChildCode(0, "1");
String pbase = getChildCode(1, "1");
@@ -174,11 +195,11 @@ public class ResourceExpr extends Expr {
if (getChildren().isEmpty()) {
return resourceName;
} else {
- return makeParameterCall(resourceName, "getQuantityString");
+ return makeParameterCall(resources, resourceName, "getQuantityString");
}
}
if ("stateListAnimator".equals(mResourceType)) return "android.animation.AnimatorInflater.loadStateListAnimator(" + context + ", " + resourceName + ")";
- if ("string".equals(mResourceType)) return makeParameterCall(resourceName, "getString");
+ if ("string".equals(mResourceType)) return makeParameterCall(resources, resourceName, "getString");
if ("stringArray".equals(mResourceType)) return resources + ".getStringArray(" + resourceName + ")";
if ("transition".equals(mResourceType)) return "android.transition.TransitionInflater.from(" + context + ").inflateTransition(" + resourceName + ")";
if ("typedArray".equals(mResourceType)) return resources + ".obtainTypedArray(" + resourceName + ")";
@@ -196,9 +217,9 @@ public class ResourceExpr extends Expr {
}
}
- private String makeParameterCall(String resourceName, String methodCall) {
- StringBuilder sb = new StringBuilder("getRoot().getResources().");
- sb.append(methodCall).append("(").append(resourceName);
+ private String makeParameterCall(String resources, String resourceName, String methodCall) {
+ StringBuilder sb = new StringBuilder(resources);
+ sb.append('.').append(methodCall).append("(").append(resourceName);
for (Expr expr : getChildren()) {
sb.append(", ").append(expr.toCode().generate());
}
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
index 8d76b030..e7314606 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
@@ -8,13 +8,33 @@ class DynamicUtilWriter() {
nl("")
block("public class DynamicUtil") {
nl("@SuppressWarnings(\"deprecation\")")
- block("public static int getColorFromResource(final android.view.View root, final int resourceId)") {
+ block("public static int getColorFromResource(final android.view.View view, final int resourceId)") {
if (targetSdk >= 23) {
block("if (VERSION.SDK_INT >= VERSION_CODES.M)") {
- nl("return root.getContext().getColor(resourceId);")
+ nl("return view.getContext().getColor(resourceId);")
}
}
- nl("return root.getResources().getColor(resourceId);")
+ nl("return view.getResources().getColor(resourceId);")
+ }
+
+ nl("@SuppressWarnings(\"deprecation\")")
+ block("public static android.content.res.ColorStateList getColorStateListFromResource(final android.view.View view, final int resourceId)") {
+ if (targetSdk >= 23) {
+ block("if (VERSION.SDK_INT >= VERSION_CODES.M)") {
+ nl("return view.getContext().getColorStateList(resourceId);")
+ }
+ }
+ nl("return view.getResources().getColorStateList(resourceId);")
+ }
+
+ nl("@SuppressWarnings(\"deprecation\")")
+ block("public static android.graphics.drawable.Drawable getDrawableFromResource(final android.view.View view, final int resourceId)") {
+ if (targetSdk >= 21) {
+ block("if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP)") {
+ nl("return view.getContext().getDrawable(resourceId);")
+ }
+ }
+ nl("return view.getResources().getDrawable(resourceId);")
}
block("public static boolean parse(String str, boolean fallback)") {
diff --git a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
index 84b032af..3d3d8fed 100644
--- a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
+++ b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
@@ -51,7 +51,7 @@ public class ExpressionVisitorTest {
}
private <T extends Expr> T parse(String input, Class<T> klass) {
- final Expr parsed = mParser.parse(input, null);
+ final Expr parsed = mParser.parse(input, null, null);
assertSame(klass, parsed.getClass());
return (T) parsed;
}
@@ -89,7 +89,7 @@ public class ExpressionVisitorTest {
@Test
public void testComparison() {
- final Expr res = mParser.parse("3 " + mOp + " 5", null);
+ final Expr res = mParser.parse("3 " + mOp + " 5", null, null);
assertEquals(3, mParser.getModel().size());
assertTrue(res instanceof ComparisonExpr);
// 0 because they are both static
@@ -180,7 +180,7 @@ public class ExpressionVisitorTest {
assertEquals(0, parsed.getArgs().size());
assertEquals(1, parsed.getDependencies().size());
final Dependency dep = parsed.getDependencies().get(0);
- assertSame(mParser.parse("user", null), dep.getOther());
+ assertSame(mParser.parse("user", null, null), dep.getOther());
assertFalse(dep.isConditional());
}
diff --git a/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java b/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java
index c7f81ab1..564ecef4 100644
--- a/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java
+++ b/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java
@@ -77,8 +77,8 @@ public class LayoutBinderTest {
int originalSize = mExprModel.size();
mLayoutBinder.addVariable("user", "android.databinding.tool2.LayoutBinderTest.TestUser",
null);
- mLayoutBinder.parse("user.name", null);
- mLayoutBinder.parse("user.lastName", null);
+ mLayoutBinder.parse("user.name", null, null);
+ mLayoutBinder.parse("user.lastName", null, null);
assertEquals(originalSize + 3, mExprModel.size());
final List<Expr> bindingExprs = mExprModel.getBindingExpressions();
assertEquals(2, bindingExprs.size());
@@ -94,7 +94,7 @@ public class LayoutBinderTest {
public void testParseWithMethods() {
mLayoutBinder.addVariable("user", "android.databinding.tool.LayoutBinderTest.TestUser",
null);
- mLayoutBinder.parse("user.fullName", null);
+ mLayoutBinder.parse("user.fullName", null, null);
Expr item = mExprModel.getBindingExpressions().get(0);
assertTrue(item instanceof FieldAccessExpr);
IdentifierExpr id = mExprModel.identifier("user");
diff --git a/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java b/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java
index 2bb8832f..d6fb4707 100644
--- a/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java
+++ b/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java
@@ -57,7 +57,7 @@ public class ExecutionPathTest {
public void simpleExpr() {
MockLayoutBinder lb = new MockLayoutBinder();
ExprModel model = lb.getModel();
- Expr parsed = lb.parse(mExpression, null);
+ Expr parsed = lb.parse(mExpression, null, null);
List<ExecutionPath> paths = new ArrayList<ExecutionPath>();
ExecutionPath root = ExecutionPath.createRoot();
paths.add(root);
diff --git a/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java b/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
index e20dea74..a661c30f 100644
--- a/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
+++ b/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
@@ -154,7 +154,7 @@ public class ExprModelTest {
IdentifierExpr a = lb.addVariable("a", "java.lang.String", null);
IdentifierExpr b = lb.addVariable("b", "java.lang.String", null);
IdentifierExpr c = lb.addVariable("c", "java.lang.String", null);
- lb.parse("a == null ? b : c", null);
+ lb.parse("a == null ? b : c", null, null);
mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class));
lb.getModel().seal();
List<Expr> shouldRead = getShouldRead();
@@ -303,7 +303,7 @@ public class ExprModelTest {
IdentifierExpr c = lb.addVariable("c", "java.lang.String", null);
IdentifierExpr d = lb.addVariable("d", "java.lang.String", null);
IdentifierExpr e = lb.addVariable("e", "java.lang.String", null);
- final Expr aTernary = lb.parse("a == null ? b == null ? c : d : e", null);
+ final Expr aTernary = lb.parse("a == null ? b == null ? c : d : e", null, null);
assertTrue(aTernary instanceof TernaryExpr);
final Expr bTernary = ((TernaryExpr) aTernary).getIfTrue();
assertTrue(bTernary instanceof TernaryExpr);
@@ -1132,7 +1132,7 @@ public class ExprModelTest {
}
private <T extends Expr> T parse(LayoutBinder binder, String input, Class<T> klass) {
- final Expr parsed = binder.parse(input, null);
+ final Expr parsed = binder.parse(input, null, null);
assertTrue(klass.isAssignableFrom(parsed.getClass()));
return (T) parsed;
}
diff --git a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
index 7829c0d1..f50267b8 100644
--- a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
+++ b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
@@ -640,29 +640,29 @@ public abstract class ViewDataBinding extends BaseObservable {
}
/** @hide */
- protected int getColorFromResource(int resourceId) {
+ protected static int getColorFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.M) {
- return getRoot().getContext().getColor(resourceId);
+ return view.getContext().getColor(resourceId);
} else {
- return getRoot().getResources().getColor(resourceId);
+ return view.getResources().getColor(resourceId);
}
}
/** @hide */
- protected ColorStateList getColorStateListFromResource(int resourceId) {
+ protected static ColorStateList getColorStateListFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.M) {
- return getRoot().getContext().getColorStateList(resourceId);
+ return view.getContext().getColorStateList(resourceId);
} else {
- return getRoot().getResources().getColorStateList(resourceId);
+ return view.getResources().getColorStateList(resourceId);
}
}
/** @hide */
- protected Drawable getDrawableFromResource(int resourceId) {
+ protected static Drawable getDrawableFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- return getRoot().getContext().getDrawable(resourceId);
+ return view.getContext().getDrawable(resourceId);
} else {
- return getRoot().getResources().getDrawable(resourceId);
+ return view.getResources().getDrawable(resourceId);
}
}