summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2015-02-17 16:02:52 -0800
committerGeorge Mount <mount@google.com>2015-02-17 16:15:29 -0800
commit812d215fa6658b0377699e01e42fa66fd14ccbe4 (patch)
treec929c6b79bf7583f62aac9b46472cc8d24e6a640 /tools
parentd872e1cdf78608ac86297237b5ef85b4648e9e04 (diff)
downloadframeworks_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')
-rw-r--r--tools/data-binding/annotationprocessor/src/main/java/com/android/databinding/annotationprocessor/ProcessBindable.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/Binding.java12
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/BindingTarget.java10
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/ExpressionVisitor.java5
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/BracketExpr.java10
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ComparisonExpr.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/Expr.java18
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ExprModel.java19
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/FieldAccessExpr.java17
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/GroupExpr.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/IdentifierExpr.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MathExpr.java10
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/MethodCallExpr.java10
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/ResourceExpr.java20
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/SymbolExpr.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/expr/TernaryExpr.java8
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationAnalyzer.java378
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationClass.java317
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationField.java47
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/AnnotationMethod.java74
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/Callable.java4
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassAnalyzer.java371
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassClass.java230
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassField.java27
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ClassMethod.java65
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelAnalyzer.java391
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelClass.java302
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelField.java30
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ModelMethod.java60
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionAnalyzer.java111
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionClass.java68
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionField.java19
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/reflection/ReflectionMethod.java32
-rw-r--r--tools/data-binding/compiler/src/main/java/com/android/databinding/store/SetterStore.java75
-rw-r--r--tools/data-binding/compiler/src/main/kotlin/com/android/databinding/ext/ext.kt6
-rw-r--r--tools/data-binding/compiler/src/main/kotlin/com/android/databinding/writer/LayoutBinderWriter.kt2
-rw-r--r--tools/data-binding/compiler/src/test/java/com/android/databinding/ExpressionVisitorTest.java6
-rw-r--r--tools/data-binding/compiler/src/test/java/com/android/databinding/LayoutBinderTest.java4
-rw-r--r--tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprModelTest.java6
-rw-r--r--tools/data-binding/compiler/src/test/java/com/android/databinding/expr/ExprTest.java8
-rw-r--r--tools/data-binding/gradlePlugin/src/main/kotlin/plugin.kt7
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?) {