diff --git a/tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/FindMethodTest.java b/tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/FindMethodTest.java index 4e5ecd30b626a..0b4762bd59418 100644 --- a/tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/FindMethodTest.java +++ b/tools/data-binding/TestApp/src/androidTest/java/com/android/databinding/testapp/FindMethodTest.java @@ -71,4 +71,24 @@ public class FindMethodTest TextView textView = mBinder.getTextView8(); assertEquals("hello world", textView.getText().toString()); } + + public void testImportStaticMethod() throws Throwable { + TextView textView = mBinder.getTextView9(); + assertEquals("world", textView.getText().toString()); + } + + public void testImportStaticField() throws Throwable { + TextView textView = mBinder.getTextView10(); + assertEquals("hello world", textView.getText().toString()); + } + + public void testAliasStaticMethod() throws Throwable { + TextView textView = mBinder.getTextView11(); + assertEquals("world", textView.getText().toString()); + } + + public void testAliasStaticField() throws Throwable { + TextView textView = mBinder.getTextView12(); + assertEquals("hello world", textView.getText().toString()); + } } diff --git a/tools/data-binding/TestApp/src/main/res/layout/find_method_test.xml b/tools/data-binding/TestApp/src/main/res/layout/find_method_test.xml index 810c783be9172..a5213a4f016e8 100644 --- a/tools/data-binding/TestApp/src/main/res/layout/find_method_test.xml +++ b/tools/data-binding/TestApp/src/main/res/layout/find_method_test.xml @@ -4,9 +4,8 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + + + + + + \ No newline at end of file diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java index 912910659e77d..acc9d2cf41f63 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java @@ -575,17 +575,18 @@ abstract public class Expr { } } - protected void replaceStaticAccess(ModelAnalyzer modelAnalyzer) { + protected void replaceStaticIdentifiers(ModelAnalyzer modelAnalyzer) { for (int i = 0; i < mChildren.size(); i++) { Expr child = mChildren.get(i); String packageName = child.asPackage(); if (packageName != null) { ModelClass modelClass = modelAnalyzer.findClass(packageName); if (modelClass != null) { - Expr staticAccessExpr = getModel().staticAccessExpr(modelClass); + child.removeParentAndUnregisterIfOrphan(this); + StaticIdentifierExpr staticAccessExpr = getModel().staticIdentifier(packageName); + staticAccessExpr.setUserDefinedType(packageName); staticAccessExpr.getParents().add(this); mChildren.set(i, staticAccessExpr); - child.removeParentAndUnregisterIfOrphan(this); } } } @@ -595,11 +596,11 @@ abstract public class Expr { while (mParents.remove(parent)) { } if (getParents().isEmpty()) { - getModel().unregister(this); for (Expr expr : mChildren) { expr.removeParentAndUnregisterIfOrphan(this); } mChildren.clear(); + getModel().unregister(this); } } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java index ce11da8e1d0a6..3ec9485893a35 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java @@ -146,10 +146,6 @@ public class ExprModel { return register(new BracketExpr(variableExpr, argExpr)); } - public Expr staticAccessExpr(ModelClass modelClass) { - return register(new StaticAccessExpr(modelClass)); - } - public Expr castExpr(String type, Expr expr) { return register(new CastExpr(type, expr)); } @@ -166,7 +162,9 @@ public class ExprModel { public Expr bindingExpr(Expr bindingExpr) { Preconditions.checkArgument(mExprMap.containsKey(bindingExpr.getUniqueKey()), "Main expression should already be registered"); - mBindingExpressions.add(bindingExpr); + if (!mBindingExpressions.contains(bindingExpr)) { + mBindingExpressions.add(bindingExpr); + } return bindingExpr; } @@ -257,6 +255,9 @@ public class ExprModel { } // non-dynamic binding expressions receive some ids so that they can be invalidated + for (int i = 0; i < mBindingExpressions.size(); i++) { + L.d("[" + i + "] " + mBindingExpressions.get(i)); + } for (Expr expr : mBindingExpressions) { if (!(expr.isDynamic() || !expr.hasId())) { L.d("Expr " + expr + " is dynamic? " + expr.isDynamic() + ", has ID? " + expr.hasId()); @@ -348,7 +349,7 @@ public class ExprModel { public boolean apply(Expr input) { return input instanceof IdentifierExpr && !input.hasId() - && !modelAnalyzer.isObservable(input.getResolvedType()) + && !input.isObservable() && input.isDynamic(); } }); @@ -358,7 +359,7 @@ public class ExprModel { return Iterables.filter(mExprMap.values(), new Predicate() { @Override public boolean apply(Expr input) { - return modelAnalyzer.isObservable(input.getResolvedType()); + return input.isObservable(); } }); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java index 8f3140a4c6993..fdff0233838a6 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java @@ -39,7 +39,7 @@ public class FieldAccessExpr extends Expr { mIsObservableField = isObservableField; } - public Expr getParent() { + public Expr getChild() { return getChildren().get(0); } @@ -52,7 +52,7 @@ public class FieldAccessExpr extends Expr { @Override public boolean isDynamic() { - if (!getParent().isDynamic()) { + if (!getChild().isDynamic()) { return false; } if (mGetter == null) { @@ -66,7 +66,7 @@ public class FieldAccessExpr extends Expr { protected List constructDependencies() { final List dependencies = constructDynamicChildrenDependencies(); for (Dependency dependency : dependencies) { - if (dependency.getOther() == getParent()) { + if (dependency.getOther() == getChild()) { dependency.setMandatory(true); } } @@ -94,16 +94,17 @@ public class FieldAccessExpr extends Expr { @Override protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if (mGetter == null) { - replaceStaticAccess(modelAnalyzer); - Expr parent = getParent(); - boolean isStatic = parent instanceof StaticAccessExpr; - mGetter = modelAnalyzer.findMethodOrField(parent.getResolvedType(), mName, isStatic); + replaceStaticIdentifiers(modelAnalyzer); + Expr child = getChild(); + child.resolveType(modelAnalyzer); + boolean isStatic = child instanceof StaticIdentifierExpr; + mGetter = modelAnalyzer.findMethodOrField(child.getResolvedType(), mName, isStatic); if (modelAnalyzer.isObservableField(mGetter.resolvedType)) { // Make this the ".get()" and add an extra field access for the observable field - parent.getParents().remove(this); - getChildren().remove(parent); + child.getParents().remove(this); + getChildren().remove(child); - FieldAccessExpr observableField = getModel().observableField(parent, mName); + FieldAccessExpr observableField = getModel().observableField(child, mName); observableField.mGetter = mGetter; getChildren().add(observableField); @@ -117,7 +118,7 @@ public class FieldAccessExpr extends Expr { @Override protected String asPackage() { - String parentPackage = getParent().asPackage(); + String parentPackage = getChild().asPackage(); return parentPackage == null ? null : parentPackage + "." + mName; } } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java index e2f33bff4f8f6..5c3bd04113997 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java @@ -45,14 +45,14 @@ public class MethodCallExpr extends Expr { @Override protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if (mGetter == null) { - replaceStaticAccess(modelAnalyzer); + replaceStaticIdentifiers(modelAnalyzer); List args = new ArrayList<>(); for (Expr expr : getArgs()) { args.add(expr.getResolvedType()); } Expr target = getTarget(); - boolean isStatic = target instanceof StaticAccessExpr; + boolean isStatic = target instanceof StaticIdentifierExpr; mGetter = modelAnalyzer.findMethod(target.getResolvedType(), mName, args, isStatic); } return mGetter.resolvedType; diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticAccessExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticAccessExpr.java deleted file mode 100644 index adb715633cabe..0000000000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticAccessExpr.java +++ /dev/null @@ -1,45 +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 com.android.databinding.expr; - -import com.android.databinding.reflection.ModelAnalyzer; -import com.android.databinding.reflection.ModelClass; - -import java.util.ArrayList; -import java.util.List; - -public class StaticAccessExpr extends Expr { - private ModelClass mStaticClass; - - public StaticAccessExpr(ModelClass modelClass) { - mStaticClass = modelClass; - } - - @Override - protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { - return mStaticClass; - } - - @Override - protected List constructDependencies() { - return new ArrayList<>(); - } - - protected String computeUniqueKey() { - return mStaticClass.toJavaCode(); - } - -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticIdentifierExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticIdentifierExpr.java index 240a3541498f2..643b693f7ee34 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticIdentifierExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/StaticIdentifierExpr.java @@ -22,6 +22,11 @@ public class StaticIdentifierExpr extends IdentifierExpr { super(name); } + @Override + public boolean isObservable() { + return false; + } + @Override public boolean isDynamic() { return false; diff --git a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt index 5a274891ff3c1..bce2e28052154 100644 --- a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt +++ b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt @@ -46,7 +46,6 @@ import com.android.databinding.expr.ResourceExpr import com.android.databinding.expr.BracketExpr import com.android.databinding.reflection.Callable import com.android.databinding.expr.CastExpr -import com.android.databinding.expr.StaticAccessExpr fun String.stripNonJava() = this.split("[^a-zA-Z0-9]").map{ it.trim() }.joinToCamelCaseAsVar() @@ -161,7 +160,7 @@ fun Expr.toCode(full : Boolean = false) : KCode { app("", it.getRight().toCode()) } is FieldAccessExpr -> kcode("") { - app("", it.getParent().toCode()) + app("", it.getChild().toCode()) if (it.getGetter().type == Callable.Type.FIELD) { app(".", it.getGetter().name) } else { @@ -222,9 +221,6 @@ fun Expr.toCode(full : Boolean = false) : KCode { app("(", it.getCastType()) app(") ", it.getCastExpr().toCode()) } - is StaticAccessExpr -> kcode("") { - app("", it.getResolvedType().toJavaCode()) - } else -> kcode("//NOT IMPLEMENTED YET") } diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java index c8ea898fa6b58..8237aee8c0cc3 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java @@ -139,8 +139,8 @@ public class ExpressionVisitorTest { @Test public void testInheritedFieldResolution() { final FieldAccessExpr parsed = parse("myStr.length", FieldAccessExpr.class); - assertTrue(parsed.getParent() instanceof IdentifierExpr); - final IdentifierExpr id = (IdentifierExpr) parsed.getParent(); + assertTrue(parsed.getChild() instanceof IdentifierExpr); + final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); id.setUserDefinedType("java.lang.String"); assertSame(int.class, parsed.getResolvedType()); Callable getter = parsed.getGetter(); @@ -155,8 +155,8 @@ public class ExpressionVisitorTest { @Test public void testGetterResolution() { final FieldAccessExpr parsed = parse("myStr.bytes", FieldAccessExpr.class); - assertTrue(parsed.getParent() instanceof IdentifierExpr); - final IdentifierExpr id = (IdentifierExpr) parsed.getParent(); + assertTrue(parsed.getChild() instanceof IdentifierExpr); + final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); id.setUserDefinedType("java.lang.String"); assertSame(byte[].class, parsed.getResolvedType()); Callable getter = parsed.getGetter(); diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java index 6f3320673bf91..fdb79ed33485b 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java @@ -93,7 +93,7 @@ public class LayoutBinderTest { fa.getResolvedType(); final Callable getter = fa.getGetter(); assertTrue(getter.type == Callable.Type.METHOD); - assertSame(id, fa.getParent()); + assertSame(id, fa.getChild()); assertTrue(fa.isDynamic()); }