diff options
author | George Mount <mount@google.com> | 2015-02-17 16:02:52 -0800 |
---|---|---|
committer | George Mount <mount@google.com> | 2015-02-17 16:15:29 -0800 |
commit | 812d215fa6658b0377699e01e42fa66fd14ccbe4 (patch) | |
tree | c929c6b79bf7583f62aac9b46472cc8d24e6a640 /tools | |
parent | d872e1cdf78608ac86297237b5ef85b4648e9e04 (diff) | |
download | frameworks_base-812d215fa6658b0377699e01e42fa66fd14ccbe4.zip frameworks_base-812d215fa6658b0377699e01e42fa66fd14ccbe4.tar.gz frameworks_base-812d215fa6658b0377699e01e42fa66fd14ccbe4.tar.bz2 |
Removed reflection-based implementations and renamed classes.
Renamed Model* classes to Annotation*
Renamed Reflection* classes to Model*
Removed Class* classes -- they are no longer needed.
The names were confusing. I think this is better.
Diffstat (limited to 'tools')
41 files changed, 1039 insertions, 1780 deletions
diff --git a/tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java b/tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java index eaeb3c7..4113292 100644 --- a/tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java +++ b/tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java @@ -1,7 +1,6 @@ package com.android.databinding.annotationprocessor; import com.android.databinding.reflection.ModelAnalyzer; -import com.android.databinding.reflection.ReflectionAnalyzer; import android.binding.Bindable; @@ -18,7 +17,6 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.annotation.processing.AbstractProcessor; @@ -28,15 +26,11 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; -import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import javax.tools.Diagnostic; import javax.tools.FileObject; import javax.tools.JavaFileObject; @@ -54,7 +48,7 @@ public class ProcessBindable extends AbstractProcessor { @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); - ReflectionAnalyzer.setProcessingEnvironment(processingEnv); + ModelAnalyzer.setProcessingEnvironment(processingEnv); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/Binding.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/Binding.java index d1740cc..3153bda 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/Binding.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/Binding.java @@ -16,8 +16,8 @@ package com.android.databinding; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import com.android.databinding.store.SetterStore; import com.android.databinding.expr.Expr; @@ -39,15 +39,15 @@ public class Binding { } public String toJavaCode(String targetViewName, String expressionCode) { - ReflectionClass viewType = mTarget.getResolvedType(); - return SetterStore.get(ReflectionAnalyzer.getInstance()).getSetterCall(mName, viewType, + ModelClass viewType = mTarget.getResolvedType(); + return SetterStore.get(ModelAnalyzer.getInstance()).getSetterCall(mName, viewType, mExpr.getResolvedType(), targetViewName, expressionCode); } -// private String resolveJavaCode(ReflectionAnalyzer reflectionAnalyzer) { +// private String resolveJavaCode(ModelAnalyzer modelAnalyzer) { // // } -//// return reflectionAnalyzer.findMethod(mTarget.getResolvedType(), mName, +//// return modelAnalyzer.findMethod(mTarget.getResolvedType(), mName, //// Arrays.asList(mExpr.getResolvedType())); // //} // diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/BindingTarget.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/BindingTarget.java index d165f07..0c5911c 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/BindingTarget.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/BindingTarget.java @@ -18,8 +18,8 @@ package com.android.databinding; import com.android.databinding.expr.Expr; import com.android.databinding.expr.ExprModel; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import com.android.databinding.store.ResourceBundle; import java.util.ArrayList; @@ -28,7 +28,7 @@ import java.util.List; public class BindingTarget { List<Binding> mBindings = new ArrayList<>(); ExprModel mModel; - ReflectionClass mResolvedClass; + ModelClass mResolvedClass; // if this target presents itself in multiple layout files with different view types, // it receives an interface type and should use it in the getter instead. private ResourceBundle.BindingTargetBundle mBundle; @@ -57,9 +57,9 @@ public class BindingTarget { return mBundle.getFullClassName(); } - public ReflectionClass getResolvedType() { + public ModelClass getResolvedType() { if (mResolvedClass == null) { - mResolvedClass = ReflectionAnalyzer.getInstance().findClass(mBundle.getFullClassName()); + mResolvedClass = ModelAnalyzer.getInstance().findClass(mBundle.getFullClassName()); } return mResolvedClass; } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/ExpressionVisitor.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/ExpressionVisitor.java index 1b5459d..cc0516f 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/ExpressionVisitor.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/ExpressionVisitor.java @@ -20,7 +20,6 @@ import com.google.common.base.Preconditions; import com.android.databinding.expr.Expr; import com.android.databinding.expr.ExprModel; -import com.android.databinding.reflection.ReflectionAnalyzer; import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.tree.ParseTree; @@ -241,8 +240,8 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> { // @org.jetbrains.annotations.NotNull // @Override // public Class<? extends Object> resolveValueType( -// @org.jetbrains.annotations.NotNull ReflectionAnalyzer reflectionAnalyzer) { -// return reflectionAnalyzer.commonParentOf(aggregate.getResolvedClass(), nextResult.getResolvedClass()); +// @org.jetbrains.annotations.NotNull ModelAnalyzer modelAnalyzer) { +// return modelAnalyzer.commonParentOf(aggregate.getResolvedClass(), nextResult.getResolvedClass()); // } // // @org.jetbrains.annotations.NotNull diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/BracketExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/BracketExpr.java index 06cc7c1..7b5752b 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/BracketExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/BracketExpr.java @@ -16,12 +16,10 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ClassClass; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; -import java.util.Map; public class BracketExpr extends Expr { @@ -38,8 +36,8 @@ public class BracketExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { - ReflectionClass targetType = getTarget().resolveType(reflectionAnalyzer); + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + ModelClass targetType = getTarget().resolveType(modelAnalyzer); if (targetType.isArray()) { mAccessor = BracketAccessor.ARRAY; } else if (targetType.isList()) { diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ComparisonExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ComparisonExpr.java index 2737e31..2935729 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ComparisonExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ComparisonExpr.java @@ -16,8 +16,8 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; @@ -34,8 +34,8 @@ public class ComparisonExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { - return reflectionAnalyzer.loadPrimitive("boolean"); + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return modelAnalyzer.loadPrimitive("boolean"); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java index 7e59733..862a7b2 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java @@ -28,8 +28,8 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; abstract public class Expr { @@ -41,7 +41,7 @@ abstract public class Expr { private Boolean mIsDynamic; - private ReflectionClass mResolvedType; + private ModelClass mResolvedType; private String mUniqueKey; @@ -145,7 +145,7 @@ abstract public class Expr { } public boolean isObservable() { - return ReflectionAnalyzer.getInstance().isObservable(getResolvedType()); + return ModelAnalyzer.getInstance().isObservable(getResolvedType()); } public BitSet getShouldReadFlags() { @@ -278,15 +278,15 @@ abstract public class Expr { } - public ReflectionClass getResolvedType() { + public ModelClass getResolvedType() { if (mResolvedType == null) { // TODO not get instance - mResolvedType = resolveType(ReflectionAnalyzer.getInstance()); + mResolvedType = resolveType(ModelAnalyzer.getInstance()); } return mResolvedType; } - abstract protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer); + abstract protected ModelClass resolveType(ModelAnalyzer modelAnalyzer); abstract protected List<Dependency> constructDependencies(); @@ -535,7 +535,7 @@ abstract public class Expr { } public String getDefaultValue() { - return ReflectionAnalyzer.getInstance().getDefaultValue(getResolvedType().toJavaCode()); + return ModelAnalyzer.getInstance().getDefaultValue(getResolvedType().toJavaCode()); } protected BitSet getPredicateInvalidFlags() { @@ -569,7 +569,7 @@ abstract public class Expr { return mIsUsed; } - public void updateExpr(ReflectionAnalyzer reflectionAnalyzer) { + public void updateExpr(ModelAnalyzer modelAnalyzer) { } static class Node { diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java index 4a0d7fd..17d0470 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java @@ -21,8 +21,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.util.L; import com.android.databinding.writer.FlagSet; @@ -192,7 +191,7 @@ public class ExprModel { public void seal() { List<Expr> notifiableExpressions = new ArrayList<>(); //ensure class analyzer. We need to know observables at this point - final ReflectionAnalyzer reflectionAnalyzer = ReflectionAnalyzer.getInstance(); + final ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance(); ArrayList<Expr> processedExprs = new ArrayList<>(); ArrayList<Expr> exprs = new ArrayList<>(); @@ -201,13 +200,13 @@ public class ExprModel { exprs.addAll(mExprMap.values()); exprs.removeAll(processedExprs); for (Expr expr: exprs) { - expr.updateExpr(reflectionAnalyzer); + expr.updateExpr(modelAnalyzer); } processedExprs.addAll(exprs); } while (!exprs.isEmpty()); int counter = 0; - final Iterable<Expr> observables = filterObservables(reflectionAnalyzer); + final Iterable<Expr> observables = filterObservables(modelAnalyzer); List<String> flagMapping = Lists.newArrayList(); mObservables = Lists.newArrayList(); for (Expr expr : observables) { @@ -220,7 +219,7 @@ public class ExprModel { } // non-observable identifiers gets next ids - final Iterable<Expr> nonObservableIds = filterNonObservableIds(reflectionAnalyzer); + final Iterable<Expr> nonObservableIds = filterNonObservableIds(modelAnalyzer); for (Expr expr : nonObservableIds) { flagMapping.add(expr.getUniqueKey()); expr.setId(counter++); @@ -337,23 +336,23 @@ public class ExprModel { return mFlagMapping[id]; } - private Iterable<Expr> filterNonObservableIds(final ReflectionAnalyzer reflectionAnalyzer) { + private Iterable<Expr> filterNonObservableIds(final ModelAnalyzer modelAnalyzer) { return Iterables.filter(mExprMap.values(), new Predicate<Expr>() { @Override public boolean apply(Expr input) { return input instanceof IdentifierExpr && !input.hasId() - && !reflectionAnalyzer.isObservable(input.getResolvedType()) + && !modelAnalyzer.isObservable(input.getResolvedType()) && input.isDynamic(); } }); } - private Iterable<Expr> filterObservables(final ReflectionAnalyzer reflectionAnalyzer) { + private Iterable<Expr> filterObservables(final ModelAnalyzer modelAnalyzer) { return Iterables.filter(mExprMap.values(), new Predicate<Expr>() { @Override public boolean apply(Expr input) { - return reflectionAnalyzer.isObservable(input.getResolvedType()); + return modelAnalyzer.isObservable(input.getResolvedType()); } }); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java index 5e63971..c7cb8b0 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java @@ -16,11 +16,10 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.reflection.Callable; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelClass; -import java.util.Collections; import java.util.List; public class FieldAccessExpr extends Expr { @@ -87,10 +86,10 @@ public class FieldAccessExpr extends Expr { } @Override - public void updateExpr(ReflectionAnalyzer reflectionAnalyzer) { + public void updateExpr(ModelAnalyzer modelAnalyzer) { if (mGetter == null) { - mGetter = reflectionAnalyzer.findMethodOrField(mChildren.get(0).getResolvedType(), mName); - if (reflectionAnalyzer.isObservableField(mGetter.resolvedType)) { + mGetter = modelAnalyzer.findMethodOrField(mChildren.get(0).getResolvedType(), mName); + if (modelAnalyzer.isObservableField(mGetter.resolvedType)) { // Make this the ".get()" and add an extra field access for the observable field Expr parent = getParent(); parent.getParents().remove(this); @@ -101,16 +100,16 @@ public class FieldAccessExpr extends Expr { getChildren().add(observableField); observableField.getParents().add(this); - mGetter = reflectionAnalyzer.findMethodOrField(mGetter.resolvedType, "get"); + mGetter = modelAnalyzer.findMethodOrField(mGetter.resolvedType, "get"); mName = ""; } } } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if (mGetter == null) { - mGetter = reflectionAnalyzer.findMethodOrField(mChildren.get(0).getResolvedType(), mName); + mGetter = modelAnalyzer.findMethodOrField(mChildren.get(0).getResolvedType(), mName); } return mGetter.resolvedType; } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/GroupExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/GroupExpr.java index d62b98c..e21778b 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/GroupExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/GroupExpr.java @@ -16,8 +16,8 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; @@ -27,8 +27,8 @@ public class GroupExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { - return getWrapped().resolveType(reflectionAnalyzer); + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return getWrapped().resolveType(modelAnalyzer); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/IdentifierExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/IdentifierExpr.java index 6e94851..cfcbc43 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/IdentifierExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/IdentifierExpr.java @@ -19,8 +19,8 @@ package com.android.databinding.expr; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; @@ -58,10 +58,10 @@ public class IdentifierExpr extends Expr { } @Override - protected ReflectionClass resolveType(final ReflectionAnalyzer reflectionAnalyzer) { + protected ModelClass resolveType(final ModelAnalyzer modelAnalyzer) { Preconditions.checkNotNull(mUserDefinedType, "Identifiers must have user defined types from the XML file. %s is missing it", mName); - return reflectionAnalyzer.findClass(mUserDefinedType); + return modelAnalyzer.findClass(mUserDefinedType); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MathExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MathExpr.java index 7d99a58..378bc3b 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MathExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MathExpr.java @@ -16,8 +16,8 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; @@ -34,15 +34,15 @@ public class MathExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if ("+".equals(mOp)) { // TODO we need upper casting etc. if (getLeft().getResolvedType().isString() || getRight().getResolvedType().isString()) { - return reflectionAnalyzer.findClass(String.class); + return modelAnalyzer.findClass(String.class); } } - return reflectionAnalyzer.findCommonParentOf(getLeft().getResolvedType(), + return modelAnalyzer.findCommonParentOf(getLeft().getResolvedType(), getRight().getResolvedType()); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java index 119e65e..dfae772 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java @@ -18,9 +18,9 @@ package com.android.databinding.expr; import com.google.common.collect.Iterables; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.reflection.Callable; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelClass; import java.util.ArrayList; import java.util.Arrays; @@ -37,13 +37,13 @@ public class MethodCallExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if (mGetter == null) { - List<ReflectionClass> args = new ArrayList<>(); + List<ModelClass> args = new ArrayList<>(); for (Expr expr : getArgs()) { args.add(expr.getResolvedType()); } - mGetter = reflectionAnalyzer.findMethod(getTarget().getResolvedType(), mName, args); + mGetter = modelAnalyzer.findMethod(getTarget().getResolvedType(), mName, args); } return mGetter.resolvedType; } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ResourceExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ResourceExpr.java index a8caace..1951a4d 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ResourceExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ResourceExpr.java @@ -17,8 +17,8 @@ package com.android.databinding.expr; import com.google.common.collect.ImmutableMap; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.Collections; import java.util.List; @@ -60,7 +60,7 @@ public class ResourceExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { String type; switch (mResourceType) { case "anim": @@ -70,7 +70,7 @@ public class ResourceExpr extends Expr { type = "android.animation.Animator"; break; case "bool": - return reflectionAnalyzer.findClass(boolean.class); + return modelAnalyzer.findClass(boolean.class); case "color": case "dimenOffset": case "dimenSize": @@ -78,18 +78,18 @@ public class ResourceExpr extends Expr { case "integer": case "layout": case "plurals": - return reflectionAnalyzer.findClass(int.class); + return modelAnalyzer.findClass(int.class); case "colorStateList": type = "android.content.res.ColorStateList"; break; case "dimen": case "fraction": - return reflectionAnalyzer.findClass(float.class); + return modelAnalyzer.findClass(float.class); case "drawable": type = "android.graphics.drawable.Drawable"; break; case "intArray": - return reflectionAnalyzer.findClass(int[].class); + return modelAnalyzer.findClass(int[].class); case "interpolator": type = ""; break; @@ -97,9 +97,9 @@ public class ResourceExpr extends Expr { type = "android.animation.StateListAnimator"; break; case "string": - return reflectionAnalyzer.findClass(String.class); + return modelAnalyzer.findClass(String.class); case "stringArray": - return reflectionAnalyzer.findClass(String[].class); + return modelAnalyzer.findClass(String[].class); case "transition": type = "android.transition.Transition"; break; @@ -110,7 +110,7 @@ public class ResourceExpr extends Expr { type = mResourceType; break; } - return reflectionAnalyzer.findClass(type); + return modelAnalyzer.findClass(type); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/SymbolExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/SymbolExpr.java index 5c66822..9489ee3 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/SymbolExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/SymbolExpr.java @@ -18,8 +18,8 @@ package com.android.databinding.expr; import com.google.common.collect.Lists; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.List; @@ -38,8 +38,8 @@ public class SymbolExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { - return reflectionAnalyzer.findClass(mType); + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return modelAnalyzer.findClass(mType); } @Override diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/TernaryExpr.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/TernaryExpr.java index 01dde25..6d0f003 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/TernaryExpr.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/expr/TernaryExpr.java @@ -18,8 +18,8 @@ package com.android.databinding.expr; import com.google.common.collect.Lists; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; import java.util.BitSet; import java.util.List; @@ -47,8 +47,8 @@ public class TernaryExpr extends Expr { } @Override - protected ReflectionClass resolveType(ReflectionAnalyzer reflectionAnalyzer) { - return reflectionAnalyzer.findCommonParentOf(getIfTrue().getResolvedType(), + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return modelAnalyzer.findCommonParentOf(getIfTrue().getResolvedType(), getIfFalse().getResolvedType()); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationAnalyzer.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationAnalyzer.java new file mode 100644 index 0000000..02c4fc2 --- /dev/null +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationAnalyzer.java @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.databinding.reflection; + +import com.google.common.collect.ImmutableMap; + +import com.android.databinding.util.L; + +import org.apache.commons.lang3.StringUtils; + +import android.binding.Bindable; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic; + +public class AnnotationAnalyzer extends ModelAnalyzer { + + public static final String LIST_CLASS_NAME = "java.util.List"; + + public static final String MAP_CLASS_NAME = "java.util.Map"; + + public static final String STRING_CLASS_NAME = "java.lang.String"; + + public static final String OBJECT_CLASS_NAME = "java.lang.Object"; + + static AnnotationAnalyzer instance; + private static final String OBSERVABLE_CLASS_NAME = "android.binding.Observable"; + private static final String OBSERVABLE_LIST_CLASS_NAME = "android.binding.ObservableList"; + private static final String OBSERVABLE_MAP_CLASS_NAME = "android.binding.ObservableMap"; + private static final String[] OBSERVABLE_FIELDS = { + "com.android.databinding.library.ObservableBoolean", + "com.android.databinding.library.ObservableByte", + "com.android.databinding.library.ObservableChar", + "com.android.databinding.library.ObservableShort", + "com.android.databinding.library.ObservableInt", + "com.android.databinding.library.ObservableLong", + "com.android.databinding.library.ObservableFloat", + "com.android.databinding.library.ObservableDouble", + "com.android.databinding.library.ObservableField", + }; + private static final String I_VIEW_DATA_BINDER = "com.android.databinding.library.IViewDataBinder"; + private static final Map<String, TypeKind> PRIMITIVE_TYPES = + new ImmutableMap.Builder<String, TypeKind>() + .put("boolean", TypeKind.BOOLEAN) + .put("byte", TypeKind.BYTE) + .put("short", TypeKind.SHORT) + .put("char", TypeKind.CHAR) + .put("int", TypeKind.INT) + .put("long", TypeKind.LONG) + .put("float", TypeKind.FLOAT) + .put("double", TypeKind.DOUBLE) + .build(); + + public final ProcessingEnvironment processingEnv; + public final TypeMirror listType; + public final TypeMirror mapType; + public final TypeMirror stringType; + public final TypeMirror objectType; + + private final AnnotationClass mObservableType; + private final AnnotationClass mObservableListType; + private final AnnotationClass mObservableMapType; + private final AnnotationClass[] mObservableFieldTypes; + private final AnnotationClass mIViewDataBinderType; + + public AnnotationAnalyzer(ProcessingEnvironment processingEnvironment) { + processingEnv = processingEnvironment; + instance = this; + Types typeUtil = processingEnv.getTypeUtils(); + listType = typeUtil.erasure(findType(LIST_CLASS_NAME).asType()); + mapType = typeUtil.erasure(findType(MAP_CLASS_NAME).asType()); + stringType = typeUtil.erasure(findType(STRING_CLASS_NAME).asType()); + objectType = typeUtil.erasure(findType(OBJECT_CLASS_NAME).asType()); + mObservableType = new AnnotationClass(findType(OBSERVABLE_CLASS_NAME).asType()); + mObservableListType = new AnnotationClass(typeUtil.erasure( + findType(OBSERVABLE_LIST_CLASS_NAME).asType())); + mObservableMapType = new AnnotationClass(typeUtil.erasure( + findType(OBSERVABLE_MAP_CLASS_NAME).asType())); + mIViewDataBinderType = new AnnotationClass(findType(I_VIEW_DATA_BINDER).asType()); + mObservableFieldTypes = new AnnotationClass[OBSERVABLE_FIELDS.length]; + for (int i = 0; i < OBSERVABLE_FIELDS.length; i++) { + mObservableFieldTypes[i] = new AnnotationClass(findType(OBSERVABLE_FIELDS[i]).asType()); + } + } + + TypeElement findType(String type) { + return processingEnv.getElementUtils().getTypeElement(type); + } + + @Override + public boolean isDataBinder(ModelClass modelClass) { + return mIViewDataBinderType.isAssignableFrom(modelClass); + } + + @Override + public Callable findMethod(ModelClass modelClass, String name, + List<ModelClass> args) { + AnnotationClass clazz = (AnnotationClass)modelClass; + // TODO implement properly + for (String methodName : new String[]{"set" + StringUtils.capitalize(name), name}) { + for (ModelMethod method : clazz.getMethods(methodName, args.size())) { + ModelClass[] parameters = method.getParameterTypes(); + boolean parametersMatch = true; + boolean isVarArgs = ((AnnotationMethod)method).mMethod.isVarArgs(); + for (int i = 0; i < parameters.length; i++) { + if (isVarArgs && i == parameters.length - 1) { + ModelClass component = parameters[i].getComponentType(); + for (int j = i; j < args.size(); j++) { + if (!component.isAssignableFrom(args.get(j))) { + parametersMatch = false; + break; + } + } + } else if (!parameters[i].isAssignableFrom(args.get(i))) { + parametersMatch = false; + break; + } + } + if (parametersMatch) { + return new Callable(Callable.Type.METHOD, methodName, + method.getReturnType(args), true, false); + } + } + } + String message = "cannot find method " + name + " at class " + clazz.toJavaCode(); + printMessage(Diagnostic.Kind.ERROR, message); + throw new IllegalArgumentException(message); + } + + @Override + public boolean isObservable(ModelClass modelClass) { + AnnotationClass annotationClass = (AnnotationClass)modelClass; + return mObservableType.isAssignableFrom(annotationClass) || + mObservableListType.isAssignableFrom(annotationClass) || + mObservableMapType.isAssignableFrom(annotationClass); + } + + @Override + public boolean isObservableField(ModelClass modelClass) { + AnnotationClass annotationClass = (AnnotationClass)modelClass; + AnnotationClass erasure = new AnnotationClass(getTypeUtils().erasure(annotationClass.mTypeMirror)); + for (AnnotationClass observableField : mObservableFieldTypes) { + if (observableField.isAssignableFrom(erasure)) { + return true; + } + } + return false; + } + + @Override + public boolean isBindable(ModelField field) { + VariableElement fieldElement = ((AnnotationField) field).mField; + return fieldElement.getAnnotation(Bindable.class) != null; + } + + @Override + public boolean isBindable(ModelMethod method) { + ExecutableElement methodElement = ((AnnotationMethod) method).mMethod; + return methodElement.getAnnotation(Bindable.class) != null; + } + + @Override + public Callable findMethodOrField(ModelClass modelClass, String name) { + AnnotationClass annotationClass = (AnnotationClass)modelClass; + for (String methodName : + new String[]{"get" + StringUtils.capitalize(name), + "is" + StringUtils.capitalize(name), name}) { + ModelMethod[] methods = modelClass.getMethods(methodName, 0); + for (ModelMethod modelMethod : methods) { + AnnotationMethod method = (AnnotationMethod) modelMethod; + if (method.isPublic()) { + final AnnotationField backingField = findField(annotationClass, name, true); + final Callable result = new Callable(Callable.Type.METHOD, methodName, + method.getReturnType(null), true, isBindable(method) || + (backingField != null && isBindable(backingField))); + L.d("backing field for %s is %s", result, backingField); + return result; + } + } + } + + AnnotationField field = findField(annotationClass, name, false); + if (field != null && field.mField.getModifiers().contains(Modifier.PUBLIC)) { + AnnotationClass fieldType = new AnnotationClass(field.mField.asType()); + return new Callable(Callable.Type.FIELD, name, fieldType, + !field.mField.getModifiers().contains(Modifier.FINAL) + || isObservable(fieldType), isBindable(field)); + } + throw new IllegalArgumentException( + "cannot find " + name + " in " + + ((DeclaredType) annotationClass.mTypeMirror).asElement().getSimpleName()); + } + + private AnnotationField findField(AnnotationClass clazz, String name, boolean allowNonPublic) { + if (clazz == null || clazz.mTypeMirror.getKind() != TypeKind.DECLARED) { + return null; + } + TypeElement typeElement = (TypeElement) ((DeclaredType) clazz.mTypeMirror).asElement(); + for (VariableElement field : ElementFilter.fieldsIn( + getElementUtils().getAllMembers(typeElement))) { + if (name.equals(stripFieldName(field.getSimpleName().toString()))) { + if (allowNonPublic || field.getModifiers().contains(Modifier.PUBLIC)) { + return new AnnotationField(typeElement, field); + } + } + } + return null; // nothing found + } + + @Override + public AnnotationClass loadPrimitive(String className) { + TypeKind typeKind = PRIMITIVE_TYPES.get(className); + if (typeKind == null) { + return null; + } else { + Types typeUtils = getTypeUtils(); + return new AnnotationClass(typeUtils.getPrimitiveType(typeKind)); + } + } + + private static String stripFieldName(String fieldName) { + if (fieldName.length() > 2) { + final char start = fieldName.charAt(2); + if (fieldName.startsWith("m_") && Character.isJavaIdentifierStart(start)) { + return Character.toLowerCase(start) + fieldName.substring(3); + } + } + if (fieldName.length() > 1) { + final char start = fieldName.charAt(1); + final char fieldIdentifier = fieldName.charAt(0); + final boolean strip; + if (fieldIdentifier == '_') { + strip = true; + } else if (fieldIdentifier == 'm' && Character.isJavaIdentifierStart(start) && + !Character.isLowerCase(start)) { + strip = true; + } else { + strip = false; // not mUppercase format + } + if (strip) { + return Character.toLowerCase(start) + fieldName.substring(2); + } + } + return fieldName; + } + + @Override + public AnnotationClass findClass(String className) { + className = className.trim(); + int numDimensions = 0; + while (className.endsWith("[]")) { + numDimensions++; + className = className.substring(0, className.length() - 2); + } + AnnotationClass primitive = loadPrimitive(className); + if (primitive != null) { + return addDimension(primitive.mTypeMirror, numDimensions); + } + int templateOpenIndex = className.indexOf('<'); + DeclaredType declaredType; + if (templateOpenIndex < 0) { + Elements elementUtils = getElementUtils(); + TypeElement typeElement = elementUtils.getTypeElement(className); + declaredType = (DeclaredType) typeElement.asType(); + } else { + int templateCloseIndex = className.lastIndexOf('>'); + String paramStr = className.substring(templateOpenIndex + 1, templateCloseIndex - 1); + + Elements elementUtils = getElementUtils(); + String baseClassName = className.substring(0, templateOpenIndex); + TypeElement typeElement = elementUtils.getTypeElement(baseClassName); + + ArrayList<String> templateParameters = splitTemplateParameters(paramStr); + TypeMirror[] typeArgs = new TypeMirror[templateParameters.size()]; + for (int i = 0; i < typeArgs.length; i++) { + typeArgs[i] = findClass(templateParameters.get(i)).mTypeMirror; + } + + Types typeUtils = getTypeUtils(); + declaredType = typeUtils.getDeclaredType(typeElement, typeArgs); + } + return addDimension(declaredType, numDimensions); + } + + private AnnotationClass addDimension(TypeMirror type, int numDimensions) { + while (numDimensions > 0) { + type = getTypeUtils().getArrayType(type); + numDimensions--; + } + return new AnnotationClass(type); + } + + private ArrayList<String> splitTemplateParameters(String templateParameters) { + ArrayList<String> list = new ArrayList<>(); + int index = 0; + int openCount = 0; + StringBuilder arg = new StringBuilder(); + while (index < templateParameters.length()) { + char c = templateParameters.charAt(index); + if (c == ',' && openCount == 0) { + list.add(arg.toString()); + arg.delete(0, arg.length()); + } else if (!Character.isWhitespace(c)) { + arg.append(c); + if (c == '<') { + openCount++; + } else if (c == '>') { + openCount--; + } + } + } + list.add(arg.toString()); + return list; + } + + @Override + public List<URL> getResources(String name) { + ArrayList<URL> urls = new ArrayList<>(); + try { + Enumeration<URL> resources = getClass().getClassLoader().getResources(name); + while (resources.hasMoreElements()) { + urls.add(resources.nextElement()); + } + } catch (IOException e) { + printMessage(Diagnostic.Kind.ERROR, "IOException while getting resources: " + + e.getLocalizedMessage()); + } + + return urls; + } + + @Override + public ModelClass findClass(Class classType) { + return findClass(classType.getCanonicalName()); + } + + public Types getTypeUtils() { + return processingEnv.getTypeUtils(); + } + + public Elements getElementUtils() { + return processingEnv.getElementUtils(); + } + + public void printMessage(Diagnostic.Kind kind, String message) { + processingEnv.getMessager().printMessage(kind, message); + } +} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationClass.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationClass.java new file mode 100644 index 0000000..e7db2d5 --- /dev/null +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationClass.java @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.databinding.reflection; + +import java.util.ArrayList; +import java.util.List; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.PrimitiveType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic; + +public class AnnotationClass implements ModelClass { + + final TypeMirror mTypeMirror; + + public AnnotationClass(TypeMirror typeMirror) { + mTypeMirror = typeMirror; + } + + @Override + public String toJavaCode() { + return toJavaCode(mTypeMirror); + } + + private static String toJavaCode(TypeMirror typeElement) { + return typeElement.toString(); + } + + @Override + public boolean isArray() { + return mTypeMirror.getKind() == TypeKind.ARRAY; + } + + @Override + public AnnotationClass getComponentType() { + TypeMirror component; + if (isArray()) { + component = ((ArrayType) mTypeMirror).getComponentType(); + } else if (isList()) { + DeclaredType listType = findInterface(getListType()); + if (listType == null) { + return null; + } + component = listType.getTypeArguments().get(0); + } else { + DeclaredType mapType = findInterface(getMapType()); + if (mapType == null) { + return null; + } + component = mapType.getTypeArguments().get(1); + } + + return new AnnotationClass(component); + } + + private DeclaredType findInterface(TypeMirror interfaceType) { + Types typeUtil = getTypeUtils(); + TypeMirror foundInterface = null; + if (typeUtil.isSameType(interfaceType, typeUtil.erasure(mTypeMirror))) { + foundInterface = mTypeMirror; + } else if (mTypeMirror.getKind() == TypeKind.DECLARED) { + DeclaredType declaredType = (DeclaredType) mTypeMirror; + TypeElement typeElement = (TypeElement) declaredType.asElement(); + for (TypeMirror type : typeElement.getInterfaces()) { + if (typeUtil.isSameType(interfaceType, typeUtil.erasure(type))) { + foundInterface = type; + break; + } + } + if (foundInterface == null) { + printMessage(Diagnostic.Kind.ERROR, + "Detected " + interfaceType + " type for " + mTypeMirror + + ", but not able to find the implemented interface."); + return null; + } + } + if (foundInterface.getKind() != TypeKind.DECLARED) { + printMessage(Diagnostic.Kind.ERROR, + "Found " + interfaceType + " type for " + mTypeMirror + + ", but it isn't a declared type: " + foundInterface); + return null; + } + return (DeclaredType) foundInterface; + } + + @Override + public boolean isList() { + AnnotationAnalyzer analyzer = AnnotationAnalyzer.instance; + Types typeUtil = getTypeUtils(); + return typeUtil.isAssignable(typeUtil.erasure(mTypeMirror), getListType()); + } + + @Override + public boolean isMap() { + AnnotationAnalyzer analyzer = AnnotationAnalyzer.instance; + Types typeUtil = getTypeUtils(); + return typeUtil.isAssignable(typeUtil.erasure(mTypeMirror), getMapType()); + } + + @Override + public boolean isString() { + return getTypeUtils().isSameType(mTypeMirror, getStringType()); + } + + @Override + public boolean isNullable() { + switch (mTypeMirror.getKind()) { + case ARRAY: + case DECLARED: + case NULL: + return true; + default: + return false; + } + } + + @Override + public boolean isPrimitive() { + switch (mTypeMirror.getKind()) { + case BOOLEAN: + case BYTE: + case SHORT: + case INT: + case LONG: + case CHAR: + case FLOAT: + case DOUBLE: + return true; + default: + return false; + } + } + + @Override + public boolean isBoolean() { + return mTypeMirror.getKind() == TypeKind.BOOLEAN; + } + + @Override + public boolean isChar() { + return mTypeMirror.getKind() == TypeKind.CHAR; + } + + @Override + public boolean isByte() { + return mTypeMirror.getKind() == TypeKind.BYTE; + } + + @Override + public boolean isShort() { + return mTypeMirror.getKind() == TypeKind.SHORT; + } + + @Override + public boolean isInt() { + return mTypeMirror.getKind() == TypeKind.INT; + } + + @Override + public boolean isLong() { + return mTypeMirror.getKind() == TypeKind.LONG; + } + + @Override + public boolean isFloat() { + return mTypeMirror.getKind() == TypeKind.FLOAT; + } + + @Override + public boolean isDouble() { + return mTypeMirror.getKind() == TypeKind.DOUBLE; + } + + @Override + public boolean isObject() { + return getTypeUtils().isSameType(mTypeMirror, getObjectType()); + } + + @Override + public boolean isVoid() { + return mTypeMirror.getKind() == TypeKind.VOID; + } + + @Override + public AnnotationClass unbox() { + if (!isNullable()) { + return this; + } + try { + return new AnnotationClass(getTypeUtils().unboxedType(mTypeMirror)); + } catch (IllegalArgumentException e) { + // I'm being lazy. This is much easier than checking every type. + return this; + } + } + + @Override + public ModelClass box() { + if (!isPrimitive()) { + return this; + } + return new AnnotationClass(getTypeUtils().boxedClass((PrimitiveType) mTypeMirror).asType()); + } + + @Override + public boolean isAssignableFrom(ModelClass that) { + TypeMirror thatType = ((AnnotationClass)that).mTypeMirror; + return getTypeUtils().isAssignable(thatType, mTypeMirror); + } + + @Override + public ModelMethod[] getMethods(String name, int numParameters) { + ArrayList<AnnotationMethod> matching = new ArrayList<>(); + if (mTypeMirror.getKind() == TypeKind.DECLARED) { + DeclaredType declaredType = (DeclaredType) mTypeMirror; + getMethods(declaredType, matching, name, numParameters); + } + return matching.toArray(new ModelMethod[matching.size()]); + } + + private static void getMethods(DeclaredType declaredType, ArrayList<AnnotationMethod> methods, + String name, int numParameters) { + Elements elementUtils = getElementUtils(); + for (ExecutableElement element : + ElementFilter.methodsIn(elementUtils.getAllMembers((TypeElement)declaredType.asElement()))) { + if (element.getSimpleName().toString().equals(name)) { + List<? extends VariableElement> parameters = element.getParameters(); + if (parameters.size() == numParameters || + (element.isVarArgs() && parameters.size() <= numParameters - 1)) { + methods.add(new AnnotationMethod(declaredType, element)); + } + } + } + } + + @Override + public AnnotationClass getSuperclass() { + if (mTypeMirror.getKind() == TypeKind.DECLARED) { + DeclaredType declaredType = (DeclaredType) mTypeMirror; + TypeElement typeElement = (TypeElement) declaredType.asElement(); + TypeMirror superClass = typeElement.getSuperclass(); + if (superClass.getKind() == TypeKind.DECLARED) { + return new AnnotationClass(superClass); + } + } + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AnnotationClass) { + return getTypeUtils().isSameType(mTypeMirror, ((AnnotationClass) obj).mTypeMirror); + } else { + return false; + } + } + + @Override + public int hashCode() { + return mTypeMirror.toString().hashCode(); + } + + private static Types getTypeUtils() { + return AnnotationAnalyzer.instance.processingEnv.getTypeUtils(); + } + + private static Elements getElementUtils() { + return AnnotationAnalyzer.instance.processingEnv.getElementUtils(); + } + + private static TypeMirror getListType() { + return AnnotationAnalyzer.instance.listType; + } + + private static TypeMirror getMapType() { + return AnnotationAnalyzer.instance.mapType; + } + + private static TypeMirror getStringType() { + return AnnotationAnalyzer.instance.stringType; + } + + private static TypeMirror getObjectType() { + return AnnotationAnalyzer.instance.objectType; + } + + private static void printMessage(Diagnostic.Kind kind, String message) { + AnnotationAnalyzer.instance.printMessage(kind, message); + } + + @Override + public String toString() { + return mTypeMirror.toString(); + } +} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationField.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationField.java new file mode 100644 index 0000000..a268853 --- /dev/null +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationField.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.databinding.reflection; + +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; + +public class AnnotationField implements ModelField { + + final VariableElement mField; + + final TypeElement mDeclaredClass; + + public AnnotationField(TypeElement declaredClass, VariableElement field) { + mDeclaredClass = declaredClass; + mField = field; + } + + @Override + public String toString() { + return mField.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AnnotationField) { + AnnotationField that = (AnnotationField) obj; + return mDeclaredClass.equals(that.mDeclaredClass) && AnnotationAnalyzer.instance + .getTypeUtils().isSameType(mField.asType(), that.mField.asType()); + } else { + return false; + } + } +} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationMethod.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationMethod.java new file mode 100644 index 0000000..f98b819 --- /dev/null +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationMethod.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.databinding.reflection; + +import java.util.List; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ExecutableType; +import javax.lang.model.type.TypeMirror; + +public class AnnotationMethod implements ModelMethod { + final ExecutableElement mMethod; + final DeclaredType mDeclaringType; + + public AnnotationMethod(DeclaredType declaringType, ExecutableElement method) { + mDeclaringType = declaringType; + mMethod = method; + } + + @Override + public ModelClass getDeclaringClass() { + return new AnnotationClass(mDeclaringType); + } + + @Override + public ModelClass[] getParameterTypes() { + List<? extends VariableElement> parameters = mMethod.getParameters(); + ModelClass[] parameterTypes = new ModelClass[parameters.size()]; + for (int i = 0; i < parameters.size(); i++) { + parameterTypes[i] = new AnnotationClass(parameters.get(i).asType()); + } + return parameterTypes; + } + + @Override + public String getName() { + return mMethod.getSimpleName().toString(); + } + + @Override + public ModelClass getReturnType(List<ModelClass> args) { + ExecutableType executableType = (ExecutableType) AnnotationAnalyzer.instance.getTypeUtils().asMemberOf(mDeclaringType, mMethod); + TypeMirror returnType = executableType.getReturnType(); + // TODO: support argument-supplied types + // for example: public T[] toArray(T[] arr) + return new AnnotationClass(returnType); + } + + @Override + public boolean isPublic() { + return mMethod.getModifiers().contains(Modifier.PUBLIC); + } + + @Override + public boolean isStatic() { + return mMethod.getModifiers().contains(Modifier.STATIC); + } +} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/Callable.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/Callable.java index 75c1e03..5c39b5c 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/Callable.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/Callable.java @@ -26,13 +26,13 @@ public class Callable { public final String name; - public final ReflectionClass resolvedType; + public final ModelClass resolvedType; public final boolean isDynamic; public final boolean canBeInvalidated; - public Callable(Type type, String name, ReflectionClass resolvedType, boolean isDynamic, + public Callable(Type type, String name, ModelClass resolvedType, boolean isDynamic, boolean canBeInvalidated) { this.type = type; this.name = name; diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassAnalyzer.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassAnalyzer.java deleted file mode 100644 index 1d4438b..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassAnalyzer.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.databinding.reflection; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; - -import com.android.databinding.store.SetterStore; -import com.android.databinding.util.L; - -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ClassAnalyzer extends ReflectionAnalyzer { - - private static final String OBSERVABLE_CLASS_NAME = "android.binding.Observable"; - private static final String OBSERVABLE_LIST_CLASS_NAME = "android.binding.ObservableList"; - private static final String OBSERVABLE_MAP_CLASS_NAME = "android.binding.ObservableMap"; - private static final String BINDABLE_ANNOTATION_NAME = "android.binding.Bindable"; - private static final String[] OBSERVABLE_FIELDS = { - "com.android.databinding.library.ObservableBoolean", - "com.android.databinding.library.ObservableByte", - "com.android.databinding.library.ObservableChar", - "com.android.databinding.library.ObservableShort", - "com.android.databinding.library.ObservableInt", - "com.android.databinding.library.ObservableLong", - "com.android.databinding.library.ObservableFloat", - "com.android.databinding.library.ObservableDouble", - "com.android.databinding.library.ObservableField", - }; - private static final String I_VIEW_DATA_BINDER = "com.android.databinding.library.IViewDataBinder"; - - private static Map<String, String> sTestClassNameMapping = ImmutableMap.of( - OBSERVABLE_CLASS_NAME, "com.android.databinding.MockObservable", - BINDABLE_ANNOTATION_NAME, "com.android.databinding.MockBindable", - OBSERVABLE_LIST_CLASS_NAME, "com.android.databinding.MockObservableLsit", - OBSERVABLE_MAP_CLASS_NAME, "com.android.databinding.MockObservableMap", - I_VIEW_DATA_BINDER, "com.android.databinding.MockIViewDataBinder" - ); - - private static ClassAnalyzer sClassAnalyzer; - - private static ClassLoader sClassLoader; - - private HashMap<String, ClassClass> mClassCache = new HashMap<>(); - - private final ClassLoader mClassLoader; - - private final Class mObservable; - - private final Class mObservableList; - - private final Class mObservableMap; - - private final Class[] mObservableFields; - - private final Class mBindable; - - private final boolean mTestMode; - - private final Class mIViewDataBinder; - - private ClassAnalyzer(ClassLoader classLoader, boolean testMode) { - mClassLoader = classLoader; - mTestMode = testMode; - try { - mIViewDataBinder = classLoader.loadClass(getClassName(I_VIEW_DATA_BINDER)); - mObservable = classLoader.loadClass(getClassName(OBSERVABLE_CLASS_NAME)); - mObservableList = classLoader.loadClass(getClassName(OBSERVABLE_LIST_CLASS_NAME)); - mObservableMap = classLoader.loadClass(getClassName(OBSERVABLE_MAP_CLASS_NAME)); - mBindable = classLoader.loadClass(getClassName(BINDABLE_ANNOTATION_NAME)); - mObservableFields = new Class[OBSERVABLE_FIELDS.length]; - for (int i = 0; i < OBSERVABLE_FIELDS.length; i++) { - mObservableFields[i] = classLoader.loadClass(getClassName(OBSERVABLE_FIELDS[i])); - } - - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - public static void setClassLoader(ClassLoader classLoader) { - if (sClassAnalyzer != null) { - throw new IllegalStateException("class analyzer is already created, you cannot " - + "change class loader after that"); - } - L.d("setting class loader to %s", classLoader); - sClassLoader = classLoader; - } - - public static ClassAnalyzer getInstance() { - if (sClassAnalyzer == null) { - Preconditions.checkNotNull(sClassLoader, - "cannot access class analyzer before class loader is ready"); - sClassAnalyzer = new ClassAnalyzer(sClassLoader, false); - } - return sClassAnalyzer; - } - - private String getClassName(String name) { - if (mTestMode && sTestClassNameMapping.containsKey(name)) { - return sTestClassNameMapping.get(name); - } - return name; - } - - @Override - public boolean isDataBinder(ReflectionClass reflectionClass) { - ClassClass classClass = (ClassClass) reflectionClass; - return mIViewDataBinder.isAssignableFrom(classClass.mClass); - } - - @Override - public Callable findMethod(ReflectionClass reflectionClass, String name, - List<ReflectionClass> argClasses) { - Class klass = ((ClassClass) reflectionClass).mClass; - ArrayList<Class> args = new ArrayList<>(argClasses.size()); - for (int i = 0; i < argClasses.size(); i++) { - args.add(((ClassClass) argClasses.get(i)).mClass); - } - // TODO implement properly - for (String methodName : new String[]{"set" + StringUtils.capitalize(name), name}) { - for (Method method : klass.getMethods()) { - if (methodName.equals(method.getName()) && args.size() == method - .getParameterTypes().length) { - return new Callable(Callable.Type.METHOD, methodName, - new ClassClass(method.getReturnType()), true, false); - } - } - } - L.e(new Exception(), "cannot find method %s in %s", name, klass); - throw new IllegalArgumentException( - "cannot find method " + name + " at class " + klass.getSimpleName()); - } - - @Override - public boolean isObservable(ReflectionClass reflectionClass) { - Class klass = ((ClassClass) reflectionClass).mClass; - return isObservable(klass); - } - - private boolean isObservable(Class klass) { - return mObservable.isAssignableFrom(klass) || mObservableList.isAssignableFrom(klass) || - mObservableMap.isAssignableFrom(klass); - } - - @Override - public boolean isObservableField(ReflectionClass reflectionClass) { - Class klass = ((ClassClass) reflectionClass).mClass; - for (Class observableField : mObservableFields) { - if (observableField.isAssignableFrom(klass)) { - return true; - } - } - return false; - } - - @Override - public boolean isBindable(ReflectionField reflectionField) { - Field field = ((ClassField) reflectionField).mField; - return isBindable(field); - } - - @Override - public boolean isBindable(ReflectionMethod reflectionMethod) { - Method method = ((ClassMethod) reflectionMethod).mMethod; - return isBindable(method); - } - - private boolean isBindable(Field field) { - return field.getAnnotation(mBindable) != null; - } - - private boolean isBindable(Method method) { - return method.getAnnotation(mBindable) != null; - } - - @Override - public Callable findMethodOrField(ReflectionClass reflectionClass, String name) { - Class klass = ((ClassClass) reflectionClass).mClass; - for (String methodName : - new String[]{"get" + StringUtils.capitalize(name), - "is" + StringUtils.capitalize(name), name}) { - try { - Method method = klass.getMethod(methodName); - Field backingField = findField(klass, name, true); - if (Modifier.isPublic(method.getModifiers())) { - final Callable result = new Callable(Callable.Type.METHOD, methodName, - new ClassClass(method.getReturnType()), true, - isBindable(method) || (backingField != null && isBindable(backingField)) ); - L.d("backing field for %s is %s", result, backingField); - return result; - } - } catch (Throwable t) { - - } - } - try { - Field field = findField(klass, name, false); - if (Modifier.isPublic(field.getModifiers())) { - return new Callable(Callable.Type.FIELD, name, new ClassClass(field.getType()), - !Modifier.isFinal(field.getModifiers()) - || isObservable(field.getType()), isBindable(field)); - } - } catch (Throwable t) { - - } - throw new IllegalArgumentException( - "cannot find " + name + " in " + klass.getCanonicalName()); - } - - private Field findField(Class klass, String name, boolean allowNonPublic) { - try { - return getField(klass, name, allowNonPublic); - } catch (NoSuchFieldException e) { - - } - String capitalizedName = StringUtils.capitalize(name); - - try { - return getField(klass, "m" + capitalizedName, allowNonPublic); - } catch (Throwable t){} - try { - return getField(klass, "_" + name, allowNonPublic); - } catch (Throwable t){} - try { - return getField(klass, "_" + capitalizedName, allowNonPublic); - } catch (Throwable t){} - try { - return getField(klass, "m_" + name, allowNonPublic); - } catch (Throwable t){} - try { - return getField(klass, "m_" + capitalizedName, allowNonPublic); - } catch (Throwable t){} - return null; - } - - private Field getField(Class klass, String exactName, boolean allowNonPublic) - throws NoSuchFieldException { - try { - return klass.getField(exactName); - } catch (NoSuchFieldException e) { - if (allowNonPublic) { - return klass.getDeclaredField(exactName); - } else { - throw e; - } - } - } - - public ClassClass loadPrimitive(String className) { - if ("int".equals(className)) { - return new ClassClass(int.class); - } - if ("short".equals(className)) { - return new ClassClass(short.class); - } - if ("long".equals(className)) { - return new ClassClass(long.class); - } - if ("float".equals(className)) { - return new ClassClass(float.class); - } - if ("double".equals(className)) { - return new ClassClass(double.class); - } - if ("boolean".equals(className) || "bool".equals(className)) { - return new ClassClass(boolean.class); - } - return null; - } - - @Override - public ClassClass findClass(String className) { - ClassClass loaded = mClassCache.get(className); - if (loaded != null) { - return loaded; - } - L.d("trying to load class %s from %s", className, mClassLoader.toString()); - loaded = loadPrimitive(className); - if (loaded == null) { - try { - if (className.startsWith("[") && className.contains("L")) { - int indexOfL = className.indexOf('L'); - ClassClass baseClass = findClass( - className.substring(indexOfL + 1, className.length() - 1)); - String realClassName = className.substring(0, indexOfL + 1) + - baseClass.mClass.getCanonicalName() + ';'; - loaded = new ClassClass(Class.forName(realClassName, false, mClassLoader)); - mClassCache.put(className, loaded); - } else { - loaded = loadRecursively(className); - mClassCache.put(className, loaded); - } - - } catch (Throwable t) { - L.e(t, "cannot load class " + className); - } - } - Preconditions.checkNotNull(loaded, "Tried to load " + className + " but could not find :/"); - L.d("loaded class %s", loaded.mClass.getCanonicalName()); - return loaded; - } - - @Override - public ReflectionClass findClass(Class classType) { - return new ClassClass(classType); - } - - private ClassClass loadRecursively(String className) throws ClassNotFoundException { - try { - L.d("recursively checking %s", className); - return new ClassClass(mClassLoader.loadClass(className)); - } catch (ClassNotFoundException ex) { - int lastIndexOfDot = className.lastIndexOf("."); - if (lastIndexOfDot == -1) { - throw ex; - } - return loadRecursively(className.substring(0, lastIndexOfDot) + "$" + className - .substring(lastIndexOfDot + 1)); - } - } - - public static void initForTests() { - if (sClassAnalyzer == null) { - setClassLoader(ClassLoader.getSystemClassLoader()); - sClassAnalyzer = new ClassAnalyzer(sClassLoader, true); - } - } - - @Override - public List<URL> getResources(String name) { - List<URL> urlList = new ArrayList<URL>(); - Enumeration<URL> urls = null; - try { - urls = mClassLoader.getResources(name); - if (urls != null) { - while (urls.hasMoreElements()) { - urlList.add(urls.nextElement()); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return urlList; - } -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassClass.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassClass.java deleted file mode 100644 index 2ffa0e7..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassClass.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import java.lang.reflect.Method; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -public class ClassClass implements ReflectionClass { - - public final Class mClass; - - public ClassClass(Class clazz) { - mClass = clazz; - } - - @Override - public String toJavaCode() { - return toJavaCode(mClass); - } - - private static String toJavaCode(Class aClass) { - if (aClass.isArray()) { - Class component = aClass.getComponentType(); - return toJavaCode(component) + "[]"; - } else { - return aClass.getCanonicalName().replace('$', '.'); - } - } - - @Override - public boolean isArray() { - return mClass.isArray(); - } - - @Override - public ClassClass getComponentType() { - if (mClass.isArray()) { - return new ClassClass(mClass.getComponentType()); - } else if (isList() || isMap()) { - return new ClassClass(Object.class); - } else { - return null; - } - } - - @Override - public boolean isList() { - return List.class.isAssignableFrom(mClass); - } - - @Override - public boolean isMap() { - return Map.class.isAssignableFrom(mClass); - } - - @Override - public boolean isString() { - return String.class.equals(mClass); - } - - @Override - public boolean isNullable() { - return Object.class.isAssignableFrom(mClass); - } - - @Override - public boolean isPrimitive() { - return mClass.isPrimitive(); - } - - @Override - public boolean isBoolean() { - return boolean.class.equals(mClass); - } - - @Override - public boolean isChar() { - return char.class.equals(mClass); - } - - @Override - public boolean isByte() { - return byte.class.equals(mClass); - } - - @Override - public boolean isShort() { - return short.class.equals(mClass); - } - - @Override - public boolean isInt() { - return int.class.equals(mClass); - } - - @Override - public boolean isLong() { - return long.class.equals(mClass); - } - - @Override - public boolean isFloat() { - return float.class.equals(mClass); - } - - @Override - public boolean isDouble() { - return double.class.equals(mClass); - } - - @Override - public boolean isObject() { - return Object.class.equals(mClass); - } - - @Override - public boolean isVoid() { - return void.class.equals(mClass); - } - - @Override - public ClassClass unbox() { - if (mClass.isPrimitive()) { - return this; - } - if (Integer.class.equals(mClass)) { - return new ClassClass(int.class); - } else if (Long.class.equals(mClass)) { - return new ClassClass(long.class); - } else if (Short.class.equals(mClass)) { - return new ClassClass(short.class); - } else if (Byte.class.equals(mClass)) { - return new ClassClass(byte.class); - } else if (Character.class.equals(mClass)) { - return new ClassClass(char.class); - } else if (Double.class.equals(mClass)) { - return new ClassClass(double.class); - } else if (Float.class.equals(mClass)) { - return new ClassClass(float.class); - } else if (Boolean.class.equals(mClass)) { - return new ClassClass(boolean.class); - } else { - // not a boxed type - return this; - } - - } - - @Override - public ReflectionClass box() { - if (!mClass.isPrimitive()) { - return this; - } - if (int.class.equals(mClass)) { - return new ClassClass(Integer.class); - } else if (long.class.equals(mClass)) { - return new ClassClass(Long.class); - } else if (short.class.equals(mClass)) { - return new ClassClass(Short.class); - } else if (byte.class.equals(mClass)) { - return new ClassClass(Byte.class); - } else if (char.class.equals(mClass)) { - return new ClassClass(Character.class); - } else if (double.class.equals(mClass)) { - return new ClassClass(Double.class); - } else if (float.class.equals(mClass)) { - return new ClassClass(Float.class); - } else if (boolean.class.equals(mClass)) { - return new ClassClass(Boolean.class); - } else { - // not a valid type? - return this; - } - } - - @Override - public boolean isAssignableFrom(ReflectionClass that) { - Class thatClass = ((ClassClass) that).mClass; - return mClass.isAssignableFrom(thatClass); - } - - @Override - public ReflectionMethod[] getMethods(String name, int numParameters) { - Method[] methods = mClass.getMethods(); - ArrayList<ReflectionMethod> matching = new ArrayList<>(); - for (Method method : methods) { - if (method.getName().equals(name) && - method.getParameterTypes().length == numParameters) { - matching.add(new ClassMethod(method)); - } - } - return matching.toArray(new ReflectionMethod[matching.size()]); - } - - @Override - public ClassClass getSuperclass() { - return new ClassClass(mClass.getSuperclass()); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ClassClass) { - return mClass.equals(((ClassClass) obj).mClass); - } else { - return false; - } - } - - @Override - public int hashCode() { - return mClass.hashCode(); - } -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassField.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassField.java deleted file mode 100644 index b5ea8f0..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassField.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import java.lang.reflect.Field; - -public class ClassField implements ReflectionField { - - public final Field mField; - - public ClassField(Field field) { - mField = field; - } -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassMethod.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassMethod.java deleted file mode 100644 index 3c7cf0b..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassMethod.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.List; - -public class ClassMethod implements ReflectionMethod { - - public final Method mMethod; - - public ClassMethod(Method method) { - mMethod = method; - } - - - @Override - public ReflectionClass getDeclaringClass() { - return new ClassClass(mMethod.getDeclaringClass()); - } - - @Override - public ReflectionClass[] getParameterTypes() { - Class[] parameterTypes = mMethod.getParameterTypes(); - ReflectionClass[] parameterClasses = new ReflectionClass[parameterTypes.length]; - for (int i = 0; i < parameterTypes.length; i++) { - parameterClasses[i] = new ClassClass(parameterTypes[i]); - } - return parameterClasses; - } - - @Override - public String getName() { - return mMethod.getName(); - } - - @Override - public ReflectionClass getReturnType(List<ReflectionClass> args) { - return new ClassClass(mMethod.getReturnType()); - } - - @Override - public boolean isPublic() { - return Modifier.isPublic(mMethod.getModifiers()); - } - - @Override - public boolean isStatic() { - return Modifier.isStatic(mMethod.getModifiers()); - } -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelAnalyzer.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelAnalyzer.java index f183e97..58c4266 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelAnalyzer.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelAnalyzer.java @@ -15,381 +15,92 @@ */ package com.android.databinding.reflection; -import com.google.common.collect.ImmutableMap; +import com.google.common.base.Preconditions; -import com.android.databinding.util.L; - -import org.apache.commons.lang3.StringUtils; - -import android.binding.Bindable; - -import java.io.IOException; import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; -import java.util.Map; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import javax.tools.Diagnostic; -import javax.tools.FileObject; -import javax.tools.StandardLocation; -public class ModelAnalyzer extends ReflectionAnalyzer { +public abstract class ModelAnalyzer { + private static ModelAnalyzer sAnalyzer; - public static final String LIST_CLASS_NAME = "java.util.List"; + public abstract boolean isDataBinder(ModelClass modelClass); - public static final String MAP_CLASS_NAME = "java.util.Map"; + public abstract Callable findMethod(ModelClass modelClass, String name, + List<ModelClass> args); - public static final String STRING_CLASS_NAME = "java.lang.String"; + public abstract boolean isObservable(ModelClass modelClass); - public static final String OBJECT_CLASS_NAME = "java.lang.Object"; + public abstract boolean isObservableField(ModelClass modelClass); - static ModelAnalyzer instance; - private static final String OBSERVABLE_CLASS_NAME = "android.binding.Observable"; - private static final String OBSERVABLE_LIST_CLASS_NAME = "android.binding.ObservableList"; - private static final String OBSERVABLE_MAP_CLASS_NAME = "android.binding.ObservableMap"; - private static final String[] OBSERVABLE_FIELDS = { - "com.android.databinding.library.ObservableBoolean", - "com.android.databinding.library.ObservableByte", - "com.android.databinding.library.ObservableChar", - "com.android.databinding.library.ObservableShort", - "com.android.databinding.library.ObservableInt", - "com.android.databinding.library.ObservableLong", - "com.android.databinding.library.ObservableFloat", - "com.android.databinding.library.ObservableDouble", - "com.android.databinding.library.ObservableField", - }; - private static final String I_VIEW_DATA_BINDER = "com.android.databinding.library.IViewDataBinder"; - private static final Map<String, TypeKind> PRIMITIVE_TYPES = - new ImmutableMap.Builder<String, TypeKind>() - .put("boolean", TypeKind.BOOLEAN) - .put("byte", TypeKind.BYTE) - .put("short", TypeKind.SHORT) - .put("char", TypeKind.CHAR) - .put("int", TypeKind.INT) - .put("long", TypeKind.LONG) - .put("float", TypeKind.FLOAT) - .put("double", TypeKind.DOUBLE) - .build(); + public abstract boolean isBindable(ModelField field); - public final ProcessingEnvironment processingEnv; - public final TypeMirror listType; - public final TypeMirror mapType; - public final TypeMirror stringType; - public final TypeMirror objectType; + public abstract boolean isBindable(ModelMethod method); - private final ModelClass mObservableType; - private final ModelClass mObservableListType; - private final ModelClass mObservableMapType; - private final ModelClass[] mObservableFieldTypes; - private final ModelClass mIViewDataBinderType; + public abstract Callable findMethodOrField(ModelClass modelClass, String name); - public ModelAnalyzer(ProcessingEnvironment processingEnvironment) { - processingEnv = processingEnvironment; - instance = this; - Types typeUtil = processingEnv.getTypeUtils(); - listType = typeUtil.erasure(findType(LIST_CLASS_NAME).asType()); - mapType = typeUtil.erasure(findType(MAP_CLASS_NAME).asType()); - stringType = typeUtil.erasure(findType(STRING_CLASS_NAME).asType()); - objectType = typeUtil.erasure(findType(OBJECT_CLASS_NAME).asType()); - mObservableType = new ModelClass(findType(OBSERVABLE_CLASS_NAME).asType()); - mObservableListType = new ModelClass(typeUtil.erasure(findType(OBSERVABLE_LIST_CLASS_NAME).asType())); - mObservableMapType = new ModelClass(typeUtil.erasure( - findType(OBSERVABLE_MAP_CLASS_NAME).asType())); - mIViewDataBinderType = new ModelClass(findType(I_VIEW_DATA_BINDER).asType()); - mObservableFieldTypes = new ModelClass[OBSERVABLE_FIELDS.length]; - for (int i = 0; i < OBSERVABLE_FIELDS.length; i++) { - mObservableFieldTypes[i] = new ModelClass(findType(OBSERVABLE_FIELDS[i]).asType()); + public ModelClass findCommonParentOf(ModelClass modelClass1, + ModelClass modelClass2) { + ModelClass curr = modelClass1; + while (curr != null && !curr.isAssignableFrom(modelClass2)) { + curr = curr.getSuperclass(); } - } - - TypeElement findType(String type) { - return processingEnv.getElementUtils().getTypeElement(type); - } - - @Override - public boolean isDataBinder(ReflectionClass reflectionClass) { - return mIViewDataBinderType.isAssignableFrom(reflectionClass); - } - - @Override - public ReflectionClass findCommonParentOf(ReflectionClass reflectionClass1, - ReflectionClass reflectionClass2) { - return super.findCommonParentOf(toModel(reflectionClass1), toModel(reflectionClass2)); - } - - @Override - public Callable findMethod(ReflectionClass reflectionClass, String name, - List<ReflectionClass> args) { - ModelClass clazz = toModel(reflectionClass); - // TODO implement properly - for (String methodName : new String[]{"set" + StringUtils.capitalize(name), name}) { - for (ReflectionMethod method : clazz.getMethods(methodName, args.size())) { - ReflectionClass[] parameters = method.getParameterTypes(); - boolean parametersMatch = true; - boolean isVarArgs = ((ModelMethod)method).mMethod.isVarArgs(); - for (int i = 0; i < parameters.length; i++) { - if (isVarArgs && i == parameters.length - 1) { - ReflectionClass component = parameters[i].getComponentType(); - for (int j = i; j < args.size(); j++) { - if (!component.isAssignableFrom(args.get(j))) { - parametersMatch = false; - break; - } - } - } else if (!parameters[i].isAssignableFrom(args.get(i))) { - parametersMatch = false; - break; - } - } - if (parametersMatch) { - return new Callable(Callable.Type.METHOD, methodName, - method.getReturnType(args), true, false); - } + if (curr == null) { + ModelClass primitive1 = modelClass1.unbox(); + ModelClass primitive2 = modelClass2.unbox(); + if (!modelClass1.equals(primitive1) || !modelClass2.equals(primitive2)) { + return findCommonParentOf(primitive1, primitive2); } } - String message = "cannot find method " + name + " at class " + clazz.toJavaCode(); - printMessage(Diagnostic.Kind.ERROR, message); - throw new IllegalArgumentException(message); - } + Preconditions.checkNotNull(curr, + "must be able to find a common parent for " + modelClass1 + " and " + modelClass2); + return curr; - @Override - public boolean isObservable(ReflectionClass reflectionClass) { - return mObservableType.isAssignableFrom(reflectionClass) || - mObservableListType.isAssignableFrom(reflectionClass) || - mObservableMapType.isAssignableFrom(reflectionClass); } - @Override - public boolean isObservableField(ReflectionClass reflectionClass) { - ModelClass modelClass = toModel(reflectionClass); - ModelClass erasure = new ModelClass(getTypeUtils().erasure(modelClass.mTypeMirror)); - for (ModelClass observableField : mObservableFieldTypes) { - if (observableField.isAssignableFrom(erasure)) { - return true; - } - } - return false; - } + public abstract ModelClass loadPrimitive(String className); - @Override - public boolean isBindable(ReflectionField field) { - VariableElement fieldElement = ((ModelField) field).mField; - return fieldElement.getAnnotation(Bindable.class) != null; + public static ModelAnalyzer getInstance() { + return sAnalyzer; } - @Override - public boolean isBindable(ReflectionMethod method) { - ExecutableElement methodElement = ((ModelMethod) method).mMethod; - return methodElement.getAnnotation(Bindable.class) != null; + public static void setProcessingEnvironment(ProcessingEnvironment processingEnvironment) { + AnnotationAnalyzer annotationAnalyzer = new AnnotationAnalyzer(processingEnvironment); + sAnalyzer = annotationAnalyzer; } - @Override - public Callable findMethodOrField(ReflectionClass reflectionClass, String name) { - ModelClass modelClass = toModel(reflectionClass); - for (String methodName : - new String[]{"get" + StringUtils.capitalize(name), - "is" + StringUtils.capitalize(name), name}) { - ReflectionMethod[] methods = reflectionClass.getMethods(methodName, 0); - for (ReflectionMethod reflectionMethod : methods) { - ModelMethod method = (ModelMethod) reflectionMethod; - if (method.isPublic()) { - final ModelField backingField = findField(modelClass, name, true); - final Callable result = new Callable(Callable.Type.METHOD, methodName, - method.getReturnType(null), true, isBindable(method) || - (backingField != null && isBindable(backingField))); - L.d("backing field for %s is %s", result, backingField); - return result; - } - } + public String getDefaultValue(String className) { + if("int".equals(className)) { + return "0"; } - - ModelField field = findField(modelClass, name, false); - if (field != null && field.mField.getModifiers().contains(Modifier.PUBLIC)) { - ModelClass fieldType = new ModelClass(field.mField.asType()); - return new Callable(Callable.Type.FIELD, name, fieldType, - !field.mField.getModifiers().contains(Modifier.FINAL) - || isObservable(fieldType), isBindable(field)); + if("short".equals(className)) { + return "0"; } - throw new IllegalArgumentException( - "cannot find " + name + " in " + - ((DeclaredType)modelClass.mTypeMirror).asElement().getSimpleName()); - } - - private ModelField findField(ModelClass clazz, String name, boolean allowNonPublic) { - if (clazz == null || clazz.mTypeMirror.getKind() != TypeKind.DECLARED) { - return null; + if("long".equals(className)) { + return "0L"; } - TypeElement typeElement = (TypeElement) ((DeclaredType) clazz.mTypeMirror).asElement(); - for (VariableElement field : ElementFilter.fieldsIn( - getElementUtils().getAllMembers(typeElement))) { - if (name.equals(stripFieldName(field.getSimpleName().toString()))) { - if (allowNonPublic || field.getModifiers().contains(Modifier.PUBLIC)) { - return new ModelField(typeElement, field); - } - } + if("float".equals(className)) { + return "0f"; } - return null; // nothing found - } - - @Override - public ModelClass loadPrimitive(String className) { - TypeKind typeKind = PRIMITIVE_TYPES.get(className); - if (typeKind == null) { - return null; - } else { - Types typeUtils = getTypeUtils(); - return new ModelClass(typeUtils.getPrimitiveType(typeKind)); + if("double".equals(className)) { + return "0.0"; } - } - - private static String stripFieldName(String fieldName) { - if (fieldName.length() > 2) { - final char start = fieldName.charAt(2); - if (fieldName.startsWith("m_") && Character.isJavaIdentifierStart(start)) { - return Character.toLowerCase(start) + fieldName.substring(3); - } + if("boolean".equals(className)) { + return "false"; } - if (fieldName.length() > 1) { - final char start = fieldName.charAt(1); - final char fieldIdentifier = fieldName.charAt(0); - final boolean strip; - if (fieldIdentifier == '_') { - strip = true; - } else if (fieldIdentifier == 'm' && Character.isJavaIdentifierStart(start) && - !Character.isLowerCase(start)) { - strip = true; - } else { - strip = false; // not mUppercase format - } - if (strip) { - return Character.toLowerCase(start) + fieldName.substring(2); - } + if ("char".equals(className)) { + return "'\\u0000'"; } - return fieldName; - } - - @Override - public ModelClass findClass(String className) { - className = className.trim(); - int numDimensions = 0; - while (className.endsWith("[]")) { - numDimensions++; - className = className.substring(0, className.length() - 2); - } - ModelClass primitive = loadPrimitive(className); - if (primitive != null) { - return addDimension(primitive.mTypeMirror, numDimensions); - } - int templateOpenIndex = className.indexOf('<'); - DeclaredType declaredType; - if (templateOpenIndex < 0) { - Elements elementUtils = getElementUtils(); - TypeElement typeElement = elementUtils.getTypeElement(className); - declaredType = (DeclaredType) typeElement.asType(); - } else { - int templateCloseIndex = className.lastIndexOf('>'); - String paramStr = className.substring(templateOpenIndex + 1, templateCloseIndex - 1); - - Elements elementUtils = getElementUtils(); - String baseClassName = className.substring(0, templateOpenIndex); - TypeElement typeElement = elementUtils.getTypeElement(baseClassName); - - ArrayList<String> templateParameters = splitTemplateParameters(paramStr); - TypeMirror[] typeArgs = new TypeMirror[templateParameters.size()]; - for (int i = 0; i < typeArgs.length; i++) { - typeArgs[i] = findClass(templateParameters.get(i)).mTypeMirror; - } - - Types typeUtils = getTypeUtils(); - declaredType = typeUtils.getDeclaredType(typeElement, typeArgs); + if ("byte".equals(className)) { + return "0"; } - return addDimension(declaredType, numDimensions); + return "null"; } - private ModelClass addDimension(TypeMirror type, int numDimensions) { - while (numDimensions > 0) { - type = getTypeUtils().getArrayType(type); - numDimensions--; - } - return new ModelClass(type); - } + public abstract ModelClass findClass(String className); - private ArrayList<String> splitTemplateParameters(String templateParameters) { - ArrayList<String> list = new ArrayList<>(); - int index = 0; - int openCount = 0; - StringBuilder arg = new StringBuilder(); - while (index < templateParameters.length()) { - char c = templateParameters.charAt(index); - if (c == ',' && openCount == 0) { - list.add(arg.toString()); - arg.delete(0, arg.length()); - } else if (!Character.isWhitespace(c)) { - arg.append(c); - if (c == '<') { - openCount++; - } else if (c == '>') { - openCount--; - } - } - } - list.add(arg.toString()); - return list; - } + public abstract List<URL> getResources(String name); - @Override - public List<URL> getResources(String name) { - ArrayList<URL> urls = new ArrayList<>(); - try { - Enumeration<URL> resources = getClass().getClassLoader().getResources(name); - while (resources.hasMoreElements()) { - urls.add(resources.nextElement()); - } - } catch (IOException e) { - printMessage(Diagnostic.Kind.ERROR, "IOException while getting resources: " + - e.getLocalizedMessage()); - } - - return urls; - } - - @Override - public ReflectionClass findClass(Class classType) { - return new ClassClass(classType); - } - - public Types getTypeUtils() { - return processingEnv.getTypeUtils(); - } - - public Elements getElementUtils() { - return processingEnv.getElementUtils(); - } - - public void printMessage(Diagnostic.Kind kind, String message) { - processingEnv.getMessager().printMessage(kind, message); - } - - public ModelClass toModel(ReflectionClass reflectionClass) { - if (reflectionClass instanceof ClassClass) { - String name = ((ClassClass) reflectionClass).mClass.getCanonicalName(); - return findClass(name); - } else { - return (ModelClass) reflectionClass; - } - } + public abstract ModelClass findClass(Class classType); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelClass.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelClass.java index 6450624..6e5f41b 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelClass.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelClass.java @@ -15,305 +15,51 @@ */ package com.android.databinding.reflection; -import java.util.ArrayList; -import java.util.List; +public interface ModelClass { -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.PrimitiveType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import javax.tools.Diagnostic; + String toJavaCode(); -public class ModelClass implements ReflectionClass { + boolean isArray(); - final TypeMirror mTypeMirror; + ModelClass getComponentType(); - public ModelClass(TypeMirror typeMirror) { - mTypeMirror = typeMirror; - } + boolean isList(); - @Override - public String toJavaCode() { - return toJavaCode(mTypeMirror); - } + boolean isMap(); - private static String toJavaCode(TypeMirror typeElement) { - return typeElement.toString(); - } + boolean isString(); - @Override - public boolean isArray() { - return mTypeMirror.getKind() == TypeKind.ARRAY; - } + boolean isNullable(); - @Override - public ModelClass getComponentType() { - TypeMirror component; - if (isArray()) { - component = ((ArrayType) mTypeMirror).getComponentType(); - } else if (isList()) { - DeclaredType listType = findInterface(getListType()); - if (listType == null) { - return null; - } - component = listType.getTypeArguments().get(0); - } else { - DeclaredType mapType = findInterface(getMapType()); - if (mapType == null) { - return null; - } - component = mapType.getTypeArguments().get(1); - } + boolean isPrimitive(); - return new ModelClass(component); - } + boolean isBoolean(); - private DeclaredType findInterface(TypeMirror interfaceType) { - Types typeUtil = getTypeUtils(); - TypeMirror foundInterface = null; - if (typeUtil.isSameType(interfaceType, typeUtil.erasure(mTypeMirror))) { - foundInterface = mTypeMirror; - } else if (mTypeMirror.getKind() == TypeKind.DECLARED) { - DeclaredType declaredType = (DeclaredType) mTypeMirror; - TypeElement typeElement = (TypeElement) declaredType.asElement(); - for (TypeMirror type : typeElement.getInterfaces()) { - if (typeUtil.isSameType(interfaceType, typeUtil.erasure(type))) { - foundInterface = type; - break; - } - } - if (foundInterface == null) { - printMessage(Diagnostic.Kind.ERROR, - "Detected " + interfaceType + " type for " + mTypeMirror + - ", but not able to find the implemented interface."); - return null; - } - } - if (foundInterface.getKind() != TypeKind.DECLARED) { - printMessage(Diagnostic.Kind.ERROR, - "Found " + interfaceType + " type for " + mTypeMirror + - ", but it isn't a declared type: " + foundInterface); - return null; - } - return (DeclaredType) foundInterface; - } + boolean isChar(); - @Override - public boolean isList() { - ModelAnalyzer analyzer = ModelAnalyzer.instance; - Types typeUtil = getTypeUtils(); - return typeUtil.isAssignable(typeUtil.erasure(mTypeMirror), getListType()); - } + boolean isByte(); - @Override - public boolean isMap() { - ModelAnalyzer analyzer = ModelAnalyzer.instance; - Types typeUtil = getTypeUtils(); - return typeUtil.isAssignable(typeUtil.erasure(mTypeMirror), getMapType()); - } + boolean isShort(); - @Override - public boolean isString() { - return getTypeUtils().isSameType(mTypeMirror, getStringType()); - } + boolean isInt(); - @Override - public boolean isNullable() { - switch (mTypeMirror.getKind()) { - case ARRAY: - case DECLARED: - case NULL: - return true; - default: - return false; - } - } + boolean isLong(); - @Override - public boolean isPrimitive() { - switch (mTypeMirror.getKind()) { - case BOOLEAN: - case BYTE: - case SHORT: - case INT: - case LONG: - case CHAR: - case FLOAT: - case DOUBLE: - return true; - default: - return false; - } - } + boolean isFloat(); - @Override - public boolean isBoolean() { - return mTypeMirror.getKind() == TypeKind.BOOLEAN; - } + boolean isDouble(); - @Override - public boolean isChar() { - return mTypeMirror.getKind() == TypeKind.CHAR; - } + boolean isObject(); - @Override - public boolean isByte() { - return mTypeMirror.getKind() == TypeKind.BYTE; - } + boolean isVoid(); - @Override - public boolean isShort() { - return mTypeMirror.getKind() == TypeKind.SHORT; - } + ModelClass unbox(); - @Override - public boolean isInt() { - return mTypeMirror.getKind() == TypeKind.INT; - } + ModelClass box(); - @Override - public boolean isLong() { - return mTypeMirror.getKind() == TypeKind.LONG; - } + boolean isAssignableFrom(ModelClass that); - @Override - public boolean isFloat() { - return mTypeMirror.getKind() == TypeKind.FLOAT; - } + ModelMethod[] getMethods(String name, int numParameters); - @Override - public boolean isDouble() { - return mTypeMirror.getKind() == TypeKind.DOUBLE; - } - - @Override - public boolean isObject() { - return getTypeUtils().isSameType(mTypeMirror, getObjectType()); - } - - @Override - public boolean isVoid() { - return mTypeMirror.getKind() == TypeKind.VOID; - } - - @Override - public ModelClass unbox() { - if (!isNullable()) { - return this; - } - try { - return new ModelClass(getTypeUtils().unboxedType(mTypeMirror)); - } catch (IllegalArgumentException e) { - // I'm being lazy. This is much easier than checking every type. - return this; - } - } - - @Override - public ReflectionClass box() { - if (!isPrimitive()) { - return this; - } - return new ModelClass(getTypeUtils().boxedClass((PrimitiveType) mTypeMirror).asType()); - } - - @Override - public boolean isAssignableFrom(ReflectionClass that) { - TypeMirror thatType = ModelAnalyzer.instance.toModel(that).mTypeMirror; - return getTypeUtils().isAssignable(thatType, mTypeMirror); - } - - @Override - public ReflectionMethod[] getMethods(String name, int numParameters) { - ArrayList<ModelMethod> matching = new ArrayList<>(); - if (mTypeMirror.getKind() == TypeKind.DECLARED) { - DeclaredType declaredType = (DeclaredType) mTypeMirror; - getMethods(declaredType, matching, name, numParameters); - } - return matching.toArray(new ReflectionMethod[matching.size()]); - } - - private static void getMethods(DeclaredType declaredType, ArrayList<ModelMethod> methods, - String name, int numParameters) { - Elements elementUtils = getElementUtils(); - for (ExecutableElement element : - ElementFilter.methodsIn(elementUtils.getAllMembers((TypeElement)declaredType.asElement()))) { - if (element.getSimpleName().toString().equals(name)) { - List<? extends VariableElement> parameters = element.getParameters(); - if (parameters.size() == numParameters || - (element.isVarArgs() && parameters.size() <= numParameters - 1)) { - methods.add(new ModelMethod(declaredType, element)); - } - } - } - } - - @Override - public ModelClass getSuperclass() { - if (mTypeMirror.getKind() == TypeKind.DECLARED) { - DeclaredType declaredType = (DeclaredType) mTypeMirror; - TypeElement typeElement = (TypeElement) declaredType.asElement(); - TypeMirror superClass = typeElement.getSuperclass(); - if (superClass.getKind() == TypeKind.DECLARED) { - return new ModelClass(superClass); - } - } - return null; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ModelClass) { - return getTypeUtils().isSameType(mTypeMirror, ((ModelClass) obj).mTypeMirror); - } else { - return false; - } - } - - @Override - public int hashCode() { - return mTypeMirror.toString().hashCode(); - } - - private static Types getTypeUtils() { - return ModelAnalyzer.instance.processingEnv.getTypeUtils(); - } - - private static Elements getElementUtils() { - return ModelAnalyzer.instance.processingEnv.getElementUtils(); - } - - private static TypeMirror getListType() { - return ModelAnalyzer.instance.listType; - } - - private static TypeMirror getMapType() { - return ModelAnalyzer.instance.mapType; - } - - private static TypeMirror getStringType() { - return ModelAnalyzer.instance.stringType; - } - - private static TypeMirror getObjectType() { - return ModelAnalyzer.instance.objectType; - } - - private static void printMessage(Diagnostic.Kind kind, String message) { - ModelAnalyzer.instance.printMessage(kind, message); - } - - @Override - public String toString() { - return mTypeMirror.toString(); - } + ModelClass getSuperclass(); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelField.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelField.java index f854613..b554c3c 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelField.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelField.java @@ -15,33 +15,5 @@ */ package com.android.databinding.reflection; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; - -public class ModelField implements ReflectionField { - - final VariableElement mField; - - final TypeElement mDeclaredClass; - - public ModelField(TypeElement declaredClass, VariableElement field) { - mDeclaredClass = declaredClass; - mField = field; - } - - @Override - public String toString() { - return mField.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ModelField) { - ModelField that = (ModelField) obj; - return mDeclaredClass.equals(that.mDeclaredClass) && ModelAnalyzer.instance - .getTypeUtils().isSameType(mField.asType(), that.mField.asType()); - } else { - return false; - } - } +public interface ModelField { } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelMethod.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelMethod.java index dac30cf..822f598 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelMethod.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelMethod.java @@ -17,62 +17,16 @@ package com.android.databinding.reflection; import java.util.List; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.TypeParameterElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.ExecutableType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; +public interface ModelMethod { + ModelClass getDeclaringClass(); -public class ModelMethod implements ReflectionMethod { - final ExecutableElement mMethod; - final DeclaredType mDeclaringType; + ModelClass[] getParameterTypes(); - public ModelMethod(DeclaredType declaringType, ExecutableElement method) { - mDeclaringType = declaringType; - mMethod = method; - } + String getName(); - @Override - public ReflectionClass getDeclaringClass() { - return new ModelClass(mDeclaringType); - } + ModelClass getReturnType(List<ModelClass> args); - @Override - public ReflectionClass[] getParameterTypes() { - List<? extends VariableElement> parameters = mMethod.getParameters(); - ReflectionClass[] parameterTypes = new ReflectionClass[parameters.size()]; - for (int i = 0; i < parameters.size(); i++) { - parameterTypes[i] = new ModelClass(parameters.get(i).asType()); - } - return parameterTypes; - } + boolean isPublic(); - @Override - public String getName() { - return mMethod.getSimpleName().toString(); - } - - @Override - public ReflectionClass getReturnType(List<ReflectionClass> args) { - ExecutableType executableType = (ExecutableType) ModelAnalyzer.instance.getTypeUtils().asMemberOf(mDeclaringType, mMethod); - TypeMirror returnType = executableType.getReturnType(); - // TODO: support argument-supplied types - // for example: public T[] toArray(T[] arr) - return new ModelClass(returnType); - } - - @Override - public boolean isPublic() { - return mMethod.getModifiers().contains(Modifier.PUBLIC); - } - - @Override - public boolean isStatic() { - return mMethod.getModifiers().contains(Modifier.STATIC); - } + boolean isStatic(); } diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionAnalyzer.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionAnalyzer.java deleted file mode 100644 index d78c0ad..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionAnalyzer.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import com.google.common.base.Preconditions; - -import java.net.URL; -import java.util.List; - -import javax.annotation.processing.ProcessingEnvironment; - -public abstract class ReflectionAnalyzer { - private static ReflectionAnalyzer sAnalyzer; - - public abstract boolean isDataBinder(ReflectionClass reflectionClass); - - public abstract Callable findMethod(ReflectionClass reflectionClass, String name, - List<ReflectionClass> args); - - public abstract boolean isObservable(ReflectionClass reflectionClass); - - public abstract boolean isObservableField(ReflectionClass reflectionClass); - - public abstract boolean isBindable(ReflectionField field); - - public abstract boolean isBindable(ReflectionMethod method); - - public abstract Callable findMethodOrField(ReflectionClass reflectionClass, String name); - - public ReflectionClass findCommonParentOf(ReflectionClass reflectionClass1, - ReflectionClass reflectionClass2) { - ReflectionClass curr = reflectionClass1; - while (curr != null && !curr.isAssignableFrom(reflectionClass2)) { - curr = curr.getSuperclass(); - } - if (curr == null) { - ReflectionClass primitive1 = reflectionClass1.unbox(); - ReflectionClass primitive2 = reflectionClass2.unbox(); - if (!reflectionClass1.equals(primitive1) || !reflectionClass2.equals(primitive2)) { - return findCommonParentOf(primitive1, primitive2); - } - } - Preconditions.checkNotNull(curr, - "must be able to find a common parent for " + reflectionClass1 + " and " + reflectionClass2); - return curr; - - } - - public abstract ReflectionClass loadPrimitive(String className); - - public static ReflectionAnalyzer getInstance() { - return sAnalyzer; - } - - public static void setClassLoader(ClassLoader classLoader) { - ClassAnalyzer.setClassLoader(classLoader); - sAnalyzer = ClassAnalyzer.getInstance(); - } - - public static void setProcessingEnvironment(ProcessingEnvironment processingEnvironment) { - ModelAnalyzer modelAnalyzer = new ModelAnalyzer(processingEnvironment); - sAnalyzer = modelAnalyzer; - } - - public String getDefaultValue(String className) { - if("int".equals(className)) { - return "0"; - } - if("short".equals(className)) { - return "0"; - } - if("long".equals(className)) { - return "0L"; - } - if("float".equals(className)) { - return "0f"; - } - if("double".equals(className)) { - return "0.0"; - } - if("boolean".equals(className)) { - return "false"; - } - if ("char".equals(className)) { - return "'\\u0000'"; - } - if ("byte".equals(className)) { - return "0"; - } - return "null"; - } - - public abstract ReflectionClass findClass(String className); - - public abstract List<URL> getResources(String name); - - public abstract ReflectionClass findClass(Class classType); -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionClass.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionClass.java deleted file mode 100644 index ef13ab2..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionClass.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import java.net.URL; -import java.util.List; - -public interface ReflectionClass { - - String toJavaCode(); - - boolean isArray(); - - ReflectionClass getComponentType(); - - boolean isList(); - - boolean isMap(); - - boolean isString(); - - boolean isNullable(); - - boolean isPrimitive(); - - boolean isBoolean(); - - boolean isChar(); - - boolean isByte(); - - boolean isShort(); - - boolean isInt(); - - boolean isLong(); - - boolean isFloat(); - - boolean isDouble(); - - boolean isObject(); - - boolean isVoid(); - - ReflectionClass unbox(); - - ReflectionClass box(); - - boolean isAssignableFrom(ReflectionClass that); - - ReflectionMethod[] getMethods(String name, int numParameters); - - ReflectionClass getSuperclass(); -}
\ No newline at end of file diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionField.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionField.java deleted file mode 100644 index b4f6bc5..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionField.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -public interface ReflectionField { -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionMethod.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionMethod.java deleted file mode 100644 index 9940a3c..0000000 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionMethod.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.databinding.reflection; - -import java.util.List; - -public interface ReflectionMethod { - ReflectionClass getDeclaringClass(); - - ReflectionClass[] getParameterTypes(); - - String getName(); - - ReflectionClass getReturnType(List<ReflectionClass> args); - - boolean isPublic(); - - boolean isStatic(); -} diff --git a/tools/data-binding/compiler/src/main/java/com/android/databinding/store/SetterStore.java b/tools/data-binding/compiler/src/main/java/com/android/databinding/store/SetterStore.java index caa8c80..d95d512 100644 --- a/tools/data-binding/compiler/src/main/java/com/android/databinding/store/SetterStore.java +++ b/tools/data-binding/compiler/src/main/java/com/android/databinding/store/SetterStore.java @@ -15,9 +15,9 @@ */ package com.android.databinding.store; -import com.android.databinding.reflection.ReflectionAnalyzer; -import com.android.databinding.reflection.ReflectionClass; -import com.android.databinding.reflection.ReflectionMethod; +import com.android.databinding.reflection.ModelAnalyzer; +import com.android.databinding.reflection.ModelClass; +import com.android.databinding.reflection.ModelMethod; import java.io.File; import java.io.IOException; @@ -27,7 +27,6 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.URL; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -53,10 +52,10 @@ public class SetterStore { private static SetterStore sStore; private final IntermediateV1 mStore; - private final ReflectionAnalyzer mClassAnalyzer; + private final ModelAnalyzer mClassAnalyzer; - private SetterStore(ReflectionAnalyzer reflectionAnalyzer, IntermediateV1 store) { - mClassAnalyzer = reflectionAnalyzer; + private SetterStore(ModelAnalyzer modelAnalyzer, IntermediateV1 store) { + mClassAnalyzer = modelAnalyzer; mStore = store; } @@ -93,22 +92,22 @@ public class SetterStore { return sStore; } - public static SetterStore get(ReflectionAnalyzer reflectionAnalyzer) { + public static SetterStore get(ModelAnalyzer modelAnalyzer) { if (sStore == null) { - sStore = load(reflectionAnalyzer); + sStore = load(modelAnalyzer); } return sStore; } - private static SetterStore load(ReflectionAnalyzer reflectionAnalyzer) { + private static SetterStore load(ModelAnalyzer modelAnalyzer) { IntermediateV1 store = new IntermediateV1(); String resourceName = SetterStore.class.getPackage().getName().replace('.', '/') + '/' + SETTER_STORE_FILE_NAME; try { - for (URL resource : reflectionAnalyzer.getResources(resourceName)) { + for (URL resource : modelAnalyzer.getResources(resourceName)) { merge(store, resource); } - return new SetterStore(reflectionAnalyzer, store); + return new SetterStore(modelAnalyzer, store); } catch (IOException e) { System.err.println("Could not read SetterStore intermediate file: " + e.getLocalizedMessage()); @@ -118,7 +117,7 @@ public class SetterStore { e.getLocalizedMessage()); e.printStackTrace(); } - return new SetterStore(reflectionAnalyzer, store); + return new SetterStore(modelAnalyzer, store); } private static SetterStore load(InputStream inputStream) @@ -255,8 +254,8 @@ public class SetterStore { } } - public String getSetterCall(String attribute, ReflectionClass viewType, - ReflectionClass valueType, String viewExpression, String valueExpression) { + public String getSetterCall(String attribute, ModelClass viewType, + ModelClass valueType, String viewExpression, String valueExpression) { if (!attribute.startsWith("android:")) { int colon = attribute.indexOf(':'); if (colon >= 0) { @@ -266,9 +265,9 @@ public class SetterStore { HashMap<AccessorKey, MethodDescription> adapters = mStore.adapterMethods.get(attribute); MethodDescription adapter = null; String setterName = null; - ReflectionMethod bestSetterMethod = getBestSetter(viewType, valueType, attribute); - ReflectionClass bestViewType = null; - ReflectionClass bestValueType = null; + ModelMethod bestSetterMethod = getBestSetter(viewType, valueType, attribute); + ModelClass bestViewType = null; + ModelClass bestValueType = null; if (bestSetterMethod != null) { bestViewType = bestSetterMethod.getDeclaringClass(); bestValueType = bestSetterMethod.getParameterTypes()[0]; @@ -278,10 +277,10 @@ public class SetterStore { if (adapters != null) { for (AccessorKey key : adapters.keySet()) { try { - ReflectionClass adapterViewType = mClassAnalyzer.findClass(key.viewType); + ModelClass adapterViewType = mClassAnalyzer.findClass(key.viewType); if (adapterViewType.isAssignableFrom(viewType)) { try { - ReflectionClass adapterValueType = mClassAnalyzer.findClass(key.valueType); + ModelClass adapterValueType = mClassAnalyzer.findClass(key.valueType); boolean isBetterView = bestViewType == null || bestValueType.isAssignableFrom(adapterValueType); if (isBetterParameter(valueType, adapterValueType, bestValueType, @@ -317,7 +316,7 @@ public class SetterStore { } } - private ReflectionMethod getBestSetter(ReflectionClass viewType, ReflectionClass argumentType, + private ModelMethod getBestSetter(ModelClass viewType, ModelClass argumentType, String attribute) { String setterName = null; @@ -325,7 +324,7 @@ public class SetterStore { if (renamed != null) { for (String className : renamed.keySet()) { try { - ReflectionClass renamedViewType = mClassAnalyzer.findClass(className); + ModelClass renamedViewType = mClassAnalyzer.findClass(className); if (renamedViewType.isAssignableFrom(viewType)) { setterName = renamed.get(className).method; break; @@ -338,16 +337,16 @@ public class SetterStore { if (setterName == null) { setterName = getDefaultSetter(attribute); } - ReflectionMethod[] methods = viewType.getMethods(setterName, 1); + ModelMethod[] methods = viewType.getMethods(setterName, 1); - ReflectionClass bestParameterType = null; - ReflectionMethod bestMethod = null; - List<ReflectionClass> args = new ArrayList<>(); + ModelClass bestParameterType = null; + ModelMethod bestMethod = null; + List<ModelClass> args = new ArrayList<>(); args.add(argumentType); - for (ReflectionMethod method : methods) { - ReflectionClass[] parameterTypes = method.getParameterTypes(); + for (ModelMethod method : methods) { + ModelClass[] parameterTypes = method.getParameterTypes(); if (method.getReturnType(args).isVoid() && !method.isStatic() && method.isPublic()) { - ReflectionClass param = parameterTypes[0]; + ModelClass param = parameterTypes[0]; if (isBetterParameter(argumentType, param, bestParameterType, true)) { bestParameterType = param; bestMethod = method; @@ -365,8 +364,8 @@ public class SetterStore { return "set" + propertyName; } - private boolean isBetterParameter(ReflectionClass argument, ReflectionClass parameter, - ReflectionClass oldParameter, boolean isBetterViewTypeMatch) { + private boolean isBetterParameter(ModelClass argument, ModelClass parameter, + ModelClass oldParameter, boolean isBetterViewTypeMatch) { // Right view type. Check the value if (!isBetterViewTypeMatch && oldParameter.equals(argument)) { return false; @@ -406,7 +405,7 @@ public class SetterStore { } } - private static boolean isImplicitConversion(ReflectionClass from, ReflectionClass to) { + private static boolean isImplicitConversion(ModelClass from, ModelClass to) { if (from != null && to != null && from.isPrimitive() && to.isPrimitive()) { if (from.isBoolean() || to.isBoolean() || to.isChar()) { return false; @@ -419,17 +418,17 @@ public class SetterStore { } } - private MethodDescription getConversionMethod(ReflectionClass from, ReflectionClass to) { + private MethodDescription getConversionMethod(ModelClass from, ModelClass to) { if (from != null && to != null) { for (String fromClassName : mStore.conversionMethods.keySet()) { try { - ReflectionClass convertFrom = mClassAnalyzer.findClass(fromClassName); + ModelClass convertFrom = mClassAnalyzer.findClass(fromClassName); if (canUseForConversion(from, convertFrom)) { HashMap<String, MethodDescription> conversion = mStore.conversionMethods.get(fromClassName); for (String toClassName : conversion.keySet()) { try { - ReflectionClass convertTo = mClassAnalyzer.findClass(toClassName); + ModelClass convertTo = mClassAnalyzer.findClass(toClassName); if (canUseForConversion(convertTo, to)) { return conversion.get(toClassName); } @@ -446,11 +445,11 @@ public class SetterStore { return null; } - private boolean canUseForConversion(ReflectionClass from, ReflectionClass to) { + private boolean canUseForConversion(ModelClass from, ModelClass to) { return from.equals(to) || isBoxingConversion(from, to) || to.isAssignableFrom(from); } - private static int getConversionLevel(ReflectionClass primitive) { + private static int getConversionLevel(ModelClass primitive) { if (primitive == null) { return -1; } else if (primitive.isByte()) { @@ -472,7 +471,7 @@ public class SetterStore { } } - public static boolean isBoxingConversion(ReflectionClass class1, ReflectionClass class2) { + public static boolean isBoxingConversion(ModelClass class1, ModelClass class2) { if (class1.isPrimitive() != class2.isPrimitive()) { return (class1.box().equals(class2.box())); } else { diff --git a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/ext/ext.kt b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/ext/ext.kt index f870ca4..b7abeb7 100644 --- a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/ext/ext.kt +++ b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/ext/ext.kt @@ -17,9 +17,9 @@ import kotlin.properties.ReadOnlyProperty import kotlin.properties.Delegates import com.android.databinding.ext.joinToCamelCase import com.android.databinding.ext.joinToCamelCaseAsVar -import com.android.databinding.reflection.ReflectionAnalyzer -import com.android.databinding.reflection.ReflectionClass -import com.android.databinding.reflection.ReflectionAnalyzer +import com.android.databinding.reflection.ModelAnalyzer +import com.android.databinding.reflection.ModelClass +import com.android.databinding.reflection.ModelAnalyzer private class LazyExt<K, T>(private val initializer: (k : K) -> T) : ReadOnlyProperty<K, T> { private val mapping = hashMapOf<K, T>() diff --git a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt index d5f98ad..709ec71 100644 --- a/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt +++ b/tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt @@ -15,7 +15,7 @@ package com.android.databinding.writer import com.android.databinding.LayoutBinder import com.android.databinding.expr.Expr -import com.android.databinding.reflection.ReflectionAnalyzer +import com.android.databinding.reflection.ModelAnalyzer import kotlin.properties.Delegates import com.android.databinding.ext.joinToCamelCaseAsVar import com.android.databinding.BindingTarget diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java index fa1e111..c8ea898 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java @@ -26,7 +26,7 @@ import com.android.databinding.expr.MethodCallExpr; import com.android.databinding.expr.SymbolExpr; import com.android.databinding.expr.TernaryExpr; import com.android.databinding.reflection.Callable; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import org.junit.Before; import org.junit.Test; @@ -43,7 +43,7 @@ public class ExpressionVisitorTest { @Before public void setUp() throws Exception { - ReflectionAnalyzer.initForTests(); + ModelAnalyzer.initForTests(); } private <T extends Expr> T parse(String input, Class<T> klass) { @@ -69,7 +69,7 @@ public class ExpressionVisitorTest { @Before public void setUp() throws Exception { - ReflectionAnalyzer.initForTests(); + ModelAnalyzer.initForTests(); } @Parameterized.Parameters diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java index 8859d36..6f33206 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java @@ -20,7 +20,7 @@ import com.android.databinding.expr.FieldAccessExpr; import com.android.databinding.expr.IdentifierExpr; import com.android.databinding.expr.StaticIdentifierExpr; import com.android.databinding.reflection.Callable; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import org.junit.Before; import org.junit.Test; @@ -35,7 +35,7 @@ public class LayoutBinderTest { ExprModel mExprModel; @Before public void setUp() throws Exception { - ReflectionAnalyzer.initForTests(); + ModelAnalyzer.initForTests(); mLayoutBinder = new LayoutBinder(null); mExprModel = mLayoutBinder.getModel(); } diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprModelTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprModelTest.java index f2b2236..5fb3802 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprModelTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprModelTest.java @@ -19,7 +19,7 @@ package com.android.databinding.expr; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import com.android.databinding.LayoutBinder; import com.android.databinding.util.L; @@ -45,7 +45,7 @@ public class ExprModelTest { } @Override - protected Class resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected Class resolveType(ModelAnalyzer modelAnalyzer) { return Integer.class; } @@ -77,7 +77,7 @@ public class ExprModelTest { @Before public void setUp() throws Exception { - ReflectionAnalyzer.initForTests(); + ModelAnalyzer.initForTests(); mExprModel = new ExprModel(); } diff --git a/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprTest.java b/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprTest.java index fd6daf8..32a8ef4 100644 --- a/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprTest.java +++ b/tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprTest.java @@ -16,7 +16,7 @@ package com.android.databinding.expr; -import com.android.databinding.reflection.ReflectionAnalyzer; +import com.android.databinding.reflection.ModelAnalyzer; import org.junit.Before; import org.junit.Test; @@ -37,7 +37,7 @@ public class ExprTest{ } @Override - protected Class resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected Class resolveType(ModelAnalyzer modelAnalyzer) { return Integer.class; } @@ -59,14 +59,14 @@ public class ExprTest{ @Before public void setUp() throws Exception { - ReflectionAnalyzer.initForTests(); + ModelAnalyzer.initForTests(); } @Test(expected=IllegalStateException.class) public void testBadExpr() { Expr expr = new Expr() { @Override - protected Class resolveType(ReflectionAnalyzer reflectionAnalyzer) { + protected Class resolveType(ModelAnalyzer modelAnalyzer) { return Integer.class; } diff --git a/tools/data-binding/gradlePlugin/src/main/kotlin/plugin.kt b/tools/data-binding/gradlePlugin/src/main/kotlin/plugin.kt index a05541f..e423eed 100644 --- a/tools/data-binding/gradlePlugin/src/main/kotlin/plugin.kt +++ b/tools/data-binding/gradlePlugin/src/main/kotlin/plugin.kt @@ -43,7 +43,7 @@ import javax.tools.JavaCompiler import javax.tools.ToolProvider import java.util.Arrays import org.apache.commons.io.FileUtils -import com.android.databinding.reflection.ReflectionAnalyzer +import com.android.databinding.reflection.ModelAnalyzer import com.android.databinding.writer.JavaFileWriter import java.io.FileInputStream import java.io.FileOutputStream @@ -202,11 +202,6 @@ class DataBinderPlugin : Plugin<Project> { val cpFiles = arrayListOf<File>() cpFiles.addAll(dexTask.getInputFiles()) cpFiles.addAll(jCompileTask.getClasspath().getFiles()) - val urls = cpFiles.map { it.toURI().toURL() }.copyToArray() - log("generated urls: ${urls} len: ${urls.size}") - val classLoader = URLClassLoader(urls, androidClassLoader) - log("created class loader") - ReflectionAnalyzer.setClassLoader(classLoader) //project.task("compileGenerated", MethodClosure(this, "compileGenerated")) } fun compileGenerated(o : Any?) { |