11b9940e612fc73202837fbe9db2f9035f307b5d1George Mount/* 21b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Copyright (C) 2015 The Android Open Source Project 31b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 41b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 51b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * you may not use this file except in compliance with the License. 61b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * You may obtain a copy of the License at 71b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 81b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * http://www.apache.org/licenses/LICENSE-2.0 91b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * 101b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * Unless required by applicable law or agreed to in writing, software 111b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * distributed under the License is distributed on an "AS IS" BASIS, 121b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * See the License for the specific language governing permissions and 141b9940e612fc73202837fbe9db2f9035f307b5d1George Mount * limitations under the License. 151b9940e612fc73202837fbe9db2f9035f307b5d1George Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.reflection; 171b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 18fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.Bindable; 19fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 201b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport java.util.List; 211b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 22fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mountpublic abstract class ModelMethod { 23fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract ModelClass getDeclaringClass(); 24fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 25fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract ModelClass[] getParameterTypes(); 26fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 27fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract String getName(); 281b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 29fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract ModelClass getReturnType(List<ModelClass> args); 301b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 31fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract boolean isVoid(); 321b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 33fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract boolean isPublic(); 341b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 35bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount public abstract boolean isProtected(); 36bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount 37fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract boolean isStatic(); 381b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 39716ba89e7f459f49ea85070d4710c1d79d715298George Mount public abstract boolean isAbstract(); 40716ba89e7f459f49ea85070d4710c1d79d715298George Mount 41fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount /** 42fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * @return whether or not this method has been given the {@link Bindable} annotation. 43fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount */ 44fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract boolean isBindable(); 4597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 4697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar /** 4797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Since when this method is available. Important for Binding expressions so that we don't 4897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * call non-existing APIs when setting UI. 4997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * 5097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * @return The SDK_INT where this method was added. If it is not a framework method, should 5197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * return 1. 5297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar */ 53fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract int getMinApi(); 5497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 5597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar /** 5697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Returns the JNI description of the method which can be used to lookup it in SDK. 57fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount * @see TypeUtil 5897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar */ 59fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract String getJniDescription(); 60fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 61fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount /** 62fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * @return true if the final parameter is a varargs parameter. 63fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount */ 64fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public abstract boolean isVarArgs(); 65fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 66fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount /** 67fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * @param args The arguments to the method 68fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount * @return Whether the arguments would be accepted as parameters to this method. 69fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount */ 70fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public boolean acceptsArguments(List<ModelClass> args) { 71fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount boolean isVarArgs = isVarArgs(); 72fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass[] parameterTypes = getParameterTypes(); 73fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if ((!isVarArgs && args.size() != parameterTypes.length) || 74fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount (isVarArgs && args.size() < parameterTypes.length - 1)) { 75fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return false; // The wrong number of parameters 76fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 77fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount boolean parametersMatch = true; 78fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount for (int i = 0; i < args.size(); i++) { 79fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass parameterType = getParameter(i, parameterTypes); 80fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass arg = args.get(i); 81bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount if (parameterType.isIncomplete()) { 82bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount parameterType = parameterType.erasure(); 83bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 84fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (!parameterType.isAssignableFrom(arg) && !isImplicitConversion(arg, parameterType)) { 85fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount parametersMatch = false; 86fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount break; 87fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 88fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 89fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return parametersMatch; 90fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 91fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 92fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public boolean isBetterArgMatchThan(ModelMethod other, List<ModelClass> args) { 93fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass[] parameterTypes = getParameterTypes(); 94fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass[] otherParameterTypes = other.getParameterTypes(); 95fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount for (int i = 0; i < args.size(); i++) { 96fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass arg = args.get(i); 97fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass thisParameter = getParameter(i, parameterTypes); 98fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final ModelClass thatParameter = other.getParameter(i, otherParameterTypes); 9911df39c91611b9ff2d7c87a9a9829251a015bccfGeorge Mount if (thisParameter.equals(thatParameter)) { 10011df39c91611b9ff2d7c87a9a9829251a015bccfGeorge Mount continue; 10111df39c91611b9ff2d7c87a9a9829251a015bccfGeorge Mount } 102fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount final int diff = compareParameter(arg, thisParameter, thatParameter); 103fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (diff != 0) { 104fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return diff < 0; 105fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 106fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 107fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return false; 108fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 109fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 1106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar public ModelClass getReturnType() { 1116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return getReturnType(null); 1126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 1136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 114fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private ModelClass getParameter(int index, ModelClass[] parameterTypes) { 115fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int normalParamCount = isVarArgs() ? parameterTypes.length - 1 : parameterTypes.length; 116fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (index < normalParamCount) { 117fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return parameterTypes[index]; 118fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else { 119fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return parameterTypes[parameterTypes.length - 1].getComponentType(); 120fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 121fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 122fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 123fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount private static int compareParameter(ModelClass arg, ModelClass thisParameter, 124fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount ModelClass thatParameter) { 125fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (thatParameter.equals(arg)) { 126fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 1; 127fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (thisParameter.equals(arg)) { 128fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 129fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (isBoxingConversion(thatParameter, arg)) { 130fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 1; 131fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (isBoxingConversion(thisParameter, arg)) { 132fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount // Boxing/unboxing is second best 133fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 134fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else { 135fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int argConversionLevel = getImplicitConversionLevel(arg); 136fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (argConversionLevel != -1) { 137fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int oldConversionLevel = getImplicitConversionLevel(thatParameter); 138fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int newConversionLevel = getImplicitConversionLevel(thisParameter); 139fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (newConversionLevel != -1 && 140fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount (oldConversionLevel == -1 || newConversionLevel < oldConversionLevel)) { 141fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 142fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (oldConversionLevel != -1) { 143fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 1; 144fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 145fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 146fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount // Look for more exact match 147fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (thatParameter.isAssignableFrom(thisParameter)) { 148fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 149fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 150fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 151fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 0; // no difference 152fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 153fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 154fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public static boolean isBoxingConversion(ModelClass class1, ModelClass class2) { 155fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (class1.isPrimitive() != class2.isPrimitive()) { 156fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return (class1.box().equals(class2.box())); 157fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else { 158fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return false; 159fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 160fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 161fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 162fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public static int getImplicitConversionLevel(ModelClass primitive) { 163fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (primitive == null) { 164fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 165fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isByte()) { 166fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 0; 167fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isChar()) { 168fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 1; 169fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isShort()) { 170fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 2; 171fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isInt()) { 172fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 3; 173fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isLong()) { 174fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 4; 175fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isFloat()) { 176fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 5; 177fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else if (primitive.isDouble()) { 178fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return 6; 179fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else { 180fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return -1; 181fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 182fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 183fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 184fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public static boolean isImplicitConversion(ModelClass from, ModelClass to) { 185fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (from != null && to != null && from.isPrimitive() && to.isPrimitive()) { 186fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (from.isBoolean() || to.isBoolean() || to.isChar()) { 187fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return false; 188fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 189fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int fromConversionLevel = getImplicitConversionLevel(from); 190fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount int toConversionLevel = getImplicitConversionLevel(to); 191fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return fromConversionLevel < toConversionLevel; 192fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } else { 193fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return false; 194fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 195fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 1961b9940e612fc73202837fbe9db2f9035f307b5d1George Mount} 197