179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount/* 279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * Copyright (C) 2015 The Android Open Source Project 379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * 479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * you may not use this file except in compliance with the License. 679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * You may obtain a copy of the License at 779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * 879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * 1079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * Unless required by applicable law or agreed to in writing, software 1179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 1279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * See the License for the specific language governing permissions and 1479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount * limitations under the License. 1579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount */ 16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.reflection.annotation; 1797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 18fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.Bindable; 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelMethod; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.SdkUtil; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.TypeUtil; 23fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 2479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport java.util.List; 2579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 26d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport javax.lang.model.element.Element; 27d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport javax.lang.model.element.ElementKind; 2879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport javax.lang.model.element.ExecutableElement; 2979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport javax.lang.model.element.Modifier; 30d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport javax.lang.model.element.TypeElement; 3179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport javax.lang.model.type.DeclaredType; 3279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport javax.lang.model.type.ExecutableType; 33fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mountimport javax.lang.model.type.TypeKind; 3479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mountimport javax.lang.model.type.TypeMirror; 35d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport javax.lang.model.util.Elements; 36a7e767e576adebcddf043ad34ccb8dd167f777b3George Mountimport javax.lang.model.util.Types; 3779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 38fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mountclass AnnotationMethod extends ModelMethod { 39a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount final ExecutableType mMethod; 4079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount final DeclaredType mDeclaringType; 41a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount final ExecutableElement mExecutableElement; 4297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar int mApiLevel = -1; // calculated on demand 43d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass mReceiverType; 4479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 45a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount public AnnotationMethod(DeclaredType declaringType, ExecutableElement executableElement) { 4679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount mDeclaringType = declaringType; 47a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount mExecutableElement = executableElement; 4897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar Types typeUtils = AnnotationAnalyzer.get().getTypeUtils(); 49a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount mMethod = (ExecutableType) typeUtils.asMemberOf(declaringType, executableElement); 5079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 5179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 5279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 5379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public ModelClass getDeclaringClass() { 54d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (mReceiverType == null) { 55d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mReceiverType = findReceiverType(mDeclaringType); 56d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (mReceiverType == null) { 57d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount mReceiverType = new AnnotationClass(mDeclaringType); 58d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 59d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 60d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return mReceiverType; 61d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 62d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 63d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount // TODO: When going to Java 1.8, use mExecutableElement.getReceiverType() 64d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private ModelClass findReceiverType(DeclaredType subType) { 65d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount List<? extends TypeMirror> supers = getTypeUtils().directSupertypes(subType); 66d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (TypeMirror superType : supers) { 67d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (superType.getKind() == TypeKind.DECLARED) { 68d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount DeclaredType declaredType = (DeclaredType) superType; 69d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ModelClass inSuper = findReceiverType(declaredType); 70d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (inSuper != null) { 71d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return inSuper; 72d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } else if (hasExecutableMethod(declaredType)) { 73d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return new AnnotationClass(declaredType); 74d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 75d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 76d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 77d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 78d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 79d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 80d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private boolean hasExecutableMethod(DeclaredType declaredType) { 81d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount Elements elementUtils = getElementUtils(); 82d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount TypeElement enclosing = (TypeElement) mExecutableElement.getEnclosingElement(); 83d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount TypeElement typeElement = (TypeElement) declaredType.asElement(); 84d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount for (Element element : typeElement.getEnclosedElements()) { 85d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (element.getKind() == ElementKind.METHOD) { 86d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount ExecutableElement executableElement = (ExecutableElement) element; 87d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount if (executableElement.equals(mExecutableElement) || 88d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount elementUtils.overrides(mExecutableElement, executableElement, enclosing)) { 89d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return true; 90d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 91d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 92d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 93d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return false; 9479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 9579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 9679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 9779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public ModelClass[] getParameterTypes() { 98a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount List<? extends TypeMirror> parameters = mMethod.getParameterTypes(); 9979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount ModelClass[] parameterTypes = new ModelClass[parameters.size()]; 10079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount for (int i = 0; i < parameters.size(); i++) { 101a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount parameterTypes[i] = new AnnotationClass(parameters.get(i)); 10279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 10379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return parameterTypes; 10479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 10579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 10679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 10779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public String getName() { 108a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount return mExecutableElement.getSimpleName().toString(); 10979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 11079fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 11179fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 11279fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public ModelClass getReturnType(List<ModelClass> args) { 113a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount TypeMirror returnType = mMethod.getReturnType(); 11479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount // TODO: support argument-supplied types 11579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount // for example: public T[] toArray(T[] arr) 11679fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount return new AnnotationClass(returnType); 11779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 11879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 11979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 120fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public boolean isVoid() { 121fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mMethod.getReturnType().getKind() == TypeKind.VOID; 122fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 123fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 124fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount @Override 12579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public boolean isPublic() { 126a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount return mExecutableElement.getModifiers().contains(Modifier.PUBLIC); 12779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 12879fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount 12979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount @Override 130bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount public boolean isProtected() { 131bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount return mExecutableElement.getModifiers().contains(Modifier.PROTECTED); 132bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount } 133bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount 134bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount @Override 13579fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public boolean isStatic() { 136a7e767e576adebcddf043ad34ccb8dd167f777b3George Mount return mExecutableElement.getModifiers().contains(Modifier.STATIC); 13779fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount } 13897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 13997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 140716ba89e7f459f49ea85070d4710c1d79d715298George Mount public boolean isAbstract() { 141716ba89e7f459f49ea85070d4710c1d79d715298George Mount return mExecutableElement.getModifiers().contains(Modifier.ABSTRACT); 142716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 143716ba89e7f459f49ea85070d4710c1d79d715298George Mount 144716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 145fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public boolean isBindable() { 146fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mExecutableElement.getAnnotation(Bindable.class) != null; 147fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 148fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 149fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount @Override 15097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public int getMinApi() { 15197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar if (mApiLevel == -1) { 15297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar mApiLevel = SdkUtil.getMinApi(this); 15397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 15497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return mApiLevel; 15597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 15697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 15797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 15897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public String getJniDescription() { 15997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return TypeUtil.getInstance().getDescription(this); 16097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 16197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 16297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar @Override 163fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount public boolean isVarArgs() { 164fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount return mExecutableElement.isVarArgs(); 165fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount } 166fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount 167d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static Types getTypeUtils() { 168d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return AnnotationAnalyzer.get().mProcessingEnv.getTypeUtils(); 169d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 170d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 171d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount private static Elements getElementUtils() { 172d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return AnnotationAnalyzer.get().mProcessingEnv.getElementUtils(); 173d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 174d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 175fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount @Override 17697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar public String toString() { 17797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return "AnnotationMethod{" + 17897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar "mMethod=" + mMethod + 17997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar ", mDeclaringType=" + mDeclaringType + 18097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar ", mExecutableElement=" + mExecutableElement + 18197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar ", mApiLevel=" + mApiLevel + 18297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar '}'; 18397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar } 18479fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount} 185