197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar/*
297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * you may not use this file except in compliance with the License.
697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * You may obtain a copy of the License at
797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar *
1097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * See the License for the specific language governing permissions and
1497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * limitations under the License.
1597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar */
1697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.reflection.annotation;
1897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass;
20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelMethod;
21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.TypeUtil;
2297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
2397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport java.util.List;
2497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
2597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport javax.lang.model.type.ArrayType;
2697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport javax.lang.model.type.ExecutableType;
2797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport javax.lang.model.type.TypeMirror;
2897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport javax.lang.model.type.TypeVariable;
2997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
3097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarpublic class AnnotationTypeUtil extends TypeUtil {
3197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    javax.lang.model.util.Types mTypes;
3297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
3397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    public AnnotationTypeUtil(
3497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            AnnotationAnalyzer annotationAnalyzer) {
3597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        mTypes = annotationAnalyzer.getTypeUtils();
3697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    }
3797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
3897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    @Override
3997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    public String getDescription(ModelClass modelClass) {
4097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        // TODO use interface
4197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        return modelClass.getCanonicalName().replace('.', '/');
4297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    }
4397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
4497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    @Override
4597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    public String getDescription(ModelMethod modelMethod) {
4697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        // TODO use interface
4797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        return modelMethod.getName() + getDescription(
4897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                ((AnnotationMethod) modelMethod).mExecutableElement.asType());
4997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    }
5097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
5197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    private String getDescription(TypeMirror typeMirror) {
5297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        if (typeMirror == null) {
5397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            throw new UnsupportedOperationException();
5497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        }
5597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        switch (typeMirror.getKind()) {
5697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case BOOLEAN:
5797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return BOOLEAN;
5897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case BYTE:
5997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return BYTE;
6097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case SHORT:
6197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return SHORT;
6297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case INT:
6397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return INT;
6497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case LONG:
6597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return LONG;
6697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case CHAR:
6797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return CHAR;
6897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case FLOAT:
6997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return FLOAT;
7097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case DOUBLE:
7197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return DOUBLE;
7297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case DECLARED:
7397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return CLASS_PREFIX + mTypes.erasure(typeMirror).toString().replace('.', '/') + CLASS_SUFFIX;
7497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case VOID:
7597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return VOID;
7697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case ARRAY:
7797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final ArrayType arrayType = (ArrayType) typeMirror;
7897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final String componentType = getDescription(arrayType.getComponentType());
7997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return ARRAY + componentType;
8097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case TYPEVAR:
8197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final TypeVariable typeVariable = (TypeVariable) typeMirror;
8297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final String name = typeVariable.toString();
8397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return CLASS_PREFIX + name.replace('.', '/') + CLASS_SUFFIX;
8497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            case EXECUTABLE:
8597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final ExecutableType executableType = (ExecutableType) typeMirror;
8697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final int argStart = mTypes.erasure(executableType).toString().indexOf('(');
8797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final String methodName = executableType.toString().substring(0, argStart);
8897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                final String args = joinArgs(executableType.getParameterTypes());
8997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                // TODO detect constructor?
9097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                return methodName + "(" + args + ")" + getDescription(
9197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                        executableType.getReturnType());
9297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            default:
9397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                throw new UnsupportedOperationException("cannot understand type "
9497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar                        + typeMirror.toString() + ", kind:" + typeMirror.getKind().name());
9597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        }
9697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    }
9797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar
9897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    private String joinArgs(List<? extends TypeMirror> mirrorList) {
9997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        StringBuilder result = new StringBuilder();
10097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        for (TypeMirror mirror : mirrorList) {
10197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar            result.append(getDescription(mirror));
10297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        }
10397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar        return result.toString();
10497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar    }
10597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar}
106