diff options
author | George Mount <mount@google.com> | 2016-03-09 15:38:02 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-03-09 15:38:02 +0000 |
commit | 3b54f63a65ad1ac66ed424efc595598ace99ce9f (patch) | |
tree | b215474bb443ac36ddff8d860ae666f09a847d01 | |
parent | 2bf1d3b17e04fd03ff447d57f770c89f935f52ae (diff) | |
parent | c0c1dab0b6254e4d27f18c37a72a9e7952e958a0 (diff) | |
download | data-binding-3b54f63a65ad1ac66ed424efc595598ace99ce9f.tar.gz |
Merge changes Ideb0570c,Ia55955ce,I7e2b2f84 into studio-master-dev
* changes:
Support for java 8 method reference syntax.
Have two-way binding use localized variables to prevent NPE.
Two-way binding tests
88 files changed, 4243 insertions, 1561 deletions
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java index f38dcc4f..a7aa9d6b 100644 --- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java +++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java @@ -16,13 +16,6 @@ package android.databinding.compilationTest; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.PrefixFileFilter; -import org.apache.commons.io.filefilter.SuffixFileFilter; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; - import android.databinding.tool.processing.ErrorMessages; import android.databinding.tool.processing.ScopedErrorReport; import android.databinding.tool.processing.ScopedException; @@ -30,6 +23,12 @@ import android.databinding.tool.store.Location; import com.google.common.base.Joiner; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.PrefixFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -37,7 +36,6 @@ import java.util.Collection; import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -160,7 +158,7 @@ public class SimpleCompilationTest extends BaseCompilationTest { expectedErrorFile = "/app/src/main/res/layout/broken.xml"; } else if (errorFile.getCanonicalPath().equals(invalidSetter.getCanonicalPath())) { message = String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx", - String.class.getCanonicalName()); + String.class.getCanonicalName(), "android.widget.TextView"); expectedErrorFile = "/app/src/main/res/layout/invalid_setter.xml"; } else { fail("unexpected exception " + exception.getBareMessage()); @@ -179,9 +177,9 @@ public class SimpleCompilationTest extends BaseCompilationTest { "/app/src/main/res/layout/broken.xml", "myVar.length())", String.format(ErrorMessages.SYNTAX_ERROR, - "extraneous input ')' expecting {<EOF>, ',', '.', '[', '+', '-', '*', '/', " - + "'%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', " - + "'==', '!=', '&', '^', '|', '&&', '||', '?', '??'}")); + "extraneous input ')' expecting {<EOF>, ',', '.', '::', '[', '+', '-', " + + "'*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', " + + "'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}")); } @Test @@ -190,9 +188,9 @@ public class SimpleCompilationTest extends BaseCompilationTest { "/app/src/main/res/layout/broken.xml", "new String()", String.format(ErrorMessages.SYNTAX_ERROR, - "mismatched input 'String' expecting {<EOF>, ',', '.', '[', '+', '-', '*', " - + "'/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof'," - + " '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}")); + "mismatched input 'String' expecting {<EOF>, ',', '.', '::', '[', '+', " + + "'-', '*', '/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', " + + "'instanceof', '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}")); } @Test @@ -210,7 +208,7 @@ public class SimpleCompilationTest extends BaseCompilationTest { ScopedException ex = singleFileErrorTest("/layout/invalid_setter_binding.xml", "/app/src/main/res/layout/invalid_setter.xml", "myVariable", String.format(ErrorMessages.CANNOT_FIND_SETTER_CALL, "android:textx", - String.class.getCanonicalName())); + String.class.getCanonicalName(), "android.widget.TextView")); } @Test @@ -259,7 +257,7 @@ public class SimpleCompilationTest extends BaseCompilationTest { prepareProject(); ScopedException ex = singleFileErrorTest("/layout/invalid_variable_type.xml", "/app/src/main/res/layout/invalid_variable.xml", "myVariable", - String.format(ErrorMessages.CANNOT_RESOLVE_TYPE, "myVariable~")); + String.format(ErrorMessages.CANNOT_RESOLVE_TYPE, "myVariable")); } @Test @@ -327,4 +325,25 @@ public class SimpleCompilationTest extends BaseCompilationTest { assertEquals("Merge shouldn't support includes as root. Error message was '" + result.error, ErrorMessages.INCLUDE_INSIDE_MERGE, ex.getBareMessage()); } + + @Test + public void testAssignTwoWayEvent() throws Throwable { + prepareProject(); + copyResourceTo("/layout/layout_with_two_way_event_attribute.xml", + "/app/src/main/res/layout/layout_with_two_way_event_attribute.xml"); + CompilationResult result = runGradle("assembleDebug"); + assertNotEquals(0, result.resultCode); + List<ScopedException> errors = ScopedException.extractErrors(result.error); + assertEquals(result.error, 1, errors.size()); + final ScopedException ex = errors.get(0); + final ScopedErrorReport report = ex.getScopedErrorReport(); + final File errorFile = new File(report.getFilePath()); + assertTrue(errorFile.exists()); + assertEquals(new File(testFolder, + "/app/src/main/res/layout/layout_with_two_way_event_attribute.xml") + .getCanonicalFile(), + errorFile.getCanonicalFile()); + assertEquals("The attribute android:textAttrChanged is a two-way binding event attribute " + + "and cannot be assigned.", ex.getBareMessage()); + } } diff --git a/compilationTests/src/test/resources/layout/layout_with_two_way_event_attribute.xml b/compilationTests/src/test/resources/layout/layout_with_two_way_event_attribute.xml new file mode 100644 index 00000000..16536e34 --- /dev/null +++ b/compilationTests/src/test/resources/layout/layout_with_two_way_event_attribute.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<layout xmlns:android="http://schemas.android.com/apk/res/android" +> + <data> + <variable name="myVariable" type="String"/> + <variable name="myEventListener" type="android.databinding.InverseBindingListener"/> + </data> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <!-- undefined variable --> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/textView" + android:text="@{myVariable}" + android:textAttrChanged="@{myEventListener}"/> + </LinearLayout> +</layout>
\ No newline at end of file diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java index 4dc059f3..59e86141 100644 --- a/compiler/src/main/java/android/databinding/tool/Binding.java +++ b/compiler/src/main/java/android/databinding/tool/Binding.java @@ -75,7 +75,7 @@ public class Binding implements LocationScopeProvider { LambdaExpr lambdaExpr = (LambdaExpr) mExpr; final ModelClass listener = getListenerParameter(mTarget, mName, mExpr.getModel()); Preconditions.checkNotNull(listener, ErrorMessages.CANNOT_FIND_SETTER_CALL, mName, - "lambda"); + "lambda", getTarget().getInterfaceType()); //noinspection ConstantConditions List<ModelMethod> abstractMethods = listener.getAbstractMethods(); int numberOfAbstractMethods = abstractMethods.size(); @@ -106,7 +106,8 @@ public class Binding implements LocationScopeProvider { Scope.enter(this); resolveSetterCall(); if (mSetterCall == null) { - L.e(ErrorMessages.CANNOT_FIND_SETTER_CALL, mName, mExpr.getResolvedType()); + L.e(ErrorMessages.CANNOT_FIND_SETTER_CALL, mName, mExpr.getResolvedType(), + getTarget().getInterfaceType()); } } finally { Scope.exit(); diff --git a/compiler/src/main/java/android/databinding/tool/BindingTarget.java b/compiler/src/main/java/android/databinding/tool/BindingTarget.java index 74ef86cd..8c59ca75 100644 --- a/compiler/src/main/java/android/databinding/tool/BindingTarget.java +++ b/compiler/src/main/java/android/databinding/tool/BindingTarget.java @@ -58,28 +58,24 @@ public class BindingTarget implements LocationScopeProvider { L.e(ErrorMessages.TWO_WAY_EVENT_ATTRIBUTE, name); } mBindings.add(new Binding(this, name, expr)); - if (expr.isTwoWay()) { - try { - Scope.enter(expr); - expr.assertIsInvertible(); - final InverseBinding inverseBinding = new InverseBinding(this, name, expr); - mInverseBindings.add(inverseBinding); - mBindings.add(new Binding(this, inverseBinding.getEventAttribute(), - mModel.twoWayListenerExpr(inverseBinding), - inverseBinding.getEventSetter())); - } finally { - Scope.exit(); - } - } } public String getInterfaceType() { return mBundle.getInterfaceType() == null ? mBundle.getFullClassName() : mBundle.getInterfaceType(); } + public InverseBinding addInverseBinding(String name, Expr expr, String bindingClass) { + expr.assertIsInvertible(); + final InverseBinding inverseBinding = new InverseBinding(this, name, expr, bindingClass); + mInverseBindings.add(inverseBinding); + mBindings.add(new Binding(this, inverseBinding.getEventAttribute(), + mModel.twoWayListenerExpr(inverseBinding), + inverseBinding.getEventSetter())); + return inverseBinding; + } + public InverseBinding addInverseBinding(String name, BindingGetterCall call) { - final InverseBinding inverseBinding = new InverseBinding(this, name, null); - inverseBinding.setGetterCall(call); + final InverseBinding inverseBinding = new InverseBinding(this, name, call); mInverseBindings.add(inverseBinding); mBindings.add(new Binding(this, inverseBinding.getEventAttribute(), mModel.twoWayListenerExpr(inverseBinding))); @@ -111,7 +107,7 @@ public class BindingTarget implements LocationScopeProvider { if (mResolvedClass == null) { if (mBundle.isBinder()) { mResolvedClass = ModelAnalyzer.getInstance(). - findClass(ModelAnalyzer.VIEW_DATA_BINDING, mModel.getImports()); + findClass(mBundle.getInterfaceType(), mModel.getImports()); } else { mResolvedClass = ModelAnalyzer.getInstance().findClass(mBundle.getFullClassName(), mModel.getImports()); diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java index b7456da0..278492ad 100644 --- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java +++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java @@ -23,6 +23,7 @@ import android.databinding.tool.writer.DataBinderWriter; import android.databinding.tool.writer.DynamicUtilWriter; import android.databinding.tool.writer.JavaFileWriter; +import java.util.HashMap; import java.util.Set; /** @@ -69,6 +70,7 @@ public class CompilerChef { chef.mResourceBundle = bundle; chef.mFileWriter = fileWriter; chef.mResourceBundle.validateMultiResLayouts(); + chef.pushClassesToAnalyzer(); return chef; } @@ -89,6 +91,42 @@ public class CompilerChef { return mResourceBundle != null && mResourceBundle.getLayoutBundles().size() > 0; } + /** + * Injects ViewDataBinding subclasses to the ModelAnalyzer so that they can be + * analyzed prior to creation. This is useful for resolving variable setters and + * View fields during compilation. + */ + private void pushClassesToAnalyzer() { + ModelAnalyzer analyzer = ModelAnalyzer.getInstance(); + for (String layoutName : mResourceBundle.getLayoutBundles().keySet()) { + ResourceBundle.LayoutFileBundle layoutFileBundle = + mResourceBundle.getLayoutBundles().get(layoutName).get(0); + final HashMap<String, String> imports = new HashMap<String, String>(); + for (ResourceBundle.NameTypeLocation imp : layoutFileBundle.getImports()) { + imports.put(imp.name, imp.type); + } + final HashMap<String, String> variables = new HashMap<String, String>(); + for (ResourceBundle.VariableDeclaration variable : layoutFileBundle.getVariables()) { + final String variableName = variable.name; + String type = variable.type; + if (imports.containsKey(type)) { + type = imports.get(type); + } + variables.put(variableName, type); + } + final HashMap<String, String> fields = new HashMap<String, String>(); + for (ResourceBundle.BindingTargetBundle bindingTargetBundle : + layoutFileBundle.getBindingTargetBundles()) { + if (bindingTargetBundle.getId() != null) { + fields.put(bindingTargetBundle.getId(), bindingTargetBundle.getInterfaceType()); + } + } + final String className = layoutFileBundle.getBindingClassPackage() + "." + + layoutFileBundle.getBindingClassName(); + analyzer.injectViewDataBinding(className, variables, fields); + } + } + public void writeDataBinderMapper(int minSdk, BRWriter brWriter) { ensureDataBinder(); final String pkg = "android.databinding"; diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java index 5fc5534d..f35b1e2b 100644 --- a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java +++ b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java @@ -202,6 +202,17 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> { } @Override + public Expr visitFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx) { + try { + onEnter(ctx); + return mModel.methodReference(ctx.expression().accept(this), + ctx.Identifier().getSymbol().getText()); + } finally { + onExit(ctx); + } + } + + @Override public Expr visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { try { onEnter(ctx); diff --git a/compiler/src/main/java/android/databinding/tool/InverseBinding.java b/compiler/src/main/java/android/databinding/tool/InverseBinding.java index e04be283..13dd8875 100644 --- a/compiler/src/main/java/android/databinding/tool/InverseBinding.java +++ b/compiler/src/main/java/android/databinding/tool/InverseBinding.java @@ -16,25 +16,23 @@ package android.databinding.tool; +import android.databinding.tool.expr.CallbackArgExpr; +import android.databinding.tool.expr.CallbackExprModel; import android.databinding.tool.expr.Expr; import android.databinding.tool.expr.ExprModel; import android.databinding.tool.expr.FieldAccessExpr; +import android.databinding.tool.expr.IdentifierExpr; import android.databinding.tool.processing.ErrorMessages; import android.databinding.tool.processing.Scope; import android.databinding.tool.processing.scopes.LocationScopeProvider; import android.databinding.tool.reflection.ModelAnalyzer; import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.solver.ExecutionPath; import android.databinding.tool.store.Location; import android.databinding.tool.store.SetterStore; import android.databinding.tool.store.SetterStore.BindingGetterCall; import android.databinding.tool.store.SetterStore.BindingSetterCall; import android.databinding.tool.util.L; -import android.databinding.tool.util.Preconditions; -import android.databinding.tool.writer.FlagSet; -import android.databinding.tool.writer.KCode; -import android.databinding.tool.writer.LayoutBinderWriterKt; - -import kotlin.jvm.functions.Function2; import java.util.ArrayList; import java.util.List; @@ -46,11 +44,38 @@ public class InverseBinding implements LocationScopeProvider { private final BindingTarget mTarget; private BindingGetterCall mGetterCall; private final ArrayList<FieldAccessExpr> mChainedExpressions = new ArrayList<FieldAccessExpr>(); + private final CallbackExprModel mCallbackExprModel; + private final Expr mInverseExpr; + private final CallbackArgExpr mVariableExpr; + private final ExecutionPath mExecutionPath; + + public InverseBinding(BindingTarget target, String name, Expr expr, String bindingClassName) { + mTarget = target; + mName = name; + mCallbackExprModel = new CallbackExprModel(expr.getModel()); + mExpr = expr.cloneToModel(mCallbackExprModel); + setGetterCall(mExpr); + mVariableExpr = mCallbackExprModel.callbackArg("callbackArg_0"); + ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance(); + ModelClass type = modelAnalyzer.findClass(getGetterCall().getGetterType(), null); + mVariableExpr.setClassFromCallback(type); + mVariableExpr.setUserDefinedType(getGetterCall().getGetterType()); + mInverseExpr = + mExpr.generateInverse(mCallbackExprModel, mVariableExpr, bindingClassName); + mExecutionPath = ExecutionPath.createRoot(); + mInverseExpr.toExecutionPath(mExecutionPath); + mCallbackExprModel.seal(); + } - public InverseBinding(BindingTarget target, String name, Expr expr) { + public InverseBinding(BindingTarget target, String name, BindingGetterCall getterCall) { mTarget = target; mName = name; - mExpr = expr; + mExpr = null; + mCallbackExprModel = null; + mInverseExpr = null; + mVariableExpr = null; + mExecutionPath = null; + setGetterCall(getterCall); } @Override @@ -62,7 +87,7 @@ public class InverseBinding implements LocationScopeProvider { } } - void setGetterCall(BindingGetterCall getterCall) { + private void setGetterCall(BindingGetterCall getterCall) { mGetterCall = getterCall; } @@ -74,74 +99,56 @@ public class InverseBinding implements LocationScopeProvider { return mTarget.getResolvedType().isViewDataBinding(); } - private SetterStore.BindingGetterCall getGetterCall() { - if (mGetterCall == null) { - if (mExpr != null) { - mExpr.getResolvedType(); // force resolve of ObservableFields - } - try { - Scope.enter(mTarget); - Scope.enter(this); - resolveGetterCall(); - if (mGetterCall == null) { - L.e(ErrorMessages.CANNOT_FIND_GETTER_CALL, mName, - mExpr == null ? "Unknown" : mExpr.getResolvedType(), - mTarget.getResolvedType()); - } - } finally { - Scope.exit(); - Scope.exit(); + private void setGetterCall(Expr expr) { + try { + Scope.enter(mTarget); + Scope.enter(this); + ModelClass viewType = mTarget.getResolvedType(); + final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance()); + final ModelClass resolvedType = expr == null ? null : expr.getResolvedType(); + mGetterCall = setterStore.getGetterCall(mName, viewType, resolvedType, + expr.getModel().getImports()); + if (mGetterCall == null) { + L.e(ErrorMessages.CANNOT_FIND_GETTER_CALL, mName, + expr == null ? "Unknown" : mExpr.getResolvedType(), + mTarget.getResolvedType()); } + } finally { + Scope.exit(); + Scope.exit(); } - return mGetterCall; } - private void resolveGetterCall() { - ModelClass viewType = mTarget.getResolvedType(); - final SetterStore setterStore = SetterStore.get(ModelAnalyzer.getInstance()); - final ModelClass resolvedType = mExpr == null ? null : mExpr.getResolvedType(); - mGetterCall = setterStore.getGetterCall(mName, viewType, resolvedType, - getModel().getImports()); + public SetterStore.BindingGetterCall getGetterCall() { + return mGetterCall; } public BindingTarget getTarget() { return mTarget; } - public KCode toJavaCode(String bindingComponent, final FlagSet flagField) { - final String targetViewName = LayoutBinderWriterKt.getFieldName(getTarget()); - KCode code = new KCode(); - // A chained expression will have substituted its chained value for the expression - // unless the attribute has no expression. Therefore, chaining and expressions are - // mutually exclusive. - Preconditions.check((mExpr == null) != mChainedExpressions.isEmpty(), - "Chained expressions are only against unbound attributes."); - if (mExpr != null) { - code.app("", mExpr.toInverseCode(new KCode(getGetterCall().toJava(bindingComponent, - targetViewName)))); - } else { // !mChainedExpressions.isEmpty()) - final String fieldName = flagField.getLocalName(); - FlagSet flagSet = new FlagSet(); - for (FieldAccessExpr expr : mChainedExpressions) { - flagSet = flagSet.or(new FlagSet(expr.getId())); - } - final FlagSet allFlags = flagSet; - code.nl(new KCode("synchronized(this) {")); - code.tab(LayoutBinderWriterKt - .mapOr(flagField, flagSet, new Function2<String, Integer, KCode>() { - @Override - public KCode invoke(String suffix, Integer index) { - return new KCode(fieldName) - .app(suffix) - .app(" |= ") - .app(LayoutBinderWriterKt.binaryCode(allFlags, index)) - .app(";"); - } - })); - code.nl(new KCode("}")); - code.nl(new KCode("requestRebind()")); - } - return code; + public Expr getExpr() { + return mExpr; + } + + public Expr getInverseExpr() { + return mInverseExpr; + } + + public IdentifierExpr getVariableExpr() { + return mVariableExpr; + } + + public ExecutionPath getExecutionPath() { + return mExecutionPath; + } + + public CallbackExprModel getCallbackExprModel() { + return mCallbackExprModel; + } + + public List<FieldAccessExpr> getChainedExpressions() { + return mChainedExpressions; } public String getBindingAdapterInstanceClass() { diff --git a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java index 7348bd75..7969854a 100644 --- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java +++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java @@ -216,13 +216,18 @@ public class LayoutBinder implements FileScopeProvider { for (BindingTarget bindingTarget : mBindingTargets) { try { Scope.enter(bindingTarget.mBundle); + final String className = getPackage() + "." + getClassName(); for (BindingTargetBundle.BindingBundle bindingBundle : bindingTarget.mBundle .getBindingBundleList()) { try { Scope.enter(bindingBundle.getValueLocation()); - bindingTarget.addBinding(bindingBundle.getName(), - parse(bindingBundle.getExpr(), bindingBundle.isTwoWay(), - bindingBundle.getValueLocation())); + Expr expr = parse(bindingBundle.getExpr(), + bindingBundle.getValueLocation()); + bindingTarget.addBinding(bindingBundle.getName(), expr); + if (bindingBundle.isTwoWay()) { + bindingTarget.addInverseBinding(bindingBundle.getName(), expr, + className); + } } finally { Scope.exit(); } @@ -290,10 +295,9 @@ public class LayoutBinder implements FileScopeProvider { return target; } - public Expr parse(String input, boolean isTwoWay, @Nullable Location locationInFile) { + public Expr parse(String input, @Nullable Location locationInFile) { final Expr parsed = mExpressionParser.parse(input, locationInFile); parsed.setBindingExpression(true); - parsed.setTwoWay(isTwoWay); return parsed; } diff --git a/compiler/src/main/java/android/databinding/tool/expr/ArgListExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ArgListExpr.java index c8f6e2cf..cdb0d14a 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ArgListExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ArgListExpr.java @@ -42,12 +42,17 @@ public class ArgListExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { throw new IllegalStateException("should never try to convert an argument expressions" + " into code"); } @Override + public Expr cloneToModel(ExprModel model) { + return model.argListExpr(cloneToModel(model, getChildren())); + } + + @Override protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { return modelAnalyzer.findClass(Void.class); } diff --git a/compiler/src/main/java/android/databinding/tool/expr/BitShiftExpr.java b/compiler/src/main/java/android/databinding/tool/expr/BitShiftExpr.java index cbc895bb..f4da3ec0 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/BitShiftExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/BitShiftExpr.java @@ -57,15 +57,25 @@ public class BitShiftExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode() - .app("", getLeft().toCode(expand)) + .app("", getLeft().toCode()) .app(getOp()) - .app("", getRight().toCode(expand)); + .app("", getRight().toCode()); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.bitshift(getLeft().cloneToModel(model), mOp, getRight().cloneToModel(model)); } @Override public String getInvertibleError() { return "Bit shift operators cannot be inverted in two-way binding"; } + + @Override + public String toString() { + return getLeft().toString() + ' ' + mOp + ' ' + getRight().toString(); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java b/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java index 0829ad04..a9a61556 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java @@ -21,6 +21,8 @@ import android.databinding.tool.reflection.ModelClass; import android.databinding.tool.solver.ExecutionPath; import android.databinding.tool.writer.KCode; +import com.google.common.collect.Lists; + import java.util.ArrayList; import java.util.List; @@ -90,7 +92,7 @@ public class BracketExpr extends Expr { protected String computeUniqueKey() { final String targetKey = getTarget().computeUniqueKey(); - return addTwoWay(join(targetKey, "$", getArg().computeUniqueKey(), "$")); + return join(targetKey, "$", getArg().computeUniqueKey(), "$"); } @Override @@ -115,7 +117,7 @@ public class BracketExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { String cast = argCastsInteger() ? "(Integer) " : ""; switch (getAccessor()) { case ARRAY: { @@ -152,12 +154,33 @@ public class BracketExpr extends Expr { } @Override - public KCode toInverseCode(KCode value) { - String cast = argCastsInteger() ? "(Integer) " : ""; - return new KCode(). - app("setTo(", getTarget().toCode(true)). - app(", "). - app(cast, getArg().toCode(true)). - app(", ", value).app(");"); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + Expr arg = getArg().cloneToModel(model); + arg = argCastsInteger() + ? model.castExpr("int", model.castExpr("Integer", arg)) + : arg; + StaticIdentifierExpr viewDataBinding = + model.staticIdentifier(ModelAnalyzer.VIEW_DATA_BINDING); + viewDataBinding.setUserDefinedType(ModelAnalyzer.VIEW_DATA_BINDING); + ModelClass targetType = getTarget().getResolvedType(); + if ((targetType.isList() || targetType.isMap()) && + value.getResolvedType().isPrimitive()) { + ModelClass boxed = value.getResolvedType().box(); + value = model.castExpr(boxed.toJavaCode(), value); + } + List<Expr> args = Lists.newArrayList(getTarget().cloneToModel(model), arg, value); + MethodCallExpr setter = model.methodCall(viewDataBinding, "setTo", args); + setter.setAllowProtected(); + return setter; + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.bracketExpr(getTarget().cloneToModel(model), getArg().cloneToModel(model)); + } + + @Override + public String toString() { + return getTarget().toString() + '[' + getArg() + ']'; } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/BuiltInVariableExpr.java b/compiler/src/main/java/android/databinding/tool/expr/BuiltInVariableExpr.java index d2fdea13..ff1d1adf 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/BuiltInVariableExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/BuiltInVariableExpr.java @@ -49,7 +49,7 @@ public class BuiltInVariableExpr extends IdentifierExpr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { if (mAccessCode == null) { return new KCode().app(mName); } else { @@ -65,4 +65,9 @@ public class BuiltInVariableExpr extends IdentifierExpr { public String getInvertibleError() { return "Built-in variables may not be the target of two-way binding"; } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.builtInVariable(mName, mUserDefinedType, mAccessCode); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java b/compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java index 2f77f831..34841c93 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java @@ -68,7 +68,7 @@ public class CallbackArgExpr extends IdentifierExpr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode(CallbackWrapper.ARG_PREFIX + mArgIndex); } @@ -85,4 +85,9 @@ public class CallbackArgExpr extends IdentifierExpr { public String getName() { return mName; } + + @Override + public Expr cloneToModel(ExprModel model) { + return new CallbackArgExpr(mArgIndex, mName); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java b/compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java index 1e0fc8ac..501125c0 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java +++ b/compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java @@ -18,7 +18,6 @@ package android.databinding.tool.expr; import android.databinding.tool.processing.ErrorMessages; import android.databinding.tool.processing.Scope; -import android.databinding.tool.processing.ScopedException; import android.databinding.tool.store.Location; import android.databinding.tool.util.L; import android.databinding.tool.util.Preconditions; diff --git a/compiler/src/main/java/android/databinding/tool/expr/CastExpr.java b/compiler/src/main/java/android/databinding/tool/expr/CastExpr.java index 9a4a36ae..9a66cd98 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/CastExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/CastExpr.java @@ -46,7 +46,7 @@ public class CastExpr extends Expr { } protected String computeUniqueKey() { - return addTwoWay(join(mType, getCastExpr().computeUniqueKey())); + return join(mType, getCastExpr().computeUniqueKey()); } public Expr getCastExpr() { @@ -58,11 +58,12 @@ public class CastExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode() .app("(") .app(getCastType()) - .app(") ", getCastExpr().toCode(expand)); + .app(") (", getCastExpr().toCode()) + .app(")"); } @Override @@ -71,8 +72,20 @@ public class CastExpr extends Expr { } @Override - public KCode toInverseCode(KCode value) { - // assume no need to cast in reverse - return getCastExpr().toInverseCode(value); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + Expr castExpr = getCastExpr(); + ModelClass exprType = castExpr.getResolvedType(); + Expr castValue = model.castExpr(exprType.toJavaCode(), value); + return castExpr.generateInverse(model, castValue, bindingClassName); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.castExpr(mType, getCastExpr().cloneToModel(model)); + } + + @Override + public String toString() { + return "(" + mType + ") " + getCastExpr(); } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/ComparisonExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ComparisonExpr.java index 172ea219..6b36bca9 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ComparisonExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ComparisonExpr.java @@ -62,14 +62,27 @@ public class ComparisonExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { - return new KCode().app("", getLeft().toCode(expand)) - .app(" ").app(getOp()).app(" ") - .app("", getRight().toCode(expand)); + protected KCode generateCode() { + return new KCode() + .app("(", getLeft().toCode()) + .app(") ") + .app(getOp()) + .app(" (", getRight().toCode()) + .app(")"); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.comparison(mOp, getLeft().cloneToModel(model), getRight().cloneToModel(model)); } @Override public String getInvertibleError() { return "Comparison operators are not valid as targets of two-way binding"; } + + @Override + public String toString() { + return getLeft().toString() + ' ' + mOp + ' ' + getRight(); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/Expr.java b/compiler/src/main/java/android/databinding/tool/expr/Expr.java index 59cc916d..768a59a5 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/Expr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/Expr.java @@ -100,7 +100,6 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider { private boolean mRead; private boolean mIsUsed = false; private boolean mIsUsedInCallback = false; - private boolean mIsTwoWay = false; Expr(Iterable<Expr> children) { for (Expr expr : children) { @@ -212,22 +211,6 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider { mModel = model; } - public void setTwoWay(boolean isTwoWay) { - mIsTwoWay = isTwoWay; - } - - public boolean isTwoWay() { - return mIsTwoWay; - } - - protected String addTwoWay(String uniqueKey) { - if (mIsTwoWay) { - return "twoWay(" + uniqueKey + ")"; - } else { - return "oneWay(" + uniqueKey + ")"; - } - } - private BitSet resolveShouldReadWithConditionals() { // ensure we have invalid flags BitSet bitSet = new BitSet(); @@ -751,26 +734,32 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider { } public KCode toCode() { - return toCode(false); - } - - public KCode toCode(boolean expand) { - if (!expand && isDynamic()) { + if (isDynamic()) { return new KCode(LayoutBinderWriterKt.scopedName(this)); } - return generateCode(expand); + return generateCode(); } public KCode toFullCode() { - return generateCode(false); + return generateCode(); } - protected abstract KCode generateCode(boolean expand); + protected abstract KCode generateCode(); - public KCode toInverseCode(KCode value) { + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { throw new IllegalStateException("expression does not support two-way binding"); } + public abstract Expr cloneToModel(ExprModel model); + + protected static List<Expr> cloneToModel(ExprModel model, List<Expr> exprs) { + ArrayList<Expr> clones = new ArrayList<Expr>(); + for (Expr expr : exprs) { + clones.add(expr.cloneToModel(model)); + } + return clones; + } + public void assertIsInvertible() { final String errorMessage = getInvertibleError(); if (errorMessage != null) { diff --git a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java index f9f2c654..e9cdfab2 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java @@ -170,7 +170,11 @@ public class ExprModel { } public FieldAccessExpr observableField(Expr parent, String name) { - return register(new FieldAccessExpr(parent, name, true)); + return register(new ObservableFieldExpr(parent, name)); + } + + public MethodReferenceExpr methodReference(Expr parent, String name) { + return register(new MethodReferenceExpr(parent, name)); } public SymbolExpr symbol(String text, Class type) { @@ -334,7 +338,7 @@ public class ExprModel { public void removeExpr(Expr expr) { Preconditions.check(!mSealed, "Can't modify the expression list after sealing the model."); mBindingExpressions.remove(expr); - mExprMap.remove(expr.computeUniqueKey()); + mExprMap.remove(expr.getUniqueKey()); } public List<Expr> getObservables() { @@ -402,7 +406,7 @@ public class ExprModel { for (Expr expr : mExprMap.values()) { if (expr instanceof FieldAccessExpr) { FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) expr; - if (fieldAccessExpr.getChild() instanceof ViewFieldExpr) { + if (fieldAccessExpr.getTarget() instanceof ViewFieldExpr) { flagMapping.add(fieldAccessExpr.getUniqueKey()); fieldAccessExpr.setId(counter++); } @@ -682,6 +686,10 @@ public class ExprModel { return register(new ListenerExpr(expression, name, listenerType, listenerMethod)); } + public FieldAssignmentExpr assignment(Expr target, String name, Expr value) { + return register(new FieldAssignmentExpr(target, name, value)); + } + public Map<String, CallbackWrapper> getCallbackWrappers() { return mCallbackWrappers; } @@ -696,7 +704,7 @@ public class ExprModel { return wrapper; } - public Expr lambdaExpr(Expr expr, CallbackExprModel callbackExprModel) { + public LambdaExpr lambdaExpr(Expr expr, CallbackExprModel callbackExprModel) { return register(new LambdaExpr(expr, callbackExprModel)); } diff --git a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java index 5d850b5d..d897f0a7 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java @@ -26,8 +26,6 @@ import android.databinding.tool.reflection.Callable; import android.databinding.tool.reflection.Callable.Type; import android.databinding.tool.reflection.ModelAnalyzer; import android.databinding.tool.reflection.ModelClass; -import android.databinding.tool.reflection.ModelMethod; -import android.databinding.tool.solver.ExecutionPath; import android.databinding.tool.store.SetterStore; import android.databinding.tool.store.SetterStore.BindingGetterCall; import android.databinding.tool.util.BrNameUtil; @@ -35,32 +33,20 @@ import android.databinding.tool.util.L; import android.databinding.tool.util.Preconditions; import android.databinding.tool.writer.KCode; -import java.util.ArrayList; +import com.google.common.collect.Lists; + import java.util.List; -public class FieldAccessExpr extends Expr { - String mName; +public class FieldAccessExpr extends MethodBaseExpr { // notification name for the field. Important when we map this to a method w/ different name String mBrName; Callable mGetter; - final boolean mIsObservableField; boolean mIsListener; boolean mIsViewAttributeAccess; FieldAccessExpr(Expr parent, String name) { - super(parent); + super(parent, name); mName = name; - mIsObservableField = false; - } - - FieldAccessExpr(Expr parent, String name, boolean isObservableField) { - super(parent); - mName = name; - mIsObservableField = isObservableField; - } - - public Expr getChild() { - return getChildren().get(0); } public Callable getGetter() { @@ -71,30 +57,11 @@ public class FieldAccessExpr extends Expr { } @Override - public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) { - final List<ExecutionPath> targetPaths = getChild().toExecutionPath(paths); - // after this, we need a null check. - List<ExecutionPath> result = new ArrayList<ExecutionPath>(); - if (getChild() instanceof StaticIdentifierExpr) { - result.addAll(toExecutionPathInOrder(paths, getChild())); - } else { - for (ExecutionPath path : targetPaths) { - final ComparisonExpr cmp = getModel() - .comparison("!=", getChild(), getModel().symbol("null", Object.class)); - path.addPath(cmp); - final ExecutionPath subPath = path.addBranch(cmp, true); - if (subPath != null) { - subPath.addPath(this); - result.add(subPath); - } - } - } - return result; - } - - @Override public String getInvertibleError() { - if (getGetter().setterName == null) { + if (getGetter() == null) { + return "Listeners do not support two-way binding"; + } + if (mGetter.setterName == null) { return "Two-way binding cannot resolve a setter for " + getResolvedType().toJavaCode() + " property '" + mName + "'"; } @@ -106,7 +73,7 @@ public class FieldAccessExpr extends Expr { } public int getMinApi() { - return mGetter.getMinApi(); + return mGetter == null ? 0 : mGetter.getMinApi(); } @Override @@ -118,7 +85,7 @@ public class FieldAccessExpr extends Expr { return true; } // if it is static final, gone - if (getChild().isDynamic()) { + if (getTarget().isDynamic()) { // if owner is dynamic, then we can be dynamic unless we are static final return !mGetter.isStatic() || mGetter.isDynamic(); } @@ -132,108 +99,33 @@ public class FieldAccessExpr extends Expr { } public boolean hasBindableAnnotations() { - return mGetter.canBeInvalidated(); + return mGetter != null && mGetter.canBeInvalidated(); } @Override public Expr resolveListeners(ModelClass listener, Expr parent) { - if (mName == null || mName.isEmpty()) { - return this; // ObservableFields aren't listeners - } - final ModelClass childType = getChild().getResolvedType(); - if (getGetter() == null) { - if (listener == null || !mIsListener) { - L.e("Could not resolve %s.%s as an accessor or listener on the attribute.", - childType.getCanonicalName(), mName); - return this; - } - getChild().getParents().remove(this); - } else if (listener == null) { - return this; // Not a listener, but we have a getter. - } - List<ModelMethod> abstractMethods = listener.getAbstractMethods(); - int numberOfAbstractMethods = abstractMethods == null ? 0 : abstractMethods.size(); - if (numberOfAbstractMethods != 1) { - if (mGetter == null) { - L.e("Could not find accessor %s.%s and %s has %d abstract methods, so is" + - " not resolved as a listener", - childType.getCanonicalName(), mName, - listener.getCanonicalName(), numberOfAbstractMethods); - } + final ModelClass targetType = getTarget().getResolvedType(); + if (getGetter() == null && (listener == null || !mIsListener)) { + L.e("Could not resolve %s.%s as an accessor or listener on the attribute.", + targetType.getCanonicalName(), mName); return this; } - - // Look for a signature matching the abstract method - final ModelMethod listenerMethod = abstractMethods.get(0); - final ModelClass[] listenerParameters = listenerMethod.getParameterTypes(); - boolean isStatic = getChild() instanceof StaticIdentifierExpr; - List<ModelMethod> methods = childType.findMethods(mName, isStatic); - for (ModelMethod method : methods) { - if (acceptsParameters(method, listenerParameters) && - method.getReturnType(null).equals(listenerMethod.getReturnType(null))) { - resetResolvedType(); - // replace this with ListenerExpr in parent - Expr listenerExpr = getModel().listenerExpr(getChild(), mName, listener, - listenerMethod); - if (parent != null) { - int index; - while ((index = parent.getChildren().indexOf(this)) != -1) { - parent.getChildren().set(index, listenerExpr); - } - } - if (getModel().mBindingExpressions.contains(this)) { - getModel().bindingExpr(listenerExpr); - } - getParents().remove(parent); - if (getParents().isEmpty()) { - getModel().removeExpr(this); - } - return listenerExpr; - } - } - - if (mGetter == null) { - L.e("Listener class %s with method %s did not match signature of any method %s.%s", - listener.getCanonicalName(), listenerMethod.getName(), - childType.getCanonicalName(), mName); - } - return this; - } - - private boolean acceptsParameters(ModelMethod method, ModelClass[] listenerParameters) { - ModelClass[] parameters = method.getParameterTypes(); - if (parameters.length != listenerParameters.length) { - return false; - } - for (int i = 0; i < parameters.length; i++) { - if (!parameters[i].isAssignableFrom(listenerParameters[i])) { - return false; - } - } - return true; - } - - @Override - protected List<Dependency> constructDependencies() { - final List<Dependency> dependencies = constructDynamicChildrenDependencies(); - for (Dependency dependency : dependencies) { - if (dependency.getOther() == getChild()) { - dependency.setMandatory(true); + try { + Expr listenerExpr = resolveListenersAsMethodReference(listener, parent); + L.w("Method references using '.' is deprecated. Instead of '%s', use '%s::%s'", + toString(), getTarget(), getName()); + return listenerExpr; + } catch (IllegalStateException e) { + if (getGetter() == null) { + L.e("%s", e.getMessage()); } + return this; } - return dependencies; } @Override protected String computeUniqueKey() { - if (mIsObservableField) { - return addTwoWay(join(mName, "..", super.computeUniqueKey())); - } - return addTwoWay(join(mName, ".", super.computeUniqueKey())); - } - - public String getName() { - return mName; + return join(mName, ".", getTarget().getUniqueKey()); } public String getBrName() { @@ -250,26 +142,15 @@ public class FieldAccessExpr extends Expr { } @Override - public void updateExpr(ModelAnalyzer modelAnalyzer) { - try { - Scope.enter(this); - resolveType(modelAnalyzer); - super.updateExpr(modelAnalyzer); - } finally { - Scope.exit(); - } - } - - @Override protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { if (mIsListener) { return modelAnalyzer.findClass(Object.class); } if (mGetter == null) { - Expr child = getChild(); - child.getResolvedType(); - boolean isStatic = child instanceof StaticIdentifierExpr; - ModelClass resolvedType = child.getResolvedType(); + Expr target = getTarget(); + target.getResolvedType(); + boolean isStatic = target instanceof StaticIdentifierExpr; + ModelClass resolvedType = target.getResolvedType(); L.d("resolving %s. Resolved class type: %s", this, resolvedType); mGetter = resolvedType.findGetterOrField(mName, isStatic); @@ -284,25 +165,16 @@ public class FieldAccessExpr extends Expr { if (mGetter.isStatic() && !isStatic) { // found a static method on an instance. register a new one - child.getParents().remove(this); - getChildren().remove(child); - StaticIdentifierExpr staticId = getModel().staticIdentifierFor(resolvedType); - getChildren().add(staticId); - staticId.getParents().add(this); - child = getChild(); // replace the child for the next if stmt + replaceStaticIdentifier(resolvedType); + target = getTarget(); } if (mGetter.resolvedType.isObservableField()) { // Make this the ".get()" and add an extra field access for the observable field - child.getParents().remove(this); - getChildren().remove(child); - - FieldAccessExpr observableField = getModel().observableField(child, mName); - observableField.mGetter = mGetter; - if (hasBindableAnnotations()) { - observableField.mBrName = ExtKt.br(BrNameUtil.brKey(mGetter)); - } + target.getParents().remove(this); + getChildren().remove(target); + FieldAccessExpr observableField = getModel().observableField(target, mName); getChildren().add(observableField); observableField.getParents().add(this); mGetter = mGetter.resolvedType.findGetterOrField("", false); @@ -315,9 +187,17 @@ public class FieldAccessExpr extends Expr { return mGetter.resolvedType; } + protected void replaceStaticIdentifier(ModelClass staticIdentifierType) { + getTarget().getParents().remove(this); + getChildren().remove(getTarget()); + StaticIdentifierExpr staticId = getModel().staticIdentifierFor(staticIdentifierType); + getChildren().add(staticId); + staticId.getParents().add(this); + } + @Override public Expr resolveTwoWayExpressions(Expr parent) { - final Expr child = getChild(); + final Expr child = getTarget(); if (!(child instanceof ViewFieldExpr)) { return this; } @@ -390,25 +270,17 @@ public class FieldAccessExpr extends Expr { @Override protected String asPackage() { - String parentPackage = getChild().asPackage(); + String parentPackage = getTarget().asPackage(); return parentPackage == null ? null : parentPackage + "." + mName; } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { // once we can deprecate using Field.access for callbacks, we can get rid of this since // it will be detected when resolve type is run. Preconditions.checkNotNull(getGetter(), ErrorMessages.CANNOT_RESOLVE_TYPE, this); - KCode code = new KCode(); - if (expand) { - String defaultValue = ModelAnalyzer.getInstance().getDefaultValue( - getResolvedType().toJavaCode()); - code.app("(", getChild().toCode(true)) - .app(" == null) ? ") - .app(defaultValue) - .app(" : "); - } - code.app("", getChild().toCode(expand)).app("."); + KCode code = new KCode() + .app("", getTarget().toCode()).app("."); if (getGetter().type == Callable.Type.FIELD) { return code.app(getGetter().name); } else { @@ -417,25 +289,27 @@ public class FieldAccessExpr extends Expr { } @Override - public KCode toInverseCode(KCode value) { - if (mGetter.setterName == null) { - throw new IllegalStateException("There is no inverse for " + toCode().generate()); - } - KCode castValue = new KCode("(").app(getResolvedType().toJavaCode() + ")(", value).app(")"); - String type = getChild().getResolvedType().toJavaCode(); - KCode code = new KCode("targetObj_."); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + Expr castExpr = model.castExpr(getResolvedType().toJavaCode(), value); + Expr target = getTarget().cloneToModel(model); + Expr result; if (getGetter().type == Callable.Type.FIELD) { - code.app(getGetter().setterName).app(" = ", castValue).app(";"); + result = model.assignment(target, mName, castExpr); } else { - code.app(getGetter().setterName).app("(", castValue).app(")").app(";"); + result = model.methodCall(target, mGetter.setterName, Lists.newArrayList(castExpr)); } - return new KCode() - .app("final ") - .app(type) - .app(" targetObj_ = ", getChild().toCode(true)) - .app(";") - .nl(new KCode("if (targetObj_ != null) {")) - .tab(code) - .nl(new KCode("}")); + return result; + } + + @Override + public Expr cloneToModel(ExprModel model) { + final Expr clonedTarget = getTarget().cloneToModel(model); + return model.field(clonedTarget, mName); + } + + @Override + public String toString() { + String name = mName.isEmpty() ? "get()" : mName; + return getTarget().toString() + '.' + name; } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/FieldAssignmentExpr.java b/compiler/src/main/java/android/databinding/tool/expr/FieldAssignmentExpr.java new file mode 100644 index 00000000..a99df620 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAssignmentExpr.java @@ -0,0 +1,107 @@ +/* + * 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.expr; + +import android.databinding.tool.reflection.ModelAnalyzer; +import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.solver.ExecutionPath; +import android.databinding.tool.writer.KCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is used by inverse field access expressions to assign back to the field. + * For example, <code>@={a.b}</code> is inverted to @{code a.b = value;} + */ +public class FieldAssignmentExpr extends Expr { + final String mName; + + public FieldAssignmentExpr(Expr target, String name, Expr value) { + super(target, value); + mName = name; + } + + @Override + protected String computeUniqueKey() { + return join(getTarget().getUniqueKey(), mName, "=", getValueExpr().getUniqueKey()); + } + + public Expr getTarget() { + return (FieldAccessExpr) getChildren().get(0); + } + + public Expr getValueExpr() { + return getChildren().get(1); + } + + @Override + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return modelAnalyzer.findClass(void.class); + } + + @Override + protected List<Dependency> constructDependencies() { + return constructDynamicChildrenDependencies(); + } + + @Override + protected KCode generateCode() { + return new KCode() + .app("", getTarget().toCode()) + .app("." + mName + " = ", getValueExpr().toCode()); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.assignment(getTarget().cloneToModel(model), mName, getValueExpr()); + } + + @Override + protected String getInvertibleError() { + return "Assignment expressions are inverses of field access expressions."; + } + + @Override + public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) { + Expr child = getTarget(); + List<ExecutionPath> targetPaths = child.toExecutionPath(paths); + + // after this, we need a null check. + List<ExecutionPath> result = new ArrayList<ExecutionPath>(); + if (child instanceof StaticIdentifierExpr) { + result.addAll(toExecutionPathInOrder(paths, child)); + } else { + for (ExecutionPath path : targetPaths) { + final ComparisonExpr cmp = getModel() + .comparison("!=", child, getModel().symbol("null", Object.class)); + path.addPath(cmp); + final ExecutionPath subPath = path.addBranch(cmp, true); + if (subPath != null) { + subPath.addPath(this); + result.add(subPath); + } + } + } + return result; + } + + @Override + public String toString() { + return getTarget().toString() + '.' + mName + " = " + getValueExpr(); + } +} diff --git a/compiler/src/main/java/android/databinding/tool/expr/IdentifierExpr.java b/compiler/src/main/java/android/databinding/tool/expr/IdentifierExpr.java index 9ff4f218..b866218a 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/IdentifierExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/IdentifierExpr.java @@ -23,6 +23,8 @@ import android.databinding.tool.util.Preconditions; import android.databinding.tool.writer.KCode; import android.databinding.tool.writer.LayoutBinderWriterKt; +import com.google.common.collect.Lists; + import java.util.ArrayList; import java.util.List; @@ -78,12 +80,8 @@ public class IdentifierExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { - if (expand) { - return new KCode(LayoutBinderWriterKt.getFieldName(this)); - } else { - return new KCode(LayoutBinderWriterKt.scopedName(this)); - } + protected KCode generateCode() { + return new KCode(LayoutBinderWriterKt.scopedName(this)); } public void setDeclared() { @@ -100,7 +98,20 @@ public class IdentifierExpr extends Expr { } @Override - public KCode toInverseCode(KCode value) { - return new KCode().app(LayoutBinderWriterKt.getSetterName(this)).app("(", value).app(");"); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + String thisType = bindingClassName + ".this"; + Expr target = model.builtInVariable(thisType, bindingClassName, thisType); + return model.methodCall(target, LayoutBinderWriterKt.getSetterName(this), + Lists.newArrayList(value)); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.identifier(mName); + } + + @Override + public String toString() { + return mName; } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/InstanceOfExpr.java b/compiler/src/main/java/android/databinding/tool/expr/InstanceOfExpr.java index 980d6356..8783d0e7 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/InstanceOfExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/InstanceOfExpr.java @@ -37,14 +37,19 @@ public class InstanceOfExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode() - .app("", getExpr().toCode(expand)) + .app("", getExpr().toCode()) .app(" instanceof ") .app(getType().toJavaCode()); } @Override + public Expr cloneToModel(ExprModel model) { + return model.instanceOfOp(getExpr().cloneToModel(model), mTypeStr); + } + + @Override protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { mType = modelAnalyzer.findClass(mTypeStr, getModel().getImports()); return modelAnalyzer.loadPrimitive("boolean"); @@ -67,4 +72,9 @@ public class InstanceOfExpr extends Expr { public String getInvertibleError() { return "two-way binding can't target a value with the 'instanceof' operator"; } + + @Override + public String toString() { + return getExpr().toString() + " instanceof " + mTypeStr; + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java b/compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java index e210f277..13c6cb72 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java @@ -83,7 +83,7 @@ public class LambdaExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { Preconditions .checkNotNull(mCallbackWrapper, "Cannot find the callback method for %s", this); KCode code = new KCode(""); @@ -97,6 +97,11 @@ public class LambdaExpr extends Expr { return code; } + @Override + public Expr cloneToModel(ExprModel model) { + return model.lambdaExpr(getExpr().cloneToModel(model), (CallbackExprModel) model); + } + public String generateConstructor() { return getCallbackWrapper().constructForIdentifier(mCallbackId); } diff --git a/compiler/src/main/java/android/databinding/tool/expr/ListenerExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ListenerExpr.java index 6adf997c..d8d07ff1 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ListenerExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ListenerExpr.java @@ -54,7 +54,7 @@ public class ListenerExpr extends Expr { return mMethod; } - public Expr getChild() { + public Expr getTarget() { return getChildren().get(0); } @@ -64,24 +64,24 @@ public class ListenerExpr extends Expr { @Override public boolean isDynamic() { - return getChild().isDynamic(); + return getTarget().isDynamic(); } @Override protected List<Dependency> constructDependencies() { final List<Dependency> dependencies = new ArrayList<Dependency>(); - Dependency dependency = new Dependency(this, getChild()); + Dependency dependency = new Dependency(this, getTarget()); dependency.setMandatory(true); dependencies.add(dependency); return dependencies; } protected String computeUniqueKey() { - return join(getResolvedType().getCanonicalName(), getChild().computeUniqueKey(), mName); + return join(getResolvedType().getCanonicalName(), getTarget().computeUniqueKey(), mName); } @Override - public KCode generateCode(boolean expand) { + public KCode generateCode() { KCode code = new KCode("("); final int minApi = Math.max(mListenerType.getMinApi(), mMethod.getMinApi()); if (minApi > 1) { @@ -89,7 +89,7 @@ public class ListenerExpr extends Expr { } final String fieldName = LayoutBinderWriterKt.getFieldName(this); final String listenerClassName = LayoutBinderWriterKt.getListenerClassName(this); - final KCode value = getChild().toCode(); + final KCode value = getTarget().toCode(); code.app("((") .app(fieldName) .app(" == null) ? (") @@ -99,7 +99,7 @@ public class ListenerExpr extends Expr { .app("()) : ") .app(fieldName) .app(")"); - if (getChild().isDynamic()) { + if (getTarget().isDynamic()) { code.app(".setValue(", value) .app(")"); } @@ -108,7 +108,17 @@ public class ListenerExpr extends Expr { } @Override + public Expr cloneToModel(ExprModel model) { + return model.listenerExpr(getTarget().cloneToModel(model), mName, mListenerType, mMethod); + } + + @Override public String getInvertibleError() { return "Listeners cannot be the target of a two-way binding"; } + + @Override + public String toString() { + return getTarget().toString() + "::" + mName; + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/MathExpr.java b/compiler/src/main/java/android/databinding/tool/expr/MathExpr.java index 99e3257d..63222de3 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/MathExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/MathExpr.java @@ -18,12 +18,14 @@ package android.databinding.tool.expr; import android.databinding.tool.reflection.ModelAnalyzer; import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.util.Preconditions; import android.databinding.tool.writer.KCode; import java.util.List; public class MathExpr extends Expr { final String mOp; + MathExpr(Expr left, String op, Expr right) { super(left, right); mOp = op; @@ -31,7 +33,7 @@ public class MathExpr extends Expr { @Override protected String computeUniqueKey() { - return addTwoWay(join(getLeft().getUniqueKey(), mOp, getRight().getUniqueKey())); + return join(getLeft().getUniqueKey(), mOp, getRight().getUniqueKey()); } @Override @@ -61,8 +63,12 @@ public class MathExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { - return new KCode().app("", getLeft().toCode(expand)).app(mOp, getRight().toCode(expand)); + protected KCode generateCode() { + return new KCode().app("(", getLeft().toCode()) + .app(") ") + .app(mOp) + .app(" (", getRight().toCode()) + .app(")"); } @Override @@ -81,61 +87,50 @@ public class MathExpr extends Expr { } } - private String inverseCast() { - if (!getLeft().isDynamic()) { - return inverseCast(getRight()); - } else { - return inverseCast(getLeft()); - } - } - - private String inverseCast(Expr expr) { - if (!expr.getResolvedType().isAssignableFrom(getResolvedType())) { - return "(" + getResolvedType() + ")"; - } - return null; - } - @Override - public KCode toInverseCode(KCode value) { - if (!isDynamic()) { - return toCode(); - } + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { final Expr left = getLeft(); final Expr right = getRight(); - final Expr constExpr = left.isDynamic() ? right : left; - final Expr varExpr = left.isDynamic() ? left : right; - final String cast = inverseCast(); - if (cast != null) { - value = new KCode(cast).app("(", value).app(")"); - } + Preconditions.check(left.isDynamic() ^ right.isDynamic(), "Two-way binding of a math " + + "operations requires A signle dynamic expression. Neither or both sides are " + + "dynamic: (%s) %s (%s)", left, mOp, right); + final Expr constExpr = (left.isDynamic() ? right : left).cloneToModel(model); + final Expr newValue; switch (mOp.charAt(0)) { case '+': // const + x = value => x = value - const - return varExpr.toInverseCode(value.app(" - (", constExpr.toCode()).app(")")); + newValue = model.math(value, "-", constExpr); + break; case '*': // const * x = value => x = value / const - return varExpr.toInverseCode(value.app(" / (", constExpr.toCode()).app(")")); + newValue = model.math(value, "/", constExpr); + break; case '-': - if (!left.isDynamic()) { // const - x = value => x = const - value) - return varExpr.toInverseCode(new KCode() - .app("(", constExpr.toCode()) - .app(") - (", value) - .app(")")); + if (!left.isDynamic()) { // const - x = value => x = const - (value) + newValue = model.math(constExpr, "-", value); } else { // x - const = value => x = value + const) - return varExpr.toInverseCode(value.app(" + ", constExpr.toCode())); + newValue = model.math(value, "+", constExpr); } + break; case '/': if (!left.isDynamic()) { // const / x = value => x = const / value - return varExpr.toInverseCode(new KCode("(") - .app("", constExpr.toCode()) - .app(") / (", value) - .app(")")); + newValue = model.math(constExpr, "/", value); } else { // x / const = value => x = value * const - return varExpr.toInverseCode(new KCode("(") - .app("", value) - .app(") * (", constExpr.toCode()) - .app(")")); + newValue = model.math(value, "*", constExpr); } + break; + default: + throw new IllegalStateException("Invalid math operation is not invertible: " + mOp); } - throw new IllegalStateException("Invalid math operation is not invertible: " + mOp); + final Expr varExpr = left.isDynamic() ? left : right; + return varExpr.generateInverse(model, newValue, bindingClassName); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.math(getLeft().cloneToModel(model), mOp, getRight().cloneToModel(model)); + } + + @Override + public String toString() { + return "(" + getLeft() + ") " + mOp + " (" + getRight() + ")"; } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/MethodBaseExpr.java b/compiler/src/main/java/android/databinding/tool/expr/MethodBaseExpr.java new file mode 100644 index 00000000..3b5bd877 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/expr/MethodBaseExpr.java @@ -0,0 +1,153 @@ +/* + * 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.expr; + +import android.databinding.tool.processing.Scope; +import android.databinding.tool.reflection.ModelAnalyzer; +import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.reflection.ModelMethod; +import android.databinding.tool.solver.ExecutionPath; + +import java.util.ArrayList; +import java.util.List; + +public abstract class MethodBaseExpr extends Expr { + String mName; + + MethodBaseExpr(Expr parent, String name) { + super(parent); + mName = name; + } + + public Expr getTarget() { + return getChildren().get(0); + } + + @Override + public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) { + final List<ExecutionPath> targetPaths = getTarget().toExecutionPath(paths); + // after this, we need a null check. + List<ExecutionPath> result = new ArrayList<ExecutionPath>(); + if (getTarget() instanceof StaticIdentifierExpr) { + result.addAll(toExecutionPathInOrder(paths, getTarget())); + } else { + for (ExecutionPath path : targetPaths) { + final ComparisonExpr cmp = getModel() + .comparison("!=", getTarget(), getModel().symbol("null", Object.class)); + path.addPath(cmp); + final ExecutionPath subPath = path.addBranch(cmp, true); + if (subPath != null) { + subPath.addPath(this); + result.add(subPath); + } + } + } + return result; + } + + protected Expr resolveListenersAsMethodReference(ModelClass listener, Expr parent) { + final Expr target = getTarget(); + final ModelClass childType = target.getResolvedType(); + if (listener == null) { + throw new IllegalStateException( + String.format("Could not resolve %s as a listener.", this)); + } + + List<ModelMethod> abstractMethods = listener.getAbstractMethods(); + int numberOfAbstractMethods = abstractMethods == null ? 0 : abstractMethods.size(); + if (numberOfAbstractMethods != 1) { + throw new IllegalStateException(String.format( + "Could not find accessor %s.%s and %s has %d abstract methods, so is" + + " not resolved as a listener", + childType.getCanonicalName(), mName, + listener.getCanonicalName(), numberOfAbstractMethods)); + } + + // Look for a signature matching the abstract method + final ModelMethod listenerMethod = abstractMethods.get(0); + final ModelClass[] listenerParameters = listenerMethod.getParameterTypes(); + boolean isStatic = getTarget() instanceof StaticIdentifierExpr; + List<ModelMethod> methods = childType.findMethods(mName, isStatic); + for (ModelMethod method : methods) { + if (acceptsParameters(method, listenerParameters) && + method.getReturnType(null).equals(listenerMethod.getReturnType(null))) { + target.getParents().remove(this); + resetResolvedType(); + // replace this with ListenerExpr in parent + Expr listenerExpr = getModel().listenerExpr(getTarget(), mName, listener, + listenerMethod); + if (parent != null) { + int index; + while ((index = parent.getChildren().indexOf(this)) != -1) { + parent.getChildren().set(index, listenerExpr); + } + } + if (getModel().mBindingExpressions.contains(this)) { + getModel().bindingExpr(listenerExpr); + } + getParents().remove(parent); + if (getParents().isEmpty()) { + getModel().removeExpr(this); + } + return listenerExpr; + } + } + + throw new IllegalStateException(String.format( + "Listener class %s with method %s did not match signature of any method %s", + listener.getCanonicalName(), listenerMethod.getName(), this)); + } + + private boolean acceptsParameters(ModelMethod method, ModelClass[] listenerParameters) { + ModelClass[] parameters = method.getParameterTypes(); + if (parameters.length != listenerParameters.length) { + return false; + } + for (int i = 0; i < parameters.length; i++) { + if (!parameters[i].isAssignableFrom(listenerParameters[i])) { + return false; + } + } + return true; + } + + @Override + protected List<Dependency> constructDependencies() { + final List<Dependency> dependencies = constructDynamicChildrenDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.getOther() == getTarget()) { + dependency.setMandatory(true); + } + } + return dependencies; + } + + public String getName() { + return mName; + } + + @Override + public void updateExpr(ModelAnalyzer modelAnalyzer) { + try { + Scope.enter(this); + resolveType(modelAnalyzer); + super.updateExpr(modelAnalyzer); + } finally { + Scope.exit(); + } + } +} diff --git a/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java b/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java index 71822fb5..6acbfa2e 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java @@ -36,8 +36,9 @@ import static android.databinding.tool.reflection.Callable.STATIC; public class MethodCallExpr extends Expr { final String mName; - Callable mGetter; + // Allow protected calls -- only used for ViewDataBinding methods. + private boolean mAllowProtected; static List<Expr> concat(Expr e, List<Expr> list) { List<Expr> merged = new ArrayList<Expr>(); @@ -64,18 +65,24 @@ public class MethodCallExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { KCode code = new KCode() - .app("", getTarget().toCode(expand)) + .app("", getTarget().toCode()) .app(".") .app(getGetter().name) .app("("); - appendArgs(code, expand); + appendArgs(code); code.app(")"); return code; } - private void appendArgs(KCode code, boolean expand) { + @Override + public Expr cloneToModel(ExprModel model) { + return model.methodCall(getTarget().cloneToModel(model), mName, + cloneToModel(model, getArgs())); + } + + private void appendArgs(KCode code) { boolean first = true; for (Expr arg : getArgs()) { if (first) { @@ -83,7 +90,7 @@ public class MethodCallExpr extends Expr { } else { code.app(", "); } - code.app("", arg.toCode(expand)); + code.app("", arg.toCode()); } } @@ -122,12 +129,20 @@ public class MethodCallExpr extends Expr { Expr target = getTarget(); boolean isStatic = target instanceof StaticIdentifierExpr; - ModelMethod method = target.getResolvedType().getMethod(mName, args, isStatic); + ModelMethod method = target.getResolvedType().getMethod(mName, args, isStatic, + mAllowProtected); if (method == null) { - String message = "cannot find method '" + mName + "' in class " + + StringBuilder argTypes = new StringBuilder(); + for (ModelClass arg : args) { + if (argTypes.length() != 0) { + argTypes.append(", "); + } + argTypes.append(arg.toJavaCode()); + } + String message = "cannot find method '" + mName + "(" + argTypes + ")' in class " + target.getResolvedType().toJavaCode(); IllegalArgumentException e = new IllegalArgumentException(message); - L.e(e, "cannot find method %s in class %s", mName, + L.e(e, "cannot find method %s(%s) in class %s", mName, argTypes, target.getResolvedType().toJavaCode()); throw e; } @@ -185,8 +200,31 @@ public class MethodCallExpr extends Expr { return mGetter; } + public void setAllowProtected() { + mAllowProtected = true; + } + @Override public String getInvertibleError() { return "Method calls may not be used in two-way expressions"; } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(getTarget()) + .append('.') + .append(mName) + .append('('); + final List<Expr> args = getArgs(); + for (int i = 0; i < args.size(); i++) { + Expr arg = args.get(i); + if (i != 0) { + buf.append(", "); + } + buf.append(arg); + } + buf.append(')'); + return buf.toString(); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/MethodReferenceExpr.java b/compiler/src/main/java/android/databinding/tool/expr/MethodReferenceExpr.java new file mode 100644 index 00000000..9b717e83 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/expr/MethodReferenceExpr.java @@ -0,0 +1,85 @@ +/* + * 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.expr; + +import android.databinding.tool.reflection.ModelAnalyzer; +import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.util.L; +import android.databinding.tool.util.Preconditions; +import android.databinding.tool.writer.KCode; + +public class MethodReferenceExpr extends MethodBaseExpr { + + MethodReferenceExpr(Expr parent, String name) { + super(parent, name); + } + + @Override + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + return modelAnalyzer.findClass(Object.class); + } + + @Override + protected String computeUniqueKey() { + return join(mName, "::", getTarget().getUniqueKey()); + } + + @Override + public String getInvertibleError() { + return "Listeners do not support two-way binding"; + } + + @Override + public boolean isDynamic() { + return true; + } + + @Override + public Expr resolveListeners(ModelClass listener, Expr parent) { + try { + return resolveListenersAsMethodReference(listener, parent); + } catch (IllegalStateException e) { + L.e("%s", e.getMessage()); + return this; + } + } + + @Override + protected KCode generateCode() { + // once we can deprecate using Field.access for callbacks, we can get rid of this since + // it will be detected when resolve type is run. + Preconditions.check(false, "Cannot generate code for unresolved method reference %s", this); + return null; + } + + @Override + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + Preconditions.check(false, "Method references do not have an inverse"); + return this; + } + + @Override + public Expr cloneToModel(ExprModel model) { + final Expr clonedTarget = getTarget().cloneToModel(model); + return model.methodReference(clonedTarget, mName); + } + + @Override + public String toString() { + return getTarget().toString() + "::" + mName; + } +} diff --git a/compiler/src/main/java/android/databinding/tool/expr/ObservableFieldExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ObservableFieldExpr.java new file mode 100644 index 00000000..22d81453 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/expr/ObservableFieldExpr.java @@ -0,0 +1,80 @@ +/* + * 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.expr; + +import android.databinding.tool.ext.ExtKt; +import android.databinding.tool.reflection.ModelAnalyzer; +import android.databinding.tool.reflection.ModelClass; +import android.databinding.tool.util.BrNameUtil; +import android.databinding.tool.util.L; + +public class ObservableFieldExpr extends FieldAccessExpr { + + ObservableFieldExpr(Expr parent, String name) { + super(parent, name); + } + + @Override + public Expr resolveListeners(ModelClass listener, Expr parent) { + return this; // ObservableFields aren't listeners + } + + @Override + protected String computeUniqueKey() { + return join(mName, "..", getTarget().getUniqueKey()); + } + + @Override + protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { + if (mGetter == null) { + Expr target = getTarget(); + target.getResolvedType(); + boolean isStatic = target instanceof StaticIdentifierExpr; + ModelClass resolvedType = target.getResolvedType(); + L.d("resolving %s. Resolved class type: %s", this, resolvedType); + + mGetter = resolvedType.findGetterOrField(mName, isStatic); + + if (mGetter == null) { + L.e("Could not find accessor %s.%s", resolvedType.getCanonicalName(), mName); + return null; + } + + if (mGetter.isStatic() && !isStatic) { + // found a static method on an instance. register a new one + replaceStaticIdentifier(resolvedType); + } + if (hasBindableAnnotations()) { + mBrName = ExtKt.br(BrNameUtil.brKey(getGetter())); + } else { + mBrName = ExtKt.br(mName); + } + } + return mGetter.resolvedType; + } + + @Override + public Expr cloneToModel(ExprModel model) { + final Expr clonedTarget = getTarget().cloneToModel(model); + return model.observableField(clonedTarget, mName); + } + + @Override + public String toString() { + return getTarget().toString() + '.' + mName; + } +} diff --git a/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java index 752cb9f8..2ecf5fb0 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java @@ -120,20 +120,22 @@ public class ResourceExpr extends Expr { @Override protected String computeUniqueKey() { - String base; - if (mPackage == null) { - base = "@" + mResourceType + "/" + mResourceId; - } else { - base = "@" + "android:" + mResourceType + "/" + mResourceId; - } + String base = toString(); return join(base, computeChildrenKey()); } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode(toJava()); } + @Override + public Expr cloneToModel(ExprModel model) { + String pkg = mPackage.isEmpty() ? "" : "android"; + return model.resourceExpr(pkg, mResourceType, mResourceId, + cloneToModel(model, getChildren())); + } + public String getResourceId() { return mPackage + "R." + getResourceObject() + "." + mResourceId; } @@ -211,4 +213,13 @@ public class ResourceExpr extends Expr { } return rFileObject; } + + @Override + public String toString() { + if (mPackage == null) { + return "@" + mResourceType + "/" + mResourceId; + } else { + return "@" + "android:" + mResourceType + "/" + mResourceId; + } + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/StaticIdentifierExpr.java b/compiler/src/main/java/android/databinding/tool/expr/StaticIdentifierExpr.java index 7618e946..0d36f2a1 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/StaticIdentifierExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/StaticIdentifierExpr.java @@ -41,11 +41,17 @@ public class StaticIdentifierExpr extends IdentifierExpr { } @Override - public KCode toInverseCode(KCode value) { + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { throw new IllegalStateException("StaticIdentifierExpr is not invertible."); } + @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode(getResolvedType().toJavaCode()); } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.staticIdentifier(mName); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java b/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java index ee3a1677..388d2240 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java @@ -20,7 +20,6 @@ import android.databinding.tool.reflection.ModelAnalyzer; import android.databinding.tool.reflection.ModelClass; import android.databinding.tool.solver.ExecutionPath; import android.databinding.tool.writer.KCode; -import android.databinding.tool.writer.LayoutBinderWriterKt; import java.util.ArrayList; import java.util.List; @@ -55,11 +54,16 @@ public class SymbolExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode(getText()); } @Override + public Expr cloneToModel(ExprModel model) { + return model.symbol(mText, mType); + } + + @Override protected List<Dependency> constructDependencies() { return new ArrayList<Dependency>(); } @@ -76,4 +80,9 @@ public class SymbolExpr extends Expr { } return super.toExecutionPath(paths); } + + @Override + public String toString() { + return mText; + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java b/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java index a23e6c22..856cab04 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java @@ -124,26 +124,35 @@ public class TernaryExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { return new KCode() - .app("", getPred().toCode(expand)) - .app(" ? ", getIfTrue().toCode(expand)) - .app(" : ", getIfFalse().toCode(expand)); + .app("(", getPred().toCode()) + .app(") ? (", getIfTrue().toCode()) + .app(") : (", getIfFalse().toCode()) + .app(")"); } @Override - public KCode toInverseCode(KCode variable) { - return new KCode() - .app("if (", getPred().toCode(true)) - .app(") {") - .tab(getIfTrue().toInverseCode(variable)) - .nl(new KCode("} else {")) - .tab(getIfFalse().toInverseCode(variable)) - .nl(new KCode("}")); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + final Expr pred = getPred().cloneToModel(model); + final Expr ifTrue = getIfTrue().generateInverse(model, value, bindingClassName); + final Expr ifFalse = getIfFalse().generateInverse(model, value, bindingClassName); + return model.ternary(pred, ifTrue, ifFalse); + } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.ternary(getPred().cloneToModel(model), getIfTrue().cloneToModel(model), + getIfFalse().cloneToModel(model)); } @Override public boolean isConditional() { return true; } + + @Override + public String toString() { + return getPred().toString() + " ? " + getIfTrue() + " : " + getIfFalse(); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java b/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java index 1a656732..c14cdd6c 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java @@ -45,12 +45,17 @@ public class TwoWayListenerExpr extends Expr { } @Override - protected KCode generateCode(boolean expand) { + protected KCode generateCode() { final String fieldName = LayoutBinderWriterKt.getFieldName(mInverseBinding); return new KCode(fieldName); } @Override + public Expr cloneToModel(ExprModel model) { + return model.twoWayListenerExpr(mInverseBinding); + } + + @Override protected String computeUniqueKey() { return "event(" + mInverseBinding.getEventAttribute() + ", " + System.identityHashCode(mInverseBinding) + ")"; diff --git a/compiler/src/main/java/android/databinding/tool/expr/UnaryExpr.java b/compiler/src/main/java/android/databinding/tool/expr/UnaryExpr.java index 881a352c..18e5985f 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/UnaryExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/UnaryExpr.java @@ -36,17 +36,22 @@ public class UnaryExpr extends Expr { @Override protected String computeUniqueKey() { - return addTwoWay(join(getOpStr(), getExpr().getUniqueKey())); + return join(getOpStr(), getExpr().getUniqueKey()); } @Override - public KCode toInverseCode(KCode value) { - return getExpr().toInverseCode(new KCode().app(mOp, value)); + public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) { + return model.unary(mOp, getExpr().generateInverse(model, value, bindingClassName)); } @Override - protected KCode generateCode(boolean expand) { - return new KCode().app(getOp(), getExpr().toCode(expand)); + public Expr cloneToModel(ExprModel model) { + return model.unary(mOp, getExpr().cloneToModel(model)); + } + + @Override + protected KCode generateCode() { + return new KCode().app(getOp(), getExpr().toCode()); } @Override @@ -76,4 +81,9 @@ public class UnaryExpr extends Expr { public Expr getExpr() { return getChildren().get(0); } + + @Override + public String toString() { + return mOp + getExpr(); + } } diff --git a/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java b/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java index 0a6b15b1..59c0dbeb 100644 --- a/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java +++ b/compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java @@ -25,7 +25,7 @@ public class ViewFieldExpr extends BuiltInVariableExpr { private final BindingTarget mBindingTarget; ViewFieldExpr(BindingTarget bindingTarget) { - super(LayoutBinderWriterKt.getFieldName(bindingTarget), initialType(bindingTarget), + super(LayoutBinderWriterKt.getFieldName(bindingTarget), bindingTarget.getInterfaceType(), LayoutBinderWriterKt.getFieldName(bindingTarget)); mBindingTarget = bindingTarget; } @@ -35,12 +35,6 @@ public class ViewFieldExpr extends BuiltInVariableExpr { return "View fields may not be the target of two-way binding"; } - private static String initialType(BindingTarget bindingTarget) { - return bindingTarget.isBinder() - ? "android.databinding.ViewDataBinding" - : bindingTarget.getInterfaceType(); - } - public BindingTarget getBindingTarget() { return mBindingTarget; } @@ -49,8 +43,13 @@ public class ViewFieldExpr extends BuiltInVariableExpr { protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { final ModelClass type = modelAnalyzer.findClass(mBindingTarget.getInterfaceType(), null); if (type == null) { - return modelAnalyzer.findClass("android.databinding.ViewDataBinding", null); + return modelAnalyzer.findClass(ModelAnalyzer.VIEW_DATA_BINDING, null); } return type; } + + @Override + public Expr cloneToModel(ExprModel model) { + return model.viewFieldExpr(mBindingTarget); + } } diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClass.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClass.java new file mode 100644 index 00000000..4759a9a6 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClass.java @@ -0,0 +1,217 @@ +/* + * 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.util.StringUtils; + +import java.util.Arrays; +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#injectViewDataBinding(String, Map, Map) + */ +public class InjectedBindingClass extends ModelClass { + private final String mClassName; + private final String mSuperClass; + private final Map<String, String> mVariables; + private final Map<String, String> mFields; + + public InjectedBindingClass(String className, String superClass, Map<String, String> variables, + Map<String, String> fields) { + mClassName = className; + mSuperClass = superClass; + mVariables = variables; + mFields = fields; + } + + @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 + protected ModelField[] getDeclaredFields() { + ModelClass superClass = getSuperclass(); + final ModelField[] superFields = superClass.getDeclaredFields(); + final int fieldCount = superFields.length + mFields.size(); + final ModelField[] fields = Arrays.copyOf(superFields, fieldCount); + int index = superFields.length; + for (String fieldName : mFields.keySet()) { + final String fieldType = mFields.get(fieldName); + fields[index++] = new InjectedBindingClassField(fieldName, fieldType); + } + return fields; + } + + @Override + protected ModelMethod[] getDeclaredMethods() { + ModelClass superClass = getSuperclass(); + final ModelMethod[] superMethods = superClass.getDeclaredMethods(); + final int methodCount = superMethods.length + (mVariables.size() * 2); + final ModelMethod[] methods = Arrays.copyOf(superMethods, methodCount); + int index = superMethods.length; + for (String variableName : mVariables.keySet()) { + final String variableType = mVariables.get(variableName); + final String getterName = "get" + StringUtils.capitalize(variableName); + methods[index++] = new InjectedBindingClassMethod(this, getterName, variableType, null); + final String setterName = "set" + StringUtils.capitalize(variableName); + methods[index++] = new InjectedBindingClassMethod(this, setterName, "void", variableType); + } + return methods; + } + + @Override + public String toString() { + return "Injected Class: " + mClassName; + } +} diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassField.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassField.java new file mode 100644 index 00000000..d15cc908 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassField.java @@ -0,0 +1,65 @@ +/* + * 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 java.util.Map; + +/** + * A class that can be used by ModelAnalyzer without any backing model. This is used + * for fields on ViewDataBinding subclasses that haven't been generated yet. + * + * @see ModelAnalyzer#injectViewDataBinding(String, Map, Map) + */ +public class InjectedBindingClassField extends ModelField { + private final String mType; + private final String mName; + + public InjectedBindingClassField(String name, String type) { + mName = name; + mType = type; + } + + @Override + public boolean isBindable() { + return false; + } + + @Override + public String getName() { + return mName; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isFinal() { + return true; + } + + @Override + public ModelClass getFieldType() { + return ModelAnalyzer.getInstance().findClass(mType, null); + } +} diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassMethod.java new file mode 100644 index 00000000..20e24824 --- /dev/null +++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedBindingClassMethod.java @@ -0,0 +1,111 @@ +/* + * 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 java.util.List; +import java.util.Map; + +/** + * A class that can be used by ModelAnalyzer without any backing model. This is used + * for methods on ViewDataBinding subclasses that haven't been generated yet. + * + * @see ModelAnalyzer#injectViewDataBinding(String, Map, Map) + */ +public class InjectedBindingClassMethod extends ModelMethod { + private final InjectedBindingClass mContainingClass; + private final String mName; + private final String mReturnType; + private final String mParameter; + + public InjectedBindingClassMethod(InjectedBindingClass containingClass, String name, String returnType, + String parameter) { + mContainingClass = containingClass; + mName = name; + mReturnType = returnType; + mParameter = parameter; + } + + @Override + public ModelClass getDeclaringClass() { + return mContainingClass; + } + + @Override + public ModelClass[] getParameterTypes() { + if (mParameter != null) { + ModelClass parameterType = ModelAnalyzer.getInstance().findClass(mParameter, null); + return new ModelClass[] { parameterType }; + } + return new ModelClass[0]; + } + + @Override + public String getName() { + return mName; + } + + @Override + public ModelClass getReturnType(List<ModelClass> args) { + ModelClass returnType = ModelAnalyzer.getInstance().findClass(mReturnType, null); + return returnType; + } + + @Override + public boolean isVoid() { + return getReturnType().isVoid(); + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public boolean isProtected() { + return false; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isAbstract() { + return true; + } + + @Override + public boolean isBindable() { + return false; + } + + @Override + public int getMinApi() { + return 0; + } + + @Override + public String getJniDescription() { + return TypeUtil.getInstance().getDescription(this); + } + + @Override + public boolean isVarArgs() { + return false; + } +} diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java index 6b4bf876..8943200b 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java @@ -19,6 +19,7 @@ import android.databinding.tool.reflection.annotation.AnnotationAnalyzer; import android.databinding.tool.util.L; import android.databinding.tool.util.Preconditions; +import java.util.HashMap; import java.util.Map; import javax.annotation.processing.ProcessingEnvironment; @@ -82,6 +83,8 @@ public abstract class ModelAnalyzer { private ModelClass mViewStubType; private static ModelAnalyzer sAnalyzer; + private final Map<String, InjectedBindingClass> mInjectedClasses = + new HashMap<String, InjectedBindingClass>(); protected void setInstance(ModelAnalyzer analyzer) { sAnalyzer = analyzer; @@ -218,12 +221,27 @@ public abstract class ModelAnalyzer { return "null"; } - public abstract ModelClass findClass(String className, Map<String, String> imports); + public final ModelClass findClass(String className, Map<String, String> imports) { + if (mInjectedClasses.containsKey(className)) { + return mInjectedClasses.get(className); + } + return findClassInternal(className, imports); + } + + public abstract ModelClass findClassInternal(String className, Map<String, String> imports); public abstract ModelClass findClass(Class classType); public abstract TypeUtil createTypeUtil(); + public ModelClass injectViewDataBinding(String className, Map<String, String> variables, + Map<String, String> fields) { + InjectedBindingClass injectedClass = new InjectedBindingClass(className, + ModelAnalyzer.VIEW_DATA_BINDING, variables, fields); + mInjectedClasses.put(className, injectedClass); + return injectedClass; + } + ModelClass[] getListTypes() { if (mListTypes == null) { mListTypes = new ModelClass[LIST_CLASS_NAMES.length]; diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java index 35eaf6fa..243fcdee 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java @@ -235,23 +235,27 @@ public abstract class ModelClass { public abstract boolean isAssignableFrom(ModelClass that); /** - * Returns an array containing all public methods on the type represented by this ModelClass - * with the name <code>name</code> and can take the passed-in types as arguments. This will - * also work if the arguments match VarArgs parameter. + * Returns an array containing all public methods (or protected if allowProtected is true) + * on the type represented by this ModelClass with the name <code>name</code> and can + * take the passed-in types as arguments. This will also work if the arguments match + * VarArgs parameter. * * @param name The name of the method to find. * @param args The types that the method should accept. * @param staticOnly Whether only static methods should be returned or both instance methods * and static methods are valid. + * @param allowProtected true if the method can be protected as well as public. * * @return An array containing all public methods with the name <code>name</code> and taking * <code>args</code> parameters. */ - public ModelMethod[] getMethods(String name, List<ModelClass> args, boolean staticOnly) { + public ModelMethod[] getMethods(String name, List<ModelClass> args, boolean staticOnly, + boolean allowProtected) { ModelMethod[] methods = getDeclaredMethods(); ArrayList<ModelMethod> matching = new ArrayList<ModelMethod>(); for (ModelMethod method : methods) { - if (method.isPublic() && (!staticOnly || method.isStatic()) && + if ((method.isPublic() || (allowProtected && method.isProtected())) && + (!staticOnly || method.isStatic()) && name.equals(method.getName()) && method.acceptsArguments(args)) { matching.add(method); } @@ -288,9 +292,11 @@ public abstract class ModelClass { * @param args The arguments that the method should accept * @param staticOnly true if the returned method must be static or false if it does not * matter. + * @param allowProtected true if the method can be protected as well as public. */ - public ModelMethod getMethod(String name, List<ModelClass> args, boolean staticOnly) { - ModelMethod[] methods = getMethods(name, args, staticOnly); + public ModelMethod getMethod(String name, List<ModelClass> args, boolean staticOnly, + boolean allowProtected) { + ModelMethod[] methods = getMethods(name, args, staticOnly, allowProtected); L.d("looking methods for %s. static only ? %s . method count: %d", name, staticOnly, methods.length); for (ModelMethod method : methods) { @@ -397,7 +403,8 @@ public abstract class ModelClass { name }; for (String methodName : methodNames) { - ModelMethod[] methods = getMethods(methodName, new ArrayList<ModelClass>(), staticOnly); + ModelMethod[] methods = + getMethods(methodName, new ArrayList<ModelClass>(), staticOnly, false); for (ModelMethod method : methods) { if (method.isPublic() && (!staticOnly || method.isStatic()) && !method.getReturnType(Arrays.asList(method.getParameterTypes())).isVoid()) { @@ -465,7 +472,8 @@ public abstract class ModelClass { name }; for (String methodName : methodNames) { - ModelMethod[] methods = getMethods(methodName, new ArrayList<ModelClass>(), false); + ModelMethod[] methods = + getMethods(methodName, new ArrayList<ModelClass>(), false, false); for (ModelMethod method : methods) { if (method.isPublic() && !method.isStatic() && !method.getReturnType(Arrays.asList(method.getParameterTypes())).isVoid()) { diff --git a/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java index 87ae28d4..5bd214e3 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java @@ -32,6 +32,8 @@ public abstract class ModelMethod { public abstract boolean isPublic(); + public abstract boolean isProtected(); + public abstract boolean isStatic(); public abstract boolean isAbstract(); @@ -76,6 +78,9 @@ public abstract class ModelMethod { for (int i = 0; i < args.size(); i++) { ModelClass parameterType = getParameter(i, parameterTypes); ModelClass arg = args.get(i); + if (parameterType.isIncomplete()) { + parameterType = parameterType.erasure(); + } if (!parameterType.isAssignableFrom(arg) && !isImplicitConversion(arg, parameterType)) { parametersMatch = false; break; diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java index ef52880b..80664cda 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java @@ -26,7 +26,6 @@ import java.util.Map; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; @@ -85,7 +84,7 @@ public class AnnotationAnalyzer extends ModelAnalyzer { } @Override - public AnnotationClass findClass(String className, Map<String, String> imports) { + public ModelClass findClassInternal(String className, Map<String, String> imports) { className = className.trim(); int numDimensions = 0; while (className.endsWith("[]")) { @@ -121,7 +120,8 @@ public class AnnotationAnalyzer extends ModelAnalyzer { ArrayList<String> templateParameters = splitTemplateParameters(paramStr); TypeMirror[] typeArgs = new TypeMirror[templateParameters.size()]; for (int i = 0; i < typeArgs.length; i++) { - final AnnotationClass clazz = findClass(templateParameters.get(i), imports); + final AnnotationClass clazz = (AnnotationClass) + findClass(templateParameters.get(i), imports); if (clazz == null) { L.e("cannot find type argument for %s in %s", templateParameters.get(i), baseClassName); diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.java index ce17c4b0..feae09db 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.java @@ -286,13 +286,17 @@ class AnnotationClass extends ModelClass { @Override public boolean isAssignableFrom(ModelClass that) { - if (that == null) { + ModelClass other = that; + while (other != null && !(other instanceof AnnotationClass)) { + other = other.getSuperclass(); + } + if (other == null) { return false; } - if (equals(that)) { + if (equals(other)) { return true; } - AnnotationClass thatAnnotationClass = (AnnotationClass) that; + AnnotationClass thatAnnotationClass = (AnnotationClass) other; return getTypeUtils().isAssignable(thatAnnotationClass.mTypeMirror, this.mTypeMirror); } diff --git a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java index d7caa452..66c1dbc5 100644 --- a/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java +++ b/compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java @@ -127,6 +127,11 @@ class AnnotationMethod extends ModelMethod { } @Override + public boolean isProtected() { + return mExecutableElement.getModifiers().contains(Modifier.PROTECTED); + } + + @Override public boolean isStatic() { return mExecutableElement.getModifiers().contains(Modifier.STATIC); } 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 95688100..90f75e2f 100644 --- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java +++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java @@ -714,7 +714,7 @@ public class SetterStore { if (viewType == null) { return null; } else if (viewType.isViewDataBinding()) { - return new ViewDataBindingGetterCall(attribute); + return new ViewDataBindingGetterCall(viewType, attribute); } attribute = stripNamespace(attribute); @@ -758,11 +758,11 @@ public class SetterStore { viewType.getCanonicalName()); } else { bestMethod.call = new AdapterGetter(inverseDescription, - setters.get(0)); + setters.get(0), key.valueType); } } else { bestMethod.call = new AdapterGetter(inverseDescription, - eventCall); + eventCall, key.valueType); } } @@ -1271,6 +1271,7 @@ public class SetterStore { } private static class IntermediateV2 extends IntermediateV1 { + private static final long serialVersionUID = 0xA45C2EB637E35C07L; public final HashMap<String, HashMap<AccessorKey, InverseDescription>> inverseAdapters = new HashMap<String, HashMap<AccessorKey, InverseDescription>>(); public final HashMap<String, HashMap<String, InverseDescription>> inverseMethods = @@ -1635,6 +1636,8 @@ public class SetterStore { public interface BindingGetterCall { String toJava(String componentExpression, String viewExpression); + String getGetterType(); + int getMinApi(); String getBindingAdapterInstanceClass(); @@ -1650,12 +1653,14 @@ public class SetterStore { private final String mGetter; private final BindingSetterCall mEventSetter; private final String mAttribute; + private final ModelClass mBindingClass; - public ViewDataBindingGetterCall(String attribute) { + public ViewDataBindingGetterCall(ModelClass bindingClass, String attribute) { final int colonIndex = attribute.indexOf(':'); mAttribute = attribute.substring(colonIndex + 1); mGetter = "get" + StringUtils.capitalize(mAttribute); mEventSetter = new ViewDataBindingEventSetter(); + mBindingClass = bindingClass; } @Override @@ -1664,6 +1669,11 @@ public class SetterStore { } @Override + public String getGetterType() { + return mBindingClass.findInstanceGetter(mGetter).getReturnType().toJavaCode(); + } + + @Override public int getMinApi() { return 0; } @@ -1716,6 +1726,11 @@ public class SetterStore { } @Override + public String getGetterType() { + return mMethod.getReturnType().toJavaCode(); + } + + @Override public int getMinApi() { return mMethod.getMinApi(); } @@ -1734,10 +1749,18 @@ public class SetterStore { private final InverseDescription mInverseDescription; private String mBindingAdapterCall; private final BindingSetterCall mEventCall; + private final String mGetterType; - public AdapterGetter(InverseDescription description, BindingSetterCall eventCall) { + public AdapterGetter(InverseDescription description, BindingSetterCall eventCall, + String getterType) { mInverseDescription = description; mEventCall = eventCall; + mGetterType = getterType; + } + + @Override + public String getGetterType() { + return mGetterType; } @Override diff --git a/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt b/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt index 618c1413..84884516 100644 --- a/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt +++ b/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt @@ -30,7 +30,7 @@ fun Expr.shouldLocalizeInCallbacks() = canBeEvaluatedToAVariable() && !resolvedT fun CallbackExprModel.localizeGlobalVariables(vararg ignore: Expr): KCode = kcode("// localize variables for thread safety") { // puts all variables in this model to local values. mExprMap.values.filter { it.shouldLocalizeInCallbacks() && !ignore.contains(it) }.forEach { - nl("// ${it.uniqueKey}") + nl("// ${it.toString()}") nl("${it.resolvedType.toJavaCode()} ${it.scopedName()} = ${if (it.isVariable()) it.fieldName else it.defaultValue};") } } diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt index 51c1cc95..6147519b 100644 --- a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt +++ b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt @@ -206,7 +206,6 @@ val Expr.callbackLocalName by lazyProp { expr : Expr -> else expr.toCode().generate() } - val Expr.executePendingLocalName by lazyProp { expr : Expr -> if(expr.needsLocalField) "${expr.model.ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD, false)}" else expr.toCode().generate() @@ -366,7 +365,12 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { nl(declareVariables()) nl(declareBoundValues()) nl(declareListeners()) - nl(declareInverseBindingImpls()); + try { + Scope.enter(Scope.GLOBAL) + nl(declareInverseBindingImpls()); + } finally { + Scope.exit() + } nl(declareConstructor(minSdk)) nl(declareInvalidateAll()) nl(declareHasPendingBindings()) @@ -853,14 +857,30 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { className = "android.databinding.InverseBindingListener" param = "" } - nl("private $className ${inverseBinding.fieldName} = new $className($param) {") { - tab("@Override") - tab("public void onChange() {") { - tab(inverseBinding.toJavaCode("mBindingComponent", mDirtyFlags)).app(";"); + block("private $className ${inverseBinding.fieldName} = new $className($param)") { + nl("@Override") + block("public void onChange()") { + if (inverseBinding.inverseExpr != null) { + val valueExpr = inverseBinding.variableExpr + val getterCall = inverseBinding.getterCall + nl("// Inverse of ${inverseBinding.expr}") + nl("// is ${inverseBinding.inverseExpr}") + nl("${valueExpr.resolvedType.toJavaCode()} ${valueExpr.name} = ${getterCall.toJava("mBindingComponent", target.fieldName)};") + nl(inverseBinding.callbackExprModel.localizeGlobalVariables(valueExpr)) + nl(inverseBinding.executionPath.toCode()) + } else { + block("synchronized(this)") { + val flagSet = inverseBinding.chainedExpressions.fold(FlagSet(), { initial, expr -> + initial.or(FlagSet(expr.id)) + }) + mDirtyFlags.mapOr(flagSet) { suffix, index -> + tab("${mDirtyFlags.localValue(index)} |= ${flagSet.binaryCode(index)};") + } + } + nl("requestRebind();") + } } - tab("}") - } - nl("};") + }.app(";") } } } @@ -999,7 +1019,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { if (!assignedValues.isEmpty()) { val assignment = kcode("") { assignedValues.forEach { expr: Expr -> - tab("// read ${expr.uniqueKey}") + tab("// read ${expr}") tab("${expr.executePendingLocalName}").app(" = ", expr.toFullCode()).app(";") } } @@ -1018,7 +1038,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { it.value.forEach { expr: Expr -> justRead.add(expr) - L.d("%s / readWithDependants %s", className, expr.uniqueKey); + L.d("%s / readWithDependants %s", className, expr); L.d("flag set:%s . inherited flags: %s. need another if: %s", flagSet, inheritedFlags, needsIfWrapper); // if I am the condition for an expression, set its flag @@ -1138,9 +1158,9 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { extendsImplements = "extends" } nl("public static class ${expr.listenerClassName} $extendsImplements ${listenerType.canonicalName}{") { - if (expr.child.isDynamic) { - tab("private ${expr.child.resolvedType.toJavaCode()} value;") - tab("public ${expr.listenerClassName} setValue(${expr.child.resolvedType.toJavaCode()} value) {") { + if (expr.target.isDynamic) { + tab("private ${expr.target.resolvedType.toJavaCode()} value;") + tab("public ${expr.listenerClassName} setValue(${expr.target.resolvedType.toJavaCode()} value) {") { tab("this.value = value;") tab("return value == null ? null : this;") } @@ -1156,10 +1176,10 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) { }.joinToString(", ") }) {") { val obj : String - if (expr.child.isDynamic) { + if (expr.target.isDynamic) { obj = "this.value" } else { - obj = expr.child.toCode().generate(); + obj = expr.target.toCode().generate(); } val returnStr : String if (!returnType.isVoid) { diff --git a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java index 97331cfa..84b032af 100644 --- a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java +++ b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java @@ -143,8 +143,8 @@ public class ExpressionVisitorTest { @Test public void testInheritedFieldResolution() { final FieldAccessExpr parsed = parse("myStr.length", FieldAccessExpr.class); - assertTrue(parsed.getChild() instanceof IdentifierExpr); - final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); + assertTrue(parsed.getTarget() instanceof IdentifierExpr); + final IdentifierExpr id = (IdentifierExpr) parsed.getTarget(); id.setUserDefinedType("java.lang.String"); assertEquals(new JavaClass(int.class), parsed.getResolvedType()); Callable getter = parsed.getGetter(); @@ -159,8 +159,8 @@ public class ExpressionVisitorTest { @Test public void testGetterResolution() { final FieldAccessExpr parsed = parse("myStr.bytes", FieldAccessExpr.class); - assertTrue(parsed.getChild() instanceof IdentifierExpr); - final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); + assertTrue(parsed.getTarget() instanceof IdentifierExpr); + final IdentifierExpr id = (IdentifierExpr) parsed.getTarget(); id.setUserDefinedType("java.lang.String"); assertEquals(new JavaClass(byte[].class), parsed.getResolvedType()); Callable getter = parsed.getGetter(); diff --git a/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java b/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java index 8b1f820d..c7f81ab1 100644 --- a/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java +++ b/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java @@ -77,8 +77,8 @@ public class LayoutBinderTest { int originalSize = mExprModel.size(); mLayoutBinder.addVariable("user", "android.databinding.tool2.LayoutBinderTest.TestUser", null); - mLayoutBinder.parse("user.name", false, null); - mLayoutBinder.parse("user.lastName", false, null); + mLayoutBinder.parse("user.name", null); + mLayoutBinder.parse("user.lastName", null); assertEquals(originalSize + 3, mExprModel.size()); final List<Expr> bindingExprs = mExprModel.getBindingExpressions(); assertEquals(2, bindingExprs.size()); @@ -94,7 +94,7 @@ public class LayoutBinderTest { public void testParseWithMethods() { mLayoutBinder.addVariable("user", "android.databinding.tool.LayoutBinderTest.TestUser", null); - mLayoutBinder.parse("user.fullName", false, null); + mLayoutBinder.parse("user.fullName", null); Expr item = mExprModel.getBindingExpressions().get(0); assertTrue(item instanceof FieldAccessExpr); IdentifierExpr id = mExprModel.identifier("user"); @@ -102,7 +102,7 @@ public class LayoutBinderTest { fa.getResolvedType(); final Callable getter = fa.getGetter(); assertTrue(getter.type == Callable.Type.METHOD); - assertSame(id, fa.getChild()); + assertSame(id, fa.getTarget()); assertTrue(fa.isDynamic()); } diff --git a/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java b/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java index 4f31ecaa..2bb8832f 100644 --- a/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java +++ b/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java @@ -57,7 +57,7 @@ public class ExecutionPathTest { public void simpleExpr() { MockLayoutBinder lb = new MockLayoutBinder(); ExprModel model = lb.getModel(); - Expr parsed = lb.parse(mExpression, false, null); + Expr parsed = lb.parse(mExpression, null); List<ExecutionPath> paths = new ArrayList<ExecutionPath>(); ExecutionPath root = ExecutionPath.createRoot(); paths.add(root); diff --git a/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java b/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java index 6a89cb6a..20d523f6 100644 --- a/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java +++ b/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java @@ -75,11 +75,16 @@ public class ExprModelTest { } @Override - protected KCode generateCode(boolean full) { + protected KCode generateCode() { return new KCode(); } @Override + public Expr cloneToModel(ExprModel model) { + return this; + } + + @Override protected String getInvertibleError() { return "DummyExpr cannot be 2-way."; } @@ -149,7 +154,7 @@ public class ExprModelTest { IdentifierExpr a = lb.addVariable("a", "java.lang.String", null); IdentifierExpr b = lb.addVariable("b", "java.lang.String", null); IdentifierExpr c = lb.addVariable("c", "java.lang.String", null); - lb.parse("a == null ? b : c", false, null); + lb.parse("a == null ? b : c", null); mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class)); lb.getModel().seal(); List<Expr> shouldRead = getShouldRead(); @@ -298,7 +303,7 @@ public class ExprModelTest { IdentifierExpr c = lb.addVariable("c", "java.lang.String", null); IdentifierExpr d = lb.addVariable("d", "java.lang.String", null); IdentifierExpr e = lb.addVariable("e", "java.lang.String", null); - final Expr aTernary = lb.parse("a == null ? b == null ? c : d : e", false, null); + final Expr aTernary = lb.parse("a == null ? b == null ? c : d : e", null); assertTrue(aTernary instanceof TernaryExpr); final Expr bTernary = ((TernaryExpr) aTernary).getIfTrue(); assertTrue(bTernary instanceof TernaryExpr); @@ -796,7 +801,7 @@ public class ExprModelTest { assertFalse(fieldAccess.isDynamic()); mExprModel.seal(); assertEquals(0, getShouldRead().size()); - final Expr child = fieldAccess.getChild(); + final Expr child = fieldAccess.getTarget(); assertTrue(child instanceof StaticIdentifierExpr); StaticIdentifierExpr id = (StaticIdentifierExpr) child; assertEquals(id.getResolvedType().getCanonicalName(), "android.view.View"); @@ -1058,7 +1063,7 @@ public class ExprModelTest { } private <T extends Expr> T parse(LayoutBinder binder, String input, Class<T> klass) { - final Expr parsed = binder.parse(input, false, null); + final Expr parsed = binder.parse(input, null); assertTrue(klass.isAssignableFrom(parsed.getClass())); return (T) parsed; } diff --git a/compiler/src/test/java/android/databinding/tool/expr/ExprTest.java b/compiler/src/test/java/android/databinding/tool/expr/ExprTest.java index 61d04cb6..6966dd49 100644 --- a/compiler/src/test/java/android/databinding/tool/expr/ExprTest.java +++ b/compiler/src/test/java/android/databinding/tool/expr/ExprTest.java @@ -56,11 +56,16 @@ public class ExprTest{ } @Override - protected KCode generateCode(boolean full) { + protected KCode generateCode() { return new KCode(); } @Override + public Expr cloneToModel(ExprModel model) { + return this; + } + + @Override protected String getInvertibleError() { return null; } @@ -90,11 +95,16 @@ public class ExprTest{ } @Override - protected KCode generateCode(boolean full) { + protected KCode generateCode() { return new KCode(); } @Override + public Expr cloneToModel(ExprModel model) { + return this; + } + + @Override protected String getInvertibleError() { return null; } diff --git a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaAnalyzer.java b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaAnalyzer.java index 1b97cd9f..695e04b8 100644 --- a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaAnalyzer.java +++ b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaAnalyzer.java @@ -13,17 +13,17 @@ package android.databinding.tool.reflection.java; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; - -import org.apache.commons.io.FileUtils; - import android.databinding.tool.reflection.ModelAnalyzer; import android.databinding.tool.reflection.ModelClass; import android.databinding.tool.reflection.SdkUtil; import android.databinding.tool.reflection.TypeUtil; import android.databinding.tool.util.L; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; + +import org.apache.commons.io.FileUtils; + import java.io.File; import java.io.IOException; import java.net.MalformedURLException; @@ -72,7 +72,7 @@ public class JavaAnalyzer extends ModelAnalyzer { } @Override - public ModelClass findClass(String className, Map<String, String> imports) { + public ModelClass findClassInternal(String className, Map<String, String> imports) { // TODO handle imports JavaClass loaded = mClassCache.get(className); if (loaded != null) { diff --git a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaMethod.java b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaMethod.java index 0d00c574..b7b626c1 100644 --- a/compiler/src/test/java/android/databinding/tool/reflection/java/JavaMethod.java +++ b/compiler/src/test/java/android/databinding/tool/reflection/java/JavaMethod.java @@ -68,6 +68,11 @@ public class JavaMethod extends ModelMethod { } @Override + public boolean isProtected() { + return Modifier.isProtected(mMethod.getModifiers()); + } + + @Override public boolean isStatic() { return Modifier.isStatic(mMethod.getModifiers()); } diff --git a/compilerCommon/BindingExpression.g4 b/compilerCommon/BindingExpression.g4 index f88d6ee1..f6f709d2 100644 --- a/compilerCommon/BindingExpression.g4 +++ b/compilerCommon/BindingExpression.g4 @@ -64,6 +64,7 @@ expression | resources # Resource // | typeArguments (explicitGenericInvocationSuffix | 'this' arguments) # GenericCall | expression '.' Identifier # DotOp + | expression '::' Identifier # FunctionRef // | expression '.' 'this' # ThisReference // | expression '.' explicitGenericInvocation # ExplicitGenericInvocationOp | expression '[' expression ']' # BracketOp diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens index 4d9b950b..f80b7e6c 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens @@ -41,20 +41,21 @@ T__39=40 T__40=41 T__41=42 T__42=43 -THIS=44 -VoidLiteral=45 -IntegerLiteral=46 -FloatingPointLiteral=47 -BooleanLiteral=48 -CharacterLiteral=49 -SingleQuoteString=50 -DoubleQuoteString=51 -NullLiteral=52 -Identifier=53 -WS=54 -ResourceReference=55 -PackageName=56 -ResourceType=57 +T__43=44 +THIS=45 +VoidLiteral=46 +IntegerLiteral=47 +FloatingPointLiteral=48 +BooleanLiteral=49 +CharacterLiteral=50 +SingleQuoteString=51 +DoubleQuoteString=52 +NullLiteral=53 +Identifier=54 +WS=55 +ResourceReference=56 +PackageName=57 +ResourceType=58 ','=1 'default'=2 '='=3 @@ -62,41 +63,42 @@ ResourceType=57 '('=5 ')'=6 '.'=7 -'['=8 -']'=9 -'+'=10 -'-'=11 -'~'=12 -'!'=13 -'*'=14 -'/'=15 -'%'=16 -'<<'=17 -'>>>'=18 -'>>'=19 -'<='=20 -'>='=21 -'>'=22 -'<'=23 -'instanceof'=24 -'=='=25 -'!='=26 -'&'=27 -'^'=28 -'|'=29 -'&&'=30 -'||'=31 -'?'=32 -':'=33 -'??'=34 -'class'=35 -'boolean'=36 -'char'=37 -'byte'=38 -'short'=39 -'int'=40 -'long'=41 -'float'=42 -'double'=43 -'this'=44 -'null'=52 +'::'=8 +'['=9 +']'=10 +'+'=11 +'-'=12 +'~'=13 +'!'=14 +'*'=15 +'/'=16 +'%'=17 +'<<'=18 +'>>>'=19 +'>>'=20 +'<='=21 +'>='=22 +'>'=23 +'<'=24 +'instanceof'=25 +'=='=26 +'!='=27 +'&'=28 +'^'=29 +'|'=30 +'&&'=31 +'||'=32 +'?'=33 +':'=34 +'??'=35 +'class'=36 +'boolean'=37 +'char'=38 +'byte'=39 +'short'=40 +'int'=41 +'long'=42 +'float'=43 +'double'=44 +'this'=45 +'null'=53 diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java index c44dc350..fc81eb83 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java @@ -18,39 +18,39 @@ public class BindingExpressionBaseListener implements BindingExpressionListener * * <p>The default implementation does nothing.</p> */ - @Override public void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { } + @Override public void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { } + @Override public void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx) { } + @Override public void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx) { } + @Override public void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { } + @Override public void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { } + @Override public void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { } /** * {@inheritDoc} @@ -70,130 +70,130 @@ public class BindingExpressionBaseListener implements BindingExpressionListener * * <p>The default implementation does nothing.</p> */ - @Override public void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { } + @Override public void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { } + @Override public void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { } + @Override public void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { } + @Override public void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { } + @Override public void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { } + @Override public void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { } + @Override public void enterMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { } + @Override public void exitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { } + @Override public void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { } + @Override public void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { } + @Override public void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { } + @Override public void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { } + @Override public void enterTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { } + @Override public void exitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { } + @Override public void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { } + @Override public void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { } + @Override public void enterDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { } + @Override public void exitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { } + @Override public void enterMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { } + @Override public void exitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { } /** * {@inheritDoc} @@ -213,6 +213,19 @@ public class BindingExpressionBaseListener implements BindingExpressionListener * * <p>The default implementation does nothing.</p> */ + @Override public void enterFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx) { } + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ + @Override public void exitFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx) { } + + /** + * {@inheritDoc} + * + * <p>The default implementation does nothing.</p> + */ @Override public void enterBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx) { } /** * {@inheritDoc} @@ -252,26 +265,26 @@ public class BindingExpressionBaseListener implements BindingExpressionListener * * <p>The default implementation does nothing.</p> */ - @Override public void enterLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { } + @Override public void enterSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { } + @Override public void exitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void enterSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { } + @Override public void enterLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { } /** * {@inheritDoc} * * <p>The default implementation does nothing.</p> */ - @Override public void exitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { } + @Override public void exitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { } /** * {@inheritDoc} diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java index f89ac735..01a86e6c 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java @@ -19,7 +19,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -27,7 +27,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitResource(@NotNull BindingExpressionParser.ResourceContext ctx) { return visitChildren(ctx); } + @Override public Result visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -35,7 +35,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -51,7 +51,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitResource(@NotNull BindingExpressionParser.ResourceContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -59,7 +59,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { return visitChildren(ctx); } + @Override public Result visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -67,7 +67,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { return visitChildren(ctx); } + @Override public Result visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -75,7 +75,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { return visitChildren(ctx); } + @Override public Result visitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -83,7 +83,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -91,7 +91,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -99,7 +99,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -107,7 +107,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -115,7 +115,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -123,7 +123,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { return visitChildren(ctx); } + @Override public Result visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -139,6 +139,14 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ + @Override public Result visitFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx) { return visitChildren(ctx); } + + /** + * {@inheritDoc} + * + * <p>The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.</p> + */ @Override public Result visitBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx) { return visitChildren(ctx); } /** @@ -163,7 +171,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { return visitChildren(ctx); } + @Override public Result visitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} @@ -171,7 +179,7 @@ public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisit * <p>The default implementation returns the result of calling * {@link #visitChildren} on {@code ctx}.</p> */ - @Override public Result visitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx) { return visitChildren(ctx); } + @Override public Result visitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java index ff6e7457..8b8bb8b9 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java @@ -16,10 +16,10 @@ public class BindingExpressionLexer extends Lexer { T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, - T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, THIS=44, VoidLiteral=45, - IntegerLiteral=46, FloatingPointLiteral=47, BooleanLiteral=48, CharacterLiteral=49, - SingleQuoteString=50, DoubleQuoteString=51, NullLiteral=52, Identifier=53, - WS=54, ResourceReference=55, PackageName=56, ResourceType=57; + T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, THIS=45, VoidLiteral=46, + IntegerLiteral=47, FloatingPointLiteral=48, BooleanLiteral=49, CharacterLiteral=50, + SingleQuoteString=51, DoubleQuoteString=52, NullLiteral=53, Identifier=54, + WS=55, ResourceReference=56, PackageName=57, ResourceType=58; public static String[] modeNames = { "DEFAULT_MODE" }; @@ -30,7 +30,7 @@ public class BindingExpressionLexer extends Lexer { "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", - "T__41", "T__42", "THIS", "VoidLiteral", "IntegerLiteral", "DecimalIntegerLiteral", + "T__41", "T__42", "T__43", "THIS", "VoidLiteral", "IntegerLiteral", "DecimalIntegerLiteral", "HexIntegerLiteral", "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix", "DecimalNumeral", "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore", "Underscores", "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore", @@ -47,18 +47,18 @@ public class BindingExpressionLexer extends Lexer { }; private static final String[] _LITERAL_NAMES = { - null, "','", "'default'", "'='", "'->'", "'('", "')'", "'.'", "'['", "']'", - "'+'", "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", "'>>>'", "'>>'", - "'<='", "'>='", "'>'", "'<'", "'instanceof'", "'=='", "'!='", "'&'", "'^'", - "'|'", "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", "'boolean'", "'char'", - "'byte'", "'short'", "'int'", "'long'", "'float'", "'double'", "'this'", - null, null, null, null, null, null, null, "'null'" + null, "','", "'default'", "'='", "'->'", "'('", "')'", "'.'", "'::'", + "'['", "']'", "'+'", "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", + "'>>>'", "'>>'", "'<='", "'>='", "'>'", "'<'", "'instanceof'", "'=='", + "'!='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", + "'boolean'", "'char'", "'byte'", "'short'", "'int'", "'long'", "'float'", + "'double'", "'this'", null, null, null, null, null, null, null, "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, "THIS", "VoidLiteral", + null, null, null, null, null, null, null, null, null, "THIS", "VoidLiteral", "IntegerLiteral", "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral", "SingleQuoteString", "DoubleQuoteString", "NullLiteral", "Identifier", "WS", "ResourceReference", "PackageName", "ResourceType" @@ -117,10 +117,10 @@ public class BindingExpressionLexer extends Lexer { @Override public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { switch (ruleIndex) { - case 94: + case 95: return JavaLetter_sempred(_localctx, predIndex); - case 95: + case 96: return JavaLetterOrDigit_sempred(_localctx, predIndex); } return true; @@ -147,7 +147,7 @@ public class BindingExpressionLexer extends Lexer { } public static final String _serializedATN = - "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\2;\u036b\b\1\4\2\t"+ + "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\2<\u0370\b\1\4\2\t"+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -158,305 +158,307 @@ public class BindingExpressionLexer extends Lexer { "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+ - "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+ - "\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13"+ - "\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22"+ - "\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3\26"+ - "\3\27\3\27\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ - "\3\31\3\32\3\32\3\32\3\33\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37"+ - "\3\37\3\37\3 \3 \3 \3!\3!\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3$\3$\3%\3%\3%"+ - "\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3"+ - ")\3)\3)\3)\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3,\3-\3"+ - "-\3-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\5.\u0175"+ - "\n.\3/\3/\3/\3/\5/\u017b\n/\3\60\3\60\5\60\u017f\n\60\3\61\3\61\5\61\u0183"+ - "\n\61\3\62\3\62\5\62\u0187\n\62\3\63\3\63\5\63\u018b\n\63\3\64\3\64\3"+ - "\65\3\65\3\65\5\65\u0192\n\65\3\65\3\65\3\65\5\65\u0197\n\65\5\65\u0199"+ - "\n\65\3\66\3\66\7\66\u019d\n\66\f\66\16\66\u01a0\13\66\3\66\5\66\u01a3"+ - "\n\66\3\67\3\67\5\67\u01a7\n\67\38\38\39\39\59\u01ad\n9\3:\6:\u01b0\n"+ - ":\r:\16:\u01b1\3;\3;\3;\3;\3<\3<\7<\u01ba\n<\f<\16<\u01bd\13<\3<\5<\u01c0"+ - "\n<\3=\3=\3>\3>\5>\u01c6\n>\3?\3?\5?\u01ca\n?\3?\3?\3@\3@\7@\u01d0\n@"+ - "\f@\16@\u01d3\13@\3@\5@\u01d6\n@\3A\3A\3B\3B\5B\u01dc\nB\3C\3C\3C\3C\3"+ - "D\3D\7D\u01e4\nD\fD\16D\u01e7\13D\3D\5D\u01ea\nD\3E\3E\3F\3F\5F\u01f0"+ - "\nF\3G\3G\5G\u01f4\nG\3H\3H\3H\5H\u01f9\nH\3H\5H\u01fc\nH\3H\5H\u01ff"+ - "\nH\3H\3H\3H\5H\u0204\nH\3H\5H\u0207\nH\3H\3H\3H\5H\u020c\nH\3H\3H\3H"+ - "\5H\u0211\nH\3I\3I\3I\3J\3J\3K\5K\u0219\nK\3K\3K\3L\3L\3M\3M\3N\3N\3N"+ - "\5N\u0224\nN\3O\3O\5O\u0228\nO\3O\3O\3O\5O\u022d\nO\3O\3O\5O\u0231\nO"+ - "\3P\3P\3P\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3R\5R\u0241\nR\3S\3S\3S\3S\3S"+ - "\3S\3S\3S\5S\u024b\nS\3T\3T\3U\3U\7U\u0251\nU\fU\16U\u0254\13U\3U\3U\3"+ - "V\3V\5V\u025a\nV\3V\3V\3W\6W\u025f\nW\rW\16W\u0260\3X\3X\5X\u0265\nX\3"+ - "Y\3Y\5Y\u0269\nY\3Z\3Z\3Z\3Z\5Z\u026f\nZ\3[\3[\3[\3[\3[\3[\3[\3[\3[\3"+ - "[\3[\5[\u027c\n[\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3]\3]\3^\3^\3^\3^\3^\3_\3"+ - "_\7_\u028e\n_\f_\16_\u0291\13_\3`\3`\3`\3`\3`\3`\5`\u0299\n`\3a\3a\3a"+ - "\3a\3a\3a\5a\u02a1\na\3b\6b\u02a4\nb\rb\16b\u02a5\3b\3b\3c\3c\3c\3c\5"+ - "c\u02ae\nc\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3d\3d\5d\u02bc\nd\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3e\3"+ - "e\3e\3e\3e\3e\3e\3e\3e\5e\u036a\ne\2\2\2f\3\2\3\5\2\4\7\2\5\t\2\6\13\2"+ - "\7\r\2\b\17\2\t\21\2\n\23\2\13\25\2\f\27\2\r\31\2\16\33\2\17\35\2\20\37"+ - "\2\21!\2\22#\2\23%\2\24\'\2\25)\2\26+\2\27-\2\30/\2\31\61\2\32\63\2\33"+ - "\65\2\34\67\2\359\2\36;\2\37=\2 ?\2!A\2\"C\2#E\2$G\2%I\2&K\2\'M\2(O\2"+ - ")Q\2*S\2+U\2,W\2-Y\2.[\2/]\2\60_\2\2a\2\2c\2\2e\2\2g\2\2i\2\2k\2\2m\2"+ - "\2o\2\2q\2\2s\2\2u\2\2w\2\2y\2\2{\2\2}\2\2\177\2\2\u0081\2\2\u0083\2\2"+ - "\u0085\2\2\u0087\2\2\u0089\2\2\u008b\2\2\u008d\2\61\u008f\2\2\u0091\2"+ - "\2\u0093\2\2\u0095\2\2\u0097\2\2\u0099\2\2\u009b\2\2\u009d\2\2\u009f\2"+ - "\2\u00a1\2\2\u00a3\2\62\u00a5\2\63\u00a7\2\2\u00a9\2\64\u00ab\2\65\u00ad"+ - "\2\2\u00af\2\2\u00b1\2\2\u00b3\2\2\u00b5\2\2\u00b7\2\2\u00b9\2\2\u00bb"+ - "\2\66\u00bd\2\67\u00bf\2\2\u00c1\2\2\u00c3\28\u00c5\29\u00c7\2:\u00c9"+ - "\2;\3\2\30\4\2NNnn\3\2\63;\4\2ZZzz\5\2\62;CHch\3\2\629\4\2DDdd\3\2\62"+ - "\63\4\2GGgg\4\2--//\6\2FFHHffhh\4\2RRrr\4\2))^^\4\2$$^^\4\2^^bb\13\2$"+ - "$))^^bbddhhppttvv\3\2\62\65\6\2&&C\\aac|\4\2\2\u0101\ud802\udc01\3\2\ud802"+ - "\udc01\3\2\udc02\ue001\7\2&&\62;C\\aac|\5\2\13\f\16\17\"\"\u0390\2\3\3"+ - "\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2"+ - "\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3"+ - "\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2"+ - "%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61"+ - "\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2"+ - "\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I"+ - "\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2"+ - "\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2\u008d\3\2\2\2\2\u00a3"+ - "\3\2\2\2\2\u00a5\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00bb\3\2\2"+ - "\2\2\u00bd\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9"+ - "\3\2\2\2\3\u00cb\3\2\2\2\5\u00cd\3\2\2\2\7\u00d5\3\2\2\2\t\u00d7\3\2\2"+ - "\2\13\u00da\3\2\2\2\r\u00dc\3\2\2\2\17\u00de\3\2\2\2\21\u00e0\3\2\2\2"+ - "\23\u00e2\3\2\2\2\25\u00e4\3\2\2\2\27\u00e6\3\2\2\2\31\u00e8\3\2\2\2\33"+ - "\u00ea\3\2\2\2\35\u00ec\3\2\2\2\37\u00ee\3\2\2\2!\u00f0\3\2\2\2#\u00f2"+ - "\3\2\2\2%\u00f5\3\2\2\2\'\u00f9\3\2\2\2)\u00fc\3\2\2\2+\u00ff\3\2\2\2"+ - "-\u0102\3\2\2\2/\u0104\3\2\2\2\61\u0106\3\2\2\2\63\u0111\3\2\2\2\65\u0114"+ - "\3\2\2\2\67\u0117\3\2\2\29\u0119\3\2\2\2;\u011b\3\2\2\2=\u011d\3\2\2\2"+ - "?\u0120\3\2\2\2A\u0123\3\2\2\2C\u0125\3\2\2\2E\u0127\3\2\2\2G\u012a\3"+ - "\2\2\2I\u0130\3\2\2\2K\u0138\3\2\2\2M\u013d\3\2\2\2O\u0142\3\2\2\2Q\u0148"+ - "\3\2\2\2S\u014c\3\2\2\2U\u0151\3\2\2\2W\u0157\3\2\2\2Y\u015e\3\2\2\2["+ - "\u0174\3\2\2\2]\u017a\3\2\2\2_\u017c\3\2\2\2a\u0180\3\2\2\2c\u0184\3\2"+ - "\2\2e\u0188\3\2\2\2g\u018c\3\2\2\2i\u0198\3\2\2\2k\u019a\3\2\2\2m\u01a6"+ - "\3\2\2\2o\u01a8\3\2\2\2q\u01ac\3\2\2\2s\u01af\3\2\2\2u\u01b3\3\2\2\2w"+ - "\u01b7\3\2\2\2y\u01c1\3\2\2\2{\u01c5\3\2\2\2}\u01c7\3\2\2\2\177\u01cd"+ - "\3\2\2\2\u0081\u01d7\3\2\2\2\u0083\u01db\3\2\2\2\u0085\u01dd\3\2\2\2\u0087"+ - "\u01e1\3\2\2\2\u0089\u01eb\3\2\2\2\u008b\u01ef\3\2\2\2\u008d\u01f3\3\2"+ - "\2\2\u008f\u0210\3\2\2\2\u0091\u0212\3\2\2\2\u0093\u0215\3\2\2\2\u0095"+ - "\u0218\3\2\2\2\u0097\u021c\3\2\2\2\u0099\u021e\3\2\2\2\u009b\u0220\3\2"+ - "\2\2\u009d\u0230\3\2\2\2\u009f\u0232\3\2\2\2\u00a1\u0235\3\2\2\2\u00a3"+ - "\u0240\3\2\2\2\u00a5\u024a\3\2\2\2\u00a7\u024c\3\2\2\2\u00a9\u024e\3\2"+ - "\2\2\u00ab\u0257\3\2\2\2\u00ad\u025e\3\2\2\2\u00af\u0264\3\2\2\2\u00b1"+ - "\u0268\3\2\2\2\u00b3\u026e\3\2\2\2\u00b5\u027b\3\2\2\2\u00b7\u027d\3\2"+ - "\2\2\u00b9\u0284\3\2\2\2\u00bb\u0286\3\2\2\2\u00bd\u028b\3\2\2\2\u00bf"+ - "\u0298\3\2\2\2\u00c1\u02a0\3\2\2\2\u00c3\u02a3\3\2\2\2\u00c5\u02a9\3\2"+ - "\2\2\u00c7\u02bb\3\2\2\2\u00c9\u0369\3\2\2\2\u00cb\u00cc\7.\2\2\u00cc"+ - "\4\3\2\2\2\u00cd\u00ce\7f\2\2\u00ce\u00cf\7g\2\2\u00cf\u00d0\7h\2\2\u00d0"+ - "\u00d1\7c\2\2\u00d1\u00d2\7w\2\2\u00d2\u00d3\7n\2\2\u00d3\u00d4\7v\2\2"+ - "\u00d4\6\3\2\2\2\u00d5\u00d6\7?\2\2\u00d6\b\3\2\2\2\u00d7\u00d8\7/\2\2"+ - "\u00d8\u00d9\7@\2\2\u00d9\n\3\2\2\2\u00da\u00db\7*\2\2\u00db\f\3\2\2\2"+ - "\u00dc\u00dd\7+\2\2\u00dd\16\3\2\2\2\u00de\u00df\7\60\2\2\u00df\20\3\2"+ - "\2\2\u00e0\u00e1\7]\2\2\u00e1\22\3\2\2\2\u00e2\u00e3\7_\2\2\u00e3\24\3"+ - "\2\2\2\u00e4\u00e5\7-\2\2\u00e5\26\3\2\2\2\u00e6\u00e7\7/\2\2\u00e7\30"+ - "\3\2\2\2\u00e8\u00e9\7\u0080\2\2\u00e9\32\3\2\2\2\u00ea\u00eb\7#\2\2\u00eb"+ - "\34\3\2\2\2\u00ec\u00ed\7,\2\2\u00ed\36\3\2\2\2\u00ee\u00ef\7\61\2\2\u00ef"+ - " \3\2\2\2\u00f0\u00f1\7\'\2\2\u00f1\"\3\2\2\2\u00f2\u00f3\7>\2\2\u00f3"+ - "\u00f4\7>\2\2\u00f4$\3\2\2\2\u00f5\u00f6\7@\2\2\u00f6\u00f7\7@\2\2\u00f7"+ - "\u00f8\7@\2\2\u00f8&\3\2\2\2\u00f9\u00fa\7@\2\2\u00fa\u00fb\7@\2\2\u00fb"+ - "(\3\2\2\2\u00fc\u00fd\7>\2\2\u00fd\u00fe\7?\2\2\u00fe*\3\2\2\2\u00ff\u0100"+ - "\7@\2\2\u0100\u0101\7?\2\2\u0101,\3\2\2\2\u0102\u0103\7@\2\2\u0103.\3"+ - "\2\2\2\u0104\u0105\7>\2\2\u0105\60\3\2\2\2\u0106\u0107\7k\2\2\u0107\u0108"+ - "\7p\2\2\u0108\u0109\7u\2\2\u0109\u010a\7v\2\2\u010a\u010b\7c\2\2\u010b"+ - "\u010c\7p\2\2\u010c\u010d\7e\2\2\u010d\u010e\7g\2\2\u010e\u010f\7q\2\2"+ - "\u010f\u0110\7h\2\2\u0110\62\3\2\2\2\u0111\u0112\7?\2\2\u0112\u0113\7"+ - "?\2\2\u0113\64\3\2\2\2\u0114\u0115\7#\2\2\u0115\u0116\7?\2\2\u0116\66"+ - "\3\2\2\2\u0117\u0118\7(\2\2\u01188\3\2\2\2\u0119\u011a\7`\2\2\u011a:\3"+ - "\2\2\2\u011b\u011c\7~\2\2\u011c<\3\2\2\2\u011d\u011e\7(\2\2\u011e\u011f"+ - "\7(\2\2\u011f>\3\2\2\2\u0120\u0121\7~\2\2\u0121\u0122\7~\2\2\u0122@\3"+ - "\2\2\2\u0123\u0124\7A\2\2\u0124B\3\2\2\2\u0125\u0126\7<\2\2\u0126D\3\2"+ - "\2\2\u0127\u0128\7A\2\2\u0128\u0129\7A\2\2\u0129F\3\2\2\2\u012a\u012b"+ - "\7e\2\2\u012b\u012c\7n\2\2\u012c\u012d\7c\2\2\u012d\u012e\7u\2\2\u012e"+ - "\u012f\7u\2\2\u012fH\3\2\2\2\u0130\u0131\7d\2\2\u0131\u0132\7q\2\2\u0132"+ - "\u0133\7q\2\2\u0133\u0134\7n\2\2\u0134\u0135\7g\2\2\u0135\u0136\7c\2\2"+ - "\u0136\u0137\7p\2\2\u0137J\3\2\2\2\u0138\u0139\7e\2\2\u0139\u013a\7j\2"+ - "\2\u013a\u013b\7c\2\2\u013b\u013c\7t\2\2\u013cL\3\2\2\2\u013d\u013e\7"+ - "d\2\2\u013e\u013f\7{\2\2\u013f\u0140\7v\2\2\u0140\u0141\7g\2\2\u0141N"+ - "\3\2\2\2\u0142\u0143\7u\2\2\u0143\u0144\7j\2\2\u0144\u0145\7q\2\2\u0145"+ - "\u0146\7t\2\2\u0146\u0147\7v\2\2\u0147P\3\2\2\2\u0148\u0149\7k\2\2\u0149"+ - "\u014a\7p\2\2\u014a\u014b\7v\2\2\u014bR\3\2\2\2\u014c\u014d\7n\2\2\u014d"+ - "\u014e\7q\2\2\u014e\u014f\7p\2\2\u014f\u0150\7i\2\2\u0150T\3\2\2\2\u0151"+ - "\u0152\7h\2\2\u0152\u0153\7n\2\2\u0153\u0154\7q\2\2\u0154\u0155\7c\2\2"+ - "\u0155\u0156\7v\2\2\u0156V\3\2\2\2\u0157\u0158\7f\2\2\u0158\u0159\7q\2"+ - "\2\u0159\u015a\7w\2\2\u015a\u015b\7d\2\2\u015b\u015c\7n\2\2\u015c\u015d"+ - "\7g\2\2\u015dX\3\2\2\2\u015e\u015f\7v\2\2\u015f\u0160\7j\2\2\u0160\u0161"+ - "\7k\2\2\u0161\u0162\7u\2\2\u0162Z\3\2\2\2\u0163\u0164\7X\2\2\u0164\u0165"+ - "\7q\2\2\u0165\u0166\7k\2\2\u0166\u0175\7f\2\2\u0167\u0168\7x\2\2\u0168"+ - "\u0169\7q\2\2\u0169\u016a\7k\2\2\u016a\u0175\7f\2\2\u016b\u016c\7\u00b1"+ - "\2\2\u016c\u016d\7^\2\2\u016d\u016e\7a\2\2\u016e\u016f\7*\2\2\u016f\u0170"+ - "\7\u30c6\2\2\u0170\u0171\7+\2\2\u0171\u0172\7a\2\2\u0172\u0173\7\61\2"+ - "\2\u0173\u0175\7\u00b1\2\2\u0174\u0163\3\2\2\2\u0174\u0167\3\2\2\2\u0174"+ - "\u016b\3\2\2\2\u0175\\\3\2\2\2\u0176\u017b\5_\60\2\u0177\u017b\5a\61\2"+ - "\u0178\u017b\5c\62\2\u0179\u017b\5e\63\2\u017a\u0176\3\2\2\2\u017a\u0177"+ - "\3\2\2\2\u017a\u0178\3\2\2\2\u017a\u0179\3\2\2\2\u017b^\3\2\2\2\u017c"+ - "\u017e\5i\65\2\u017d\u017f\5g\64\2\u017e\u017d\3\2\2\2\u017e\u017f\3\2"+ - "\2\2\u017f`\3\2\2\2\u0180\u0182\5u;\2\u0181\u0183\5g\64\2\u0182\u0181"+ - "\3\2\2\2\u0182\u0183\3\2\2\2\u0183b\3\2\2\2\u0184\u0186\5}?\2\u0185\u0187"+ - "\5g\64\2\u0186\u0185\3\2\2\2\u0186\u0187\3\2\2\2\u0187d\3\2\2\2\u0188"+ - "\u018a\5\u0085C\2\u0189\u018b\5g\64\2\u018a\u0189\3\2\2\2\u018a\u018b"+ - "\3\2\2\2\u018bf\3\2\2\2\u018c\u018d\t\2\2\2\u018dh\3\2\2\2\u018e\u0199"+ - "\7\62\2\2\u018f\u0196\5o8\2\u0190\u0192\5k\66\2\u0191\u0190\3\2\2\2\u0191"+ - "\u0192\3\2\2\2\u0192\u0197\3\2\2\2\u0193\u0194\5s:\2\u0194\u0195\5k\66"+ - "\2\u0195\u0197\3\2\2\2\u0196\u0191\3\2\2\2\u0196\u0193\3\2\2\2\u0197\u0199"+ - "\3\2\2\2\u0198\u018e\3\2\2\2\u0198\u018f\3\2\2\2\u0199j\3\2\2\2\u019a"+ - "\u01a2\5m\67\2\u019b\u019d\5q9\2\u019c\u019b\3\2\2\2\u019d\u01a0\3\2\2"+ - "\2\u019e\u019c\3\2\2\2\u019e\u019f\3\2\2\2\u019f\u01a1\3\2\2\2\u01a0\u019e"+ - "\3\2\2\2\u01a1\u01a3\5m\67\2\u01a2\u019e\3\2\2\2\u01a2\u01a3\3\2\2\2\u01a3"+ - "l\3\2\2\2\u01a4\u01a7\7\62\2\2\u01a5\u01a7\5o8\2\u01a6\u01a4\3\2\2\2\u01a6"+ - "\u01a5\3\2\2\2\u01a7n\3\2\2\2\u01a8\u01a9\t\3\2\2\u01a9p\3\2\2\2\u01aa"+ - "\u01ad\5m\67\2\u01ab\u01ad\7a\2\2\u01ac\u01aa\3\2\2\2\u01ac\u01ab\3\2"+ - "\2\2\u01adr\3\2\2\2\u01ae\u01b0\7a\2\2\u01af\u01ae\3\2\2\2\u01b0\u01b1"+ - "\3\2\2\2\u01b1\u01af\3\2\2\2\u01b1\u01b2\3\2\2\2\u01b2t\3\2\2\2\u01b3"+ - "\u01b4\7\62\2\2\u01b4\u01b5\t\4\2\2\u01b5\u01b6\5w<\2\u01b6v\3\2\2\2\u01b7"+ - "\u01bf\5y=\2\u01b8\u01ba\5{>\2\u01b9\u01b8\3\2\2\2\u01ba\u01bd\3\2\2\2"+ - "\u01bb\u01b9\3\2\2\2\u01bb\u01bc\3\2\2\2\u01bc\u01be\3\2\2\2\u01bd\u01bb"+ - "\3\2\2\2\u01be\u01c0\5y=\2\u01bf\u01bb\3\2\2\2\u01bf\u01c0\3\2\2\2\u01c0"+ - "x\3\2\2\2\u01c1\u01c2\t\5\2\2\u01c2z\3\2\2\2\u01c3\u01c6\5y=\2\u01c4\u01c6"+ - "\7a\2\2\u01c5\u01c3\3\2\2\2\u01c5\u01c4\3\2\2\2\u01c6|\3\2\2\2\u01c7\u01c9"+ - "\7\62\2\2\u01c8\u01ca\5s:\2\u01c9\u01c8\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca"+ - "\u01cb\3\2\2\2\u01cb\u01cc\5\177@\2\u01cc~\3\2\2\2\u01cd\u01d5\5\u0081"+ - "A\2\u01ce\u01d0\5\u0083B\2\u01cf\u01ce\3\2\2\2\u01d0\u01d3\3\2\2\2\u01d1"+ - "\u01cf\3\2\2\2\u01d1\u01d2\3\2\2\2\u01d2\u01d4\3\2\2\2\u01d3\u01d1\3\2"+ - "\2\2\u01d4\u01d6\5\u0081A\2\u01d5\u01d1\3\2\2\2\u01d5\u01d6\3\2\2\2\u01d6"+ - "\u0080\3\2\2\2\u01d7\u01d8\t\6\2\2\u01d8\u0082\3\2\2\2\u01d9\u01dc\5\u0081"+ - "A\2\u01da\u01dc\7a\2\2\u01db\u01d9\3\2\2\2\u01db\u01da\3\2\2\2\u01dc\u0084"+ - "\3\2\2\2\u01dd\u01de\7\62\2\2\u01de\u01df\t\7\2\2\u01df\u01e0\5\u0087"+ - "D\2\u01e0\u0086\3\2\2\2\u01e1\u01e9\5\u0089E\2\u01e2\u01e4\5\u008bF\2"+ - "\u01e3\u01e2\3\2\2\2\u01e4\u01e7\3\2\2\2\u01e5\u01e3\3\2\2\2\u01e5\u01e6"+ - "\3\2\2\2\u01e6\u01e8\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e8\u01ea\5\u0089E"+ - "\2\u01e9\u01e5\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u0088\3\2\2\2\u01eb\u01ec"+ - "\t\b\2\2\u01ec\u008a\3\2\2\2\u01ed\u01f0\5\u0089E\2\u01ee\u01f0\7a\2\2"+ - "\u01ef\u01ed\3\2\2\2\u01ef\u01ee\3\2\2\2\u01f0\u008c\3\2\2\2\u01f1\u01f4"+ - "\5\u008fH\2\u01f2\u01f4\5\u009bN\2\u01f3\u01f1\3\2\2\2\u01f3\u01f2\3\2"+ - "\2\2\u01f4\u008e\3\2\2\2\u01f5\u01f6\5k\66\2\u01f6\u01f8\7\60\2\2\u01f7"+ - "\u01f9\5k\66\2\u01f8\u01f7\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9\u01fb\3\2"+ - "\2\2\u01fa\u01fc\5\u0091I\2\u01fb\u01fa\3\2\2\2\u01fb\u01fc\3\2\2\2\u01fc"+ - "\u01fe\3\2\2\2\u01fd\u01ff\5\u0099M\2\u01fe\u01fd\3\2\2\2\u01fe\u01ff"+ - "\3\2\2\2\u01ff\u0211\3\2\2\2\u0200\u0201\7\60\2\2\u0201\u0203\5k\66\2"+ - "\u0202\u0204\5\u0091I\2\u0203\u0202\3\2\2\2\u0203\u0204\3\2\2\2\u0204"+ - "\u0206\3\2\2\2\u0205\u0207\5\u0099M\2\u0206\u0205\3\2\2\2\u0206\u0207"+ - "\3\2\2\2\u0207\u0211\3\2\2\2\u0208\u0209\5k\66\2\u0209\u020b\5\u0091I"+ - "\2\u020a\u020c\5\u0099M\2\u020b\u020a\3\2\2\2\u020b\u020c\3\2\2\2\u020c"+ - "\u0211\3\2\2\2\u020d\u020e\5k\66\2\u020e\u020f\5\u0099M\2\u020f\u0211"+ - "\3\2\2\2\u0210\u01f5\3\2\2\2\u0210\u0200\3\2\2\2\u0210\u0208\3\2\2\2\u0210"+ - "\u020d\3\2\2\2\u0211\u0090\3\2\2\2\u0212\u0213\5\u0093J\2\u0213\u0214"+ - "\5\u0095K\2\u0214\u0092\3\2\2\2\u0215\u0216\t\t\2\2\u0216\u0094\3\2\2"+ - "\2\u0217\u0219\5\u0097L\2\u0218\u0217\3\2\2\2\u0218\u0219\3\2\2\2\u0219"+ - "\u021a\3\2\2\2\u021a\u021b\5k\66\2\u021b\u0096\3\2\2\2\u021c\u021d\t\n"+ - "\2\2\u021d\u0098\3\2\2\2\u021e\u021f\t\13\2\2\u021f\u009a\3\2\2\2\u0220"+ - "\u0221\5\u009dO\2\u0221\u0223\5\u009fP\2\u0222\u0224\5\u0099M\2\u0223"+ - "\u0222\3\2\2\2\u0223\u0224\3\2\2\2\u0224\u009c\3\2\2\2\u0225\u0227\5u"+ - ";\2\u0226\u0228\7\60\2\2\u0227\u0226\3\2\2\2\u0227\u0228\3\2\2\2\u0228"+ - "\u0231\3\2\2\2\u0229\u022a\7\62\2\2\u022a\u022c\t\4\2\2\u022b\u022d\5"+ - "w<\2\u022c\u022b\3\2\2\2\u022c\u022d\3\2\2\2\u022d\u022e\3\2\2\2\u022e"+ - "\u022f\7\60\2\2\u022f\u0231\5w<\2\u0230\u0225\3\2\2\2\u0230\u0229\3\2"+ - "\2\2\u0231\u009e\3\2\2\2\u0232\u0233\5\u00a1Q\2\u0233\u0234\5\u0095K\2"+ - "\u0234\u00a0\3\2\2\2\u0235\u0236\t\f\2\2\u0236\u00a2\3\2\2\2\u0237\u0238"+ - "\7v\2\2\u0238\u0239\7t\2\2\u0239\u023a\7w\2\2\u023a\u0241\7g\2\2\u023b"+ - "\u023c\7h\2\2\u023c\u023d\7c\2\2\u023d\u023e\7n\2\2\u023e\u023f\7u\2\2"+ - "\u023f\u0241\7g\2\2\u0240\u0237\3\2\2\2\u0240\u023b\3\2\2\2\u0241\u00a4"+ - "\3\2\2\2\u0242\u0243\7)\2\2\u0243\u0244\5\u00a7T\2\u0244\u0245\7)\2\2"+ - "\u0245\u024b\3\2\2\2\u0246\u0247\7)\2\2\u0247\u0248\5\u00b3Z\2\u0248\u0249"+ - "\7)\2\2\u0249\u024b\3\2\2\2\u024a\u0242\3\2\2\2\u024a\u0246\3\2\2\2\u024b"+ - "\u00a6\3\2\2\2\u024c\u024d\n\r\2\2\u024d\u00a8\3\2\2\2\u024e\u0252\7b"+ - "\2\2\u024f\u0251\5\u00b1Y\2\u0250\u024f\3\2\2\2\u0251\u0254\3\2\2\2\u0252"+ - "\u0250\3\2\2\2\u0252\u0253\3\2\2\2\u0253\u0255\3\2\2\2\u0254\u0252\3\2"+ - "\2\2\u0255\u0256\7b\2\2\u0256\u00aa\3\2\2\2\u0257\u0259\7$\2\2\u0258\u025a"+ - "\5\u00adW\2\u0259\u0258\3\2\2\2\u0259\u025a\3\2\2\2\u025a\u025b\3\2\2"+ - "\2\u025b\u025c\7$\2\2\u025c\u00ac\3\2\2\2\u025d\u025f\5\u00afX\2\u025e"+ - "\u025d\3\2\2\2\u025f\u0260\3\2\2\2\u0260\u025e\3\2\2\2\u0260\u0261\3\2"+ - "\2\2\u0261\u00ae\3\2\2\2\u0262\u0265\n\16\2\2\u0263\u0265\5\u00b3Z\2\u0264"+ - "\u0262\3\2\2\2\u0264\u0263\3\2\2\2\u0265\u00b0\3\2\2\2\u0266\u0269\n\17"+ - "\2\2\u0267\u0269\5\u00b3Z\2\u0268\u0266\3\2\2\2\u0268\u0267\3\2\2\2\u0269"+ - "\u00b2\3\2\2\2\u026a\u026b\7^\2\2\u026b\u026f\t\20\2\2\u026c\u026f\5\u00b5"+ - "[\2\u026d\u026f\5\u00b7\\\2\u026e\u026a\3\2\2\2\u026e\u026c\3\2\2\2\u026e"+ - "\u026d\3\2\2\2\u026f\u00b4\3\2\2\2\u0270\u0271\7^\2\2\u0271\u027c\5\u0081"+ - "A\2\u0272\u0273\7^\2\2\u0273\u0274\5\u0081A\2\u0274\u0275\5\u0081A\2\u0275"+ - "\u027c\3\2\2\2\u0276\u0277\7^\2\2\u0277\u0278\5\u00b9]\2\u0278\u0279\5"+ - "\u0081A\2\u0279\u027a\5\u0081A\2\u027a\u027c\3\2\2\2\u027b\u0270\3\2\2"+ - "\2\u027b\u0272\3\2\2\2\u027b\u0276\3\2\2\2\u027c\u00b6\3\2\2\2\u027d\u027e"+ - "\7^\2\2\u027e\u027f\7w\2\2\u027f\u0280\5y=\2\u0280\u0281\5y=\2\u0281\u0282"+ - "\5y=\2\u0282\u0283\5y=\2\u0283\u00b8\3\2\2\2\u0284\u0285\t\21\2\2\u0285"+ - "\u00ba\3\2\2\2\u0286\u0287\7p\2\2\u0287\u0288\7w\2\2\u0288\u0289\7n\2"+ - "\2\u0289\u028a\7n\2\2\u028a\u00bc\3\2\2\2\u028b\u028f\5\u00bf`\2\u028c"+ - "\u028e\5\u00c1a\2\u028d\u028c\3\2\2\2\u028e\u0291\3\2\2\2\u028f\u028d"+ - "\3\2\2\2\u028f\u0290\3\2\2\2\u0290\u00be\3\2\2\2\u0291\u028f\3\2\2\2\u0292"+ - "\u0299\t\22\2\2\u0293\u0294\n\23\2\2\u0294\u0299\6`\2\2\u0295\u0296\t"+ - "\24\2\2\u0296\u0297\t\25\2\2\u0297\u0299\6`\3\2\u0298\u0292\3\2\2\2\u0298"+ - "\u0293\3\2\2\2\u0298\u0295\3\2\2\2\u0299\u00c0\3\2\2\2\u029a\u02a1\t\26"+ - "\2\2\u029b\u029c\n\23\2\2\u029c\u02a1\6a\4\2\u029d\u029e\t\24\2\2\u029e"+ - "\u029f\t\25\2\2\u029f\u02a1\6a\5\2\u02a0\u029a\3\2\2\2\u02a0\u029b\3\2"+ - "\2\2\u02a0\u029d\3\2\2\2\u02a1\u00c2\3\2\2\2\u02a2\u02a4\t\27\2\2\u02a3"+ - "\u02a2\3\2\2\2\u02a4\u02a5\3\2\2\2\u02a5\u02a3\3\2\2\2\u02a5\u02a6\3\2"+ - "\2\2\u02a6\u02a7\3\2\2\2\u02a7\u02a8\bb\2\2\u02a8\u00c4\3\2\2\2\u02a9"+ - "\u02ad\7B\2\2\u02aa\u02ab\5\u00c7d\2\u02ab\u02ac\7<\2\2\u02ac\u02ae\3"+ - "\2\2\2\u02ad\u02aa\3\2\2\2\u02ad\u02ae\3\2\2\2\u02ae\u02af\3\2\2\2\u02af"+ - "\u02b0\5\u00c9e\2\u02b0\u02b1\7\61\2\2\u02b1\u02b2\5\u00bd_\2\u02b2\u00c6"+ - "\3\2\2\2\u02b3\u02b4\7c\2\2\u02b4\u02b5\7p\2\2\u02b5\u02b6\7f\2\2\u02b6"+ - "\u02b7\7t\2\2\u02b7\u02b8\7q\2\2\u02b8\u02b9\7k\2\2\u02b9\u02bc\7f\2\2"+ - "\u02ba\u02bc\5\u00bd_\2\u02bb\u02b3\3\2\2\2\u02bb\u02ba\3\2\2\2\u02bc"+ - "\u00c8\3\2\2\2\u02bd\u02be\7c\2\2\u02be\u02bf\7p\2\2\u02bf\u02c0\7k\2"+ - "\2\u02c0\u036a\7o\2\2\u02c1\u02c2\7c\2\2\u02c2\u02c3\7p\2\2\u02c3\u02c4"+ - "\7k\2\2\u02c4\u02c5\7o\2\2\u02c5\u02c6\7c\2\2\u02c6\u02c7\7v\2\2\u02c7"+ - "\u02c8\7q\2\2\u02c8\u036a\7t\2\2\u02c9\u02ca\7d\2\2\u02ca\u02cb\7q\2\2"+ - "\u02cb\u02cc\7q\2\2\u02cc\u036a\7n\2\2\u02cd\u02ce\7e\2\2\u02ce\u02cf"+ - "\7q\2\2\u02cf\u02d0\7n\2\2\u02d0\u02d1\7q\2\2\u02d1\u036a\7t\2\2\u02d2"+ - "\u02d3\7e\2\2\u02d3\u02d4\7q\2\2\u02d4\u02d5\7n\2\2\u02d5\u02d6\7q\2\2"+ - "\u02d6\u02d7\7t\2\2\u02d7\u02d8\7U\2\2\u02d8\u02d9\7v\2\2\u02d9\u02da"+ - "\7c\2\2\u02da\u02db\7v\2\2\u02db\u02dc\7g\2\2\u02dc\u02dd\7N\2\2\u02dd"+ - "\u02de\7k\2\2\u02de\u02df\7u\2\2\u02df\u036a\7v\2\2\u02e0\u02e1\7f\2\2"+ - "\u02e1\u02e2\7k\2\2\u02e2\u02e3\7o\2\2\u02e3\u02e4\7g\2\2\u02e4\u036a"+ - "\7p\2\2\u02e5\u02e6\7f\2\2\u02e6\u02e7\7k\2\2\u02e7\u02e8\7o\2\2\u02e8"+ - "\u02e9\7g\2\2\u02e9\u02ea\7p\2\2\u02ea\u02eb\7Q\2\2\u02eb\u02ec\7h\2\2"+ - "\u02ec\u02ed\7h\2\2\u02ed\u02ee\7u\2\2\u02ee\u02ef\7g\2\2\u02ef\u036a"+ - "\7v\2\2\u02f0\u02f1\7f\2\2\u02f1\u02f2\7k\2\2\u02f2\u02f3\7o\2\2\u02f3"+ - "\u02f4\7g\2\2\u02f4\u02f5\7p\2\2\u02f5\u02f6\7U\2\2\u02f6\u02f7\7k\2\2"+ - "\u02f7\u02f8\7|\2\2\u02f8\u036a\7g\2\2\u02f9\u02fa\7f\2\2\u02fa\u02fb"+ - "\7t\2\2\u02fb\u02fc\7c\2\2\u02fc\u02fd\7y\2\2\u02fd\u02fe\7c\2\2\u02fe"+ - "\u02ff\7d\2\2\u02ff\u0300\7n\2\2\u0300\u036a\7g\2\2\u0301\u0302\7h\2\2"+ - "\u0302\u0303\7t\2\2\u0303\u0304\7c\2\2\u0304\u0305\7e\2\2\u0305\u0306"+ - "\7v\2\2\u0306\u0307\7k\2\2\u0307\u0308\7q\2\2\u0308\u036a\7p\2\2\u0309"+ - "\u030a\7k\2\2\u030a\u036a\7f\2\2\u030b\u030c\7k\2\2\u030c\u030d\7p\2\2"+ - "\u030d\u030e\7v\2\2\u030e\u030f\7g\2\2\u030f\u0310\7i\2\2\u0310\u0311"+ - "\7g\2\2\u0311\u036a\7t\2\2\u0312\u0313\7k\2\2\u0313\u0314\7p\2\2\u0314"+ - "\u0315\7v\2\2\u0315\u0316\7C\2\2\u0316\u0317\7t\2\2\u0317\u0318\7t\2\2"+ - "\u0318\u0319\7c\2\2\u0319\u036a\7{\2\2\u031a\u031b\7k\2\2\u031b\u031c"+ - "\7p\2\2\u031c\u031d\7v\2\2\u031d\u031e\7g\2\2\u031e\u031f\7t\2\2\u031f"+ - "\u0320\7r\2\2\u0320\u0321\7q\2\2\u0321\u0322\7n\2\2\u0322\u0323\7c\2\2"+ - "\u0323\u0324\7v\2\2\u0324\u0325\7q\2\2\u0325\u036a\7t\2\2\u0326\u0327"+ - "\7n\2\2\u0327\u0328\7c\2\2\u0328\u0329\7{\2\2\u0329\u032a\7q\2\2\u032a"+ - "\u032b\7w\2\2\u032b\u036a\7v\2\2\u032c\u032d\7r\2\2\u032d\u032e\7n\2\2"+ - "\u032e\u032f\7w\2\2\u032f\u0330\7t\2\2\u0330\u0331\7c\2\2\u0331\u0332"+ - "\7n\2\2\u0332\u036a\7u\2\2\u0333\u0334\7u\2\2\u0334\u0335\7v\2\2\u0335"+ - "\u0336\7c\2\2\u0336\u0337\7v\2\2\u0337\u0338\7g\2\2\u0338\u0339\7N\2\2"+ - "\u0339\u033a\7k\2\2\u033a\u033b\7u\2\2\u033b\u033c\7v\2\2\u033c\u033d"+ - "\7C\2\2\u033d\u033e\7p\2\2\u033e\u033f\7k\2\2\u033f\u0340\7o\2\2\u0340"+ - "\u0341\7c\2\2\u0341\u0342\7v\2\2\u0342\u0343\7q\2\2\u0343\u036a\7t\2\2"+ - "\u0344\u0345\7u\2\2\u0345\u0346\7v\2\2\u0346\u0347\7t\2\2\u0347\u0348"+ - "\7k\2\2\u0348\u0349\7p\2\2\u0349\u036a\7i\2\2\u034a\u034b\7u\2\2\u034b"+ - "\u034c\7v\2\2\u034c\u034d\7t\2\2\u034d\u034e\7k\2\2\u034e\u034f\7p\2\2"+ - "\u034f\u0350\7i\2\2\u0350\u0351\7C\2\2\u0351\u0352\7t\2\2\u0352\u0353"+ - "\7t\2\2\u0353\u0354\7c\2\2\u0354\u036a\7{\2\2\u0355\u0356\7v\2\2\u0356"+ - "\u0357\7t\2\2\u0357\u0358\7c\2\2\u0358\u0359\7p\2\2\u0359\u035a\7u\2\2"+ - "\u035a\u035b\7k\2\2\u035b\u035c\7v\2\2\u035c\u035d\7k\2\2\u035d\u035e"+ - "\7q\2\2\u035e\u036a\7p\2\2\u035f\u0360\7v\2\2\u0360\u0361\7{\2\2\u0361"+ - "\u0362\7r\2\2\u0362\u0363\7g\2\2\u0363\u0364\7f\2\2\u0364\u0365\7C\2\2"+ - "\u0365\u0366\7t\2\2\u0366\u0367\7t\2\2\u0367\u0368\7c\2\2\u0368\u036a"+ - "\7{\2\2\u0369\u02bd\3\2\2\2\u0369\u02c1\3\2\2\2\u0369\u02c9\3\2\2\2\u0369"+ - "\u02cd\3\2\2\2\u0369\u02d2\3\2\2\2\u0369\u02e0\3\2\2\2\u0369\u02e5\3\2"+ - "\2\2\u0369\u02f0\3\2\2\2\u0369\u02f9\3\2\2\2\u0369\u0301\3\2\2\2\u0369"+ - "\u0309\3\2\2\2\u0369\u030b\3\2\2\2\u0369\u0312\3\2\2\2\u0369\u031a\3\2"+ - "\2\2\u0369\u0326\3\2\2\2\u0369\u032c\3\2\2\2\u0369\u0333\3\2\2\2\u0369"+ - "\u0344\3\2\2\2\u0369\u034a\3\2\2\2\u0369\u0355\3\2\2\2\u0369\u035f\3\2"+ - "\2\2\u036a\u00ca\3\2\2\28\2\u0174\u017a\u017e\u0182\u0186\u018a\u0191"+ - "\u0196\u0198\u019e\u01a2\u01a6\u01ac\u01b1\u01bb\u01bf\u01c5\u01c9\u01d1"+ - "\u01d5\u01db\u01e5\u01e9\u01ef\u01f3\u01f8\u01fb\u01fe\u0203\u0206\u020b"+ - "\u0210\u0218\u0223\u0227\u022c\u0230\u0240\u024a\u0252\u0259\u0260\u0264"+ - "\u0268\u026e\u027b\u028f\u0298\u02a0\u02a5\u02ad\u02bb\u0369\3\b\2\2"; + "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3"+ + "\3\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3\n"+ + "\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21"+ + "\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26"+ + "\3\26\3\27\3\27\3\27\3\30\3\30\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32"+ + "\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\36"+ + "\3\36\3\37\3\37\3 \3 \3 \3!\3!\3!\3\"\3\"\3#\3#\3$\3$\3$\3%\3%\3%\3%\3"+ + "%\3%\3&\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3)\3)"+ + "\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3-"+ + "\3-\3-\3-\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/"+ + "\3/\3/\5/\u017a\n/\3\60\3\60\3\60\3\60\5\60\u0180\n\60\3\61\3\61\5\61"+ + "\u0184\n\61\3\62\3\62\5\62\u0188\n\62\3\63\3\63\5\63\u018c\n\63\3\64\3"+ + "\64\5\64\u0190\n\64\3\65\3\65\3\66\3\66\3\66\5\66\u0197\n\66\3\66\3\66"+ + "\3\66\5\66\u019c\n\66\5\66\u019e\n\66\3\67\3\67\7\67\u01a2\n\67\f\67\16"+ + "\67\u01a5\13\67\3\67\5\67\u01a8\n\67\38\38\58\u01ac\n8\39\39\3:\3:\5:"+ + "\u01b2\n:\3;\6;\u01b5\n;\r;\16;\u01b6\3<\3<\3<\3<\3=\3=\7=\u01bf\n=\f"+ + "=\16=\u01c2\13=\3=\5=\u01c5\n=\3>\3>\3?\3?\5?\u01cb\n?\3@\3@\5@\u01cf"+ + "\n@\3@\3@\3A\3A\7A\u01d5\nA\fA\16A\u01d8\13A\3A\5A\u01db\nA\3B\3B\3C\3"+ + "C\5C\u01e1\nC\3D\3D\3D\3D\3E\3E\7E\u01e9\nE\fE\16E\u01ec\13E\3E\5E\u01ef"+ + "\nE\3F\3F\3G\3G\5G\u01f5\nG\3H\3H\5H\u01f9\nH\3I\3I\3I\5I\u01fe\nI\3I"+ + "\5I\u0201\nI\3I\5I\u0204\nI\3I\3I\3I\5I\u0209\nI\3I\5I\u020c\nI\3I\3I"+ + "\3I\5I\u0211\nI\3I\3I\3I\5I\u0216\nI\3J\3J\3J\3K\3K\3L\5L\u021e\nL\3L"+ + "\3L\3M\3M\3N\3N\3O\3O\3O\5O\u0229\nO\3P\3P\5P\u022d\nP\3P\3P\3P\5P\u0232"+ + "\nP\3P\3P\5P\u0236\nP\3Q\3Q\3Q\3R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3S\5S\u0246"+ + "\nS\3T\3T\3T\3T\3T\3T\3T\3T\5T\u0250\nT\3U\3U\3V\3V\7V\u0256\nV\fV\16"+ + "V\u0259\13V\3V\3V\3W\3W\5W\u025f\nW\3W\3W\3X\6X\u0264\nX\rX\16X\u0265"+ + "\3Y\3Y\5Y\u026a\nY\3Z\3Z\5Z\u026e\nZ\3[\3[\3[\3[\5[\u0274\n[\3\\\3\\\3"+ + "\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\5\\\u0281\n\\\3]\3]\3]\3]\3]\3]\3]"+ + "\3^\3^\3_\3_\3_\3_\3_\3`\3`\7`\u0293\n`\f`\16`\u0296\13`\3a\3a\3a\3a\3"+ + "a\3a\5a\u029e\na\3b\3b\3b\3b\3b\3b\5b\u02a6\nb\3c\6c\u02a9\nc\rc\16c\u02aa"+ + "\3c\3c\3d\3d\3d\3d\5d\u02b3\nd\3d\3d\3d\3d\3e\3e\3e\3e\3e\3e\3e\3e\5e"+ + "\u02c1\ne\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f"+ + "\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3f\5f\u036f\nf\2\2\2g\3\2\3\5"+ + "\2\4\7\2\5\t\2\6\13\2\7\r\2\b\17\2\t\21\2\n\23\2\13\25\2\f\27\2\r\31\2"+ + "\16\33\2\17\35\2\20\37\2\21!\2\22#\2\23%\2\24\'\2\25)\2\26+\2\27-\2\30"+ + "/\2\31\61\2\32\63\2\33\65\2\34\67\2\359\2\36;\2\37=\2 ?\2!A\2\"C\2#E\2"+ + "$G\2%I\2&K\2\'M\2(O\2)Q\2*S\2+U\2,W\2-Y\2.[\2/]\2\60_\2\61a\2\2c\2\2e"+ + "\2\2g\2\2i\2\2k\2\2m\2\2o\2\2q\2\2s\2\2u\2\2w\2\2y\2\2{\2\2}\2\2\177\2"+ + "\2\u0081\2\2\u0083\2\2\u0085\2\2\u0087\2\2\u0089\2\2\u008b\2\2\u008d\2"+ + "\2\u008f\2\62\u0091\2\2\u0093\2\2\u0095\2\2\u0097\2\2\u0099\2\2\u009b"+ + "\2\2\u009d\2\2\u009f\2\2\u00a1\2\2\u00a3\2\2\u00a5\2\63\u00a7\2\64\u00a9"+ + "\2\2\u00ab\2\65\u00ad\2\66\u00af\2\2\u00b1\2\2\u00b3\2\2\u00b5\2\2\u00b7"+ + "\2\2\u00b9\2\2\u00bb\2\2\u00bd\2\67\u00bf\28\u00c1\2\2\u00c3\2\2\u00c5"+ + "\29\u00c7\2:\u00c9\2;\u00cb\2<\3\2\30\4\2NNnn\3\2\63;\4\2ZZzz\5\2\62;"+ + "CHch\3\2\629\4\2DDdd\3\2\62\63\4\2GGgg\4\2--//\6\2FFHHffhh\4\2RRrr\4\2"+ + "))^^\4\2$$^^\4\2^^bb\13\2$$))^^bbddhhppttvv\3\2\62\65\6\2&&C\\aac|\4\2"+ + "\2\u0101\ud802\udc01\3\2\ud802\udc01\3\2\udc02\ue001\7\2&&\62;C\\aac|"+ + "\5\2\13\f\16\17\"\"\u0395\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2"+ + "\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2"+ + "\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3"+ + "\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2"+ + "\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67"+ + "\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2"+ + "\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2"+ + "\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]"+ + "\3\2\2\2\2_\3\2\2\2\2\u008f\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2"+ + "\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c5"+ + "\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\3\u00cd\3\2\2"+ + "\2\5\u00cf\3\2\2\2\7\u00d7\3\2\2\2\t\u00d9\3\2\2\2\13\u00dc\3\2\2\2\r"+ + "\u00de\3\2\2\2\17\u00e0\3\2\2\2\21\u00e2\3\2\2\2\23\u00e5\3\2\2\2\25\u00e7"+ + "\3\2\2\2\27\u00e9\3\2\2\2\31\u00eb\3\2\2\2\33\u00ed\3\2\2\2\35\u00ef\3"+ + "\2\2\2\37\u00f1\3\2\2\2!\u00f3\3\2\2\2#\u00f5\3\2\2\2%\u00f7\3\2\2\2\'"+ + "\u00fa\3\2\2\2)\u00fe\3\2\2\2+\u0101\3\2\2\2-\u0104\3\2\2\2/\u0107\3\2"+ + "\2\2\61\u0109\3\2\2\2\63\u010b\3\2\2\2\65\u0116\3\2\2\2\67\u0119\3\2\2"+ + "\29\u011c\3\2\2\2;\u011e\3\2\2\2=\u0120\3\2\2\2?\u0122\3\2\2\2A\u0125"+ + "\3\2\2\2C\u0128\3\2\2\2E\u012a\3\2\2\2G\u012c\3\2\2\2I\u012f\3\2\2\2K"+ + "\u0135\3\2\2\2M\u013d\3\2\2\2O\u0142\3\2\2\2Q\u0147\3\2\2\2S\u014d\3\2"+ + "\2\2U\u0151\3\2\2\2W\u0156\3\2\2\2Y\u015c\3\2\2\2[\u0163\3\2\2\2]\u0179"+ + "\3\2\2\2_\u017f\3\2\2\2a\u0181\3\2\2\2c\u0185\3\2\2\2e\u0189\3\2\2\2g"+ + "\u018d\3\2\2\2i\u0191\3\2\2\2k\u019d\3\2\2\2m\u019f\3\2\2\2o\u01ab\3\2"+ + "\2\2q\u01ad\3\2\2\2s\u01b1\3\2\2\2u\u01b4\3\2\2\2w\u01b8\3\2\2\2y\u01bc"+ + "\3\2\2\2{\u01c6\3\2\2\2}\u01ca\3\2\2\2\177\u01cc\3\2\2\2\u0081\u01d2\3"+ + "\2\2\2\u0083\u01dc\3\2\2\2\u0085\u01e0\3\2\2\2\u0087\u01e2\3\2\2\2\u0089"+ + "\u01e6\3\2\2\2\u008b\u01f0\3\2\2\2\u008d\u01f4\3\2\2\2\u008f\u01f8\3\2"+ + "\2\2\u0091\u0215\3\2\2\2\u0093\u0217\3\2\2\2\u0095\u021a\3\2\2\2\u0097"+ + "\u021d\3\2\2\2\u0099\u0221\3\2\2\2\u009b\u0223\3\2\2\2\u009d\u0225\3\2"+ + "\2\2\u009f\u0235\3\2\2\2\u00a1\u0237\3\2\2\2\u00a3\u023a\3\2\2\2\u00a5"+ + "\u0245\3\2\2\2\u00a7\u024f\3\2\2\2\u00a9\u0251\3\2\2\2\u00ab\u0253\3\2"+ + "\2\2\u00ad\u025c\3\2\2\2\u00af\u0263\3\2\2\2\u00b1\u0269\3\2\2\2\u00b3"+ + "\u026d\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7\u0280\3\2\2\2\u00b9\u0282\3\2"+ + "\2\2\u00bb\u0289\3\2\2\2\u00bd\u028b\3\2\2\2\u00bf\u0290\3\2\2\2\u00c1"+ + "\u029d\3\2\2\2\u00c3\u02a5\3\2\2\2\u00c5\u02a8\3\2\2\2\u00c7\u02ae\3\2"+ + "\2\2\u00c9\u02c0\3\2\2\2\u00cb\u036e\3\2\2\2\u00cd\u00ce\7.\2\2\u00ce"+ + "\4\3\2\2\2\u00cf\u00d0\7f\2\2\u00d0\u00d1\7g\2\2\u00d1\u00d2\7h\2\2\u00d2"+ + "\u00d3\7c\2\2\u00d3\u00d4\7w\2\2\u00d4\u00d5\7n\2\2\u00d5\u00d6\7v\2\2"+ + "\u00d6\6\3\2\2\2\u00d7\u00d8\7?\2\2\u00d8\b\3\2\2\2\u00d9\u00da\7/\2\2"+ + "\u00da\u00db\7@\2\2\u00db\n\3\2\2\2\u00dc\u00dd\7*\2\2\u00dd\f\3\2\2\2"+ + "\u00de\u00df\7+\2\2\u00df\16\3\2\2\2\u00e0\u00e1\7\60\2\2\u00e1\20\3\2"+ + "\2\2\u00e2\u00e3\7<\2\2\u00e3\u00e4\7<\2\2\u00e4\22\3\2\2\2\u00e5\u00e6"+ + "\7]\2\2\u00e6\24\3\2\2\2\u00e7\u00e8\7_\2\2\u00e8\26\3\2\2\2\u00e9\u00ea"+ + "\7-\2\2\u00ea\30\3\2\2\2\u00eb\u00ec\7/\2\2\u00ec\32\3\2\2\2\u00ed\u00ee"+ + "\7\u0080\2\2\u00ee\34\3\2\2\2\u00ef\u00f0\7#\2\2\u00f0\36\3\2\2\2\u00f1"+ + "\u00f2\7,\2\2\u00f2 \3\2\2\2\u00f3\u00f4\7\61\2\2\u00f4\"\3\2\2\2\u00f5"+ + "\u00f6\7\'\2\2\u00f6$\3\2\2\2\u00f7\u00f8\7>\2\2\u00f8\u00f9\7>\2\2\u00f9"+ + "&\3\2\2\2\u00fa\u00fb\7@\2\2\u00fb\u00fc\7@\2\2\u00fc\u00fd\7@\2\2\u00fd"+ + "(\3\2\2\2\u00fe\u00ff\7@\2\2\u00ff\u0100\7@\2\2\u0100*\3\2\2\2\u0101\u0102"+ + "\7>\2\2\u0102\u0103\7?\2\2\u0103,\3\2\2\2\u0104\u0105\7@\2\2\u0105\u0106"+ + "\7?\2\2\u0106.\3\2\2\2\u0107\u0108\7@\2\2\u0108\60\3\2\2\2\u0109\u010a"+ + "\7>\2\2\u010a\62\3\2\2\2\u010b\u010c\7k\2\2\u010c\u010d\7p\2\2\u010d\u010e"+ + "\7u\2\2\u010e\u010f\7v\2\2\u010f\u0110\7c\2\2\u0110\u0111\7p\2\2\u0111"+ + "\u0112\7e\2\2\u0112\u0113\7g\2\2\u0113\u0114\7q\2\2\u0114\u0115\7h\2\2"+ + "\u0115\64\3\2\2\2\u0116\u0117\7?\2\2\u0117\u0118\7?\2\2\u0118\66\3\2\2"+ + "\2\u0119\u011a\7#\2\2\u011a\u011b\7?\2\2\u011b8\3\2\2\2\u011c\u011d\7"+ + "(\2\2\u011d:\3\2\2\2\u011e\u011f\7`\2\2\u011f<\3\2\2\2\u0120\u0121\7~"+ + "\2\2\u0121>\3\2\2\2\u0122\u0123\7(\2\2\u0123\u0124\7(\2\2\u0124@\3\2\2"+ + "\2\u0125\u0126\7~\2\2\u0126\u0127\7~\2\2\u0127B\3\2\2\2\u0128\u0129\7"+ + "A\2\2\u0129D\3\2\2\2\u012a\u012b\7<\2\2\u012bF\3\2\2\2\u012c\u012d\7A"+ + "\2\2\u012d\u012e\7A\2\2\u012eH\3\2\2\2\u012f\u0130\7e\2\2\u0130\u0131"+ + "\7n\2\2\u0131\u0132\7c\2\2\u0132\u0133\7u\2\2\u0133\u0134\7u\2\2\u0134"+ + "J\3\2\2\2\u0135\u0136\7d\2\2\u0136\u0137\7q\2\2\u0137\u0138\7q\2\2\u0138"+ + "\u0139\7n\2\2\u0139\u013a\7g\2\2\u013a\u013b\7c\2\2\u013b\u013c\7p\2\2"+ + "\u013cL\3\2\2\2\u013d\u013e\7e\2\2\u013e\u013f\7j\2\2\u013f\u0140\7c\2"+ + "\2\u0140\u0141\7t\2\2\u0141N\3\2\2\2\u0142\u0143\7d\2\2\u0143\u0144\7"+ + "{\2\2\u0144\u0145\7v\2\2\u0145\u0146\7g\2\2\u0146P\3\2\2\2\u0147\u0148"+ + "\7u\2\2\u0148\u0149\7j\2\2\u0149\u014a\7q\2\2\u014a\u014b\7t\2\2\u014b"+ + "\u014c\7v\2\2\u014cR\3\2\2\2\u014d\u014e\7k\2\2\u014e\u014f\7p\2\2\u014f"+ + "\u0150\7v\2\2\u0150T\3\2\2\2\u0151\u0152\7n\2\2\u0152\u0153\7q\2\2\u0153"+ + "\u0154\7p\2\2\u0154\u0155\7i\2\2\u0155V\3\2\2\2\u0156\u0157\7h\2\2\u0157"+ + "\u0158\7n\2\2\u0158\u0159\7q\2\2\u0159\u015a\7c\2\2\u015a\u015b\7v\2\2"+ + "\u015bX\3\2\2\2\u015c\u015d\7f\2\2\u015d\u015e\7q\2\2\u015e\u015f\7w\2"+ + "\2\u015f\u0160\7d\2\2\u0160\u0161\7n\2\2\u0161\u0162\7g\2\2\u0162Z\3\2"+ + "\2\2\u0163\u0164\7v\2\2\u0164\u0165\7j\2\2\u0165\u0166\7k\2\2\u0166\u0167"+ + "\7u\2\2\u0167\\\3\2\2\2\u0168\u0169\7X\2\2\u0169\u016a\7q\2\2\u016a\u016b"+ + "\7k\2\2\u016b\u017a\7f\2\2\u016c\u016d\7x\2\2\u016d\u016e\7q\2\2\u016e"+ + "\u016f\7k\2\2\u016f\u017a\7f\2\2\u0170\u0171\7\u00b1\2\2\u0171\u0172\7"+ + "^\2\2\u0172\u0173\7a\2\2\u0173\u0174\7*\2\2\u0174\u0175\7\u30c6\2\2\u0175"+ + "\u0176\7+\2\2\u0176\u0177\7a\2\2\u0177\u0178\7\61\2\2\u0178\u017a\7\u00b1"+ + "\2\2\u0179\u0168\3\2\2\2\u0179\u016c\3\2\2\2\u0179\u0170\3\2\2\2\u017a"+ + "^\3\2\2\2\u017b\u0180\5a\61\2\u017c\u0180\5c\62\2\u017d\u0180\5e\63\2"+ + "\u017e\u0180\5g\64\2\u017f\u017b\3\2\2\2\u017f\u017c\3\2\2\2\u017f\u017d"+ + "\3\2\2\2\u017f\u017e\3\2\2\2\u0180`\3\2\2\2\u0181\u0183\5k\66\2\u0182"+ + "\u0184\5i\65\2\u0183\u0182\3\2\2\2\u0183\u0184\3\2\2\2\u0184b\3\2\2\2"+ + "\u0185\u0187\5w<\2\u0186\u0188\5i\65\2\u0187\u0186\3\2\2\2\u0187\u0188"+ + "\3\2\2\2\u0188d\3\2\2\2\u0189\u018b\5\177@\2\u018a\u018c\5i\65\2\u018b"+ + "\u018a\3\2\2\2\u018b\u018c\3\2\2\2\u018cf\3\2\2\2\u018d\u018f\5\u0087"+ + "D\2\u018e\u0190\5i\65\2\u018f\u018e\3\2\2\2\u018f\u0190\3\2\2\2\u0190"+ + "h\3\2\2\2\u0191\u0192\t\2\2\2\u0192j\3\2\2\2\u0193\u019e\7\62\2\2\u0194"+ + "\u019b\5q9\2\u0195\u0197\5m\67\2\u0196\u0195\3\2\2\2\u0196\u0197\3\2\2"+ + "\2\u0197\u019c\3\2\2\2\u0198\u0199\5u;\2\u0199\u019a\5m\67\2\u019a\u019c"+ + "\3\2\2\2\u019b\u0196\3\2\2\2\u019b\u0198\3\2\2\2\u019c\u019e\3\2\2\2\u019d"+ + "\u0193\3\2\2\2\u019d\u0194\3\2\2\2\u019el\3\2\2\2\u019f\u01a7\5o8\2\u01a0"+ + "\u01a2\5s:\2\u01a1\u01a0\3\2\2\2\u01a2\u01a5\3\2\2\2\u01a3\u01a1\3\2\2"+ + "\2\u01a3\u01a4\3\2\2\2\u01a4\u01a6\3\2\2\2\u01a5\u01a3\3\2\2\2\u01a6\u01a8"+ + "\5o8\2\u01a7\u01a3\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8n\3\2\2\2\u01a9\u01ac"+ + "\7\62\2\2\u01aa\u01ac\5q9\2\u01ab\u01a9\3\2\2\2\u01ab\u01aa\3\2\2\2\u01ac"+ + "p\3\2\2\2\u01ad\u01ae\t\3\2\2\u01aer\3\2\2\2\u01af\u01b2\5o8\2\u01b0\u01b2"+ + "\7a\2\2\u01b1\u01af\3\2\2\2\u01b1\u01b0\3\2\2\2\u01b2t\3\2\2\2\u01b3\u01b5"+ + "\7a\2\2\u01b4\u01b3\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b4\3\2\2\2\u01b6"+ + "\u01b7\3\2\2\2\u01b7v\3\2\2\2\u01b8\u01b9\7\62\2\2\u01b9\u01ba\t\4\2\2"+ + "\u01ba\u01bb\5y=\2\u01bbx\3\2\2\2\u01bc\u01c4\5{>\2\u01bd\u01bf\5}?\2"+ + "\u01be\u01bd\3\2\2\2\u01bf\u01c2\3\2\2\2\u01c0\u01be\3\2\2\2\u01c0\u01c1"+ + "\3\2\2\2\u01c1\u01c3\3\2\2\2\u01c2\u01c0\3\2\2\2\u01c3\u01c5\5{>\2\u01c4"+ + "\u01c0\3\2\2\2\u01c4\u01c5\3\2\2\2\u01c5z\3\2\2\2\u01c6\u01c7\t\5\2\2"+ + "\u01c7|\3\2\2\2\u01c8\u01cb\5{>\2\u01c9\u01cb\7a\2\2\u01ca\u01c8\3\2\2"+ + "\2\u01ca\u01c9\3\2\2\2\u01cb~\3\2\2\2\u01cc\u01ce\7\62\2\2\u01cd\u01cf"+ + "\5u;\2\u01ce\u01cd\3\2\2\2\u01ce\u01cf\3\2\2\2\u01cf\u01d0\3\2\2\2\u01d0"+ + "\u01d1\5\u0081A\2\u01d1\u0080\3\2\2\2\u01d2\u01da\5\u0083B\2\u01d3\u01d5"+ + "\5\u0085C\2\u01d4\u01d3\3\2\2\2\u01d5\u01d8\3\2\2\2\u01d6\u01d4\3\2\2"+ + "\2\u01d6\u01d7\3\2\2\2\u01d7\u01d9\3\2\2\2\u01d8\u01d6\3\2\2\2\u01d9\u01db"+ + "\5\u0083B\2\u01da\u01d6\3\2\2\2\u01da\u01db\3\2\2\2\u01db\u0082\3\2\2"+ + "\2\u01dc\u01dd\t\6\2\2\u01dd\u0084\3\2\2\2\u01de\u01e1\5\u0083B\2\u01df"+ + "\u01e1\7a\2\2\u01e0\u01de\3\2\2\2\u01e0\u01df\3\2\2\2\u01e1\u0086\3\2"+ + "\2\2\u01e2\u01e3\7\62\2\2\u01e3\u01e4\t\7\2\2\u01e4\u01e5\5\u0089E\2\u01e5"+ + "\u0088\3\2\2\2\u01e6\u01ee\5\u008bF\2\u01e7\u01e9\5\u008dG\2\u01e8\u01e7"+ + "\3\2\2\2\u01e9\u01ec\3\2\2\2\u01ea\u01e8\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb"+ + "\u01ed\3\2\2\2\u01ec\u01ea\3\2\2\2\u01ed\u01ef\5\u008bF\2\u01ee\u01ea"+ + "\3\2\2\2\u01ee\u01ef\3\2\2\2\u01ef\u008a\3\2\2\2\u01f0\u01f1\t\b\2\2\u01f1"+ + "\u008c\3\2\2\2\u01f2\u01f5\5\u008bF\2\u01f3\u01f5\7a\2\2\u01f4\u01f2\3"+ + "\2\2\2\u01f4\u01f3\3\2\2\2\u01f5\u008e\3\2\2\2\u01f6\u01f9\5\u0091I\2"+ + "\u01f7\u01f9\5\u009dO\2\u01f8\u01f6\3\2\2\2\u01f8\u01f7\3\2\2\2\u01f9"+ + "\u0090\3\2\2\2\u01fa\u01fb\5m\67\2\u01fb\u01fd\7\60\2\2\u01fc\u01fe\5"+ + "m\67\2\u01fd\u01fc\3\2\2\2\u01fd\u01fe\3\2\2\2\u01fe\u0200\3\2\2\2\u01ff"+ + "\u0201\5\u0093J\2\u0200\u01ff\3\2\2\2\u0200\u0201\3\2\2\2\u0201\u0203"+ + "\3\2\2\2\u0202\u0204\5\u009bN\2\u0203\u0202\3\2\2\2\u0203\u0204\3\2\2"+ + "\2\u0204\u0216\3\2\2\2\u0205\u0206\7\60\2\2\u0206\u0208\5m\67\2\u0207"+ + "\u0209\5\u0093J\2\u0208\u0207\3\2\2\2\u0208\u0209\3\2\2\2\u0209\u020b"+ + "\3\2\2\2\u020a\u020c\5\u009bN\2\u020b\u020a\3\2\2\2\u020b\u020c\3\2\2"+ + "\2\u020c\u0216\3\2\2\2\u020d\u020e\5m\67\2\u020e\u0210\5\u0093J\2\u020f"+ + "\u0211\5\u009bN\2\u0210\u020f\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u0216"+ + "\3\2\2\2\u0212\u0213\5m\67\2\u0213\u0214\5\u009bN\2\u0214\u0216\3\2\2"+ + "\2\u0215\u01fa\3\2\2\2\u0215\u0205\3\2\2\2\u0215\u020d\3\2\2\2\u0215\u0212"+ + "\3\2\2\2\u0216\u0092\3\2\2\2\u0217\u0218\5\u0095K\2\u0218\u0219\5\u0097"+ + "L\2\u0219\u0094\3\2\2\2\u021a\u021b\t\t\2\2\u021b\u0096\3\2\2\2\u021c"+ + "\u021e\5\u0099M\2\u021d\u021c\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u021f"+ + "\3\2\2\2\u021f\u0220\5m\67\2\u0220\u0098\3\2\2\2\u0221\u0222\t\n\2\2\u0222"+ + "\u009a\3\2\2\2\u0223\u0224\t\13\2\2\u0224\u009c\3\2\2\2\u0225\u0226\5"+ + "\u009fP\2\u0226\u0228\5\u00a1Q\2\u0227\u0229\5\u009bN\2\u0228\u0227\3"+ + "\2\2\2\u0228\u0229\3\2\2\2\u0229\u009e\3\2\2\2\u022a\u022c\5w<\2\u022b"+ + "\u022d\7\60\2\2\u022c\u022b\3\2\2\2\u022c\u022d\3\2\2\2\u022d\u0236\3"+ + "\2\2\2\u022e\u022f\7\62\2\2\u022f\u0231\t\4\2\2\u0230\u0232\5y=\2\u0231"+ + "\u0230\3\2\2\2\u0231\u0232\3\2\2\2\u0232\u0233\3\2\2\2\u0233\u0234\7\60"+ + "\2\2\u0234\u0236\5y=\2\u0235\u022a\3\2\2\2\u0235\u022e\3\2\2\2\u0236\u00a0"+ + "\3\2\2\2\u0237\u0238\5\u00a3R\2\u0238\u0239\5\u0097L\2\u0239\u00a2\3\2"+ + "\2\2\u023a\u023b\t\f\2\2\u023b\u00a4\3\2\2\2\u023c\u023d\7v\2\2\u023d"+ + "\u023e\7t\2\2\u023e\u023f\7w\2\2\u023f\u0246\7g\2\2\u0240\u0241\7h\2\2"+ + "\u0241\u0242\7c\2\2\u0242\u0243\7n\2\2\u0243\u0244\7u\2\2\u0244\u0246"+ + "\7g\2\2\u0245\u023c\3\2\2\2\u0245\u0240\3\2\2\2\u0246\u00a6\3\2\2\2\u0247"+ + "\u0248\7)\2\2\u0248\u0249\5\u00a9U\2\u0249\u024a\7)\2\2\u024a\u0250\3"+ + "\2\2\2\u024b\u024c\7)\2\2\u024c\u024d\5\u00b5[\2\u024d\u024e\7)\2\2\u024e"+ + "\u0250\3\2\2\2\u024f\u0247\3\2\2\2\u024f\u024b\3\2\2\2\u0250\u00a8\3\2"+ + "\2\2\u0251\u0252\n\r\2\2\u0252\u00aa\3\2\2\2\u0253\u0257\7b\2\2\u0254"+ + "\u0256\5\u00b3Z\2\u0255\u0254\3\2\2\2\u0256\u0259\3\2\2\2\u0257\u0255"+ + "\3\2\2\2\u0257\u0258\3\2\2\2\u0258\u025a\3\2\2\2\u0259\u0257\3\2\2\2\u025a"+ + "\u025b\7b\2\2\u025b\u00ac\3\2\2\2\u025c\u025e\7$\2\2\u025d\u025f\5\u00af"+ + "X\2\u025e\u025d\3\2\2\2\u025e\u025f\3\2\2\2\u025f\u0260\3\2\2\2\u0260"+ + "\u0261\7$\2\2\u0261\u00ae\3\2\2\2\u0262\u0264\5\u00b1Y\2\u0263\u0262\3"+ + "\2\2\2\u0264\u0265\3\2\2\2\u0265\u0263\3\2\2\2\u0265\u0266\3\2\2\2\u0266"+ + "\u00b0\3\2\2\2\u0267\u026a\n\16\2\2\u0268\u026a\5\u00b5[\2\u0269\u0267"+ + "\3\2\2\2\u0269\u0268\3\2\2\2\u026a\u00b2\3\2\2\2\u026b\u026e\n\17\2\2"+ + "\u026c\u026e\5\u00b5[\2\u026d\u026b\3\2\2\2\u026d\u026c\3\2\2\2\u026e"+ + "\u00b4\3\2\2\2\u026f\u0270\7^\2\2\u0270\u0274\t\20\2\2\u0271\u0274\5\u00b7"+ + "\\\2\u0272\u0274\5\u00b9]\2\u0273\u026f\3\2\2\2\u0273\u0271\3\2\2\2\u0273"+ + "\u0272\3\2\2\2\u0274\u00b6\3\2\2\2\u0275\u0276\7^\2\2\u0276\u0281\5\u0083"+ + "B\2\u0277\u0278\7^\2\2\u0278\u0279\5\u0083B\2\u0279\u027a\5\u0083B\2\u027a"+ + "\u0281\3\2\2\2\u027b\u027c\7^\2\2\u027c\u027d\5\u00bb^\2\u027d\u027e\5"+ + "\u0083B\2\u027e\u027f\5\u0083B\2\u027f\u0281\3\2\2\2\u0280\u0275\3\2\2"+ + "\2\u0280\u0277\3\2\2\2\u0280\u027b\3\2\2\2\u0281\u00b8\3\2\2\2\u0282\u0283"+ + "\7^\2\2\u0283\u0284\7w\2\2\u0284\u0285\5{>\2\u0285\u0286\5{>\2\u0286\u0287"+ + "\5{>\2\u0287\u0288\5{>\2\u0288\u00ba\3\2\2\2\u0289\u028a\t\21\2\2\u028a"+ + "\u00bc\3\2\2\2\u028b\u028c\7p\2\2\u028c\u028d\7w\2\2\u028d\u028e\7n\2"+ + "\2\u028e\u028f\7n\2\2\u028f\u00be\3\2\2\2\u0290\u0294\5\u00c1a\2\u0291"+ + "\u0293\5\u00c3b\2\u0292\u0291\3\2\2\2\u0293\u0296\3\2\2\2\u0294\u0292"+ + "\3\2\2\2\u0294\u0295\3\2\2\2\u0295\u00c0\3\2\2\2\u0296\u0294\3\2\2\2\u0297"+ + "\u029e\t\22\2\2\u0298\u0299\n\23\2\2\u0299\u029e\6a\2\2\u029a\u029b\t"+ + "\24\2\2\u029b\u029c\t\25\2\2\u029c\u029e\6a\3\2\u029d\u0297\3\2\2\2\u029d"+ + "\u0298\3\2\2\2\u029d\u029a\3\2\2\2\u029e\u00c2\3\2\2\2\u029f\u02a6\t\26"+ + "\2\2\u02a0\u02a1\n\23\2\2\u02a1\u02a6\6b\4\2\u02a2\u02a3\t\24\2\2\u02a3"+ + "\u02a4\t\25\2\2\u02a4\u02a6\6b\5\2\u02a5\u029f\3\2\2\2\u02a5\u02a0\3\2"+ + "\2\2\u02a5\u02a2\3\2\2\2\u02a6\u00c4\3\2\2\2\u02a7\u02a9\t\27\2\2\u02a8"+ + "\u02a7\3\2\2\2\u02a9\u02aa\3\2\2\2\u02aa\u02a8\3\2\2\2\u02aa\u02ab\3\2"+ + "\2\2\u02ab\u02ac\3\2\2\2\u02ac\u02ad\bc\2\2\u02ad\u00c6\3\2\2\2\u02ae"+ + "\u02b2\7B\2\2\u02af\u02b0\5\u00c9e\2\u02b0\u02b1\7<\2\2\u02b1\u02b3\3"+ + "\2\2\2\u02b2\u02af\3\2\2\2\u02b2\u02b3\3\2\2\2\u02b3\u02b4\3\2\2\2\u02b4"+ + "\u02b5\5\u00cbf\2\u02b5\u02b6\7\61\2\2\u02b6\u02b7\5\u00bf`\2\u02b7\u00c8"+ + "\3\2\2\2\u02b8\u02b9\7c\2\2\u02b9\u02ba\7p\2\2\u02ba\u02bb\7f\2\2\u02bb"+ + "\u02bc\7t\2\2\u02bc\u02bd\7q\2\2\u02bd\u02be\7k\2\2\u02be\u02c1\7f\2\2"+ + "\u02bf\u02c1\5\u00bf`\2\u02c0\u02b8\3\2\2\2\u02c0\u02bf\3\2\2\2\u02c1"+ + "\u00ca\3\2\2\2\u02c2\u02c3\7c\2\2\u02c3\u02c4\7p\2\2\u02c4\u02c5\7k\2"+ + "\2\u02c5\u036f\7o\2\2\u02c6\u02c7\7c\2\2\u02c7\u02c8\7p\2\2\u02c8\u02c9"+ + "\7k\2\2\u02c9\u02ca\7o\2\2\u02ca\u02cb\7c\2\2\u02cb\u02cc\7v\2\2\u02cc"+ + "\u02cd\7q\2\2\u02cd\u036f\7t\2\2\u02ce\u02cf\7d\2\2\u02cf\u02d0\7q\2\2"+ + "\u02d0\u02d1\7q\2\2\u02d1\u036f\7n\2\2\u02d2\u02d3\7e\2\2\u02d3\u02d4"+ + "\7q\2\2\u02d4\u02d5\7n\2\2\u02d5\u02d6\7q\2\2\u02d6\u036f\7t\2\2\u02d7"+ + "\u02d8\7e\2\2\u02d8\u02d9\7q\2\2\u02d9\u02da\7n\2\2\u02da\u02db\7q\2\2"+ + "\u02db\u02dc\7t\2\2\u02dc\u02dd\7U\2\2\u02dd\u02de\7v\2\2\u02de\u02df"+ + "\7c\2\2\u02df\u02e0\7v\2\2\u02e0\u02e1\7g\2\2\u02e1\u02e2\7N\2\2\u02e2"+ + "\u02e3\7k\2\2\u02e3\u02e4\7u\2\2\u02e4\u036f\7v\2\2\u02e5\u02e6\7f\2\2"+ + "\u02e6\u02e7\7k\2\2\u02e7\u02e8\7o\2\2\u02e8\u02e9\7g\2\2\u02e9\u036f"+ + "\7p\2\2\u02ea\u02eb\7f\2\2\u02eb\u02ec\7k\2\2\u02ec\u02ed\7o\2\2\u02ed"+ + "\u02ee\7g\2\2\u02ee\u02ef\7p\2\2\u02ef\u02f0\7Q\2\2\u02f0\u02f1\7h\2\2"+ + "\u02f1\u02f2\7h\2\2\u02f2\u02f3\7u\2\2\u02f3\u02f4\7g\2\2\u02f4\u036f"+ + "\7v\2\2\u02f5\u02f6\7f\2\2\u02f6\u02f7\7k\2\2\u02f7\u02f8\7o\2\2\u02f8"+ + "\u02f9\7g\2\2\u02f9\u02fa\7p\2\2\u02fa\u02fb\7U\2\2\u02fb\u02fc\7k\2\2"+ + "\u02fc\u02fd\7|\2\2\u02fd\u036f\7g\2\2\u02fe\u02ff\7f\2\2\u02ff\u0300"+ + "\7t\2\2\u0300\u0301\7c\2\2\u0301\u0302\7y\2\2\u0302\u0303\7c\2\2\u0303"+ + "\u0304\7d\2\2\u0304\u0305\7n\2\2\u0305\u036f\7g\2\2\u0306\u0307\7h\2\2"+ + "\u0307\u0308\7t\2\2\u0308\u0309\7c\2\2\u0309\u030a\7e\2\2\u030a\u030b"+ + "\7v\2\2\u030b\u030c\7k\2\2\u030c\u030d\7q\2\2\u030d\u036f\7p\2\2\u030e"+ + "\u030f\7k\2\2\u030f\u036f\7f\2\2\u0310\u0311\7k\2\2\u0311\u0312\7p\2\2"+ + "\u0312\u0313\7v\2\2\u0313\u0314\7g\2\2\u0314\u0315\7i\2\2\u0315\u0316"+ + "\7g\2\2\u0316\u036f\7t\2\2\u0317\u0318\7k\2\2\u0318\u0319\7p\2\2\u0319"+ + "\u031a\7v\2\2\u031a\u031b\7C\2\2\u031b\u031c\7t\2\2\u031c\u031d\7t\2\2"+ + "\u031d\u031e\7c\2\2\u031e\u036f\7{\2\2\u031f\u0320\7k\2\2\u0320\u0321"+ + "\7p\2\2\u0321\u0322\7v\2\2\u0322\u0323\7g\2\2\u0323\u0324\7t\2\2\u0324"+ + "\u0325\7r\2\2\u0325\u0326\7q\2\2\u0326\u0327\7n\2\2\u0327\u0328\7c\2\2"+ + "\u0328\u0329\7v\2\2\u0329\u032a\7q\2\2\u032a\u036f\7t\2\2\u032b\u032c"+ + "\7n\2\2\u032c\u032d\7c\2\2\u032d\u032e\7{\2\2\u032e\u032f\7q\2\2\u032f"+ + "\u0330\7w\2\2\u0330\u036f\7v\2\2\u0331\u0332\7r\2\2\u0332\u0333\7n\2\2"+ + "\u0333\u0334\7w\2\2\u0334\u0335\7t\2\2\u0335\u0336\7c\2\2\u0336\u0337"+ + "\7n\2\2\u0337\u036f\7u\2\2\u0338\u0339\7u\2\2\u0339\u033a\7v\2\2\u033a"+ + "\u033b\7c\2\2\u033b\u033c\7v\2\2\u033c\u033d\7g\2\2\u033d\u033e\7N\2\2"+ + "\u033e\u033f\7k\2\2\u033f\u0340\7u\2\2\u0340\u0341\7v\2\2\u0341\u0342"+ + "\7C\2\2\u0342\u0343\7p\2\2\u0343\u0344\7k\2\2\u0344\u0345\7o\2\2\u0345"+ + "\u0346\7c\2\2\u0346\u0347\7v\2\2\u0347\u0348\7q\2\2\u0348\u036f\7t\2\2"+ + "\u0349\u034a\7u\2\2\u034a\u034b\7v\2\2\u034b\u034c\7t\2\2\u034c\u034d"+ + "\7k\2\2\u034d\u034e\7p\2\2\u034e\u036f\7i\2\2\u034f\u0350\7u\2\2\u0350"+ + "\u0351\7v\2\2\u0351\u0352\7t\2\2\u0352\u0353\7k\2\2\u0353\u0354\7p\2\2"+ + "\u0354\u0355\7i\2\2\u0355\u0356\7C\2\2\u0356\u0357\7t\2\2\u0357\u0358"+ + "\7t\2\2\u0358\u0359\7c\2\2\u0359\u036f\7{\2\2\u035a\u035b\7v\2\2\u035b"+ + "\u035c\7t\2\2\u035c\u035d\7c\2\2\u035d\u035e\7p\2\2\u035e\u035f\7u\2\2"+ + "\u035f\u0360\7k\2\2\u0360\u0361\7v\2\2\u0361\u0362\7k\2\2\u0362\u0363"+ + "\7q\2\2\u0363\u036f\7p\2\2\u0364\u0365\7v\2\2\u0365\u0366\7{\2\2\u0366"+ + "\u0367\7r\2\2\u0367\u0368\7g\2\2\u0368\u0369\7f\2\2\u0369\u036a\7C\2\2"+ + "\u036a\u036b\7t\2\2\u036b\u036c\7t\2\2\u036c\u036d\7c\2\2\u036d\u036f"+ + "\7{\2\2\u036e\u02c2\3\2\2\2\u036e\u02c6\3\2\2\2\u036e\u02ce\3\2\2\2\u036e"+ + "\u02d2\3\2\2\2\u036e\u02d7\3\2\2\2\u036e\u02e5\3\2\2\2\u036e\u02ea\3\2"+ + "\2\2\u036e\u02f5\3\2\2\2\u036e\u02fe\3\2\2\2\u036e\u0306\3\2\2\2\u036e"+ + "\u030e\3\2\2\2\u036e\u0310\3\2\2\2\u036e\u0317\3\2\2\2\u036e\u031f\3\2"+ + "\2\2\u036e\u032b\3\2\2\2\u036e\u0331\3\2\2\2\u036e\u0338\3\2\2\2\u036e"+ + "\u0349\3\2\2\2\u036e\u034f\3\2\2\2\u036e\u035a\3\2\2\2\u036e\u0364\3\2"+ + "\2\2\u036f\u00cc\3\2\2\28\2\u0179\u017f\u0183\u0187\u018b\u018f\u0196"+ + "\u019b\u019d\u01a3\u01a7\u01ab\u01b1\u01b6\u01c0\u01c4\u01ca\u01ce\u01d6"+ + "\u01da\u01e0\u01ea\u01ee\u01f4\u01f8\u01fd\u0200\u0203\u0208\u020b\u0210"+ + "\u0215\u021d\u0228\u022c\u0231\u0235\u0245\u024f\u0257\u025e\u0265\u0269"+ + "\u026d\u0273\u0280\u0294\u029d\u02a5\u02aa\u02b2\u02c0\u036e\3\b\2\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens index 4d9b950b..f80b7e6c 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens @@ -41,20 +41,21 @@ T__39=40 T__40=41 T__41=42 T__42=43 -THIS=44 -VoidLiteral=45 -IntegerLiteral=46 -FloatingPointLiteral=47 -BooleanLiteral=48 -CharacterLiteral=49 -SingleQuoteString=50 -DoubleQuoteString=51 -NullLiteral=52 -Identifier=53 -WS=54 -ResourceReference=55 -PackageName=56 -ResourceType=57 +T__43=44 +THIS=45 +VoidLiteral=46 +IntegerLiteral=47 +FloatingPointLiteral=48 +BooleanLiteral=49 +CharacterLiteral=50 +SingleQuoteString=51 +DoubleQuoteString=52 +NullLiteral=53 +Identifier=54 +WS=55 +ResourceReference=56 +PackageName=57 +ResourceType=58 ','=1 'default'=2 '='=3 @@ -62,41 +63,42 @@ ResourceType=57 '('=5 ')'=6 '.'=7 -'['=8 -']'=9 -'+'=10 -'-'=11 -'~'=12 -'!'=13 -'*'=14 -'/'=15 -'%'=16 -'<<'=17 -'>>>'=18 -'>>'=19 -'<='=20 -'>='=21 -'>'=22 -'<'=23 -'instanceof'=24 -'=='=25 -'!='=26 -'&'=27 -'^'=28 -'|'=29 -'&&'=30 -'||'=31 -'?'=32 -':'=33 -'??'=34 -'class'=35 -'boolean'=36 -'char'=37 -'byte'=38 -'short'=39 -'int'=40 -'long'=41 -'float'=42 -'double'=43 -'this'=44 -'null'=52 +'::'=8 +'['=9 +']'=10 +'+'=11 +'-'=12 +'~'=13 +'!'=14 +'*'=15 +'/'=16 +'%'=17 +'<<'=18 +'>>>'=19 +'>>'=20 +'<='=21 +'>='=22 +'>'=23 +'<'=24 +'instanceof'=25 +'=='=26 +'!='=27 +'&'=28 +'^'=29 +'|'=30 +'&&'=31 +'||'=32 +'?'=33 +':'=34 +'??'=35 +'class'=36 +'boolean'=37 +'char'=38 +'byte'=39 +'short'=40 +'int'=41 +'long'=42 +'float'=43 +'double'=44 +'this'=45 +'null'=53 diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java index d2b28e54..29edb7cb 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java @@ -10,43 +10,43 @@ import org.antlr.v4.runtime.tree.ParseTreeListener; */ public interface BindingExpressionListener extends ParseTreeListener { /** - * Enter a parse tree produced by the {@code BracketOp} + * Enter a parse tree produced by the {@code CastOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); + void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); /** - * Exit a parse tree produced by the {@code BracketOp} + * Exit a parse tree produced by the {@code CastOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); + void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); /** - * Enter a parse tree produced by the {@code Resource} + * Enter a parse tree produced by the {@code ComparisonOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx); + void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); /** - * Exit a parse tree produced by the {@code Resource} + * Exit a parse tree produced by the {@code ComparisonOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx); + void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); /** - * Enter a parse tree produced by the {@code CastOp} + * Enter a parse tree produced by the {@code BracketOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); + void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); /** - * Exit a parse tree produced by the {@code CastOp} + * Exit a parse tree produced by the {@code BracketOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); + void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); /** * Enter a parse tree produced by the {@code UnaryOp} @@ -62,17 +62,43 @@ public interface BindingExpressionListener extends ParseTreeListener { void exitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx); /** - * Enter a parse tree produced by the {@code AndOrOp} + * Enter a parse tree produced by the {@code Resource} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); + void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx); /** - * Exit a parse tree produced by the {@code AndOrOp} + * Exit a parse tree produced by the {@code Resource} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); + void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx); + + /** + * Enter a parse tree produced by the {@code QuestionQuestionOp} + * labeled alternative in {@link BindingExpressionParser#expression}. + * @param ctx the parse tree + */ + void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); + /** + * Exit a parse tree produced by the {@code QuestionQuestionOp} + * labeled alternative in {@link BindingExpressionParser#expression}. + * @param ctx the parse tree + */ + void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); + + /** + * Enter a parse tree produced by the {@code Grouping} + * labeled alternative in {@link BindingExpressionParser#expression}. + * @param ctx the parse tree + */ + void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); + /** + * Exit a parse tree produced by the {@code Grouping} + * labeled alternative in {@link BindingExpressionParser#expression}. + * @param ctx the parse tree + */ + void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); /** * Enter a parse tree produced by the {@code MethodInvocation} @@ -88,30 +114,30 @@ public interface BindingExpressionListener extends ParseTreeListener { void exitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx); /** - * Enter a parse tree produced by the {@code Primary} + * Enter a parse tree produced by the {@code BitShiftOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); + void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); /** - * Exit a parse tree produced by the {@code Primary} + * Exit a parse tree produced by the {@code BitShiftOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); + void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); /** - * Enter a parse tree produced by the {@code Grouping} + * Enter a parse tree produced by the {@code AndOrOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); + void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); /** - * Exit a parse tree produced by the {@code Grouping} + * Exit a parse tree produced by the {@code AndOrOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); + void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); /** * Enter a parse tree produced by the {@code TernaryOp} @@ -127,17 +153,17 @@ public interface BindingExpressionListener extends ParseTreeListener { void exitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx); /** - * Enter a parse tree produced by the {@code ComparisonOp} + * Enter a parse tree produced by the {@code Primary} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); + void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); /** - * Exit a parse tree produced by the {@code ComparisonOp} + * Exit a parse tree produced by the {@code Primary} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); + void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); /** * Enter a parse tree produced by the {@code DotOp} @@ -166,43 +192,30 @@ public interface BindingExpressionListener extends ParseTreeListener { void exitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx); /** - * Enter a parse tree produced by the {@code QuestionQuestionOp} - * labeled alternative in {@link BindingExpressionParser#expression}. - * @param ctx the parse tree - */ - void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); - /** - * Exit a parse tree produced by the {@code QuestionQuestionOp} - * labeled alternative in {@link BindingExpressionParser#expression}. - * @param ctx the parse tree - */ - void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); - - /** - * Enter a parse tree produced by the {@code BitShiftOp} + * Enter a parse tree produced by the {@code InstanceOfOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); + void enterInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx); /** - * Exit a parse tree produced by the {@code BitShiftOp} + * Exit a parse tree produced by the {@code InstanceOfOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); + void exitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx); /** - * Enter a parse tree produced by the {@code InstanceOfOp} + * Enter a parse tree produced by the {@code FunctionRef} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void enterInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx); + void enterFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx); /** - * Exit a parse tree produced by the {@code InstanceOfOp} + * Exit a parse tree produced by the {@code FunctionRef} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree */ - void exitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx); + void exitFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx); /** * Enter a parse tree produced by the {@code BinaryOp} @@ -244,30 +257,30 @@ public interface BindingExpressionListener extends ParseTreeListener { void exitRootLambda(@NotNull BindingExpressionParser.RootLambdaContext ctx); /** - * Enter a parse tree produced by the {@code LambdaParameterList} + * Enter a parse tree produced by the {@code SingleLambdaParameter} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree */ - void enterLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); + void enterSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); /** - * Exit a parse tree produced by the {@code LambdaParameterList} + * Exit a parse tree produced by the {@code SingleLambdaParameter} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree */ - void exitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); + void exitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); /** - * Enter a parse tree produced by the {@code SingleLambdaParameter} + * Enter a parse tree produced by the {@code LambdaParameterList} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree */ - void enterSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); + void enterLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); /** - * Exit a parse tree produced by the {@code SingleLambdaParameter} + * Exit a parse tree produced by the {@code LambdaParameterList} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree */ - void exitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); + void exitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); /** * Enter a parse tree produced by {@link BindingExpressionParser#bindingSyntax}. diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java index 632507fd..ece7caad 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java @@ -1,13 +1,25 @@ // Generated from BindingExpression.g4 by ANTLR 4.5 package android.databinding.parser; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; +import org.antlr.v4.runtime.FailedPredicateException; +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.RuleVersion; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.misc.NotNull; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; + import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; public class BindingExpressionParser extends Parser { public static final int @@ -16,10 +28,10 @@ public class BindingExpressionParser extends Parser { T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, - T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, THIS=44, VoidLiteral=45, - IntegerLiteral=46, FloatingPointLiteral=47, BooleanLiteral=48, CharacterLiteral=49, - SingleQuoteString=50, DoubleQuoteString=51, NullLiteral=52, Identifier=53, - WS=54, ResourceReference=55, PackageName=56, ResourceType=57; + T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, THIS=45, VoidLiteral=46, + IntegerLiteral=47, FloatingPointLiteral=48, BooleanLiteral=49, CharacterLiteral=50, + SingleQuoteString=51, DoubleQuoteString=52, NullLiteral=53, Identifier=54, + WS=55, ResourceReference=56, PackageName=57, ResourceType=58; public static final int RULE_bindingSyntax = 0, RULE_defaults = 1, RULE_constantValue = 2, RULE_lambdaExpression = 3, RULE_lambdaParameters = 4, RULE_inferredFormalParameterList = 5, RULE_expression = 6, @@ -37,18 +49,18 @@ public class BindingExpressionParser extends Parser { }; private static final String[] _LITERAL_NAMES = { - null, "','", "'default'", "'='", "'->'", "'('", "')'", "'.'", "'['", "']'", - "'+'", "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", "'>>>'", "'>>'", - "'<='", "'>='", "'>'", "'<'", "'instanceof'", "'=='", "'!='", "'&'", "'^'", - "'|'", "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", "'boolean'", "'char'", - "'byte'", "'short'", "'int'", "'long'", "'float'", "'double'", "'this'", - null, null, null, null, null, null, null, "'null'" + null, "','", "'default'", "'='", "'->'", "'('", "')'", "'.'", "'::'", + "'['", "']'", "'+'", "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", + "'>>>'", "'>>'", "'<='", "'>='", "'>'", "'<'", "'instanceof'", "'=='", + "'!='", "'&'", "'^'", "'|'", "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", + "'boolean'", "'char'", "'byte'", "'short'", "'int'", "'long'", "'float'", + "'double'", "'this'", null, null, null, null, null, null, null, "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, "THIS", "VoidLiteral", + null, null, null, null, null, null, null, null, null, "THIS", "VoidLiteral", "IntegerLiteral", "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral", "SingleQuoteString", "DoubleQuoteString", "NullLiteral", "Identifier", "WS", "ResourceReference", "PackageName", "ResourceType" @@ -391,40 +403,40 @@ public class BindingExpressionParser extends Parser { super.copyFrom(ctx); } } - public static class LambdaParameterListContext extends LambdaParametersContext { - public InferredFormalParameterListContext params; - public InferredFormalParameterListContext inferredFormalParameterList() { - return getRuleContext(InferredFormalParameterListContext.class,0); - } - public LambdaParameterListContext(LambdaParametersContext ctx) { copyFrom(ctx); } + public static class SingleLambdaParameterContext extends LambdaParametersContext { + public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); } + public SingleLambdaParameterContext(LambdaParametersContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterLambdaParameterList(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterSingleLambdaParameter(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitLambdaParameterList(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitSingleLambdaParameter(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitLambdaParameterList(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitSingleLambdaParameter(this); else return visitor.visitChildren(this); } } - public static class SingleLambdaParameterContext extends LambdaParametersContext { - public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); } - public SingleLambdaParameterContext(LambdaParametersContext ctx) { copyFrom(ctx); } + public static class LambdaParameterListContext extends LambdaParametersContext { + public InferredFormalParameterListContext params; + public InferredFormalParameterListContext inferredFormalParameterList() { + return getRuleContext(InferredFormalParameterListContext.class,0); + } + public LambdaParameterListContext(LambdaParametersContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterSingleLambdaParameter(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterLambdaParameterList(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitSingleLambdaParameter(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitLambdaParameterList(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitSingleLambdaParameter(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitLambdaParameterList(this); else return visitor.visitChildren(this); } } @@ -553,66 +565,72 @@ public class BindingExpressionParser extends Parser { super.copyFrom(ctx); } } - public static class BracketOpContext extends ExpressionContext { - public List<? extends ExpressionContext> expression() { - return getRuleContexts(ExpressionContext.class); + public static class CastOpContext extends ExpressionContext { + public TypeContext type() { + return getRuleContext(TypeContext.class,0); } - public ExpressionContext expression(int i) { - return getRuleContext(ExpressionContext.class,i); + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); } - public BracketOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public CastOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBracketOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterCastOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBracketOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitCastOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBracketOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitCastOp(this); else return visitor.visitChildren(this); } } - public static class ResourceContext extends ExpressionContext { - public ResourcesContext resources() { - return getRuleContext(ResourcesContext.class,0); + public static class ComparisonOpContext extends ExpressionContext { + public ExpressionContext left; + public Token op; + public ExpressionContext right; + public List<? extends ExpressionContext> expression() { + return getRuleContexts(ExpressionContext.class); } - public ResourceContext(ExpressionContext ctx) { copyFrom(ctx); } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public ComparisonOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterResource(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterComparisonOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitResource(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitComparisonOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitResource(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitComparisonOp(this); else return visitor.visitChildren(this); } } - public static class CastOpContext extends ExpressionContext { - public TypeContext type() { - return getRuleContext(TypeContext.class,0); + public static class BracketOpContext extends ExpressionContext { + public List<? extends ExpressionContext> expression() { + return getRuleContexts(ExpressionContext.class); } - public ExpressionContext expression() { - return getRuleContext(ExpressionContext.class,0); + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); } - public CastOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public BracketOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterCastOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBracketOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitCastOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBracketOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitCastOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBracketOp(this); else return visitor.visitChildren(this); } } @@ -636,7 +654,26 @@ public class BindingExpressionParser extends Parser { else return visitor.visitChildren(this); } } - public static class AndOrOpContext extends ExpressionContext { + public static class ResourceContext extends ExpressionContext { + public ResourcesContext resources() { + return getRuleContext(ResourcesContext.class,0); + } + public ResourceContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterResource(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitResource(this); + } + @Override + public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitResource(this); + else return visitor.visitChildren(this); + } + } + public static class QuestionQuestionOpContext extends ExpressionContext { public ExpressionContext left; public Token op; public ExpressionContext right; @@ -646,18 +683,37 @@ public class BindingExpressionParser extends Parser { public ExpressionContext expression(int i) { return getRuleContext(ExpressionContext.class,i); } - public AndOrOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public QuestionQuestionOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterAndOrOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterQuestionQuestionOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitAndOrOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitQuestionQuestionOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitAndOrOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitQuestionQuestionOp(this); + else return visitor.visitChildren(this); + } + } + public static class GroupingContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public GroupingContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterGrouping(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitGrouping(this); + } + @Override + public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitGrouping(this); else return visitor.visitChildren(this); } } @@ -687,48 +743,53 @@ public class BindingExpressionParser extends Parser { else return visitor.visitChildren(this); } } - public static class PrimaryContext extends ExpressionContext { - public LiteralContext literal() { - return getRuleContext(LiteralContext.class,0); - } - public TerminalNode VoidLiteral() { return getToken(BindingExpressionParser.VoidLiteral, 0); } - public IdentifierContext identifier() { - return getRuleContext(IdentifierContext.class,0); + public static class BitShiftOpContext extends ExpressionContext { + public ExpressionContext left; + public Token op; + public ExpressionContext right; + public List<? extends ExpressionContext> expression() { + return getRuleContexts(ExpressionContext.class); } - public ClassExtractionContext classExtraction() { - return getRuleContext(ClassExtractionContext.class,0); + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); } - public PrimaryContext(ExpressionContext ctx) { copyFrom(ctx); } + public BitShiftOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterPrimary(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBitShiftOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitPrimary(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBitShiftOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitPrimary(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBitShiftOp(this); else return visitor.visitChildren(this); } } - public static class GroupingContext extends ExpressionContext { - public ExpressionContext expression() { - return getRuleContext(ExpressionContext.class,0); + public static class AndOrOpContext extends ExpressionContext { + public ExpressionContext left; + public Token op; + public ExpressionContext right; + public List<? extends ExpressionContext> expression() { + return getRuleContexts(ExpressionContext.class); } - public GroupingContext(ExpressionContext ctx) { copyFrom(ctx); } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public AndOrOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterGrouping(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterAndOrOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitGrouping(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitAndOrOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitGrouping(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitAndOrOp(this); else return visitor.visitChildren(this); } } @@ -758,28 +819,29 @@ public class BindingExpressionParser extends Parser { else return visitor.visitChildren(this); } } - public static class ComparisonOpContext extends ExpressionContext { - public ExpressionContext left; - public Token op; - public ExpressionContext right; - public List<? extends ExpressionContext> expression() { - return getRuleContexts(ExpressionContext.class); + public static class PrimaryContext extends ExpressionContext { + public LiteralContext literal() { + return getRuleContext(LiteralContext.class,0); } - public ExpressionContext expression(int i) { - return getRuleContext(ExpressionContext.class,i); + public TerminalNode VoidLiteral() { return getToken(BindingExpressionParser.VoidLiteral, 0); } + public IdentifierContext identifier() { + return getRuleContext(IdentifierContext.class,0); } - public ComparisonOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public ClassExtractionContext classExtraction() { + return getRuleContext(ClassExtractionContext.class,0); + } + public PrimaryContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterComparisonOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterPrimary(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitComparisonOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitPrimary(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitComparisonOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitPrimary(this); else return visitor.visitChildren(this); } } @@ -828,75 +890,45 @@ public class BindingExpressionParser extends Parser { else return visitor.visitChildren(this); } } - public static class QuestionQuestionOpContext extends ExpressionContext { - public ExpressionContext left; - public Token op; - public ExpressionContext right; - public List<? extends ExpressionContext> expression() { - return getRuleContexts(ExpressionContext.class); - } - public ExpressionContext expression(int i) { - return getRuleContext(ExpressionContext.class,i); - } - public QuestionQuestionOpContext(ExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterQuestionQuestionOp(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitQuestionQuestionOp(this); - } - @Override - public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitQuestionQuestionOp(this); - else return visitor.visitChildren(this); - } - } - public static class BitShiftOpContext extends ExpressionContext { - public ExpressionContext left; - public Token op; - public ExpressionContext right; - public List<? extends ExpressionContext> expression() { - return getRuleContexts(ExpressionContext.class); + public static class InstanceOfOpContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); } - public ExpressionContext expression(int i) { - return getRuleContext(ExpressionContext.class,i); + public TypeContext type() { + return getRuleContext(TypeContext.class,0); } - public BitShiftOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public InstanceOfOpContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBitShiftOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterInstanceOfOp(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBitShiftOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitInstanceOfOp(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBitShiftOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitInstanceOfOp(this); else return visitor.visitChildren(this); } } - public static class InstanceOfOpContext extends ExpressionContext { + public static class FunctionRefContext extends ExpressionContext { public ExpressionContext expression() { return getRuleContext(ExpressionContext.class,0); } - public TypeContext type() { - return getRuleContext(TypeContext.class,0); - } - public InstanceOfOpContext(ExpressionContext ctx) { copyFrom(ctx); } + public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); } + public FunctionRefContext(ExpressionContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterInstanceOfOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterFunctionRef(this); } @Override public void exitRule(ParseTreeListener listener) { - if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitInstanceOfOp(this); + if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitFunctionRef(this); } @Override public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) { - if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitInstanceOfOp(this); + if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitFunctionRef(this); else return visitor.visitChildren(this); } } @@ -970,7 +1002,7 @@ public class BindingExpressionParser extends Parser { setState(87); ((UnaryOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__9 || _la==T__10) ) { + if ( !(_la==T__10 || _la==T__11) ) { ((UnaryOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -988,7 +1020,7 @@ public class BindingExpressionParser extends Parser { setState(89); ((UnaryOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__11 || _la==T__12) ) { + if ( !(_la==T__12 || _la==T__13) ) { ((UnaryOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1063,7 +1095,7 @@ public class BindingExpressionParser extends Parser { break; } _ctx.stop = _input.LT(-1); - setState(162); + setState(165); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,9,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -1071,7 +1103,7 @@ public class BindingExpressionParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(160); + setState(163); switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { case 1: { @@ -1083,7 +1115,7 @@ public class BindingExpressionParser extends Parser { setState(103); ((MathOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__14) | (1L << T__15) | (1L << T__16))) != 0)) ) { ((MathOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1103,7 +1135,7 @@ public class BindingExpressionParser extends Parser { setState(106); ((MathOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__9 || _la==T__10) ) { + if ( !(_la==T__10 || _la==T__11) ) { ((MathOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1123,7 +1155,7 @@ public class BindingExpressionParser extends Parser { setState(109); ((BitShiftOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__17) | (1L << T__18))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) ) { ((BitShiftOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1143,7 +1175,7 @@ public class BindingExpressionParser extends Parser { setState(112); ((ComparisonOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23))) != 0)) ) { ((ComparisonOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1163,7 +1195,7 @@ public class BindingExpressionParser extends Parser { setState(115); ((ComparisonOpContext)_localctx).op = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__24 || _la==T__25) ) { + if ( !(_la==T__25 || _la==T__26) ) { ((ComparisonOpContext)_localctx).op = _errHandler.recoverInline(this); } else { consume(); @@ -1181,7 +1213,7 @@ public class BindingExpressionParser extends Parser { setState(117); if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); setState(118); - ((BinaryOpContext)_localctx).op = match(T__26); + ((BinaryOpContext)_localctx).op = match(T__27); setState(119); ((BinaryOpContext)_localctx).right = expression(8); } @@ -1195,7 +1227,7 @@ public class BindingExpressionParser extends Parser { setState(120); if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); setState(121); - ((BinaryOpContext)_localctx).op = match(T__27); + ((BinaryOpContext)_localctx).op = match(T__28); setState(122); ((BinaryOpContext)_localctx).right = expression(7); } @@ -1209,7 +1241,7 @@ public class BindingExpressionParser extends Parser { setState(123); if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); setState(124); - ((BinaryOpContext)_localctx).op = match(T__28); + ((BinaryOpContext)_localctx).op = match(T__29); setState(125); ((BinaryOpContext)_localctx).right = expression(6); } @@ -1223,7 +1255,7 @@ public class BindingExpressionParser extends Parser { setState(126); if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); setState(127); - ((AndOrOpContext)_localctx).op = match(T__29); + ((AndOrOpContext)_localctx).op = match(T__30); setState(128); ((AndOrOpContext)_localctx).right = expression(5); } @@ -1237,7 +1269,7 @@ public class BindingExpressionParser extends Parser { setState(129); if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); setState(130); - ((AndOrOpContext)_localctx).op = match(T__30); + ((AndOrOpContext)_localctx).op = match(T__31); setState(131); ((AndOrOpContext)_localctx).right = expression(4); } @@ -1251,11 +1283,11 @@ public class BindingExpressionParser extends Parser { setState(132); if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); setState(133); - ((TernaryOpContext)_localctx).op = match(T__31); + ((TernaryOpContext)_localctx).op = match(T__32); setState(134); ((TernaryOpContext)_localctx).iftrue = expression(0); setState(135); - match(T__32); + match(T__33); setState(136); ((TernaryOpContext)_localctx).iffalse = expression(2); } @@ -1269,7 +1301,7 @@ public class BindingExpressionParser extends Parser { setState(138); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(139); - ((QuestionQuestionOpContext)_localctx).op = match(T__33); + ((QuestionQuestionOpContext)_localctx).op = match(T__34); setState(140); ((QuestionQuestionOpContext)_localctx).right = expression(2); } @@ -1280,7 +1312,7 @@ public class BindingExpressionParser extends Parser { _localctx = new DotOpContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(141); - if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)"); + if (!(precpred(_ctx, 20))) throw new FailedPredicateException(this, "precpred(_ctx, 20)"); setState(142); match(T__6); setState(143); @@ -1290,62 +1322,75 @@ public class BindingExpressionParser extends Parser { case 14: { - _localctx = new BracketOpContext(new ExpressionContext(_parentctx, _parentState)); + _localctx = new FunctionRefContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(144); - if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); + if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)"); setState(145); match(T__7); setState(146); - expression(0); + match(Identifier); + } + break; + + case 15: + { + _localctx = new BracketOpContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); setState(147); + if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); + setState(148); match(T__8); + setState(149); + expression(0); + setState(150); + match(T__9); } break; - case 15: + case 16: { _localctx = new MethodInvocationContext(new ExpressionContext(_parentctx, _parentState)); ((MethodInvocationContext)_localctx).target = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(149); + setState(152); if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); - setState(150); + setState(153); match(T__6); - setState(151); + setState(154); ((MethodInvocationContext)_localctx).methodName = match(Identifier); - setState(152); + setState(155); match(T__4); - setState(154); + setState(157); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << VoidLiteral) | (1L << IntegerLiteral) | (1L << FloatingPointLiteral) | (1L << BooleanLiteral) | (1L << CharacterLiteral) | (1L << SingleQuoteString) | (1L << DoubleQuoteString) | (1L << NullLiteral) | (1L << Identifier) | (1L << ResourceReference))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << VoidLiteral) | (1L << IntegerLiteral) | (1L << FloatingPointLiteral) | (1L << BooleanLiteral) | (1L << CharacterLiteral) | (1L << SingleQuoteString) | (1L << DoubleQuoteString) | (1L << NullLiteral) | (1L << Identifier) | (1L << ResourceReference))) != 0)) { { - setState(153); + setState(156); ((MethodInvocationContext)_localctx).args = expressionList(); } } - setState(156); + setState(159); match(T__5); } break; - case 16: + case 17: { _localctx = new InstanceOfOpContext(new ExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expression); - setState(157); + setState(160); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(158); - match(T__23); - setState(159); + setState(161); + match(T__24); + setState(162); type(); } break; } } } - setState(164); + setState(167); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,9,_ctx); } @@ -1392,12 +1437,12 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(165); + setState(168); type(); - setState(166); + setState(169); match(T__6); - setState(167); - match(T__34); + setState(170); + match(T__35); } } catch (RecognitionException re) { @@ -1445,21 +1490,21 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(169); + setState(172); expression(0); - setState(174); + setState(177); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__0) { { { - setState(170); + setState(173); match(T__0); - setState(171); + setState(174); expression(0); } } - setState(176); + setState(179); _errHandler.sync(this); _la = _input.LA(1); } @@ -1507,7 +1552,7 @@ public class BindingExpressionParser extends Parser { LiteralContext _localctx = new LiteralContext(_ctx, getState()); enterRule(_localctx, 18, RULE_literal); try { - setState(179); + setState(182); switch (_input.LA(1)) { case IntegerLiteral: case FloatingPointLiteral: @@ -1516,7 +1561,7 @@ public class BindingExpressionParser extends Parser { case NullLiteral: enterOuterAlt(_localctx, 1); { - setState(177); + setState(180); javaLiteral(); } break; @@ -1524,7 +1569,7 @@ public class BindingExpressionParser extends Parser { case DoubleQuoteString: enterOuterAlt(_localctx, 2); { - setState(178); + setState(181); stringLiteral(); } break; @@ -1571,7 +1616,7 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(181); + setState(184); match(Identifier); } } @@ -1619,7 +1664,7 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(183); + setState(186); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << IntegerLiteral) | (1L << FloatingPointLiteral) | (1L << BooleanLiteral) | (1L << CharacterLiteral) | (1L << NullLiteral))) != 0)) ) { _errHandler.recoverInline(this); @@ -1669,7 +1714,7 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(185); + setState(188); _la = _input.LA(1); if ( !(_la==SingleQuoteString || _la==DoubleQuoteString) ) { _errHandler.recoverInline(this); @@ -1722,9 +1767,9 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(187); + setState(190); typeArguments(); - setState(188); + setState(191); explicitGenericInvocationSuffix(); } } @@ -1773,28 +1818,28 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(190); - match(T__22); - setState(191); + setState(193); + match(T__23); + setState(194); type(); - setState(196); + setState(199); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__0) { { { - setState(192); + setState(195); match(T__0); - setState(193); + setState(196); type(); } } - setState(198); + setState(201); _errHandler.sync(this); _la = _input.LA(1); } - setState(199); - match(T__21); + setState(202); + match(T__22); } } catch (RecognitionException re) { @@ -1840,34 +1885,33 @@ public class BindingExpressionParser extends Parser { enterRule(_localctx, 30, RULE_type); try { int _alt; - setState(217); + setState(220); switch (_input.LA(1)) { case Identifier: enterOuterAlt(_localctx, 1); { - setState(201); + setState(204); classOrInterfaceType(); - setState(206); + setState(209); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,13,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(202); - match(T__7); - setState(203); + setState(205); match(T__8); + setState(206); + match(T__9); } } } - setState(208); + setState(211); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,13,_ctx); } } break; - case T__35: case T__36: case T__37: case T__38: @@ -1875,25 +1919,26 @@ public class BindingExpressionParser extends Parser { case T__40: case T__41: case T__42: + case T__43: enterOuterAlt(_localctx, 2); { - setState(209); + setState(212); primitiveType(); - setState(214); + setState(217); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,14,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(210); - match(T__7); - setState(211); + setState(213); match(T__8); + setState(214); + match(T__9); } } } - setState(216); + setState(219); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,14,_ctx); } @@ -1945,9 +1990,9 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(219); + setState(222); match(Identifier); - setState(220); + setState(223); arguments(); } } @@ -1993,18 +2038,18 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(222); + setState(225); match(T__4); - setState(224); + setState(227); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << VoidLiteral) | (1L << IntegerLiteral) | (1L << FloatingPointLiteral) | (1L << BooleanLiteral) | (1L << CharacterLiteral) | (1L << SingleQuoteString) | (1L << DoubleQuoteString) | (1L << NullLiteral) | (1L << Identifier) | (1L << ResourceReference))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << VoidLiteral) | (1L << IntegerLiteral) | (1L << FloatingPointLiteral) | (1L << BooleanLiteral) | (1L << CharacterLiteral) | (1L << SingleQuoteString) | (1L << DoubleQuoteString) | (1L << NullLiteral) | (1L << Identifier) | (1L << ResourceReference))) != 0)) { { - setState(223); + setState(226); expressionList(); } } - setState(226); + setState(229); match(T__5); } } @@ -2060,33 +2105,33 @@ public class BindingExpressionParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(228); + setState(231); identifier(); - setState(230); + setState(233); switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { case 1: { - setState(229); + setState(232); typeArguments(); } break; } - setState(239); + setState(242); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,19,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(232); + setState(235); match(T__6); - setState(233); + setState(236); match(Identifier); - setState(235); + setState(238); switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { case 1: { - setState(234); + setState(237); typeArguments(); } break; @@ -2094,7 +2139,7 @@ public class BindingExpressionParser extends Parser { } } } - setState(241); + setState(244); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,19,_ctx); } @@ -2139,9 +2184,9 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(242); + setState(245); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -2190,13 +2235,13 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(244); + setState(247); match(ResourceReference); - setState(246); + setState(249); switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { case 1: { - setState(245); + setState(248); resourceParameters(); } break; @@ -2244,11 +2289,11 @@ public class BindingExpressionParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(248); + setState(251); match(T__4); - setState(249); + setState(252); expressionList(); - setState(250); + setState(253); match(T__5); } } @@ -2309,22 +2354,25 @@ public class BindingExpressionParser extends Parser { return precpred(_ctx, 1); case 12: - return precpred(_ctx, 19); + return precpred(_ctx, 20); case 13: - return precpred(_ctx, 18); + return precpred(_ctx, 19); case 14: - return precpred(_ctx, 17); + return precpred(_ctx, 18); case 15: + return precpred(_ctx, 17); + + case 16: return precpred(_ctx, 9); } return true; } public static final String _serializedATN = - "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\3;\u00ff\4\2\t\2\4"+ + "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\3<\u0102\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\3\2\5\2\61\n\2"+ @@ -2334,83 +2382,84 @@ public class BindingExpressionParser extends Parser { "\3\b\3\b\5\bg\n\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b"+ "\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3"+ "\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b"+ - "\3\b\3\b\3\b\3\b\5\b\u009d\n\b\3\b\3\b\3\b\3\b\7\b\u00a3\n\b\f\b\16\b"+ - "\u00a6\13\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\7\n\u00af\n\n\f\n\16\n\u00b2\13"+ - "\n\3\13\3\13\5\13\u00b6\n\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\17"+ - "\3\20\3\20\3\20\3\20\7\20\u00c5\n\20\f\20\16\20\u00c8\13\20\3\20\3\20"+ - "\3\21\3\21\3\21\7\21\u00cf\n\21\f\21\16\21\u00d2\13\21\3\21\3\21\3\21"+ - "\7\21\u00d7\n\21\f\21\16\21\u00da\13\21\5\21\u00dc\n\21\3\22\3\22\3\22"+ - "\3\23\3\23\5\23\u00e3\n\23\3\23\3\23\3\24\3\24\5\24\u00e9\n\24\3\24\3"+ - "\24\3\24\5\24\u00ee\n\24\7\24\u00f0\n\24\f\24\16\24\u00f3\13\24\3\25\3"+ - "\25\3\26\3\26\5\26\u00f9\n\26\3\27\3\27\3\27\3\27\3\27\2\2\3\16\30\2\2"+ - "\4\2\6\2\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2\36\2 \2\""+ - "\2$\2&\2(\2*\2,\2\2\13\3\2\f\r\3\2\16\17\3\2\20\22\3\2\23\25\3\2\26\31"+ - "\3\2\33\34\4\2\60\63\66\66\3\2\64\65\3\2&-\u0113\2\63\3\2\2\2\4\65\3\2"+ - "\2\2\6=\3\2\2\2\b?\3\2\2\2\nI\3\2\2\2\fK\3\2\2\2\16f\3\2\2\2\20\u00a7"+ - "\3\2\2\2\22\u00ab\3\2\2\2\24\u00b5\3\2\2\2\26\u00b7\3\2\2\2\30\u00b9\3"+ - "\2\2\2\32\u00bb\3\2\2\2\34\u00bd\3\2\2\2\36\u00c0\3\2\2\2 \u00db\3\2\2"+ - "\2\"\u00dd\3\2\2\2$\u00e0\3\2\2\2&\u00e6\3\2\2\2(\u00f4\3\2\2\2*\u00f6"+ - "\3\2\2\2,\u00fa\3\2\2\2.\60\5\16\b\2/\61\5\4\3\2\60/\3\2\2\2\60\61\3\2"+ - "\2\2\61\64\3\2\2\2\62\64\5\b\5\2\63.\3\2\2\2\63\62\3\2\2\2\64\3\3\2\2"+ - "\2\65\66\7\3\2\2\66\67\7\4\2\2\678\7\5\2\289\5\6\4\29\5\3\2\2\2:>\5\24"+ - "\13\2;>\79\2\2<>\5\26\f\2=:\3\2\2\2=;\3\2\2\2=<\3\2\2\2>\7\3\2\2\2?@\5"+ - "\n\6\2@A\7\6\2\2AB\5\16\b\2B\t\3\2\2\2CJ\7\67\2\2DF\7\7\2\2EG\5\f\7\2"+ - "FE\3\2\2\2FG\3\2\2\2GH\3\2\2\2HJ\7\b\2\2IC\3\2\2\2ID\3\2\2\2J\13\3\2\2"+ - "\2KP\7\67\2\2LM\7\3\2\2MO\7\67\2\2NL\3\2\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2"+ - "\2\2Q\r\3\2\2\2RP\3\2\2\2ST\b\b\1\2TU\7\7\2\2UV\5 \21\2VW\7\b\2\2WX\5"+ - "\16\b\22Xg\3\2\2\2YZ\t\2\2\2Zg\5\16\b\21[\\\t\3\2\2\\g\5\16\b\20]^\7\7"+ - "\2\2^_\5\16\b\2_`\7\b\2\2`g\3\2\2\2ag\5\24\13\2bg\7/\2\2cg\5\26\f\2dg"+ - "\5\20\t\2eg\5*\26\2fS\3\2\2\2fY\3\2\2\2f[\3\2\2\2f]\3\2\2\2fa\3\2\2\2"+ - "fb\3\2\2\2fc\3\2\2\2fd\3\2\2\2fe\3\2\2\2g\u00a4\3\2\2\2hi\f\17\2\2ij\t"+ - "\4\2\2j\u00a3\5\16\b\20kl\f\16\2\2lm\t\2\2\2m\u00a3\5\16\b\17no\f\r\2"+ - "\2op\t\5\2\2p\u00a3\5\16\b\16qr\f\f\2\2rs\t\6\2\2s\u00a3\5\16\b\rtu\f"+ - "\n\2\2uv\t\7\2\2v\u00a3\5\16\b\13wx\f\t\2\2xy\7\35\2\2y\u00a3\5\16\b\n"+ - "z{\f\b\2\2{|\7\36\2\2|\u00a3\5\16\b\t}~\f\7\2\2~\177\7\37\2\2\177\u00a3"+ - "\5\16\b\b\u0080\u0081\f\6\2\2\u0081\u0082\7 \2\2\u0082\u00a3\5\16\b\7"+ - "\u0083\u0084\f\5\2\2\u0084\u0085\7!\2\2\u0085\u00a3\5\16\b\6\u0086\u0087"+ - "\f\4\2\2\u0087\u0088\7\"\2\2\u0088\u0089\5\16\b\2\u0089\u008a\7#\2\2\u008a"+ - "\u008b\5\16\b\4\u008b\u00a3\3\2\2\2\u008c\u008d\f\3\2\2\u008d\u008e\7"+ - "$\2\2\u008e\u00a3\5\16\b\4\u008f\u0090\f\25\2\2\u0090\u0091\7\t\2\2\u0091"+ - "\u00a3\7\67\2\2\u0092\u0093\f\24\2\2\u0093\u0094\7\n\2\2\u0094\u0095\5"+ - "\16\b\2\u0095\u0096\7\13\2\2\u0096\u00a3\3\2\2\2\u0097\u0098\f\23\2\2"+ - "\u0098\u0099\7\t\2\2\u0099\u009a\7\67\2\2\u009a\u009c\7\7\2\2\u009b\u009d"+ - "\5\22\n\2\u009c\u009b\3\2\2\2\u009c\u009d\3\2\2\2\u009d\u009e\3\2\2\2"+ - "\u009e\u00a3\7\b\2\2\u009f\u00a0\f\13\2\2\u00a0\u00a1\7\32\2\2\u00a1\u00a3"+ - "\5 \21\2\u00a2h\3\2\2\2\u00a2k\3\2\2\2\u00a2n\3\2\2\2\u00a2q\3\2\2\2\u00a2"+ - "t\3\2\2\2\u00a2w\3\2\2\2\u00a2z\3\2\2\2\u00a2}\3\2\2\2\u00a2\u0080\3\2"+ - "\2\2\u00a2\u0083\3\2\2\2\u00a2\u0086\3\2\2\2\u00a2\u008c\3\2\2\2\u00a2"+ - "\u008f\3\2\2\2\u00a2\u0092\3\2\2\2\u00a2\u0097\3\2\2\2\u00a2\u009f\3\2"+ - "\2\2\u00a3\u00a6\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5"+ - "\17\3\2\2\2\u00a6\u00a4\3\2\2\2\u00a7\u00a8\5 \21\2\u00a8\u00a9\7\t\2"+ - "\2\u00a9\u00aa\7%\2\2\u00aa\21\3\2\2\2\u00ab\u00b0\5\16\b\2\u00ac\u00ad"+ - "\7\3\2\2\u00ad\u00af\5\16\b\2\u00ae\u00ac\3\2\2\2\u00af\u00b2\3\2\2\2"+ - "\u00b0\u00ae\3\2\2\2\u00b0\u00b1\3\2\2\2\u00b1\23\3\2\2\2\u00b2\u00b0"+ - "\3\2\2\2\u00b3\u00b6\5\30\r\2\u00b4\u00b6\5\32\16\2\u00b5\u00b3\3\2\2"+ - "\2\u00b5\u00b4\3\2\2\2\u00b6\25\3\2\2\2\u00b7\u00b8\7\67\2\2\u00b8\27"+ - "\3\2\2\2\u00b9\u00ba\t\b\2\2\u00ba\31\3\2\2\2\u00bb\u00bc\t\t\2\2\u00bc"+ - "\33\3\2\2\2\u00bd\u00be\5\36\20\2\u00be\u00bf\5\"\22\2\u00bf\35\3\2\2"+ - "\2\u00c0\u00c1\7\31\2\2\u00c1\u00c6\5 \21\2\u00c2\u00c3\7\3\2\2\u00c3"+ - "\u00c5\5 \21\2\u00c4\u00c2\3\2\2\2\u00c5\u00c8\3\2\2\2\u00c6\u00c4\3\2"+ - "\2\2\u00c6\u00c7\3\2\2\2\u00c7\u00c9\3\2\2\2\u00c8\u00c6\3\2\2\2\u00c9"+ - "\u00ca\7\30\2\2\u00ca\37\3\2\2\2\u00cb\u00d0\5&\24\2\u00cc\u00cd\7\n\2"+ - "\2\u00cd\u00cf\7\13\2\2\u00ce\u00cc\3\2\2\2\u00cf\u00d2\3\2\2\2\u00d0"+ - "\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1\u00dc\3\2\2\2\u00d2\u00d0\3\2"+ - "\2\2\u00d3\u00d8\5(\25\2\u00d4\u00d5\7\n\2\2\u00d5\u00d7\7\13\2\2\u00d6"+ - "\u00d4\3\2\2\2\u00d7\u00da\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9\3\2"+ - "\2\2\u00d9\u00dc\3\2\2\2\u00da\u00d8\3\2\2\2\u00db\u00cb\3\2\2\2\u00db"+ - "\u00d3\3\2\2\2\u00dc!\3\2\2\2\u00dd\u00de\7\67\2\2\u00de\u00df\5$\23\2"+ - "\u00df#\3\2\2\2\u00e0\u00e2\7\7\2\2\u00e1\u00e3\5\22\n\2\u00e2\u00e1\3"+ - "\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4\u00e5\7\b\2\2\u00e5"+ - "%\3\2\2\2\u00e6\u00e8\5\26\f\2\u00e7\u00e9\5\36\20\2\u00e8\u00e7\3\2\2"+ - "\2\u00e8\u00e9\3\2\2\2\u00e9\u00f1\3\2\2\2\u00ea\u00eb\7\t\2\2\u00eb\u00ed"+ - "\7\67\2\2\u00ec\u00ee\5\36\20\2\u00ed\u00ec\3\2\2\2\u00ed\u00ee\3\2\2"+ - "\2\u00ee\u00f0\3\2\2\2\u00ef\u00ea\3\2\2\2\u00f0\u00f3\3\2\2\2\u00f1\u00ef"+ - "\3\2\2\2\u00f1\u00f2\3\2\2\2\u00f2\'\3\2\2\2\u00f3\u00f1\3\2\2\2\u00f4"+ - "\u00f5\t\n\2\2\u00f5)\3\2\2\2\u00f6\u00f8\79\2\2\u00f7\u00f9\5,\27\2\u00f8"+ - "\u00f7\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9+\3\2\2\2\u00fa\u00fb\7\7\2\2"+ - "\u00fb\u00fc\5\22\n\2\u00fc\u00fd\7\b\2\2\u00fd-\3\2\2\2\27\60\63=FIP"+ - "f\u009c\u00a2\u00a4\u00b0\u00b5\u00c6\u00d0\u00d8\u00db\u00e2\u00e8\u00ed"+ - "\u00f1\u00f8"; + "\3\b\3\b\3\b\3\b\3\b\3\b\3\b\5\b\u00a0\n\b\3\b\3\b\3\b\3\b\7\b\u00a6\n"+ + "\b\f\b\16\b\u00a9\13\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\7\n\u00b2\n\n\f\n\16"+ + "\n\u00b5\13\n\3\13\3\13\5\13\u00b9\n\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17"+ + "\3\17\3\17\3\20\3\20\3\20\3\20\7\20\u00c8\n\20\f\20\16\20\u00cb\13\20"+ + "\3\20\3\20\3\21\3\21\3\21\7\21\u00d2\n\21\f\21\16\21\u00d5\13\21\3\21"+ + "\3\21\3\21\7\21\u00da\n\21\f\21\16\21\u00dd\13\21\5\21\u00df\n\21\3\22"+ + "\3\22\3\22\3\23\3\23\5\23\u00e6\n\23\3\23\3\23\3\24\3\24\5\24\u00ec\n"+ + "\24\3\24\3\24\3\24\5\24\u00f1\n\24\7\24\u00f3\n\24\f\24\16\24\u00f6\13"+ + "\24\3\25\3\25\3\26\3\26\5\26\u00fc\n\26\3\27\3\27\3\27\3\27\3\27\2\2\3"+ + "\16\30\2\2\4\2\6\2\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2"+ + "\36\2 \2\"\2$\2&\2(\2*\2,\2\2\13\3\2\r\16\3\2\17\20\3\2\21\23\3\2\24\26"+ + "\3\2\27\32\3\2\34\35\4\2\61\64\67\67\3\2\65\66\3\2\'.\u0117\2\63\3\2\2"+ + "\2\4\65\3\2\2\2\6=\3\2\2\2\b?\3\2\2\2\nI\3\2\2\2\fK\3\2\2\2\16f\3\2\2"+ + "\2\20\u00aa\3\2\2\2\22\u00ae\3\2\2\2\24\u00b8\3\2\2\2\26\u00ba\3\2\2\2"+ + "\30\u00bc\3\2\2\2\32\u00be\3\2\2\2\34\u00c0\3\2\2\2\36\u00c3\3\2\2\2 "+ + "\u00de\3\2\2\2\"\u00e0\3\2\2\2$\u00e3\3\2\2\2&\u00e9\3\2\2\2(\u00f7\3"+ + "\2\2\2*\u00f9\3\2\2\2,\u00fd\3\2\2\2.\60\5\16\b\2/\61\5\4\3\2\60/\3\2"+ + "\2\2\60\61\3\2\2\2\61\64\3\2\2\2\62\64\5\b\5\2\63.\3\2\2\2\63\62\3\2\2"+ + "\2\64\3\3\2\2\2\65\66\7\3\2\2\66\67\7\4\2\2\678\7\5\2\289\5\6\4\29\5\3"+ + "\2\2\2:>\5\24\13\2;>\7:\2\2<>\5\26\f\2=:\3\2\2\2=;\3\2\2\2=<\3\2\2\2>"+ + "\7\3\2\2\2?@\5\n\6\2@A\7\6\2\2AB\5\16\b\2B\t\3\2\2\2CJ\78\2\2DF\7\7\2"+ + "\2EG\5\f\7\2FE\3\2\2\2FG\3\2\2\2GH\3\2\2\2HJ\7\b\2\2IC\3\2\2\2ID\3\2\2"+ + "\2J\13\3\2\2\2KP\78\2\2LM\7\3\2\2MO\78\2\2NL\3\2\2\2OR\3\2\2\2PN\3\2\2"+ + "\2PQ\3\2\2\2Q\r\3\2\2\2RP\3\2\2\2ST\b\b\1\2TU\7\7\2\2UV\5 \21\2VW\7\b"+ + "\2\2WX\5\16\b\22Xg\3\2\2\2YZ\t\2\2\2Zg\5\16\b\21[\\\t\3\2\2\\g\5\16\b"+ + "\20]^\7\7\2\2^_\5\16\b\2_`\7\b\2\2`g\3\2\2\2ag\5\24\13\2bg\7\60\2\2cg"+ + "\5\26\f\2dg\5\20\t\2eg\5*\26\2fS\3\2\2\2fY\3\2\2\2f[\3\2\2\2f]\3\2\2\2"+ + "fa\3\2\2\2fb\3\2\2\2fc\3\2\2\2fd\3\2\2\2fe\3\2\2\2g\u00a7\3\2\2\2hi\f"+ + "\17\2\2ij\t\4\2\2j\u00a6\5\16\b\20kl\f\16\2\2lm\t\2\2\2m\u00a6\5\16\b"+ + "\17no\f\r\2\2op\t\5\2\2p\u00a6\5\16\b\16qr\f\f\2\2rs\t\6\2\2s\u00a6\5"+ + "\16\b\rtu\f\n\2\2uv\t\7\2\2v\u00a6\5\16\b\13wx\f\t\2\2xy\7\36\2\2y\u00a6"+ + "\5\16\b\nz{\f\b\2\2{|\7\37\2\2|\u00a6\5\16\b\t}~\f\7\2\2~\177\7 \2\2\177"+ + "\u00a6\5\16\b\b\u0080\u0081\f\6\2\2\u0081\u0082\7!\2\2\u0082\u00a6\5\16"+ + "\b\7\u0083\u0084\f\5\2\2\u0084\u0085\7\"\2\2\u0085\u00a6\5\16\b\6\u0086"+ + "\u0087\f\4\2\2\u0087\u0088\7#\2\2\u0088\u0089\5\16\b\2\u0089\u008a\7$"+ + "\2\2\u008a\u008b\5\16\b\4\u008b\u00a6\3\2\2\2\u008c\u008d\f\3\2\2\u008d"+ + "\u008e\7%\2\2\u008e\u00a6\5\16\b\4\u008f\u0090\f\26\2\2\u0090\u0091\7"+ + "\t\2\2\u0091\u00a6\78\2\2\u0092\u0093\f\25\2\2\u0093\u0094\7\n\2\2\u0094"+ + "\u00a6\78\2\2\u0095\u0096\f\24\2\2\u0096\u0097\7\13\2\2\u0097\u0098\5"+ + "\16\b\2\u0098\u0099\7\f\2\2\u0099\u00a6\3\2\2\2\u009a\u009b\f\23\2\2\u009b"+ + "\u009c\7\t\2\2\u009c\u009d\78\2\2\u009d\u009f\7\7\2\2\u009e\u00a0\5\22"+ + "\n\2\u009f\u009e\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1"+ + "\u00a6\7\b\2\2\u00a2\u00a3\f\13\2\2\u00a3\u00a4\7\33\2\2\u00a4\u00a6\5"+ + " \21\2\u00a5h\3\2\2\2\u00a5k\3\2\2\2\u00a5n\3\2\2\2\u00a5q\3\2\2\2\u00a5"+ + "t\3\2\2\2\u00a5w\3\2\2\2\u00a5z\3\2\2\2\u00a5}\3\2\2\2\u00a5\u0080\3\2"+ + "\2\2\u00a5\u0083\3\2\2\2\u00a5\u0086\3\2\2\2\u00a5\u008c\3\2\2\2\u00a5"+ + "\u008f\3\2\2\2\u00a5\u0092\3\2\2\2\u00a5\u0095\3\2\2\2\u00a5\u009a\3\2"+ + "\2\2\u00a5\u00a2\3\2\2\2\u00a6\u00a9\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a7"+ + "\u00a8\3\2\2\2\u00a8\17\3\2\2\2\u00a9\u00a7\3\2\2\2\u00aa\u00ab\5 \21"+ + "\2\u00ab\u00ac\7\t\2\2\u00ac\u00ad\7&\2\2\u00ad\21\3\2\2\2\u00ae\u00b3"+ + "\5\16\b\2\u00af\u00b0\7\3\2\2\u00b0\u00b2\5\16\b\2\u00b1\u00af\3\2\2\2"+ + "\u00b2\u00b5\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\23"+ + "\3\2\2\2\u00b5\u00b3\3\2\2\2\u00b6\u00b9\5\30\r\2\u00b7\u00b9\5\32\16"+ + "\2\u00b8\u00b6\3\2\2\2\u00b8\u00b7\3\2\2\2\u00b9\25\3\2\2\2\u00ba\u00bb"+ + "\78\2\2\u00bb\27\3\2\2\2\u00bc\u00bd\t\b\2\2\u00bd\31\3\2\2\2\u00be\u00bf"+ + "\t\t\2\2\u00bf\33\3\2\2\2\u00c0\u00c1\5\36\20\2\u00c1\u00c2\5\"\22\2\u00c2"+ + "\35\3\2\2\2\u00c3\u00c4\7\32\2\2\u00c4\u00c9\5 \21\2\u00c5\u00c6\7\3\2"+ + "\2\u00c6\u00c8\5 \21\2\u00c7\u00c5\3\2\2\2\u00c8\u00cb\3\2\2\2\u00c9\u00c7"+ + "\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00cc\3\2\2\2\u00cb\u00c9\3\2\2\2\u00cc"+ + "\u00cd\7\31\2\2\u00cd\37\3\2\2\2\u00ce\u00d3\5&\24\2\u00cf\u00d0\7\13"+ + "\2\2\u00d0\u00d2\7\f\2\2\u00d1\u00cf\3\2\2\2\u00d2\u00d5\3\2\2\2\u00d3"+ + "\u00d1\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4\u00df\3\2\2\2\u00d5\u00d3\3\2"+ + "\2\2\u00d6\u00db\5(\25\2\u00d7\u00d8\7\13\2\2\u00d8\u00da\7\f\2\2\u00d9"+ + "\u00d7\3\2\2\2\u00da\u00dd\3\2\2\2\u00db\u00d9\3\2\2\2\u00db\u00dc\3\2"+ + "\2\2\u00dc\u00df\3\2\2\2\u00dd\u00db\3\2\2\2\u00de\u00ce\3\2\2\2\u00de"+ + "\u00d6\3\2\2\2\u00df!\3\2\2\2\u00e0\u00e1\78\2\2\u00e1\u00e2\5$\23\2\u00e2"+ + "#\3\2\2\2\u00e3\u00e5\7\7\2\2\u00e4\u00e6\5\22\n\2\u00e5\u00e4\3\2\2\2"+ + "\u00e5\u00e6\3\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\u00e8\7\b\2\2\u00e8%\3"+ + "\2\2\2\u00e9\u00eb\5\26\f\2\u00ea\u00ec\5\36\20\2\u00eb\u00ea\3\2\2\2"+ + "\u00eb\u00ec\3\2\2\2\u00ec\u00f4\3\2\2\2\u00ed\u00ee\7\t\2\2\u00ee\u00f0"+ + "\78\2\2\u00ef\u00f1\5\36\20\2\u00f0\u00ef\3\2\2\2\u00f0\u00f1\3\2\2\2"+ + "\u00f1\u00f3\3\2\2\2\u00f2\u00ed\3\2\2\2\u00f3\u00f6\3\2\2\2\u00f4\u00f2"+ + "\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\'\3\2\2\2\u00f6\u00f4\3\2\2\2\u00f7"+ + "\u00f8\t\n\2\2\u00f8)\3\2\2\2\u00f9\u00fb\7:\2\2\u00fa\u00fc\5,\27\2\u00fb"+ + "\u00fa\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc+\3\2\2\2\u00fd\u00fe\7\7\2\2"+ + "\u00fe\u00ff\5\22\n\2\u00ff\u0100\7\b\2\2\u0100-\3\2\2\2\27\60\63=FIP"+ + "f\u009f\u00a5\u00a7\u00b3\u00b8\u00c9\u00d3\u00db\u00de\u00e5\u00eb\u00f0"+ + "\u00f4\u00fb"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java index 11064f47..871a64b6 100644 --- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java +++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java @@ -13,28 +13,28 @@ import org.antlr.v4.runtime.tree.ParseTreeVisitor; */ public interface BindingExpressionVisitor<Result> extends ParseTreeVisitor<Result> { /** - * Visit a parse tree produced by the {@code BracketOp} + * Visit a parse tree produced by the {@code CastOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); + Result visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); /** - * Visit a parse tree produced by the {@code Resource} + * Visit a parse tree produced by the {@code ComparisonOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitResource(@NotNull BindingExpressionParser.ResourceContext ctx); + Result visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); /** - * Visit a parse tree produced by the {@code CastOp} + * Visit a parse tree produced by the {@code BracketOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx); + Result visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx); /** * Visit a parse tree produced by the {@code UnaryOp} @@ -45,84 +45,84 @@ public interface BindingExpressionVisitor<Result> extends ParseTreeVisitor<Resul Result visitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx); /** - * Visit a parse tree produced by the {@code AndOrOp} + * Visit a parse tree produced by the {@code Resource} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); + Result visitResource(@NotNull BindingExpressionParser.ResourceContext ctx); /** - * Visit a parse tree produced by the {@code MethodInvocation} + * Visit a parse tree produced by the {@code QuestionQuestionOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx); + Result visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); /** - * Visit a parse tree produced by the {@code Primary} + * Visit a parse tree produced by the {@code Grouping} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); + Result visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); /** - * Visit a parse tree produced by the {@code Grouping} + * Visit a parse tree produced by the {@code MethodInvocation} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx); + Result visitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx); /** - * Visit a parse tree produced by the {@code TernaryOp} + * Visit a parse tree produced by the {@code BitShiftOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx); + Result visitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); /** - * Visit a parse tree produced by the {@code ComparisonOp} + * Visit a parse tree produced by the {@code AndOrOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx); + Result visitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx); /** - * Visit a parse tree produced by the {@code DotOp} + * Visit a parse tree produced by the {@code TernaryOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx); + Result visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx); /** - * Visit a parse tree produced by the {@code MathOp} + * Visit a parse tree produced by the {@code Primary} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx); + Result visitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx); /** - * Visit a parse tree produced by the {@code QuestionQuestionOp} + * Visit a parse tree produced by the {@code DotOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx); + Result visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx); /** - * Visit a parse tree produced by the {@code BitShiftOp} + * Visit a parse tree produced by the {@code MathOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree * @return the visitor result */ - Result visitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx); + Result visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx); /** * Visit a parse tree produced by the {@code InstanceOfOp} @@ -133,6 +133,14 @@ public interface BindingExpressionVisitor<Result> extends ParseTreeVisitor<Resul Result visitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx); /** + * Visit a parse tree produced by the {@code FunctionRef} + * labeled alternative in {@link BindingExpressionParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + Result visitFunctionRef(@NotNull BindingExpressionParser.FunctionRefContext ctx); + + /** * Visit a parse tree produced by the {@code BinaryOp} * labeled alternative in {@link BindingExpressionParser#expression}. * @param ctx the parse tree @@ -157,20 +165,20 @@ public interface BindingExpressionVisitor<Result> extends ParseTreeVisitor<Resul Result visitRootLambda(@NotNull BindingExpressionParser.RootLambdaContext ctx); /** - * Visit a parse tree produced by the {@code LambdaParameterList} + * Visit a parse tree produced by the {@code SingleLambdaParameter} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree * @return the visitor result */ - Result visitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); + Result visitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); /** - * Visit a parse tree produced by the {@code SingleLambdaParameter} + * Visit a parse tree produced by the {@code LambdaParameterList} * labeled alternative in {@link BindingExpressionParser#lambdaParameters}. * @param ctx the parse tree * @return the visitor result */ - Result visitSingleLambdaParameter(@NotNull BindingExpressionParser.SingleLambdaParameterContext ctx); + Result visitLambdaParameterList(@NotNull BindingExpressionParser.LambdaParameterListContext ctx); /** * Visit a parse tree produced by {@link BindingExpressionParser#bindingSyntax}. diff --git a/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java b/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java index fa773745..746729ec 100644 --- a/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java +++ b/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java @@ -22,7 +22,7 @@ public class ErrorMessages { public static final String UNDEFINED_VARIABLE = "Identifiers must have user defined types from the XML file. %s is missing it"; public static final String CANNOT_FIND_SETTER_CALL = - "Cannot find the setter for attribute '%s' with parameter type %s."; + "Cannot find the setter for attribute '%s' with parameter type %s on %s."; public static final String CANNOT_RESOLVE_TYPE = "Cannot resolve type for %s"; public static final String MULTI_CONFIG_LAYOUT_CLASS_NAME_MISMATCH = diff --git a/databinding.properties b/databinding.properties index 95277f2f..77cf3068 100644 --- a/databinding.properties +++ b/databinding.properties @@ -1,6 +1,6 @@ # global settings for projects kotlinVersion = 1.0.0 -extensionsVersion = 1.0-rc5 +extensionsVersion = 1.1 # we use a public plugin so that it does not need data binding while compiling library androidPublicPluginVersion= 1.5.0 javaTargetCompatibility = 1.6 diff --git a/integration-tests/TestApp/app/src/androidTestApi14/java/android/databinding/testapp/RootTag.java b/integration-tests/TestApp/app/src/androidTestApi14/java/android/databinding/testapp/RootTag.java index 132beb6e..9adc8f30 100644 --- a/integration-tests/TestApp/app/src/androidTestApi14/java/android/databinding/testapp/RootTag.java +++ b/integration-tests/TestApp/app/src/androidTestApi14/java/android/databinding/testapp/RootTag.java @@ -15,21 +15,17 @@ */ package android.databinding.testapp; -import android.databinding.testapp.BaseDataBinderTest; import android.databinding.testapp.databinding.RootTagBinding; +import android.test.UiThreadTest; public class RootTag extends BaseDataBinderTest<RootTagBinding> { public RootTag() { super(RootTagBinding.class); } - @Override - protected void setUp() throws Exception { - super.setUp(); - initBinder(); - } - + @UiThreadTest public void testRootTagSet() throws Throwable { + initBinder(); mBinder.executePendingBindings(); assertEquals("foo", mBinder.textView1.getTag()); assertEquals("hello world", mBinder.textView1.getText().toString()); diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BracketTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BracketTest.java index 136b7ccb..a4cda6a2 100644 --- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BracketTest.java +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BracketTest.java @@ -94,7 +94,7 @@ public class BracketTest extends BaseDataBinderTest<BracketTestBinding> { @UiThreadTest public void testBracketObj() { mBinder.executePendingBindings(); - assertEquals("Hello World", mBinder.indexObj.getText().toString()); + assertEquals("Hello World", mBinder.indexObjView.getText().toString()); assertEquals("Hello", mBinder.sparseArrayTextObj.getText().toString()); } diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/LeakTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/LeakTest.java index 8f63bcc8..5d00b669 100644 --- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/LeakTest.java +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/LeakTest.java @@ -19,6 +19,7 @@ import android.util.Log; import android.widget.FrameLayout; import java.lang.ref.WeakReference; +import java.util.ArrayList; public class LeakTest extends ActivityInstrumentationTestCase2<TestActivity> { WeakReference<LeakTestBinding> mWeakReference = new WeakReference<LeakTestBinding>(null); @@ -63,8 +64,9 @@ public class LeakTest extends ActivityInstrumentationTestCase2<TestActivity> { } }); WeakReference<Object> canary = new WeakReference<Object>(new Object()); + ArrayList<WeakReference<byte[]>> leak = new ArrayList<>(); while (canary.get() != null) { - byte[] b = new byte[1024 * 1024]; + leak.add(new WeakReference<byte[]>(new byte[100])); System.gc(); } assertNull(mWeakReference.get()); diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/ListenerWithDotTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/ListenerWithDotTest.java new file mode 100644 index 00000000..67b244d5 --- /dev/null +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/ListenerWithDotTest.java @@ -0,0 +1,131 @@ +/* + * 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.testapp; + +import android.databinding.ViewStubProxy; +import android.databinding.testapp.databinding.ListenersWithDotBinding; +import android.databinding.testapp.vo.ListenerBindingObject; +import android.databinding.testapp.vo.ListenerBindingObject.Inner; +import android.test.UiThreadTest; +import android.view.View; + +public class ListenerWithDotTest extends BaseDataBinderTest<ListenersWithDotBinding> { + private ListenerBindingObject mBindingObject; + + public ListenerWithDotTest() { + super(ListenersWithDotBinding.class); + } + + @Override + protected void setUp() throws Exception { + mBindingObject = new ListenerBindingObject(getActivity()); + super.setUp(); + initBinder(new Runnable() { + @Override + public void run() { + mBinder.setObj(mBindingObject); + } + }); + ListenerBindingObject.lastClick = 0; + } + + @UiThreadTest + public void testInstanceClick() throws Throwable { + View view = mBinder.click1; + assertEquals(0, ListenerBindingObject.lastClick); + view.callOnClick(); + assertEquals(1, ListenerBindingObject.lastClick); + } + + @UiThreadTest + public void testStaticClick() throws Throwable { + View view = mBinder.click2; + assertEquals(0, ListenerBindingObject.lastClick); + view.callOnClick(); + assertEquals(2, ListenerBindingObject.lastClick); + } + + @UiThreadTest + public void testInstanceClickTwoArgs() throws Throwable { + View view = mBinder.click3; + assertEquals(0, ListenerBindingObject.lastClick); + view.callOnClick(); + assertEquals(3, ListenerBindingObject.lastClick); + assertTrue(view.isClickable()); + ListenerBindingObject.lastClick = 0; + mBindingObject.clickable.set(false); + mBinder.executePendingBindings(); + assertFalse(view.isClickable()); + mBindingObject.useOne.set(true); + mBinder.executePendingBindings(); + assertFalse(view.isClickable()); + mBindingObject.clickable.set(true); + mBinder.executePendingBindings(); + view.callOnClick(); + assertEquals(1, ListenerBindingObject.lastClick); + } + + @UiThreadTest + public void testStaticClickTwoArgs() throws Throwable { + View view = mBinder.click4; + assertEquals(0, ListenerBindingObject.lastClick); + view.callOnClick(); + assertEquals(4, ListenerBindingObject.lastClick); + assertTrue(view.isClickable()); + ListenerBindingObject.lastClick = 0; + mBindingObject.clickable.set(false); + mBinder.executePendingBindings(); + assertFalse(view.isClickable()); + view.setClickable(true); + view.callOnClick(); + assertEquals(4, ListenerBindingObject.lastClick); + } + + @UiThreadTest + public void testClickExpression() throws Throwable { + View view = mBinder.click5; + assertEquals(0, ListenerBindingObject.lastClick); + view.callOnClick(); + assertEquals(2, ListenerBindingObject.lastClick); + ListenerBindingObject.lastClick = 0; + mBindingObject.useOne.set(true); + mBinder.executePendingBindings(); + view.callOnClick(); + assertEquals(1, ListenerBindingObject.lastClick); + } + + @UiThreadTest + public void testInflateListener() throws Throwable { + ViewStubProxy viewStubProxy = mBinder.viewStub; + assertFalse(viewStubProxy.isInflated()); + assertFalse(mBindingObject.inflateCalled); + viewStubProxy.getViewStub().inflate(); + assertTrue(mBindingObject.inflateCalled); + assertTrue(viewStubProxy.isInflated()); + } + + @UiThreadTest + public void testBaseObservableClick() throws Throwable { + View view = mBinder.click6; + Inner inner = new Inner(); + mBinder.setObj2(inner); + mBinder.executePendingBindings(); + assertFalse(inner.clicked); + view.callOnClick(); + assertTrue(inner.clicked); + } +} diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TextViewBindingAdapterTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TextViewBindingAdapterTest.java index c6bc6715..83dfe728 100644 --- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TextViewBindingAdapterTest.java +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TextViewBindingAdapterTest.java @@ -31,6 +31,7 @@ import android.text.method.DialerKeyListener; import android.text.method.DigitsKeyListener; import android.text.method.KeyListener; import android.text.method.TextKeyListener; +import android.widget.EditText; import android.widget.TextView; public class TextViewBindingAdapterTest @@ -315,4 +316,14 @@ public class TextViewBindingAdapterTest android.R.color.holo_blue_bright); assertEquals(expectedColor, textView.getCurrentTextColor()); } + + @UiThreadTest + public void testTwoWayText() throws Throwable { + EditText view = mBinder.twoWayText; + mBindingObject.setText("Hello"); + mBinder.executePendingBindings(); + assertEquals("Hello", view.getText().toString()); + view.setText("World"); + assertEquals("World", mBindingObject.getText()); + } } diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TwoWayBindingAdapterTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TwoWayBindingAdapterTest.java new file mode 100644 index 00000000..7506f2b5 --- /dev/null +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TwoWayBindingAdapterTest.java @@ -0,0 +1,718 @@ +/* + * 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 android.databinding.testapp; + +import android.app.Instrumentation; +import android.content.Context; +import android.databinding.testapp.databinding.TwoWayBinding; +import android.databinding.testapp.vo.TwoWayBindingObject; +import android.os.SystemClock; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.BackgroundColorSpan; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.TabHost.TabSpec; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class TwoWayBindingAdapterTest extends BaseDataBinderTest<TwoWayBinding> { + + TwoWayBindingObject mBindingObject; + + public TwoWayBindingAdapterTest() { + super(TwoWayBinding.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + initBinder(new Runnable() { + @Override + public void run() { + Context context = getBinder().getRoot().getContext(); + mBindingObject = new TwoWayBindingObject(context); + getBinder().setObj(mBindingObject); + getBinder().executePendingBindings(); + } + }); + } + + public void testListViewSelectedItemPosition() throws Throwable { + makeVisible(mBinder.listView); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(0, mBindingObject.selectedItemPosition.get()); + assertEquals(0, mBinder.listView.getSelectedItemPosition()); + mBinder.listView.setSelection(1); + } + }); + long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.selectedItemPosition.get() == 0 && + SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1, mBinder.listView.getSelectedItemPosition()); + assertEquals(1, mBindingObject.selectedItemPosition.get()); + } + }); + } + + private void clickView(final View view, float offsetX) throws Throwable { + final int[] xy = new int[2]; + final int[] viewSize = new int[2]; + do { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + view.getLocationOnScreen(xy); + viewSize[0] = view.getWidth(); + viewSize[1] = view.getHeight(); + } + }); + } while (xy[0] < 0 || xy[1] < 0); + + final float x = xy[0] + offsetX; + final float y = xy[1] + (viewSize[1] / 2f); + + Instrumentation inst = getInstrumentation(); + + long downTime = SystemClock.uptimeMillis(); + long eventTime = SystemClock.uptimeMillis(); + + MotionEvent event = MotionEvent.obtain(downTime, eventTime, + MotionEvent.ACTION_DOWN, x, y, 0); + inst.sendPointerSync(event); + inst.waitForIdleSync(); + + eventTime = SystemClock.uptimeMillis(); + final int touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop(); + event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, + x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0); + inst.sendPointerSync(event); + inst.waitForIdleSync(); + + eventTime = SystemClock.uptimeMillis(); + event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0); + inst.sendPointerSync(event); + inst.waitForIdleSync(); + } + + private void clickChild(View view, float offsetX) throws Throwable { + View childView = view; + while (childView != null) { + childView.callOnClick(); + if (childView instanceof ViewGroup) { + final ViewGroup viewGroup = (ViewGroup) childView; + if (viewGroup.getChildCount() > 0) { + childView = viewGroup.getChildAt(0); + } else { + childView = null; + } + } else { + clickView(childView, offsetX); + childView = null; + } + } + } + + public void testCalendarViewDate() throws Throwable { + makeVisible(mBinder.calendarView); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertNotSame(0, mBindingObject.date.get()); + assertEquals(mBindingObject.date.get(), mBinder.calendarView.getDate()); + } + }); + final long[] date = new long[2]; + float offsetX = 0; + long timeout = SystemClock.uptimeMillis() + 1500; + do { + // Just randomly poke at the CalendarView to set the date + clickChild(mBinder.calendarView, offsetX); + offsetX += 48; + runTestOnUiThread(new Runnable() { + @Override + public void run() { + date[0] = mBinder.calendarView.getDate(); + if (date[1] == 0) { + date[1] = date[0]; + } + } + }); + } while (date[0] == date[1] && SystemClock.uptimeMillis() < timeout); + + timeout = SystemClock.uptimeMillis() + 100; + while (mBindingObject.date.get() == 0 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + assertEquals(date[0], mBindingObject.date.get()); + } + + public void testCheckBoxChecked() throws Throwable { + makeVisible(mBinder.checkBox); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertFalse(mBindingObject.checked.get()); + assertFalse(mBinder.checkBox.isChecked()); + mBinder.checkBox.setChecked(true); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (!mBindingObject.checked.get() && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertTrue(mBinder.checkBox.isChecked()); + assertTrue(mBindingObject.checked.get()); + } + }); + } + + private boolean focusOn(final View view) throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + view.requestFocus(); + } + }); + long timeout = SystemClock.uptimeMillis() + 500; + final boolean[] focused = new boolean[1]; + while (SystemClock.uptimeMillis() < timeout) { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + focused[0] = view.isFocused(); + } + }); + if (focused[0]) { + return true; + } + } + return false; + } + + public void testNumberPickerNumber() throws Throwable { + makeVisible(mBinder.textView, mBinder.numberPicker); + assertTrue(focusOn(mBinder.textView)); + final EditText[] pickerText = new EditText[1]; + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1, mBindingObject.number.get()); + assertEquals(1, mBinder.numberPicker.getValue()); + for (int i = 0; i < mBinder.numberPicker.getChildCount(); i++) { + View view = mBinder.numberPicker.getChildAt(i); + if (view instanceof EditText) { + pickerText[0] = (EditText) view; + break; + } + } + } + }); + assertNotNull(pickerText[0]); + assertTrue(focusOn(pickerText[0])); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + pickerText[0].setText("10"); + } + }); + assertTrue(focusOn(mBinder.textView)); + + final long timeout = SystemClock.uptimeMillis() + 10; + while (mBindingObject.number.get() == 1 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(10, mBinder.numberPicker.getValue()); + assertEquals(10, mBindingObject.number.get()); + } + }); + } + + public void testRatingBarRating() throws Throwable { + makeVisible(mBinder.ratingBar); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1f, mBindingObject.rating.get()); + assertEquals(1f, mBinder.ratingBar.getRating()); + mBinder.ratingBar.setRating(2.5f); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.rating.get() == 1f && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(2.5f, mBinder.ratingBar.getRating()); + assertEquals(2.5f, mBindingObject.rating.get()); + } + }); + } + + public void testSeekBarProgress() throws Throwable { + makeVisible(mBinder.seekBar); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1, mBindingObject.progress.get()); + assertEquals(1, mBinder.seekBar.getProgress()); + mBinder.seekBar.setProgress(30); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.progress.get() == 1 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(30, mBinder.seekBar.getProgress()); + assertEquals(30, mBindingObject.progress.get()); + } + }); + } + + public void testTabHostCurrentTab() throws Throwable { + makeVisible(mBinder.tabhost); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + mBinder.tabhost.setup(); + TabSpec tab1 = mBinder.tabhost.newTabSpec("Tab1"); + TabSpec tab2 = mBinder.tabhost.newTabSpec("Tab2"); + + tab1.setIndicator("tab1"); + tab1.setContent(R.id.foo); + tab2.setIndicator("tab2"); + tab2.setContent(R.id.bar); + mBinder.tabhost.addTab(tab1); + mBinder.tabhost.addTab(tab2); + mBinder.tabhost.setCurrentTab(1); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.currentTab.get() == 0 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1, mBinder.tabhost.getCurrentTab()); + assertEquals(1, mBindingObject.currentTab.get()); + } + }); + } + + public void testTextViewText() throws Throwable { + makeVisible(mBinder.textView); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(null, mBindingObject.text.get()); + assertEquals("", mBinder.textView.getText().toString()); + mBinder.textView.setText("Hello World"); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals("Hello World", mBinder.textView.getText().toString()); + assertEquals("Hello World", mBindingObject.text.get()); + } + }); + } + + public void testDatePicker() throws Throwable { + makeVisible(mBinder.datePicker); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1972, mBindingObject.year.get()); + assertEquals(9, mBindingObject.month.get()); + assertEquals(21, mBindingObject.day.get()); + assertEquals(1972, mBinder.datePicker.getYear()); + assertEquals(9, mBinder.datePicker.getMonth()); + assertEquals(21, mBinder.datePicker.getDayOfMonth()); + mBinder.datePicker.updateDate(2003, 4, 17); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(2003, mBindingObject.year.get()); + assertEquals(4, mBindingObject.month.get()); + assertEquals(17, mBindingObject.day.get()); + } + }); + } + + public void testExpressions1() throws Throwable { + makeVisible(mBinder.expressions1); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1972, mBindingObject.year.get()); + assertEquals(9, mBindingObject.month.get()); + assertEquals(21, mBindingObject.day.get()); + assertEquals(1972000, mBinder.expressions1.getYear()); + assertEquals(2, mBinder.expressions1.getMonth()); + assertEquals(22, mBinder.expressions1.getDayOfMonth()); + mBinder.expressions1.updateDate(2003000, 3, 18); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(2003, mBindingObject.year.get()); + assertEquals(8, mBindingObject.month.get()); + assertEquals(17, mBindingObject.day.get()); + } + }); + } + + public void testExpressions2() throws Throwable { + makeVisible(mBinder.expressions2); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1972, mBindingObject.year.get()); + assertEquals(9, mBindingObject.month.get()); + assertEquals(21, mBindingObject.day.get()); + assertEquals(1, mBinder.expressions2.getYear()); + assertEquals(9, mBinder.expressions2.getMonth()); + assertEquals(21, mBinder.expressions2.getDayOfMonth()); + mBinder.expressions2.updateDate(2, 4, 17); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(2000, mBindingObject.year.get()); + assertEquals(4, mBindingObject.month.get()); + assertEquals(17, mBindingObject.day.get()); + } + }); + } + + public void testExpressions3() throws Throwable { + makeVisible(mBinder.expressions3); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals((Integer)1, mBindingObject.list.get(1)); + assertEquals((Integer)2, mBindingObject.map.get("two")); + assertEquals(2, mBindingObject.array.get()[1]); + assertEquals(1, mBinder.expressions3.getYear()); + assertEquals(2, mBinder.expressions3.getMonth()); + assertEquals(2, mBinder.expressions3.getDayOfMonth()); + mBinder.expressions3.updateDate(2003, 4, 17); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals((Integer)2003, mBindingObject.list.get(1)); + assertEquals((Integer)4, mBindingObject.map.get("two")); + assertEquals(17, mBindingObject.array.get()[1]); + } + }); + } + + public void testExpressions4() throws Throwable { + makeVisible(mBinder.expressions4); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(1972, mBindingObject.year.get()); + assertEquals(9, mBindingObject.month.get()); + assertEquals(21, mBindingObject.day.get()); + assertEquals(50, mBinder.expressions4.getYear()); + assertEquals(5, mBinder.expressions4.getMonth()); + assertEquals(21, mBinder.expressions4.getDayOfMonth()); + mBinder.expressions4.updateDate(49, 4, 17); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.year.get() == 1972 && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(2040, mBindingObject.year.get()); + assertEquals(6, mBindingObject.month.get()); + assertEquals(17, mBindingObject.day.get()); + } + }); + } + + public void testChaining() throws Throwable { + makeVisible(mBinder.checkBox, mBinder.checkBox2); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertTrue(mBinder.checkBox2.isChecked()); + mBindingObject.checked.set(true); + mBinder.executePendingBindings(); + assertFalse(mBinder.checkBox2.isChecked()); + } + }); + } + + public void testTwoWayChaining() throws Throwable { + makeVisible(mBinder.checkBox3, mBinder.checkBox4); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertFalse(mBinder.checkBox3.isChecked()); + assertTrue(mBinder.checkBox4.isChecked()); + mBinder.checkBox3.setChecked(true); + mBinder.executePendingBindings(); + assertTrue(mBinder.checkBox3.isChecked()); + assertFalse(mBinder.checkBox4.isChecked()); + } + }); + } + + public void testIncludedTwoWay1() throws Throwable { + makeVisible(mBinder.included.editText1, mBinder.textView); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(null, mBindingObject.text.get()); + assertEquals("", mBinder.textView.getText().toString()); + assertEquals("", mBinder.included.editText1.getText().toString()); + mBinder.included.editText1.setText("Hello World"); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals("Hello World", mBinder.included.editText1.getText().toString()); + assertEquals("Hello World", mBinder.textView.getText().toString()); + assertEquals("Hello World", mBindingObject.text.get()); + } + }); + } + + public void testIncludedTwoWay2() throws Throwable { + makeVisible(mBinder.included.editText2, mBinder.textView); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(null, mBindingObject.text.get()); + assertEquals("", mBinder.textView.getText().toString()); + assertEquals("", mBinder.included.editText2.getText().toString()); + mBinder.included.editText2.setText("Hello World"); + } + }); + + final long timeout = SystemClock.uptimeMillis() + 500; + while (mBindingObject.text.get().isEmpty() && SystemClock.uptimeMillis() < timeout) { + Thread.sleep(1); + } + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals("Hello World", mBinder.included.editText2.getText().toString()); + assertEquals("Hello World", mBinder.textView.getText().toString()); + assertEquals("Hello World", mBindingObject.text.get()); + } + }); + } + + public void testNoEditableLoop() throws Throwable { + makeVisible(mBinder.editText1, mBinder.editText2); + + final SpannableString text = new SpannableString("Hello World Also"); + BackgroundColorSpan highlight = new BackgroundColorSpan(0xFFFFFF80); + text.setSpan(highlight, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + mBindingObject.textLatch = new CountDownLatch(2); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals("", mBinder.editText1.getText().toString()); + assertEquals(0, mBindingObject.text1Changes); + assertEquals(0, mBindingObject.text2Changes); + + // Change the text of one of the controls + mBinder.editText1.setText("Hello World"); + } + }); + + assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS)); + mBindingObject.textLatch = new CountDownLatch(2); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertNotNull(mBindingObject.editText.get()); + assertEquals("Hello World", mBindingObject.editText.get().toString()); + // They should both be set + assertEquals(1, mBindingObject.text1Changes); + assertEquals(1, mBindingObject.text2Changes); + + // Edit the span, but the text remains the same. + mBinder.editText2.setText(text); + } + }); + + assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS)); + mBindingObject.textLatch = new CountDownLatch(1); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + // The one control should notify a change, but not the other. + assertEquals(2, mBindingObject.text1Changes); + assertEquals(2, mBindingObject.text2Changes); + + // No more changes should occur + mBinder.executePendingBindings(); + } + }); + + assertFalse(mBindingObject.textLatch.await(200, TimeUnit.MILLISECONDS)); + mBindingObject.textLatch = new CountDownLatch(2); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + // Nothing changed: + assertEquals(2, mBindingObject.text1Changes); + assertEquals(2, mBindingObject.text2Changes); + + // Now try changing the value to the same thing. Because the + // value is Spannable, it will set it to the EditText + // and then get back a String in the onTextChanged. + mBindingObject.editText.set(text); + } + }); + + assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS)); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertEquals(3, mBindingObject.text1Changes); + assertEquals(3, mBindingObject.text2Changes); + assertEquals("Hello World Also", mBindingObject.editText.get()); + } + }); + } + + private void makeVisible(final View... views) throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + mBinder.calendarView.setVisibility(View.GONE); + mBinder.listView.setVisibility(View.GONE); + mBinder.checkBox.setVisibility(View.GONE); + mBinder.numberPicker.setVisibility(View.GONE); + mBinder.ratingBar.setVisibility(View.GONE); + mBinder.seekBar.setVisibility(View.GONE); + mBinder.tabhost.setVisibility(View.GONE); + mBinder.textView.setVisibility(View.GONE); + mBinder.timePicker.setVisibility(View.GONE); + mBinder.datePicker.setVisibility(View.GONE); + mBinder.expressions1.setVisibility(View.GONE); + mBinder.expressions2.setVisibility(View.GONE); + mBinder.expressions3.setVisibility(View.GONE); + mBinder.expressions4.setVisibility(View.GONE); + mBinder.checkBox2.setVisibility(View.GONE); + mBinder.checkBox3.setVisibility(View.GONE); + mBinder.checkBox4.setVisibility(View.GONE); + mBinder.editText1.setVisibility(View.GONE); + mBinder.editText2.setVisibility(View.GONE); + mBinder.included.editText1.setVisibility(View.GONE); + mBinder.included.editText2.setVisibility(View.GONE); + for (View view : views) { + view.setVisibility(View.VISIBLE); + } + } + }); + getInstrumentation().waitForIdleSync(); + } +} diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/LandscapeConfigTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/LandscapeConfigTest.java index ddda2695..e3fc74ff 100644 --- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/LandscapeConfigTest.java +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/LandscapeConfigTest.java @@ -34,9 +34,15 @@ public class LandscapeConfigTest extends BaseLandDataBinderTest<MultiResLayoutBi super(MultiResLayoutBinding.class, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } + @Override + protected void setUp() throws Exception { + super.setUp(); + initBinder(); + getInstrumentation().waitForIdleSync(); + } + public void testSharedViewIdAndVariableInheritance() throws InterruptedException, NoSuchMethodException, NoSuchFieldException { - initBinder(); assertEquals("MultiResLayoutBindingLandImpl", mBinder.getClass().getSimpleName()); assertPublicField(TextView.class, "objectInLandTextView"); assertPublicField(TextView.class, "objectInDefaultTextView"); @@ -54,7 +60,6 @@ public class LandscapeConfigTest extends BaseLandDataBinderTest<MultiResLayoutBi @UiThreadTest public void testSetVariable() throws Throwable { - initBinder(); assertTrue(mBinder.setVariable(BR.objectInBoth, null)); assertTrue(mBinder.setVariable(BR.objectInDefault, null)); assertTrue(mBinder.setVariable(BR.objectInLand, null)); diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/PortraitConfigTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/PortraitConfigTest.java index 6a259bb2..bcc2c4c9 100644 --- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/PortraitConfigTest.java +++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/PortraitConfigTest.java @@ -33,9 +33,15 @@ public class PortraitConfigTest extends BaseDataBinderTest<MultiResLayoutBinding super(MultiResLayoutBinding.class, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } + @Override + protected void setUp() throws Exception { + super.setUp(); + initBinder(); + getInstrumentation().waitForIdleSync(); + } + public void testSharedViewIdAndVariableInheritance() throws InterruptedException, NoSuchMethodException, NoSuchFieldException { - initBinder(); assertEquals("MultiResLayoutBindingImpl", mBinder.getClass().getSimpleName()); assertPublicField(TextView.class, "objectInLandTextView"); assertPublicField(TextView.class, "objectInDefaultTextView"); @@ -52,7 +58,6 @@ public class PortraitConfigTest extends BaseDataBinderTest<MultiResLayoutBinding @UiThreadTest public void testSetVariable() throws Throwable { - initBinder(); assertTrue(mBinder.setVariable(BR.objectInBoth, null)); assertTrue(mBinder.setVariable(BR.objectInDefault, null)); assertFalse(mBinder.setVariable(BR.obj, null)); diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/CustomNamespaceAdapter.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/CustomNamespaceAdapter.java index 9b8d8bee..1888bb00 100644 --- a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/CustomNamespaceAdapter.java +++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/CustomNamespaceAdapter.java @@ -24,7 +24,7 @@ public class CustomNamespaceAdapter { view.setText(value); } - @BindingAdapter({"bind:set2"}) + @BindingAdapter({"set2"}) public static void setTwo(TextView view, String value) { view.setText(value); } diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TextViewBindingObject.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TextViewBindingObject.java index b1d04b69..f57638b2 100644 --- a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TextViewBindingObject.java +++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TextViewBindingObject.java @@ -123,6 +123,9 @@ public class TextViewBindingObject extends BindingAdapterBindingObject { @Bindable private float mTextSize = 10f; + @Bindable + private String mText; + public TextView.BufferType getBufferType() { return mBufferType; } @@ -252,6 +255,15 @@ public class TextViewBindingObject extends BindingAdapterBindingObject { return mTextAllCaps; } + public String getText() { + return mText; + } + + public void setText(String text) { + mText = text; + notifyPropertyChanged(BR.text); + } + public void changeValues() { mAutoLink = Linkify.EMAIL_ADDRESSES; mDrawablePadding = 10; diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TwoWayBindingObject.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TwoWayBindingObject.java new file mode 100644 index 00000000..873b1dce --- /dev/null +++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TwoWayBindingObject.java @@ -0,0 +1,79 @@ +/* + * 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 android.databinding.testapp.vo; + +import android.content.Context; +import android.databinding.ObservableArrayList; +import android.databinding.ObservableArrayMap; +import android.databinding.ObservableBoolean; +import android.databinding.ObservableField; +import android.databinding.ObservableFloat; +import android.databinding.ObservableInt; +import android.databinding.ObservableLong; +import android.widget.ArrayAdapter; +import android.widget.ListAdapter; + +import java.util.concurrent.CountDownLatch; + +public class TwoWayBindingObject { + private static final String[] VALUES = { + "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" + }; + public final ListAdapter adapter; + public final ObservableInt selectedItemPosition = new ObservableInt(); + public final ObservableLong date = new ObservableLong(System.currentTimeMillis()); + public final ObservableBoolean checked = new ObservableBoolean(); + public final ObservableInt number = new ObservableInt(1); + public final ObservableFloat rating = new ObservableFloat(1); + public final ObservableInt progress = new ObservableInt(1); + public final ObservableInt currentTab = new ObservableInt(); + public final ObservableField<String> text = new ObservableField<>(); + public final ObservableInt hour = new ObservableInt(); + public final ObservableInt minute = new ObservableInt(); + public final ObservableInt year = new ObservableInt(1972); + public final ObservableInt month = new ObservableInt(9); + public final ObservableInt day = new ObservableInt(21); + public final ObservableArrayList<Integer> list = new ObservableArrayList<>(); + public final ObservableArrayMap<String, Integer> map = new ObservableArrayMap<>(); + public final ObservableField<int[]> array = new ObservableField<>(); + public final ObservableField<CharSequence> editText = new ObservableField<>(); + public int text1Changes; + public int text2Changes; + public CountDownLatch textLatch; + + public TwoWayBindingObject(Context context) { + this.adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, VALUES); + int[] arr = new int[10]; + for (int i = 0; i < 10; i++) { + list.add(i); + arr[i] = i + 1; + } + array.set(arr); + for (int i = 0; i < VALUES.length; i++) { + map.put(VALUES[i], i + 1); + } + } + + public void textChanged1(CharSequence s, int start, int before, int count) { + text1Changes++; + textLatch.countDown(); + } + + public void textChanged2(CharSequence s, int start, int before, int count) { + text2Changes++; + textLatch.countDown(); + } +} diff --git a/integration-tests/TestApp/app/src/main/res/layout/bracket_test.xml b/integration-tests/TestApp/app/src/main/res/layout/bracket_test.xml index e9a0e2f9..04beb943 100644 --- a/integration-tests/TestApp/app/src/main/res/layout/bracket_test.xml +++ b/integration-tests/TestApp/app/src/main/res/layout/bracket_test.xml @@ -35,7 +35,7 @@ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:id="@+id/indexObj" + android:id="@+id/indexObjView" android:text="@{array[indexObj]}"/> <TextView android:layout_width="wrap_content" diff --git a/integration-tests/TestApp/app/src/main/res/layout/conditional_binding.xml b/integration-tests/TestApp/app/src/main/res/layout/conditional_binding.xml index 675c37cb..3f6c64e0 100644 --- a/integration-tests/TestApp/app/src/main/res/layout/conditional_binding.xml +++ b/integration-tests/TestApp/app/src/main/res/layout/conditional_binding.xml @@ -43,6 +43,6 @@ android:id="@+id/view1" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onClick="@{cond1 ? obj4.clicked : null}"/> + android:onClick="@{cond1 ? obj4::clicked : null}"/> </LinearLayout> </layout>
\ No newline at end of file diff --git a/integration-tests/TestApp/app/src/main/res/layout/listeners.xml b/integration-tests/TestApp/app/src/main/res/layout/listeners.xml index 00a26ff8..89572ac9 100644 --- a/integration-tests/TestApp/app/src/main/res/layout/listeners.xml +++ b/integration-tests/TestApp/app/src/main/res/layout/listeners.xml @@ -26,289 +26,289 @@ <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onMovedToScrapHeap="@{obj.onMovedToScrapHeap}" - android:onScroll="@{obj.onScroll}" - android:onScrollStateChanged="@{obj.onScrollStateChanged}" - android:onItemClick="@{obj.onItemClick}" - android:onItemLongClick="@{obj.onItemLongClick}" - android:onItemSelected="@{obj.onItemSelected}" - android:onNothingSelected="@{obj.onNothingSelected}" + android:onMovedToScrapHeap="@{obj::onMovedToScrapHeap}" + android:onScroll="@{obj::onScroll}" + android:onScrollStateChanged="@{obj::onScrollStateChanged}" + android:onItemClick="@{obj::onItemClick}" + android:onItemLongClick="@{obj::onItemLongClick}" + android:onItemSelected="@{obj::onItemSelected}" + android:onNothingSelected="@{obj::onNothingSelected}" /> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onScroll="@{obj.onScroll}" - android:onItemSelected="@{obj.onItemSelected}" + android:onScroll="@{obj::onScroll}" + android:onItemSelected="@{obj::onItemSelected}" /> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onScrollStateChanged="@{obj.onScrollStateChanged}" - android:onNothingSelected="@{obj.onNothingSelected}" + android:onScrollStateChanged="@{obj::onScrollStateChanged}" + android:onNothingSelected="@{obj::onNothingSelected}" /> <ActionMenuView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onMenuItemClick="@{obj.onMenuItemClick}" + android:onMenuItemClick="@{obj::onMenuItemClick}" /> <AutoCompleteTextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onDismiss="@{obj.onDismiss}" - android:onItemClick="@{obj.onItemClick}" - android:fixText="@{obj.fixText}" - android:isValid="@{obj.isValid}" - android:onItemSelected="@{obj.onItemSelected}" - android:onNothingSelected="@{obj.onNothingSelected}" + android:onDismiss="@{obj::onDismiss}" + android:onItemClick="@{obj::onItemClick}" + android:fixText="@{obj::fixText}" + android:isValid="@{obj::isValid}" + android:onItemSelected="@{obj::onItemSelected}" + android:onNothingSelected="@{obj::onNothingSelected}" /> <AutoCompleteTextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:isValid="@{obj.isValid}" - android:onItemSelected="@{obj.onItemSelected}" + android:isValid="@{obj::isValid}" + android:onItemSelected="@{obj::onItemSelected}" /> <AutoCompleteTextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:fixText="@{obj.fixText}" - android:onNothingSelected="@{obj.onNothingSelected}" + android:fixText="@{obj::fixText}" + android:onNothingSelected="@{obj::onNothingSelected}" /> <CalendarView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onSelectedDayChange="@{obj.onSelectedDayChange}" + android:onSelectedDayChange="@{obj::onSelectedDayChange}" /> <Chronometer android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onChronometerTick="@{obj.onChronometerTick}" + android:onChronometerTick="@{obj::onChronometerTick}" /> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onCheckedChanged="@{obj.onCheckedChanged}" + android:onCheckedChanged="@{obj::onCheckedChanged}" /> <ExpandableListView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onChildClick="@{obj.onChildClick}" - android:onGroupClick="@{obj.onGroupClick}" - android:onGroupCollapse="@{obj.onGroupCollapse}" - android:onGroupExpand="@{obj.onGroupExpand}" - android:onItemClick="@{obj.onItemClick}" + android:onChildClick="@{obj::onChildClick}" + android:onGroupClick="@{obj::onGroupClick}" + android:onGroupCollapse="@{obj::onGroupCollapse}" + android:onGroupExpand="@{obj::onGroupExpand}" + android:onItemClick="@{obj::onItemClick}" /> <NumberPicker android:layout_width="wrap_content" android:layout_height="wrap_content" - android:format="@{obj.format}" - android:onValueChange="@{obj.onValueChange}" - android:onScrollStateChange="@{obj.onScrollStateChange}" + android:format="@{obj::format}" + android:onValueChange="@{obj::onValueChange}" + android:onScrollStateChange="@{obj::onScrollStateChange}" /> <RadioGroup android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onCheckedChanged="@{obj.onCheckedChanged}" + android:onCheckedChanged="@{obj::onCheckedChanged}" /> <RatingBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onRatingChanged="@{obj.onRatingChanged}" + android:onRatingChanged="@{obj::onRatingChanged}" /> <SearchView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onClose="@{obj.onClose}" - android:onQueryTextChange="@{obj.onQueryTextChange}" - android:onQueryTextSubmit="@{obj.onQueryTextSubmit}" - android:onSuggestionClick="@{obj.onSuggestionClick}" - android:onSuggestionSelect="@{obj.onSuggestionSelect}" + android:onClose="@{obj::onClose}" + android:onQueryTextChange="@{obj::onQueryTextChange}" + android:onQueryTextSubmit="@{obj::onQueryTextSubmit}" + android:onSuggestionClick="@{obj::onSuggestionClick}" + android:onSuggestionSelect="@{obj::onSuggestionSelect}" /> <SearchView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onQueryTextSubmit="@{obj.onQueryTextSubmit}" - android:onSuggestionClick="@{obj.onSuggestionClick}" + android:onQueryTextSubmit="@{obj::onQueryTextSubmit}" + android:onSuggestionClick="@{obj::onSuggestionClick}" /> <SearchView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onQueryTextChange="@{obj.onQueryTextChange}" - android:onSuggestionClick="@{obj.onSuggestionClick}" + android:onQueryTextChange="@{obj::onQueryTextChange}" + android:onSuggestionClick="@{obj::onSuggestionClick}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onProgressChanged="@{obj.onProgressChanged}" - android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" - android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + android:onProgressChanged="@{obj::onProgressChanged}" + android:onStartTrackingTouch="@{obj::onStartTrackingTouch}" + android:onStopTrackingTouch="@{obj::onStopTrackingTouch}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" - android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + android:onStartTrackingTouch="@{obj::onStartTrackingTouch}" + android:onStopTrackingTouch="@{obj::onStopTrackingTouch}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onProgressChanged="@{obj.onProgressChanged}" - android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + android:onProgressChanged="@{obj::onProgressChanged}" + android:onStopTrackingTouch="@{obj::onStopTrackingTouch}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onProgressChanged="@{obj.onProgressChanged}" - android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + android:onProgressChanged="@{obj::onProgressChanged}" + android:onStartTrackingTouch="@{obj::onStartTrackingTouch}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onProgressChanged="@{obj.onProgressChanged}" + android:onProgressChanged="@{obj::onProgressChanged}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + android:onStartTrackingTouch="@{obj::onStartTrackingTouch}" /> <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + android:onStopTrackingTouch="@{obj::onStopTrackingTouch}" /> <TabHost android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onTabChanged="@{obj.onTabChanged}" + android:onTabChanged="@{obj::onTabChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onEditorAction="@{obj.onEditorAction}" - android:afterTextChanged="@{obj.afterTextChanged}" - android:beforeTextChanged="@{obj.beforeTextChanged}" - android:onTextChanged="@{obj.onTextChanged}" + android:onEditorAction="@{obj::onEditorAction}" + android:afterTextChanged="@{obj::afterTextChanged}" + android:beforeTextChanged="@{obj::beforeTextChanged}" + android:onTextChanged="@{obj::onTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:beforeTextChanged="@{obj.beforeTextChanged}" - android:onTextChanged="@{obj.onTextChanged}" + android:beforeTextChanged="@{obj::beforeTextChanged}" + android:onTextChanged="@{obj::onTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:afterTextChanged="@{obj.afterTextChanged}" - android:onTextChanged="@{obj.onTextChanged}" + android:afterTextChanged="@{obj::afterTextChanged}" + android:onTextChanged="@{obj::onTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:afterTextChanged="@{obj.afterTextChanged}" - android:beforeTextChanged="@{obj.beforeTextChanged}" + android:afterTextChanged="@{obj::afterTextChanged}" + android:beforeTextChanged="@{obj::beforeTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onTextChanged="@{obj.onTextChanged}" + android:onTextChanged="@{obj::onTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:beforeTextChanged="@{obj.beforeTextChanged}" + android:beforeTextChanged="@{obj::beforeTextChanged}" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:afterTextChanged="@{obj.afterTextChanged}" + android:afterTextChanged="@{obj::afterTextChanged}" /> <TimePicker android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onTimeChanged="@{obj.onTimeChanged}" + android:onTimeChanged="@{obj::onTimeChanged}" /> <Toolbar android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onMenuItemClick="@{obj.onMenuItemClick}" - android:onNavigationClick="@{obj.onClick}" + android:onMenuItemClick="@{obj::onMenuItemClick}" + android:onNavigationClick="@{obj::onClick}" /> <VideoView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onCompletion="@{obj.onCompletion}" - android:onError="@{obj.onError}" - android:onInfo="@{obj.onInfo}" - android:onPrepared="@{obj.onPrepared}" + android:onCompletion="@{obj::onCompletion}" + android:onError="@{obj::onError}" + android:onInfo="@{obj::onInfo}" + android:onPrepared="@{obj::onPrepared}" /> <View android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onApplyWindowInsets="@{obj.onApplyWindowInsets}" - android:onCreateContextMenu="@{obj.onCreateContextMenu}" - android:onDrag="@{obj.onDrag}" - android:onFocusChange="@{obj.onFocusChange}" - android:onGenericMotion="@{obj.onGenericMotion}" - android:onHover="@{obj.onHover}" - android:onKey="@{obj.onKey}" - android:onLongClick="@{obj.onLongClick}" - android:onClick="@{obj.onClick}" - android:onSystemUiVisibilityChange="@{obj.onSystemUiVisibilityChange}" - android:onTouch="@{obj.onTouch}" - android:getOutline="@{obj.getOutline}" - android:onViewAttachedToWindow="@{obj.onViewAttachedToWindow}" - android:onViewDetachedFromWindow="@{obj.onViewDetachedFromWindow}" + android:onApplyWindowInsets="@{obj::onApplyWindowInsets}" + android:onCreateContextMenu="@{obj::onCreateContextMenu}" + android:onDrag="@{obj::onDrag}" + android:onFocusChange="@{obj::onFocusChange}" + android:onGenericMotion="@{obj::onGenericMotion}" + android:onHover="@{obj::onHover}" + android:onKey="@{obj::onKey}" + android:onLongClick="@{obj::onLongClick}" + android:onClick="@{obj::onClick}" + android:onSystemUiVisibilityChange="@{obj::onSystemUiVisibilityChange}" + android:onTouch="@{obj::onTouch}" + android:getOutline="@{obj::getOutline}" + android:onViewAttachedToWindow="@{obj::onViewAttachedToWindow}" + android:onViewDetachedFromWindow="@{obj::onViewDetachedFromWindow}" android:clickable="@{true}" android:longClickable="@{true}" /> <View android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onClick="@{obj.onClick}" - android:onLongClick="@{obj.onLongClick}" - android:onViewAttachedToWindow="@{obj.onViewAttachedToWindow}" + android:onClick="@{obj::onClick}" + android:onLongClick="@{obj::onLongClick}" + android:onViewAttachedToWindow="@{obj::onViewAttachedToWindow}" /> <View android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onViewDetachedFromWindow="@{obj.onViewDetachedFromWindow}" + android:onViewDetachedFromWindow="@{obj::onViewDetachedFromWindow}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onChildViewAdded="@{obj.onChildViewAdded}" - android:onChildViewRemoved="@{obj.onChildViewRemoved}" - android:onAnimationEnd="@{obj.onAnimationEnd}" - android:onAnimationStart="@{obj.onAnimationStart}" - android:onAnimationRepeat="@{obj.onAnimationRepeat}" + android:onChildViewAdded="@{obj::onChildViewAdded}" + android:onChildViewRemoved="@{obj::onChildViewRemoved}" + android:onAnimationEnd="@{obj::onAnimationEnd}" + android:onAnimationStart="@{obj::onAnimationStart}" + android:onAnimationRepeat="@{obj::onAnimationRepeat}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onChildViewRemoved="@{obj.onChildViewRemoved}" - android:onAnimationStart="@{obj.onAnimationStart}" - android:onAnimationRepeat="@{obj.onAnimationRepeat}" + android:onChildViewRemoved="@{obj::onChildViewRemoved}" + android:onAnimationStart="@{obj::onAnimationStart}" + android:onAnimationRepeat="@{obj::onAnimationRepeat}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onChildViewAdded="@{obj.onChildViewAdded}" - android:onAnimationEnd="@{obj.onAnimationEnd}" - android:onAnimationRepeat="@{obj.onAnimationRepeat}" + android:onChildViewAdded="@{obj::onChildViewAdded}" + android:onAnimationEnd="@{obj::onAnimationEnd}" + android:onAnimationRepeat="@{obj::onAnimationRepeat}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onAnimationEnd="@{obj.onAnimationEnd}" - android:onAnimationStart="@{obj.onAnimationStart}" + android:onAnimationEnd="@{obj::onAnimationEnd}" + android:onAnimationStart="@{obj::onAnimationStart}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onAnimationEnd="@{obj.onAnimationEnd}" + android:onAnimationEnd="@{obj::onAnimationEnd}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onAnimationStart="@{obj.onAnimationStart}" + android:onAnimationStart="@{obj::onAnimationStart}" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onAnimationRepeat="@{obj.onAnimationRepeat}" + android:onAnimationRepeat="@{obj::onAnimationRepeat}" /> <ViewStub android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/viewStub" - android:onInflate="@{obj.onInflate}" + android:onInflate="@{obj::onInflate}" android:layout="@layout/plain_layout" /> <ZoomControls android:layout_width="wrap_content" android:layout_height="wrap_content" - android:onZoomIn="@{obj.onClick}" - android:onZoomOut="@{obj.onClick}" + android:onZoomIn="@{obj::onClick}" + android:onZoomOut="@{obj::onClick}" /> <View android:id="@+id/click1" - android:onClick="@{obj.onClick1}" + android:onClick="@{obj::onClick1}" android:layout_width="10dp" android:layout_height="10dp" /> <View android:id="@+id/click2" - android:onClick="@{ListenerBindingObject.onClick2}" + android:onClick="@{ListenerBindingObject::onClick2}" android:layout_width="10dp" android:layout_height="10dp" /> <View android:id="@+id/click3" - android:onClick="@{obj.useOne ? obj.onClick1 : obj.onClick3}" + android:onClick="@{obj.useOne ? obj::onClick1 : obj::onClick3}" android:clickable="@{obj.clickable}" android:layout_width="10dp" android:layout_height="10dp" /> <View android:id="@+id/click4" - android:onClick="@{ListenerBindingObject.onClick4}" + android:onClick="@{ListenerBindingObject::onClick4}" android:clickable="@{obj.clickable}" android:layout_width="10dp" android:layout_height="10dp" /> <View android:id="@+id/click5" - android:onClick="@{obj.useOne ? obj.onClick1 : ListenerBindingObject.onClick2}" + android:onClick="@{obj.useOne ? obj::onClick1 : ListenerBindingObject::onClick2}" android:layout_width="10dp" android:layout_height="10dp" /> @@ -316,26 +316,26 @@ <View android:id="@+id/listener1" android:layout_width="10dp" android:layout_height="10dp" - android:onFoo="@{obj.onFoo}" - android:onFoo2="@{obj.onFoo}" + android:onFoo="@{obj::onFoo}" + android:onFoo2="@{obj::onFoo}" /> <View android:id="@+id/listener2" android:layout_width="10dp" android:layout_height="10dp" - android:onBar1="@{obj.onBar}" - android:onBar2="@{obj.onBar}" + android:onBar1="@{obj::onBar}" + android:onBar2="@{obj::onBar}" /> <View android:id="@+id/click6" android:layout_width="10dp" android:layout_height="10dp" - android:onClick="@{obj2.onClick}" + android:onClick="@{obj2::onClick}" /> <View android:id="@+id/click7" android:layout_width="10dp" android:layout_height="10dp" app:fooId="@{1}" app:barId="@{2}" - app:runnable="@{obj.runnableRun}" + app:runnable="@{obj::runnableRun}" /> </LinearLayout> </layout>
\ No newline at end of file diff --git a/integration-tests/TestApp/app/src/main/res/layout/listeners_with_dot.xml b/integration-tests/TestApp/app/src/main/res/layout/listeners_with_dot.xml new file mode 100644 index 00000000..e9e61454 --- /dev/null +++ b/integration-tests/TestApp/app/src/main/res/layout/listeners_with_dot.xml @@ -0,0 +1,344 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<layout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <data> + <variable name="obj" type="android.databinding.testapp.vo.ListenerBindingObject"/> + <variable name="obj2" type="android.databinding.testapp.vo.ListenerBindingObject.Inner"/> + <import type="android.databinding.testapp.vo.ListenerBindingObject"/> + </data> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <ListView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onMovedToScrapHeap="@{obj.onMovedToScrapHeap}" + android:onScroll="@{obj.onScroll}" + android:onScrollStateChanged="@{obj.onScrollStateChanged}" + android:onItemClick="@{obj.onItemClick}" + android:onItemLongClick="@{obj.onItemLongClick}" + android:onItemSelected="@{obj.onItemSelected}" + android:onNothingSelected="@{obj.onNothingSelected}" + /> + <ListView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onScroll="@{obj.onScroll}" + android:onItemSelected="@{obj.onItemSelected}" + /> + <ListView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onScrollStateChanged="@{obj.onScrollStateChanged}" + android:onNothingSelected="@{obj.onNothingSelected}" + /> + <ActionMenuView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onMenuItemClick="@{obj.onMenuItemClick}" + /> + <AutoCompleteTextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onDismiss="@{obj.onDismiss}" + android:onItemClick="@{obj.onItemClick}" + android:fixText="@{obj.fixText}" + android:isValid="@{obj.isValid}" + android:onItemSelected="@{obj.onItemSelected}" + android:onNothingSelected="@{obj.onNothingSelected}" + /> + <AutoCompleteTextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:isValid="@{obj.isValid}" + android:onItemSelected="@{obj.onItemSelected}" + /> + <AutoCompleteTextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:fixText="@{obj.fixText}" + android:onNothingSelected="@{obj.onNothingSelected}" + /> + <CalendarView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onSelectedDayChange="@{obj.onSelectedDayChange}" + /> + <Chronometer android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onChronometerTick="@{obj.onChronometerTick}" + /> + <CheckBox android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onCheckedChanged="@{obj.onCheckedChanged}" + /> + <ExpandableListView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onChildClick="@{obj.onChildClick}" + android:onGroupClick="@{obj.onGroupClick}" + android:onGroupCollapse="@{obj.onGroupCollapse}" + android:onGroupExpand="@{obj.onGroupExpand}" + android:onItemClick="@{obj.onItemClick}" + /> + <NumberPicker android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:format="@{obj.format}" + android:onValueChange="@{obj.onValueChange}" + android:onScrollStateChange="@{obj.onScrollStateChange}" + /> + <RadioGroup android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onCheckedChanged="@{obj.onCheckedChanged}" + /> + <RatingBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onRatingChanged="@{obj.onRatingChanged}" + /> + <SearchView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onClose="@{obj.onClose}" + android:onQueryTextChange="@{obj.onQueryTextChange}" + android:onQueryTextSubmit="@{obj.onQueryTextSubmit}" + android:onSuggestionClick="@{obj.onSuggestionClick}" + android:onSuggestionSelect="@{obj.onSuggestionSelect}" + /> + <SearchView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onQueryTextSubmit="@{obj.onQueryTextSubmit}" + android:onSuggestionClick="@{obj.onSuggestionClick}" + /> + <SearchView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onQueryTextChange="@{obj.onQueryTextChange}" + android:onSuggestionClick="@{obj.onSuggestionClick}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onProgressChanged="@{obj.onProgressChanged}" + android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onProgressChanged="@{obj.onProgressChanged}" + android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onProgressChanged="@{obj.onProgressChanged}" + android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onProgressChanged="@{obj.onProgressChanged}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onStartTrackingTouch="@{obj.onStartTrackingTouch}" + /> + <SeekBar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onStopTrackingTouch="@{obj.onStopTrackingTouch}" + /> + <TabHost android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onTabChanged="@{obj.onTabChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onEditorAction="@{obj.onEditorAction}" + android:afterTextChanged="@{obj.afterTextChanged}" + android:beforeTextChanged="@{obj.beforeTextChanged}" + android:onTextChanged="@{obj.onTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:beforeTextChanged="@{obj.beforeTextChanged}" + android:onTextChanged="@{obj.onTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:afterTextChanged="@{obj.afterTextChanged}" + android:onTextChanged="@{obj.onTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:afterTextChanged="@{obj.afterTextChanged}" + android:beforeTextChanged="@{obj.beforeTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onTextChanged="@{obj.onTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:beforeTextChanged="@{obj.beforeTextChanged}" + /> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:afterTextChanged="@{obj.afterTextChanged}" + /> + <TimePicker android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onTimeChanged="@{obj.onTimeChanged}" + /> + <Toolbar android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onMenuItemClick="@{obj.onMenuItemClick}" + android:onNavigationClick="@{obj.onClick}" + /> + <VideoView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onCompletion="@{obj.onCompletion}" + android:onError="@{obj.onError}" + android:onInfo="@{obj.onInfo}" + android:onPrepared="@{obj.onPrepared}" + /> + <View android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onApplyWindowInsets="@{obj.onApplyWindowInsets}" + android:onCreateContextMenu="@{obj.onCreateContextMenu}" + android:onDrag="@{obj.onDrag}" + android:onFocusChange="@{obj.onFocusChange}" + android:onGenericMotion="@{obj.onGenericMotion}" + android:onHover="@{obj.onHover}" + android:onKey="@{obj.onKey}" + android:onLongClick="@{obj.onLongClick}" + android:onClick="@{obj.onClick}" + android:onSystemUiVisibilityChange="@{obj.onSystemUiVisibilityChange}" + android:onTouch="@{obj.onTouch}" + android:getOutline="@{obj.getOutline}" + android:onViewAttachedToWindow="@{obj.onViewAttachedToWindow}" + android:onViewDetachedFromWindow="@{obj.onViewDetachedFromWindow}" + android:clickable="@{true}" + android:longClickable="@{true}" + /> + <View android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onClick="@{obj.onClick}" + android:onLongClick="@{obj.onLongClick}" + android:onViewAttachedToWindow="@{obj.onViewAttachedToWindow}" + /> + <View android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onViewDetachedFromWindow="@{obj.onViewDetachedFromWindow}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onChildViewAdded="@{obj.onChildViewAdded}" + android:onChildViewRemoved="@{obj.onChildViewRemoved}" + android:onAnimationEnd="@{obj.onAnimationEnd}" + android:onAnimationStart="@{obj.onAnimationStart}" + android:onAnimationRepeat="@{obj.onAnimationRepeat}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onChildViewRemoved="@{obj.onChildViewRemoved}" + android:onAnimationStart="@{obj.onAnimationStart}" + android:onAnimationRepeat="@{obj.onAnimationRepeat}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onChildViewAdded="@{obj.onChildViewAdded}" + android:onAnimationEnd="@{obj.onAnimationEnd}" + android:onAnimationRepeat="@{obj.onAnimationRepeat}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onAnimationEnd="@{obj.onAnimationEnd}" + android:onAnimationStart="@{obj.onAnimationStart}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onAnimationEnd="@{obj.onAnimationEnd}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onAnimationStart="@{obj.onAnimationStart}" + /> + <FrameLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onAnimationRepeat="@{obj.onAnimationRepeat}" + /> + <ViewStub android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/viewStub" + android:onInflate="@{obj.onInflate}" + android:layout="@layout/plain_layout" + /> + <ZoomControls android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:onZoomIn="@{obj.onClick}" + android:onZoomOut="@{obj.onClick}" + /> + <View android:id="@+id/click1" + android:onClick="@{obj.onClick1}" + android:layout_width="10dp" + android:layout_height="10dp" + /> + <View android:id="@+id/click2" + android:onClick="@{ListenerBindingObject.onClick2}" + android:layout_width="10dp" + android:layout_height="10dp" + /> + <View android:id="@+id/click3" + android:onClick="@{obj.useOne ? obj.onClick1 : obj.onClick3}" + android:clickable="@{obj.clickable}" + android:layout_width="10dp" + android:layout_height="10dp" + /> + <View android:id="@+id/click4" + android:onClick="@{ListenerBindingObject.onClick4}" + android:clickable="@{obj.clickable}" + android:layout_width="10dp" + android:layout_height="10dp" + /> + <View android:id="@+id/click5" + android:onClick="@{obj.useOne ? obj.onClick1 : ListenerBindingObject.onClick2}" + android:layout_width="10dp" + android:layout_height="10dp" + /> + + <View android:id="@+id/listener1" + android:layout_width="10dp" + android:layout_height="10dp" + android:onFoo="@{obj.onFoo}" + android:onFoo2="@{obj.onFoo}" + /> + <View android:id="@+id/listener2" + android:layout_width="10dp" + android:layout_height="10dp" + android:onBar1="@{obj.onBar}" + android:onBar2="@{obj.onBar}" + /> + <View android:id="@+id/click6" + android:layout_width="10dp" + android:layout_height="10dp" + android:onClick="@{obj2.onClick}" + /> + <View android:id="@+id/click7" + android:layout_width="10dp" + android:layout_height="10dp" + app:fooId="@{1}" + app:barId="@{2}" + app:runnable="@{obj.runnableRun}" + /> + </LinearLayout> +</layout>
\ No newline at end of file diff --git a/integration-tests/TestApp/app/src/main/res/layout/text_view_adapter_test.xml b/integration-tests/TestApp/app/src/main/res/layout/text_view_adapter_test.xml index 43b11da0..12aa6ed1 100644 --- a/integration-tests/TestApp/app/src/main/res/layout/text_view_adapter_test.xml +++ b/integration-tests/TestApp/app/src/main/res/layout/text_view_adapter_test.xml @@ -87,6 +87,10 @@ <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/textWithColor" android:textColor="@{@android:color/holo_blue_bright}" - /> + /> + <EditText android:layout_width="match_parent" android:layout_height="match_parent" + android:id="@+id/twoWayText" + android:text="@={obj.text}" + /> </LinearLayout> -</layout>
\ No newline at end of file +</layout> diff --git a/integration-tests/TestApp/app/src/main/res/layout/two_way.xml b/integration-tests/TestApp/app/src/main/res/layout/two_way.xml new file mode 100644 index 00000000..227278a5 --- /dev/null +++ b/integration-tests/TestApp/app/src/main/res/layout/two_way.xml @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + <data> + <variable name="obj" type="android.databinding.testapp.vo.TwoWayBindingObject"/> + </data> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <CalendarView + android:id="@+id/calendarView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:date="@={obj.date}" + /> + <ListView + android:id="@+id/listView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:selectedItemPosition="@={obj.selectedItemPosition}" + android:adapter="@{obj.adapter}" + /> + <CheckBox + android:id="@+id/checkBox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked="@={obj.checked}" + android:text="Check Box" + /> + <NumberPicker + android:id="@+id/numberPicker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:value="@={obj.number}" + android:minValue="@{1}" + android:maxValue="@{100}" + /> + <RatingBar + android:id="@+id/ratingBar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:rating="@={obj.rating}" + android:numStars="5" + /> + <SeekBar + android:id="@+id/seekBar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:max="100" + android:progress="@={obj.progress}" + /> + <TabHost + android:id="@android:id/tabhost" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:currentTab="@={obj.currentTab}"> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <TabWidget + android:id="@android:id/tabs" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> + <FrameLayout + android:id="@android:id/tabcontent" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <View + android:id="@+id/foo" + android:layout_width="10dp" + android:layout_height="10dp"/> + <View + android:id="@+id/bar" + android:layout_width="10dp" + android:layout_height="10dp"/> + </FrameLayout> + </LinearLayout> + </TabHost> + <EditText + android:id="@+id/textView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@={obj.text}" + /> + <TimePicker + android:id="@+id/timePicker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hour="@={obj.hour}" + android:minute="@={obj.minute}" + /> + <DatePicker + android:id="@+id/datePicker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:year="@={obj.year}" + android:month="@={obj.month}" + android:day="@={obj.day}"/> + <DatePicker + android:id="@+id/expressions1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:year="@={obj.year * @integer/oneThousand}" + android:month="@={11 - obj.month}" + android:day="@={obj.day + 1}"/> + <DatePicker + android:id="@+id/expressions2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:year="@={obj.year / @integer/oneThousand}" + android:month="@={@bool/alwaysTrue ? obj.month : obj.day}" + android:day="@={@bool/alwaysFalse ? obj.month : obj.day}"/> + <DatePicker + android:id="@+id/expressions3" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:year="@={obj.list[@integer/one]}" + android:month="@={obj.map[`two`]}" + android:day="@={obj.array[1]}"/> + <DatePicker + android:id="@+id/expressions4" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:year="@={(int)(100000f/obj.year)}" + android:month="@={1 + (obj.month / 2)}" + android:day="@={true ? obj.day : obj.month}"/> + <CheckBox + android:id="@+id/checkBox2" + android:checked="@{!checkBox.checked}" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <CheckBox + android:id="@+id/checkBox3" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <CheckBox + android:id="@+id/checkBox4" + android:checked="@{!checkBox3.checked}" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <include + android:id="@+id/included" + layout="@layout/two_way_included" + android:obj="@{obj}" + android:text="@={obj.text}"/> + <EditText + android:id="@+id/editText1" + android:text="@={obj.editText}" + android:bufferType="editable" + android:onTextChanged="@{obj::textChanged1}" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <EditText + android:id="@+id/editText2" + android:text="@={obj.editText}" + android:bufferType="editable" + android:onTextChanged="@{obj::textChanged2}" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + </LinearLayout> +</layout> diff --git a/integration-tests/TestApp/app/src/main/res/layout/two_way_included.xml b/integration-tests/TestApp/app/src/main/res/layout/two_way_included.xml new file mode 100644 index 00000000..a1a02e02 --- /dev/null +++ b/integration-tests/TestApp/app/src/main/res/layout/two_way_included.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + <data> + <variable name="text" type="String"/> + <variable name="obj" type="android.databinding.testapp.vo.TwoWayBindingObject"/> + </data> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <EditText + android:id="@+id/editText1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@={text}"/> + <EditText + android:id="@+id/editText2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@={obj.text}"/> + </LinearLayout> +</layout>
\ No newline at end of file diff --git a/integration-tests/TestApp/app/src/main/res/layout/view_stub.xml b/integration-tests/TestApp/app/src/main/res/layout/view_stub.xml index 322c9668..b6af0fac 100644 --- a/integration-tests/TestApp/app/src/main/res/layout/view_stub.xml +++ b/integration-tests/TestApp/app/src/main/res/layout/view_stub.xml @@ -12,11 +12,9 @@ xmlns:bind="http://schemas.android.com/apk/res-auto"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{firstName}" - android:id="@+id/firstName" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{lastName}" - android:id="@+id/lastName" /> <ViewStub android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/integration-tests/TestApp/app/src/main/res/values/integers.xml b/integration-tests/TestApp/app/src/main/res/values/integers.xml new file mode 100644 index 00000000..b56db93c --- /dev/null +++ b/integration-tests/TestApp/app/src/main/res/values/integers.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <integer name="oneThousand">1000</integer> + <integer name="one">1</integer> +</resources>
\ No newline at end of file diff --git a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java index 68c76c90..bcdcdba1 100644 --- a/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java +++ b/samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java @@ -69,14 +69,6 @@ public class MainActivity extends ActionBarActivity implements Observable { mListeners.notifyChange(this, BR.selected); } - public void onSave(View v) { - if (selected == null) { - return; - } - selected.setName(dataBinder.selectedName.getText().toString()); - selected.setLastName(dataBinder.selectedLastname.getText().toString()); - } - public void onUnselect (View v) { setSelected(null); } diff --git a/samples/BindingDemo/app/src/main/res/layout/main_activity.xml b/samples/BindingDemo/app/src/main/res/layout/main_activity.xml index c16a94f1..e17f27a6 100644 --- a/samples/BindingDemo/app/src/main/res/layout/main_activity.xml +++ b/samples/BindingDemo/app/src/main/res/layout/main_activity.xml @@ -93,7 +93,7 @@ if they are getting complex.--> android:layout_row="0" android:background="@android:color/holo_blue_dark" android:gravity="center" - android:text="@{activity.selected.name}" /> + android:text="@={activity.selected.name}" /> <EditText android:id="@+id/selected_lastname" @@ -104,16 +104,7 @@ if they are getting complex.--> android:layout_row="1" android:background="@android:color/holo_blue_bright" android:gravity="center" - android:text="@{activity.selected.lastName}" /> - <Button - android:id="@+id/edit_button" - android:onClick="@{activity.onSave}" - android:text='@{"Save changes to " + activity.selected.name}' - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_column="1" - android:layout_gravity="right" - android:layout_row="2"/> + android:text="@={activity.selected.lastName}" /> <Button android:id="@+id/delete_button" |