summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2018-10-19 14:15:57 -0700
committerYigit Boyar <yboyar@google.com>2018-10-19 14:47:39 -0700
commitdc62f2f3563222b320f1406ab4ae4dfa67fbaa3e (patch)
tree6f9cb6e45c2a0a24bfc0b364a457f10dbcfc4061 /compiler
parent2ec6c75f754b0f6ffdf1ab87920c76cb5679aeba (diff)
downloaddata-binding-dc62f2f3563222b320f1406ab4ae4dfa67fbaa3e.tar.gz
Change ModelClass to use Lists instead of Arrays
This avoids creating an unnecessary array. Also moved Injected class to be kotlin as well. Bug: 117808327 Test: existing tests Change-Id: I481106b1089e5d1066ec0733683876926d519fad
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/main/java/android/databinding/tool/CompilerChef.java3
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java245
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.kt141
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelClass.kt24
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.kt14
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/SetterStore.java2
-rw-r--r--compiler/src/test/java/android/databinding/tool/reflection/SdkVersionTest.java8
-rw-r--r--compiler/src/test/java/android/databinding/tool/reflection/java/JavaClass.java47
8 files changed, 186 insertions, 298 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
index 46cd6724..d93d701d 100644
--- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java
+++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
@@ -163,6 +163,9 @@ public class CompilerChef {
String fieldName = bindingTargetBundle.getId();
if (fields.add(fieldName)) {
String fieldType = bindingTargetBundle.getInterfaceType();
+ if (fieldType == null) {
+ fieldType = bindingTargetBundle.getFullClassName();
+ }
bindingClass.addField(fieldName, fieldType);
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
deleted file mode 100644
index c100bfd3..00000000
--- a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.databinding.tool.reflection;
-
-import android.databinding.tool.ext.ExtKt;
-import android.databinding.tool.util.StringUtils;
-
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.TypeName;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A class that can be used by ModelAnalyzer without any backing model. This is used
- * for ViewDataBinding subclasses that haven't been generated yet, but we still want
- * to resolve methods and fields for them.
- *
- * @see ModelAnalyzer#injectClass(InjectedClass)
- */
-public class InjectedClass extends ModelClass {
- private final String mClassName;
- private final String mSuperClass;
- private final List<InjectedMethod> mMethods = new ArrayList<InjectedMethod>();
- private final List<InjectedField> mFields = new ArrayList<InjectedField>();
-
- public InjectedClass(String className, String superClass) {
- mClassName = className;
- mSuperClass = superClass;
- }
-
- public void addVariable(String name, String type, ImportBag imports) {
- String capName = StringUtils.capitalize(name);
- String setName = "set" + capName;
- String getName = "get" + capName;
- addMethod(new InjectedMethod(this, false, getName, imports, type));
- addMethod(new InjectedMethod(this, false, setName, imports,
- "void", type));
- }
-
- public void addField(String name, String type) {
- addField(new InjectedField(name, type));
- }
-
- public void addField(InjectedField field) {
- mFields.add(field);
- }
-
- public void addMethod(InjectedMethod method) {
- mMethods.add(method);
- }
-
- @Override
- public String toJavaCode() {
- return mClassName;
- }
-
- @Override
- public boolean isArray() {
- return false;
- }
-
- @Override
- public ModelClass getComponentType() {
- return null;
- }
-
- @Override
- public boolean isNullable() {
- return true;
- }
-
- @Override
- public boolean isPrimitive() {
- return false;
- }
-
- @Override
- public boolean isBoolean() {
- return false;
- }
-
- @Override
- public boolean isChar() {
- return false;
- }
-
- @Override
- public boolean isByte() {
- return false;
- }
-
- @Override
- public boolean isShort() {
- return false;
- }
-
- @Override
- public boolean isInt() {
- return false;
- }
-
- @Override
- public boolean isLong() {
- return false;
- }
-
- @Override
- public boolean isFloat() {
- return false;
- }
-
- @Override
- public boolean isDouble() {
- return false;
- }
-
- @Override
- public boolean isGeneric() {
- return false;
- }
-
- @Override
- public List<ModelClass> getTypeArguments() {
- return null;
- }
-
- @Override
- public boolean isTypeVar() {
- return false;
- }
-
- @Override
- public boolean isWildcard() {
- return false;
- }
-
- @Override
- public boolean isInterface() {
- return false;
- }
-
- @Override
- public boolean isVoid() {
- return false;
- }
-
- @Override
- public ModelClass unbox() {
- return this;
- }
-
- @Override
- public ModelClass box() {
- return this;
- }
-
- @Override
- public boolean isObservable() {
- return getSuperclass().isObservable();
- }
-
- @Override
- public boolean isAssignableFrom(ModelClass that) {
- ModelClass superClass = that;
- while (superClass != null && !superClass.isObject()) {
- if (superClass.toJavaCode().equals(mClassName)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public ModelClass getSuperclass() {
- return ModelAnalyzer.getInstance().findClass(mSuperClass, null);
- }
-
- @Override
- public ModelClass erasure() {
- return this;
- }
-
- @Override
- public String getJniDescription() {
- return TypeUtil.getInstance().getDescription(this);
- }
-
- @Override
- public ModelField[] getDeclaredFields() {
- ModelClass superClass = getSuperclass();
- final ModelField[] superFields = superClass.getDeclaredFields();
- final int initialCount = superFields.length;
- final int fieldCount = initialCount + mFields.size();
- final ModelField[] fields = Arrays.copyOf(superFields, fieldCount);
- for (int i = 0; i < mFields.size(); i++) {
- fields[i + initialCount] = mFields.get(i);
- }
- return fields;
- }
-
- @Override
- public ModelMethod[] getDeclaredMethods() {
- ModelClass superClass = getSuperclass();
- final ModelMethod[] superMethods = superClass.getDeclaredMethods();
- final int initialCount = superMethods.length;
- final int methodCount = initialCount + mMethods.size();
- final ModelMethod[] methods = Arrays.copyOf(superMethods, methodCount);
- for (int i = 0; i < mMethods.size(); i++) {
- methods[i + initialCount] = mMethods.get(i);
- }
- return methods;
- }
-
- @Override
- public TypeName getTypeName() {
- ModelAnalyzer instance = ModelAnalyzer.getInstance();
- if (instance == null) {
- return ExtKt.toTypeName(mClassName, false);
- }
- return ExtKt.toTypeName(mClassName, instance.libTypes);
- }
-
- @Override
- public String toString() {
- return "Injected Class: " + mClassName;
- }
-}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.kt b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.kt
new file mode 100644
index 00000000..d3103c3e
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 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 android.databinding.tool.reflection
+
+import android.databinding.tool.ext.toTypeName
+import android.databinding.tool.util.StringUtils
+import com.squareup.javapoet.TypeName
+import java.util.*
+
+/**
+ * A class that can be used by ModelAnalyzer without any backing model. This is used
+ * for ViewDataBinding subclasses that haven't been generated yet, but we still want
+ * to resolve methods and fields for them.
+ *
+ * @see ModelAnalyzer.injectClass
+ */
+class InjectedClass(private val mClassName: String, private val mSuperClass: String) : ModelClass() {
+ private val mMethods = ArrayList<InjectedMethod>()
+ private val mFields = ArrayList<InjectedField>()
+
+ override val isArray = false
+
+ override val componentType: ModelClass? = null
+
+ override val isNullable = true
+
+ override val isPrimitive = false
+
+ override val isBoolean = false
+
+ override val isChar = false
+
+ override val isByte = false
+
+ override val isShort = false
+
+ override val isInt = false
+
+ override val isLong = false
+
+ override val isFloat = false
+
+ override val isDouble = false
+
+ override val isGeneric = false
+
+ override val typeArguments: List<ModelClass>? = null
+
+ override val isTypeVar = false
+
+ override val isWildcard = false
+
+ override val isInterface = false
+
+ override val isVoid = false
+
+ override val isObservable by lazy(LazyThreadSafetyMode.NONE) {
+ superclass.isObservable
+ }
+
+ override val superclass by lazy(LazyThreadSafetyMode.NONE) {
+ ModelAnalyzer.getInstance().findClass(mSuperClass, null)!!
+ }
+
+ override val jniDescription: String by lazy(LazyThreadSafetyMode.NONE) {
+ TypeUtil.getInstance().getDescription(this)
+ }
+
+ // not cached because it is mutable
+ override val declaredFields: List<ModelField>
+ get() {
+ return superclass.declaredFields + mFields
+ }
+
+ // not cached because it is mutable
+ override val declaredMethods: List<ModelMethod>
+ get() {
+ return superclass.declaredMethods + mMethods
+ }
+
+ override val typeName: TypeName by lazy(LazyThreadSafetyMode.NONE) {
+ val instance = ModelAnalyzer.getInstance()
+ mClassName.toTypeName(instance.libTypes)
+ }
+
+ fun addVariable(name: String, type: String, imports: ImportBag) {
+ val capName = StringUtils.capitalize(name)
+ val setName = "set" + capName!!
+ val getName = "get$capName"
+ addMethod(InjectedMethod(this, false, getName, imports, type))
+ addMethod(InjectedMethod(this, false, setName, imports,
+ "void", type))
+ }
+
+ fun addField(name: String, type: String) {
+ addField(InjectedField(name, type))
+ }
+
+ private fun addField(field: InjectedField) {
+ mFields.add(field)
+ }
+
+ fun addMethod(method: InjectedMethod) {
+ mMethods.add(method)
+ }
+
+ override fun toJavaCode() = mClassName
+
+ override fun unbox() = this
+
+ override fun box() = this
+
+ override fun isAssignableFrom(that: ModelClass?): Boolean {
+ var maybeSuper = that
+ while (maybeSuper != null && !maybeSuper.isObject) {
+ if (maybeSuper.toJavaCode() == mClassName) {
+ return true
+ }
+ maybeSuper = maybeSuper.superclass
+ }
+ return false
+ }
+
+ override fun erasure() = this
+
+ override fun toString() = "Injected Class: $mClassName"
+}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.kt b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.kt
index a44fcf4c..f72bd6f1 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.kt
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.kt
@@ -297,9 +297,9 @@ abstract class ModelClass {
return false
}
- abstract val declaredFields: Array<ModelField>
+ abstract val declaredFields: List<ModelField>
- abstract val declaredMethods: Array<ModelMethod>
+ abstract val declaredMethods: List<ModelMethod>
// implementation only so that PSI model doesn't break
open val typeName: TypeName
@@ -365,13 +365,13 @@ abstract class ModelClass {
* `args` parameters.
*/
private fun getMethods(name: String, args: List<ModelClass>, staticOnly: Boolean,
- allowProtected: Boolean, unwrapObservableFields: Boolean): Array<ModelMethod> {
+ allowProtected: Boolean, unwrapObservableFields: Boolean): List<ModelMethod> {
return declaredMethods.filter { method ->
(method.isPublic || (allowProtected && method.isProtected))
&& (!staticOnly || method.isStatic)
&& name == method.name
&& method.acceptsArguments(args, unwrapObservableFields)
- }.toTypedArray()
+ }
}
/**
@@ -381,13 +381,13 @@ abstract class ModelClass {
* @param numParameters The number of parameters that the method should take
* @return An array containing all public methods with the given name and number of parameters.
*/
- fun getMethods(name: String, numParameters: Int): Array<ModelMethod> {
+ fun getMethods(name: String, numParameters: Int): List<ModelMethod> {
return declaredMethods.filter { method ->
method.isPublic &&
!method.isStatic &&
name == method.name &&
method.parameterTypes.size == numParameters
- }.toTypedArray()
+ }
}
/**
@@ -574,15 +574,11 @@ abstract class ModelClass {
* listener methods during Expr.resolveListeners.
*/
fun findMethods(name: String, staticOnly: Boolean): List<ModelMethod> {
- val methods = declaredMethods
- val matching = ArrayList<ModelMethod>()
- for (method in methods) {
- if (method.name == name && (!staticOnly || method.isStatic) &&
- method.isPublic) {
- matching.add(method)
- }
+ return declaredMethods.filter { method ->
+ method.isPublic &&
+ method.name == name &&
+ (!staticOnly || method.isStatic)
}
- return matching
}
override fun equals(other: Any?): Boolean {
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.kt b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.kt
index eeec3fe0..75805a63 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.kt
+++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.kt
@@ -245,12 +245,11 @@ class AnnotationClass(
val elementUtils = elementUtils
val typeElement = declaredType.asElement() as TypeElement
val members = elementUtils.getAllMembers(typeElement)
- val methods = ElementFilter.methodsIn(members)
- Array(methods.size) {
- AnnotationMethod(declaredType, methods[it]) as ModelMethod
+ ElementFilter.methodsIn(members).map {
+ AnnotationMethod(declaredType, it) as ModelMethod
}
} else {
- emptyArray()
+ emptyList()
}
}
@@ -297,12 +296,11 @@ class AnnotationClass(
val elementUtils = elementUtils
val typeElement = declaredType.asElement() as TypeElement
val members = elementUtils.getAllMembers(typeElement)
- val fields = ElementFilter.fieldsIn(members)
- Array(fields.size) {
- AnnotationField(declaredType, fields[it]) as ModelField
+ ElementFilter.fieldsIn(members).map {
+ AnnotationField(declaredType, it) as ModelField
}
} else {
- emptyArray()
+ emptyList()
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
index 4fce56ef..c04d73db 100644
--- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
+++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
@@ -731,7 +731,7 @@ public class SetterStore {
List<ModelClass> args = new ArrayList<>();
args.add(argumentType);
for (String name : setterCandidates) {
- ModelMethod[] methods = viewType.getMethods(name, 1);
+ List<ModelMethod> methods = viewType.getMethods(name, 1);
for (ModelMethod method : methods) {
ModelClass[] parameterTypes = method.getParameterTypes();
diff --git a/compiler/src/test/java/android/databinding/tool/reflection/SdkVersionTest.java b/compiler/src/test/java/android/databinding/tool/reflection/SdkVersionTest.java
index 58153656..8c9114d5 100644
--- a/compiler/src/test/java/android/databinding/tool/reflection/SdkVersionTest.java
+++ b/compiler/src/test/java/android/databinding/tool/reflection/SdkVersionTest.java
@@ -30,14 +30,14 @@ public class SdkVersionTest {
public void testApiVersionsFromResources() {
SdkUtil.get().swapApiChecker(new SdkUtil.ApiChecker(null));
ModelClass view = ModelAnalyzer.getInstance().findClass("android.widget.TextView", null);
- ModelMethod isSuggestionsEnabled = view.getMethods("isSuggestionsEnabled", 0)[0];
+ ModelMethod isSuggestionsEnabled = view.getMethods("isSuggestionsEnabled", 0).get(0);
assertEquals(14, SdkUtil.get().getMinApi(isSuggestionsEnabled));
}
@Test
public void testNewApiMethod() {
ModelClass view = ModelAnalyzer.getInstance().findClass("android.view.View", null);
- ModelMethod setElevation = view.getMethods("setElevation", 1)[0];
+ ModelMethod setElevation = view.getMethods("setElevation", 1).get(0);
assertEquals(21, SdkUtil.get().getMinApi(setElevation));
}
@@ -45,7 +45,7 @@ public class SdkVersionTest {
public void testCustomCode() {
ModelClass view = ModelAnalyzer.getInstance()
.findClass("android.databinding.tool.reflection.SdkVersionTest", null);
- ModelMethod setElevation = view.getMethods("testCustomCode", 0)[0];
+ ModelMethod setElevation = view.getMethods("testCustomCode", 0).get(0);
assertEquals(1, SdkUtil.get().getMinApi(setElevation));
}
@@ -53,7 +53,7 @@ public class SdkVersionTest {
public void testSetForeground() {
ModelClass view = ModelAnalyzer.getInstance()
.findClass("android.widget.FrameLayout", null);
- ModelMethod setForeground = view.getMethods("setForegroundGravity", 1)[0];
+ ModelMethod setForeground = view.getMethods("setForegroundGravity", 1).get(0);
assertEquals(1, SdkUtil.get().getMinApi(setForeground));
}
}
diff --git a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaClass.java b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaClass.java
index 8b6bfaf6..b26e96a7 100644
--- a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaClass.java
+++ b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaClass.java
@@ -17,18 +17,20 @@ import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.reflection.ModelField;
import android.databinding.tool.reflection.ModelMethod;
import android.databinding.tool.reflection.TypeUtil;
+import org.jetbrains.annotations.NotNull;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class JavaClass extends ModelClass {
- public final Class mClass;
+ final Class mClass;
public JavaClass(Class clazz) {
mClass = clazz;
}
+ @NotNull
@Override
public String toJavaCode() {
return toJavaCode(mClass);
@@ -139,6 +141,7 @@ public class JavaClass extends ModelClass {
return void.class.equals(mClass);
}
+ @NotNull
@Override
public ModelClass unbox() {
if (mClass.isPrimitive()) {
@@ -167,6 +170,7 @@ public class JavaClass extends ModelClass {
}
+ @NotNull
@Override
public JavaClass box() {
if (!mClass.isPrimitive()) {
@@ -197,6 +201,7 @@ public class JavaClass extends ModelClass {
@Override
public boolean isAssignableFrom(ModelClass that) {
Class thatClass = ((JavaClass) that).mClass;
+ //noinspection unchecked
return mClass.isAssignableFrom(thatClass);
}
@@ -208,48 +213,38 @@ public class JavaClass extends ModelClass {
return new JavaClass(mClass.getSuperclass());
}
+ @NotNull
@Override
public String getCanonicalName() {
return mClass.getCanonicalName();
}
+ @NotNull
@Override
public ModelClass erasure() {
return this;
}
+ @NotNull
@Override
public String getJniDescription() {
return TypeUtil.getInstance().getDescription(this);
}
+ @NotNull
@Override
- public ModelField[] getDeclaredFields() {
- Field[] fields = mClass.getDeclaredFields();
- ModelField[] modelFields;
- if (fields == null) {
- modelFields = new ModelField[0];
- } else {
- modelFields = new ModelField[fields.length];
- for (int i = 0; i < fields.length; i++) {
- modelFields[i] = new JavaField(fields[i]);
- }
- }
- return modelFields;
+ public List<ModelField> getDeclaredFields() {
+ return Stream.of(mClass.getDeclaredFields())
+ .map(JavaField::new)
+ .collect(Collectors.toList());
}
+ @NotNull
@Override
- public ModelMethod[] getDeclaredMethods() {
- Method[] methods = mClass.getDeclaredMethods();
- if (methods == null) {
- return new ModelMethod[0];
- } else {
- ModelMethod[] classMethods = new ModelMethod[methods.length];
- for (int i = 0; i < methods.length; i++) {
- classMethods[i] = new JavaMethod(methods[i]);
- }
- return classMethods;
- }
+ public List<ModelMethod> getDeclaredMethods() {
+ return Stream.of(mClass.getDeclaredMethods())
+ .map(JavaMethod::new)
+ .collect(Collectors.toList());
}
@Override