diff options
author | Yigit Boyar <yboyar@google.com> | 2018-10-19 14:15:57 -0700 |
---|---|---|
committer | Yigit Boyar <yboyar@google.com> | 2018-10-19 14:47:39 -0700 |
commit | dc62f2f3563222b320f1406ab4ae4dfa67fbaa3e (patch) | |
tree | 6f9cb6e45c2a0a24bfc0b364a457f10dbcfc4061 /compiler/src/main/java/android/databinding | |
parent | 2ec6c75f754b0f6ffdf1ab87920c76cb5679aeba (diff) | |
download | data-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/src/main/java/android/databinding')
6 files changed, 161 insertions, 268 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(); |