1793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount/* 2793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * Copyright (C) 2015 The Android Open Source Project 3793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * 4793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * you may not use this file except in compliance with the License. 6793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * You may obtain a copy of the License at 7793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * 8793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * http://www.apache.org/licenses/LICENSE-2.0 9793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * 10793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * Unless required by applicable law or agreed to in writing, software 11793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * distributed under the License is distributed on an "AS IS" BASIS, 12793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * See the License for the specific language governing permissions and 14793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * limitations under the License. 15793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount */ 16793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 17793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountpackage android.databinding.tool.expr; 18793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 19793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.reflection.ModelAnalyzer; 20793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.reflection.ModelClass; 21793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.reflection.ModelMethod; 22793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport android.databinding.tool.writer.KCode; 2359229481aec5a284d322a2ca80dff836485feb0cYigit Boyarimport android.databinding.tool.writer.LayoutBinderWriterKt; 24793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 25793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport java.util.ArrayList; 26793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountimport java.util.List; 27793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 28793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount/** 29793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * This wraps an expression, but makes it unique for a particular event listener type. 30793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * This is used to differentiate listener methods. For example: 31793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * <pre> 32793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * public void onFoo(String str) {...} 33793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * public void onFoo(int i) {...} 34793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount * </pre> 35793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount */ 36793e979f25e190162eacf46d6a4efc3efc1d2f91George Mountpublic class ListenerExpr extends Expr { 37793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount private final String mName; 38793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount private final ModelClass mListenerType; 39793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount private final ModelMethod mMethod; 40793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 41793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount ListenerExpr(Expr expr, String name, ModelClass listenerType, ModelMethod method) { 42793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount super(expr); 43793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount mName = name; 44793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount mListenerType = listenerType; 45793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount mMethod = method; 46793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 47793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 48793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount @Override 49793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { 50793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return mListenerType; 51793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 52793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 53793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount public ModelMethod getMethod() { 54793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return mMethod; 55793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 56793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 57793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount public Expr getChild() { 58793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return getChildren().get(0); 59793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 60793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 61793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount public String getName() { 62793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return mName; 63793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 64793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 65793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount @Override 66793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount public boolean isDynamic() { 67793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return getChild().isDynamic(); 68793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 69793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 70793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount @Override 71793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount protected List<Dependency> constructDependencies() { 729784c9aaedeb863018f5fcaa0a598e8e2f8ed2f3Yigit Boyar final List<Dependency> dependencies = new ArrayList<Dependency>(); 73793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount Dependency dependency = new Dependency(this, getChild()); 74793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount dependency.setMandatory(true); 75793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount dependencies.add(dependency); 76793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return dependencies; 77793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 78793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 79793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount protected String computeUniqueKey() { 80793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return join(getResolvedType().getCanonicalName(), getChild().computeUniqueKey(), mName); 81793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 82793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount 83793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount @Override 84d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public KCode generateCode(boolean expand) { 85793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount KCode code = new KCode("("); 86793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount final int minApi = Math.max(mListenerType.getMinApi(), mMethod.getMinApi()); 87793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount if (minApi > 1) { 88793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount code.app("(getBuildSdkInt() < " + minApi + ") ? null : "); 89793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 9059229481aec5a284d322a2ca80dff836485feb0cYigit Boyar final String fieldName = LayoutBinderWriterKt.getFieldName(this); 9159229481aec5a284d322a2ca80dff836485feb0cYigit Boyar final String listenerClassName = LayoutBinderWriterKt.getListenerClassName(this); 92793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount final KCode value = getChild().toCode(); 93793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount code.app("((") 94793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(fieldName) 95793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(" == null) ? (") 96793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(fieldName) 97793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(" = new ") 98793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(listenerClassName) 99793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app("()) : ") 100793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(fieldName) 101793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(")"); 102793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount if (getChild().isDynamic()) { 103793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount code.app(".setValue(", value) 104793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount .app(")"); 105793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 106793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount code.app(")"); 107793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount return code; 108793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount } 109d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 110d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 111d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount public String getInvertibleError() { 112d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return "Listeners cannot be the target of a two-way binding"; 113d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 114793e979f25e190162eacf46d6a4efc3efc1d2f91George Mount} 115