blob: 13dd887523ea5db5fddcbdeb65b1d92b6fac9e51 [file] [log] [blame]
/*
* 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;
import android.databinding.tool.expr.CallbackArgExpr;
import android.databinding.tool.expr.CallbackExprModel;
import android.databinding.tool.expr.Expr;
import android.databinding.tool.expr.ExprModel;
import android.databinding.tool.expr.FieldAccessExpr;
import android.databinding.tool.expr.IdentifierExpr;
import android.databinding.tool.processing.ErrorMessages;
import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.scopes.LocationScopeProvider;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.solver.ExecutionPath;
import android.databinding.tool.store.Location;
import android.databinding.tool.store.SetterStore;
import android.databinding.tool.store.SetterStore.BindingGetterCall;
import android.databinding.tool.store.SetterStore.BindingSetterCall;
import android.databinding.tool.util.L;
import java.util.ArrayList;
import java.util.List;
public class InverseBinding implements LocationScopeProvider {
private final String mName;
private final Expr mExpr;
private final BindingTarget mTarget;
private BindingGetterCall mGetterCall;
private final ArrayList<FieldAccessExpr> mChainedExpressions = new ArrayList<FieldAccessExpr>();
private final CallbackExprModel mCallbackExprModel;
private final Expr mInverseExpr;
private final CallbackArgExpr mVariableExpr;
private final ExecutionPath mExecutionPath;
public InverseBinding(BindingTarget target, String name, Expr expr, String bindingClassName) {
mTarget = target;
mName = name;
mCallbackExprModel = new CallbackExprModel(expr.getModel());
mExpr = expr.cloneToModel(mCallbackExprModel);
setGetterCall(mExpr);
mVariableExpr = mCallbackExprModel.callbackArg("callbackArg_0");
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
ModelClass type = modelAnalyzer.findClass(getGetterCall().getGetterType(), null);
mVariableExpr.setClassFromCallback(type);
mVariableExpr.setUserDefinedType(getGetterCall().getGetterType());
mInverseExpr =
mExpr.generateInverse(mCallbackExprModel, mVariableExpr, bindingClassName);
mExecutionPath = ExecutionPath.createRoot();
mInverseExpr.toExecutionPath(mExecutionPath);
mCallbackExprModel.seal();
}
public InverseBinding(BindingTarget target, String name, BindingGetterCall getterCall) {
mTarget = target;
mName = name;
mExpr = null;
mCallbackExprModel = null;
mInverseExpr = null;
mVariableExpr = null;
mExecutionPath = null;
setGetterCall(getterCall);
}
@Override
public List<Location> provideScopeLocation() {
if (mExpr != null) {
return mExpr.getLocations();
} else {
return mChainedExpressions.get(0).getLocations();
}
}
private void setGetterCall(BindingGetterCall getterCall) {
mGetterCall = getterCall;
}
public void addChainedExpression(FieldAccessExpr expr) {
mChainedExpressions.add(expr);
}
public boolean isOnBinder() {
return mTarget.getResolvedType().isViewDataBinding();
}
private void setGetterCall(Expr expr) {
try {
Scope.enter(mTarget);
Scope.enter(this);
ModelClass viewType = mTarget.getResolvedType();
final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance());
final ModelClass resolvedType = expr == null ? null : expr.getResolvedType();
mGetterCall = setterStore.getGetterCall(mName, viewType, resolvedType,
expr.getModel().getImports());
if (mGetterCall == null) {
L.e(ErrorMessages.CANNOT_FIND_GETTER_CALL, mName,
expr == null ? "Unknown" : mExpr.getResolvedType(),
mTarget.getResolvedType());
}
} finally {
Scope.exit();
Scope.exit();
}
}
public SetterStore.BindingGetterCall getGetterCall() {
return mGetterCall;
}
public BindingTarget getTarget() {
return mTarget;
}
public Expr getExpr() {
return mExpr;
}
public Expr getInverseExpr() {
return mInverseExpr;
}
public IdentifierExpr getVariableExpr() {
return mVariableExpr;
}
public ExecutionPath getExecutionPath() {
return mExecutionPath;
}
public CallbackExprModel getCallbackExprModel() {
return mCallbackExprModel;
}
public List<FieldAccessExpr> getChainedExpressions() {
return mChainedExpressions;
}
public String getBindingAdapterInstanceClass() {
return getGetterCall().getBindingAdapterInstanceClass();
}
/**
* The min api level in which this binding should be executed.
* <p>
* This should be the minimum value among the dependencies of this binding.
*/
public int getMinApi() {
final BindingGetterCall getterCall = getGetterCall();
return Math.max(getterCall.getMinApi(), getterCall.getEvent().getMinApi());
}
public BindingSetterCall getEventSetter() {
final BindingGetterCall getterCall = getGetterCall();
return getterCall.getEvent();
}
public String getName() {
return mName;
}
public String getEventAttribute() {
return getGetterCall().getEventAttribute();
}
public ExprModel getModel() {
if (mExpr != null) {
return mExpr.getModel();
}
return mChainedExpressions.get(0).getModel();
}
}