BracketExpr.java revision af146d6a8c0efcf5682d14047c06866a5548f78f
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* 2f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Copyright (C) 2015 The Android Open Source Project 3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 4f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 5f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * you may not use this file except in compliance with the License. 6f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * You may obtain a copy of the License at 7f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 8f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 9f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 10f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Unless required by applicable law or agreed to in writing, software 11f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 12f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * See the License for the specific language governing permissions and 14f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * limitations under the License. 15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */ 16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 17f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crosspackage android.databinding.tool.expr; 18f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 19f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossimport android.databinding.tool.reflection.ModelAnalyzer; 20f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossimport android.databinding.tool.reflection.ModelClass; 21f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossimport android.databinding.tool.writer.KCode; 22f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 23f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossimport java.util.List; 24f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 25f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crosspublic class BracketExpr extends Expr { 26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 27f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross public enum BracketAccessor { 28f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ARRAY, 29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross LIST, 30f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross MAP, 31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross private BracketAccessor mAccessor; 34e7b6cf13f94f66ea446c95ab34040b0a577e43dcJohn Michelau 35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross BracketExpr(Expr target, Expr arg) { 36bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown super(target, arg); 37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 38f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross @Override 40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { 41957983787d7a753d34b582ae0165160f4ebf815cRobert Craig ModelClass targetType = getTarget().getResolvedType(); 42957983787d7a753d34b582ae0165160f4ebf815cRobert Craig if (targetType.isArray()) { 43f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross mAccessor = BracketAccessor.ARRAY; 44f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else if (targetType.isList()) { 451dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown mAccessor = BracketAccessor.LIST; 461dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown } else if (targetType.isMap()) { 47bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown mAccessor = BracketAccessor.MAP; 48bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown } else { 491fc4f80fc38f782f128102795481924a97a2d3c5James Dong throw new IllegalArgumentException("Cannot determine variable type used in [] " + 50bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown "expression. Cast the value to List, Map, " + 51bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown "or array. Type detected: " + targetType.toJavaCode()); 52bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown } 53d907b32052aca02ad679e6ae786848d328723080keunyoung return targetType.getComponentType(); 54bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown } 55bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown 56bf7f49238d0af497d4300f7e611cf831854d6434Jeff Brown @Override 5754bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris protected List<Dependency> constructDependencies() { 5854bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris final List<Dependency> dependencies = constructDynamicChildrenDependencies(); 5954bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris for (Dependency dependency : dependencies) { 6054bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris if (dependency.getOther() == getTarget()) { 6154bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris dependency.setMandatory(true); 6254bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris } 635ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 6493d705b6d742e8f00167ff2384e35c2205a6f9daFelipe Leme return dependencies; 655ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 665ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock 675ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock protected String computeUniqueKey() { 685ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock final String targetKey = getTarget().computeUniqueKey(); 695ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock return addTwoWay(join(targetKey, "$", getArg().computeUniqueKey(), "$")); 705ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 715ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock 725ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock @Override 735ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock public String getInvertibleError() { 745ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock return null; 755ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 765ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock 775ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock public Expr getTarget() { 785ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock return getChildren().get(0); 795ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 805ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock 815ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock public Expr getArg() { 825ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock return getChildren().get(1); 835ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock } 845ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock 855ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock public BracketAccessor getAccessor() { 865ecd4beef8f10f91febf916414c65d3d0e1cf734John Spurlock return mAccessor; 870c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross } 88f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 89f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross public boolean argCastsInteger() { 90f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return mAccessor != BracketAccessor.MAP && getArg().getResolvedType().isObject(); 91f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 92f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 93f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross @Override 94f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross protected KCode generateCode(boolean expand) { 95f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross String cast = argCastsInteger() ? "(Integer) " : ""; 96f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross switch (getAccessor()) { 97f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case ARRAY: { 98f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return new KCode(). 99f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app("getFromArray(", getTarget().toCode()). 100f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(", "). 101f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(cast, getArg().toCode()).app(")"); 102f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 103f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case LIST: { 104f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ModelClass listType = ModelAnalyzer.getInstance().findClass(java.util.List.class). 105f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross erasure(); 106f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ModelClass targetType = getTarget().getResolvedType().erasure(); 107f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (listType.isAssignableFrom(targetType)) { 108f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return new KCode(). 109cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich app("getFromList(", getTarget().toCode()). 110f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(", "). 111f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(cast, getArg().toCode()). 1120c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app(")"); 113f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 114f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return new KCode(). 1150c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app("", getTarget().toCode()). 116f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(".get("). 117f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(cast, getArg().toCode()). 118f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross app(")"); 119f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 120f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1210c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross case MAP: 1228620bb4118a68721d10c29529dc6978847d08d00Felipe Leme return new KCode(). 1230c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app("", getTarget().toCode()). 1240c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app(".get(", getArg().toCode()). 1250c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app(")"); 1260c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross } 12793d705b6d742e8f00167ff2384e35c2205a6f9daFelipe Leme throw new IllegalStateException("Invalid BracketAccessor type"); 1288620bb4118a68721d10c29529dc6978847d08d00Felipe Leme } 1290c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross 1300c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross @Override 1310c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross public KCode toInverseCode(KCode value) { 1320c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross String cast = argCastsInteger() ? "(Integer) " : ""; 1330c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross return new KCode(). 1340c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app("setTo(", getTarget().toCode(true)). 1358620bb4118a68721d10c29529dc6978847d08d00Felipe Leme app(", "). 1360c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app(cast, getArg().toCode(true)). 1370c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross app(", ", value).app(");"); 1380c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross } 1390c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross} 1400c22e8b31651caf12a2b4d4acef5bc65d486e570Colin Cross