summaryrefslogtreecommitdiff
path: root/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java')
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java129
1 files changed, 55 insertions, 74 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
index 5d850b5d..bdfc9f84 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
@@ -35,6 +35,8 @@ import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.KCode;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.List;
@@ -43,23 +45,15 @@ public class FieldAccessExpr extends Expr {
// notification name for the field. Important when we map this to a method w/ different name
String mBrName;
Callable mGetter;
- final boolean mIsObservableField;
boolean mIsListener;
boolean mIsViewAttributeAccess;
FieldAccessExpr(Expr parent, String name) {
super(parent);
mName = name;
- mIsObservableField = false;
- }
-
- FieldAccessExpr(Expr parent, String name, boolean isObservableField) {
- super(parent);
- mName = name;
- mIsObservableField = isObservableField;
}
- public Expr getChild() {
+ public Expr getTarget() {
return getChildren().get(0);
}
@@ -72,15 +66,15 @@ public class FieldAccessExpr extends Expr {
@Override
public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) {
- final List<ExecutionPath> targetPaths = getChild().toExecutionPath(paths);
+ final List<ExecutionPath> targetPaths = getTarget().toExecutionPath(paths);
// after this, we need a null check.
List<ExecutionPath> result = new ArrayList<ExecutionPath>();
- if (getChild() instanceof StaticIdentifierExpr) {
- result.addAll(toExecutionPathInOrder(paths, getChild()));
+ if (getTarget() instanceof StaticIdentifierExpr) {
+ result.addAll(toExecutionPathInOrder(paths, getTarget()));
} else {
for (ExecutionPath path : targetPaths) {
final ComparisonExpr cmp = getModel()
- .comparison("!=", getChild(), getModel().symbol("null", Object.class));
+ .comparison("!=", getTarget(), getModel().symbol("null", Object.class));
path.addPath(cmp);
final ExecutionPath subPath = path.addBranch(cmp, true);
if (subPath != null) {
@@ -118,7 +112,7 @@ public class FieldAccessExpr extends Expr {
return true;
}
// if it is static final, gone
- if (getChild().isDynamic()) {
+ if (getTarget().isDynamic()) {
// if owner is dynamic, then we can be dynamic unless we are static final
return !mGetter.isStatic() || mGetter.isDynamic();
}
@@ -137,17 +131,14 @@ public class FieldAccessExpr extends Expr {
@Override
public Expr resolveListeners(ModelClass listener, Expr parent) {
- if (mName == null || mName.isEmpty()) {
- return this; // ObservableFields aren't listeners
- }
- final ModelClass childType = getChild().getResolvedType();
+ final ModelClass childType = getTarget().getResolvedType();
if (getGetter() == null) {
if (listener == null || !mIsListener) {
L.e("Could not resolve %s.%s as an accessor or listener on the attribute.",
childType.getCanonicalName(), mName);
return this;
}
- getChild().getParents().remove(this);
+ getTarget().getParents().remove(this);
} else if (listener == null) {
return this; // Not a listener, but we have a getter.
}
@@ -166,14 +157,14 @@ public class FieldAccessExpr extends Expr {
// Look for a signature matching the abstract method
final ModelMethod listenerMethod = abstractMethods.get(0);
final ModelClass[] listenerParameters = listenerMethod.getParameterTypes();
- boolean isStatic = getChild() instanceof StaticIdentifierExpr;
+ boolean isStatic = getTarget() instanceof StaticIdentifierExpr;
List<ModelMethod> methods = childType.findMethods(mName, isStatic);
for (ModelMethod method : methods) {
if (acceptsParameters(method, listenerParameters) &&
method.getReturnType(null).equals(listenerMethod.getReturnType(null))) {
resetResolvedType();
// replace this with ListenerExpr in parent
- Expr listenerExpr = getModel().listenerExpr(getChild(), mName, listener,
+ Expr listenerExpr = getModel().listenerExpr(getTarget(), mName, listener,
listenerMethod);
if (parent != null) {
int index;
@@ -217,7 +208,7 @@ public class FieldAccessExpr extends Expr {
protected List<Dependency> constructDependencies() {
final List<Dependency> dependencies = constructDynamicChildrenDependencies();
for (Dependency dependency : dependencies) {
- if (dependency.getOther() == getChild()) {
+ if (dependency.getOther() == getTarget()) {
dependency.setMandatory(true);
}
}
@@ -226,10 +217,7 @@ public class FieldAccessExpr extends Expr {
@Override
protected String computeUniqueKey() {
- if (mIsObservableField) {
- return addTwoWay(join(mName, "..", super.computeUniqueKey()));
- }
- return addTwoWay(join(mName, ".", super.computeUniqueKey()));
+ return join(mName, ".", super.computeUniqueKey());
}
public String getName() {
@@ -266,10 +254,10 @@ public class FieldAccessExpr extends Expr {
return modelAnalyzer.findClass(Object.class);
}
if (mGetter == null) {
- Expr child = getChild();
- child.getResolvedType();
- boolean isStatic = child instanceof StaticIdentifierExpr;
- ModelClass resolvedType = child.getResolvedType();
+ Expr target = getTarget();
+ target.getResolvedType();
+ boolean isStatic = target instanceof StaticIdentifierExpr;
+ ModelClass resolvedType = target.getResolvedType();
L.d("resolving %s. Resolved class type: %s", this, resolvedType);
mGetter = resolvedType.findGetterOrField(mName, isStatic);
@@ -284,25 +272,16 @@ public class FieldAccessExpr extends Expr {
if (mGetter.isStatic() && !isStatic) {
// found a static method on an instance. register a new one
- child.getParents().remove(this);
- getChildren().remove(child);
- StaticIdentifierExpr staticId = getModel().staticIdentifierFor(resolvedType);
- getChildren().add(staticId);
- staticId.getParents().add(this);
- child = getChild(); // replace the child for the next if stmt
+ replaceStaticIdentifier(resolvedType);
+ target = getTarget();
}
if (mGetter.resolvedType.isObservableField()) {
// Make this the ".get()" and add an extra field access for the observable field
- child.getParents().remove(this);
- getChildren().remove(child);
-
- FieldAccessExpr observableField = getModel().observableField(child, mName);
- observableField.mGetter = mGetter;
- if (hasBindableAnnotations()) {
- observableField.mBrName = ExtKt.br(BrNameUtil.brKey(mGetter));
- }
+ target.getParents().remove(this);
+ getChildren().remove(target);
+ FieldAccessExpr observableField = getModel().observableField(target, mName);
getChildren().add(observableField);
observableField.getParents().add(this);
mGetter = mGetter.resolvedType.findGetterOrField("", false);
@@ -315,9 +294,17 @@ public class FieldAccessExpr extends Expr {
return mGetter.resolvedType;
}
+ protected void replaceStaticIdentifier(ModelClass staticIdentifierType) {
+ getTarget().getParents().remove(this);
+ getChildren().remove(getTarget());
+ StaticIdentifierExpr staticId = getModel().staticIdentifierFor(staticIdentifierType);
+ getChildren().add(staticId);
+ staticId.getParents().add(this);
+ }
+
@Override
public Expr resolveTwoWayExpressions(Expr parent) {
- final Expr child = getChild();
+ final Expr child = getTarget();
if (!(child instanceof ViewFieldExpr)) {
return this;
}
@@ -390,25 +377,17 @@ public class FieldAccessExpr extends Expr {
@Override
protected String asPackage() {
- String parentPackage = getChild().asPackage();
+ String parentPackage = getTarget().asPackage();
return parentPackage == null ? null : parentPackage + "." + mName;
}
@Override
- protected KCode generateCode(boolean expand) {
+ protected KCode generateCode() {
// once we can deprecate using Field.access for callbacks, we can get rid of this since
// it will be detected when resolve type is run.
Preconditions.checkNotNull(getGetter(), ErrorMessages.CANNOT_RESOLVE_TYPE, this);
- KCode code = new KCode();
- if (expand) {
- String defaultValue = ModelAnalyzer.getInstance().getDefaultValue(
- getResolvedType().toJavaCode());
- code.app("(", getChild().toCode(true))
- .app(" == null) ? ")
- .app(defaultValue)
- .app(" : ");
- }
- code.app("", getChild().toCode(expand)).app(".");
+ KCode code = new KCode()
+ .app("", getTarget().toCode()).app(".");
if (getGetter().type == Callable.Type.FIELD) {
return code.app(getGetter().name);
} else {
@@ -417,25 +396,27 @@ public class FieldAccessExpr extends Expr {
}
@Override
- public KCode toInverseCode(KCode value) {
- if (mGetter.setterName == null) {
- throw new IllegalStateException("There is no inverse for " + toCode().generate());
- }
- KCode castValue = new KCode("(").app(getResolvedType().toJavaCode() + ")(", value).app(")");
- String type = getChild().getResolvedType().toJavaCode();
- KCode code = new KCode("targetObj_.");
+ public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) {
+ Expr castExpr = model.castExpr(getResolvedType().toJavaCode(), value);
+ Expr target = getTarget().cloneToModel(model);
+ Expr result;
if (getGetter().type == Callable.Type.FIELD) {
- code.app(getGetter().setterName).app(" = ", castValue).app(";");
+ result = model.assignment(target, mName, castExpr);
} else {
- code.app(getGetter().setterName).app("(", castValue).app(")").app(";");
+ result = model.methodCall(target, mGetter.setterName, Lists.newArrayList(castExpr));
}
- return new KCode()
- .app("final ")
- .app(type)
- .app(" targetObj_ = ", getChild().toCode(true))
- .app(";")
- .nl(new KCode("if (targetObj_ != null) {"))
- .tab(code)
- .nl(new KCode("}"));
+ return result;
+ }
+
+ @Override
+ public Expr cloneToModel(ExprModel model) {
+ final Expr clonedTarget = getTarget().cloneToModel(model);
+ return model.field(clonedTarget, mName);
+ }
+
+ @Override
+ public String toString() {
+ String name = mName.isEmpty() ? "get()" : mName;
+ return getTarget().toString() + '.' + name;
}
}