summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/data-binding/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java2
-rw-r--r--tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/Expr.java16
-rw-r--r--tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java9
-rw-r--r--tools/data-binding/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt5
-rw-r--r--tools/data-binding/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java103
-rw-r--r--tools/data-binding/grammarBuilder/src/test/java/android/databinding/BindingExpressionParserTest.java38
-rw-r--r--tools/data-binding/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/InnerCannotReadDependencyTest.java49
-rw-r--r--tools/data-binding/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/BasicObject.java45
-rw-r--r--tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml4
-rw-r--r--tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/inner_cannot_read_dependency.xml11
10 files changed, 224 insertions, 58 deletions
diff --git a/tools/data-binding/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java b/tools/data-binding/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
index 879c439..a30f59b 100644
--- a/tools/data-binding/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
+++ b/tools/data-binding/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
@@ -93,7 +93,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
public Expr visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) {
final Expr left = ctx.left.accept(this);
return mModel.ternary(mModel.comparison("==", left, mModel.symbol("null", Object.class)),
- left, ctx.right.accept(this));
+ ctx.right.accept(this), left);
}
@Override
diff --git a/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/Expr.java b/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/Expr.java
index a7cd412..09b96d8 100644
--- a/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/Expr.java
+++ b/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/Expr.java
@@ -400,17 +400,12 @@ abstract public class Expr {
return mRead;
}
- public boolean considerElevatingConditionals(Expr cond) {
+ public boolean considerElevatingConditionals(Expr justRead) {
boolean elevated = false;
for (Dependency dependency : mDependencies) {
- if (dependency.isConditional() && dependency.getCondition() == cond) {
+ if (dependency.isConditional() && dependency.getCondition() == justRead) {
dependency.elevate();
- // silent elevate because it is not necessary anymore (already calculated)
- // but need to mark dependencies elevated so that we can decide to calculate
- // this expression when all dependencies are elevated
- if (!dependency.getOther().isRead()) {
- elevated = true;
- }
+ elevated = true;
}
}
return elevated;
@@ -433,7 +428,7 @@ abstract public class Expr {
Predicate<Dependency> hasNestedCannotRead = new Predicate<Dependency>() {
@Override
public boolean apply(Dependency input) {
- return input.getOther().hasNestedCannotRead();
+ return input.isConditional() || input.getOther().hasNestedCannotRead();
}
};
@@ -470,6 +465,9 @@ abstract public class Expr {
}
}
+ if (mRead) {
+ mShouldReadFlags = null; // if we've been marked as read, clear should read flags
+ }
return mRead;
}
diff --git a/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java b/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
index e3ec30a..0f8a935 100644
--- a/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
+++ b/tools/data-binding/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
@@ -26,6 +26,7 @@ import android.databinding.tool.util.L;
import android.databinding.tool.writer.FlagSet;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
@@ -437,12 +438,12 @@ public class ExprModel {
return elevated;
}
- public Iterable<Expr> filterShouldRead(Iterable<Expr> exprs) {
- return Iterables.filter(exprs, sShouldReadPred);
+ public static Iterable<Expr> filterShouldRead(Iterable<Expr> exprs) {
+ return toCollection(Iterables.filter(exprs, sShouldReadPred));
}
- public Iterable<Expr> filterCanBeReadNow(Iterable<Expr> exprs) {
- return Iterables.filter(exprs, sReadNowPred);
+ public static List<Expr> toCollection(Iterable<Expr> iterable) {
+ return Arrays.asList(Iterables.toArray(iterable, Expr.class));
}
private static final Predicate<Expr> sShouldReadPred = new Predicate<Expr>() {
diff --git a/tools/data-binding/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt b/tools/data-binding/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
index 228e759..763c94b 100644
--- a/tools/data-binding/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
+++ b/tools/data-binding/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
@@ -679,7 +679,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
do {
- val batch = model.filterShouldRead(model.getPendingExpressions()).toArrayList()
+ val batch = ExprModel.filterShouldRead(model.getPendingExpressions()).toArrayList()
val mJustRead = arrayListOf<Expr>()
while (!batch.none()) {
val readNow = batch.filter { it.shouldReadNow(mJustRead) }
@@ -758,8 +758,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
// create an if case for all dependencies that might be null
val nullables = expr.getDependencies().filter {
it.isMandatory() && it.getOther().getResolvedType().isNullable()
- }
- .map { it.getOther() }
+ }.map { it.getOther() }
if (!expr.isEqualityCheck() && nullables.isNotEmpty()) {
tab ("if ( ${nullables.map { "${it.localName} != null" }.joinToString(" && ")}) {") {
tab("${expr.localName}").app(" = ", expr.toCode(true)).app(";")
diff --git a/tools/data-binding/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java b/tools/data-binding/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
index ed9934d..7bccd6e 100644
--- a/tools/data-binding/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
+++ b/tools/data-binding/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
@@ -34,6 +34,8 @@ import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.java.JavaAnalyzer;
import android.databinding.tool.util.L;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
@@ -45,8 +47,11 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class ExprModelTest {
+
private static class DummyExpr extends Expr {
+
String mKey;
+
public DummyExpr(String key, DummyExpr... children) {
super(children);
mKey = key;
@@ -76,7 +81,7 @@ public class ExprModelTest {
protected void failed(Throwable e, Description description) {
if (mExprModel != null && mExprModel.getFlagMapping() != null) {
final String[] mapping = mExprModel.getFlagMapping();
- for (int i = 0; i < mapping.length; i ++) {
+ for (int i = 0; i < mapping.length; i++) {
L.d("flag %d: %s", i, mapping[i]);
}
}
@@ -96,6 +101,7 @@ public class ExprModelTest {
assertSame(d, mExprModel.register(d));
assertEquals(1, mExprModel.mExprMap.size());
}
+
@Test
public void testAddDupe1() {
final DummyExpr d = new DummyExpr("a");
@@ -131,8 +137,8 @@ public class ExprModelTest {
IdentifierExpr a = lb.addVariable("a", "java.lang.String");
IdentifierExpr b = lb.addVariable("b", "java.lang.String");
IdentifierExpr c = lb.addVariable("c", "java.lang.String");
- final Expr ternary = lb.parse("a == null ? b : c");
- final Expr equality = mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class));
+ lb.parse("a == null ? b : c");
+ mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class));
lb.getModel().seal();
Iterable<Expr> shouldRead = getShouldRead();
// a and a == null
@@ -147,6 +153,59 @@ public class ExprModelTest {
}
@Test
+ public void testTernaryWithPlus() {
+ LayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ IdentifierExpr user = lb
+ .addVariable("user", "android.databinding.tool.expr.ExprModelTest.User");
+ MathExpr parsed = parse(lb, "user.name + \" \" + (user.lastName ?? \"\")", MathExpr.class);
+ mExprModel.seal();
+ Iterable<Expr> toRead = getShouldRead();
+ Iterable<Expr> readNow = getReadFirst(toRead);
+ assertEquals(1, Iterables.size(readNow));
+ assertSame(user, Iterables.getFirst(readNow, null));
+ List<Expr> justRead = new ArrayList<Expr>();
+ justRead.add(user);
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(2, Iterables.size(readNow)); //user.name && user.lastName
+ Iterables.addAll(justRead, readNow);
+ // user.lastname (T, F), user.name + " "
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(2, Iterables.size(readNow)); //user.name && user.lastName
+ Iterables.addAll(justRead, readNow);
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(0, Iterables.size(readNow));
+ mExprModel.markBitsRead();
+
+ toRead = getShouldRead();
+ assertEquals(2, Iterables.size(toRead));
+ justRead.clear();
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(1, Iterables.size(readNow));
+ assertSame(parsed.getRight(), Iterables.getFirst(readNow, null));
+ Iterables.addAll(justRead, readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(1, Iterables.size(readNow));
+ assertSame(parsed, Iterables.getFirst(readNow, null));
+ Iterables.addAll(justRead, readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertEquals(0, Iterables.size(readNow));
+ mExprModel.markBitsRead();
+ assertEquals(0, Iterables.size(getShouldRead()));
+ }
+
+ private List<Expr> filterOut(Iterable itr, final Iterable exclude) {
+ return Arrays.asList(Iterables.toArray(Iterables.filter(itr, new Predicate() {
+ @Override
+ public boolean apply(Object input) {
+ return !Iterables.contains(exclude, input);
+ }
+ }), Expr.class));
+ }
+
+ @Test
public void testTernaryInsideTernary() {
LayoutBinder lb = new MockLayoutBinder();
mExprModel = lb.getModel();
@@ -202,10 +261,12 @@ public class ExprModelTest {
IdentifierExpr e = lb.addVariable("e", "java.lang.String");
final Expr aTernary = lb.parse("a == null ? b == null ? c : d : e");
assertTrue(aTernary instanceof TernaryExpr);
- final Expr bTernary = ((TernaryExpr)aTernary).getIfTrue();
+ final Expr bTernary = ((TernaryExpr) aTernary).getIfTrue();
assertTrue(bTernary instanceof TernaryExpr);
- final Expr aIsNull = mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class));
- final Expr bIsNull = mExprModel.comparison("==", b, mExprModel.symbol("null", Object.class));
+ final Expr aIsNull = mExprModel
+ .comparison("==", a, mExprModel.symbol("null", Object.class));
+ final Expr bIsNull = mExprModel
+ .comparison("==", b, mExprModel.symbol("null", Object.class));
lb.getModel().seal();
Iterable<Expr> shouldRead = getShouldRead();
// a and a == null
@@ -217,7 +278,6 @@ public class ExprModelTest {
assertTrue(d.getShouldReadFlags().isEmpty());
assertTrue(e.getShouldReadFlags().isEmpty());
-
Iterable<Expr> readFirst = getReadFirst(shouldRead, null);
assertEquals(1, Iterables.size(readFirst));
final Expr first = Iterables.getFirst(readFirst, null);
@@ -267,7 +327,6 @@ public class ExprModelTest {
LayoutBinder lb = new MockLayoutBinder();
mExprModel = lb.getModel();
-
IdentifierExpr u1 = lb.addVariable("u1", User.class.getCanonicalName());
IdentifierExpr u2 = lb.addVariable("u2", User.class.getCanonicalName());
IdentifierExpr a = lb.addVariable("a", int.class.getCanonicalName());
@@ -276,7 +335,8 @@ public class ExprModelTest {
IdentifierExpr d = lb.addVariable("d", int.class.getCanonicalName());
IdentifierExpr e = lb.addVariable("e", int.class.getCanonicalName());
TernaryExpr abTernary = parse(lb, "a > b ? u1.name : u2.name", TernaryExpr.class);
- TernaryExpr bcTernary = parse(lb, "b > c ? u1.getCond(d) ? u1.lastName : u2.lastName : `xx` + u2.getCond(e) ", TernaryExpr.class);
+ TernaryExpr bcTernary = parse(lb, "b > c ? u1.getCond(d) ? u1.lastName : u2.lastName : `xx`"
+ + " + u2.getCond(e) ", TernaryExpr.class);
Expr abCmp = abTernary.getPred();
Expr bcCmp = bcTernary.getPred();
Expr u1GetCondD = ((TernaryExpr) bcTernary.getIfTrue()).getPred();
@@ -287,7 +347,6 @@ public class ExprModelTest {
Expr u1LastName = ((TernaryExpr) bcTernary.getIfTrue()).getIfTrue();
Expr u2LastName = ((TernaryExpr) bcTernary.getIfTrue()).getIfFalse();
-
mExprModel.seal();
Iterable<Expr> shouldRead = getShouldRead();
@@ -314,8 +373,10 @@ public class ExprModelTest {
assertFlags(d, bcTernary.getRequirementFlagIndex(true));
assertFlags(e, bcTernary.getRequirementFlagIndex(false));
- assertFlags(u1, bcTernary.getRequirementFlagIndex(true), abTernary.getRequirementFlagIndex(true));
- assertFlags(u2, bcTernary.getRequirementFlagIndex(false), abTernary.getRequirementFlagIndex(false));
+ assertFlags(u1, bcTernary.getRequirementFlagIndex(true),
+ abTernary.getRequirementFlagIndex(true));
+ assertFlags(u2, bcTernary.getRequirementFlagIndex(false),
+ abTernary.getRequirementFlagIndex(false));
assertFlags(u1GetCondD, bcTernary.getRequirementFlagIndex(true));
assertFlags(u2GetCondE, bcTernary.getRequirementFlagIndex(false));
@@ -342,8 +403,6 @@ public class ExprModelTest {
assertFlags(bcTernary, b, c, u1, u2, d, u1LastName, u2LastName, e);
}
-
-
@Test
public void testCircularDependency() {
LayoutBinder lb = new MockLayoutBinder();
@@ -442,11 +501,13 @@ public class ExprModelTest {
int i = 0;
log("list", iterable);
for (Expr expr : exprs) {
- assertTrue((i++) + ":must contain " + expr.getUniqueKey(), Iterables.contains(iterable, expr));
+ assertTrue((i++) + ":must contain " + expr.getUniqueKey(),
+ Iterables.contains(iterable, expr));
}
i = 0;
for (Expr expr : iterable) {
- assertTrue((i++) + ":must be expected " + expr.getUniqueKey(), ArrayUtils.contains(exprs, expr));
+ assertTrue((i++) + ":must be expected " + expr.getUniqueKey(),
+ ArrayUtils.contains(exprs, expr));
}
}
@@ -459,18 +520,16 @@ public class ExprModelTest {
private void log(String s, Iterable<Expr> iterable) {
L.d(s);
for (Expr e : iterable) {
- L.d(": %s : %s allFlags: %s readSoFar: %s", e.getUniqueKey(), e.getShouldReadFlags(), e.getShouldReadFlagsWithConditionals(), e.getReadSoFar());
+ L.d(": %s : %s allFlags: %s readSoFar: %s", e.getUniqueKey(), e.getShouldReadFlags(),
+ e.getShouldReadFlagsWithConditionals(), e.getReadSoFar());
}
L.d("end of %s", s);
}
-// private Iterable<Expr> getReadFirst(Iterable<Expr> shouldRead) {
-// return mExprModel.filterCanBeReadNow(shouldRead);
-// }
-
private Iterable<Expr> getReadFirst(Iterable<Expr> shouldRead) {
return getReadFirst(shouldRead, null);
}
+
private Iterable<Expr> getReadFirst(Iterable<Expr> shouldRead, final Iterable<Expr> justRead) {
return Iterables.filter(shouldRead, new Predicate<Expr>() {
@Override
@@ -485,7 +544,9 @@ public class ExprModelTest {
}
public static class User {
+
String name;
+
String lastName;
public String getName() {
diff --git a/tools/data-binding/grammarBuilder/src/test/java/android/databinding/BindingExpressionParserTest.java b/tools/data-binding/grammarBuilder/src/test/java/android/databinding/BindingExpressionParserTest.java
index 31f041f..9197ccf 100644
--- a/tools/data-binding/grammarBuilder/src/test/java/android/databinding/BindingExpressionParserTest.java
+++ b/tools/data-binding/grammarBuilder/src/test/java/android/databinding/BindingExpressionParserTest.java
@@ -1,23 +1,25 @@
package android.databinding;
-import android.databinding.BindingExpressionParser.AndOrOpContext;
-import android.databinding.BindingExpressionParser.BinaryOpContext;
-import android.databinding.BindingExpressionParser.BindingSyntaxContext;
-import android.databinding.BindingExpressionParser.BitShiftOpContext;
-import android.databinding.BindingExpressionParser.ComparisonOpContext;
-import android.databinding.BindingExpressionParser.DefaultsContext;
-import android.databinding.BindingExpressionParser.DotOpContext;
-import android.databinding.BindingExpressionParser.ExpressionContext;
-import android.databinding.BindingExpressionParser.GroupingContext;
-import android.databinding.BindingExpressionParser.LiteralContext;
-import android.databinding.BindingExpressionParser.MathOpContext;
-import android.databinding.BindingExpressionParser.PrimaryContext;
-import android.databinding.BindingExpressionParser.PrimitiveTypeContext;
-import android.databinding.BindingExpressionParser.QuestionQuestionOpContext;
-import android.databinding.BindingExpressionParser.ResourceContext;
-import android.databinding.BindingExpressionParser.StringLiteralContext;
-import android.databinding.BindingExpressionParser.TernaryOpContext;
-import android.databinding.BindingExpressionParser.UnaryOpContext;
+import android.databinding.parser.BindingExpressionLexer;
+import android.databinding.parser.BindingExpressionParser;
+import android.databinding.parser.BindingExpressionParser.AndOrOpContext;
+import android.databinding.parser.BindingExpressionParser.BinaryOpContext;
+import android.databinding.parser.BindingExpressionParser.BindingSyntaxContext;
+import android.databinding.parser.BindingExpressionParser.BitShiftOpContext;
+import android.databinding.parser.BindingExpressionParser.ComparisonOpContext;
+import android.databinding.parser.BindingExpressionParser.DefaultsContext;
+import android.databinding.parser.BindingExpressionParser.DotOpContext;
+import android.databinding.parser.BindingExpressionParser.ExpressionContext;
+import android.databinding.parser.BindingExpressionParser.GroupingContext;
+import android.databinding.parser.BindingExpressionParser.LiteralContext;
+import android.databinding.parser.BindingExpressionParser.MathOpContext;
+import android.databinding.parser.BindingExpressionParser.PrimaryContext;
+import android.databinding.parser.BindingExpressionParser.PrimitiveTypeContext;
+import android.databinding.parser.BindingExpressionParser.QuestionQuestionOpContext;
+import android.databinding.parser.BindingExpressionParser.ResourceContext;
+import android.databinding.parser.BindingExpressionParser.StringLiteralContext;
+import android.databinding.parser.BindingExpressionParser.TernaryOpContext;
+import android.databinding.parser.BindingExpressionParser.UnaryOpContext;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
diff --git a/tools/data-binding/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/InnerCannotReadDependencyTest.java b/tools/data-binding/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/InnerCannotReadDependencyTest.java
new file mode 100644
index 0000000..68cf06b
--- /dev/null
+++ b/tools/data-binding/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/InnerCannotReadDependencyTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.testapp;
+
+import android.databinding.testapp.databinding.InnerCannotReadDependencyBinding;
+import android.databinding.testapp.vo.BasicObject;
+import android.os.Debug;
+import android.test.UiThreadTest;
+
+import org.junit.Test;
+
+public class InnerCannotReadDependencyTest extends
+ BaseDataBinderTest<InnerCannotReadDependencyBinding> {
+
+ public InnerCannotReadDependencyTest() {
+ super(InnerCannotReadDependencyBinding.class);
+ }
+
+ @UiThreadTest
+ public void testBinding() {
+ BasicObject object = new BasicObject();
+ object.setField1("a");
+ mBinder.setObj(object);
+ mBinder.executePendingBindings();
+ assertEquals("a ", mBinder.textView.getText().toString());
+ object.setField1(null);
+ mBinder.executePendingBindings();
+ assertEquals("null ", mBinder.textView.getText().toString());
+ object.setField2("b");
+ mBinder.executePendingBindings();
+ assertEquals("null b", mBinder.textView.getText().toString());
+ object.setField1("c");
+ mBinder.executePendingBindings();
+ assertEquals("c b", mBinder.textView.getText().toString());
+ }
+}
diff --git a/tools/data-binding/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/BasicObject.java b/tools/data-binding/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/BasicObject.java
new file mode 100644
index 0000000..450f7fb
--- /dev/null
+++ b/tools/data-binding/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/BasicObject.java
@@ -0,0 +1,45 @@
+/*
+ * 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.testapp.vo;
+import android.databinding.BaseObservable;
+import android.databinding.Bindable;
+import android.databinding.testapp.BR;
+
+public class BasicObject extends BaseObservable {
+ @Bindable
+ private String mField1;
+ @Bindable
+ private String mField2;
+
+ public String getField1() {
+ return mField1;
+ }
+
+ public void setField1(String field1) {
+ this.mField1 = field1;
+ notifyPropertyChanged(BR.field1);
+ }
+
+ public String getField2() {
+ return mField2;
+ }
+
+ public void setField2(String field2) {
+ this.mField2 = field2;
+ notifyPropertyChanged(BR.field1);
+ }
+}
diff --git a/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml b/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
index c65ee39..33a3746 100644
--- a/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
+++ b/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
@@ -15,11 +15,11 @@
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@{obj.method(1.25f}"/>
+ android:text="@{obj.method(1.25f)}"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@{obj.method(`hello`}"/>
+ android:text="@{obj.method(`hello`)}"/>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content" android:layout_height="wrap_content"
diff --git a/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/inner_cannot_read_dependency.xml b/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/inner_cannot_read_dependency.xml
new file mode 100644
index 0000000..2ad1980
--- /dev/null
+++ b/tools/data-binding/integration-tests/TestApp/app/src/main/res/layout/inner_cannot_read_dependency.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <variable name="obj" type="android.databinding.testapp.vo.BasicObject"/>
+ <TextView
+ android:id="@+id/text_view"
+ android:text='@{obj.field1 + " " + (obj.field2 ?? "")}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+</LinearLayout> \ No newline at end of file