summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/compiler.xml10
-rw-r--r--.idea/gradle.xml12
-rw-r--r--.idea/misc.xml42
-rw-r--r--.idea/modules.xml20
-rw-r--r--.idea/modules/baseLibrary/baseLibrary.iml12
-rw-r--r--.idea/modules/baseLibrary/baseLibrary_main.iml13
-rw-r--r--.idea/modules/baseLibrary/baseLibrary_test.iml17
-rw-r--r--.idea/modules/compilationTests/compilationTests.iml12
-rw-r--r--.idea/modules/compilationTests/compilationTests_main.iml13
-rw-r--r--.idea/modules/compilationTests/compilationTests_test.iml32
-rw-r--r--.idea/modules/compiler/compiler.iml12
-rw-r--r--.idea/modules/compiler/compiler_main.iml24
-rw-r--r--.idea/modules/compiler/compiler_test.iml32
-rw-r--r--.idea/modules/compilerCommon/compilerCommon.iml12
-rw-r--r--.idea/modules/compilerCommon/compilerCommon_main.iml21
-rw-r--r--.idea/modules/compilerCommon/compilerCommon_test.iml23
-rw-r--r--.idea/modules/data-binding.iml12
-rw-r--r--.idea/modules/dataBinding/dataBinding.iml12
-rw-r--r--baseLibrary/baseLibrary.iml20
-rw-r--r--baseLibrary/build.gradle6
-rw-r--r--baseLibrary/db-baseLibrary.iml2
-rw-r--r--baseLibrary/src/main/java/android/databinding/CallbackRegistry.java3
-rw-r--r--build.gradle54
-rw-r--r--compilationTests/build.gradle11
-rw-r--r--compilationTests/compilationTests.iml33
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java12
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/MultiLayoutVerificationTest.java4
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java146
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml31
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml31
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml31
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_two_way_event_attribute.xml35
-rw-r--r--compiler/build.gradle10
-rw-r--r--compiler/compiler.iml36
-rw-r--r--compiler/db-compiler.iml2
-rw-r--r--compiler/src/main/java/android/databinding/tool/Binding.java53
-rw-r--r--compiler/src/main/java/android/databinding/tool/BindingTarget.java53
-rw-r--r--compiler/src/main/java/android/databinding/tool/CallbackWrapper.java99
-rw-r--r--compiler/src/main/java/android/databinding/tool/CompilerChef.java70
-rw-r--r--compiler/src/main/java/android/databinding/tool/DataBinder.java63
-rw-r--r--compiler/src/main/java/android/databinding/tool/ExpressionParser.java11
-rw-r--r--compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java176
-rw-r--r--compiler/src/main/java/android/databinding/tool/InverseBinding.java141
-rw-r--r--compiler/src/main/java/android/databinding/tool/LayoutBinder.java25
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ArgListExpr.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/BitShiftExpr.java16
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java65
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/BuiltInVariableExpr.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java93
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java126
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/CastExpr.java25
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ComparisonExpr.java21
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/Expr.java125
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ExprModel.java160
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java244
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/FieldAssignmentExpr.java107
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/GroupExpr.java59
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/IdentifierExpr.java27
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/InstanceOfExpr.java14
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java150
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ListenerExpr.java24
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/MathExpr.java125
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/MethodBaseExpr.java153
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java102
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/MethodReferenceExpr.java85
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ObservableFieldExpr.java80
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java68
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/StaticIdentifierExpr.java10
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java26
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java54
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/TwoWayListenerExpr.java7
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/UnaryExpr.java20
-rw-r--r--compiler/src/main/java/android/databinding/tool/expr/ViewFieldExpr.java15
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/Callable.java10
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java218
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java65
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java146
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java65
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java55
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/ModelMethod.java12
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationAnalyzer.java9
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationClass.java37
-rw-r--r--compiler/src/main/java/android/databinding/tool/reflection/annotation/AnnotationMethod.java5
-rw-r--r--compiler/src/main/java/android/databinding/tool/solver/ExecutionBranch.java55
-rw-r--r--compiler/src/main/java/android/databinding/tool/solver/ExecutionPath.java191
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/SetterStore.java33
-rw-r--r--compiler/src/main/java/android/databinding/tool/writer/CallbackWrapperWriter.kt73
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt90
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/BRWriter.kt4
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/DataBinderWriter.kt90
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt101
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/KCode.kt32
-rw-r--r--compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt423
-rw-r--r--compiler/src/test/java/android/databinding/BindingExpressionParserTest.java28
-rw-r--r--compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java14
-rw-r--r--compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java8
-rw-r--r--compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java69
-rw-r--r--compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java197
-rw-r--r--compiler/src/test/java/android/databinding/tool/expr/ExprTest.java14
-rw-r--r--compiler/src/test/java/android/databinding/tool/reflection/java/JavaAnalyzer.java16
-rw-r--r--compiler/src/test/java/android/databinding/tool/reflection/java/JavaMethod.java5
-rw-r--r--compilerCommon/BindingExpression.g426
-rw-r--r--compilerCommon/build.gradle16
-rw-r--r--compilerCommon/compilerCommon.iml32
-rw-r--r--compilerCommon/db-compilerCommon-base.iml41
-rw-r--r--compilerCommon/db-compilerCommon.iml6
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpression.tokens113
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java246
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java147
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java678
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.tokens113
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java330
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java1491
-rw-r--r--compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java193
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/DataBindingBuilder.java2
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java16
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java13
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java2
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/util/L.java10
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/util/StringUtils.java6
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java13
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java200
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens30
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java324
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens30
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java51
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java31
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java71
-rw-r--r--compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java45
-rw-r--r--data-binding.iml14
-rw-r--r--dataBinding/dataBinding.iml14
-rw-r--r--databinding.properties8
-rw-r--r--developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy2
-rw-r--r--extensions/baseAdapters/build.gradle5
-rw-r--r--extensions/library/build.gradle6
-rw-r--r--extensions/library/src/main/java/android/databinding/ObservableField.java2
-rw-r--r--extensions/library/src/main/java/android/databinding/ObservableInt.java2
-rw-r--r--extensions/library/src/main/java/android/databinding/ObservableParcelable.java2
-rw-r--r--extensions/library/src/main/java/android/databinding/ViewDataBinding.java98
-rw-r--r--integration-tests/MultiModuleTestApp/app/src/main/res/layout/another_layout.xml1
-rw-r--r--integration-tests/MultiModuleTestApp/testlibrary/src/main/java/android/databinding/testlibrary/TestLibObject.java5
-rw-r--r--integration-tests/MultiModuleTestApp/testlibrary/src/main/res/layout/library_only_layout.xml3
-rw-r--r--integration-tests/TestApp/app/build.gradle11
-rw-r--r--integration-tests/TestApp/app/src/androidTest/AndroidManifest.xml26
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi14/java/android/databinding/testapp/RootTag.java10
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BindableObservablesTest.java141
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BracketTest.java2
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/CallbackTest.java385
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/DataBindingTestRule.java64
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/FindMethodTest.java7
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/LeakTest.java4
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/ListenerWithDotTest.java131
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TextViewBindingAdapterTest.java11
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TwoWayBindingAdapterTest.java813
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/LandscapeConfigTest.java9
-rw-r--r--integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/multiconfig/PortraitConfigTest.java9
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/CustomNamespaceAdapter.java2
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/CallbackBindingObject.java70
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/FindMethodBindingObject.java13
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/NotBindableVo.java11
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TextViewBindingObject.java12
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TwoWayBindingObject.java91
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/ViewModel.java46
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/bindable_observables.xml33
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/bracket_test.xml2
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/callbacks.xml109
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/conditional_binding.xml2
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml10
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/listeners.xml250
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/listeners_with_dot.xml344
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/text_view_adapter_test.xml8
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/two_way.xml223
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/two_way_included.xml22
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/view_stub.xml2
-rw-r--r--integration-tests/TestApp/app/src/main/res/values/integers.xml5
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jarbin65255 -> 49850 bytes
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.md52
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.sha12
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml4
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.md52
-rw-r--r--internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.sha12
-rw-r--r--propLoader.gradle5
-rw-r--r--samples/BindingDemo/app/src/main/java/com/android/example/bindingdemo/MainActivity.java8
-rw-r--r--samples/BindingDemo/app/src/main/res/layout/main_activity.xml13
184 files changed, 9666 insertions, 3257 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 96cc43ef..0103dd1c 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -18,5 +18,15 @@
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
+ <bytecodeTargetLevel>
+ <module name="baseLibrary_main" target="1.6" />
+ <module name="baseLibrary_test" target="1.6" />
+ <module name="compilationTests_main" target="1.6" />
+ <module name="compilationTests_test" target="1.6" />
+ <module name="compiler_main" target="1.8" />
+ <module name="compiler_test" target="1.8" />
+ <module name="compilerCommon_main" target="1.8" />
+ <module name="compilerCommon_test" target="1.8" />
+ </bytecodeTargetLevel>
</component>
</project> \ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index c9e59e10..0dce8633 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -5,7 +5,7 @@
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
- <option name="gradleJvm" value="1.6" />
+ <option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
@@ -17,16 +17,6 @@
</set>
</option>
<option name="useAutoImport" value="true" />
- <option name="myModules">
- <set>
- <option value="$PROJECT_DIR$" />
- <option value="$PROJECT_DIR$/baseLibrary" />
- <option value="$PROJECT_DIR$/compilationTests" />
- <option value="$PROJECT_DIR$/compiler" />
- <option value="$PROJECT_DIR$/compilerCommon" />
- <option value="$PROJECT_DIR$/dataBinding" />
- </set>
- </option>
</GradleProjectSettings>
</option>
</component>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index caac6524..e48072ee 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
- <component name="EntryPointsManager">
- <entry_points version="2.0" />
+ <component name="ProjectInspectionProfilesVisibleTreeState">
+ <entry key="Project Default">
+ <profile-state>
+ <expanded-state>
+ <State>
+ <id />
+ </State>
+ <State>
+ <id>Class structureJava</id>
+ </State>
+ <State>
+ <id>Code maturity issuesJava</id>
+ </State>
+ <State>
+ <id>Java</id>
+ </State>
+ <State>
+ <id>Java language level migration aidsJava</id>
+ </State>
+ <State>
+ <id>Javadoc issuesJava</id>
+ </State>
+ <State>
+ <id>Performance issuesJava</id>
+ </State>
+ <State>
+ <id>Threading issuesJava</id>
+ </State>
+ </expanded-state>
+ <selected-state>
+ <State>
+ <id>BashSupport</id>
+ </State>
+ </selected-state>
+ </profile-state>
+ </entry>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
@@ -13,7 +47,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/classes" />
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/build/classes" />
</component>
</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 7eefe600..a3acbc51 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,12 +2,20 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
- <module fileurl="file://$PROJECT_DIR$/baseLibrary/baseLibrary.iml" filepath="$PROJECT_DIR$/baseLibrary/baseLibrary.iml" />
- <module fileurl="file://$PROJECT_DIR$/compilationTests/compilationTests.iml" filepath="$PROJECT_DIR$/compilationTests/compilationTests.iml" />
- <module fileurl="file://$PROJECT_DIR$/compiler/compiler.iml" filepath="$PROJECT_DIR$/compiler/compiler.iml" />
- <module fileurl="file://$PROJECT_DIR$/compilerCommon/compilerCommon.iml" filepath="$PROJECT_DIR$/compilerCommon/compilerCommon.iml" />
- <module fileurl="file://$PROJECT_DIR$/data-binding.iml" filepath="$PROJECT_DIR$/data-binding.iml" />
- <module fileurl="file://$PROJECT_DIR$/dataBinding/dataBinding.iml" filepath="$PROJECT_DIR$/dataBinding/dataBinding.iml" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary.iml" filepath="$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary.iml" group="dataBinding/baseLibrary" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary_main.iml" filepath="$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary_main.iml" group="dataBinding/baseLibrary" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary_test.iml" filepath="$PROJECT_DIR$/.idea/modules/baseLibrary/baseLibrary_test.iml" group="dataBinding/baseLibrary" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests.iml" filepath="$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests.iml" group="dataBinding/compilationTests" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests_main.iml" filepath="$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests_main.iml" group="dataBinding/compilationTests" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests_test.iml" filepath="$PROJECT_DIR$/.idea/modules/compilationTests/compilationTests_test.iml" group="dataBinding/compilationTests" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compiler/compiler.iml" filepath="$PROJECT_DIR$/.idea/modules/compiler/compiler.iml" group="dataBinding/compiler" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon.iml" filepath="$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon.iml" group="dataBinding/compilerCommon" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon_main.iml" filepath="$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon_main.iml" group="dataBinding/compilerCommon" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon_test.iml" filepath="$PROJECT_DIR$/.idea/modules/compilerCommon/compilerCommon_test.iml" group="dataBinding/compilerCommon" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compiler/compiler_main.iml" filepath="$PROJECT_DIR$/.idea/modules/compiler/compiler_main.iml" group="dataBinding/compiler" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/compiler/compiler_test.iml" filepath="$PROJECT_DIR$/.idea/modules/compiler/compiler_test.iml" group="dataBinding/compiler" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/data-binding.iml" filepath="$PROJECT_DIR$/.idea/modules/data-binding.iml" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/dataBinding/dataBinding.iml" filepath="$PROJECT_DIR$/.idea/modules/dataBinding/dataBinding.iml" group="dataBinding" />
</modules>
</component>
</project> \ No newline at end of file
diff --git a/.idea/modules/baseLibrary/baseLibrary.iml b/.idea/modules/baseLibrary/baseLibrary.iml
new file mode 100644
index 00000000..019a989b
--- /dev/null
+++ b/.idea/modules/baseLibrary/baseLibrary.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:baseLibrary" external.linked.project.path="$MODULE_DIR$/../../../baseLibrary" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../baseLibrary">
+ <excludeFolder url="file://$MODULE_DIR$/../../../baseLibrary/.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../../baseLibrary/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/baseLibrary/baseLibrary_main.iml b/.idea/modules/baseLibrary/baseLibrary_main.iml
new file mode 100644
index 00000000..4d93153a
--- /dev/null
+++ b/.idea/modules/baseLibrary/baseLibrary_main.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:baseLibrary:main" external.linked.project.path="$MODULE_DIR$/../../../baseLibrary" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/../../../baseLibrary/build/classes/main" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../baseLibrary/src/main">
+ <sourceFolder url="file://$MODULE_DIR$/../../../baseLibrary/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../baseLibrary/src/main/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/baseLibrary/baseLibrary_test.iml b/.idea/modules/baseLibrary/baseLibrary_test.iml
new file mode 100644
index 00000000..bc70242f
--- /dev/null
+++ b/.idea/modules/baseLibrary/baseLibrary_test.iml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:baseLibrary:test" external.linked.project.path="$MODULE_DIR$/../../../baseLibrary" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+ <output-test url="file://$MODULE_DIR$/../../../baseLibrary/build/classes/test" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../baseLibrary/src/test">
+ <sourceFolder url="file://$MODULE_DIR$/../../../baseLibrary/src/test/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../baseLibrary/src/test/resources" type="java-test-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
+ <orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
+ </component>
+ <component name="TestModuleProperties" production-module="baseLibrary_main" />
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilationTests/compilationTests.iml b/.idea/modules/compilationTests/compilationTests.iml
new file mode 100644
index 00000000..bedf7d94
--- /dev/null
+++ b/.idea/modules/compilationTests/compilationTests.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilationTests" external.linked.project.path="$MODULE_DIR$/../../../compilationTests" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="data-binding.dataBinding" external.system.module.version="1.0" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilationTests">
+ <excludeFolder url="file://$MODULE_DIR$/../../../compilationTests/.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../../compilationTests/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilationTests/compilationTests_main.iml b/.idea/modules/compilationTests/compilationTests_main.iml
new file mode 100644
index 00000000..def742ce
--- /dev/null
+++ b/.idea/modules/compilationTests/compilationTests_main.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilationTests:main" external.linked.project.path="$MODULE_DIR$/../../../compilationTests" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="data-binding.dataBinding" external.system.module.type="sourceSet" external.system.module.version="1.0" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/../../../compilationTests/build/classes/main" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilationTests/src/main">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilationTests/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilationTests/src/main/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilationTests/compilationTests_test.iml b/.idea/modules/compilationTests/compilationTests_test.iml
new file mode 100644
index 00000000..5241cc7f
--- /dev/null
+++ b/.idea/modules/compilationTests/compilationTests_test.iml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilationTests:test" external.linked.project.path="$MODULE_DIR$/../../../compilationTests" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="data-binding.dataBinding" external.system.module.type="sourceSet" external.system.module.version="1.0" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+ <output-test url="file://$MODULE_DIR$/../../../compilationTests/build/classes/test" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilationTests/src/test">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilationTests/src/test/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilationTests/src/test/resources" type="java-test-resource" />
+ </content>
+ <content url="file://$MODULE_DIR$/../../../compiler/src/test/java/android">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/test/java/android/databinding/tool/reflection/java" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="compilationTests_main" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
+ <orderEntry type="library" name="Gradle: org.apache.commons:commons-lang3:3.3.2" level="project" />
+ <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
+ <orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
+ <orderEntry type="module" module-name="compilerCommon_main" />
+ <orderEntry type="module" module-name="compiler_main" />
+ <orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
+ <orderEntry type="library" name="Gradle: org.antlr:antlr4:4.5.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
+ <orderEntry type="library" name="Gradle: com.android.tools:annotations:24.5.0" level="project" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.0" level="project" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.0" level="project" />
+ </component>
+ <component name="TestModuleProperties" production-module="compilationTests_main" />
+</module> \ No newline at end of file
diff --git a/.idea/modules/compiler/compiler.iml b/.idea/modules/compiler/compiler.iml
new file mode 100644
index 00000000..50b5884c
--- /dev/null
+++ b/.idea/modules/compiler/compiler.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compiler" external.linked.project.path="$MODULE_DIR$/../../../compiler" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compiler">
+ <excludeFolder url="file://$MODULE_DIR$/../../../compiler/.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../../compiler/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compiler/compiler_main.iml b/.idea/modules/compiler/compiler_main.iml
new file mode 100644
index 00000000..abf84114
--- /dev/null
+++ b/.idea/modules/compiler/compiler_main.iml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compiler:main" external.linked.project.path="$MODULE_DIR$/../../../compiler" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/../../../compiler/build/classes/main" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compiler/src/main">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/main/kotlin" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/main/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="compilerCommon_main" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.0" level="project" />
+ <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
+ <orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
+ <orderEntry type="library" name="Gradle: org.antlr:antlr4:4.5.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
+ <orderEntry type="library" name="Gradle: com.android.tools:annotations:24.5.0" level="project" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.0" level="project" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compiler/compiler_test.iml b/.idea/modules/compiler/compiler_test.iml
new file mode 100644
index 00000000..433185ee
--- /dev/null
+++ b/.idea/modules/compiler/compiler_test.iml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compiler:test" external.linked.project.path="$MODULE_DIR$/../../../compiler" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+ <output-test url="file://$MODULE_DIR$/../../../compiler/build/classes/test" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compiler/src/test/java">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/test/java" isTestSource="true" />
+ </content>
+ <content url="file://$MODULE_DIR$/../../../compiler/src/test/kotlin">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/test/kotlin" isTestSource="true" />
+ </content>
+ <content url="file://$MODULE_DIR$/../../../compiler/src/test/resources">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compiler/src/test/resources" type="java-test-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="compiler_main" />
+ <orderEntry type="module" module-name="compilerCommon_main" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.0" level="project" />
+ <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
+ <orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
+ <orderEntry type="library" name="Gradle: org.antlr:antlr4:4.5.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
+ <orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
+ <orderEntry type="library" name="Gradle: com.android.tools:annotations:24.5.0" level="project" />
+ <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.0" level="project" />
+ <orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
+ </component>
+ <component name="TestModuleProperties" production-module="compiler_main" />
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilerCommon/compilerCommon.iml b/.idea/modules/compilerCommon/compilerCommon.iml
new file mode 100644
index 00000000..27fdbd49
--- /dev/null
+++ b/.idea/modules/compilerCommon/compilerCommon.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilerCommon" external.linked.project.path="$MODULE_DIR$/../../../compilerCommon" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilerCommon">
+ <excludeFolder url="file://$MODULE_DIR$/../../../compilerCommon/.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../../compilerCommon/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilerCommon/compilerCommon_main.iml b/.idea/modules/compilerCommon/compilerCommon_main.iml
new file mode 100644
index 00000000..4978e298
--- /dev/null
+++ b/.idea/modules/compilerCommon/compilerCommon_main.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilerCommon:main" external.linked.project.path="$MODULE_DIR$/../../../compilerCommon" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/../../../compilerCommon/build/classes/main" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilerCommon/src/main">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/main/grammar-gen" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/main/xml-gen" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/main/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: org.antlr:antlr4:4.5.3" level="project" />
+ <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
+ <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
+ <orderEntry type="library" name="Gradle: com.android.tools:annotations:24.5.0" level="project" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/compilerCommon/compilerCommon_test.iml b/.idea/modules/compilerCommon/compilerCommon_test.iml
new file mode 100644
index 00000000..26e89c6f
--- /dev/null
+++ b/.idea/modules/compilerCommon/compilerCommon_test.iml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding:compilerCommon:test" external.linked.project.path="$MODULE_DIR$/../../../compilerCommon" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.type="sourceSet" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+ <output-test url="file://$MODULE_DIR$/../../../compilerCommon/build/classes/test" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../compilerCommon/src/test">
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/test/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/../../../compilerCommon/src/test/resources" type="java-test-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="compilerCommon_main" />
+ <orderEntry type="module" module-name="baseLibrary_main" />
+ <orderEntry type="library" name="Gradle: org.antlr:antlr4:4.5.3" level="project" />
+ <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
+ <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
+ <orderEntry type="library" name="Gradle: com.android.tools:annotations:24.5.0" level="project" />
+ <orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
+ <orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
+ </component>
+ <component name="TestModuleProperties" production-module="compilerCommon_main" />
+</module> \ No newline at end of file
diff --git a/.idea/modules/data-binding.iml b/.idea/modules/data-binding.iml
new file mode 100644
index 00000000..2bbad644
--- /dev/null
+++ b/.idea/modules/data-binding.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="data-binding" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../..">
+ <excludeFolder url="file://$MODULE_DIR$/../../.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/modules/dataBinding/dataBinding.iml b/.idea/modules/dataBinding/dataBinding.iml
new file mode 100644
index 00000000..d0099f24
--- /dev/null
+++ b/.idea/modules/dataBinding/dataBinding.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":dataBinding" external.linked.project.path="$MODULE_DIR$/../../../dataBinding" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="2.2.0-dev" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../../dataBinding">
+ <excludeFolder url="file://$MODULE_DIR$/../../../dataBinding/.gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/../../../dataBinding/build" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/baseLibrary/baseLibrary.iml b/baseLibrary/baseLibrary.iml
deleted file mode 100644
index c6163c1f..00000000
--- a/baseLibrary/baseLibrary.iml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":dataBinding:baseLibrary" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="1.1" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/classes/main" />
- <output-test url="file://$MODULE_DIR$/build/classes/test" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.12" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
- </component>
-</module> \ No newline at end of file
diff --git a/baseLibrary/build.gradle b/baseLibrary/build.gradle
index 7489e0d1..8cbfd6d5 100644
--- a/baseLibrary/build.gradle
+++ b/baseLibrary/build.gradle
@@ -62,6 +62,10 @@ task prebuildJar(type : Copy) {
}
}
+javadoc {
+ options.addStringOption('Xdoclint:none', '-quiet')
+}
+
project.ext.pomName = 'Data Binding Base Library'
project.ext.pomDesc = 'Shared library between Data Binding runtime lib and compiler'
-enablePublishing(this, true) \ No newline at end of file
+enablePublishing(this, true)
diff --git a/baseLibrary/db-baseLibrary.iml b/baseLibrary/db-baseLibrary.iml
index 7cf99832..1804bc90 100644
--- a/baseLibrary/db-baseLibrary.iml
+++ b/baseLibrary/db-baseLibrary.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
diff --git a/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java b/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
index 0cd7b430..322b2794 100644
--- a/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
+++ b/baseLibrary/src/main/java/android/databinding/CallbackRegistry.java
@@ -210,6 +210,9 @@ public class CallbackRegistry<C, T, A> implements Cloneable {
* @param callback The callback to add.
*/
public synchronized void add(C callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback cannot be null");
+ }
int index = mCallbacks.lastIndexOf(callback);
if (index < 0 || isRemoved(index)) {
mCallbacks.add(callback);
diff --git a/build.gradle b/build.gradle
index c33a72c2..2aa4ea4b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -169,8 +169,7 @@ def fullJar(project) {
if (localizeTask != null) {
localizeTask.dependsOn project.tasks.findByName('buildLicenseNotice')
}
-
- if (!dataBindingConfig.runProguard || !dataBindingConfig.inReleaseBuild) {
+ if (!dataBindingConfig.inReleaseBuild) {
return
}
def jarName = project.uploadArchives.repositories.mavenDeployer.pom.artifactId
@@ -178,6 +177,7 @@ def fullJar(project) {
def fatJar = "${workingDir}/${jarName}-fat.jar"
def proguardJar = "${workingDir}/${jarName}-proguard.jar"
def jarJar = project.jar.archivePath
+ def runProguard = dataBindingConfig.runProguard
project.configurations {
jarJarArchives
@@ -208,6 +208,9 @@ def fullJar(project) {
destinationDir = new File(workingDir)
with project.jar
}
+ /**
+ * not used unless jarJarFile is changed to use proguarded version instead.
+ */
project.tasks.create(name: 'proguard', type: proguard.gradle.ProGuardTask) {
dependsOn 'fatJar'
@@ -218,16 +221,16 @@ def fullJar(project) {
}
project.tasks.create(name: 'jarJarFile') {
- dependsOn 'proguard'
+ dependsOn runProguard ? 'proguard' : 'fatJar'
dependsOn project.jar
- def inputLibrary = proguardJar
+ def inputLibrary = runProguard ? proguardJar : fatJar
def outputLibrary = jarJar
inputs.file(inputLibrary)
outputs.file(outputLibrary)
doLast {
def jarJarLibrary = new File(dataBindingConfig.externalPrebuiltsBase,
- 'tools/common/m2/repository/com/googlecode/jarjar/jarjar/1.3/jarjar-1.3.jar').
+ 'tools/common/m2/repository/com/googlecode/jarjar/jarjar/1.4/jarjar-1.4.jar').
getCanonicalPath()
// in Ant
ant.taskdef(name: "jarjarIt",
@@ -238,8 +241,7 @@ def fullJar(project) {
// input is our inputLibrary
zipfileset(src: inputLibrary)
// rule to repackage antlr to new package
- rule pattern: 'org.antlr.**', result: 'com.google.repacked.antlr.@1'
- rule pattern: 'com.tunnelvisionlabs.**', result: 'com.google.repacked.tunnelvision.@1'
+ rule pattern: 'org.antlr.**', result: 'com.google.repacked.org.antlr.@1'
rule pattern: 'org.abego.treelayout.**', result: 'com.google.repacked.treelayout.@1'
// rule to repackage commons
rule pattern: 'org.apache.**', result: 'com.google.repacked.apache.@1'
@@ -248,25 +250,33 @@ def fullJar(project) {
}
}
- project.uploadArchives {
- dependsOn 'jarJarFile'
- repositories {
- mavenDeployer {
- pom.whenConfigured { pom ->
- pom.dependencies.removeAll { dep ->
- def isBaseLibrary = dep.groupId == 'com.android.databinding' &&
- dep.artifactId == 'baseLibrary'
- def isGradle = dep.groupId == 'com.android.tools.build' &&
- dep.artifactId == 'gradle'
- def isChardet = dep.groupId == 'com.googlecode.juniversalchardet' &&
- dep.artifactId == 'juniversalchardet'
- return !isBaseLibrary && !isGradle && !isChardet
+ def setupUpload = { uploadTask ->
+ uploadTask.dependsOn 'jarJarFile'
+ uploadTask.repositories {
+ mavenDeployer {
+ pom.whenConfigured { pom ->
+ pom.dependencies.removeAll { dep ->
+ def isBaseLibrary = dep.groupId == 'com.android.databinding' &&
+ dep.artifactId == 'baseLibrary'
+ def isGradle = dep.groupId == 'com.android.tools.build' &&
+ dep.artifactId == 'gradle'
+ def isChardet = dep.groupId == 'com.googlecode.juniversalchardet' &&
+ dep.artifactId == 'juniversalchardet'
+ return !isBaseLibrary && !isGradle && !isChardet
+ }
}
}
}
- }
- outputs.upToDateWhen { false } // force it to re-run all the time.
+ uploadTask.outputs.upToDateWhen { false } // force it to re-run all the time.
}
+
+ if (project.publishLocal != null) {
+ setupUpload(project.publishLocal)
+ }
+ if (project.uploadArchives != null) {
+ setupUpload(project.uploadArchives)
+ }
+
project.bintrayUpload.dependsOn 'jarJarFile'
project.publishing.publications.mavenJava(MavenPublication) {
pom.withXml {
diff --git a/compilationTests/build.gradle b/compilationTests/build.gradle
index 0ca1877a..be30dc26 100644
--- a/compilationTests/build.gradle
+++ b/compilationTests/build.gradle
@@ -9,9 +9,18 @@ dependencies {
testCompile 'commons-io:commons-io:2.4'
testCompile 'commons-codec:commons-codec:1.10'
testCompile project(':dataBinding:compilerCommon')
+ testCompile project(':dataBinding:compiler')
}
afterEvaluate {
tasks['test'].systemProperties['useReleaseVersion'] = dataBindingConfig.inReleaseBuild ? 'true' : 'false'
tasks['test'].systemProperties['addRemoteRepos'] = dataBindingConfig.addRemoteRepos ? 'true' : 'false'
-} \ No newline at end of file
+}
+
+sourceSets {
+ test {
+ java {
+ srcDirs += "${project.rootProject.getProjectDir().getAbsolutePath()}/compiler/src/test/java/android/databinding/tool/reflection/java"
+ }
+ }
+}
diff --git a/compilationTests/compilationTests.iml b/compilationTests/compilationTests.iml
deleted file mode 100644
index 751bf1e8..00000000
--- a/compilationTests/compilationTests.iml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":dataBinding:compilationTests" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="data-binding.dataBinding" external.system.module.version="1.0" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/classes/main" />
- <output-test url="file://$MODULE_DIR$/build/classes/test" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="compilerCommon" scope="TEST" />
- <orderEntry type="module" module-name="baseLibrary" scope="TEST" />
- <orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.12" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.apache.commons:commons-lang3:3.3.2" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: commons-io:commons-io:2.4" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: com.tunnelvisionlabs:antlr4:4.5" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: com.tunnelvisionlabs:antlr4-runtime:4.5" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: com.tunnelvisionlabs:antlr4-annotations:4.5" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.antlr:antlr-runtime:3.5.2" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.antlr:ST4:4.0.8" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.abego.treelayout:org.abego.treelayout.core:1.0.1" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: com.google.guava:guava:17.0" level="project" />
- </component>
-</module> \ No newline at end of file
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
index f6d1f5ec..90fd1220 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
@@ -18,7 +18,9 @@ package android.databinding.compilationTest;
import android.databinding.tool.processing.ScopedErrorReport;
import android.databinding.tool.processing.ScopedException;
+import android.databinding.tool.util.StringUtils;
+import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -51,6 +53,16 @@ public class CompilationResult {
return errors.get(0);
}
+ public List<String> getBindingWarnings() {
+ List<String> warnings = new ArrayList<String>();
+ for (String line : error.split(StringUtils.LINE_SEPARATOR)) {
+ if (line.startsWith("warning:")) {
+ warnings.add(line.substring("warning:".length()));
+ }
+ }
+ return warnings;
+ }
+
public List<ScopedException> getBindingExceptions() {
return ScopedException.extractErrors(error);
}
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/MultiLayoutVerificationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/MultiLayoutVerificationTest.java
index bbf86e7a..2c138687 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/MultiLayoutVerificationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/MultiLayoutVerificationTest.java
@@ -208,13 +208,15 @@ public class MultiLayoutVerificationTest extends BaseCompilationTest {
CompilationResult result = runGradle("assembleDebug");
assertNotEquals(result.output, 0, result.resultCode);
List<ScopedException> exceptions = result.getBindingExceptions();
- assertEquals(result.error, 2, exceptions.size());
boolean foundNormal = false;
boolean foundLandscape = false;
for (ScopedException exception : exceptions) {
ScopedErrorReport report = exception.getScopedErrorReport();
assertNotNull(report);
+ if (exception.getMessage().startsWith("Cannot find the setter")) {
+ continue;
+ }
File file = new File(report.getFilePath());
assertTrue(file.exists());
assertEquals(result.error, 1, report.getLocations().size());
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
index 229323ff..ee5467e2 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
@@ -16,23 +16,41 @@
package android.databinding.compilationTest;
+import android.databinding.tool.CompilerChef;
+import android.databinding.tool.processing.ErrorMessages;
+import android.databinding.tool.processing.ScopedErrorReport;
+import android.databinding.tool.processing.ScopedException;
+import android.databinding.tool.reflection.InjectedClass;
+import android.databinding.tool.reflection.ModelClass;
+import android.databinding.tool.reflection.ModelMethod;
+import android.databinding.tool.reflection.java.JavaAnalyzer;
+import android.databinding.tool.store.Location;
+
+import com.google.common.base.Joiner;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
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;
-import android.databinding.tool.store.Location;
-
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -118,6 +136,21 @@ public class SimpleCompilationTest extends BaseCompilationTest {
return scopedException;
}
+ private void singleFileWarningTest(String resource, String targetFile,
+ String expectedMessage)
+ throws IOException, URISyntaxException, InterruptedException {
+ prepareProject();
+ copyResourceTo(resource, targetFile);
+ CompilationResult result = runGradle("assembleDebug");
+ assertEquals(0, result.resultCode);
+ final List<String> warnings = result.getBindingWarnings();
+ boolean found = false;
+ for (String warning : warnings) {
+ found |= warning.contains(expectedMessage);
+ }
+ assertTrue(Joiner.on("\n").join(warnings),found);
+ }
+
@Test
public void testMultipleExceptionsInDifferentFiles()
throws IOException, URISyntaxException, InterruptedException {
@@ -142,7 +175,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());
@@ -161,9 +194,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
@@ -172,9 +205,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
@@ -192,7 +225,35 @@ 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
+ public void testCallbackArgumentCountMismatch() throws Throwable {
+ singleFileErrorTest("/layout/layout_with_missing_callback_args.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "(seekBar, progress) -> obj.length()",
+ String.format(ErrorMessages.CALLBACK_ARGUMENT_COUNT_MISMATCH,
+ "android.databinding.adapters.SeekBarBindingAdapter.OnProgressChanged",
+ "onProgressChanged", 3, 2));
+ }
+
+ @Test
+ public void testDuplicateCallbackArgument() throws Throwable {
+ singleFileErrorTest("/layout/layout_with_duplicate_callback_identifier.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "(seekBar, progress, progress) -> obj.length()",
+ String.format(ErrorMessages.DUPLICATE_CALLBACK_ARGUMENT,
+ "progress"));
+ }
+
+ @Test
+ public void testConflictWithVariableName() throws Throwable {
+ singleFileWarningTest("/layout/layout_with_same_name_for_var_and_callback.xml",
+ "/app/src/main/res/layout/broken.xml",
+ String.format(ErrorMessages.CALLBACK_VARIABLE_NAME_CLASH,
+ "myVar", "myVar", "String"));
+
}
@Test
@@ -213,7 +274,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
@@ -281,4 +342,61 @@ 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());
+ }
+
+ @SuppressWarnings("deprecated")
+ @Test
+ public void testDynamicUtilMembers() throws Throwable {
+ prepareProject();
+ CompilationResult result = runGradle("assembleDebug");
+ assertEquals(result.error, 0, result.resultCode);
+ assertTrue("there should not be any errors " + result.error,
+ StringUtils.isEmpty(result.error));
+ assertTrue("Test sanity, should compile fine",
+ result.resultContainsText("BUILD SUCCESSFUL"));
+ File classFile = new File(testFolder,
+ "app/build/intermediates/classes/debug/android/databinding/DynamicUtil.class");
+ assertTrue(classFile.exists());
+
+ File root = new File(testFolder, "app/build/intermediates/classes/debug/");
+ URL[] urls = new URL[] {root.toURL()};
+ JavaAnalyzer.initForTests();
+ JavaAnalyzer analyzer = (JavaAnalyzer) JavaAnalyzer.getInstance();
+ ClassLoader classLoader = new URLClassLoader(urls, analyzer.getClassLoader());
+ Class dynamicUtilClass = classLoader.loadClass("android.databinding.DynamicUtil");
+
+ InjectedClass injectedClass = CompilerChef.pushDynamicUtilToAnalyzer();
+
+ // test methods
+ for (Method method : dynamicUtilClass.getMethods()) {
+ // look for the method in the injected class
+ ArrayList<ModelClass> args = new ArrayList<ModelClass>();
+ for (Class<?> param : method.getParameterTypes()) {
+ args.add(analyzer.findClass(param));
+ }
+ ModelMethod modelMethod = injectedClass.getMethod(
+ method.getName(), args, Modifier.isStatic(method.getModifiers()), false);
+ assertNotNull("Method " + method + " not found", modelMethod);
+ }
+ }
}
diff --git a/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml b/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml
new file mode 100644
index 00000000..3ba571e0
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml
@@ -0,0 +1,31 @@
+<?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:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <View android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onProgressChanged="@{(seekBar, progress, progress) -> obj.length()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml b/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml
new file mode 100644
index 00000000..7882cb6c
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml
@@ -0,0 +1,31 @@
+<?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:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onProgressChanged="@{(seekBar, progress) -> obj.length()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml b/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml
new file mode 100644
index 00000000..379ae6ed
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml
@@ -0,0 +1,31 @@
+<?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:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onClick="@{(myVar) -> myVar.setVisibility(1)}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
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/build.gradle b/compiler/build.gradle
index 8a9e9919..cd4eac27 100644
--- a/compiler/build.gradle
+++ b/compiler/build.gradle
@@ -16,8 +16,8 @@
apply plugin: 'java'
apply plugin: 'kotlin'
-sourceCompatibility = dataBindingConfig.javaTargetCompatibility
-targetCompatibility = dataBindingConfig.javaSourceCompatibility
+sourceCompatibility = dataBindingConfig.compilerJavaTargetCompatibility
+targetCompatibility = dataBindingConfig.compilerJavaSourceCompatibility
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -38,7 +38,7 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.10'
- compile 'com.tunnelvisionlabs:antlr4:4.5'
+ compile 'org.antlr:antlr4:4.5.3'
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
testCompile 'junit:junit:4.12'
}
@@ -60,7 +60,9 @@ uploadArchives {
}
}
-
+javadoc {
+ options.addStringOption('Xdoclint:none', '-quiet')
+}
project.ext.pomName = 'Data Binding Annotation Processor'
project.ext.pomDesc = 'The annotation processor for Data Binding. Generates binding classes for runtime.'
diff --git a/compiler/compiler.iml b/compiler/compiler.iml
deleted file mode 100644
index b0d4edff..00000000
--- a/compiler/compiler.iml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":dataBinding:compiler" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="1.1" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/classes/main" />
- <output-test url="file://$MODULE_DIR$/build/classes/test" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="compilerCommon" />
- <orderEntry type="module" module-name="baseLibrary" />
- <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta-4584" level="project" />
- <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
- <orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4:4.5" level="project" />
- <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
- <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-runtime:1.0.0-beta-4584" level="project" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4-runtime:4.5" level="project" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4-annotations:4.5" level="project" />
- <orderEntry type="library" name="Gradle: org.antlr:antlr-runtime:3.5.2" level="project" />
- <orderEntry type="library" name="Gradle: org.antlr:ST4:4.0.8" level="project" />
- <orderEntry type="library" name="Gradle: org.abego.treelayout:org.abego.treelayout.core:1.0.1" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.12" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
- <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
- </component>
-</module> \ No newline at end of file
diff --git a/compiler/db-compiler.iml b/compiler/db-compiler.iml
index 2f3a0d27..d47a5828 100644
--- a/compiler/db-compiler.iml
+++ b/compiler/db-compiler.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java
index aba6b3eb..59e86141 100644
--- a/compiler/src/main/java/android/databinding/tool/Binding.java
+++ b/compiler/src/main/java/android/databinding/tool/Binding.java
@@ -17,19 +17,24 @@
package android.databinding.tool;
import android.databinding.tool.expr.Expr;
+import android.databinding.tool.expr.ExprModel;
+import android.databinding.tool.expr.LambdaExpr;
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.reflection.ModelMethod;
import android.databinding.tool.store.Location;
import android.databinding.tool.store.SetterStore;
import android.databinding.tool.store.SetterStore.BindingSetterCall;
import android.databinding.tool.store.SetterStore.SetterCall;
import android.databinding.tool.util.L;
+import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.LayoutBinderWriterKt;
import java.util.List;
+import java.util.Map;
public class Binding implements LocationScopeProvider {
@@ -55,7 +60,7 @@ public class Binding implements LocationScopeProvider {
}
public void resolveListeners() {
- final ModelClass listenerParameter = getListenerParameter(mTarget, mName, mExpr);
+ final ModelClass listenerParameter = getListenerParameter(mTarget, mName, mExpr.getModel());
Expr listenerExpr = mExpr.resolveListeners(listenerParameter, null);
if (listenerExpr != mExpr) {
listenerExpr.setBindingExpression(true);
@@ -63,6 +68,30 @@ public class Binding implements LocationScopeProvider {
}
}
+ public void resolveCallbackParams() {
+ if (!(mExpr instanceof LambdaExpr)) {
+ return;
+ }
+ LambdaExpr lambdaExpr = (LambdaExpr) mExpr;
+ final ModelClass listener = getListenerParameter(mTarget, mName, mExpr.getModel());
+ Preconditions.checkNotNull(listener, ErrorMessages.CANNOT_FIND_SETTER_CALL, mName,
+ "lambda", getTarget().getInterfaceType());
+ //noinspection ConstantConditions
+ List<ModelMethod> abstractMethods = listener.getAbstractMethods();
+ int numberOfAbstractMethods = abstractMethods.size();
+ if (numberOfAbstractMethods != 1) {
+ L.e(ErrorMessages.CANNOT_FIND_ABSTRACT_METHOD, mName, listener.getCanonicalName(),
+ numberOfAbstractMethods, 1);
+ }
+ final ModelMethod method = abstractMethods.get(0);
+ final int argCount = lambdaExpr.getCallbackExprModel().getArgCount();
+ if (argCount != 0 && argCount != method.getParameterTypes().length) {
+ L.e(ErrorMessages.CALLBACK_ARGUMENT_COUNT_MISMATCH, listener.getCanonicalName(),
+ method.getName(), method.getParameterTypes().length, argCount);
+ }
+ lambdaExpr.setup(listener, method, mExpr.getModel().obtainCallbackId());
+ }
+
public void resolveTwoWayExpressions() {
Expr expr = mExpr.resolveTwoWayExpressions(null);
if (expr != mExpr) {
@@ -77,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();
@@ -97,7 +127,8 @@ public class Binding implements LocationScopeProvider {
mSetterCall = SetterStore.get(modelAnalyzer).getSetterCall(mName,
viewStubProxy, mExpr.getResolvedType(), mExpr.getModel().getImports());
} else if (isViewStubAttribute(mName)) {
- mSetterCall = new ViewStubDirectCall(mName, viewType, mExpr);
+ mSetterCall = new ViewStubDirectCall(mName, viewType, mExpr.getResolvedType(),
+ mExpr.getModel().getImports());
} else {
mSetterCall = new ViewStubSetterCall(mName);
}
@@ -111,7 +142,8 @@ public class Binding implements LocationScopeProvider {
/**
* Similar to getSetterCall, but assumes an Object parameter to find the best matching listener.
*/
- private static ModelClass getListenerParameter(BindingTarget target, String name, Expr expr) {
+ private static ModelClass getListenerParameter(BindingTarget target, String name,
+ ExprModel model) {
ModelClass viewType = target.getResolvedType();
SetterCall setterCall;
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
@@ -122,15 +154,15 @@ public class Binding implements LocationScopeProvider {
ModelClass viewStubProxy = modelAnalyzer.
findClass("android.databinding.ViewStubProxy", null);
setterCall = SetterStore.get(modelAnalyzer).getSetterCall(name,
- viewStubProxy, objectParameter, expr.getModel().getImports());
+ viewStubProxy, objectParameter, model.getImports());
} else if (isViewStubAttribute(name)) {
- setterCall = new ViewStubDirectCall(name, viewType, expr);
+ setterCall = null; // view stub attrs are not callbacks
} else {
setterCall = new ViewStubSetterCall(name);
}
} else {
setterCall = setterStore.getSetterCall(name, viewType, objectParameter,
- expr.getModel().getImports());
+ model.getImports());
}
if (setterCall != null) {
return setterCall.getParameterTypes()[0];
@@ -244,12 +276,13 @@ public class Binding implements LocationScopeProvider {
private static class ViewStubDirectCall extends SetterCall {
private final SetterCall mWrappedCall;
- public ViewStubDirectCall(String name, ModelClass viewType, Expr expr) {
+ public ViewStubDirectCall(String name, ModelClass viewType, ModelClass resolvedType,
+ Map<String, String> imports) {
mWrappedCall = SetterStore.get(ModelAnalyzer.getInstance()).getSetterCall(name,
- viewType, expr.getResolvedType(), expr.getModel().getImports());
+ viewType, resolvedType, imports);
if (mWrappedCall == null) {
L.e("Cannot find the setter for attribute '%s' on %s with parameter type %s.",
- name, viewType, expr.getResolvedType());
+ name, viewType, resolvedType);
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/BindingTarget.java b/compiler/src/main/java/android/databinding/tool/BindingTarget.java
index d8db559e..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());
@@ -151,13 +147,34 @@ public class BindingTarget implements LocationScopeProvider {
public void resolveListeners() {
for (Binding binding : mBindings) {
- binding.resolveListeners();
+ try {
+ Scope.enter(binding);
+ binding.resolveListeners();
+ } finally {
+ Scope.exit();
+ }
+ }
+ }
+
+ public void resolveCallbackParams() {
+ for (Binding binding : mBindings) {
+ try {
+ Scope.enter(binding);
+ binding.resolveCallbackParams();
+ } finally {
+ Scope.exit();
+ }
}
}
public void resolveTwoWayExpressions() {
for (Binding binding : mBindings) {
- binding.resolveTwoWayExpressions();
+ try {
+ Scope.enter(binding);
+ binding.resolveTwoWayExpressions();
+ } finally {
+ Scope.exit();
+ }
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/CallbackWrapper.java b/compiler/src/main/java/android/databinding/tool/CallbackWrapper.java
new file mode 100644
index 00000000..d8ec24f3
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/CallbackWrapper.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+import android.databinding.tool.reflection.ModelClass;
+import android.databinding.tool.reflection.ModelMethod;
+import android.databinding.tool.util.L;
+import android.databinding.tool.util.Preconditions;
+
+/**
+ * As data-binding finds lambda expressions, it creates classes that can wrap those callbacks
+ * into methods that can be called into the ViewDataBinding classes.
+ * <p>
+ * The model keeps track of these wrappers and at the end data-binding generates all of them.
+ * These are stripped from library projects and re-generated.
+ */
+public class CallbackWrapper {
+ public static String SOURCE_ID = "sourceId";
+ public static String ARG_PREFIX = "callbackArg_";
+ public final ModelClass klass;
+ public final ModelMethod method;
+ public final String key;
+ private static final String PACKAGE = "android.databinding.generated.callback";
+ private static final String LISTENER_NAME = "Listener";
+ private String mClassName;
+ private String mListenerMethodName;
+ private boolean mInitialized;
+
+ public CallbackWrapper(ModelClass klass, ModelMethod method) {
+ this.klass = klass;
+ this.method = method;
+ this.key = uniqueKey(klass, method);
+ }
+
+ public void prepare(String className, String listenerMethodName) {
+ if (mInitialized) {
+ L.e("trying to initialize listener wrapper twice.");
+ }
+ mInitialized = true;
+ mClassName = className;
+ mListenerMethodName = listenerMethodName;
+ }
+
+ public String getPackage() {
+ return PACKAGE;
+ }
+
+ public String getClassName() {
+ Preconditions.check(mInitialized, "Listener wrapper is not initialized yet.");
+ return mClassName;
+ }
+
+ public String getListenerInterfaceName() {
+ return LISTENER_NAME;
+ }
+
+ public String getListenerMethodName() {
+ Preconditions.check(mInitialized, "Listener wrapper is not initialized yet.");
+ return mListenerMethodName;
+ }
+
+ public static String uniqueKey(ModelClass klass, ModelMethod method) {
+ String base = klass.getCanonicalName() + "#" + method.getName();
+ for (ModelClass param : method.getParameterTypes()) {
+ base += param + ",";
+ }
+ return base;
+ }
+
+ public String getCannonicalName() {
+ return getPackage() + "." + getClassName();
+ }
+
+ public String getCannonicalListenerName() {
+ return getPackage() + "." + getClassName() + "." + getListenerInterfaceName();
+ }
+
+ public String constructForIdentifier(int listenerId) {
+ return "new " + getCannonicalName() + "(this, " + listenerId + ")";
+ }
+
+ public int getMinApi() {
+ return Math.min(method.getMinApi(), klass.getMinApi());
+ }
+}
diff --git a/compiler/src/main/java/android/databinding/tool/CompilerChef.java b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
index b7456da0..c167207a 100644
--- a/compiler/src/main/java/android/databinding/tool/CompilerChef.java
+++ b/compiler/src/main/java/android/databinding/tool/CompilerChef.java
@@ -13,6 +13,8 @@
package android.databinding.tool;
+import android.databinding.tool.reflection.InjectedClass;
+import android.databinding.tool.reflection.InjectedMethod;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.store.ResourceBundle;
@@ -23,6 +25,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 +72,8 @@ public class CompilerChef {
chef.mResourceBundle = bundle;
chef.mFileWriter = fileWriter;
chef.mResourceBundle.validateMultiResLayouts();
+ chef.pushClassesToAnalyzer();
+ chef.pushDynamicUtilToAnalyzer();
return chef;
}
@@ -89,6 +94,71 @@ 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 static InjectedClass pushDynamicUtilToAnalyzer() {
+ InjectedClass injectedClass = new InjectedClass("android.databinding.DynamicUtil",
+ "java.lang.Object");
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "getColorFromResource",
+ "int", "android.view.View", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true,
+ "getColorStateListFromResource", "android.content.res.ColorStateList",
+ "android.view.View", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "getDrawableFromResource",
+ "android.graphics.drawable.Drawable", "android.view.View", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "boolean", "java.lang.String", "boolean"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "short", "java.lang.String", "short"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "int", "java.lang.String", "int"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "long", "java.lang.String", "long"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "float", "java.lang.String", "float"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "double", "java.lang.String", "double"));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, true, "parse",
+ "char", "java.lang.String", "char"));
+ ModelAnalyzer analyzer = ModelAnalyzer.getInstance();
+ analyzer.injectClass(injectedClass);
+ return injectedClass;
+ }
+
public void writeDataBinderMapper(int minSdk, BRWriter brWriter) {
ensureDataBinder();
final String pkg = "android.databinding";
diff --git a/compiler/src/main/java/android/databinding/tool/DataBinder.java b/compiler/src/main/java/android/databinding/tool/DataBinder.java
index 0280bd43..0942282f 100644
--- a/compiler/src/main/java/android/databinding/tool/DataBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/DataBinder.java
@@ -20,10 +20,13 @@ import android.databinding.tool.processing.Scope;
import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.store.ResourceBundle;
import android.databinding.tool.util.L;
+import android.databinding.tool.util.StringUtils;
+import android.databinding.tool.writer.CallbackWrapperWriter;
import android.databinding.tool.writer.ComponentWriter;
import android.databinding.tool.writer.JavaFileWriter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -38,7 +41,7 @@ public class DataBinder {
private JavaFileWriter mFileWriter;
- Set<String> writtenClasses = new HashSet<String>();
+ Set<String> mWrittenClasses = new HashSet<String>();
public DataBinder(ResourceBundle resourceBundle) {
L.d("reading resource bundle into data binder");
@@ -70,13 +73,13 @@ public class DataBinder {
if (isLibrary || layoutBinder.hasVariations()) {
String className = layoutBinder.getClassName();
String canonicalName = layoutBinder.getPackage() + "." + className;
- if (writtenClasses.contains(canonicalName)) {
+ if (mWrittenClasses.contains(canonicalName)) {
continue;
}
L.d("writing data binder base %s", canonicalName);
mFileWriter.writeToFile(canonicalName,
layoutBinder.writeViewBinderBaseClass(isLibrary));
- writtenClasses.add(canonicalName);
+ mWrittenClasses.add(canonicalName);
}
} catch (ScopedException ex){
Scope.defer(ex);
@@ -87,13 +90,14 @@ public class DataBinder {
}
public void writeBinders(int minSdk) {
+ writeCallbackWrappers(minSdk);
for (LayoutBinder layoutBinder : mLayoutBinders) {
try {
Scope.enter(layoutBinder);
String className = layoutBinder.getImplementationName();
String canonicalName = layoutBinder.getPackage() + "." + className;
L.d("writing data binder %s", canonicalName);
- writtenClasses.add(canonicalName);
+ mWrittenClasses.add(canonicalName);
mFileWriter.writeToFile(canonicalName, layoutBinder.writeViewBinder(minSdk));
} catch (ScopedException ex) {
Scope.defer(ex);
@@ -103,15 +107,62 @@ public class DataBinder {
}
}
+ private void writeCallbackWrappers(int minSdk) {
+ Map<String, CallbackWrapper> uniqueWrappers = new HashMap<String, CallbackWrapper>();
+ Set<String> classNames = new HashSet<String>();
+ int callbackCounter = 0;
+ for (LayoutBinder binder : mLayoutBinders) {
+ for (Map.Entry<String, CallbackWrapper> entry : binder.getModel().getCallbackWrappers()
+ .entrySet()) {
+ final CallbackWrapper existing = uniqueWrappers.get(entry.getKey());
+ if (existing == null) {
+ // first time seeing this. register
+ final CallbackWrapper wrapper = entry.getValue();
+ uniqueWrappers.put(entry.getKey(), wrapper);
+ String listenerName = makeUnique(classNames, wrapper.klass.getSimpleName());
+ String methodName = makeUnique(classNames,
+ "_internalCallback" + StringUtils.capitalize(wrapper.method.getName()));
+ wrapper.prepare(listenerName, methodName);
+ } else {
+ // fill from previous
+ entry.getValue()
+ .prepare(existing.getClassName(), existing.getListenerMethodName());
+ }
+
+ }
+ }
+
+ // now write the original wrappers
+ for (CallbackWrapper wrapper : uniqueWrappers.values()) {
+ final String code = new CallbackWrapperWriter(wrapper).write();
+ String className = wrapper.getClassName();
+ String canonicalName = wrapper.getPackage() + "." + className;
+ mFileWriter.writeToFile(canonicalName, code);
+ // these will be deleted for library projects.
+ mWrittenClasses.add(canonicalName);
+ }
+
+ }
+
+ private String makeUnique(Set<String> existing, String wanted) {
+ int cnt = 1;
+ while (existing.contains(wanted)) {
+ wanted = wanted + cnt;
+ cnt++;
+ }
+ existing.add(wanted);
+ return wanted;
+ }
+
public void writeComponent() {
ComponentWriter componentWriter = new ComponentWriter();
- writtenClasses.add(COMPONENT_CLASS);
+ mWrittenClasses.add(COMPONENT_CLASS);
mFileWriter.writeToFile(COMPONENT_CLASS, componentWriter.createComponent());
}
public Set<String> getWrittenClassNames() {
- return writtenClasses;
+ return mWrittenClasses;
}
public void setFileWriter(JavaFileWriter fileWriter) {
diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
index 5468c936..18fb8399 100644
--- a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
+++ b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
@@ -23,7 +23,6 @@ import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.Nullable;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -37,6 +36,8 @@ import android.databinding.tool.store.Location;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
+import com.android.annotations.Nullable;
+
import java.util.ArrayList;
import java.util.List;
@@ -49,16 +50,16 @@ public class ExpressionParser {
visitor = new ExpressionVisitor(mModel);
}
- public Expr parse(String input, @Nullable Location locationInFile) {
+ public Expr parse(String input, @Nullable Location locationInFile, BindingTarget target) {
ANTLRInputStream inputStream = new ANTLRInputStream(input);
BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
final BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
+ visitor.setBindingTarget(target);
parser.addErrorListener(new BaseErrorListener() {
@Override
- public <T extends Token> void syntaxError(Recognizer<T, ?> recognizer,
- @Nullable T offendingSymbol, int line, int charPositionInLine, String msg,
- @Nullable RecognitionException e) {
+ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
+ int charPositionInLine, String msg, RecognitionException e) {
L.e(ErrorMessages.SYNTAX_ERROR, msg);
}
});
diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
index 08e67443..d273f387 100644
--- a/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
+++ b/compiler/src/main/java/android/databinding/tool/ExpressionVisitor.java
@@ -16,14 +16,6 @@
package android.databinding.tool;
-import com.google.common.base.Objects;
-
-import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.misc.NotNull;
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.antlr.v4.runtime.tree.ParseTreeListener;
-import org.antlr.v4.runtime.tree.TerminalNode;
-
import android.databinding.parser.BindingExpressionBaseVisitor;
import android.databinding.parser.BindingExpressionParser;
import android.databinding.parser.BindingExpressionParser.AndOrOpContext;
@@ -31,6 +23,7 @@ import android.databinding.parser.BindingExpressionParser.BinaryOpContext;
import android.databinding.parser.BindingExpressionParser.BitShiftOpContext;
import android.databinding.parser.BindingExpressionParser.InstanceOfOpContext;
import android.databinding.parser.BindingExpressionParser.UnaryOpContext;
+import android.databinding.tool.expr.CallbackExprModel;
import android.databinding.tool.expr.Expr;
import android.databinding.tool.expr.ExprModel;
import android.databinding.tool.expr.StaticIdentifierExpr;
@@ -38,21 +31,36 @@ import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.util.Preconditions;
+import com.android.annotations.NonNull;
+import com.google.common.base.Objects;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
-public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
- private final ExprModel mModel;
+class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
+ private ExprModel mModel;
private ParseTreeListener mParseTreeListener;
+ private ArrayDeque<ExprModel> mModelStack = new ArrayDeque<ExprModel>();
+ private BindingTarget mTarget;
- public ExpressionVisitor(ExprModel model) {
+ ExpressionVisitor(ExprModel model) {
mModel = model;
}
- public void setParseTreeListener(ParseTreeListener parseTreeListener) {
+ void setParseTreeListener(ParseTreeListener parseTreeListener) {
mParseTreeListener = parseTreeListener;
}
+ public void setBindingTarget(BindingTarget bindingTarget) {
+ mTarget = bindingTarget;
+ }
+
private void onEnter(ParserRuleContext context) {
if (mParseTreeListener != null) {
mParseTreeListener.enterEveryRule(context);
@@ -65,8 +73,75 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
}
+ private void pushModel(ExprModel model) {
+ Preconditions.checkNotNull(mModel, "Cannot put empty model to stack");
+ Preconditions.checkNotNull(model, "Cannot set null model");
+ mModelStack.push(mModel);
+ mModel = model;
+ }
+
+ private void popModel() {
+ Preconditions.checkNotNull(mModel, "Cannot have empty mdoel stack");
+ Preconditions.check(mModelStack.size() > 0, "Cannot have empty model stack");
+ mModel = mModelStack.pop();
+ }
+
+ @Override
+ public Expr visitRootLambda(@NonNull BindingExpressionParser.RootLambdaContext ctx) {
+ try {
+ onEnter(ctx);
+ CallbackExprModel callbackModel = new CallbackExprModel(mModel);
+ ExprModel prev = mModel;
+ pushModel(callbackModel);
+ final BindingExpressionParser.LambdaExpressionContext lambdaCtx = ctx
+ .lambdaExpression();
+ lambdaCtx.args.accept(this);
+ return prev.lambdaExpr(lambdaCtx.expression().accept(this), callbackModel);
+ } finally {
+ popModel();
+ onExit(ctx);
+ }
+ }
+
@Override
- public Expr visitStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx) {
+ public Expr visitSingleLambdaParameter(
+ @NonNull BindingExpressionParser.SingleLambdaParameterContext ctx) {
+ try {
+ onEnter(ctx);
+ Preconditions.check(mModel instanceof CallbackExprModel, "Lambdas can only be used in"
+ + " callbacks.");
+ // just add it to the callback model as identifier
+ ((CallbackExprModel) mModel).callbackArg(ctx.getText());
+ return null;
+ } finally {
+ onExit(ctx);
+ }
+ }
+
+ @Override
+ public Expr visitLambdaParameterList(
+ @NonNull BindingExpressionParser.LambdaParameterListContext ctx) {
+ try {
+ onEnter(ctx);
+ Preconditions.check(mModel instanceof CallbackExprModel, "Lambdas can only be used in"
+ + " callbacks.");
+ if (ctx.params != null) {
+ for (ParseTree item : ctx.params.children) {
+ if (Objects.equal(item.getText(), ",")) {
+ continue;
+ }
+ // just add them to the callback model as identifiers
+ ((CallbackExprModel) mModel).callbackArg(item.getText());
+ }
+ }
+ return null;
+ } finally {
+ onExit(ctx);
+ }
+ }
+
+ @Override
+ public Expr visitStringLiteral(@NonNull BindingExpressionParser.StringLiteralContext ctx) {
try {
onEnter(ctx);
final String javaString;
@@ -85,34 +160,34 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) {
+ public Expr visitRootExpr(@NonNull BindingExpressionParser.RootExprContext ctx) {
try {
onEnter(ctx);
- Preconditions.check(ctx.children.size() == 3, "Grouping expression should have"
- + " 3 children. # of children: %d", ctx.children.size());
- return mModel.group(ctx.children.get(1).accept(this));
+ // TODO handle defaults
+ return mModel.bindingExpr(ctx.expression().accept(this));
+ } catch (Exception e) {
+ System.out.println("Error while parsing! " + ctx.getText());
+ e.printStackTrace();
+ throw new RuntimeException(e);
} finally {
onExit(ctx);
}
}
@Override
- public Expr visitBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx) {
+ public Expr visitGrouping(@NonNull BindingExpressionParser.GroupingContext ctx) {
try {
onEnter(ctx);
- // TODO handle defaults
- return mModel.bindingExpr(ctx.expression().accept(this));
- } catch (Exception e) {
- System.out.println("Error while parsing! " + ctx.getText());
- e.printStackTrace();
- throw new RuntimeException(e);
+ Preconditions.check(ctx.children.size() == 3, "Grouping expression should have"
+ + " 3 children. # of children: %d", ctx.children.size());
+ return ctx.children.get(1).accept(this);
} finally {
onExit(ctx);
}
}
@Override
- public Expr visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) {
+ public Expr visitDotOp(@NonNull BindingExpressionParser.DotOpContext ctx) {
try {
onEnter(ctx);
ModelAnalyzer analyzer = ModelAnalyzer.getInstance();
@@ -132,7 +207,19 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) {
+ public Expr visitFunctionRef(@NonNull BindingExpressionParser.FunctionRefContext ctx) {
+ try {
+ onEnter(ctx);
+ return mModel.methodReference(ctx.expression().accept(this),
+ ctx.Identifier().getSymbol().getText());
+ } finally {
+ onExit(ctx);
+ }
+ }
+
+ @Override
+ public Expr visitQuestionQuestionOp(
+ @NonNull BindingExpressionParser.QuestionQuestionOpContext ctx) {
try {
onEnter(ctx);
final Expr left = ctx.left.accept(this);
@@ -144,9 +231,9 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitTerminal(@NotNull TerminalNode node) {
+ public Expr visitTerminal(@NonNull TerminalNode node) {
try {
- onEnter((ParserRuleContext) node.getParent().getRuleContext());
+ onEnter((ParserRuleContext) node.getParent());
final int type = node.getSymbol().getType();
Class classType;
switch (type) {
@@ -169,18 +256,21 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
case BindingExpressionParser.NullLiteral:
classType = Object.class;
break;
+ case BindingExpressionParser.VoidLiteral:
+ classType = void.class;
+ break;
default:
throw new RuntimeException("cannot create expression from terminal node " +
node.toString());
}
return mModel.symbol(node.getText(), classType);
} finally {
- onExit((ParserRuleContext) node.getParent().getRuleContext());
+ onExit((ParserRuleContext) node.getParent());
}
}
@Override
- public Expr visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) {
+ public Expr visitComparisonOp(@NonNull BindingExpressionParser.ComparisonOpContext ctx) {
try {
onEnter(ctx);
return mModel.comparison(ctx.op.getText(), ctx.left.accept(this), ctx.right.accept(this));
@@ -190,7 +280,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) {
+ public Expr visitIdentifier(@NonNull BindingExpressionParser.IdentifierContext ctx) {
try {
onEnter(ctx);
return mModel.identifier(ctx.getText());
@@ -200,7 +290,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) {
+ public Expr visitTernaryOp(@NonNull BindingExpressionParser.TernaryOpContext ctx) {
try {
onEnter(ctx);
return mModel.ternary(ctx.left.accept(this), ctx.iftrue.accept(this),
@@ -213,7 +303,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
@Override
public Expr visitMethodInvocation(
- @NotNull BindingExpressionParser.MethodInvocationContext ctx) {
+ @NonNull BindingExpressionParser.MethodInvocationContext ctx) {
try {
onEnter(ctx);
List<Expr> args = new ArrayList<Expr>();
@@ -233,7 +323,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) {
+ public Expr visitMathOp(@NonNull BindingExpressionParser.MathOpContext ctx) {
try {
onEnter(ctx);
return mModel.math(ctx.left.accept(this), ctx.op.getText(), ctx.right.accept(this));
@@ -243,7 +333,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitAndOrOp(@NotNull AndOrOpContext ctx) {
+ public Expr visitAndOrOp(@NonNull AndOrOpContext ctx) {
try {
onEnter(ctx);
return mModel.logical(ctx.left.accept(this), ctx.op.getText(), ctx.right.accept(this));
@@ -253,7 +343,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitBinaryOp(@NotNull BinaryOpContext ctx) {
+ public Expr visitBinaryOp(@NonNull BinaryOpContext ctx) {
try {
onEnter(ctx);
return mModel.math(ctx.left.accept(this), ctx.op.getText(), ctx.right.accept(this));
@@ -263,7 +353,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitBitShiftOp(@NotNull BitShiftOpContext ctx) {
+ public Expr visitBitShiftOp(@NonNull BitShiftOpContext ctx) {
try {
onEnter(ctx);
return mModel.bitshift(ctx.left.accept(this), ctx.op.getText(), ctx.right.accept(this));
@@ -273,7 +363,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitInstanceOfOp(@NotNull InstanceOfOpContext ctx) {
+ public Expr visitInstanceOfOp(@NonNull InstanceOfOpContext ctx) {
try {
onEnter(ctx);
return mModel.instanceOfOp(ctx.expression().accept(this), ctx.type().getText());
@@ -283,7 +373,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitUnaryOp(@NotNull UnaryOpContext ctx) {
+ public Expr visitUnaryOp(@NonNull UnaryOpContext ctx) {
try {
onEnter(ctx);
return mModel.unary(ctx.op.getText(), ctx.expression().accept(this));
@@ -293,7 +383,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitResources(@NotNull BindingExpressionParser.ResourcesContext ctx) {
+ public Expr visitResources(@NonNull BindingExpressionParser.ResourcesContext ctx) {
try {
onEnter(ctx);
final List<Expr> args = new ArrayList<Expr>();
@@ -313,14 +403,14 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
final int startIndex = Math.max(1, colonIndex + 1);
final String resourceType = resourceReference.substring(startIndex, slashIndex).trim();
final String resourceName = resourceReference.substring(slashIndex + 1).trim();
- return mModel.resourceExpr(packageName, resourceType, resourceName, args);
+ return mModel.resourceExpr(mTarget, packageName, resourceType, resourceName, args);
} finally {
onExit(ctx);
}
}
@Override
- public Expr visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) {
+ public Expr visitBracketOp(@NonNull BindingExpressionParser.BracketOpContext ctx) {
try {
onEnter(ctx);
return mModel.bracketExpr(visit(ctx.expression(0)), visit(ctx.expression(1)));
@@ -330,7 +420,7 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
}
@Override
- public Expr visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) {
+ public Expr visitCastOp(@NonNull BindingExpressionParser.CastOpContext ctx) {
try {
onEnter(ctx);
return mModel.castExpr(ctx.type().getText(), visit(ctx.expression()));
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 7ed944a8..bcbafda6 100644
--- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
@@ -30,7 +30,7 @@ import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.LayoutBinderWriter;
import android.databinding.tool.writer.LayoutBinderWriterKt;
-import org.antlr.v4.runtime.misc.Nullable;
+import com.android.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
@@ -216,17 +216,25 @@ 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);
+ bindingTarget.addBinding(bindingBundle.getName(), expr);
+ if (bindingBundle.isTwoWay()) {
+ bindingTarget.addInverseBinding(bindingBundle.getName(), expr,
+ className);
+ }
} finally {
Scope.exit();
}
}
+ // resolve callbacks first because they introduce local variables.
+ bindingTarget.resolveCallbackParams();
bindingTarget.resolveTwoWayExpressions();
bindingTarget.resolveMultiSetters();
bindingTarget.resolveListeners();
@@ -245,7 +253,7 @@ public class LayoutBinder implements FileScopeProvider {
List<Expr> used = new ArrayList<Expr>();
for (BindingTarget target : mBindingTargets) {
for (Binding binding : target.getBindings()) {
- binding.getExpr().setIsUsed(true);
+ binding.getExpr().markAsUsed();
used.add(binding.getExpr());
}
}
@@ -254,7 +262,7 @@ public class LayoutBinder implements FileScopeProvider {
for (Dependency dep : e.getDependencies()) {
if (!dep.getOther().isUsed()) {
used.add(dep.getOther());
- dep.getOther().setIsUsed(true);
+ dep.getOther().markAsUsed();
}
}
}
@@ -288,10 +296,9 @@ public class LayoutBinder implements FileScopeProvider {
return target;
}
- public Expr parse(String input, boolean isTwoWay, @Nullable Location locationInFile) {
- final Expr parsed = mExpressionParser.parse(input, locationInFile);
+ public Expr parse(String input, @Nullable Location locationInFile, BindingTarget target) {
+ final Expr parsed = mExpressionParser.parse(input, locationInFile, target);
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 392512ce..a9a61556 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/BracketExpr.java
@@ -18,8 +18,12 @@ 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 com.google.common.collect.Lists;
+
+import java.util.ArrayList;
import java.util.List;
public class BracketExpr extends Expr {
@@ -54,6 +58,28 @@ public class BracketExpr extends Expr {
}
@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) {
+ Expr cmp = getModel().comparison("!=", getTarget(),
+ getModel().symbol("null", Object.class));
+ path.addPath(cmp);
+ final ExecutionPath subPath = path.addBranch(cmp, true);
+ if (subPath != null) {
+ final List<ExecutionPath> argPath = getArg().toExecutionPath(subPath);
+ result.addAll(addJustMeToExecutionPath(argPath));
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
protected List<Dependency> constructDependencies() {
final List<Dependency> dependencies = constructDynamicChildrenDependencies();
for (Dependency dependency : dependencies) {
@@ -66,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
@@ -91,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: {
@@ -128,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
new file mode 100644
index 00000000..34841c93
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/expr/CallbackArgExpr.java
@@ -0,0 +1,93 @@
+/*
+ * 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.CallbackWrapper;
+import android.databinding.tool.processing.ErrorMessages;
+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.Collections;
+import java.util.List;
+
+/**
+ * This expressions that are used to reference arguments in callbacks.
+ * <p
+ * While the callback is being parsed, they get whatever the variable user defined in the lambda.
+ * When the code is being generated, they get simple enumarated names so that multiple callbacks
+ * can be handled in the same method.
+ */
+public class CallbackArgExpr extends IdentifierExpr {
+
+ private int mArgIndex;
+
+ private String mName;
+
+ private ModelClass mClassFromCallback;
+
+ public CallbackArgExpr(int argIndex, String name) {
+ super(name);
+ mArgIndex = argIndex;
+ mName = name;
+ }
+
+ @Override
+ public boolean isDynamic() {
+ return false;
+ }
+
+ public void setClassFromCallback(ModelClass modelClass) {
+ mClassFromCallback = modelClass;
+ }
+
+ @Override
+ protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
+ Preconditions
+ .checkNotNull(mClassFromCallback, ErrorMessages.UNDEFINED_CALLBACK_ARGUMENT, mName);
+ return mClassFromCallback;
+ }
+
+ @Override
+ protected List<Dependency> constructDependencies() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected KCode generateCode() {
+ return new KCode(CallbackWrapper.ARG_PREFIX + mArgIndex);
+ }
+
+ @Override
+ protected String computeUniqueKey() {
+ return CallbackWrapper.ARG_PREFIX + mArgIndex;
+ }
+
+ @Override
+ public String getInvertibleError() {
+ return "Callback arguments cannot be inverted";
+ }
+
+ 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
new file mode 100644
index 00000000..501125c0
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/expr/CallbackExprModel.java
@@ -0,0 +1,126 @@
+/*
+ * 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.ErrorMessages;
+import android.databinding.tool.processing.Scope;
+import android.databinding.tool.store.Location;
+import android.databinding.tool.util.L;
+import android.databinding.tool.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Callbacks are evaluated when event happens, not when execute pending is run. To separate their
+ * expressions, we provide a separate model for them that extends the main model. This allows them
+ * to introduce their own variables etc. without mixing them with other expressions.
+ */
+public class CallbackExprModel extends ExprModel {
+ // used for imports and other stuff.
+ final ExprModel mOriginal;
+ final List<CallbackArgExpr> mArguments = new ArrayList<CallbackArgExpr>();
+ public CallbackExprModel(ExprModel original) {
+ mOriginal = original;
+ }
+
+ @Override
+ public Map<String, String> getImports() {
+ return mOriginal.getImports();
+ }
+
+ @Override
+ public StaticIdentifierExpr addImport(String alias, String type, Location location) {
+ return mOriginal.addImport(alias, type, location);
+ }
+
+ @Override
+ public <T extends Expr> T register(T expr) {
+ // locations are only synced to main model so we need to sync overselves here.
+ setCurrentLocationInFile(mOriginal.getCurrentLocationInFile());
+ setCurrentParserContext(mOriginal.getCurrentParserContext());
+ return super.register(expr);
+ }
+
+ @Override
+ public void seal() {
+ // ensure all types are calculated
+ for (Expr expr : mExprMap.values()) {
+ expr.getResolvedType();
+ expr.markAsUsedInCallback();
+ }
+ markSealed();
+ // we do not resolve dependencies for these expression because they are resolved via
+ // ExecutionPath and should not interfere with the main expr model's dependency graph.
+ }
+
+ @Override
+ public IdentifierExpr identifier(String name) {
+ CallbackArgExpr arg = findArgByName(name);
+ if (arg != null) {
+ return arg;
+ }
+ IdentifierExpr id = new IdentifierExpr(name);
+ final Expr existing = mExprMap.get(id.getUniqueKey());
+ if (existing == null) {
+ // this is not a method variable reference. register it in the main model
+ final IdentifierExpr identifier = mOriginal.identifier(name);
+ mExprMap.put(identifier.getUniqueKey(), identifier);
+ identifier.markAsUsedInCallback();
+ return identifier;
+ }
+ return (IdentifierExpr) existing;
+ }
+
+ private CallbackArgExpr findArgByName(String name) {
+ for (CallbackArgExpr arg : mArguments) {
+ if (name.equals(arg.getName())) {
+ return arg;
+ }
+ }
+ return null;
+ }
+
+ public CallbackArgExpr callbackArg(String name) {
+ Preconditions.checkNull(findArgByName(name),
+ ErrorMessages.DUPLICATE_CALLBACK_ARGUMENT, name);
+ final CallbackArgExpr id = new CallbackArgExpr(mArguments.size(), name);
+ final CallbackArgExpr added = register(id);
+ mArguments.add(added);
+
+ try {
+ Scope.enter(added);
+ IdentifierExpr identifierWithSameName = mOriginal.findIdentifier(name);
+ if (identifierWithSameName != null) {
+ L.w(ErrorMessages.CALLBACK_VARIABLE_NAME_CLASH, name, name,
+ identifierWithSameName.getUserDefinedType());
+ }
+ } finally {
+ Scope.exit();
+ }
+ return added;
+ }
+
+ public int getArgCount() {
+ return mArguments.size();
+ }
+
+ public List<CallbackArgExpr> getArguments() {
+ return mArguments;
+ }
+}
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 193501c2..42d98a19 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/Expr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/Expr.java
@@ -16,19 +16,21 @@
package android.databinding.tool.expr;
-import org.antlr.v4.runtime.misc.Nullable;
-
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.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.KCode;
import android.databinding.tool.writer.LayoutBinderWriterKt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
@@ -36,7 +38,6 @@ import java.util.List;
import java.util.Map;
abstract public class Expr implements VersionProvider, LocationScopeProvider {
-
public static final int NO_ID = -1;
protected List<Expr> mChildren = new ArrayList<Expr>();
@@ -98,7 +99,7 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
*/
private boolean mRead;
private boolean mIsUsed = false;
- private boolean mIsTwoWay = false;
+ private boolean mIsUsedInCallback = false;
Expr(Iterable<Expr> children) {
for (Expr expr : children) {
@@ -163,7 +164,7 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
}
public boolean canBeEvaluatedToAVariable() {
- return true; // anything except arg expr can be evaluated to a variable
+ return true; // anything except arg/return expr can be evaluated to a variable
}
public boolean isObservable() {
@@ -210,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();
@@ -341,6 +326,58 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
return mResolvedType;
}
+ public final List<ExecutionPath> toExecutionPath(ExecutionPath path) {
+ List<ExecutionPath> paths = new ArrayList<ExecutionPath>();
+ paths.add(path);
+ return toExecutionPath(paths);
+ }
+
+ public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) {
+ if (getChildren().isEmpty()) {
+ return addJustMeToExecutionPath(paths);
+ } else {
+ return toExecutionPathInOrder(paths, getChildren());
+ }
+
+ }
+
+ @NotNull
+ protected final List<ExecutionPath> addJustMeToExecutionPath(List<ExecutionPath> paths) {
+ List<ExecutionPath> result = new ArrayList<ExecutionPath>();
+ for (ExecutionPath path : paths) {
+ result.add(path.addPath(this));
+ }
+ return result;
+ }
+
+ @SuppressWarnings("Duplicates")
+ protected final List<ExecutionPath> toExecutionPathInOrder(List<ExecutionPath> paths,
+ Expr... order) {
+ List<ExecutionPath> executionPaths = paths;
+ for (Expr anOrder : order) {
+ executionPaths = anOrder.toExecutionPath(executionPaths);
+ }
+ List<ExecutionPath> result = new ArrayList<ExecutionPath>(paths.size());
+ for (ExecutionPath path : executionPaths) {
+ result.add(path.addPath(this));
+ }
+ return result;
+ }
+
+ @SuppressWarnings("Duplicates")
+ protected final List<ExecutionPath> toExecutionPathInOrder(List<ExecutionPath> paths,
+ List<Expr> order) {
+ List<ExecutionPath> executionPaths = paths;
+ for (Expr expr : order) {
+ executionPaths = expr.toExecutionPath(executionPaths);
+ }
+ List<ExecutionPath> result = new ArrayList<ExecutionPath>(paths.size());
+ for (ExecutionPath path : executionPaths) {
+ result.add(path.addPath(this));
+ }
+ return result;
+ }
+
abstract protected ModelClass resolveType(ModelAnalyzer modelAnalyzer);
abstract protected List<Dependency> constructDependencies();
@@ -516,7 +553,8 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
allCovered = false;
break;
}
- final BitSet readForConditional = (BitSet) expr.findConditionalFlags().clone();
+ final BitSet readForConditional = (BitSet) expr
+ .getShouldReadFlagsWithConditionals().clone();
// FIXME: this does not do full traversal so misses some cases
// to calculate that conditional, i should've read /readForConditional/ flags
@@ -630,13 +668,24 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
return false;
}
- public void setIsUsed(boolean isUsed) {
- mIsUsed = isUsed;
+ public void markAsUsed() {
+ mIsUsed = true;
+ for (Expr child : getChildren()) {
+ child.markAsUsed();
+ }
+ }
+
+ public void markAsUsedInCallback() {
+ mIsUsedInCallback = true;
for (Expr child : getChildren()) {
- child.setIsUsed(isUsed);
+ child.markAsUsedInCallback();
}
}
+ public boolean isIsUsedInCallback() {
+ return mIsUsedInCallback;
+ }
+
public boolean isUsed() {
return mIsUsed;
}
@@ -686,26 +735,32 @@ abstract public class Expr implements VersionProvider, LocationScopeProvider {
}
public KCode toCode() {
- return toCode(false);
- }
-
- protected KCode toCode(boolean expand) {
- if (!expand && isDynamic()) {
- return new KCode(LayoutBinderWriterKt.getExecutePendingLocalName(this));
+ 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 058427e0..34b25690 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ExprModel.java
@@ -17,6 +17,7 @@
package android.databinding.tool.expr;
import android.databinding.tool.BindingTarget;
+import android.databinding.tool.CallbackWrapper;
import android.databinding.tool.InverseBinding;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
@@ -24,9 +25,11 @@ import android.databinding.tool.reflection.ModelMethod;
import android.databinding.tool.store.Location;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
+import android.databinding.tool.writer.ExprModelExt;
import android.databinding.tool.writer.FlagSet;
import org.antlr.v4.runtime.ParserRuleContext;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -34,6 +37,7 @@ import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
public class ExprModel {
@@ -67,9 +71,6 @@ public class ExprModel {
*/
private String[] mFlagMapping;
- private BitSet mInvalidateableFlags;
- private BitSet mConditionalFlags;
-
private int mFlagBucketCount;// how many buckets we use to identify flags
private List<Expr> mObservables;
@@ -80,6 +81,13 @@ public class ExprModel {
private ParserRuleContext mCurrentParserContext;
private Location mCurrentLocationInFile;
+
+ private Map<String, CallbackWrapper> mCallbackWrappers = new HashMap<String, CallbackWrapper>();
+
+ private AtomicInteger mCallbackIdCounter = new AtomicInteger();
+
+ private ExprModelExt mExt = new ExprModelExt();
+
/**
* Adds the expression to the list of expressions and returns it.
* If it already exists, returns existing one.
@@ -94,6 +102,7 @@ public class ExprModel {
location = new Location(mCurrentParserContext);
location.setParentLocation(mCurrentLocationInFile);
}
+ //noinspection unchecked
T existing = (T) mExprMap.get(expr.getUniqueKey());
if (existing != null) {
Preconditions.check(expr.getParents().isEmpty(),
@@ -116,10 +125,30 @@ public class ExprModel {
return expr;
}
+ protected void markSealed() {
+ mSealed = true;
+ }
+
+ public ExprModelExt getExt() {
+ return mExt;
+ }
+
+ public int obtainCallbackId() {
+ return mCallbackIdCounter.incrementAndGet();
+ }
+
public void setCurrentParserContext(ParserRuleContext currentParserContext) {
mCurrentParserContext = currentParserContext;
}
+ public ParserRuleContext getCurrentParserContext() {
+ return mCurrentParserContext;
+ }
+
+ public Location getCurrentLocationInFile() {
+ return mCurrentLocationInFile;
+ }
+
public Map<String, Expr> getExprMap() {
return mExprMap;
}
@@ -141,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) {
@@ -174,13 +207,9 @@ public class ExprModel {
public StaticIdentifierExpr staticIdentifierFor(final ModelClass modelClass) {
final String type = modelClass.getCanonicalName();
// check for existing
- for (Expr expr : mExprMap.values()) {
- if (expr instanceof StaticIdentifierExpr) {
- StaticIdentifierExpr id = (StaticIdentifierExpr) expr;
- if (id.getUserDefinedType().equals(type)) {
- return id;
- }
- }
+ StaticIdentifierExpr id = findStaticIdentifierExpr(type);
+ if (id != null) {
+ return id;
}
// does not exist. Find a name for it.
@@ -203,6 +232,19 @@ public class ExprModel {
}
}
+ @Nullable
+ private StaticIdentifierExpr findStaticIdentifierExpr(String type) {
+ for (Expr expr : mExprMap.values()) {
+ if (expr instanceof StaticIdentifierExpr) {
+ StaticIdentifierExpr id = (StaticIdentifierExpr) expr;
+ if (id.getUserDefinedType().equals(type)) {
+ return id;
+ }
+ }
+ }
+ return null;
+ }
+
public MethodCallExpr methodCall(Expr target, String name, List<Expr> args) {
return register(new MethodCallExpr(target, name, args));
}
@@ -231,13 +273,9 @@ public class ExprModel {
return register(new UnaryExpr(op, expr));
}
- public Expr group(Expr grouped) {
- return register(new GroupExpr(grouped));
- }
-
- public Expr resourceExpr(String packageName, String resourceType, String resourceName,
- List<Expr> args) {
- return register(new ResourceExpr(packageName, resourceType, resourceName, args));
+ public Expr resourceExpr(BindingTarget target, String packageName, String resourceType,
+ String resourceName, List<Expr> args) {
+ return register(new ResourceExpr(target, packageName, resourceType, resourceName, args));
}
public Expr bracketExpr(Expr variableExpr, Expr argExpr) {
@@ -256,8 +294,19 @@ public class ExprModel {
}
public StaticIdentifierExpr addImport(String alias, String type, Location location) {
- Preconditions.check(!mImports.containsKey(alias),
- "%s has already been defined as %s", alias, type);
+ String existing = mImports.get(alias);
+ if (existing != null) {
+ if (existing.equals(type)) {
+ final StaticIdentifierExpr id = findStaticIdentifierExpr(type);
+ Preconditions.checkNotNull(id, "Missing import expression although it is"
+ + " registered");
+ return id;
+ } else {
+ L.e("%s has already been defined as %s but trying to re-define as %s", alias,
+ existing, type);
+ }
+ }
+
final StaticIdentifierExpr id = staticIdentifier(alias);
L.d("adding import %s as %s klass: %s", type, alias, id.getClass().getSimpleName());
id.setUserDefinedType(type);
@@ -289,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() {
@@ -338,7 +387,9 @@ public class ExprModel {
if (parent instanceof FieldAccessExpr) {
FieldAccessExpr fae = (FieldAccessExpr) parent;
L.d("checking field access expr %s. getter: %s", fae,fae.getGetter());
- if (fae.isDynamic() && fae.getGetter().canBeInvalidated()) {
+ // FAE#getter might be null if it is used only in a callback.
+ if (fae.getGetter() != null && fae.isDynamic()
+ && fae.getGetter().canBeInvalidated()) {
flagMapping.add(parent.getUniqueKey());
parent.setId(counter++);
notifiableExpressions.add(parent);
@@ -355,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++);
}
@@ -381,9 +432,9 @@ public class ExprModel {
mInvalidateAnyFlagIndex = counter ++;
flagMapping.add("INVALIDATE ANY");
mInvalidateableFieldLimit = counter;
- mInvalidateableFlags = new BitSet();
+ BitSet invalidateableFlags = new BitSet();
for (int i = 0; i < mInvalidateableFieldLimit; i++) {
- mInvalidateableFlags.set(i, true);
+ invalidateableFlags.set(i, true);
}
// make sure all dependencies are resolved to avoid future race conditions
@@ -396,9 +447,9 @@ public class ExprModel {
counter += 2;
}
}
- mConditionalFlags = new BitSet();
+ BitSet conditionalFlags = new BitSet();
for (int i = mInvalidateableFieldLimit; i < counter; i++) {
- mConditionalFlags.set(i, true);
+ conditionalFlags.set(i, true);
}
mRequirementIdCount = (counter - mInvalidateableFieldLimit) / 2;
@@ -538,15 +589,17 @@ public class ExprModel {
}
}
}
- for (Expr partialRead : markedSomeFlagsAsRead) {
- // even if all paths are not satisfied, we can elevate certain conditional dependencies
- // if all of their paths are satisfied.
- for (Dependency dependency : partialRead.getDependants()) {
- Expr dependant = dependency.getDependant();
- if (dependant.isConditional() && dependant.getAllCalculationPaths()
- .areAllPathsSatisfied(partialRead.mReadSoFar)) {
- if (dependant.considerElevatingConditionals(partialRead)) {
- elevated = true;
+ if (!elevated) {
+ for (Expr partialRead : markedSomeFlagsAsRead) {
+ // even if all paths are not satisfied, we can elevate certain conditional
+ // dependencies if all of their paths are satisfied.
+ for (Dependency dependency : partialRead.getDependants()) {
+ Expr dependant = dependency.getDependant();
+ if (dependant.isConditional() && dependant.getAllCalculationPaths()
+ .areAllPathsSatisfied(partialRead.mReadSoFar)) {
+ if (dependant.considerElevatingConditionals(partialRead)) {
+ elevated = true;
+ }
}
}
}
@@ -572,8 +625,8 @@ public class ExprModel {
return false;
}
- public static List<Expr> filterShouldRead(Iterable<Expr> exprs) {
- List<Expr> result = new ArrayList<Expr>();
+ public static ArrayList<Expr> filterShouldRead(Iterable<Expr> exprs) {
+ ArrayList<Expr> result = new ArrayList<Expr>();
for (Expr expr : exprs) {
if (!expr.getShouldReadFlags().isEmpty() &&
!hasConditionalOrNestedCannotReadDependency(expr)) {
@@ -634,4 +687,35 @@ public class ExprModel {
ModelMethod listenerMethod) {
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;
+ }
+
+ public CallbackWrapper callbackWrapper(ModelClass klass, ModelMethod method) {
+ final String key = CallbackWrapper.uniqueKey(klass, method);
+ CallbackWrapper wrapper = mCallbackWrappers.get(key);
+ if (wrapper == null) {
+ wrapper = new CallbackWrapper(klass, method);
+ mCallbackWrappers.put(key, wrapper);
+ }
+ return wrapper;
+ }
+
+ public LambdaExpr lambdaExpr(Expr expr, CallbackExprModel callbackExprModel) {
+ return register(new LambdaExpr(expr, callbackExprModel));
+ }
+
+ public IdentifierExpr findIdentifier(String name) {
+ for (Expr expr : mExprMap.values()) {
+ if (expr instanceof IdentifierExpr && name.equals(((IdentifierExpr) expr).getName())) {
+ return (IdentifierExpr) expr;
+ }
+ }
+ return null;
+ }
}
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 ff55a003..d897f0a7 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/FieldAccessExpr.java
@@ -16,48 +16,37 @@
package android.databinding.tool.expr;
-import android.databinding.tool.ext.ExtKt;
import android.databinding.tool.Binding;
import android.databinding.tool.BindingTarget;
import android.databinding.tool.InverseBinding;
+import android.databinding.tool.ext.ExtKt;
+import android.databinding.tool.processing.ErrorMessages;
import android.databinding.tool.processing.Scope;
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.util.BrNameUtil;
import android.databinding.tool.store.SetterStore;
import android.databinding.tool.store.SetterStore.BindingGetterCall;
+import android.databinding.tool.util.BrNameUtil;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.KCode;
+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);
- mName = name;
- mIsObservableField = false;
- }
-
- FieldAccessExpr(Expr parent, String name, boolean isObservableField) {
- super(parent);
+ super(parent, name);
mName = name;
- mIsObservableField = isObservableField;
- }
-
- public Expr getChild() {
- return getChildren().get(0);
}
public Callable getGetter() {
@@ -69,7 +58,10 @@ public class FieldAccessExpr extends Expr {
@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 + "'";
}
@@ -81,7 +73,7 @@ public class FieldAccessExpr extends Expr {
}
public int getMinApi() {
- return mGetter.getMinApi();
+ return mGetter == null ? 0 : mGetter.getMinApi();
}
@Override
@@ -93,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();
}
@@ -107,111 +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);
- }
- 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);
- if (methods == null) {
+ 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;
}
- 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() {
@@ -228,32 +142,21 @@ 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);
if (mGetter == null) {
- mIsListener = resolvedType.findMethods(mName, isStatic) != null;
+ mIsListener = !resolvedType.findMethods(mName, isStatic).isEmpty();
if (!mIsListener) {
L.e("Could not find accessor %s.%s", resolvedType.getCanonicalName(), mName);
}
@@ -262,22 +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;
+ 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);
@@ -290,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;
}
@@ -365,22 +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) {
- 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(".");
+ 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()
+ .app("", getTarget().toCode()).app(".");
if (getGetter().type == Callable.Type.FIELD) {
return code.app(getGetter().name);
} else {
@@ -389,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>&commat;={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/GroupExpr.java b/compiler/src/main/java/android/databinding/tool/expr/GroupExpr.java
deleted file mode 100644
index 4a76688b..00000000
--- a/compiler/src/main/java/android/databinding/tool/expr/GroupExpr.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.databinding.tool.expr;
-
-import android.databinding.tool.reflection.ModelAnalyzer;
-import android.databinding.tool.reflection.ModelClass;
-import android.databinding.tool.writer.KCode;
-
-import java.util.List;
-
-public class GroupExpr extends Expr {
- public GroupExpr(Expr wrapped) {
- super(wrapped);
- }
-
- @Override
- protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
- return getWrapped().getResolvedType();
- }
-
- @Override
- protected List<Dependency> constructDependencies() {
- return getWrapped().constructDependencies();
- }
-
- @Override
- protected KCode generateCode(boolean expand) {
- return new KCode().app("(", getWrapped().toCode(expand)).app(")");
- }
-
- public Expr getWrapped() {
- return getChildren().get(0);
- }
-
- @Override
- public KCode toInverseCode(KCode value) {
- // Nothing to do here. Other expressions should automatically take care of grouping.
- return getWrapped().toInverseCode(value);
- }
-
- @Override
- public String getInvertibleError() {
- return getWrapped().getInvertibleError();
- }
-}
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 efe4fb15..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.getExecutePendingLocalName(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
new file mode 100644
index 00000000..13c6cb72
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/expr/LambdaExpr.java
@@ -0,0 +1,150 @@
+/*
+ * 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.CallbackWrapper;
+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.util.Preconditions;
+import android.databinding.tool.writer.KCode;
+import android.databinding.tool.writer.LayoutBinderWriterKt;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class LambdaExpr extends Expr {
+ private static AtomicInteger sIdCounter = new AtomicInteger();
+ private final int mId = sIdCounter.incrementAndGet();
+ private CallbackWrapper mCallbackWrapper;
+ // set when Binding resolves the receiver
+ private final CallbackExprModel mCallbackExprModel;
+ private int mCallbackId;
+ private ExecutionPath mExecutionPath;
+
+ public LambdaExpr(Expr expr, CallbackExprModel callbackExprModel) {
+ super(expr);
+ mCallbackExprModel = callbackExprModel;
+ }
+
+ public Expr getExpr() {
+ return getChildren().get(0);
+ }
+
+ public CallbackExprModel getCallbackExprModel() {
+ return mCallbackExprModel;
+ }
+
+ @Override
+ protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
+ Preconditions.checkNotNull(mCallbackWrapper, "Lambda expression must be resolved to its"
+ + " setter first to get the type.");
+ return mCallbackWrapper.klass;
+ }
+
+ @Override
+ protected List<Dependency> constructDependencies() {
+ return Collections.emptyList();
+ }
+
+ public CallbackWrapper getCallbackWrapper() {
+ return mCallbackWrapper;
+ }
+
+ @Override
+ public Expr resolveListeners(ModelClass valueType, Expr parent) {
+ return this;
+ }
+
+ @Override
+ protected String computeUniqueKey() {
+ return "callback" + mId;
+ }
+
+ @Override
+ public boolean isDynamic() {
+ return false;
+ }
+
+ @Override
+ protected KCode generateCode() {
+ Preconditions
+ .checkNotNull(mCallbackWrapper, "Cannot find the callback method for %s", this);
+ KCode code = new KCode("");
+ final int minApi = mCallbackWrapper.getMinApi();
+ final String fieldName = LayoutBinderWriterKt.getFieldName(this);
+ if (minApi > 1) {
+ code.app("(getBuildSdkInt() < " + minApi + " ? null : ").app(fieldName).app(")");
+ } else {
+ code.app(fieldName);
+ }
+ return code;
+ }
+
+ @Override
+ public Expr cloneToModel(ExprModel model) {
+ return model.lambdaExpr(getExpr().cloneToModel(model), (CallbackExprModel) model);
+ }
+
+ public String generateConstructor() {
+ return getCallbackWrapper().constructForIdentifier(mCallbackId);
+ }
+
+ @Override
+ public void markAsUsed() {
+ super.markAsUsed();
+ }
+
+ @Override
+ protected String getInvertibleError() {
+ return "Lambda expressions cannot be inverted";
+ }
+
+ @Override
+ public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) {
+ // i'm not involved.
+ throw new UnsupportedOperationException("should not call toExecutionPath on a lambda"
+ + " expression");
+ }
+
+ public final ExecutionPath getExecutionPath() {
+ return mExecutionPath;
+ }
+
+ public int getCallbackId() {
+ return mCallbackId;
+ }
+
+ public void setup(ModelClass klass, ModelMethod method, int callbackId) {
+ mCallbackId = callbackId;
+ mCallbackWrapper = getModel().callbackWrapper(klass, method);
+ // now register the arguments as variables.
+ final ModelClass[] parameterTypes = method.getParameterTypes();
+ final List<CallbackArgExpr> args = mCallbackExprModel.getArguments();
+ if (parameterTypes.length == args.size()) {
+ for (int i = 0; i < parameterTypes.length; i++) {
+ args.get(i).setClassFromCallback(parameterTypes[i]);
+ }
+ }
+ // first convert to execution path because we may add additional expressions
+ mExecutionPath = ExecutionPath.createRoot();
+ getExpr().toExecutionPath(mExecutionPath);
+ mCallbackExprModel.seal();
+ }
+}
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 a302659d..14b82c47 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,17 @@ 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 com.google.common.collect.Lists;
+
import java.util.List;
public class MathExpr extends Expr {
+ static final String DYNAMIC_UTIL = "android.databinding.DynamicUtil";
final String mOp;
+
MathExpr(Expr left, String op, Expr right) {
super(left, right);
mOp = op;
@@ -31,7 +36,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
@@ -52,10 +57,6 @@ public class MathExpr extends Expr {
return constructDynamicChildrenDependencies();
}
- public String getOp() {
- return mOp;
- }
-
public Expr getLeft() {
return getChildren().get(0);
}
@@ -65,81 +66,99 @@ 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
public String getInvertibleError() {
if (mOp.equals("%")) {
return "The modulus operator (%) is not supported in two-way binding.";
- } else if (getResolvedType().isString()) {
- return "String concatenation operator (+) is not supported in two-way binding.";
- }
- if (!getLeft().isDynamic()) {
- return getRight().getInvertibleError();
- } else if (!getRight().isDynamic()) {
- return getLeft().getInvertibleError();
- } else {
- return "Arithmetic operator " + mOp + " is not supported with two dynamic expressions.";
}
- }
- private String inverseCast() {
- if (!getLeft().isDynamic()) {
- return inverseCast(getRight());
- } else {
- return inverseCast(getLeft());
+ final Expr left = getLeft();
+ final Expr right = getRight();
+ if (left.isDynamic() == right.isDynamic()) {
+ return "Two way binding with operator " + mOp +
+ " supports only a single dynamic expressions.";
}
- }
+ Expr dyn = left.isDynamic() ? left : right;
+ if (getResolvedType().isString()) {
+ Expr constExpr = left.isDynamic() ? right : left;
- private String inverseCast(Expr expr) {
- if (!expr.getResolvedType().isAssignableFrom(getResolvedType())) {
- return "(" + getResolvedType() + ")";
+ if (!(constExpr instanceof SymbolExpr) ||
+ !"\"\"".equals(((SymbolExpr) constExpr).getText())) {
+ return "Two-way binding with string concatenation operator (+) only supports the" +
+ " empty string constant (`` or \"\")";
+ }
+ if (!dyn.getResolvedType().unbox().isPrimitive()) {
+ return "Two-way binding with string concatenation operator (+) only supports " +
+ "primitives";
+ }
}
- return null;
+ return dyn.getInvertibleError();
}
@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;
+ Preconditions.check(left.isDynamic() ^ right.isDynamic(), "Two-way binding of a math " +
+ "operations requires A single 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 varExpr = left.isDynamic() ? left : right;
- final String cast = inverseCast();
- if (cast != null) {
- value = new KCode(cast).app("(", value).app(")");
- }
+ final Expr newValue;
switch (mOp.charAt(0)) {
case '+': // const + x = value => x = value - const
- return varExpr.toInverseCode(value.app(" - (", constExpr.toCode()).app(")"));
+ if (getResolvedType().isString()) {
+ // just convert back to the primitive type
+ newValue = parseInverse(model, value, varExpr);
+ } else {
+ 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);
+ return varExpr.generateInverse(model, newValue, bindingClassName);
+ }
+
+ private Expr parseInverse(ExprModel model, Expr value, Expr prev) {
+ IdentifierExpr dynamicUtil = model.staticIdentifier(DYNAMIC_UTIL);
+ dynamicUtil.setUserDefinedType(DYNAMIC_UTIL);
+
+ return model.methodCall(dynamicUtil, "parse", Lists.newArrayList(value, prev));
+ }
+
+ @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 4990981d..6acbfa2e 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/MethodCallExpr.java
@@ -16,26 +16,29 @@
package android.databinding.tool.expr;
-import static android.databinding.tool.reflection.Callable.DYNAMIC;
-import static android.databinding.tool.reflection.Callable.STATIC;
-
import android.databinding.tool.processing.Scope;
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.util.L;
import android.databinding.tool.writer.KCode;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import static android.databinding.tool.reflection.Callable.DYNAMIC;
+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>();
@@ -49,6 +52,7 @@ public class MethodCallExpr extends Expr {
mName = name;
}
+ @SuppressWarnings("Duplicates")
@Override
public void updateExpr(ModelAnalyzer modelAnalyzer) {
try {
@@ -61,12 +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(".")
- .app(getGetter().name)
- .app("(");
+ .app("", getTarget().toCode())
+ .app(".")
+ .app(getGetter().name)
+ .app("(");
+ appendArgs(code);
+ code.app(")");
+ return code;
+ }
+
+ @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) {
@@ -74,10 +90,33 @@ public class MethodCallExpr extends Expr {
} else {
code.app(", ");
}
- code.app("", arg.toCode(expand));
+ code.app("", arg.toCode());
}
- code.app(")");
- return code;
+ }
+
+ @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, getArgs()));
+ } else {
+ for (ExecutionPath path : targetPaths) {
+ Expr cmp = getModel()
+ .comparison("!=", getTarget(), getModel().symbol("null", Object.class));
+ path.addPath(cmp);
+ final ExecutionPath subPath = path.addBranch(cmp, true);
+ if (subPath != null) {
+ result.addAll(toExecutionPathInOrder(subPath, getArgs()));
+ }
+ }
+ }
+ return result;
+ }
+
+ private List<ExecutionPath> toExecutionPathInOrder(ExecutionPath path, List<Expr> args) {
+ return toExecutionPathInOrder(Arrays.asList(path), args);
}
@Override
@@ -90,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;
}
@@ -115,7 +162,7 @@ public class MethodCallExpr extends Expr {
flags |= STATIC;
}
mGetter = new Callable(Type.METHOD, method.getName(), null, method.getReturnType(args),
- method.getParameterTypes().length, flags);
+ method.getParameterTypes().length, flags, method);
}
return mGetter.resolvedType;
}
@@ -153,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..df36cf63 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/ResourceExpr.java
@@ -15,9 +15,11 @@
*/
package android.databinding.tool.expr;
+import android.databinding.tool.BindingTarget;
import android.databinding.tool.reflection.ModelAnalyzer;
import android.databinding.tool.reflection.ModelClass;
import android.databinding.tool.writer.KCode;
+import android.databinding.tool.writer.LayoutBinderWriterKt;
import java.util.HashMap;
import java.util.List;
@@ -45,9 +47,12 @@ public class ResourceExpr extends Expr {
protected final String mResourceId;
- public ResourceExpr(String packageName, String resourceType, String resourceName,
- List<Expr> args) {
+ protected final BindingTarget mTarget;
+
+ public ResourceExpr(BindingTarget target, String packageName, String resourceType,
+ String resourceName, List<Expr> args) {
super(args);
+ mTarget = target;
if ("android".equals(packageName)) {
mPackage = "android.";
} else {
@@ -120,20 +125,26 @@ 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();
+ String view = "";
+ if (requiresView()) {
+ view = LayoutBinderWriterKt.getFieldName(mTarget);
}
- return join(base, computeChildrenKey());
+ return join(base, view, 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(mTarget, pkg, mResourceType, mResourceId,
+ cloneToModel(model, getChildren()));
+ }
+
public String getResourceId() {
return mPackage + "R." + getResourceObject() + "." + mResourceId;
}
@@ -144,19 +155,31 @@ public class ResourceExpr extends Expr {
computeUniqueKey();
}
+ private boolean requiresView() {
+ return !mTarget.isBinder() && !("anim".equals(mResourceType) ||
+ "animator".equals(mResourceType) ||
+ "id".equals(mResourceType) ||
+ "interpolator".equals(mResourceType) ||
+ "layout".equals(mResourceType) ||
+ "stateListAnimator".equals(mResourceType) ||
+ "transition".equals(mResourceType));
+ }
+
public String toJava() {
final String context = "getRoot().getContext()";
- final String resources = "getRoot().getResources()";
+ final String viewName = requiresView() ? LayoutBinderWriterKt.getFieldName(mTarget) :
+ "getRoot()";
+ final String resources = viewName + ".getResources()";
final String resourceName = mPackage + "R." + getResourceObject() + "." + mResourceId;
if ("anim".equals(mResourceType)) return "android.view.animation.AnimationUtils.loadAnimation(" + context + ", " + resourceName + ")";
if ("animator".equals(mResourceType)) return "android.animation.AnimatorInflater.loadAnimator(" + context + ", " + resourceName + ")";
if ("bool".equals(mResourceType)) return resources + ".getBoolean(" + resourceName + ")";
- if ("color".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorFromResource(getRoot(), " + resourceName + ")";
- if ("colorStateList".equals(mResourceType)) return "getColorStateListFromResource(" + resourceName + ")";
+ if ("color".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorFromResource(" + viewName + ", " + resourceName + ")";
+ if ("colorStateList".equals(mResourceType)) return "android.databinding.DynamicUtil.getColorStateListFromResource(" + viewName + ", " + resourceName + ")";
if ("dimen".equals(mResourceType)) return resources + ".getDimension(" + resourceName + ")";
if ("dimenOffset".equals(mResourceType)) return resources + ".getDimensionPixelOffset(" + resourceName + ")";
if ("dimenSize".equals(mResourceType)) return resources + ".getDimensionPixelSize(" + resourceName + ")";
- if ("drawable".equals(mResourceType)) return "getDrawableFromResource(" + resourceName + ")";
+ if ("drawable".equals(mResourceType)) return "android.databinding.DynamicUtil.getDrawableFromResource(" + viewName + ", " + resourceName + ")";
if ("fraction".equals(mResourceType)) {
String base = getChildCode(0, "1");
String pbase = getChildCode(1, "1");
@@ -172,11 +195,11 @@ public class ResourceExpr extends Expr {
if (getChildren().isEmpty()) {
return resourceName;
} else {
- return makeParameterCall(resourceName, "getQuantityString");
+ return makeParameterCall(resources, resourceName, "getQuantityString");
}
}
if ("stateListAnimator".equals(mResourceType)) return "android.animation.AnimatorInflater.loadStateListAnimator(" + context + ", " + resourceName + ")";
- if ("string".equals(mResourceType)) return makeParameterCall(resourceName, "getString");
+ if ("string".equals(mResourceType)) return makeParameterCall(resources, resourceName, "getString");
if ("stringArray".equals(mResourceType)) return resources + ".getStringArray(" + resourceName + ")";
if ("transition".equals(mResourceType)) return "android.transition.TransitionInflater.from(" + context + ").inflateTransition(" + resourceName + ")";
if ("typedArray".equals(mResourceType)) return resources + ".obtainTypedArray(" + resourceName + ")";
@@ -194,9 +217,9 @@ public class ResourceExpr extends Expr {
}
}
- private String makeParameterCall(String resourceName, String methodCall) {
- StringBuilder sb = new StringBuilder("getRoot().getResources().");
- sb.append(methodCall).append("(").append(resourceName);
+ private String makeParameterCall(String resources, String resourceName, String methodCall) {
+ StringBuilder sb = new StringBuilder(resources);
+ sb.append('.').append(methodCall).append("(").append(resourceName);
for (Expr expr : getChildren()) {
sb.append(", ").append(expr.toCode().generate());
}
@@ -211,4 +234,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 38708c04..388d2240 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/SymbolExpr.java
@@ -18,6 +18,7 @@ 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;
@@ -53,12 +54,35 @@ 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>();
}
+
+ @Override
+ public boolean canBeEvaluatedToAVariable() {
+ return !void.class.equals(mType);
+ }
+
+ @Override
+ public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) {
+ if (void.class.equals(mType)) {
+ return paths;
+ }
+ 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 d4a37274..856cab04 100644
--- a/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java
+++ b/compiler/src/main/java/android/databinding/tool/expr/TernaryExpr.java
@@ -18,6 +18,7 @@ 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;
@@ -25,6 +26,7 @@ import java.util.BitSet;
import java.util.List;
public class TernaryExpr extends Expr {
+
TernaryExpr(Expr pred, Expr ifTrue, Expr ifFalse) {
super(pred, ifTrue, ifFalse);
}
@@ -76,7 +78,7 @@ public class TernaryExpr extends Expr {
private static boolean isNullLiteral(Expr expr) {
final ModelClass type = expr.getResolvedType();
return (type.isObject() && (expr instanceof SymbolExpr) &&
- "null".equals(((SymbolExpr)expr).getText()));
+ "null".equals(((SymbolExpr) expr).getText()));
}
@Override
@@ -99,32 +101,58 @@ public class TernaryExpr extends Expr {
}
@Override
+ public List<ExecutionPath> toExecutionPath(List<ExecutionPath> paths) {
+ List<ExecutionPath> executionPaths = getPred().toExecutionPath(paths);
+ // now optionally add others
+ List<ExecutionPath> result = new ArrayList<ExecutionPath>();
+ for (ExecutionPath path : executionPaths) {
+ ExecutionPath ifTrue = path.addBranch(getPred(), true);
+ if (ifTrue != null) {
+ result.addAll(getIfTrue().toExecutionPath(ifTrue));
+ }
+ ExecutionPath ifFalse = path.addBranch(getPred(), false);
+ if (ifFalse != null) {
+ result.addAll(getIfFalse().toExecutionPath(ifFalse));
+ }
+ }
+ return addJustMeToExecutionPath(result);
+ }
+
+ @Override
protected BitSet getPredicateInvalidFlags() {
return getPred().getInvalidFlags();
}
@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 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 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 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/Callable.java b/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
index 5b9acf27..5088523d 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/Callable.java
@@ -15,8 +15,9 @@
*/
package android.databinding.tool.reflection;
-public class Callable {
+import org.jetbrains.annotations.Nullable;
+public class Callable {
public enum Type {
METHOD,
FIELD
@@ -34,18 +35,22 @@ public class Callable {
public final ModelClass resolvedType;
+ @Nullable
+ public final ModelMethod method;
+
private final int mFlags;
private final int mParameterCount;
public Callable(Type type, String name, String setterName, ModelClass resolvedType,
- int parameterCount, int flags) {
+ int parameterCount, int flags, ModelMethod method) {
this.type = type;
this.name = name;
this.resolvedType = resolvedType;
mParameterCount = parameterCount;
this.setterName = setterName;
mFlags = flags;
+ this.method = method;
}
public String getTypeCodeName() {
@@ -81,6 +86,7 @@ public class Callable {
", isDynamic=" + isDynamic() +
", canBeInvalidated=" + canBeInvalidated() +
", static=" + isStatic() +
+ ", method=" + method +
'}';
}
}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
new file mode 100644
index 00000000..45857991
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedClass.java
@@ -0,0 +1,218 @@
+/*
+ * 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.ArrayList;
+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 InjectedClass extends ModelClass {
+ private final String mClassName;
+ private final String mSuperClass;
+ private final List<InjectedMethod> mMethods = new ArrayList<InjectedMethod>();
+ private final List<InjectedField> mFields = new ArrayList<InjectedField>();
+
+ public InjectedClass(String className, String superClass) {
+ mClassName = className;
+ mSuperClass = superClass;
+ }
+
+ public void addField(InjectedField field) {
+ mFields.add(field);
+ }
+
+ public void addMethod(InjectedMethod method) {
+ mMethods.add(method);
+ }
+
+ @Override
+ public String toJavaCode() {
+ return mClassName;
+ }
+
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ @Override
+ public ModelClass getComponentType() {
+ return null;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return true;
+ }
+
+ @Override
+ public boolean isPrimitive() {
+ return false;
+ }
+
+ @Override
+ public boolean isBoolean() {
+ return false;
+ }
+
+ @Override
+ public boolean isChar() {
+ return false;
+ }
+
+ @Override
+ public boolean isByte() {
+ return false;
+ }
+
+ @Override
+ public boolean isShort() {
+ return false;
+ }
+
+ @Override
+ public boolean isInt() {
+ return false;
+ }
+
+ @Override
+ public boolean isLong() {
+ return false;
+ }
+
+ @Override
+ public boolean isFloat() {
+ return false;
+ }
+
+ @Override
+ public boolean isDouble() {
+ return false;
+ }
+
+ @Override
+ public boolean isGeneric() {
+ return false;
+ }
+
+ @Override
+ public List<ModelClass> getTypeArguments() {
+ return null;
+ }
+
+ @Override
+ public boolean isTypeVar() {
+ return false;
+ }
+
+ @Override
+ public boolean isWildcard() {
+ return false;
+ }
+
+ @Override
+ public boolean isInterface() {
+ return false;
+ }
+
+ @Override
+ public boolean isVoid() {
+ return false;
+ }
+
+ @Override
+ public ModelClass unbox() {
+ return this;
+ }
+
+ @Override
+ public ModelClass box() {
+ return this;
+ }
+
+ @Override
+ public boolean isObservable() {
+ return getSuperclass().isObservable();
+ }
+
+ @Override
+ public boolean isAssignableFrom(ModelClass that) {
+ ModelClass superClass = that;
+ while (superClass != null && !superClass.isObject()) {
+ if (superClass.toJavaCode().equals(mClassName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ModelClass getSuperclass() {
+ return ModelAnalyzer.getInstance().findClass(mSuperClass, null);
+ }
+
+ @Override
+ public ModelClass erasure() {
+ return this;
+ }
+
+ @Override
+ public String getJniDescription() {
+ return TypeUtil.getInstance().getDescription(this);
+ }
+
+ @Override
+ protected ModelField[] getDeclaredFields() {
+ ModelClass superClass = getSuperclass();
+ final ModelField[] superFields = superClass.getDeclaredFields();
+ final int initialCount = superFields.length;
+ final int fieldCount = initialCount + mFields.size();
+ final ModelField[] fields = Arrays.copyOf(superFields, fieldCount);
+ for (int i = 0; i < mFields.size(); i++) {
+ fields[i + initialCount] = mFields.get(i);
+ }
+ return fields;
+ }
+
+ @Override
+ protected ModelMethod[] getDeclaredMethods() {
+ ModelClass superClass = getSuperclass();
+ final ModelMethod[] superMethods = superClass.getDeclaredMethods();
+ final int initialCount = superMethods.length;
+ final int methodCount = initialCount + mMethods.size();
+ final ModelMethod[] methods = Arrays.copyOf(superMethods, methodCount);
+ for (int i = 0; i < mMethods.size(); i++) {
+ methods[i + initialCount] = mMethods.get(i);
+ }
+ return methods;
+ }
+
+ @Override
+ public String toString() {
+ return "Injected Class: " + mClassName;
+ }
+}
diff --git a/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.java
new file mode 100644
index 00000000..85719f1c
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedField.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 InjectedField extends ModelField {
+ private final String mType;
+ private final String mName;
+
+ public InjectedField(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/InjectedMethod.java b/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java
new file mode 100644
index 00000000..f47442b7
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/reflection/InjectedMethod.java
@@ -0,0 +1,146 @@
+/*
+ * 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 InjectedMethod extends ModelMethod {
+ private final InjectedClass mContainingClass;
+ private final String mName;
+ private final String mReturnTypeName;
+ private final String[] mParameterTypeNames;
+ private ModelClass[] mParameterTypes;
+ private ModelClass mReturnType;
+ private boolean mIsStatic;
+
+ public InjectedMethod(InjectedClass containingClass, boolean isStatic, String name,
+ String returnType, String... parameters) {
+ mContainingClass = containingClass;
+ mName = name;
+ mIsStatic = isStatic;
+ mReturnTypeName = returnType;
+ mParameterTypeNames = parameters;
+ }
+
+ @Override
+ public ModelClass getDeclaringClass() {
+ return mContainingClass;
+ }
+
+ @Override
+ public ModelClass[] getParameterTypes() {
+ if (mParameterTypes == null) {
+ if (mParameterTypeNames == null) {
+ mParameterTypes = new ModelClass[0];
+ } else {
+ mParameterTypes = new ModelClass[mParameterTypeNames.length];
+ ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
+ for (int i = 0; i < mParameterTypeNames.length; i++) {
+ mParameterTypes[i] = modelAnalyzer.findClass(mParameterTypeNames[i], null);
+ }
+ }
+ }
+ return mParameterTypes;
+ }
+
+ @Override
+ public String getName() {
+ return mName;
+ }
+
+ @Override
+ public ModelClass getReturnType(List<ModelClass> args) {
+ if (mReturnType == null) {
+ mReturnType = ModelAnalyzer.getInstance().findClass(mReturnTypeName, null);
+ }
+ return mReturnType;
+ }
+
+ @Override
+ public boolean isVoid() {
+ return getReturnType().isVoid();
+ }
+
+ @Override
+ public boolean isPublic() {
+ return true;
+ }
+
+ @Override
+ public boolean isProtected() {
+ return false;
+ }
+
+ @Override
+ public boolean isStatic() {
+ return mIsStatic;
+ }
+
+ @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;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("public ");
+ if (mIsStatic) {
+ sb.append("static ");
+ }
+ sb.append(mReturnTypeName)
+ .append(' ')
+ .append(mName)
+ .append("(");
+ if (mParameterTypeNames != null) {
+ for (int i = 0; i < mParameterTypeNames.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(mParameterTypeNames[i]);
+ }
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+}
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 b1de46e4..995ae219 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelAnalyzer.java
@@ -18,7 +18,9 @@ package android.databinding.tool.reflection;
import android.databinding.tool.reflection.annotation.AnnotationAnalyzer;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
+import android.databinding.tool.util.StringUtils;
+import java.util.HashMap;
import java.util.Map;
import javax.annotation.processing.ProcessingEnvironment;
@@ -82,13 +84,19 @@ public abstract class ModelAnalyzer {
private ModelClass mViewStubType;
private static ModelAnalyzer sAnalyzer;
+ private final Map<String, InjectedClass> mInjectedClasses =
+ new HashMap<String, InjectedClass>();
protected void setInstance(ModelAnalyzer analyzer) {
sAnalyzer = analyzer;
}
- public ModelClass findCommonParentOf(ModelClass modelClass1,
- ModelClass modelClass2) {
+ public ModelClass findCommonParentOf(ModelClass modelClass1, ModelClass modelClass2) {
+ return findCommonParentOf(modelClass1, modelClass2, true);
+ }
+
+ public ModelClass findCommonParentOf(ModelClass modelClass1, ModelClass modelClass2,
+ boolean failOnError) {
ModelClass curr = modelClass1;
while (curr != null && !curr.isAssignableFrom(modelClass2)) {
curr = curr.getSuperclass();
@@ -103,13 +111,15 @@ public abstract class ModelAnalyzer {
ModelClass primitive1 = modelClass1.unbox();
ModelClass primitive2 = modelClass2.unbox();
if (!modelClass1.equals(primitive1) || !modelClass2.equals(primitive2)) {
- return findCommonParentOf(primitive1, primitive2);
+ return findCommonParentOf(primitive1, primitive2, failOnError);
}
}
- Preconditions.checkNotNull(curr,
- "must be able to find a common parent for " + modelClass1 + " and " + modelClass2);
+ if (failOnError) {
+ Preconditions.checkNotNull(curr,
+ "must be able to find a common parent for " + modelClass1 + " and "
+ + modelClass2);
+ }
return curr;
-
}
public abstract ModelClass loadPrimitive(String className);
@@ -124,8 +134,7 @@ public abstract class ModelAnalyzer {
+ "change class loader after that");
}
L.d("setting processing env to %s", processingEnvironment);
- AnnotationAnalyzer annotationAnalyzer = new AnnotationAnalyzer(processingEnvironment);
- sAnalyzer = annotationAnalyzer;
+ sAnalyzer = new AnnotationAnalyzer(processingEnvironment);
}
/**
@@ -213,12 +222,50 @@ 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 injectClass(InjectedClass injectedClass) {
+ mInjectedClasses.put(injectedClass.getCanonicalName(), injectedClass);
+ return injectedClass;
+ }
+
+ public ModelClass injectViewDataBinding(String className, Map<String, String> variables,
+ Map<String, String> fields) {
+ InjectedClass injectedClass = new InjectedClass(className,
+ ModelAnalyzer.VIEW_DATA_BINDING);
+
+ if (fields != null) {
+ for (String name : fields.keySet()) {
+ String type = fields.get(name);
+ injectedClass.addField(new InjectedField(name, type));
+ }
+ }
+ if (variables != null) {
+ for (String name : variables.keySet()) {
+ String type = variables.get(name);
+ String capName = StringUtils.capitalize(name);
+ String setName = "set" + capName;
+ String getName = "get" + capName;
+ injectedClass.addMethod(new InjectedMethod(injectedClass, false, getName, type));
+ injectedClass.addMethod(new InjectedMethod(injectedClass, false, setName, "void",
+ type));
+ }
+ }
+ 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 6fbc5a0f..243fcdee 100644
--- a/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
+++ b/compiler/src/main/java/android/databinding/tool/reflection/ModelClass.java
@@ -19,6 +19,8 @@ import android.databinding.tool.reflection.Callable.Type;
import android.databinding.tool.util.L;
import android.databinding.tool.util.StringUtils;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -233,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);
}
@@ -286,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) {
@@ -363,6 +371,7 @@ public abstract class ModelClass {
/**
* Returns a list of all abstract methods in the type.
*/
+ @NotNull
public List<ModelMethod> getAbstractMethods() {
ArrayList<ModelMethod> abstractMethods = new ArrayList<ModelMethod>();
ModelMethod[] methods = getDeclaredMethods();
@@ -385,7 +394,7 @@ public abstract class ModelClass {
public Callable findGetterOrField(String name, boolean staticOnly) {
if ("length".equals(name) && isArray()) {
return new Callable(Type.FIELD, name, null,
- ModelAnalyzer.getInstance().loadPrimitive("int"), 0, 0);
+ ModelAnalyzer.getInstance().loadPrimitive("int"), 0, 0, null);
}
String capitalized = StringUtils.capitalize(name);
String[] methodNames = {
@@ -394,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()) {
@@ -417,7 +427,7 @@ public abstract class ModelClass {
final String setterName = setterMethod == null ? null : setterMethod.getName();
final Callable result = new Callable(Callable.Type.METHOD, methodName,
setterName, method.getReturnType(null), method.getParameterTypes().length,
- flags);
+ flags, method);
return result;
}
}
@@ -451,7 +461,7 @@ public abstract class ModelClass {
if (publicField.isBindable()) {
flags |= CAN_BE_INVALIDATED;
}
- return new Callable(Callable.Type.FIELD, name, setterFieldName, fieldType, 0, flags);
+ return new Callable(Callable.Type.FIELD, name, setterFieldName, fieldType, 0, flags, null);
}
public ModelMethod findInstanceGetter(String name) {
@@ -462,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()) {
@@ -498,15 +509,13 @@ public abstract class ModelClass {
}
for (String name : possibleNames) {
List<ModelMethod> methods = findMethods(name, getter.isStatic());
- if (methods != null) {
- ModelClass param = getter.getReturnType(null);
- for (ModelMethod method : methods) {
- ModelClass[] parameterTypes = method.getParameterTypes();
- if (parameterTypes != null && parameterTypes.length == 1 &&
- parameterTypes[0].equals(param) &&
- method.isStatic() == getter.isStatic()) {
- return method;
- }
+ ModelClass param = getter.getReturnType(null);
+ for (ModelMethod method : methods) {
+ ModelClass[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes != null && parameterTypes.length == 1 &&
+ parameterTypes[0].equals(param) &&
+ method.isStatic() == getter.isStatic()) {
+ return method;
}
}
}
@@ -517,6 +526,7 @@ public abstract class ModelClass {
* Finds public methods that matches the given name exactly. These may be resolved into
* listener methods during Expr.resolveListeners.
*/
+ @NotNull
public List<ModelMethod> findMethods(String name, boolean staticOnly) {
ModelMethod[] methods = getDeclaredMethods();
ArrayList<ModelMethod> matching = new ArrayList<ModelMethod>();
@@ -526,9 +536,6 @@ public abstract class ModelClass {
matching.add(method);
}
}
- if (matching.isEmpty()) {
- return null;
- }
return matching;
}
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 99657153..3ec7ff8d 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;
@@ -91,6 +96,9 @@ public abstract class ModelMethod {
final ModelClass arg = args.get(i);
final ModelClass thisParameter = getParameter(i, parameterTypes);
final ModelClass thatParameter = other.getParameter(i, otherParameterTypes);
+ if (thisParameter.equals(thatParameter)) {
+ continue;
+ }
final int diff = compareParameter(arg, thisParameter, thatParameter);
if (diff != 0) {
return diff < 0;
@@ -99,6 +107,10 @@ public abstract class ModelMethod {
return false;
}
+ public ModelClass getReturnType() {
+ return getReturnType(null);
+ }
+
private ModelClass getParameter(int index, ModelClass[] parameterTypes) {
int normalParamCount = isVarArgs() ? parameterTypes.length - 1 : parameterTypes.length;
if (index < normalParamCount) {
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 4773f17d..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("[]")) {
@@ -96,6 +95,9 @@ public class AnnotationAnalyzer extends ModelAnalyzer {
if (primitive != null) {
return addDimension(primitive.mTypeMirror, numDimensions);
}
+ if ("void".equals(className.toLowerCase())) {
+ return addDimension(getTypeUtils().getNoType(TypeKind.VOID), numDimensions);
+ }
int templateOpenIndex = className.indexOf('<');
DeclaredType declaredType;
if (templateOpenIndex < 0) {
@@ -118,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 02e767ee..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,10 +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;
}
- AnnotationClass thatAnnotationClass = (AnnotationClass) that;
+ if (equals(other)) {
+ return true;
+ }
+ AnnotationClass thatAnnotationClass = (AnnotationClass) other;
return getTypeUtils().isAssignable(thatAnnotationClass.mTypeMirror, this.mTypeMirror);
}
@@ -364,6 +371,19 @@ class AnnotationClass extends ModelClass {
return declaredFields;
}
+ private static Types getTypeUtils() {
+ return AnnotationAnalyzer.get().mProcessingEnv.getTypeUtils();
+ }
+
+ private static Elements getElementUtils() {
+ return AnnotationAnalyzer.get().mProcessingEnv.getElementUtils();
+ }
+
+ @Override
+ public String toString() {
+ return mTypeMirror.toString();
+ }
+
@Override
public boolean equals(Object obj) {
if (obj instanceof AnnotationClass) {
@@ -377,17 +397,4 @@ class AnnotationClass extends ModelClass {
public int hashCode() {
return mTypeMirror.toString().hashCode();
}
-
- private static Types getTypeUtils() {
- return AnnotationAnalyzer.get().mProcessingEnv.getTypeUtils();
- }
-
- private static Elements getElementUtils() {
- return AnnotationAnalyzer.get().mProcessingEnv.getElementUtils();
- }
-
- @Override
- public String toString() {
- return mTypeMirror.toString();
- }
}
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/solver/ExecutionBranch.java b/compiler/src/main/java/android/databinding/tool/solver/ExecutionBranch.java
new file mode 100644
index 00000000..bd931911
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/solver/ExecutionBranch.java
@@ -0,0 +1,55 @@
+/*
+ * 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.solver;
+
+import android.databinding.tool.expr.Expr;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents if statements in the execution.
+ */
+public class ExecutionBranch {
+
+ @NotNull
+ private Expr mConditional;
+
+ private final boolean mExpectedCondition;
+
+ @NotNull
+ private final ExecutionPath mPath;
+
+ public ExecutionBranch(@NotNull ExecutionPath path, @NotNull Expr conditional,
+ boolean expectedCondition) {
+ mConditional = conditional;
+ mExpectedCondition = expectedCondition;
+ mPath = path;
+ }
+
+ @NotNull
+ public Expr getConditional() {
+ return mConditional;
+ }
+
+ public boolean getExpectedCondition() {
+ return mExpectedCondition;
+ }
+
+ @NotNull
+ public ExecutionPath getPath() {
+ return mPath;
+ }
+}
diff --git a/compiler/src/main/java/android/databinding/tool/solver/ExecutionPath.java b/compiler/src/main/java/android/databinding/tool/solver/ExecutionPath.java
new file mode 100644
index 00000000..411ce4fe
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/solver/ExecutionPath.java
@@ -0,0 +1,191 @@
+/*
+ * 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.solver;
+
+import android.databinding.tool.expr.Expr;
+import android.databinding.tool.util.Preconditions;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents all possible outcomes of an expressions with its branching.
+ */
+public class ExecutionPath {
+ @Nullable //null for root and branches
+ private final Expr mExpr;
+ @NotNull
+ private List<ExecutionPath> mChildren = new ArrayList<ExecutionPath>();
+
+ @Nullable
+ private ExecutionBranch mTrueBranch;
+
+ @Nullable
+ private ExecutionBranch mFalseBranch;
+
+ // values that we know due to branching
+ private Map<Expr, Boolean> mKnownValues = new HashMap<Expr, Boolean>();
+
+ // expressions that are available right now
+ private Set<Expr> mScopeExpressions = new HashSet<Expr>();
+
+ private final boolean mIsAlreadyEvaluated;
+
+ public static ExecutionPath createRoot() {
+ return new ExecutionPath(null, false);
+ }
+
+ private ExecutionPath(@Nullable Expr expr, boolean isAlreadyEvaluated) {
+ mExpr = expr;
+ mIsAlreadyEvaluated = isAlreadyEvaluated;
+ }
+
+ @Nullable
+ public ExecutionPath addBranch(Expr pred, boolean expectedValue) {
+ // TODO special predicates like Symbol(true, false)
+ Preconditions.checkNull(expectedValue ? mTrueBranch : mFalseBranch,
+ "Cannot add two " + expectedValue + "branches");
+ final Boolean knownValue = mKnownValues.get(pred);
+ if (knownValue != null) {
+ // we know the result. cut the branch
+ if (expectedValue == knownValue) {
+ // just add as a path
+ return addPath(null);
+ } else {
+ // drop path. this cannot happen
+ return null;
+ }
+ } else {
+ ExecutionPath path = createPath(null);
+ ExecutionBranch edge = new ExecutionBranch(path, pred, expectedValue);
+ path.mKnownValues.put(pred, expectedValue);
+ if (expectedValue) {
+ if (mFalseBranch != null) {
+ Preconditions.check(mFalseBranch.getConditional() == pred, "Cannot add"
+ + " branches w/ different conditionals.");
+ }
+ mTrueBranch = edge;
+ } else {
+ if (mTrueBranch != null) {
+ Preconditions.check(mTrueBranch.getConditional() == pred, "Cannot add"
+ + " branches w/ different conditionals.");
+ }
+ mFalseBranch = edge;
+ }
+ return path;
+ }
+ }
+
+ private ExecutionPath createPath(@Nullable Expr expr) {
+ ExecutionPath path = new ExecutionPath(expr, expr == null ||
+ mScopeExpressions.contains(expr));
+ // now pass down all values etc
+ path.mKnownValues.putAll(mKnownValues);
+ path.mScopeExpressions.addAll(mScopeExpressions);
+ return path;
+ }
+
+ @NotNull
+ public ExecutionPath addPath(@Nullable Expr expr) {
+ Preconditions.checkNull(mFalseBranch, "Cannot add path after branches are set");
+ Preconditions.checkNull(mTrueBranch, "Cannot add path after branches are set");
+ final ExecutionPath path = createPath(expr);
+ if (expr != null) {
+ mScopeExpressions.add(expr);
+ path.mScopeExpressions.add(expr);
+ }
+ mChildren.add(path);
+ return path;
+ }
+
+ public void debug(StringBuilder builder, int offset) {
+ offset(builder, offset);
+ if (mExpr != null || !mIsAlreadyEvaluated) {
+ builder.append("expr:").append(mExpr == null ? "root" : mExpr.getUniqueKey());
+ builder.append(" isRead:").append(mIsAlreadyEvaluated);
+ } else {
+ builder.append("branch");
+ }
+ if (!mKnownValues.isEmpty()) {
+ builder.append(" I know:");
+ for (Map.Entry<Expr, Boolean> entry : mKnownValues.entrySet()) {
+ builder.append(" ");
+ builder.append(entry.getKey().getUniqueKey());
+ builder.append(" is ").append(entry.getValue());
+ }
+ }
+ for (ExecutionPath path : mChildren) {
+ builder.append("\n");
+ path.debug(builder, offset);
+ }
+ if (mTrueBranch != null) {
+ debug(builder, mTrueBranch, offset);
+ }
+ if (mFalseBranch != null) {
+ debug(builder, mFalseBranch, offset);
+ }
+ }
+
+ @Nullable
+ public Expr getExpr() {
+ return mExpr;
+ }
+
+ @NotNull
+ public List<ExecutionPath> getChildren() {
+ return mChildren;
+ }
+
+ @Nullable
+ public ExecutionBranch getTrueBranch() {
+ return mTrueBranch;
+ }
+
+ @Nullable
+ public ExecutionBranch getFalseBranch() {
+ return mFalseBranch;
+ }
+
+ public boolean isAlreadyEvaluated() {
+ return mIsAlreadyEvaluated;
+ }
+
+ private void debug(StringBuilder builder, ExecutionBranch branch, int offset) {
+ builder.append("\n");
+ offset(builder, offset);
+ builder.append("if ")
+ .append(branch.getConditional().getUniqueKey())
+ .append(" is ").append(branch.getExpectedCondition()).append("\n");
+ branch.getPath().debug(builder, offset + 1);
+ }
+
+ private void offset(StringBuilder builder, int offset) {
+ for (int i = 0; i < offset; i++) {
+ builder.append(" ");
+ }
+ }
+
+ public Map<Expr, Boolean> getKnownValues() {
+ return mKnownValues;
+ }
+}
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/java/android/databinding/tool/writer/CallbackWrapperWriter.kt b/compiler/src/main/java/android/databinding/tool/writer/CallbackWrapperWriter.kt
new file mode 100644
index 00000000..a55108d3
--- /dev/null
+++ b/compiler/src/main/java/android/databinding/tool/writer/CallbackWrapperWriter.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.writer
+
+import android.databinding.tool.CallbackWrapper
+
+fun CallbackWrapper.allArgsWithTypes() =
+ "int ${CallbackWrapper.SOURCE_ID} ${method.parameterTypes.withIndex().map { ", ${it.value.toJavaCode()} ${CallbackWrapper.ARG_PREFIX}${it.index}" }.joinToString("")}"
+
+fun CallbackWrapper.argsWithTypes() =
+ method.parameterTypes.withIndex().map { "${it.value.toJavaCode()} ${CallbackWrapper.ARG_PREFIX}${it.index}" }.joinToString(", ")
+
+fun CallbackWrapper.args() =
+ method.parameterTypes.withIndex().map { "${CallbackWrapper.ARG_PREFIX}${it.index}" }.joinToString(", ")
+
+fun CallbackWrapper.allArgs() =
+ "mSourceId ${method.parameterTypes.withIndex().map { ", ${CallbackWrapper.ARG_PREFIX}${it.index}" }.joinToString("")}"
+
+/**
+ * For any listener type we see, we create a class that can wrap around it. This wrapper has an
+ * interface which is implemented by the ViewDataBinding.
+ */
+public class CallbackWrapperWriter(val wrapper: CallbackWrapper) {
+
+ public fun write() = kcode("") {
+ with(wrapper) {
+ @Suppress("RemoveCurlyBracesFromTemplate")
+ app("package ${`package`};")
+ val extendsImplements = if (klass.isInterface) {
+ "implements"
+ } else {
+ "extends"
+ }
+ block("public final class $className $extendsImplements ${klass.canonicalName}") {
+ // declare the actual listener interface
+ nl("final $listenerInterfaceName mListener;")
+ nl("final int mSourceId;")
+ block("public $className($listenerInterfaceName listener, int sourceId)") {
+ nl("mListener = listener;")
+ nl("mSourceId = sourceId;")
+ }
+ nl("")
+ nl("@Override")
+ block("public ${method.returnType.canonicalName} ${method.name}(${wrapper.argsWithTypes()})") {
+ val evaluate = "mListener.$listenerMethodName(${wrapper.allArgs()});"
+ if (method.returnType.isVoid) {
+ nl("$evaluate")
+ } else {
+ nl("return $evaluate")
+ }
+ }
+ nl("")
+ block("public interface $listenerInterfaceName") {
+ nl("${method.returnType} $listenerMethodName(${wrapper.allArgsWithTypes()});")
+ }
+ }
+ }
+ }.generate()
+} \ No newline at end of file
diff --git a/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt b/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt
new file mode 100644
index 00000000..84884516
--- /dev/null
+++ b/compiler/src/main/kotlin/android/databinding/tool/expr/ExprWriters.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.Callable
+import android.databinding.tool.solver.ExecutionPath
+import android.databinding.tool.writer.KCode
+import android.databinding.tool.writer.fieldName
+import android.databinding.tool.writer.isForcedToLocalize
+import android.databinding.tool.writer.isVariable
+import android.databinding.tool.writer.kcode
+import android.databinding.tool.writer.scopedName
+
+fun Expr.shouldLocalizeInCallbacks() = canBeEvaluatedToAVariable() && !resolvedType.isVoid && (isDynamic || isForcedToLocalize())
+
+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.toString()}")
+ nl("${it.resolvedType.toJavaCode()} ${it.scopedName()} = ${if (it.isVariable()) it.fieldName else it.defaultValue};")
+ }
+}
+
+fun ExecutionPath.toCode(): KCode = kcode("") {
+ val myExpr = expr
+ if (myExpr != null && !isAlreadyEvaluated) {
+ // variables are read up top
+ val localize = myExpr.shouldLocalizeInCallbacks() && !myExpr.isVariable()
+ // if this is not a method call (or method call via field access, don't do anything
+ val eligible = localize || (myExpr is MethodCallExpr || (myExpr is FieldAccessExpr && myExpr.getter.type == Callable.Type.METHOD))
+ if (eligible) {
+ val assign = if (localize) {
+ "${myExpr.scopedName()} = "
+ } else {
+ ""
+ }
+ if (myExpr is TernaryExpr) {
+ // if i know the value, short circuit it
+ if (knownValues.containsKey(myExpr.pred)) {
+ val chosen = if (knownValues[myExpr.pred]!!) myExpr.ifTrue else myExpr.ifFalse
+ // fast read me
+ nl("$assign${chosen.toCode().generate()};")
+ } else {
+ // read me
+ nl("$assign${myExpr.toFullCode().generate()};")
+ }
+ } else {
+ // read me
+ nl("$assign${myExpr.toFullCode().generate()};")
+ }
+ }
+ }
+ children.forEach {
+ nl(it.toCode())
+ }
+ // if i have branches, execute them
+ val myTrue = trueBranch
+ val myFalse = falseBranch
+ if (myTrue != null) {
+ val condition = with(myTrue.conditional) {
+ if (shouldLocalizeInCallbacks()) {
+ scopedName()
+ } else {
+ toFullCode().generate()
+ }
+ }
+ block("if ($condition)") {
+ nl(myTrue.path.toCode())
+ }
+ if (myFalse != null) {
+ block("else") {
+ nl(myFalse.path.toCode())
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/BRWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/BRWriter.kt
index 261025d4..a11804ff 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/BRWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/BRWriter.kt
@@ -24,12 +24,12 @@ class BRWriter(properties: Set<String>, val useFinal : Boolean) {
val klass: String by lazy {
kcode("") {
val prefix = if (useFinal) "final " else "";
- nl("public class BR {") {
+ block("public class BR") {
tab("public static ${prefix}int _all = 0;")
indexedProps.forEach {
tab ("public static ${prefix}int ${it.value} = ${it.index + 1};")
}
- } nl ("}")
+ }
}.generate()
}
}
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/DataBinderWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/DataBinderWriter.kt
index da953e46..9bd06a00 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/DataBinderWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/DataBinderWriter.kt
@@ -20,15 +20,14 @@ class DataBinderWriter(val pkg: String, val projectPackage: String, val classNam
fun write(brWriter : BRWriter) = kcode("") {
nl("package $pkg;")
nl("import $projectPackage.BR;")
- nl("class $className {") {
- tab("final static int TARGET_MIN_SDK = $minSdk;")
+ block("class $className") {
+ nl("final static int TARGET_MIN_SDK = $minSdk;")
nl("")
- tab("public $className() {") {
+ block("public $className()") {
}
- tab("}")
nl("")
- tab("public android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View view, int layoutId) {") {
- tab("switch(layoutId) {") {
+ block("public android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View view, int layoutId)") {
+ block("switch(layoutId)") {
layoutBinders.groupBy{it.layoutname }.forEach {
val firstVal = it.value[0]
tab("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
@@ -40,98 +39,87 @@ class DataBinderWriter(val pkg: String, val projectPackage: String, val classNam
}
} else {
// we should check the tag to decide which layout we need to inflate
- tab("{") {
+ block("") {
tab("final Object tag = view.getTag();")
tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
it.value.forEach {
- tab("if (\"${it.tag}_0\".equals(tag)) {") {
+ block("if (\"${it.tag}_0\".equals(tag))") {
if (it.isMerge) {
tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, new android.view.View[]{view});")
} else {
tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, view);")
}
- } tab("}")
+ }
}
tab("throw new java.lang.IllegalArgumentException(\"The tag for ${firstVal.layoutname} is invalid. Received: \" + tag);");
- }tab("}")
+ }
}
}
}
}
- tab("}")
- tab("return null;")
+ nl("return null;")
}
- tab("}")
-
- tab("android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View[] views, int layoutId) {") {
- tab("switch(layoutId) {") {
+ block("android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View[] views, int layoutId)") {
+ block("switch(layoutId)") {
layoutBinders.filter{it.isMerge }.groupBy{it.layoutname }.forEach {
val firstVal = it.value[0]
- tab("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
+ block("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
if (it.value.size == 1) {
tab("return new ${firstVal.`package`}.${firstVal.implementationName}(bindingComponent, views);")
} else {
// we should check the tag to decide which layout we need to inflate
- tab("{") {
- tab("final Object tag = views[0].getTag();")
- tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
- it.value.forEach {
- tab("if (\"${it.tag}_0\".equals(tag)) {") {
- tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, views);")
- } tab("}")
+ nl("final Object tag = views[0].getTag();")
+ nl("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
+ it.value.forEach {
+ block("if (\"${it.tag}_0\".equals(tag))") {
+ nl("return new ${it.`package`}.${it.implementationName}(bindingComponent, views);")
}
- }tab("}")
+ }
}
}
}
}
- tab("}")
- tab("return null;")
+ nl("return null;")
}
- tab("}")
- tab("int getLayoutId(String tag) {") {
- tab("if (tag == null) {") {
- tab("return 0;");
+ block("int getLayoutId(String tag)") {
+ block("if (tag == null)") {
+ nl("return 0;");
}
- tab("}")
// String.hashCode is well defined in the API so we can rely on it being the same on the device and the host machine
- tab("final int code = tag.hashCode();");
- tab("switch(code) {") {
+ nl("final int code = tag.hashCode();");
+ block("switch(code)") {
layoutBinders.groupBy {"${it.tag}_0".hashCode()}.forEach {
- tab("case ${it.key}:") {
+ block("case ${it.key}:") {
it.value.forEach {
- tab("if(tag.equals(\"${it.tag}_0\"))") {
- tab("return ${it.modulePackage}.R.layout.${it.layoutname};")
+ block("if(tag.equals(\"${it.tag}_0\"))") {
+ nl("return ${it.modulePackage}.R.layout.${it.layoutname};")
}
}
- tab("break;")
+ nl("break;")
}
}
}
- tab("}")
- tab("return 0;")
+ nl("return 0;")
}
- tab("}")
- tab("String convertBrIdToString(int id) {") {
- tab("if (id < 0 || id >= InnerBrLookup.sKeys.length) {") {
- tab("return null;")
- } tab("}")
- tab("return InnerBrLookup.sKeys[id];")
- } tab("}")
+ block("String convertBrIdToString(int id)") {
+ block("if (id < 0 || id >= InnerBrLookup.sKeys.length)") {
+ nl("return null;")
+ }
+ nl("return InnerBrLookup.sKeys[id];")
+ }
- tab("private static class InnerBrLookup {") {
- tab("static String[] sKeys = new String[]{") {
+ block("private static class InnerBrLookup") {
+ nl("static String[] sKeys = new String[]{") {
tab("\"_all\"")
brWriter.indexedProps.forEach {
tab(",\"${it.value}\"")
}
}.app("};")
- } tab("}")
+ }
}
- nl("}")
}.generate()
} \ No newline at end of file
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
index 34ac043c..e7314606 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/DynamicUtilWriter.kt
@@ -6,18 +6,97 @@ class DynamicUtilWriter() {
nl("import android.os.Build.VERSION;")
nl("import android.os.Build.VERSION_CODES;")
nl("")
- nl("public class DynamicUtil {")
- tab("@SuppressWarnings(\"deprecation\")")
- tab("public static int getColorFromResource(final android.view.View root, final int resourceId) {") {
- if (targetSdk >= 23) {
- tab("if (VERSION.SDK_INT >= VERSION_CODES.M) {") {
- tab("return root.getContext().getColor(resourceId);")
+ block("public class DynamicUtil") {
+ nl("@SuppressWarnings(\"deprecation\")")
+ block("public static int getColorFromResource(final android.view.View view, final int resourceId)") {
+ if (targetSdk >= 23) {
+ block("if (VERSION.SDK_INT >= VERSION_CODES.M)") {
+ nl("return view.getContext().getColor(resourceId);")
+ }
}
- tab("}")
+ nl("return view.getResources().getColor(resourceId);")
+ }
+
+ nl("@SuppressWarnings(\"deprecation\")")
+ block("public static android.content.res.ColorStateList getColorStateListFromResource(final android.view.View view, final int resourceId)") {
+ if (targetSdk >= 23) {
+ block("if (VERSION.SDK_INT >= VERSION_CODES.M)") {
+ nl("return view.getContext().getColorStateList(resourceId);")
+ }
+ }
+ nl("return view.getResources().getColorStateList(resourceId);")
+ }
+
+ nl("@SuppressWarnings(\"deprecation\")")
+ block("public static android.graphics.drawable.Drawable getDrawableFromResource(final android.view.View view, final int resourceId)") {
+ if (targetSdk >= 21) {
+ block("if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP)") {
+ nl("return view.getContext().getDrawable(resourceId);")
+ }
+ }
+ nl("return view.getResources().getDrawable(resourceId);")
+ }
+
+ block("public static boolean parse(String str, boolean fallback)") {
+ block("if (str == null)") {
+ nl("return fallback;");
+ }
+ nl("return Boolean.parseBoolean(str);")
+ }
+ block("public static byte parse(String str, byte fallback)") {
+ block("try") {
+ nl("return Byte.parseByte(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static short parse(String str, short fallback)") {
+ block("try") {
+ nl("return Short.parseShort(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static int parse(String str, int fallback)") {
+ block("try") {
+ nl("return Integer.parseInt(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static long parse(String str, long fallback)") {
+ block("try") {
+ nl("return Long.parseLong(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static float parse(String str, float fallback)") {
+ block("try") {
+ nl("return Float.parseFloat(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static double parse(String str, double fallback)") {
+ block("try") {
+ nl("return Double.parseDouble(str);")
+ }
+ block("catch (NumberFormatException e)") {
+ nl("return fallback;")
+ }
+ }
+ block("public static char parse(String str, char fallback)") {
+ block ("if (str == null || str.isEmpty())") {
+ nl("return fallback;")
+ }
+ nl("return str.charAt(0);")
}
- tab("return root.getResources().getColor(resourceId);")
}
- tab("}")
- nl("}")
- }
+ }
} \ No newline at end of file
diff --git a/compiler/src/main/kotlin/android/databinding/tool/writer/KCode.kt b/compiler/src/main/kotlin/android/databinding/tool/writer/KCode.kt
index a9b282ac..98438f69 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/KCode.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/KCode.kt
@@ -38,24 +38,24 @@ class KCode (private val s : String? = null){
while (indentCache.size <= n) {
indentCache.add("");
}
- indentCache[n] = s
+ indentCache.set(n, s)
return s
}
}
fun isNull(kcode : KCode?) = kcode == null || (kcode.nodes.isEmpty() && (kcode.s == null || kcode.s.trim() == ""))
- fun tab(vararg codes : KCode?) : KCode {
+ public fun tab(vararg codes : KCode?) : KCode {
codes.forEach { tab(it) }
return this
}
- fun tab(codes : Collection<KCode?> ) : KCode {
+ public fun tab(codes : Collection<KCode?> ) : KCode {
codes.forEach { tab(it) }
return this
}
- infix fun tab(s : String?, init : (KCode.() -> Unit)? = null) : KCode {
+ fun tab(s : String?, init : (KCode.() -> Unit)? = null) : KCode {
val c = KCode(s)
if (init != null) {
c.init()
@@ -80,7 +80,7 @@ class KCode (private val s : String? = null){
return this
}
- infix fun nl(s : String?, init : (KCode.() -> Unit)? = null) : KCode {
+ fun nl(s : String?, init : (KCode.() -> Unit)? = null) : KCode {
val c = KCode(s)
if (init != null) {
c.init()
@@ -88,6 +88,18 @@ class KCode (private val s : String? = null){
return nl(c)
}
+ fun block(s : String, init : (KCode.() -> Unit)? = null) : KCode {
+ val c = KCode()
+ if (init != null) {
+ c.init()
+ }
+ return nl(s) {
+ app(" {")
+ tab(c)
+ nl("}")
+ }
+ }
+
fun app(glue : String = "", c : KCode?) : KCode {
if (isNull(c)) {
return this
@@ -125,9 +137,13 @@ class KCode (private val s : String? = null){
val childTab = n + (if(it.sameLine) 0 else 1)
if (addedChild || newlineFirstNode) {
sb.append(lineSeparator)
- sb.append("${indent(childTab)}")
}
- it.toS(childTab, sb)
+ if (!isNull(it)) { // avoid spaces for empty lines
+ if (it.s != null && it.s.trim() != "") {
+ sb.append("${indent(childTab)}")
+ }
+ it.toS(childTab, sb)
+ }
addedChild = true
}
} }
@@ -147,4 +163,4 @@ fun kcode(s : String?, init : (KCode.() -> Unit)? = null) : KCode {
c.init()
}
return c
-}
+} \ No newline at end of file
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 690a4d60..30b2583d 100644
--- a/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
+++ b/compiler/src/main/kotlin/android/databinding/tool/writer/LayoutBinderWriter.kt
@@ -13,16 +13,22 @@
package android.databinding.tool.writer
+import android.databinding.tool.Binding
import android.databinding.tool.BindingTarget
+import android.databinding.tool.CallbackWrapper
import android.databinding.tool.InverseBinding
import android.databinding.tool.LayoutBinder
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.expr.LambdaExpr
import android.databinding.tool.expr.ListenerExpr
import android.databinding.tool.expr.ResourceExpr
import android.databinding.tool.expr.TernaryExpr
+import android.databinding.tool.expr.localizeGlobalVariables
+import android.databinding.tool.expr.shouldLocalizeInCallbacks
+import android.databinding.tool.expr.toCode
import android.databinding.tool.ext.androidId
import android.databinding.tool.ext.br
import android.databinding.tool.ext.joinToCamelCaseAsVar
@@ -30,7 +36,9 @@ import android.databinding.tool.ext.lazyProp
import android.databinding.tool.ext.versionedLazy
import android.databinding.tool.processing.ErrorMessages
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 java.util.ArrayList
import java.util.Arrays
import java.util.BitSet
@@ -39,11 +47,30 @@ import java.util.HashMap
fun String.stripNonJava() = this.split("[^a-zA-Z0-9]".toRegex()).map{ it.trim() }.joinToCamelCaseAsVar()
enum class Scope {
+ GLOBAL,
FIELD,
METHOD,
FLAG,
EXECUTE_PENDING_METHOD,
- CONSTRUCTOR_PARAM
+ CONSTRUCTOR_PARAM,
+ CALLBACK;
+ companion object {
+ var currentScope = GLOBAL;
+ private val scopeStack = arrayListOf<Scope>()
+ fun enter(scope : Scope) {
+ scopeStack.add(currentScope)
+ currentScope = scope
+ }
+
+ fun exit() {
+ currentScope = scopeStack.removeAt(scopeStack.size - 1)
+ }
+
+ fun reset() {
+ scopeStack.clear()
+ currentScope = GLOBAL
+ }
+ }
}
class ExprModelExt {
@@ -51,6 +78,9 @@ class ExprModelExt {
init {
Scope.values().forEach { usedFieldNames[it] = hashSetOf<String>() }
}
+
+ internal val forceLocalize = hashSetOf<Expr>()
+
val localizedFlags = arrayListOf<FlagSet>()
fun localizeFlag(set : FlagSet, name:String) : FlagSet {
@@ -66,6 +96,9 @@ class ExprModelExt {
candidateBase = candidateBase.substring(0, 20);
}
var candidate = candidateBase
+ if (scope == Scope.CALLBACK || scope == Scope.EXECUTE_PENDING_METHOD) {
+ candidate = candidate.decapitalize()
+ }
var i = 0
while (usedFieldNames[scope]!!.contains(candidate)) {
i ++
@@ -76,20 +109,17 @@ class ExprModelExt {
}
}
-val ExprModel.ext by lazyProp { target : ExprModel ->
- ExprModelExt()
-}
-
+fun ModelClass.defaultValue() = ModelAnalyzer.getInstance().getDefaultValue(toJavaCode())
fun ExprModel.getUniqueFieldName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.FIELD, isPublic)
fun ExprModel.getUniqueMethodName(base : String, isPublic : kotlin.Boolean) : String = ext.getUniqueName(base, Scope.METHOD, isPublic)
fun ExprModel.getConstructorParamName(base : String) : String = ext.getUniqueName(base, Scope.CONSTRUCTOR_PARAM, false)
-
fun ExprModel.localizeFlag(set : FlagSet, base : String) : FlagSet = ext.localizeFlag(set, base)
val Expr.needsLocalField by lazyProp { expr : Expr ->
expr.canBeEvaluatedToAVariable() && !(expr.isVariable() && !expr.isUsed) && (expr.isDynamic || expr is ResourceExpr)
}
+fun Expr.isForcedToLocalize() = model.ext.forceLocalize.contains(this)
// not necessarily unique. Uniqueness is solved per scope
val BindingTarget.readableName by lazyProp { target: BindingTarget ->
@@ -143,7 +173,7 @@ val BindingTarget.constructorParamName by lazyProp { target : BindingTarget ->
// not necessarily unique. Uniqueness is decided per scope
val Expr.readableName by lazyProp { expr : Expr ->
- val stripped = "${expr.uniqueKey.stripNonJava()}"
+ val stripped = expr.uniqueKey.stripNonJava()
L.d("readableUniqueName for [%s] %s is %s", System.identityHashCode(expr), expr.uniqueKey, stripped)
stripped
}
@@ -166,8 +196,18 @@ val Expr.oldValueName by lazyProp { expr : Expr ->
expr.model.getUniqueFieldName("mOld${expr.readableName.capitalize()}", false)
}
+fun Expr.scopedName() : String = when(Scope.currentScope) {
+ Scope.CALLBACK -> callbackLocalName
+ else -> executePendingLocalName
+}
+
+val Expr.callbackLocalName by lazyProp { expr : Expr ->
+ if(expr.shouldLocalizeInCallbacks()) "${expr.model.ext.getUniqueName(expr.readableName, Scope.CALLBACK, false)}"
+ 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)}"
+ if(expr.isDynamic || expr.needsLocalField) "${expr.model.ext.getUniqueName(expr.readableName, Scope.EXECUTE_PENDING_METHOD, false)}"
else expr.toCode().generate()
}
@@ -206,6 +246,17 @@ val Expr.conditionalFlags by lazyProp { expr : Expr ->
FlagSet(expr.getRequirementFlagIndex(true)))
}
+fun Binding.toAssignmentCode() : String {
+ val fieldName: String
+ if (this.target.viewClass.
+ equals(this.target.interfaceType)) {
+ fieldName = "this.${this.target.fieldName}"
+ } else {
+ fieldName = "((${this.target.viewClass}) this.${this.target.fieldName})"
+ }
+ return this.toJavaCode(fieldName, "this.mBindingComponent")
+}
+
val LayoutBinder.requiredComponent by lazyProp { layoutBinder: LayoutBinder ->
val requiredFromBindings = layoutBinder.
bindingTargets.
@@ -287,10 +338,15 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
val usedVariables by lazy {
- variables.filter {it.isUsed }
+ variables.filter {it.isUsed || it.isIsUsedInCallback }
+ }
+
+ val callbacks by lazy {
+ model.exprMap.values.filterIsInstance(LambdaExpr::class.java)
}
public fun write(minSdk : kotlin.Int) : String {
+ Scope.reset()
layoutBinder.resolveWhichExpressionsAreUsed()
calculateIndices();
return kcode("package ${layoutBinder.`package`};") {
@@ -303,33 +359,56 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
} else {
classDeclaration = "$className extends android.databinding.ViewDataBinding"
}
- nl("public class $classDeclaration {") {
- tab(declareIncludeViews())
- tab(declareViews())
- tab(declareVariables())
- tab(declareBoundValues())
- tab(declareListeners())
- tab(declareInverseBindingImpls());
- tab(declareConstructor(minSdk))
- tab(declareInvalidateAll())
- tab(declareHasPendingBindings())
- tab(declareSetVariable())
- tab(variableSettersAndGetters())
- tab(onFieldChange())
-
- tab(executePendingBindings())
-
- tab(declareListenerImpls())
- tab(declareDirtyFlags())
+ block("public class $classDeclaration ${buildImplements()}") {
+ nl(declareIncludeViews())
+ nl(declareViews())
+ nl(declareVariables())
+ nl(declareBoundValues())
+ nl(declareListeners())
+ try {
+ Scope.enter(Scope.GLOBAL)
+ nl(declareInverseBindingImpls());
+ } finally {
+ Scope.exit()
+ }
+ nl(declareConstructor(minSdk))
+ nl(declareInvalidateAll())
+ nl(declareHasPendingBindings())
+ nl(declareSetVariable())
+ nl(variableSettersAndGetters())
+ nl(onFieldChange())
+ try {
+ Scope.enter(Scope.GLOBAL)
+ nl(executePendingBindings())
+ } finally {
+ Scope.exit()
+ }
+
+ nl(declareListenerImpls())
+ try {
+ Scope.enter(Scope.CALLBACK)
+ nl(declareCallbackImplementations())
+ } finally {
+ Scope.exit()
+ }
+
+ nl(declareDirtyFlags())
if (!layoutBinder.hasVariations()) {
- tab(declareFactories())
+ nl(declareFactories())
}
+ nl(flagMapping())
+ nl("//end")
}
- nl("}")
- tab(flagMapping())
- tab("//end")
}.generate()
}
+ fun buildImplements() : String {
+ return if (callbacks.isEmpty()) {
+ ""
+ } else {
+ "implements " + callbacks.map { it.callbackWrapper.cannonicalListenerName }.distinct().joinToString(", ")
+ }
+ }
+
fun calculateIndices() : Unit {
val taggedViews = layoutBinder.bindingTargets.filter{
it.isUsed && it.tag != null && !it.isBinder
@@ -481,10 +560,76 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
}
tab("setRootTag(root);")
+ tab(declareCallbackInstances())
tab("invalidateAll();");
nl("}")
}
+ fun declareCallbackInstances() = kcode("// listeners") {
+ callbacks.groupBy { it.callbackWrapper.minApi }
+ .forEach {
+ if (it.key > 1) {
+ block("if(getBuildSdkInt() < ${it.key})") {
+ it.value.forEach { lambda ->
+ nl("${lambda.fieldName} = null;")
+ }
+ }
+ block("else") {
+ it.value.forEach { lambda ->
+ nl("${lambda.fieldName} = ${lambda.generateConstructor()};")
+ }
+ }
+ } else {
+ it.value.forEach { lambda ->
+ nl("${lambda.fieldName} = ${lambda.generateConstructor()};")
+ }
+ }
+ }
+ }
+
+ fun declareCallbackImplementations() = kcode("// callback impls") {
+ callbacks.groupBy { it.callbackWrapper }.forEach {
+ val wrapper = it.key
+ val lambdas = it.value
+ val shouldReturn = !wrapper.method.returnType.isVoid
+ if (shouldReturn) {
+ lambdas.forEach {
+ it.callbackExprModel.ext.forceLocalize.add(it.expr)
+ }
+ }
+ block("public final ${wrapper.method.returnType.canonicalName} ${wrapper.listenerMethodName}(${wrapper.allArgsWithTypes()})") {
+ Preconditions.check(lambdas.size > 0, "bindings list should not be empty")
+ if (lambdas.size == 1) {
+ val lambda = lambdas[0]
+ nl(lambda.callbackExprModel.localizeGlobalVariables(lambda))
+ nl(lambda.executionPath.toCode())
+ if (shouldReturn) {
+ nl("return ${lambda.expr.scopedName()};")
+ }
+ } else {
+ block("switch(${CallbackWrapper.SOURCE_ID})") {
+ lambdas.forEach { lambda ->
+ block("case ${lambda.callbackId}:") {
+ nl(lambda.callbackExprModel.localizeGlobalVariables(lambda))
+ nl(lambda.executionPath.toCode())
+ if (shouldReturn) {
+ nl("return ${lambda.expr.scopedName()};")
+ } else {
+ nl("break;")
+ }
+ }
+ }
+ if (shouldReturn) {
+ block("default:") {
+ nl("return ${wrapper.method.returnType.defaultValue()};")
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
fun fieldConversion(target : BindingTarget) : String {
if (!target.isUsed) {
return "null"
@@ -497,20 +642,19 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
fun declareInvalidateAll() = kcode("") {
nl("@Override")
- nl("public void invalidateAll() {") {
+ block("public void invalidateAll()") {
val fs = FlagSet(layoutBinder.model.invalidateAnyBitSet,
layoutBinder.model.flagBucketCount);
- tab("synchronized(this) {") {
+ block("synchronized(this)") {
for (i in (0..(mDirtyFlags.buckets.size - 1))) {
tab("${mDirtyFlags.localValue(i)} = ${fs.localValue(i)};")
}
- } tab("}")
+ }
includedBinders.filter{it.isUsed }.forEach { binder ->
- tab("${binder.fieldName}.invalidateAll();")
+ nl("${binder.fieldName}.invalidateAll();")
}
- tab("requestRebind();");
+ nl("requestRebind();");
}
- nl("}")
}
fun declareHasPendingBindings() = kcode("") {
@@ -548,7 +692,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
tab("return true;")
}
}
- val declaredOnly = variables.filter { !it.isUsed && it.isDeclared };
+ val declaredOnly = variables.filter { !it.isUsed && !it.isIsUsedInCallback && it.isDeclared };
declaredOnly.forEachIndexed { i, identifierExpr ->
tab ("case ${identifierExpr.name.br()} :") {
if (i == declaredOnly.size - 1) {
@@ -564,7 +708,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
fun variableSettersAndGetters() = kcode("") {
- variables.filterNot{it.isUsed }.forEach {
+ variables.filterNot{ usedVariables.contains(it) }.forEach {
nl("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName}) {") {
tab("// not used, ignore")
}
@@ -577,30 +721,28 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
usedVariables.forEach {
if (it.userDefinedType != null) {
- nl("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName}) {") {
+ block("public void ${it.setterName}(${it.resolvedType.toJavaCode()} ${it.readableName})") {
if (it.isObservable) {
- tab("updateRegistration(${it.id}, ${it.readableName});");
+ nl("updateRegistration(${it.id}, ${it.readableName});");
}
- tab("this.${it.fieldName} = ${it.readableName};")
+ nl("this.${it.fieldName} = ${it.readableName};")
// set dirty flags!
val flagSet = it.invalidateFlagSet
- tab("synchronized(this) {") {
+ block("synchronized(this)") {
mDirtyFlags.mapOr(flagSet) { suffix, index ->
- tab("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};")
+ nl("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};")
}
- } tab ("}")
+ }
// TODO: Remove this condition after releasing version 1.1 of SDK
if (ModelAnalyzer.getInstance().findClass("android.databinding.ViewDataBinding", null).isObservable) {
- tab("notifyPropertyChanged(${it.name.br()});")
+ nl("notifyPropertyChanged(${it.name.br()});")
}
- tab("super.requestRebind();")
+ nl("super.requestRebind();")
}
- nl("}")
nl("")
- nl("public ${it.resolvedType.toJavaCode()} ${it.getterName}() {") {
- tab("return ${it.fieldName};")
+ block("public ${it.resolvedType.toJavaCode()} ${it.getterName}()") {
+ nl("return ${it.fieldName};")
}
- nl("}")
}
}
}
@@ -622,42 +764,39 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
nl("")
model.observables.forEach {
- nl("private boolean ${it.onChangeName}(${it.resolvedType.toJavaCode()} ${it.readableName}, int fieldId) {") {
- tab("switch (fieldId) {", {
+ block("private boolean ${it.onChangeName}(${it.resolvedType.toJavaCode()} ${it.readableName}, int fieldId)") {
+ block("switch (fieldId)", {
val accessedFields: List<FieldAccessExpr> = it.parents.filterIsInstance(FieldAccessExpr::class.java)
- accessedFields.filter { it.hasBindableAnnotations() }
+ accessedFields.filter { it.isUsed && it.hasBindableAnnotations() }
.groupBy { it.brName }
.forEach {
// If two expressions look different but resolve to the same method,
// we are not yet able to merge them. This is why we merge their
// flags below.
- tab("case ${it.key}:") {
- tab("synchronized(this) {") {
+ block("case ${it.key}:") {
+ block("synchronized(this)") {
val flagSet = it.value.foldRight(FlagSet()) { l, r -> l.invalidateFlagSet.or(r) }
mDirtyFlags.mapOr(flagSet) { suffix, index ->
tab("${mDirtyFlags.localValue(index)} |= ${flagSet.localValue(index)};")
}
- } tab("}")
- tab("return true;")
+ }
+ nl("return true;")
}
}
- tab("case ${"".br()}:") {
+ block("case ${"".br()}:") {
val flagSet = it.invalidateFlagSet
- tab("synchronized(this) {") {
+ block("synchronized(this)") {
mDirtyFlags.mapOr(flagSet) { suffix, index ->
tab("${mDirtyFlags.localName}$suffix |= ${flagSet.localValue(index)};")
}
- } tab("}")
- tab("return true;")
+ }
+ nl("return true;")
}
-
})
- tab("}")
- tab("return false;")
+ nl("return false;")
}
- nl("}")
nl("")
}
}
@@ -679,13 +818,17 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
usedVariables.forEach {
nl("private ${it.resolvedType.toJavaCode()} ${it.fieldName};")
}
+ callbacks.forEach {
+ val wrapper = it.callbackWrapper
+ nl("private final ${wrapper.klass.canonicalName} ${it.fieldName}").app(";")
+ }
}
fun declareBoundValues() = kcode("// values") {
layoutBinder.sortedTargets.filter { it.isUsed }
.flatMap { it.bindings }
.filter { it.requiresOldValue() }
- .flatMap{ it.componentExpressions.toArrayList() }
+ .flatMap{ it.componentExpressions.toList() }
.groupBy { it }
.forEach {
val expr = it.key
@@ -714,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(";")
}
}
}
@@ -739,7 +898,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
if (model.flagMapping != null) {
val mapping = model.flagMapping
for (i in mapping.indices) {
- tab("flag $i: ${mapping[i]}")
+ tab("flag $i (${longToBinary(1L + i)}): ${model.findFlagExpression(i)}")
}
}
nl("flag mapping end*/")
@@ -747,24 +906,24 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
fun executePendingBindings() = kcode("") {
nl("@Override")
- nl("protected void executeBindings() {") {
+ block("protected void executeBindings()") {
val tmpDirtyFlags = FlagSet(mDirtyFlags.buckets)
tmpDirtyFlags.localName = "dirtyFlags";
for (i in (0..mDirtyFlags.buckets.size - 1)) {
- tab("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;")
+ nl("${tmpDirtyFlags.type} ${tmpDirtyFlags.localValue(i)} = 0;")
}
- tab("synchronized(this) {") {
+ block("synchronized(this)") {
for (i in (0..mDirtyFlags.buckets.size - 1)) {
- tab("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};")
- tab("${mDirtyFlags.localValue(i)} = 0;")
+ nl("${tmpDirtyFlags.localValue(i)} = ${mDirtyFlags.localValue(i)};")
+ nl("${mDirtyFlags.localValue(i)} = 0;")
}
- } tab("}")
+ }
model.pendingExpressions.filter { it.needsLocalField }.forEach {
- tab("${it.resolvedType.toJavaCode()} ${it.executePendingLocalName} = ${if (it.isVariable()) it.fieldName else it.defaultValue};")
+ nl("${it.resolvedType.toJavaCode()} ${it.executePendingLocalName} = ${if (it.isVariable()) it.fieldName else it.defaultValue};")
}
L.d("writing executePendingBindings for %s", className)
do {
- val batch = ExprModel.filterShouldRead(model.pendingExpressions).toArrayList()
+ val batch = ExprModel.filterShouldRead(model.pendingExpressions)
val justRead = arrayListOf<Expr>()
L.d("batch: %s", batch)
while (!batch.none()) {
@@ -776,10 +935,10 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
nl(readWithDependants(readNow, justRead, batch, tmpDirtyFlags))
batch.removeAll(justRead)
}
- tab("// batch finished")
+ nl("// batch finished")
} while (model.markBitsRead())
// verify everything is read.
- val batch = ExprModel.filterShouldRead(model.pendingExpressions).toArrayList()
+ val batch = ExprModel.filterShouldRead(model.pendingExpressions)
if (batch.isNotEmpty()) {
L.e("could not generate code for %s. This might be caused by circular dependencies."
+ "Please report on b.android.com. %d %s %s", layoutBinder.layoutname,
@@ -793,32 +952,23 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
"(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0"
}.joinToString(" || ") }"
}.forEach {
- tab("if (${it.key}) {") {
+ block("if (${it.key})") {
it.value.groupBy { Math.max(1, it.minApi) }.forEach {
val setterValues = kcode("") {
it.value.forEach { binding ->
- val fieldName: String
- if (binding.target.viewClass.
- equals(binding.target.interfaceType)) {
- fieldName = "this.${binding.target.fieldName}"
- } else {
- fieldName = "((${binding.target.viewClass}) this.${binding.target.fieldName})"
- }
- tab(binding.toJavaCode(fieldName, "this.mBindingComponent")).app(";")
+ nl(binding.toAssignmentCode()).app(";")
}
}
- tab("// api target ${it.key}")
+ nl("// api target ${it.key}")
if (it.key > 1) {
- tab("if(getBuildSdkInt() >= ${it.key}) {") {
- app("", setterValues)
+ block("if(getBuildSdkInt() >= ${it.key})") {
+ nl(setterValues)
}
- tab("}")
} else {
- app("", setterValues)
+ nl(setterValues)
}
}
}
- tab("}")
}
@@ -829,28 +979,25 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
"(${tmpDirtyFlags.localValue(index)} & ${it.expr.dirtyFlagSet.localValue(index)}) != 0"
}.joinToString(" || ")
}"}.forEach {
- tab("if (${it.key}) {") {
+ block("if (${it.key})") {
it.value.groupBy { it.expr }.map { it.value.first() }.forEach {
it.componentExpressions.forEach { expr ->
- tab("this.${expr.oldValueName} = ${expr.toCode().generate()};")
+ nl("this.${expr.oldValueName} = ${expr.toCode().generate()};")
}
}
}
- tab("}")
}
includedBinders.filter{it.isUsed }.forEach { binder ->
- tab("${binder.fieldName}.executePendingBindings();")
+ nl("${binder.fieldName}.executePendingBindings();")
}
layoutBinder.sortedTargets.filter{
it.isUsed && it.resolvedType != null && it.resolvedType.extendsViewStub()
}.forEach {
- tab("if (${it.fieldName}.getBinding() != null) {") {
- tab("${it.fieldName}.getBinding().executePendingBindings();")
+ block("if (${it.fieldName}.getBinding() != null)") {
+ nl("${it.fieldName}.getBinding().executePendingBindings();")
}
- tab("}")
}
}
- nl("}")
}
fun readWithDependants(expressionList: List<Expr>, justRead: MutableList<Expr>,
@@ -872,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(";")
}
}
@@ -891,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
@@ -973,13 +1120,11 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
if (needsIfWrapper) {
- tab(ifClause) {
- app(" {")
- app("", readCode)
+ block(ifClause) {
+ nl(readCode)
}
- tab("}")
} else {
- app("", readCode)
+ nl(readCode)
}
}
}
@@ -1013,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;")
}
@@ -1023,7 +1168,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
val listenerMethod = expr.method
val parameterTypes = listenerMethod.parameterTypes
- val returnType = listenerMethod.getReturnType(parameterTypes.toArrayList())
+ val returnType = listenerMethod.getReturnType(parameterTypes.toList())
tab("@Override")
tab("public $returnType ${listenerMethod.name}(${
parameterTypes.withIndex().map {
@@ -1031,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) {
@@ -1054,35 +1199,28 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
}
fun declareFactories() = kcode("") {
- nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") {
- tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());")
+ block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot)") {
+ nl("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());")
}
- nl("}")
- nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") {
- tab("return android.databinding.DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);")
+ block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent)") {
+ nl("return android.databinding.DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);")
}
- nl("}")
if (!layoutBinder.isMerge) {
- nl("public static $baseClassName inflate(android.view.LayoutInflater inflater) {") {
- tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());")
+ block("public static $baseClassName inflate(android.view.LayoutInflater inflater)") {
+ nl("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());")
}
- nl("}")
- nl("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") {
- tab("return bind(inflater.inflate(${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false), bindingComponent);")
+ block("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent)") {
+ nl("return bind(inflater.inflate(${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false), bindingComponent);")
}
- nl("}")
- nl("public static $baseClassName bind(android.view.View view) {") {
- tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());")
+ block("public static $baseClassName bind(android.view.View view)") {
+ nl("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());")
}
- nl("}")
- nl("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") {
- tab("if (!\"${layoutBinder.tag}_0\".equals(view.getTag())) {") {
- tab("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());")
+ block("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent)") {
+ block("if (!\"${layoutBinder.tag}_0\".equals(view.getTag()))") {
+ nl("throw new RuntimeException(\"view tag isn't correct on view:\" + view.getTag());")
}
- tab("}")
- tab("return new $baseClassName(bindingComponent, view);")
+ nl("return new $baseClassName(bindingComponent, view);")
}
- nl("}")
}
}
@@ -1091,6 +1229,7 @@ class LayoutBinderWriter(val layoutBinder : LayoutBinder) {
*/
public fun writeBaseClass(forLibrary : Boolean) : String =
kcode("package ${layoutBinder.`package`};") {
+ Scope.reset()
nl("import android.databinding.Bindable;")
nl("import android.databinding.DataBindingUtil;")
nl("import android.databinding.ViewDataBinding;")
diff --git a/compiler/src/test/java/android/databinding/BindingExpressionParserTest.java b/compiler/src/test/java/android/databinding/BindingExpressionParserTest.java
index 92824795..419f1b07 100644
--- a/compiler/src/test/java/android/databinding/BindingExpressionParserTest.java
+++ b/compiler/src/test/java/android/databinding/BindingExpressionParserTest.java
@@ -15,6 +15,7 @@
*/
package android.databinding;
+import android.databinding.parser.BindingExpressionBaseVisitor;
import android.databinding.parser.BindingExpressionLexer;
import android.databinding.parser.BindingExpressionParser;
import android.databinding.parser.BindingExpressionParser.AndOrOpContext;
@@ -39,6 +40,7 @@ import android.databinding.parser.BindingExpressionParser.UnaryOpContext;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.junit.Test;
@@ -141,14 +143,6 @@ public class BindingExpressionParserTest {
}
@Test
- public void testVoidExtraction() throws Exception {
- PrimaryContext primary = parsePrimary("void.class");
- assertNotNull(primary.classExtraction());
- assertNull(primary.classExtraction().type());
- assertEquals("void", primary.classExtraction().getChild(0).getText());
- }
-
- @Test
public void testPrimitiveClassExtraction() throws Exception {
PrimaryContext primary = parsePrimary("int.class");
PrimitiveTypeContext type = primary.classExtraction().type().primitiveType();
@@ -255,7 +249,14 @@ public class BindingExpressionParserTest {
@Test
public void testDefaults() throws Exception {
BindingSyntaxContext syntax = parseExpressionString("foo.bar, default = @id/foo_bar");
- DefaultsContext defaults = syntax.defaults();
+ BindingExpressionParser.DefaultsContext defaults = syntax
+ .accept(new BindingExpressionBaseVisitor<DefaultsContext>() {
+ @Override
+ public BindingExpressionParser.DefaultsContext visitDefaults(
+ @NotNull BindingExpressionParser.DefaultsContext ctx) {
+ return ctx;
+ }
+ });
assertEquals("@id/foo_bar", defaults.constantValue().ResourceReference().getText());
}
@@ -364,8 +365,13 @@ public class BindingExpressionParserTest {
}
private <T extends ExpressionContext> T parseExpression(String value) throws Exception {
- ExpressionContext expressionContext = parse(value).expression();
- return (T) expressionContext;
+ return (T) parse(value).accept(new BindingExpressionBaseVisitor<ExpressionContext>() {
+ @Override
+ public ExpressionContext visitRootExpr(
+ @NotNull BindingExpressionParser.RootExprContext ctx) {
+ return ctx.expression();
+ }
+ });
}
private PrimaryContext parsePrimary(String value) throws Exception {
diff --git a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
index 97331cfa..3d3d8fed 100644
--- a/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
+++ b/compiler/src/test/java/android/databinding/tool/ExpressionVisitorTest.java
@@ -51,7 +51,7 @@ public class ExpressionVisitorTest {
}
private <T extends Expr> T parse(String input, Class<T> klass) {
- final Expr parsed = mParser.parse(input, null);
+ final Expr parsed = mParser.parse(input, null, null);
assertSame(klass, parsed.getClass());
return (T) parsed;
}
@@ -89,7 +89,7 @@ public class ExpressionVisitorTest {
@Test
public void testComparison() {
- final Expr res = mParser.parse("3 " + mOp + " 5", null);
+ final Expr res = mParser.parse("3 " + mOp + " 5", null, null);
assertEquals(3, mParser.getModel().size());
assertTrue(res instanceof ComparisonExpr);
// 0 because they are both static
@@ -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();
@@ -180,7 +180,7 @@ public class ExpressionVisitorTest {
assertEquals(0, parsed.getArgs().size());
assertEquals(1, parsed.getDependencies().size());
final Dependency dep = parsed.getDependencies().get(0);
- assertSame(mParser.parse("user", null), dep.getOther());
+ assertSame(mParser.parse("user", null, null), dep.getOther());
assertFalse(dep.isConditional());
}
diff --git a/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java b/compiler/src/test/java/android/databinding/tool/LayoutBinderTest.java
index 8b1f820d..564ecef4 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, null);
+ mLayoutBinder.parse("user.lastName", null, 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, 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
new file mode 100644
index 00000000..d6fb4707
--- /dev/null
+++ b/compiler/src/test/java/android/databinding/tool/expr/ExecutionPathTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.MockLayoutBinder;
+import android.databinding.tool.reflection.java.JavaAnalyzer;
+import android.databinding.tool.solver.ExecutionPath;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(Parameterized.class)
+public class ExecutionPathTest {
+
+ private final String mExpression;
+
+ public ExecutionPathTest(String expression) {
+ mExpression = expression;
+ }
+
+
+ @Parameterized.Parameters
+ public static List<String> expressions() {
+ return Arrays.asList("a.b(3/2)",
+ "a ? (a ? b : c) : d",
+ "a ? (b ? d : f) : g",
+ "5 + 4 / 3 + 2 + 7 * 8",
+ "a ? b : c");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ JavaAnalyzer.initForTests();
+ }
+
+ @Test
+ public void simpleExpr() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ ExprModel model = lb.getModel();
+ Expr parsed = lb.parse(mExpression, null, null);
+ List<ExecutionPath> paths = new ArrayList<ExecutionPath>();
+ ExecutionPath root = ExecutionPath.createRoot();
+ paths.add(root);
+ List<ExecutionPath> result = parsed.toExecutionPath(paths);
+ StringBuilder sb = new StringBuilder();
+ root.debug(sb, 0);
+ sb.toString();
+ }
+}
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 04813e16..a661c30f 100644
--- a/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
+++ b/compiler/src/test/java/android/databinding/tool/expr/ExprModelTest.java
@@ -42,10 +42,12 @@ import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+@SuppressWarnings("Duplicates")
public class ExprModelTest {
private static class DummyExpr extends Expr {
@@ -73,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.";
}
@@ -147,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, null);
mExprModel.comparison("==", a, mExprModel.symbol("null", Object.class));
lb.getModel().seal();
List<Expr> shouldRead = getShouldRead();
@@ -296,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, null);
assertTrue(aTernary instanceof TernaryExpr);
final Expr bTernary = ((TernaryExpr) aTernary).getIfTrue();
assertTrue(bTernary instanceof TernaryExpr);
@@ -425,13 +432,10 @@ public class ExprModelTest {
assertTrue(mExprModel.markBitsRead());
shouldRead = getShouldRead();
- // FIXME: there is no real case to read u1 anymore because if b>c was not true,
- // u1.getCond(d) will never be set. Right now, we don't have mechanism to figure this out
- // and also it does not affect correctness (just an unnecessary if stmt)
- assertExactMatch(shouldRead, u1, u2, u1LastName, u2LastName, bcTernary.getIfTrue(), bcTernary);
+
+ assertExactMatch(shouldRead, u2, u1LastName, u2LastName, bcTernary.getIfTrue(), bcTernary);
firstRead = getReadFirst(shouldRead);
- assertExactMatch(firstRead, u1, u2);
- assertFlags(u1, bcTernary.getIfTrue().getRequirementFlagIndex(true));
+ assertExactMatch(firstRead, u1LastName, u2);
assertFlags(u2, bcTernary.getIfTrue().getRequirementFlagIndex(false));
assertFlags(u1LastName, bcTernary.getIfTrue().getRequirementFlagIndex(true));
assertFlags(u2LastName, bcTernary.getIfTrue().getRequirementFlagIndex(false));
@@ -597,12 +601,13 @@ public class ExprModelTest {
Collections.addAll(justRead, a, b, c);
assertEquals(0, filterOut(getReadFirst(shouldRead, justRead), justRead).size());
assertTrue(mExprModel.markBitsRead());
+
shouldRead = getShouldRead();
// if a and b are not invalid, a won't be read in the first step. But if c's expression
// is invalid and c == true, a must be read. Depending on a, d might be read as well.
// don't need to read b anymore because `a ? b : true` and `b ? a : false` has the same
// invalidation flags.
- assertExactMatch(shouldRead, a, abTernary, baTernary);
+ assertExactMatch(shouldRead, a, baTernary);
justRead.clear();
readFirst = getReadFirst(shouldRead);
@@ -611,20 +616,23 @@ public class ExprModelTest {
Collections.addAll(justRead, a);
readFirst = filterOut(getReadFirst(shouldRead, justRead), justRead);
- assertExactMatch(readFirst, abTernary, baTernary);
- Collections.addAll(justRead, abTernary, baTernary);
+ assertExactMatch(readFirst, baTernary);
+ Collections.addAll(justRead, baTernary);
readFirst = filterOut(getReadFirst(shouldRead, justRead), justRead);
assertEquals(0, filterOut(getReadFirst(shouldRead, justRead), justRead).size());
assertTrue(mExprModel.markBitsRead());
shouldRead = getShouldRead();
+ // now we can read abTernary as well which had a conditional dependency on a but we did not
+ // elevate its dependency since we had other expressions elevated already
+
// now we can read adf ternary and c ternary
justRead.clear();
- assertExactMatch(shouldRead, d, cTernary.getIfTrue(), cTernary);
+ assertExactMatch(shouldRead, abTernary, d, cTernary.getIfTrue(), cTernary);
readFirst = getReadFirst(shouldRead);
- assertExactMatch(readFirst, d);
- Collections.addAll(justRead, d);
+ assertExactMatch(readFirst, d, abTernary);
+ Collections.addAll(justRead, d, abTernary);
readFirst = filterOut(getReadFirst(shouldRead, justRead), justRead);
assertExactMatch(readFirst, cTernary.getIfTrue());
Collections.addAll(justRead, cTernary.getIfTrue());
@@ -688,6 +696,76 @@ public class ExprModelTest {
}
@Test
+ public void testInvalidateConditional() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final IdentifierExpr foo = lb.addVariable("foo", Foo.class.getCanonicalName(), null);
+ final IdentifierExpr c = lb.addVariable("c", "int", null);
+ final TernaryExpr ternary = parse(lb, "foo.a > 0 && (foo.b > 0 || c > 0)",
+ TernaryExpr.class);
+ final ComparisonExpr fooB0 = parse(lb, "foo.b > 0", ComparisonExpr.class);
+ final FieldAccessExpr fooB = (FieldAccessExpr) fooB0.getLeft();
+ mExprModel.seal();
+ final ComparisonExpr fooA0 = (ComparisonExpr) ternary.getPred();
+ final FieldAccessExpr fooA = (FieldAccessExpr) fooA0.getLeft();
+
+ // foo.b > 0 || c > 0
+ final TernaryExpr ternaryIfTrue = (TernaryExpr) ternary.getIfTrue();
+ final ComparisonExpr c0 = (ComparisonExpr) ternaryIfTrue.getIfFalse();
+
+ List<Expr> toRead = getShouldRead();
+ assertExactMatch(toRead, foo, fooA, fooA0, fooB, fooB0);
+ List<Expr> justRead = new ArrayList<Expr>();
+ List<Expr> readNow = getReadFirst(toRead, justRead);
+ assertExactMatch(readNow, foo);
+ justRead.addAll(readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, fooA, fooB);
+ justRead.addAll(readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, fooA0, fooB0);
+ justRead.addAll(readNow);
+
+ assertTrue(mExprModel.markBitsRead());
+ justRead.clear();
+ toRead = getShouldRead();
+
+ // there is a second path to calculate fooB, fooB0 where fooB is not invalid but fooA or
+ // c is invalid.
+ assertExactMatch(toRead, fooB, fooB0);
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, fooB);
+ justRead.add(fooB);
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, fooB0);
+
+ assertTrue(mExprModel.markBitsRead());
+ justRead.clear();
+ toRead = getShouldRead();
+
+ assertExactMatch(toRead, c, c0, ternary.getIfTrue(), ternary);
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, c);
+ justRead.addAll(readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, c0);
+ justRead.addAll(readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, ternary.getIfTrue());
+ justRead.addAll(readNow);
+
+ readNow = filterOut(getReadFirst(toRead, justRead), justRead);
+ assertExactMatch(readNow, ternary);
+ justRead.addAll(readNow);
+
+ assertFalse(mExprModel.markBitsRead());
+ }
+
+ @Test
public void testNoFlagsForNonBindingStatic() {
MockLayoutBinder lb = new MockLayoutBinder();
mExprModel = lb.getModel();
@@ -794,7 +872,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");
@@ -846,6 +924,86 @@ public class ExprModelTest {
}
@Test
+ public void testVoid() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "(v) -> cond1 ? obj4.clicked(v) : void", LambdaExpr.class);
+ assertNotSame(mExprModel, lambda.getCallbackExprModel());
+ }
+
+ @Test
+ public void testVoid2() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "(v) -> cond1 ? obj4.clicked(v) : Void", LambdaExpr.class);
+ assertNotSame(mExprModel, lambda.getCallbackExprModel());
+ }
+
+ @Test
+ public void testShruggy() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "(v) -> cond1 ? obj4.clicked(v) : ¯\\_(ツ)_/¯", LambdaExpr.class);
+ assertNotSame(mExprModel, lambda.getCallbackExprModel());
+ }
+
+ @Test
+ public void testParseNoArgLambda() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "() -> user.name", LambdaExpr.class);
+ assertNotSame(mExprModel, lambda.getCallbackExprModel());
+ }
+
+ @Test
+ public void testParseLambdaWithSingleArg() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "a -> user.name", LambdaExpr.class);
+ assertNotSame(mExprModel, lambda.getCallbackExprModel());
+ assertTrue("should have user", hasIdentifier(mExprModel, "user"));
+ assertTrue("should have user", hasIdentifier(lambda.getCallbackExprModel(), "user"));
+ assertSame("should have the same user", getIdentifier(mExprModel, "user"),
+ getIdentifier(lambda.getCallbackExprModel(), "user"));
+ assertTrue("should have a", hasCallbackIdentifier(lambda.getCallbackExprModel(), 0, "a"));
+ assertFalse("should not have a", hasCallbackIdentifier(mExprModel, 0, "a"));
+ }
+
+ @Test
+ public void testParseLambdaWithArguments() {
+ MockLayoutBinder lb = new MockLayoutBinder();
+ mExprModel = lb.getModel();
+ final LambdaExpr lambda = parse(lb, "(a, b, c, d) -> user.name", LambdaExpr.class);
+ final CallbackExprModel callbackModel = lambda.getCallbackExprModel();
+ assertNotSame(mExprModel, callbackModel);
+ assertTrue("should have user", hasIdentifier(mExprModel, "user"));
+ int index = 0;
+ for (String s : new String[]{"a", "b", "c", "d"}) {
+ assertTrue("should have " + s, hasCallbackIdentifier(callbackModel, index, s));
+ assertFalse("should not have " + s, hasIdentifier(mExprModel, s));
+ assertFalse("should not have " + s, hasCallbackIdentifier(mExprModel, index, s));
+ index ++;
+ }
+ }
+
+ private boolean hasIdentifier(ExprModel model, String name) {
+ return getIdentifier(model, name) != null;
+ }
+
+ private Expr getIdentifier(ExprModel model, String name) {
+ return model.getExprMap().get(new IdentifierExpr(name).getUniqueKey());
+ }
+
+ private boolean hasCallbackIdentifier(ExprModel model, int index, String name) {
+ return getCallbackIdentifier(model, index, name) != null;
+ }
+
+ private Expr getCallbackIdentifier(ExprModel model, int index, String name) {
+ return model.getExprMap().get(new CallbackArgExpr(index, name).getUniqueKey());
+ }
+
+
+ @Test
public void testFinalOfStaticField() {
MockLayoutBinder lb = new MockLayoutBinder();
mExprModel = lb.getModel();
@@ -974,7 +1132,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, null);
assertTrue(klass.isAssignableFrom(parsed.getClass()));
return (T) parsed;
}
@@ -1006,6 +1164,11 @@ public class ExprModelTest {
return ExprModel.filterShouldRead(mExprModel.getPendingExpressions());
}
+ public static class Foo {
+ public final int a = 1;
+ public final int b = 1;
+ }
+
public static class User implements Observable {
String name;
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..a79897ca 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;
@@ -66,13 +66,17 @@ public class JavaAnalyzer extends ModelAnalyzer {
}
}
+ public ClassLoader getClassLoader() {
+ return mClassLoader;
+ }
+
@Override
protected ModelClass[] getObservableFieldTypes() {
return new ModelClass[0];
}
@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 0835a14b..f6f709d2 100644
--- a/compilerCommon/BindingExpression.g4
+++ b/compilerCommon/BindingExpression.g4
@@ -26,28 +26,45 @@
grammar BindingExpression;
bindingSyntax
- : expression defaults?
+ : expression defaults? # RootExpr
+ | lambdaExpression # RootLambda
;
defaults
: ',' 'default' '=' constantValue
;
+
constantValue
: literal
| ResourceReference
| identifier
;
+lambdaExpression
+ : args=lambdaParameters '->' expr=expression
+ ;
+
+lambdaParameters
+ : Identifier # SingleLambdaParameter
+ | '(' params=inferredFormalParameterList? ')' #LambdaParameterList
+ ;
+
+inferredFormalParameterList
+ : Identifier (',' Identifier)*
+ ;
+
expression
: '(' expression ')' # Grouping
// this isn't allowed yet.
// | THIS # Primary
| literal # Primary
+ | VoidLiteral # Primary
| identifier # Primary
| classExtraction # Primary
| resources # Resource
// | typeArguments (explicitGenericInvocationSuffix | 'this' arguments) # GenericCall
| expression '.' Identifier # DotOp
+ | expression '::' Identifier # FunctionRef
// | expression '.' 'this' # ThisReference
// | expression '.' explicitGenericInvocation # ExplicitGenericInvocationOp
| expression '[' expression ']' # BracketOp
@@ -76,7 +93,6 @@ THIS
classExtraction
: type '.' 'class'
- | 'void' '.' 'class'
;
expressionList
@@ -100,6 +116,12 @@ javaLiteral
| CharacterLiteral
;
+VoidLiteral
+ : 'Void'
+ | 'void'
+ | '¯\\_(ツ)_/¯'
+ ;
+
stringLiteral
: SingleQuoteString
| DoubleQuoteString
diff --git a/compilerCommon/build.gradle b/compilerCommon/build.gradle
index 91ce05db..0f260e48 100644
--- a/compilerCommon/build.gradle
+++ b/compilerCommon/build.gradle
@@ -16,9 +16,6 @@
apply plugin: 'java'
-sourceCompatibility = dataBindingConfig.javaSourceCompatibility
-targetCompatibility = dataBindingConfig.javaTargetCompatibility
-
sourceSets {
main {
java {
@@ -38,17 +35,26 @@ sourceSets {
dependencies {
testCompile 'junit:junit:4.12'
compile project(':dataBinding:baseLibrary')
- compile 'com.tunnelvisionlabs:antlr4:4.5'
+ compile 'org.antlr:antlr4:4.5.3'
compile 'commons-io:commons-io:2.4'
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
compile 'com.google.guava:guava:17.0'
+ compile 'com.android.tools:annotations:24.5.0'
+}
+
+project.tasks.create(name : "generateXmlLexer", type : JavaExec) {
+ classpath configurations.runtime
+ main "org.antlr.v4.Tool"
+ workingDir projectDir
+ args "XMLLexer.g4", "-visitor", "-lib", projectDir.absolutePath, "-o", "src/main/xml-gen/android/databinding/parser", "-package", "android.databinding.parser"
}
project.tasks.create(name : "generateXmlParser", type : JavaExec) {
classpath configurations.runtime
main "org.antlr.v4.Tool"
workingDir projectDir
- args "XMLParser.g4", "-visitor", "-o", "src/main/java/android/databinding/parser", "-package", "android.databinding.parser", "-lib", "."
+ args "XMLParser.g4", "-visitor", "-lib", projectDir.absolutePath, "-o", "src/main/xml-gen/android/databinding/parser", "-package", "android.databinding.parser"
+ dependsOn "generateXmlLexer"
}
project.tasks.create(name : "generateGrammar", type : JavaExec) {
diff --git a/compilerCommon/compilerCommon.iml b/compilerCommon/compilerCommon.iml
deleted file mode 100644
index d9cc2c61..00000000
--- a/compilerCommon/compilerCommon.iml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":dataBinding:compilerCommon" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="1.1" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/classes/main" />
- <output-test url="file://$MODULE_DIR$/build/classes/test" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src/main/grammar-gen" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/xml-gen" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="baseLibrary" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4:4.5" level="project" />
- <orderEntry type="library" name="Gradle: commons-io:commons-io:2.4" level="project" />
- <orderEntry type="library" name="Gradle: com.googlecode.juniversalchardet:juniversalchardet:1.0.3" level="project" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4-runtime:4.5" level="project" />
- <orderEntry type="library" name="Gradle: com.tunnelvisionlabs:antlr4-annotations:4.5" level="project" />
- <orderEntry type="library" name="Gradle: org.antlr:antlr-runtime:3.5.2" level="project" />
- <orderEntry type="library" name="Gradle: org.antlr:ST4:4.0.8" level="project" />
- <orderEntry type="library" name="Gradle: org.abego.treelayout:org.abego.treelayout.core:1.0.1" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.12" level="project" />
- <orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
- <orderEntry type="library" name="Gradle: com.google.guava:guava:17.0" level="project" />
- </component>
-</module> \ No newline at end of file
diff --git a/compilerCommon/db-compilerCommon-base.iml b/compilerCommon/db-compilerCommon-base.iml
index 38f8122f..bc880d54 100644
--- a/compilerCommon/db-compilerCommon-base.iml
+++ b/compilerCommon/db-compilerCommon-base.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
@@ -16,7 +16,7 @@
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/tunnelvisionlabs/antlr4/4.5/antlr4-4.5.jar!/" />
+ <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/org/antlr/antlr4/4.5.3/antlr4-4.5.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -45,42 +45,6 @@
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/tunnelvisionlabs/antlr4-runtime/4.5/antlr4-runtime-4.5.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="module-library" exported="">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/tunnelvisionlabs/antlr4-annotations/4.5/antlr4-annotations-4.5.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="module-library" exported="">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/org/antlr/antlr-runtime/3.5.2/antlr-runtime-3.5.2.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="module-library" exported="">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/org/antlr/ST4/4.0.8/ST4-4.0.8.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="module-library" exported="">
- <library>
- <CLASSES>
<root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/org/abego/treelayout/org.abego.treelayout.core/1.0.1/org.abego.treelayout.core-1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
@@ -110,5 +74,6 @@
</library>
</orderEntry>
<orderEntry type="library" exported="" name="guava-tools" level="project" />
+ <orderEntry type="module" module-name="android-annotations" />
</component>
</module> \ No newline at end of file
diff --git a/compilerCommon/db-compilerCommon.iml b/compilerCommon/db-compilerCommon.iml
index 3b18b8a9..eb533639 100644
--- a/compilerCommon/db-compilerCommon.iml
+++ b/compilerCommon/db-compilerCommon.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
@@ -25,8 +25,7 @@
<SOURCES />
</library>
</orderEntry>
- <orderEntry type="library" exported="" name="antlr4-runtime-4.5" level="project" />
- <orderEntry type="library" exported="" name="antlr4-annotations-4.5" level="project" />
+ <orderEntry type="library" exported="" name="antlr4-runtime-4.5.3" level="project" />
<orderEntry type="module-library" scope="TEST">
<library>
<CLASSES>
@@ -49,5 +48,6 @@
</SOURCES>
</library>
</orderEntry>
+ <orderEntry type="module" module-name="android-annotations" exported="" />
</component>
</module> \ No newline at end of file
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 d9d10353..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,61 +41,64 @@ T__39=40
T__40=41
T__41=42
T__42=43
-THIS=44
-IntegerLiteral=45
-FloatingPointLiteral=46
-BooleanLiteral=47
-CharacterLiteral=48
-SingleQuoteString=49
-DoubleQuoteString=50
-NullLiteral=51
-Identifier=52
-WS=53
-ResourceReference=54
-PackageName=55
-ResourceType=56
+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
-'('=4
-')'=5
-'.'=6
-'['=7
-']'=8
-'+'=9
-'-'=10
-'~'=11
-'!'=12
-'*'=13
-'/'=14
-'%'=15
-'<<'=16
-'>>>'=17
-'>>'=18
-'<='=19
-'>='=20
-'>'=21
-'<'=22
-'instanceof'=23
-'=='=24
-'!='=25
-'&'=26
-'^'=27
-'|'=28
-'&&'=29
-'||'=30
-'?'=31
-':'=32
-'??'=33
-'class'=34
-'void'=35
-'boolean'=36
-'char'=37
-'byte'=38
-'short'=39
-'int'=40
-'long'=41
-'float'=42
-'double'=43
-'this'=44
-'null'=51
+'->'=4
+'('=5
+')'=6
+'.'=7
+'::'=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 2b114922..c9ccebd6 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseListener.java
@@ -1,9 +1,7 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -18,478 +16,504 @@ public class BindingExpressionBaseListener implements BindingExpressionListener
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { }
+ @Override public void enterRootExpr(BindingExpressionParser.RootExprContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx) { }
-
+ @Override public void exitRootExpr(BindingExpressionParser.RootExprContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx) { }
+ @Override public void enterRootLambda(BindingExpressionParser.RootLambdaContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx) { }
-
+ @Override public void exitRootLambda(BindingExpressionParser.RootLambdaContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { }
+ @Override public void enterDefaults(BindingExpressionParser.DefaultsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) { }
-
+ @Override public void exitDefaults(BindingExpressionParser.DefaultsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx) { }
+ @Override public void enterConstantValue(BindingExpressionParser.ConstantValueContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx) { }
-
+ @Override public void exitConstantValue(BindingExpressionParser.ConstantValueContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { }
+ @Override public void enterLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx) { }
-
+ @Override public void exitLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { }
+ @Override public void enterSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx) { }
-
+ @Override public void exitSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { }
+ @Override public void enterLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx) { }
-
+ @Override public void exitLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { }
+ @Override public void enterInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx) { }
-
+ @Override public void exitInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { }
+ @Override public void enterCastOp(BindingExpressionParser.CastOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx) { }
-
+ @Override public void exitCastOp(BindingExpressionParser.CastOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { }
+ @Override public void enterComparisonOp(BindingExpressionParser.ComparisonOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx) { }
-
+ @Override public void exitComparisonOp(BindingExpressionParser.ComparisonOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { }
+ @Override public void enterUnaryOp(BindingExpressionParser.UnaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx) { }
-
+ @Override public void exitUnaryOp(BindingExpressionParser.UnaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { }
+ @Override public void enterBracketOp(BindingExpressionParser.BracketOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx) { }
-
+ @Override public void exitBracketOp(BindingExpressionParser.BracketOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { }
+ @Override public void enterResource(BindingExpressionParser.ResourceContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx) { }
-
+ @Override public void exitResource(BindingExpressionParser.ResourceContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { }
+ @Override public void enterQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx) { }
-
+ @Override public void exitQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx) { }
+ @Override public void enterGrouping(BindingExpressionParser.GroupingContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx) { }
-
+ @Override public void exitGrouping(BindingExpressionParser.GroupingContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx) { }
+ @Override public void enterMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx) { }
-
+ @Override public void exitMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx) { }
+ @Override public void enterBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx) { }
-
+ @Override public void exitBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx) { }
+ @Override public void enterAndOrOp(BindingExpressionParser.AndOrOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx) { }
-
+ @Override public void exitAndOrOp(BindingExpressionParser.AndOrOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx) { }
+ @Override public void enterTernaryOp(BindingExpressionParser.TernaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx) { }
-
+ @Override public void exitTernaryOp(BindingExpressionParser.TernaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterExpression(@NotNull BindingExpressionParser.ExpressionContext ctx) { }
+ @Override public void enterPrimary(BindingExpressionParser.PrimaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitExpression(@NotNull BindingExpressionParser.ExpressionContext ctx) { }
-
+ @Override public void exitPrimary(BindingExpressionParser.PrimaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx) { }
+ @Override public void enterDotOp(BindingExpressionParser.DotOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx) { }
-
+ @Override public void exitDotOp(BindingExpressionParser.DotOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx) { }
+ @Override public void enterMathOp(BindingExpressionParser.MathOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx) { }
-
+ @Override public void exitMathOp(BindingExpressionParser.MathOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterLiteral(@NotNull BindingExpressionParser.LiteralContext ctx) { }
+ @Override public void enterInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitLiteral(@NotNull BindingExpressionParser.LiteralContext ctx) { }
-
+ @Override public void exitInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) { }
+ @Override public void enterBinaryOp(BindingExpressionParser.BinaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) { }
-
+ @Override public void exitBinaryOp(BindingExpressionParser.BinaryOpContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx) { }
+ @Override public void enterFunctionRef(BindingExpressionParser.FunctionRefContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx) { }
-
+ @Override public void exitFunctionRef(BindingExpressionParser.FunctionRefContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx) { }
+ @Override public void enterClassExtraction(BindingExpressionParser.ClassExtractionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx) { }
-
+ @Override public void exitClassExtraction(BindingExpressionParser.ClassExtractionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx) { }
+ @Override public void enterExpressionList(BindingExpressionParser.ExpressionListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx) { }
-
+ @Override public void exitExpressionList(BindingExpressionParser.ExpressionListContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx) { }
+ @Override public void enterLiteral(BindingExpressionParser.LiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx) { }
-
+ @Override public void exitLiteral(BindingExpressionParser.LiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterType(@NotNull BindingExpressionParser.TypeContext ctx) { }
+ @Override public void enterIdentifier(BindingExpressionParser.IdentifierContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitType(@NotNull BindingExpressionParser.TypeContext ctx) { }
-
+ @Override public void exitIdentifier(BindingExpressionParser.IdentifierContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { }
+ @Override public void enterJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { }
-
+ @Override public void exitJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx) { }
+ @Override public void enterStringLiteral(BindingExpressionParser.StringLiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx) { }
-
+ @Override public void exitStringLiteral(BindingExpressionParser.StringLiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { }
+ @Override public void enterExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { }
-
+ @Override public void exitExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx) { }
+ @Override public void enterTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx) { }
-
+ @Override public void exitTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterResources(@NotNull BindingExpressionParser.ResourcesContext ctx) { }
+ @Override public void enterType(BindingExpressionParser.TypeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitResources(@NotNull BindingExpressionParser.ResourcesContext ctx) { }
-
+ @Override public void exitType(BindingExpressionParser.TypeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterArguments(BindingExpressionParser.ArgumentsContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitArguments(BindingExpressionParser.ArgumentsContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void enterResources(BindingExpressionParser.ResourcesContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation does nothing.</p>
+ */
+ @Override public void exitResources(BindingExpressionParser.ResourcesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx) { }
+ @Override public void enterResourceParameters(BindingExpressionParser.ResourceParametersContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx) { }
+ @Override public void exitResourceParameters(BindingExpressionParser.ResourceParametersContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterEveryRule(@NotNull ParserRuleContext ctx) { }
+ @Override public void enterEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitEveryRule(@NotNull ParserRuleContext ctx) { }
+ @Override public void exitEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void visitTerminal(@NotNull TerminalNode node) { }
+ @Override public void visitTerminal(TerminalNode node) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void visitErrorNode(@NotNull ErrorNode node) { }
+ @Override public void visitErrorNode(ErrorNode node) { }
} \ No newline at end of file
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 08c54fa8..5ba08bae 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionBaseVisitor.java
@@ -1,7 +1,5 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
@@ -9,287 +7,288 @@ import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
- * @param <Result> The return type of the visit operation. Use {@link Void} for
+ * @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
-public class BindingExpressionBaseVisitor<Result> extends AbstractParseTreeVisitor<Result> implements BindingExpressionVisitor<Result> {
+public class BindingExpressionBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements BindingExpressionVisitor<T> {
/**
* {@inheritDoc}
*
* <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 T visitRootExpr(BindingExpressionParser.RootExprContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitRootLambda(BindingExpressionParser.RootLambdaContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitDefaults(BindingExpressionParser.DefaultsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitConstantValue(BindingExpressionParser.ConstantValueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitCastOp(BindingExpressionParser.CastOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitComparisonOp(BindingExpressionParser.ComparisonOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitUnaryOp(BindingExpressionParser.UnaryOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitBracketOp(BindingExpressionParser.BracketOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitResource(BindingExpressionParser.ResourceContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <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 T visitQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitGrouping(BindingExpressionParser.GroupingContext 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); }
-
+ @Override public T visitMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitAndOrOp(BindingExpressionParser.AndOrOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitTernaryOp(BindingExpressionParser.TernaryOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitExpression(@NotNull BindingExpressionParser.ExpressionContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitPrimary(BindingExpressionParser.PrimaryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitDotOp(BindingExpressionParser.DotOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitMathOp(BindingExpressionParser.MathOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitLiteral(@NotNull BindingExpressionParser.LiteralContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitBinaryOp(BindingExpressionParser.BinaryOpContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitFunctionRef(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 visitStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitClassExtraction(BindingExpressionParser.ClassExtractionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitExpressionList(BindingExpressionParser.ExpressionListContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitLiteral(BindingExpressionParser.LiteralContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitType(@NotNull BindingExpressionParser.TypeContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitIdentifier(BindingExpressionParser.IdentifierContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitStringLiteral(BindingExpressionParser.StringLiteralContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitResources(@NotNull BindingExpressionParser.ResourcesContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitType(BindingExpressionParser.TypeContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.</p>
+ */
+ @Override public T visitExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.</p>
+ */
+ @Override public T visitArguments(BindingExpressionParser.ArgumentsContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.</p>
+ */
+ @Override public T visitClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.</p>
+ */
+ @Override public T visitPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.</p>
+ */
+ @Override public T visitResources(BindingExpressionParser.ResourcesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx) { return visitChildren(ctx); }
+ @Override public T visitResourceParameters(BindingExpressionParser.ResourceParametersContext ctx) { return visitChildren(ctx); }
} \ No newline at end of file
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 898ab4ea..d89c63e6 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionLexer.java
@@ -1,4 +1,4 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
@@ -9,17 +9,23 @@ import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class BindingExpressionLexer extends Lexer {
+ static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
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, IntegerLiteral=45,
- FloatingPointLiteral=46, BooleanLiteral=47, CharacterLiteral=48, SingleQuoteString=49,
- DoubleQuoteString=50, NullLiteral=51, Identifier=52, WS=53, ResourceReference=54,
- PackageName=55, ResourceType=56;
+ 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,37 +36,38 @@ 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", "IntegerLiteral", "DecimalIntegerLiteral", "HexIntegerLiteral",
- "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix", "DecimalNumeral",
- "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore", "Underscores",
- "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore", "OctalNumeral",
- "OctalDigits", "OctalDigit", "OctalDigitOrUnderscore", "BinaryNumeral",
- "BinaryDigits", "BinaryDigit", "BinaryDigitOrUnderscore", "FloatingPointLiteral",
- "DecimalFloatingPointLiteral", "ExponentPart", "ExponentIndicator", "SignedInteger",
- "Sign", "FloatTypeSuffix", "HexadecimalFloatingPointLiteral", "HexSignificand",
- "BinaryExponent", "BinaryExponentIndicator", "BooleanLiteral", "CharacterLiteral",
- "SingleCharacter", "SingleQuoteString", "DoubleQuoteString", "StringCharacters",
- "StringCharacter", "SingleQuoteStringCharacter", "EscapeSequence", "OctalEscape",
- "UnicodeEscape", "ZeroToThree", "NullLiteral", "Identifier", "JavaLetter",
- "JavaLetterOrDigit", "WS", "ResourceReference", "PackageName", "ResourceType"
+ "T__41", "T__42", "T__43", "THIS", "VoidLiteral", "IntegerLiteral", "DecimalIntegerLiteral",
+ "HexIntegerLiteral", "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix",
+ "DecimalNumeral", "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore",
+ "Underscores", "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore",
+ "OctalNumeral", "OctalDigits", "OctalDigit", "OctalDigitOrUnderscore",
+ "BinaryNumeral", "BinaryDigits", "BinaryDigit", "BinaryDigitOrUnderscore",
+ "FloatingPointLiteral", "DecimalFloatingPointLiteral", "ExponentPart",
+ "ExponentIndicator", "SignedInteger", "Sign", "FloatTypeSuffix", "HexadecimalFloatingPointLiteral",
+ "HexSignificand", "BinaryExponent", "BinaryExponentIndicator", "BooleanLiteral",
+ "CharacterLiteral", "SingleCharacter", "SingleQuoteString", "DoubleQuoteString",
+ "StringCharacters", "StringCharacter", "SingleQuoteStringCharacter", "EscapeSequence",
+ "OctalEscape", "UnicodeEscape", "ZeroToThree", "NullLiteral", "Identifier",
+ "JavaLetter", "JavaLetterOrDigit", "WS", "ResourceReference", "PackageName",
+ "ResourceType"
};
private static final String[] _LITERAL_NAMES = {
- null, "','", "'default'", "'='", "'('", "')'", "'.'", "'['", "']'", "'+'",
- "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", "'>>>'", "'>>'", "'<='",
- "'>='", "'>'", "'<'", "'instanceof'", "'=='", "'!='", "'&'", "'^'", "'|'",
- "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", "'void'", "'boolean'",
- "'char'", "'byte'", "'short'", "'int'", "'long'", "'float'", "'double'",
- "'this'", 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", "IntegerLiteral",
- "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral", "SingleQuoteString",
- "DoubleQuoteString", "NullLiteral", "Identifier", "WS", "ResourceReference",
- "PackageName", "ResourceType"
+ null, null, null, null, null, null, null, null, null, "THIS", "VoidLiteral",
+ "IntegerLiteral", "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral",
+ "SingleQuoteString", "DoubleQuoteString", "NullLiteral", "Identifier",
+ "WS", "ResourceReference", "PackageName", "ResourceType"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -90,7 +97,7 @@ public class BindingExpressionLexer extends Lexer {
}
@Override
- @NotNull
+
public Vocabulary getVocabulary() {
return VOCABULARY;
}
@@ -98,7 +105,7 @@ public class BindingExpressionLexer extends Lexer {
public BindingExpressionLexer(CharStream input) {
super(input);
- _interp = new LexerATNSimulator(this,_ATN);
+ _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
@@ -114,13 +121,15 @@ public class BindingExpressionLexer extends Lexer {
public String[] getModeNames() { return modeNames; }
@Override
+ public ATN getATN() { return _ATN; }
+
+ @Override
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
switch (ruleIndex) {
- case 93:
- return JavaLetter_sempred(_localctx, predIndex);
-
- case 94:
- return JavaLetterOrDigit_sempred(_localctx, predIndex);
+ case 95:
+ return JavaLetter_sempred((RuleContext)_localctx, predIndex);
+ case 96:
+ return JavaLetterOrDigit_sempred((RuleContext)_localctx, predIndex);
}
return true;
}
@@ -128,7 +137,6 @@ public class BindingExpressionLexer extends Lexer {
switch (predIndex) {
case 0:
return Character.isJavaIdentifierStart(_input.LA(-1));
-
case 1:
return Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)));
}
@@ -138,7 +146,6 @@ public class BindingExpressionLexer extends Lexer {
switch (predIndex) {
case 2:
return Character.isJavaIdentifierPart(_input.LA(-1));
-
case 3:
return Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)));
}
@@ -146,7 +153,7 @@ public class BindingExpressionLexer extends Lexer {
}
public static final String _serializedATN =
- "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\2:\u0358\b\1\4\2\t"+
+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\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"+
@@ -157,300 +164,311 @@ 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\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\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\21\3\22\3\22\3\22"+
- "\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3\27\3\27"+
- "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31"+
- "\3\32\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\36\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.\5.\u0168\n.\3/\3/\5/\u016c\n/\3\60\3\60\5\60"+
- "\u0170\n\60\3\61\3\61\5\61\u0174\n\61\3\62\3\62\5\62\u0178\n\62\3\63\3"+
- "\63\3\64\3\64\3\64\5\64\u017f\n\64\3\64\3\64\3\64\5\64\u0184\n\64\5\64"+
- "\u0186\n\64\3\65\3\65\7\65\u018a\n\65\f\65\16\65\u018d\13\65\3\65\5\65"+
- "\u0190\n\65\3\66\3\66\5\66\u0194\n\66\3\67\3\67\38\38\58\u019a\n8\39\6"+
- "9\u019d\n9\r9\169\u019e\3:\3:\3:\3:\3;\3;\7;\u01a7\n;\f;\16;\u01aa\13"+
- ";\3;\5;\u01ad\n;\3<\3<\3=\3=\5=\u01b3\n=\3>\3>\5>\u01b7\n>\3>\3>\3?\3"+
- "?\7?\u01bd\n?\f?\16?\u01c0\13?\3?\5?\u01c3\n?\3@\3@\3A\3A\5A\u01c9\nA"+
- "\3B\3B\3B\3B\3C\3C\7C\u01d1\nC\fC\16C\u01d4\13C\3C\5C\u01d7\nC\3D\3D\3"+
- "E\3E\5E\u01dd\nE\3F\3F\5F\u01e1\nF\3G\3G\3G\5G\u01e6\nG\3G\5G\u01e9\n"+
- "G\3G\5G\u01ec\nG\3G\3G\3G\5G\u01f1\nG\3G\5G\u01f4\nG\3G\3G\3G\5G\u01f9"+
- "\nG\3G\3G\3G\5G\u01fe\nG\3H\3H\3H\3I\3I\3J\5J\u0206\nJ\3J\3J\3K\3K\3L"+
- "\3L\3M\3M\3M\5M\u0211\nM\3N\3N\5N\u0215\nN\3N\3N\3N\5N\u021a\nN\3N\3N"+
- "\5N\u021e\nN\3O\3O\3O\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\5Q\u022e\nQ\3R"+
- "\3R\3R\3R\3R\3R\3R\3R\5R\u0238\nR\3S\3S\3T\3T\7T\u023e\nT\fT\16T\u0241"+
- "\13T\3T\3T\3U\3U\5U\u0247\nU\3U\3U\3V\6V\u024c\nV\rV\16V\u024d\3W\3W\5"+
- "W\u0252\nW\3X\3X\5X\u0256\nX\3Y\3Y\3Y\3Y\5Y\u025c\nY\3Z\3Z\3Z\3Z\3Z\3"+
- "Z\3Z\3Z\3Z\3Z\3Z\5Z\u0269\nZ\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3]\3]\3]\3]"+
- "\3]\3^\3^\7^\u027b\n^\f^\16^\u027e\13^\3_\3_\3_\3_\3_\3_\5_\u0286\n_\3"+
- "`\3`\3`\3`\3`\3`\5`\u028e\n`\3a\6a\u0291\na\ra\16a\u0292\3a\3a\3b\3b\3"+
- "b\3b\5b\u029b\nb\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3c\5c\u02a9\nc\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3d\3"+
- "d\3d\3d\3d\3d\3d\3d\3d\3d\3d\5d\u0357\nd\2\2\2e\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\2_\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\60\u008d\2\2\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\61\u00a3\2\62\u00a5\2\2\u00a7\2\63\u00a9\2\64\u00ab\2\2\u00ad"+
- "\2\2\u00af\2\2\u00b1\2\2\u00b3\2\2\u00b5\2\2\u00b7\2\2\u00b9\2\65\u00bb"+
- "\2\66\u00bd\2\2\u00bf\2\2\u00c1\2\67\u00c3\28\u00c5\29\u00c7\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\2GGg"+
- "g\4\2--//\6\2FFHHffhh\4\2RRrr\4\2))^^\4\2$$^^\4\2^^bb\13\2$$))^^bbddh"+
- "hppttvv\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\"\"\u037b\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\u008b\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3"+
- "\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2"+
- "\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\3\u00c9"+
- "\3\2\2\2\5\u00cb\3\2\2\2\7\u00d3\3\2\2\2\t\u00d5\3\2\2\2\13\u00d7\3\2"+
- "\2\2\r\u00d9\3\2\2\2\17\u00db\3\2\2\2\21\u00dd\3\2\2\2\23\u00df\3\2\2"+
- "\2\25\u00e1\3\2\2\2\27\u00e3\3\2\2\2\31\u00e5\3\2\2\2\33\u00e7\3\2\2\2"+
- "\35\u00e9\3\2\2\2\37\u00eb\3\2\2\2!\u00ed\3\2\2\2#\u00f0\3\2\2\2%\u00f4"+
- "\3\2\2\2\'\u00f7\3\2\2\2)\u00fa\3\2\2\2+\u00fd\3\2\2\2-\u00ff\3\2\2\2"+
- "/\u0101\3\2\2\2\61\u010c\3\2\2\2\63\u010f\3\2\2\2\65\u0112\3\2\2\2\67"+
- "\u0114\3\2\2\29\u0116\3\2\2\2;\u0118\3\2\2\2=\u011b\3\2\2\2?\u011e\3\2"+
- "\2\2A\u0120\3\2\2\2C\u0122\3\2\2\2E\u0125\3\2\2\2G\u012b\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[\u0167\3\2"+
- "\2\2]\u0169\3\2\2\2_\u016d\3\2\2\2a\u0171\3\2\2\2c\u0175\3\2\2\2e\u0179"+
- "\3\2\2\2g\u0185\3\2\2\2i\u0187\3\2\2\2k\u0193\3\2\2\2m\u0195\3\2\2\2o"+
- "\u0199\3\2\2\2q\u019c\3\2\2\2s\u01a0\3\2\2\2u\u01a4\3\2\2\2w\u01ae\3\2"+
- "\2\2y\u01b2\3\2\2\2{\u01b4\3\2\2\2}\u01ba\3\2\2\2\177\u01c4\3\2\2\2\u0081"+
- "\u01c8\3\2\2\2\u0083\u01ca\3\2\2\2\u0085\u01ce\3\2\2\2\u0087\u01d8\3\2"+
- "\2\2\u0089\u01dc\3\2\2\2\u008b\u01e0\3\2\2\2\u008d\u01fd\3\2\2\2\u008f"+
- "\u01ff\3\2\2\2\u0091\u0202\3\2\2\2\u0093\u0205\3\2\2\2\u0095\u0209\3\2"+
- "\2\2\u0097\u020b\3\2\2\2\u0099\u020d\3\2\2\2\u009b\u021d\3\2\2\2\u009d"+
- "\u021f\3\2\2\2\u009f\u0222\3\2\2\2\u00a1\u022d\3\2\2\2\u00a3\u0237\3\2"+
- "\2\2\u00a5\u0239\3\2\2\2\u00a7\u023b\3\2\2\2\u00a9\u0244\3\2\2\2\u00ab"+
- "\u024b\3\2\2\2\u00ad\u0251\3\2\2\2\u00af\u0255\3\2\2\2\u00b1\u025b\3\2"+
- "\2\2\u00b3\u0268\3\2\2\2\u00b5\u026a\3\2\2\2\u00b7\u0271\3\2\2\2\u00b9"+
- "\u0273\3\2\2\2\u00bb\u0278\3\2\2\2\u00bd\u0285\3\2\2\2\u00bf\u028d\3\2"+
- "\2\2\u00c1\u0290\3\2\2\2\u00c3\u0296\3\2\2\2\u00c5\u02a8\3\2\2\2\u00c7"+
- "\u0356\3\2\2\2\u00c9\u00ca\7.\2\2\u00ca\4\3\2\2\2\u00cb\u00cc\7f\2\2\u00cc"+
- "\u00cd\7g\2\2\u00cd\u00ce\7h\2\2\u00ce\u00cf\7c\2\2\u00cf\u00d0\7w\2\2"+
- "\u00d0\u00d1\7n\2\2\u00d1\u00d2\7v\2\2\u00d2\6\3\2\2\2\u00d3\u00d4\7?"+
- "\2\2\u00d4\b\3\2\2\2\u00d5\u00d6\7*\2\2\u00d6\n\3\2\2\2\u00d7\u00d8\7"+
- "+\2\2\u00d8\f\3\2\2\2\u00d9\u00da\7\60\2\2\u00da\16\3\2\2\2\u00db\u00dc"+
- "\7]\2\2\u00dc\20\3\2\2\2\u00dd\u00de\7_\2\2\u00de\22\3\2\2\2\u00df\u00e0"+
- "\7-\2\2\u00e0\24\3\2\2\2\u00e1\u00e2\7/\2\2\u00e2\26\3\2\2\2\u00e3\u00e4"+
- "\7\u0080\2\2\u00e4\30\3\2\2\2\u00e5\u00e6\7#\2\2\u00e6\32\3\2\2\2\u00e7"+
- "\u00e8\7,\2\2\u00e8\34\3\2\2\2\u00e9\u00ea\7\61\2\2\u00ea\36\3\2\2\2\u00eb"+
- "\u00ec\7\'\2\2\u00ec \3\2\2\2\u00ed\u00ee\7>\2\2\u00ee\u00ef\7>\2\2\u00ef"+
- "\"\3\2\2\2\u00f0\u00f1\7@\2\2\u00f1\u00f2\7@\2\2\u00f2\u00f3\7@\2\2\u00f3"+
- "$\3\2\2\2\u00f4\u00f5\7@\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*\3\2\2\2\u00fd\u00fe\7@\2\2\u00fe,\3\2\2\2\u00ff\u0100\7"+
- ">\2\2\u0100.\3\2\2\2\u0101\u0102\7k\2\2\u0102\u0103\7p\2\2\u0103\u0104"+
- "\7u\2\2\u0104\u0105\7v\2\2\u0105\u0106\7c\2\2\u0106\u0107\7p\2\2\u0107"+
- "\u0108\7e\2\2\u0108\u0109\7g\2\2\u0109\u010a\7q\2\2\u010a\u010b\7h\2\2"+
- "\u010b\60\3\2\2\2\u010c\u010d\7?\2\2\u010d\u010e\7?\2\2\u010e\62\3\2\2"+
- "\2\u010f\u0110\7#\2\2\u0110\u0111\7?\2\2\u0111\64\3\2\2\2\u0112\u0113"+
- "\7(\2\2\u0113\66\3\2\2\2\u0114\u0115\7`\2\2\u01158\3\2\2\2\u0116\u0117"+
- "\7~\2\2\u0117:\3\2\2\2\u0118\u0119\7(\2\2\u0119\u011a\7(\2\2\u011a<\3"+
- "\2\2\2\u011b\u011c\7~\2\2\u011c\u011d\7~\2\2\u011d>\3\2\2\2\u011e\u011f"+
- "\7A\2\2\u011f@\3\2\2\2\u0120\u0121\7<\2\2\u0121B\3\2\2\2\u0122\u0123\7"+
- "A\2\2\u0123\u0124\7A\2\2\u0124D\3\2\2\2\u0125\u0126\7e\2\2\u0126\u0127"+
- "\7n\2\2\u0127\u0128\7c\2\2\u0128\u0129\7u\2\2\u0129\u012a\7u\2\2\u012a"+
- "F\3\2\2\2\u012b\u012c\7x\2\2\u012c\u012d\7q\2\2\u012d\u012e\7k\2\2\u012e"+
- "\u012f\7f\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\u0168\5]/\2\u0164\u0168"+
- "\5_\60\2\u0165\u0168\5a\61\2\u0166\u0168\5c\62\2\u0167\u0163\3\2\2\2\u0167"+
- "\u0164\3\2\2\2\u0167\u0165\3\2\2\2\u0167\u0166\3\2\2\2\u0168\\\3\2\2\2"+
- "\u0169\u016b\5g\64\2\u016a\u016c\5e\63\2\u016b\u016a\3\2\2\2\u016b\u016c"+
- "\3\2\2\2\u016c^\3\2\2\2\u016d\u016f\5s:\2\u016e\u0170\5e\63\2\u016f\u016e"+
- "\3\2\2\2\u016f\u0170\3\2\2\2\u0170`\3\2\2\2\u0171\u0173\5{>\2\u0172\u0174"+
- "\5e\63\2\u0173\u0172\3\2\2\2\u0173\u0174\3\2\2\2\u0174b\3\2\2\2\u0175"+
- "\u0177\5\u0083B\2\u0176\u0178\5e\63\2\u0177\u0176\3\2\2\2\u0177\u0178"+
- "\3\2\2\2\u0178d\3\2\2\2\u0179\u017a\t\2\2\2\u017af\3\2\2\2\u017b\u0186"+
- "\7\62\2\2\u017c\u0183\5m\67\2\u017d\u017f\5i\65\2\u017e\u017d\3\2\2\2"+
- "\u017e\u017f\3\2\2\2\u017f\u0184\3\2\2\2\u0180\u0181\5q9\2\u0181\u0182"+
- "\5i\65\2\u0182\u0184\3\2\2\2\u0183\u017e\3\2\2\2\u0183\u0180\3\2\2\2\u0184"+
- "\u0186\3\2\2\2\u0185\u017b\3\2\2\2\u0185\u017c\3\2\2\2\u0186h\3\2\2\2"+
- "\u0187\u018f\5k\66\2\u0188\u018a\5o8\2\u0189\u0188\3\2\2\2\u018a\u018d"+
- "\3\2\2\2\u018b\u0189\3\2\2\2\u018b\u018c\3\2\2\2\u018c\u018e\3\2\2\2\u018d"+
- "\u018b\3\2\2\2\u018e\u0190\5k\66\2\u018f\u018b\3\2\2\2\u018f\u0190\3\2"+
- "\2\2\u0190j\3\2\2\2\u0191\u0194\7\62\2\2\u0192\u0194\5m\67\2\u0193\u0191"+
- "\3\2\2\2\u0193\u0192\3\2\2\2\u0194l\3\2\2\2\u0195\u0196\t\3\2\2\u0196"+
- "n\3\2\2\2\u0197\u019a\5k\66\2\u0198\u019a\7a\2\2\u0199\u0197\3\2\2\2\u0199"+
- "\u0198\3\2\2\2\u019ap\3\2\2\2\u019b\u019d\7a\2\2\u019c\u019b\3\2\2\2\u019d"+
- "\u019e\3\2\2\2\u019e\u019c\3\2\2\2\u019e\u019f\3\2\2\2\u019fr\3\2\2\2"+
- "\u01a0\u01a1\7\62\2\2\u01a1\u01a2\t\4\2\2\u01a2\u01a3\5u;\2\u01a3t\3\2"+
- "\2\2\u01a4\u01ac\5w<\2\u01a5\u01a7\5y=\2\u01a6\u01a5\3\2\2\2\u01a7\u01aa"+
- "\3\2\2\2\u01a8\u01a6\3\2\2\2\u01a8\u01a9\3\2\2\2\u01a9\u01ab\3\2\2\2\u01aa"+
- "\u01a8\3\2\2\2\u01ab\u01ad\5w<\2\u01ac\u01a8\3\2\2\2\u01ac\u01ad\3\2\2"+
- "\2\u01adv\3\2\2\2\u01ae\u01af\t\5\2\2\u01afx\3\2\2\2\u01b0\u01b3\5w<\2"+
- "\u01b1\u01b3\7a\2\2\u01b2\u01b0\3\2\2\2\u01b2\u01b1\3\2\2\2\u01b3z\3\2"+
- "\2\2\u01b4\u01b6\7\62\2\2\u01b5\u01b7\5q9\2\u01b6\u01b5\3\2\2\2\u01b6"+
- "\u01b7\3\2\2\2\u01b7\u01b8\3\2\2\2\u01b8\u01b9\5}?\2\u01b9|\3\2\2\2\u01ba"+
- "\u01c2\5\177@\2\u01bb\u01bd\5\u0081A\2\u01bc\u01bb\3\2\2\2\u01bd\u01c0"+
- "\3\2\2\2\u01be\u01bc\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf\u01c1\3\2\2\2\u01c0"+
- "\u01be\3\2\2\2\u01c1\u01c3\5\177@\2\u01c2\u01be\3\2\2\2\u01c2\u01c3\3"+
- "\2\2\2\u01c3~\3\2\2\2\u01c4\u01c5\t\6\2\2\u01c5\u0080\3\2\2\2\u01c6\u01c9"+
- "\5\177@\2\u01c7\u01c9\7a\2\2\u01c8\u01c6\3\2\2\2\u01c8\u01c7\3\2\2\2\u01c9"+
- "\u0082\3\2\2\2\u01ca\u01cb\7\62\2\2\u01cb\u01cc\t\7\2\2\u01cc\u01cd\5"+
- "\u0085C\2\u01cd\u0084\3\2\2\2\u01ce\u01d6\5\u0087D\2\u01cf\u01d1\5\u0089"+
- "E\2\u01d0\u01cf\3\2\2\2\u01d1\u01d4\3\2\2\2\u01d2\u01d0\3\2\2\2\u01d2"+
- "\u01d3\3\2\2\2\u01d3\u01d5\3\2\2\2\u01d4\u01d2\3\2\2\2\u01d5\u01d7\5\u0087"+
- "D\2\u01d6\u01d2\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u0086\3\2\2\2\u01d8"+
- "\u01d9\t\b\2\2\u01d9\u0088\3\2\2\2\u01da\u01dd\5\u0087D\2\u01db\u01dd"+
- "\7a\2\2\u01dc\u01da\3\2\2\2\u01dc\u01db\3\2\2\2\u01dd\u008a\3\2\2\2\u01de"+
- "\u01e1\5\u008dG\2\u01df\u01e1\5\u0099M\2\u01e0\u01de\3\2\2\2\u01e0\u01df"+
- "\3\2\2\2\u01e1\u008c\3\2\2\2\u01e2\u01e3\5i\65\2\u01e3\u01e5\7\60\2\2"+
- "\u01e4\u01e6\5i\65\2\u01e5\u01e4\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6\u01e8"+
- "\3\2\2\2\u01e7\u01e9\5\u008fH\2\u01e8\u01e7\3\2\2\2\u01e8\u01e9\3\2\2"+
- "\2\u01e9\u01eb\3\2\2\2\u01ea\u01ec\5\u0097L\2\u01eb\u01ea\3\2\2\2\u01eb"+
- "\u01ec\3\2\2\2\u01ec\u01fe\3\2\2\2\u01ed\u01ee\7\60\2\2\u01ee\u01f0\5"+
- "i\65\2\u01ef\u01f1\5\u008fH\2\u01f0\u01ef\3\2\2\2\u01f0\u01f1\3\2\2\2"+
- "\u01f1\u01f3\3\2\2\2\u01f2\u01f4\5\u0097L\2\u01f3\u01f2\3\2\2\2\u01f3"+
- "\u01f4\3\2\2\2\u01f4\u01fe\3\2\2\2\u01f5\u01f6\5i\65\2\u01f6\u01f8\5\u008f"+
- "H\2\u01f7\u01f9\5\u0097L\2\u01f8\u01f7\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9"+
- "\u01fe\3\2\2\2\u01fa\u01fb\5i\65\2\u01fb\u01fc\5\u0097L\2\u01fc\u01fe"+
- "\3\2\2\2\u01fd\u01e2\3\2\2\2\u01fd\u01ed\3\2\2\2\u01fd\u01f5\3\2\2\2\u01fd"+
- "\u01fa\3\2\2\2\u01fe\u008e\3\2\2\2\u01ff\u0200\5\u0091I\2\u0200\u0201"+
- "\5\u0093J\2\u0201\u0090\3\2\2\2\u0202\u0203\t\t\2\2\u0203\u0092\3\2\2"+
- "\2\u0204\u0206\5\u0095K\2\u0205\u0204\3\2\2\2\u0205\u0206\3\2\2\2\u0206"+
- "\u0207\3\2\2\2\u0207\u0208\5i\65\2\u0208\u0094\3\2\2\2\u0209\u020a\t\n"+
- "\2\2\u020a\u0096\3\2\2\2\u020b\u020c\t\13\2\2\u020c\u0098\3\2\2\2\u020d"+
- "\u020e\5\u009bN\2\u020e\u0210\5\u009dO\2\u020f\u0211\5\u0097L\2\u0210"+
- "\u020f\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u009a\3\2\2\2\u0212\u0214\5s"+
- ":\2\u0213\u0215\7\60\2\2\u0214\u0213\3\2\2\2\u0214\u0215\3\2\2\2\u0215"+
- "\u021e\3\2\2\2\u0216\u0217\7\62\2\2\u0217\u0219\t\4\2\2\u0218\u021a\5"+
- "u;\2\u0219\u0218\3\2\2\2\u0219\u021a\3\2\2\2\u021a\u021b\3\2\2\2\u021b"+
- "\u021c\7\60\2\2\u021c\u021e\5u;\2\u021d\u0212\3\2\2\2\u021d\u0216\3\2"+
- "\2\2\u021e\u009c\3\2\2\2\u021f\u0220\5\u009fP\2\u0220\u0221\5\u0093J\2"+
- "\u0221\u009e\3\2\2\2\u0222\u0223\t\f\2\2\u0223\u00a0\3\2\2\2\u0224\u0225"+
- "\7v\2\2\u0225\u0226\7t\2\2\u0226\u0227\7w\2\2\u0227\u022e\7g\2\2\u0228"+
- "\u0229\7h\2\2\u0229\u022a\7c\2\2\u022a\u022b\7n\2\2\u022b\u022c\7u\2\2"+
- "\u022c\u022e\7g\2\2\u022d\u0224\3\2\2\2\u022d\u0228\3\2\2\2\u022e\u00a2"+
- "\3\2\2\2\u022f\u0230\7)\2\2\u0230\u0231\5\u00a5S\2\u0231\u0232\7)\2\2"+
- "\u0232\u0238\3\2\2\2\u0233\u0234\7)\2\2\u0234\u0235\5\u00b1Y\2\u0235\u0236"+
- "\7)\2\2\u0236\u0238\3\2\2\2\u0237\u022f\3\2\2\2\u0237\u0233\3\2\2\2\u0238"+
- "\u00a4\3\2\2\2\u0239\u023a\n\r\2\2\u023a\u00a6\3\2\2\2\u023b\u023f\7b"+
- "\2\2\u023c\u023e\5\u00afX\2\u023d\u023c\3\2\2\2\u023e\u0241\3\2\2\2\u023f"+
- "\u023d\3\2\2\2\u023f\u0240\3\2\2\2\u0240\u0242\3\2\2\2\u0241\u023f\3\2"+
- "\2\2\u0242\u0243\7b\2\2\u0243\u00a8\3\2\2\2\u0244\u0246\7$\2\2\u0245\u0247"+
- "\5\u00abV\2\u0246\u0245\3\2\2\2\u0246\u0247\3\2\2\2\u0247\u0248\3\2\2"+
- "\2\u0248\u0249\7$\2\2\u0249\u00aa\3\2\2\2\u024a\u024c\5\u00adW\2\u024b"+
- "\u024a\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u024b\3\2\2\2\u024d\u024e\3\2"+
- "\2\2\u024e\u00ac\3\2\2\2\u024f\u0252\n\16\2\2\u0250\u0252\5\u00b1Y\2\u0251"+
- "\u024f\3\2\2\2\u0251\u0250\3\2\2\2\u0252\u00ae\3\2\2\2\u0253\u0256\n\17"+
- "\2\2\u0254\u0256\5\u00b1Y\2\u0255\u0253\3\2\2\2\u0255\u0254\3\2\2\2\u0256"+
- "\u00b0\3\2\2\2\u0257\u0258\7^\2\2\u0258\u025c\t\20\2\2\u0259\u025c\5\u00b3"+
- "Z\2\u025a\u025c\5\u00b5[\2\u025b\u0257\3\2\2\2\u025b\u0259\3\2\2\2\u025b"+
- "\u025a\3\2\2\2\u025c\u00b2\3\2\2\2\u025d\u025e\7^\2\2\u025e\u0269\5\177"+
- "@\2\u025f\u0260\7^\2\2\u0260\u0261\5\177@\2\u0261\u0262\5\177@\2\u0262"+
- "\u0269\3\2\2\2\u0263\u0264\7^\2\2\u0264\u0265\5\u00b7\\\2\u0265\u0266"+
- "\5\177@\2\u0266\u0267\5\177@\2\u0267\u0269\3\2\2\2\u0268\u025d\3\2\2\2"+
- "\u0268\u025f\3\2\2\2\u0268\u0263\3\2\2\2\u0269\u00b4\3\2\2\2\u026a\u026b"+
- "\7^\2\2\u026b\u026c\7w\2\2\u026c\u026d\5w<\2\u026d\u026e\5w<\2\u026e\u026f"+
- "\5w<\2\u026f\u0270\5w<\2\u0270\u00b6\3\2\2\2\u0271\u0272\t\21\2\2\u0272"+
- "\u00b8\3\2\2\2\u0273\u0274\7p\2\2\u0274\u0275\7w\2\2\u0275\u0276\7n\2"+
- "\2\u0276\u0277\7n\2\2\u0277\u00ba\3\2\2\2\u0278\u027c\5\u00bd_\2\u0279"+
- "\u027b\5\u00bf`\2\u027a\u0279\3\2\2\2\u027b\u027e\3\2\2\2\u027c\u027a"+
- "\3\2\2\2\u027c\u027d\3\2\2\2\u027d\u00bc\3\2\2\2\u027e\u027c\3\2\2\2\u027f"+
- "\u0286\t\22\2\2\u0280\u0281\n\23\2\2\u0281\u0286\6_\2\2\u0282\u0283\t"+
- "\24\2\2\u0283\u0284\t\25\2\2\u0284\u0286\6_\3\2\u0285\u027f\3\2\2\2\u0285"+
- "\u0280\3\2\2\2\u0285\u0282\3\2\2\2\u0286\u00be\3\2\2\2\u0287\u028e\t\26"+
- "\2\2\u0288\u0289\n\23\2\2\u0289\u028e\6`\4\2\u028a\u028b\t\24\2\2\u028b"+
- "\u028c\t\25\2\2\u028c\u028e\6`\5\2\u028d\u0287\3\2\2\2\u028d\u0288\3\2"+
- "\2\2\u028d\u028a\3\2\2\2\u028e\u00c0\3\2\2\2\u028f\u0291\t\27\2\2\u0290"+
- "\u028f\3\2\2\2\u0291\u0292\3\2\2\2\u0292\u0290\3\2\2\2\u0292\u0293\3\2"+
- "\2\2\u0293\u0294\3\2\2\2\u0294\u0295\ba\2\2\u0295\u00c2\3\2\2\2\u0296"+
- "\u029a\7B\2\2\u0297\u0298\5\u00c5c\2\u0298\u0299\7<\2\2\u0299\u029b\3"+
- "\2\2\2\u029a\u0297\3\2\2\2\u029a\u029b\3\2\2\2\u029b\u029c\3\2\2\2\u029c"+
- "\u029d\5\u00c7d\2\u029d\u029e\7\61\2\2\u029e\u029f\5\u00bb^\2\u029f\u00c4"+
- "\3\2\2\2\u02a0\u02a1\7c\2\2\u02a1\u02a2\7p\2\2\u02a2\u02a3\7f\2\2\u02a3"+
- "\u02a4\7t\2\2\u02a4\u02a5\7q\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a9\7f\2\2"+
- "\u02a7\u02a9\5\u00bb^\2\u02a8\u02a0\3\2\2\2\u02a8\u02a7\3\2\2\2\u02a9"+
- "\u00c6\3\2\2\2\u02aa\u02ab\7c\2\2\u02ab\u02ac\7p\2\2\u02ac\u02ad\7k\2"+
- "\2\u02ad\u0357\7o\2\2\u02ae\u02af\7c\2\2\u02af\u02b0\7p\2\2\u02b0\u02b1"+
- "\7k\2\2\u02b1\u02b2\7o\2\2\u02b2\u02b3\7c\2\2\u02b3\u02b4\7v\2\2\u02b4"+
- "\u02b5\7q\2\2\u02b5\u0357\7t\2\2\u02b6\u02b7\7d\2\2\u02b7\u02b8\7q\2\2"+
- "\u02b8\u02b9\7q\2\2\u02b9\u0357\7n\2\2\u02ba\u02bb\7e\2\2\u02bb\u02bc"+
- "\7q\2\2\u02bc\u02bd\7n\2\2\u02bd\u02be\7q\2\2\u02be\u0357\7t\2\2\u02bf"+
- "\u02c0\7e\2\2\u02c0\u02c1\7q\2\2\u02c1\u02c2\7n\2\2\u02c2\u02c3\7q\2\2"+
- "\u02c3\u02c4\7t\2\2\u02c4\u02c5\7U\2\2\u02c5\u02c6\7v\2\2\u02c6\u02c7"+
- "\7c\2\2\u02c7\u02c8\7v\2\2\u02c8\u02c9\7g\2\2\u02c9\u02ca\7N\2\2\u02ca"+
- "\u02cb\7k\2\2\u02cb\u02cc\7u\2\2\u02cc\u0357\7v\2\2\u02cd\u02ce\7f\2\2"+
- "\u02ce\u02cf\7k\2\2\u02cf\u02d0\7o\2\2\u02d0\u02d1\7g\2\2\u02d1\u0357"+
- "\7p\2\2\u02d2\u02d3\7f\2\2\u02d3\u02d4\7k\2\2\u02d4\u02d5\7o\2\2\u02d5"+
- "\u02d6\7g\2\2\u02d6\u02d7\7p\2\2\u02d7\u02d8\7Q\2\2\u02d8\u02d9\7h\2\2"+
- "\u02d9\u02da\7h\2\2\u02da\u02db\7u\2\2\u02db\u02dc\7g\2\2\u02dc\u0357"+
- "\7v\2\2\u02dd\u02de\7f\2\2\u02de\u02df\7k\2\2\u02df\u02e0\7o\2\2\u02e0"+
- "\u02e1\7g\2\2\u02e1\u02e2\7p\2\2\u02e2\u02e3\7U\2\2\u02e3\u02e4\7k\2\2"+
- "\u02e4\u02e5\7|\2\2\u02e5\u0357\7g\2\2\u02e6\u02e7\7f\2\2\u02e7\u02e8"+
- "\7t\2\2\u02e8\u02e9\7c\2\2\u02e9\u02ea\7y\2\2\u02ea\u02eb\7c\2\2\u02eb"+
- "\u02ec\7d\2\2\u02ec\u02ed\7n\2\2\u02ed\u0357\7g\2\2\u02ee\u02ef\7h\2\2"+
- "\u02ef\u02f0\7t\2\2\u02f0\u02f1\7c\2\2\u02f1\u02f2\7e\2\2\u02f2\u02f3"+
- "\7v\2\2\u02f3\u02f4\7k\2\2\u02f4\u02f5\7q\2\2\u02f5\u0357\7p\2\2\u02f6"+
- "\u02f7\7k\2\2\u02f7\u0357\7f\2\2\u02f8\u02f9\7k\2\2\u02f9\u02fa\7p\2\2"+
- "\u02fa\u02fb\7v\2\2\u02fb\u02fc\7g\2\2\u02fc\u02fd\7i\2\2\u02fd\u02fe"+
- "\7g\2\2\u02fe\u0357\7t\2\2\u02ff\u0300\7k\2\2\u0300\u0301\7p\2\2\u0301"+
- "\u0302\7v\2\2\u0302\u0303\7C\2\2\u0303\u0304\7t\2\2\u0304\u0305\7t\2\2"+
- "\u0305\u0306\7c\2\2\u0306\u0357\7{\2\2\u0307\u0308\7k\2\2\u0308\u0309"+
- "\7p\2\2\u0309\u030a\7v\2\2\u030a\u030b\7g\2\2\u030b\u030c\7t\2\2\u030c"+
- "\u030d\7r\2\2\u030d\u030e\7q\2\2\u030e\u030f\7n\2\2\u030f\u0310\7c\2\2"+
- "\u0310\u0311\7v\2\2\u0311\u0312\7q\2\2\u0312\u0357\7t\2\2\u0313\u0314"+
- "\7n\2\2\u0314\u0315\7c\2\2\u0315\u0316\7{\2\2\u0316\u0317\7q\2\2\u0317"+
- "\u0318\7w\2\2\u0318\u0357\7v\2\2\u0319\u031a\7r\2\2\u031a\u031b\7n\2\2"+
- "\u031b\u031c\7w\2\2\u031c\u031d\7t\2\2\u031d\u031e\7c\2\2\u031e\u031f"+
- "\7n\2\2\u031f\u0357\7u\2\2\u0320\u0321\7u\2\2\u0321\u0322\7v\2\2\u0322"+
- "\u0323\7c\2\2\u0323\u0324\7v\2\2\u0324\u0325\7g\2\2\u0325\u0326\7N\2\2"+
- "\u0326\u0327\7k\2\2\u0327\u0328\7u\2\2\u0328\u0329\7v\2\2\u0329\u032a"+
- "\7C\2\2\u032a\u032b\7p\2\2\u032b\u032c\7k\2\2\u032c\u032d\7o\2\2\u032d"+
- "\u032e\7c\2\2\u032e\u032f\7v\2\2\u032f\u0330\7q\2\2\u0330\u0357\7t\2\2"+
- "\u0331\u0332\7u\2\2\u0332\u0333\7v\2\2\u0333\u0334\7t\2\2\u0334\u0335"+
- "\7k\2\2\u0335\u0336\7p\2\2\u0336\u0357\7i\2\2\u0337\u0338\7u\2\2\u0338"+
- "\u0339\7v\2\2\u0339\u033a\7t\2\2\u033a\u033b\7k\2\2\u033b\u033c\7p\2\2"+
- "\u033c\u033d\7i\2\2\u033d\u033e\7C\2\2\u033e\u033f\7t\2\2\u033f\u0340"+
- "\7t\2\2\u0340\u0341\7c\2\2\u0341\u0357\7{\2\2\u0342\u0343\7v\2\2\u0343"+
- "\u0344\7t\2\2\u0344\u0345\7c\2\2\u0345\u0346\7p\2\2\u0346\u0347\7u\2\2"+
- "\u0347\u0348\7k\2\2\u0348\u0349\7v\2\2\u0349\u034a\7k\2\2\u034a\u034b"+
- "\7q\2\2\u034b\u0357\7p\2\2\u034c\u034d\7v\2\2\u034d\u034e\7{\2\2\u034e"+
- "\u034f\7r\2\2\u034f\u0350\7g\2\2\u0350\u0351\7f\2\2\u0351\u0352\7C\2\2"+
- "\u0352\u0353\7t\2\2\u0353\u0354\7t\2\2\u0354\u0355\7c\2\2\u0355\u0357"+
- "\7{\2\2\u0356\u02aa\3\2\2\2\u0356\u02ae\3\2\2\2\u0356\u02b6\3\2\2\2\u0356"+
- "\u02ba\3\2\2\2\u0356\u02bf\3\2\2\2\u0356\u02cd\3\2\2\2\u0356\u02d2\3\2"+
- "\2\2\u0356\u02dd\3\2\2\2\u0356\u02e6\3\2\2\2\u0356\u02ee\3\2\2\2\u0356"+
- "\u02f6\3\2\2\2\u0356\u02f8\3\2\2\2\u0356\u02ff\3\2\2\2\u0356\u0307\3\2"+
- "\2\2\u0356\u0313\3\2\2\2\u0356\u0319\3\2\2\2\u0356\u0320\3\2\2\2\u0356"+
- "\u0331\3\2\2\2\u0356\u0337\3\2\2\2\u0356\u0342\3\2\2\2\u0356\u034c\3\2"+
- "\2\2\u0357\u00c8\3\2\2\2\67\2\u0167\u016b\u016f\u0173\u0177\u017e\u0183"+
- "\u0185\u018b\u018f\u0193\u0199\u019e\u01a8\u01ac\u01b2\u01b6\u01be\u01c2"+
- "\u01c8\u01d2\u01d6\u01dc\u01e0\u01e5\u01e8\u01eb\u01f0\u01f3\u01f8\u01fd"+
- "\u0205\u0210\u0214\u0219\u021d\u022d\u0237\u023f\u0246\u024d\u0251\u0255"+
- "\u025b\u0268\u027c\u0285\u028d\u0292\u029a\u02a8\u0356\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\2g\3\3\5\4\7"+
+ "\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22"+
+ "#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C"+
+ "#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\2c\2e\2g\2i\2k\2m\2o\2q\2s\2u\2w\2"+
+ "y\2{\2}\2\177\2\u0081\2\u0083\2\u0085\2\u0087\2\u0089\2\u008b\2\u008d"+
+ "\2\u008f\62\u0091\2\u0093\2\u0095\2\u0097\2\u0099\2\u009b\2\u009d\2\u009f"+
+ "\2\u00a1\2\u00a3\2\u00a5\63\u00a7\64\u00a9\2\u00ab\65\u00ad\66\u00af\2"+
+ "\u00b1\2\u00b3\2\u00b5\2\u00b7\2\u00b9\2\u00bb\2\u00bd\67\u00bf8\u00c1"+
+ "\2\u00c3\2\u00c59\u00c7:\u00c9;\u00cb<\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\2"+
+ "RRrr\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\2"+
+ "O\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\7A\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\u0134J\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\7"+
+ "d\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\u0087D\2\u018e\u0190\5i\65\2\u018f\u018e\3\2\2\2\u018f"+
+ "\u0190\3\2\2\2\u0190h\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\u01acp\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\u009d"+
+ "O\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\5m\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\u009b"+
+ "N\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\u0097L\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\u00afX\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\u0083B\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\7"+
+ "p\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\6"+
+ "b\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\u00c9"+
+ "e\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 {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
}
} \ No newline at end of file
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 d9d10353..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,61 +41,64 @@ T__39=40
T__40=41
T__41=42
T__42=43
-THIS=44
-IntegerLiteral=45
-FloatingPointLiteral=46
-BooleanLiteral=47
-CharacterLiteral=48
-SingleQuoteString=49
-DoubleQuoteString=50
-NullLiteral=51
-Identifier=52
-WS=53
-ResourceReference=54
-PackageName=55
-ResourceType=56
+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
-'('=4
-')'=5
-'.'=6
-'['=7
-']'=8
-'+'=9
-'-'=10
-'~'=11
-'!'=12
-'*'=13
-'/'=14
-'%'=15
-'<<'=16
-'>>>'=17
-'>>'=18
-'<='=19
-'>='=20
-'>'=21
-'<'=22
-'instanceof'=23
-'=='=24
-'!='=25
-'&'=26
-'^'=27
-'|'=28
-'&&'=29
-'||'=30
-'?'=31
-':'=32
-'??'=33
-'class'=34
-'void'=35
-'boolean'=36
-'char'=37
-'byte'=38
-'short'=39
-'int'=40
-'long'=41
-'float'=42
-'double'=43
-'this'=44
-'null'=51
+'->'=4
+'('=5
+')'=6
+'.'=7
+'::'=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 acd4c225..23d2d84b 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionListener.java
@@ -1,7 +1,5 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeListener;
/**
@@ -10,419 +8,445 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
*/
public interface BindingExpressionListener extends ParseTreeListener {
/**
- * Enter a parse tree produced by the {@code BracketOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Enter a parse tree produced by the {@code RootExpr}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
*/
- void enterBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx);
+ void enterRootExpr(BindingExpressionParser.RootExprContext ctx);
/**
- * Exit a parse tree produced by the {@code BracketOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Exit a parse tree produced by the {@code RootExpr}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
*/
- void exitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx);
-
+ void exitRootExpr(BindingExpressionParser.RootExprContext ctx);
/**
- * Enter a parse tree produced by the {@code Resource}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Enter a parse tree produced by the {@code RootLambda}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
*/
- void enterResource(@NotNull BindingExpressionParser.ResourceContext ctx);
+ void enterRootLambda(BindingExpressionParser.RootLambdaContext ctx);
/**
- * Exit a parse tree produced by the {@code Resource}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Exit a parse tree produced by the {@code RootLambda}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
*/
- void exitResource(@NotNull BindingExpressionParser.ResourceContext ctx);
-
+ void exitRootLambda(BindingExpressionParser.RootLambdaContext ctx);
/**
- * Enter a parse tree produced by the {@code CastOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Enter a parse tree produced by {@link BindingExpressionParser#defaults}.
* @param ctx the parse tree
*/
- void enterCastOp(@NotNull BindingExpressionParser.CastOpContext ctx);
+ void enterDefaults(BindingExpressionParser.DefaultsContext ctx);
/**
- * Exit a parse tree produced by the {@code CastOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Exit a parse tree produced by {@link BindingExpressionParser#defaults}.
* @param ctx the parse tree
*/
- void exitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx);
-
+ void exitDefaults(BindingExpressionParser.DefaultsContext ctx);
/**
- * Enter a parse tree produced by the {@code UnaryOp}
+ * Enter a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * @param ctx the parse tree
+ */
+ void enterConstantValue(BindingExpressionParser.ConstantValueContext ctx);
+ /**
+ * Exit a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * @param ctx the parse tree
+ */
+ void exitConstantValue(BindingExpressionParser.ConstantValueContext ctx);
+ /**
+ * Enter a parse tree produced by {@link BindingExpressionParser#lambdaExpression}.
+ * @param ctx the parse tree
+ */
+ void enterLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link BindingExpressionParser#lambdaExpression}.
+ * @param ctx the parse tree
+ */
+ void exitLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code SingleLambdaParameter}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ */
+ void enterSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code SingleLambdaParameter}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ */
+ void exitSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code LambdaParameterList}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ */
+ void enterLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx);
+ /**
+ * Exit a parse tree produced by the {@code LambdaParameterList}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ */
+ void exitLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx);
+ /**
+ * Enter a parse tree produced by {@link BindingExpressionParser#inferredFormalParameterList}.
+ * @param ctx the parse tree
+ */
+ void enterInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx);
+ /**
+ * Exit a parse tree produced by {@link BindingExpressionParser#inferredFormalParameterList}.
+ * @param ctx the parse tree
+ */
+ void exitInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx);
+ /**
+ * Enter a parse tree produced by the {@code CastOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx);
+ void enterCastOp(BindingExpressionParser.CastOpContext ctx);
/**
- * Exit a parse tree produced by the {@code UnaryOp}
+ * Exit a parse tree produced by the {@code CastOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx);
-
+ void exitCastOp(BindingExpressionParser.CastOpContext ctx);
/**
- * Enter a parse tree produced by the {@code AndOrOp}
+ * Enter a parse tree produced by the {@code ComparisonOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx);
+ void enterComparisonOp(BindingExpressionParser.ComparisonOpContext ctx);
/**
- * Exit a parse tree produced by the {@code AndOrOp}
+ * Exit a parse tree produced by the {@code ComparisonOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx);
-
+ void exitComparisonOp(BindingExpressionParser.ComparisonOpContext ctx);
/**
- * Enter a parse tree produced by the {@code MethodInvocation}
+ * Enter a parse tree produced by the {@code UnaryOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx);
+ void enterUnaryOp(BindingExpressionParser.UnaryOpContext ctx);
/**
- * Exit a parse tree produced by the {@code MethodInvocation}
+ * Exit a parse tree produced by the {@code UnaryOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx);
-
+ void exitUnaryOp(BindingExpressionParser.UnaryOpContext ctx);
/**
- * Enter a parse tree produced by the {@code Primary}
+ * Enter a parse tree produced by the {@code BracketOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx);
+ void enterBracketOp(BindingExpressionParser.BracketOpContext ctx);
/**
- * Exit a parse tree produced by the {@code Primary}
+ * Exit a parse tree produced by the {@code BracketOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx);
-
+ void exitBracketOp(BindingExpressionParser.BracketOpContext ctx);
/**
- * Enter a parse tree produced by the {@code Grouping}
+ * Enter a parse tree produced by the {@code Resource}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterGrouping(@NotNull BindingExpressionParser.GroupingContext ctx);
+ void enterResource(BindingExpressionParser.ResourceContext ctx);
/**
- * Exit a parse tree produced by the {@code Grouping}
+ * Exit a parse tree produced by the {@code Resource}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx);
-
+ void exitResource(BindingExpressionParser.ResourceContext ctx);
/**
- * Enter a parse tree produced by the {@code TernaryOp}
+ * Enter a parse tree produced by the {@code QuestionQuestionOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx);
+ void enterQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx);
/**
- * Exit a parse tree produced by the {@code TernaryOp}
+ * Exit a parse tree produced by the {@code QuestionQuestionOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx);
-
+ void exitQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx);
/**
- * Enter a parse tree produced by the {@code ComparisonOp}
+ * Enter a parse tree produced by the {@code Grouping}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx);
+ void enterGrouping(BindingExpressionParser.GroupingContext ctx);
/**
- * Exit a parse tree produced by the {@code ComparisonOp}
+ * Exit a parse tree produced by the {@code Grouping}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx);
-
+ void exitGrouping(BindingExpressionParser.GroupingContext ctx);
/**
- * Enter a parse tree produced by the {@code DotOp}
+ * Enter a parse tree produced by the {@code MethodInvocation}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterDotOp(@NotNull BindingExpressionParser.DotOpContext ctx);
+ void enterMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx);
/**
- * Exit a parse tree produced by the {@code DotOp}
+ * Exit a parse tree produced by the {@code MethodInvocation}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx);
-
+ void exitMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx);
/**
- * Enter a parse tree produced by the {@code MathOp}
+ * Enter a parse tree produced by the {@code BitShiftOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterMathOp(@NotNull BindingExpressionParser.MathOpContext ctx);
+ void enterBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx);
/**
- * Exit a parse tree produced by the {@code MathOp}
+ * Exit a parse tree produced by the {@code BitShiftOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx);
-
+ void exitBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx);
/**
- * Enter a parse tree produced by the {@code QuestionQuestionOp}
+ * Enter a parse tree produced by the {@code AndOrOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx);
+ void enterAndOrOp(BindingExpressionParser.AndOrOpContext ctx);
/**
- * Exit a parse tree produced by the {@code QuestionQuestionOp}
+ * Exit a parse tree produced by the {@code AndOrOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx);
-
+ void exitAndOrOp(BindingExpressionParser.AndOrOpContext ctx);
/**
- * Enter a parse tree produced by the {@code BitShiftOp}
+ * Enter a parse tree produced by the {@code TernaryOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx);
+ void enterTernaryOp(BindingExpressionParser.TernaryOpContext ctx);
/**
- * Exit a parse tree produced by the {@code BitShiftOp}
+ * Exit a parse tree produced by the {@code TernaryOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx);
-
+ void exitTernaryOp(BindingExpressionParser.TernaryOpContext ctx);
/**
- * Enter a parse tree produced by the {@code InstanceOfOp}
+ * Enter a parse tree produced by the {@code Primary}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx);
+ void enterPrimary(BindingExpressionParser.PrimaryContext ctx);
/**
- * Exit a parse tree produced by the {@code InstanceOfOp}
+ * Exit a parse tree produced by the {@code Primary}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx);
-
+ void exitPrimary(BindingExpressionParser.PrimaryContext ctx);
/**
- * Enter a parse tree produced by the {@code BinaryOp}
+ * Enter a parse tree produced by the {@code DotOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx);
+ void enterDotOp(BindingExpressionParser.DotOpContext ctx);
/**
- * Exit a parse tree produced by the {@code BinaryOp}
+ * Exit a parse tree produced by the {@code DotOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx);
-
+ void exitDotOp(BindingExpressionParser.DotOpContext ctx);
/**
- * Enter a parse tree produced by {@link BindingExpressionParser#bindingSyntax}.
+ * Enter a parse tree produced by the {@code MathOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx);
+ void enterMathOp(BindingExpressionParser.MathOpContext ctx);
/**
- * Exit a parse tree produced by {@link BindingExpressionParser#bindingSyntax}.
+ * Exit a parse tree produced by the {@code MathOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx);
-
+ void exitMathOp(BindingExpressionParser.MathOpContext ctx);
/**
- * Enter a parse tree produced by {@link BindingExpressionParser#defaults}.
+ * Enter a parse tree produced by the {@code InstanceOfOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx);
+ void enterInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx);
/**
- * Exit a parse tree produced by {@link BindingExpressionParser#defaults}.
+ * Exit a parse tree produced by the {@code InstanceOfOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx);
-
+ void exitInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx);
/**
- * Enter a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * Enter a parse tree produced by the {@code BinaryOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx);
+ void enterBinaryOp(BindingExpressionParser.BinaryOpContext ctx);
/**
- * Exit a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * Exit a parse tree produced by the {@code BinaryOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx);
-
+ void exitBinaryOp(BindingExpressionParser.BinaryOpContext ctx);
/**
- * Enter a parse tree produced by {@link BindingExpressionParser#expression}.
+ * Enter a parse tree produced by the {@code FunctionRef}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void enterExpression(@NotNull BindingExpressionParser.ExpressionContext ctx);
+ void enterFunctionRef(BindingExpressionParser.FunctionRefContext ctx);
/**
- * Exit a parse tree produced by {@link BindingExpressionParser#expression}.
+ * Exit a parse tree produced by the {@code FunctionRef}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
*/
- void exitExpression(@NotNull BindingExpressionParser.ExpressionContext ctx);
-
+ void exitFunctionRef(BindingExpressionParser.FunctionRefContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#classExtraction}.
* @param ctx the parse tree
*/
- void enterClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx);
+ void enterClassExtraction(BindingExpressionParser.ClassExtractionContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#classExtraction}.
* @param ctx the parse tree
*/
- void exitClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx);
-
+ void exitClassExtraction(BindingExpressionParser.ClassExtractionContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#expressionList}.
* @param ctx the parse tree
*/
- void enterExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx);
+ void enterExpressionList(BindingExpressionParser.ExpressionListContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#expressionList}.
* @param ctx the parse tree
*/
- void exitExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx);
-
+ void exitExpressionList(BindingExpressionParser.ExpressionListContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#literal}.
* @param ctx the parse tree
*/
- void enterLiteral(@NotNull BindingExpressionParser.LiteralContext ctx);
+ void enterLiteral(BindingExpressionParser.LiteralContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#literal}.
* @param ctx the parse tree
*/
- void exitLiteral(@NotNull BindingExpressionParser.LiteralContext ctx);
-
+ void exitLiteral(BindingExpressionParser.LiteralContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#identifier}.
* @param ctx the parse tree
*/
- void enterIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx);
+ void enterIdentifier(BindingExpressionParser.IdentifierContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#identifier}.
* @param ctx the parse tree
*/
- void exitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx);
-
+ void exitIdentifier(BindingExpressionParser.IdentifierContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#javaLiteral}.
* @param ctx the parse tree
*/
- void enterJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx);
+ void enterJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#javaLiteral}.
* @param ctx the parse tree
*/
- void exitJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx);
-
+ void exitJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#stringLiteral}.
* @param ctx the parse tree
*/
- void enterStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx);
+ void enterStringLiteral(BindingExpressionParser.StringLiteralContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#stringLiteral}.
* @param ctx the parse tree
*/
- void exitStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx);
-
+ void exitStringLiteral(BindingExpressionParser.StringLiteralContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocation}.
* @param ctx the parse tree
*/
- void enterExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx);
+ void enterExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocation}.
* @param ctx the parse tree
*/
- void exitExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx);
-
+ void exitExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#typeArguments}.
* @param ctx the parse tree
*/
- void enterTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx);
+ void enterTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#typeArguments}.
* @param ctx the parse tree
*/
- void exitTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx);
-
+ void exitTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#type}.
* @param ctx the parse tree
*/
- void enterType(@NotNull BindingExpressionParser.TypeContext ctx);
+ void enterType(BindingExpressionParser.TypeContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#type}.
* @param ctx the parse tree
*/
- void exitType(@NotNull BindingExpressionParser.TypeContext ctx);
-
+ void exitType(BindingExpressionParser.TypeContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocationSuffix}.
* @param ctx the parse tree
*/
- void enterExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
+ void enterExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocationSuffix}.
* @param ctx the parse tree
*/
- void exitExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
-
+ void exitExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#arguments}.
* @param ctx the parse tree
*/
- void enterArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx);
+ void enterArguments(BindingExpressionParser.ArgumentsContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#arguments}.
* @param ctx the parse tree
*/
- void exitArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx);
-
+ void exitArguments(BindingExpressionParser.ArgumentsContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#classOrInterfaceType}.
* @param ctx the parse tree
*/
- void enterClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
+ void enterClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#classOrInterfaceType}.
* @param ctx the parse tree
*/
- void exitClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
-
+ void exitClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#primitiveType}.
* @param ctx the parse tree
*/
- void enterPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx);
+ void enterPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#primitiveType}.
* @param ctx the parse tree
*/
- void exitPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx);
-
+ void exitPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#resources}.
* @param ctx the parse tree
*/
- void enterResources(@NotNull BindingExpressionParser.ResourcesContext ctx);
+ void enterResources(BindingExpressionParser.ResourcesContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#resources}.
* @param ctx the parse tree
*/
- void exitResources(@NotNull BindingExpressionParser.ResourcesContext ctx);
-
+ void exitResources(BindingExpressionParser.ResourcesContext ctx);
/**
* Enter a parse tree produced by {@link BindingExpressionParser#resourceParameters}.
* @param ctx the parse tree
*/
- void enterResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx);
+ void enterResourceParameters(BindingExpressionParser.ResourceParametersContext ctx);
/**
* Exit a parse tree produced by {@link BindingExpressionParser#resourceParameters}.
* @param ctx the parse tree
*/
- void exitResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx);
+ void exitResourceParameters(BindingExpressionParser.ResourceParametersContext ctx);
} \ No newline at end of file
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 b469d2d4..9633908f 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionParser.java
@@ -1,4 +1,4 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
@@ -9,47 +9,55 @@ import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class BindingExpressionParser extends Parser {
+ static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
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, IntegerLiteral=45,
- FloatingPointLiteral=46, BooleanLiteral=47, CharacterLiteral=48, SingleQuoteString=49,
- DoubleQuoteString=50, NullLiteral=51, Identifier=52, WS=53, ResourceReference=54,
- PackageName=55, ResourceType=56;
+ 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_expression = 3,
- RULE_classExtraction = 4, RULE_expressionList = 5, RULE_literal = 6, RULE_identifier = 7,
- RULE_javaLiteral = 8, RULE_stringLiteral = 9, RULE_explicitGenericInvocation = 10,
- RULE_typeArguments = 11, RULE_type = 12, RULE_explicitGenericInvocationSuffix = 13,
- RULE_arguments = 14, RULE_classOrInterfaceType = 15, RULE_primitiveType = 16,
- RULE_resources = 17, RULE_resourceParameters = 18;
+ RULE_bindingSyntax = 0, RULE_defaults = 1, RULE_constantValue = 2, RULE_lambdaExpression = 3,
+ RULE_lambdaParameters = 4, RULE_inferredFormalParameterList = 5, RULE_expression = 6,
+ RULE_classExtraction = 7, RULE_expressionList = 8, RULE_literal = 9, RULE_identifier = 10,
+ RULE_javaLiteral = 11, RULE_stringLiteral = 12, RULE_explicitGenericInvocation = 13,
+ RULE_typeArguments = 14, RULE_type = 15, RULE_explicitGenericInvocationSuffix = 16,
+ RULE_arguments = 17, RULE_classOrInterfaceType = 18, RULE_primitiveType = 19,
+ RULE_resources = 20, RULE_resourceParameters = 21;
public static final String[] ruleNames = {
- "bindingSyntax", "defaults", "constantValue", "expression", "classExtraction",
- "expressionList", "literal", "identifier", "javaLiteral", "stringLiteral",
- "explicitGenericInvocation", "typeArguments", "type", "explicitGenericInvocationSuffix",
- "arguments", "classOrInterfaceType", "primitiveType", "resources", "resourceParameters"
+ "bindingSyntax", "defaults", "constantValue", "lambdaExpression", "lambdaParameters",
+ "inferredFormalParameterList", "expression", "classExtraction", "expressionList",
+ "literal", "identifier", "javaLiteral", "stringLiteral", "explicitGenericInvocation",
+ "typeArguments", "type", "explicitGenericInvocationSuffix", "arguments",
+ "classOrInterfaceType", "primitiveType", "resources", "resourceParameters"
};
private static final String[] _LITERAL_NAMES = {
- null, "','", "'default'", "'='", "'('", "')'", "'.'", "'['", "']'", "'+'",
- "'-'", "'~'", "'!'", "'*'", "'/'", "'%'", "'<<'", "'>>>'", "'>>'", "'<='",
- "'>='", "'>'", "'<'", "'instanceof'", "'=='", "'!='", "'&'", "'^'", "'|'",
- "'&&'", "'||'", "'?'", "':'", "'??'", "'class'", "'void'", "'boolean'",
- "'char'", "'byte'", "'short'", "'int'", "'long'", "'float'", "'double'",
- "'this'", 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", "IntegerLiteral",
- "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral", "SingleQuoteString",
- "DoubleQuoteString", "NullLiteral", "Identifier", "WS", "ResourceReference",
- "PackageName", "ResourceType"
+ null, null, null, null, null, null, null, null, null, "THIS", "VoidLiteral",
+ "IntegerLiteral", "FloatingPointLiteral", "BooleanLiteral", "CharacterLiteral",
+ "SingleQuoteString", "DoubleQuoteString", "NullLiteral", "Identifier",
+ "WS", "ResourceReference", "PackageName", "ResourceType"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@@ -79,7 +87,7 @@ public class BindingExpressionParser extends Parser {
}
@Override
- @NotNull
+
public Vocabulary getVocabulary() {
return VOCABULARY;
}
@@ -93,55 +101,99 @@ public class BindingExpressionParser extends Parser {
@Override
public String getSerializedATN() { return _serializedATN; }
+ @Override
+ public ATN getATN() { return _ATN; }
+
public BindingExpressionParser(TokenStream input) {
super(input);
- _interp = new ParserATNSimulator(this,_ATN);
+ _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
public static class BindingSyntaxContext extends ParserRuleContext {
+ public BindingSyntaxContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_bindingSyntax; }
+
+ public BindingSyntaxContext() { }
+ public void copyFrom(BindingSyntaxContext ctx) {
+ super.copyFrom(ctx);
+ }
+ }
+ public static class RootExprContext extends BindingSyntaxContext {
public ExpressionContext expression() {
return getRuleContext(ExpressionContext.class,0);
}
public DefaultsContext defaults() {
return getRuleContext(DefaultsContext.class,0);
}
- public BindingSyntaxContext(ParserRuleContext parent, int invokingState) {
- super(parent, invokingState);
+ public RootExprContext(BindingSyntaxContext ctx) { copyFrom(ctx); }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterRootExpr(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitRootExpr(this);
}
- @Override public int getRuleIndex() { return RULE_bindingSyntax; }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitRootExpr(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class RootLambdaContext extends BindingSyntaxContext {
+ public LambdaExpressionContext lambdaExpression() {
+ return getRuleContext(LambdaExpressionContext.class,0);
+ }
+ public RootLambdaContext(BindingSyntaxContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBindingSyntax(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterRootLambda(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBindingSyntax(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitRootLambda(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBindingSyntax(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitRootLambda(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final BindingSyntaxContext bindingSyntax() throws RecognitionException {
BindingSyntaxContext _localctx = new BindingSyntaxContext(_ctx, getState());
enterRule(_localctx, 0, RULE_bindingSyntax);
int _la;
try {
- enterOuterAlt(_localctx, 1);
- {
- setState(38);
- expression(0);
- setState(40);
- _la = _input.LA(1);
- if (_la==T__0) {
+ setState(49);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
+ case 1:
+ _localctx = new RootExprContext(_localctx);
+ enterOuterAlt(_localctx, 1);
{
- setState(39);
- defaults();
+ setState(44);
+ expression(0);
+ setState(46);
+ _la = _input.LA(1);
+ if (_la==T__0) {
+ {
+ setState(45);
+ defaults();
+ }
}
- }
+ }
+ break;
+ case 2:
+ _localctx = new RootLambdaContext(_localctx);
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(48);
+ lambdaExpression();
+ }
+ break;
}
}
catch (RecognitionException re) {
@@ -172,26 +224,25 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitDefaults(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitDefaults(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitDefaults(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final DefaultsContext defaults() throws RecognitionException {
DefaultsContext _localctx = new DefaultsContext(_ctx, getState());
enterRule(_localctx, 2, RULE_defaults);
try {
enterOuterAlt(_localctx, 1);
{
- setState(42);
+ setState(51);
match(T__0);
- setState(43);
+ setState(52);
match(T__1);
- setState(44);
+ setState(53);
match(T__2);
- setState(45);
+ setState(54);
constantValue();
}
}
@@ -227,18 +278,17 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitConstantValue(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitConstantValue(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitConstantValue(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ConstantValueContext constantValue() throws RecognitionException {
ConstantValueContext _localctx = new ConstantValueContext(_ctx, getState());
enterRule(_localctx, 4, RULE_constantValue);
try {
- setState(50);
+ setState(59);
switch (_input.LA(1)) {
case IntegerLiteral:
case FloatingPointLiteral:
@@ -249,21 +299,21 @@ public class BindingExpressionParser extends Parser {
case NullLiteral:
enterOuterAlt(_localctx, 1);
{
- setState(47);
+ setState(56);
literal();
}
break;
case ResourceReference:
enterOuterAlt(_localctx, 2);
{
- setState(48);
+ setState(57);
match(ResourceReference);
}
break;
case Identifier:
enterOuterAlt(_localctx, 3);
{
- setState(49);
+ setState(58);
identifier();
}
break;
@@ -282,58 +332,230 @@ public class BindingExpressionParser extends Parser {
return _localctx;
}
- public static class ExpressionContext extends ParserRuleContext {
- public ExpressionContext(ParserRuleContext parent, int invokingState) {
+ public static class LambdaExpressionContext extends ParserRuleContext {
+ public LambdaParametersContext args;
+ public ExpressionContext expr;
+ public LambdaParametersContext lambdaParameters() {
+ return getRuleContext(LambdaParametersContext.class,0);
+ }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public LambdaExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
- @Override public int getRuleIndex() { return RULE_expression; }
+ @Override public int getRuleIndex() { return RULE_lambdaExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterLambdaExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitLambdaExpression(this);
+ }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitLambdaExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final LambdaExpressionContext lambdaExpression() throws RecognitionException {
+ LambdaExpressionContext _localctx = new LambdaExpressionContext(_ctx, getState());
+ enterRule(_localctx, 6, RULE_lambdaExpression);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(61);
+ ((LambdaExpressionContext)_localctx).args = lambdaParameters();
+ setState(62);
+ match(T__3);
+ setState(63);
+ ((LambdaExpressionContext)_localctx).expr = expression(0);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class LambdaParametersContext extends ParserRuleContext {
+ public LambdaParametersContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_lambdaParameters; }
- public ExpressionContext() { }
- public void copyFrom(ExpressionContext ctx) {
+ public LambdaParametersContext() { }
+ public void copyFrom(LambdaParametersContext ctx) {
super.copyFrom(ctx);
}
}
- public static class BracketOpContext extends ExpressionContext {
- public List<? extends ExpressionContext> expression() {
- return getRuleContexts(ExpressionContext.class);
+ 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).enterSingleLambdaParameter(this);
}
- public ExpressionContext expression(int i) {
- return getRuleContext(ExpressionContext.class,i);
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitSingleLambdaParameter(this);
}
- public BracketOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitSingleLambdaParameter(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ 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).enterBracketOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterLambdaParameterList(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBracketOp(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).visitBracketOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitLambdaParameterList(this);
else return visitor.visitChildren(this);
}
}
- public static class ResourceContext extends ExpressionContext {
- public ResourcesContext resources() {
- return getRuleContext(ResourcesContext.class,0);
+
+ public final LambdaParametersContext lambdaParameters() throws RecognitionException {
+ LambdaParametersContext _localctx = new LambdaParametersContext(_ctx, getState());
+ enterRule(_localctx, 8, RULE_lambdaParameters);
+ int _la;
+ try {
+ setState(71);
+ switch (_input.LA(1)) {
+ case Identifier:
+ _localctx = new SingleLambdaParameterContext(_localctx);
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(65);
+ match(Identifier);
+ }
+ break;
+ case T__4:
+ _localctx = new LambdaParameterListContext(_localctx);
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(66);
+ match(T__4);
+ setState(68);
+ _la = _input.LA(1);
+ if (_la==Identifier) {
+ {
+ setState(67);
+ ((LambdaParameterListContext)_localctx).params = inferredFormalParameterList();
+ }
+ }
+
+ setState(70);
+ match(T__5);
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
}
- public ResourceContext(ExpressionContext ctx) { copyFrom(ctx); }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class InferredFormalParameterListContext extends ParserRuleContext {
+ public List<TerminalNode> Identifier() { return getTokens(BindingExpressionParser.Identifier); }
+ public TerminalNode Identifier(int i) {
+ return getToken(BindingExpressionParser.Identifier, i);
+ }
+ public InferredFormalParameterListContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_inferredFormalParameterList; }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterResource(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterInferredFormalParameterList(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitResource(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitInferredFormalParameterList(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitResource(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitInferredFormalParameterList(this);
else return visitor.visitChildren(this);
}
}
+
+ public final InferredFormalParameterListContext inferredFormalParameterList() throws RecognitionException {
+ InferredFormalParameterListContext _localctx = new InferredFormalParameterListContext(_ctx, getState());
+ enterRule(_localctx, 10, RULE_inferredFormalParameterList);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(73);
+ match(Identifier);
+ setState(78);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==T__0) {
+ {
+ {
+ setState(74);
+ match(T__0);
+ setState(75);
+ match(Identifier);
+ }
+ }
+ setState(80);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class ExpressionContext extends ParserRuleContext {
+ public ExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_expression; }
+
+ public ExpressionContext() { }
+ public void copyFrom(ExpressionContext ctx) {
+ super.copyFrom(ctx);
+ }
+ }
public static class CastOpContext extends ExpressionContext {
public TypeContext type() {
return getRuleContext(TypeContext.class,0);
@@ -351,8 +573,33 @@ public class BindingExpressionParser extends Parser {
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).visitCastOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitCastOp(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ComparisonOpContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List<ExpressionContext> expression() {
+ return getRuleContexts(ExpressionContext.class);
+ }
+ 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).enterComparisonOp(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitComparisonOp(this);
+ }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitComparisonOp(this);
else return visitor.visitChildren(this);
}
}
@@ -371,84 +618,74 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitUnaryOp(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitUnaryOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitUnaryOp(this);
else return visitor.visitChildren(this);
}
}
- public static class AndOrOpContext extends ExpressionContext {
- public ExpressionContext left;
- public Token op;
- public ExpressionContext right;
- public List<? extends ExpressionContext> expression() {
+ public static class BracketOpContext extends ExpressionContext {
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
return getRuleContext(ExpressionContext.class,i);
}
- public AndOrOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public BracketOpContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterAndOrOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBracketOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitAndOrOp(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).visitAndOrOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitBracketOp(this);
else return visitor.visitChildren(this);
}
}
- public static class MethodInvocationContext extends ExpressionContext {
- public ExpressionContext target;
- public Token methodName;
- public ExpressionListContext args;
- public ExpressionContext expression() {
- return getRuleContext(ExpressionContext.class,0);
- }
- public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); }
- public ExpressionListContext expressionList() {
- return getRuleContext(ExpressionListContext.class,0);
+ public static class ResourceContext extends ExpressionContext {
+ public ResourcesContext resources() {
+ return getRuleContext(ResourcesContext.class,0);
}
- public MethodInvocationContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public ResourceContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterMethodInvocation(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterResource(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitMethodInvocation(this);
+ 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).visitMethodInvocation(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitResource(this);
else return visitor.visitChildren(this);
}
}
- public static class PrimaryContext extends ExpressionContext {
- public LiteralContext literal() {
- return getRuleContext(LiteralContext.class,0);
- }
- public IdentifierContext identifier() {
- return getRuleContext(IdentifierContext.class,0);
+ public static class QuestionQuestionOpContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List<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 QuestionQuestionOpContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterPrimary(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterQuestionQuestionOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitPrimary(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).visitPrimary(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitQuestionQuestionOp(this);
else return visitor.visitChildren(this);
}
}
@@ -466,154 +703,181 @@ public class BindingExpressionParser extends Parser {
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);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitGrouping(this);
else return visitor.visitChildren(this);
}
}
- public static class TernaryOpContext extends ExpressionContext {
- public ExpressionContext left;
- public Token op;
- public ExpressionContext iftrue;
- public ExpressionContext iffalse;
- public List<? extends ExpressionContext> expression() {
- return getRuleContexts(ExpressionContext.class);
+ public static class MethodInvocationContext extends ExpressionContext {
+ public ExpressionContext target;
+ public Token methodName;
+ public ExpressionListContext args;
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
}
- public ExpressionContext expression(int i) {
- return getRuleContext(ExpressionContext.class,i);
+ public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); }
+ public ExpressionListContext expressionList() {
+ return getRuleContext(ExpressionListContext.class,0);
}
- public TernaryOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public MethodInvocationContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterTernaryOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterMethodInvocation(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitTernaryOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitMethodInvocation(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitTernaryOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitMethodInvocation(this);
else return visitor.visitChildren(this);
}
}
- public static class ComparisonOpContext extends ExpressionContext {
+ public static class BitShiftOpContext extends ExpressionContext {
public ExpressionContext left;
public Token op;
public ExpressionContext right;
- public List<? extends ExpressionContext> expression() {
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
return getRuleContext(ExpressionContext.class,i);
}
- public ComparisonOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public BitShiftOpContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterComparisonOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBitShiftOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitComparisonOp(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).visitComparisonOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitBitShiftOp(this);
else return visitor.visitChildren(this);
}
}
- public static class DotOpContext 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<ExpressionContext> expression() {
+ return getRuleContexts(ExpressionContext.class);
}
- public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); }
- public DotOpContext(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).enterDotOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterAndOrOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitDotOp(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).visitDotOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitAndOrOp(this);
else return visitor.visitChildren(this);
}
}
- public static class MathOpContext extends ExpressionContext {
+ public static class TernaryOpContext extends ExpressionContext {
public ExpressionContext left;
public Token op;
- public ExpressionContext right;
- public List<? extends ExpressionContext> expression() {
+ public ExpressionContext iftrue;
+ public ExpressionContext iffalse;
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
return getRuleContext(ExpressionContext.class,i);
}
- public MathOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public TernaryOpContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterMathOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterTernaryOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitMathOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitTernaryOp(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitMathOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitTernaryOp(this);
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 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 QuestionQuestionOpContext(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).enterQuestionQuestionOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterPrimary(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitQuestionQuestionOp(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).visitQuestionQuestionOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitPrimary(this);
else return visitor.visitChildren(this);
}
}
- public static class BitShiftOpContext extends ExpressionContext {
+ public static class DotOpContext extends ExpressionContext {
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public TerminalNode Identifier() { return getToken(BindingExpressionParser.Identifier, 0); }
+ public DotOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterDotOp(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitDotOp(this);
+ }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitDotOp(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class MathOpContext extends ExpressionContext {
public ExpressionContext left;
public Token op;
public ExpressionContext right;
- public List<? extends ExpressionContext> expression() {
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
return getRuleContext(ExpressionContext.class,i);
}
- public BitShiftOpContext(ExpressionContext ctx) { copyFrom(ctx); }
+ public MathOpContext(ExpressionContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterBitShiftOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).enterMathOp(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
- if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBitShiftOp(this);
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitMathOp(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBitShiftOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitMathOp(this);
else return visitor.visitChildren(this);
}
}
@@ -634,8 +898,8 @@ public class BindingExpressionParser extends Parser {
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).visitInstanceOfOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitInstanceOfOp(this);
else return visitor.visitChildren(this);
}
}
@@ -643,7 +907,7 @@ public class BindingExpressionParser extends Parser {
public ExpressionContext left;
public Token op;
public ExpressionContext right;
- public List<? extends ExpressionContext> expression() {
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
@@ -659,13 +923,32 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitBinaryOp(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitBinaryOp(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitBinaryOp(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class FunctionRefContext extends ExpressionContext {
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ 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).enterFunctionRef(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitFunctionRef(this);
+ }
+ @Override
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitFunctionRef(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ExpressionContext expression() throws RecognitionException {
return expression(0);
}
@@ -675,408 +958,409 @@ public class BindingExpressionParser extends Parser {
int _parentState = getState();
ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState);
ExpressionContext _prevctx = _localctx;
- int _startState = 6;
- enterRecursionRule(_localctx, 6, RULE_expression, _p);
+ int _startState = 12;
+ enterRecursionRule(_localctx, 12, RULE_expression, _p);
int _la;
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(70);
- switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
+ setState(100);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
case 1:
{
- _localctx = new CastOpContext(_localctx);
+ _localctx = new GroupingContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(53);
- match(T__3);
- setState(54);
- type();
- setState(55);
+ setState(82);
match(T__4);
- setState(56);
- expression(16);
+ setState(83);
+ expression(0);
+ setState(84);
+ match(T__5);
}
break;
-
case 2:
{
- _localctx = new UnaryOpContext(_localctx);
+ _localctx = new PrimaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(58);
- ((UnaryOpContext)_localctx).op = _input.LT(1);
- _la = _input.LA(1);
- if ( !(_la==T__8 || _la==T__9) ) {
- ((UnaryOpContext)_localctx).op = _errHandler.recoverInline(this);
- } else {
- consume();
- }
- setState(59);
- expression(15);
+ setState(86);
+ literal();
}
break;
-
case 3:
{
- _localctx = new UnaryOpContext(_localctx);
+ _localctx = new PrimaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(60);
- ((UnaryOpContext)_localctx).op = _input.LT(1);
- _la = _input.LA(1);
- if ( !(_la==T__10 || _la==T__11) ) {
- ((UnaryOpContext)_localctx).op = _errHandler.recoverInline(this);
- } else {
- consume();
- }
- setState(61);
- expression(14);
+ setState(87);
+ match(VoidLiteral);
}
break;
-
case 4:
{
- _localctx = new GroupingContext(_localctx);
+ _localctx = new PrimaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(62);
- match(T__3);
- setState(63);
- expression(0);
- setState(64);
- match(T__4);
+ setState(88);
+ identifier();
}
break;
-
case 5:
{
_localctx = new PrimaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(66);
- literal();
+ setState(89);
+ classExtraction();
}
break;
-
case 6:
{
- _localctx = new PrimaryContext(_localctx);
+ _localctx = new ResourceContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(67);
- identifier();
+ setState(90);
+ resources();
}
break;
-
case 7:
{
- _localctx = new PrimaryContext(_localctx);
+ _localctx = new CastOpContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(68);
- classExtraction();
+ setState(91);
+ match(T__4);
+ setState(92);
+ type();
+ setState(93);
+ match(T__5);
+ setState(94);
+ expression(16);
}
break;
-
case 8:
{
- _localctx = new ResourceContext(_localctx);
+ _localctx = new UnaryOpContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(69);
- resources();
+ setState(96);
+ ((UnaryOpContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !(_la==T__10 || _la==T__11) ) {
+ ((UnaryOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ } else {
+ consume();
+ }
+ setState(97);
+ expression(15);
+ }
+ break;
+ case 9:
+ {
+ _localctx = new UnaryOpContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(98);
+ ((UnaryOpContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !(_la==T__12 || _la==T__13) ) {
+ ((UnaryOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ } else {
+ consume();
+ }
+ setState(99);
+ expression(14);
}
break;
}
_ctx.stop = _input.LT(-1);
- setState(132);
+ setState(165);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,9,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(130);
- switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
+ setState(163);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) {
case 1:
{
_localctx = new MathOpContext(new ExpressionContext(_parentctx, _parentState));
((MathOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(72);
+ setState(102);
if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)");
- setState(73);
+ setState(103);
((MathOpContext)_localctx).op = _input.LT(1);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__12) | (1L << T__13) | (1L << T__14))) != 0)) ) {
- ((MathOpContext)_localctx).op = _errHandler.recoverInline(this);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__14) | (1L << T__15) | (1L << T__16))) != 0)) ) {
+ ((MathOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
} else {
consume();
}
- setState(74);
+ setState(104);
((MathOpContext)_localctx).right = expression(14);
}
break;
-
case 2:
{
_localctx = new MathOpContext(new ExpressionContext(_parentctx, _parentState));
((MathOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(75);
+ setState(105);
if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)");
- setState(76);
+ setState(106);
((MathOpContext)_localctx).op = _input.LT(1);
_la = _input.LA(1);
- if ( !(_la==T__8 || _la==T__9) ) {
- ((MathOpContext)_localctx).op = _errHandler.recoverInline(this);
+ if ( !(_la==T__10 || _la==T__11) ) {
+ ((MathOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
} else {
consume();
}
- setState(77);
+ setState(107);
((MathOpContext)_localctx).right = expression(13);
}
break;
-
case 3:
{
_localctx = new BitShiftOpContext(new ExpressionContext(_parentctx, _parentState));
((BitShiftOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(78);
+ setState(108);
if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)");
- setState(79);
+ setState(109);
((BitShiftOpContext)_localctx).op = _input.LT(1);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__15) | (1L << T__16) | (1L << T__17))) != 0)) ) {
- ((BitShiftOpContext)_localctx).op = _errHandler.recoverInline(this);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) ) {
+ ((BitShiftOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
} else {
consume();
}
- setState(80);
+ setState(110);
((BitShiftOpContext)_localctx).right = expression(12);
}
break;
-
case 4:
{
_localctx = new ComparisonOpContext(new ExpressionContext(_parentctx, _parentState));
((ComparisonOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(81);
+ setState(111);
if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)");
- setState(82);
+ setState(112);
((ComparisonOpContext)_localctx).op = _input.LT(1);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21))) != 0)) ) {
- ((ComparisonOpContext)_localctx).op = _errHandler.recoverInline(this);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23))) != 0)) ) {
+ ((ComparisonOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
} else {
consume();
}
- setState(83);
+ setState(113);
((ComparisonOpContext)_localctx).right = expression(11);
}
break;
-
case 5:
{
_localctx = new ComparisonOpContext(new ExpressionContext(_parentctx, _parentState));
((ComparisonOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(84);
+ setState(114);
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
- setState(85);
+ setState(115);
((ComparisonOpContext)_localctx).op = _input.LT(1);
_la = _input.LA(1);
- if ( !(_la==T__23 || _la==T__24) ) {
- ((ComparisonOpContext)_localctx).op = _errHandler.recoverInline(this);
+ if ( !(_la==T__25 || _la==T__26) ) {
+ ((ComparisonOpContext)_localctx).op = (Token)_errHandler.recoverInline(this);
} else {
consume();
}
- setState(86);
+ setState(116);
((ComparisonOpContext)_localctx).right = expression(9);
}
break;
-
case 6:
{
_localctx = new BinaryOpContext(new ExpressionContext(_parentctx, _parentState));
((BinaryOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(87);
+ setState(117);
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
- setState(88);
- ((BinaryOpContext)_localctx).op = match(T__25);
- setState(89);
+ setState(118);
+ ((BinaryOpContext)_localctx).op = match(T__27);
+ setState(119);
((BinaryOpContext)_localctx).right = expression(8);
}
break;
-
case 7:
{
_localctx = new BinaryOpContext(new ExpressionContext(_parentctx, _parentState));
((BinaryOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(90);
+ setState(120);
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
- setState(91);
- ((BinaryOpContext)_localctx).op = match(T__26);
- setState(92);
+ setState(121);
+ ((BinaryOpContext)_localctx).op = match(T__28);
+ setState(122);
((BinaryOpContext)_localctx).right = expression(7);
}
break;
-
case 8:
{
_localctx = new BinaryOpContext(new ExpressionContext(_parentctx, _parentState));
((BinaryOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(93);
+ setState(123);
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
- setState(94);
- ((BinaryOpContext)_localctx).op = match(T__27);
- setState(95);
+ setState(124);
+ ((BinaryOpContext)_localctx).op = match(T__29);
+ setState(125);
((BinaryOpContext)_localctx).right = expression(6);
}
break;
-
case 9:
{
_localctx = new AndOrOpContext(new ExpressionContext(_parentctx, _parentState));
((AndOrOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(96);
+ setState(126);
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
- setState(97);
- ((AndOrOpContext)_localctx).op = match(T__28);
- setState(98);
+ setState(127);
+ ((AndOrOpContext)_localctx).op = match(T__30);
+ setState(128);
((AndOrOpContext)_localctx).right = expression(5);
}
break;
-
case 10:
{
_localctx = new AndOrOpContext(new ExpressionContext(_parentctx, _parentState));
((AndOrOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(99);
+ setState(129);
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
- setState(100);
- ((AndOrOpContext)_localctx).op = match(T__29);
- setState(101);
+ setState(130);
+ ((AndOrOpContext)_localctx).op = match(T__31);
+ setState(131);
((AndOrOpContext)_localctx).right = expression(4);
}
break;
-
case 11:
{
_localctx = new TernaryOpContext(new ExpressionContext(_parentctx, _parentState));
((TernaryOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(102);
+ setState(132);
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
- setState(103);
- ((TernaryOpContext)_localctx).op = match(T__30);
- setState(104);
+ setState(133);
+ ((TernaryOpContext)_localctx).op = match(T__32);
+ setState(134);
((TernaryOpContext)_localctx).iftrue = expression(0);
- setState(105);
- match(T__31);
- setState(106);
+ setState(135);
+ match(T__33);
+ setState(136);
((TernaryOpContext)_localctx).iffalse = expression(2);
}
break;
-
case 12:
{
_localctx = new QuestionQuestionOpContext(new ExpressionContext(_parentctx, _parentState));
((QuestionQuestionOpContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(108);
+ setState(138);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(109);
- ((QuestionQuestionOpContext)_localctx).op = match(T__32);
- setState(110);
+ setState(139);
+ ((QuestionQuestionOpContext)_localctx).op = match(T__34);
+ setState(140);
((QuestionQuestionOpContext)_localctx).right = expression(2);
}
break;
-
case 13:
{
_localctx = new DotOpContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(111);
- if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)");
- setState(112);
- match(T__5);
- setState(113);
+ setState(141);
+ if (!(precpred(_ctx, 20))) throw new FailedPredicateException(this, "precpred(_ctx, 20)");
+ setState(142);
+ match(T__6);
+ setState(143);
match(Identifier);
}
break;
-
case 14:
{
+ _localctx = new FunctionRefContext(new ExpressionContext(_parentctx, _parentState));
+ pushNewRecursionContext(_localctx, _startState, RULE_expression);
+ setState(144);
+ if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)");
+ setState(145);
+ match(T__7);
+ setState(146);
+ match(Identifier);
+ }
+ break;
+ case 15:
+ {
_localctx = new BracketOpContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(114);
+ setState(147);
if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)");
- setState(115);
- match(T__6);
- setState(116);
+ setState(148);
+ match(T__8);
+ setState(149);
expression(0);
- setState(117);
- match(T__7);
+ 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(119);
+ setState(152);
if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)");
- setState(120);
- match(T__5);
- setState(121);
+ setState(153);
+ match(T__6);
+ setState(154);
((MethodInvocationContext)_localctx).methodName = match(Identifier);
- setState(122);
- match(T__3);
- setState(124);
+ setState(155);
+ match(T__4);
+ setState(157);
_la = _input.LA(1);
- if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__34) | (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 << 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(123);
+ setState(156);
((MethodInvocationContext)_localctx).args = expressionList();
}
}
- setState(126);
- match(T__4);
+ setState(159);
+ match(T__5);
}
break;
-
- case 16:
+ case 17:
{
_localctx = new InstanceOfOpContext(new ExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expression);
- setState(127);
+ setState(160);
if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)");
- setState(128);
- match(T__22);
- setState(129);
+ setState(161);
+ match(T__24);
+ setState(162);
type();
}
break;
}
}
}
- setState(134);
+ setState(167);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,5,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,9,_ctx);
}
}
}
@@ -1108,51 +1392,24 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitClassExtraction(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitClassExtraction(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitClassExtraction(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ClassExtractionContext classExtraction() throws RecognitionException {
ClassExtractionContext _localctx = new ClassExtractionContext(_ctx, getState());
- enterRule(_localctx, 8, RULE_classExtraction);
+ enterRule(_localctx, 14, RULE_classExtraction);
try {
- setState(142);
- switch (_input.LA(1)) {
- case T__35:
- case T__36:
- case T__37:
- case T__38:
- case T__39:
- case T__40:
- case T__41:
- case T__42:
- case Identifier:
- enterOuterAlt(_localctx, 1);
- {
- setState(135);
- type();
- setState(136);
- match(T__5);
- setState(137);
- match(T__33);
- }
- break;
- case T__34:
- enterOuterAlt(_localctx, 2);
- {
- setState(139);
- match(T__34);
- setState(140);
- match(T__5);
- setState(141);
- match(T__33);
- }
- break;
- default:
- throw new NoViableAltException(this);
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(168);
+ type();
+ setState(169);
+ match(T__6);
+ setState(170);
+ match(T__35);
}
}
catch (RecognitionException re) {
@@ -1167,7 +1424,7 @@ public class BindingExpressionParser extends Parser {
}
public static class ExpressionListContext extends ParserRuleContext {
- public List<? extends ExpressionContext> expression() {
+ public List<ExpressionContext> expression() {
return getRuleContexts(ExpressionContext.class);
}
public ExpressionContext expression(int i) {
@@ -1186,35 +1443,34 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitExpressionList(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitExpressionList(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitExpressionList(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ExpressionListContext expressionList() throws RecognitionException {
ExpressionListContext _localctx = new ExpressionListContext(_ctx, getState());
- enterRule(_localctx, 10, RULE_expressionList);
+ enterRule(_localctx, 16, RULE_expressionList);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(144);
+ setState(172);
expression(0);
- setState(149);
+ setState(177);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==T__0) {
{
{
- setState(145);
+ setState(173);
match(T__0);
- setState(146);
+ setState(174);
expression(0);
}
}
- setState(151);
+ setState(179);
_errHandler.sync(this);
_la = _input.LA(1);
}
@@ -1251,18 +1507,17 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitLiteral(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitLiteral(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitLiteral(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final LiteralContext literal() throws RecognitionException {
LiteralContext _localctx = new LiteralContext(_ctx, getState());
- enterRule(_localctx, 12, RULE_literal);
+ enterRule(_localctx, 18, RULE_literal);
try {
- setState(154);
+ setState(182);
switch (_input.LA(1)) {
case IntegerLiteral:
case FloatingPointLiteral:
@@ -1271,7 +1526,7 @@ public class BindingExpressionParser extends Parser {
case NullLiteral:
enterOuterAlt(_localctx, 1);
{
- setState(152);
+ setState(180);
javaLiteral();
}
break;
@@ -1279,7 +1534,7 @@ public class BindingExpressionParser extends Parser {
case DoubleQuoteString:
enterOuterAlt(_localctx, 2);
{
- setState(153);
+ setState(181);
stringLiteral();
}
break;
@@ -1313,20 +1568,19 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitIdentifier(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitIdentifier(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitIdentifier(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final IdentifierContext identifier() throws RecognitionException {
IdentifierContext _localctx = new IdentifierContext(_ctx, getState());
- enterRule(_localctx, 14, RULE_identifier);
+ enterRule(_localctx, 20, RULE_identifier);
try {
enterOuterAlt(_localctx, 1);
{
- setState(156);
+ setState(184);
match(Identifier);
}
}
@@ -1360,21 +1614,20 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitJavaLiteral(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitJavaLiteral(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitJavaLiteral(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final JavaLiteralContext javaLiteral() throws RecognitionException {
JavaLiteralContext _localctx = new JavaLiteralContext(_ctx, getState());
- enterRule(_localctx, 16, RULE_javaLiteral);
+ enterRule(_localctx, 22, RULE_javaLiteral);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(158);
+ 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);
@@ -1410,21 +1663,20 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitStringLiteral(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitStringLiteral(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitStringLiteral(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final StringLiteralContext stringLiteral() throws RecognitionException {
StringLiteralContext _localctx = new StringLiteralContext(_ctx, getState());
- enterRule(_localctx, 18, RULE_stringLiteral);
+ enterRule(_localctx, 24, RULE_stringLiteral);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(160);
+ setState(188);
_la = _input.LA(1);
if ( !(_la==SingleQuoteString || _la==DoubleQuoteString) ) {
_errHandler.recoverInline(this);
@@ -1464,22 +1716,21 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitExplicitGenericInvocation(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitExplicitGenericInvocation(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitExplicitGenericInvocation(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ExplicitGenericInvocationContext explicitGenericInvocation() throws RecognitionException {
ExplicitGenericInvocationContext _localctx = new ExplicitGenericInvocationContext(_ctx, getState());
- enterRule(_localctx, 20, RULE_explicitGenericInvocation);
+ enterRule(_localctx, 26, RULE_explicitGenericInvocation);
try {
enterOuterAlt(_localctx, 1);
{
- setState(162);
+ setState(190);
typeArguments();
- setState(163);
+ setState(191);
explicitGenericInvocationSuffix();
}
}
@@ -1495,7 +1746,7 @@ public class BindingExpressionParser extends Parser {
}
public static class TypeArgumentsContext extends ParserRuleContext {
- public List<? extends TypeContext> type() {
+ public List<TypeContext> type() {
return getRuleContexts(TypeContext.class);
}
public TypeContext type(int i) {
@@ -1514,42 +1765,41 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitTypeArguments(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitTypeArguments(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitTypeArguments(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final TypeArgumentsContext typeArguments() throws RecognitionException {
TypeArgumentsContext _localctx = new TypeArgumentsContext(_ctx, getState());
- enterRule(_localctx, 22, RULE_typeArguments);
+ enterRule(_localctx, 28, RULE_typeArguments);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(165);
- match(T__21);
- setState(166);
+ setState(193);
+ match(T__23);
+ setState(194);
type();
- setState(171);
+ setState(199);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==T__0) {
{
{
- setState(167);
+ setState(195);
match(T__0);
- setState(168);
+ setState(196);
type();
}
}
- setState(173);
+ setState(201);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(174);
- match(T__20);
+ setState(202);
+ match(T__22);
}
}
catch (RecognitionException re) {
@@ -1583,46 +1833,44 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitType(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitType(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitType(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final TypeContext type() throws RecognitionException {
TypeContext _localctx = new TypeContext(_ctx, getState());
- enterRule(_localctx, 24, RULE_type);
+ enterRule(_localctx, 30, RULE_type);
try {
int _alt;
- setState(192);
+ setState(220);
switch (_input.LA(1)) {
case Identifier:
enterOuterAlt(_localctx, 1);
{
- setState(176);
+ setState(204);
classOrInterfaceType();
- setState(181);
+ setState(209);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,10,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,13,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(177);
- match(T__6);
- setState(178);
- match(T__7);
+ setState(205);
+ match(T__8);
+ setState(206);
+ match(T__9);
}
}
}
- setState(183);
+ setState(211);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,10,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,13,_ctx);
}
}
break;
- case T__35:
case T__36:
case T__37:
case T__38:
@@ -1630,27 +1878,28 @@ public class BindingExpressionParser extends Parser {
case T__40:
case T__41:
case T__42:
+ case T__43:
enterOuterAlt(_localctx, 2);
{
- setState(184);
+ setState(212);
primitiveType();
- setState(189);
+ setState(217);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,14,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(185);
- match(T__6);
- setState(186);
- match(T__7);
+ setState(213);
+ match(T__8);
+ setState(214);
+ match(T__9);
}
}
}
- setState(191);
+ setState(219);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,14,_ctx);
}
}
break;
@@ -1687,22 +1936,21 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitExplicitGenericInvocationSuffix(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitExplicitGenericInvocationSuffix(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitExplicitGenericInvocationSuffix(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ExplicitGenericInvocationSuffixContext explicitGenericInvocationSuffix() throws RecognitionException {
ExplicitGenericInvocationSuffixContext _localctx = new ExplicitGenericInvocationSuffixContext(_ctx, getState());
- enterRule(_localctx, 26, RULE_explicitGenericInvocationSuffix);
+ enterRule(_localctx, 32, RULE_explicitGenericInvocationSuffix);
try {
enterOuterAlt(_localctx, 1);
{
- setState(194);
+ setState(222);
match(Identifier);
- setState(195);
+ setState(223);
arguments();
}
}
@@ -1734,33 +1982,32 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitArguments(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitArguments(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitArguments(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ArgumentsContext arguments() throws RecognitionException {
ArgumentsContext _localctx = new ArgumentsContext(_ctx, getState());
- enterRule(_localctx, 28, RULE_arguments);
+ enterRule(_localctx, 34, RULE_arguments);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(197);
- match(T__3);
- setState(199);
+ setState(225);
+ match(T__4);
+ setState(227);
_la = _input.LA(1);
- if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__34) | (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 << 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(198);
+ setState(226);
expressionList();
}
}
- setState(201);
- match(T__4);
+ setState(229);
+ match(T__5);
}
}
catch (RecognitionException re) {
@@ -1778,13 +2025,13 @@ public class BindingExpressionParser extends Parser {
public IdentifierContext identifier() {
return getRuleContext(IdentifierContext.class,0);
}
- public List<? extends TypeArgumentsContext> typeArguments() {
+ public List<TypeArgumentsContext> typeArguments() {
return getRuleContexts(TypeArgumentsContext.class);
}
public TypeArgumentsContext typeArguments(int i) {
return getRuleContext(TypeArgumentsContext.class,i);
}
- public List<? extends TerminalNode> Identifier() { return getTokens(BindingExpressionParser.Identifier); }
+ public List<TerminalNode> Identifier() { return getTokens(BindingExpressionParser.Identifier); }
public TerminalNode Identifier(int i) {
return getToken(BindingExpressionParser.Identifier, i);
}
@@ -1801,47 +2048,48 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitClassOrInterfaceType(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitClassOrInterfaceType(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitClassOrInterfaceType(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ClassOrInterfaceTypeContext classOrInterfaceType() throws RecognitionException {
ClassOrInterfaceTypeContext _localctx = new ClassOrInterfaceTypeContext(_ctx, getState());
- enterRule(_localctx, 30, RULE_classOrInterfaceType);
+ enterRule(_localctx, 36, RULE_classOrInterfaceType);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(203);
+ setState(231);
identifier();
- setState(205);
- switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
+ setState(233);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) {
case 1:
{
- setState(204);
+ setState(232);
typeArguments();
}
break;
}
- setState(214);
+ setState(242);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(207);
- match(T__5);
- setState(208);
+ setState(235);
+ match(T__6);
+ setState(236);
match(Identifier);
- setState(210);
- switch ( getInterpreter().adaptivePredict(_input,15,_ctx) ) {
+ setState(238);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) {
case 1:
{
- setState(209);
+ setState(237);
typeArguments();
}
break;
@@ -1849,9 +2097,9 @@ public class BindingExpressionParser extends Parser {
}
}
}
- setState(216);
+ setState(244);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,16,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
}
}
}
@@ -1880,23 +2128,22 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitPrimitiveType(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitPrimitiveType(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitPrimitiveType(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final PrimitiveTypeContext primitiveType() throws RecognitionException {
PrimitiveTypeContext _localctx = new PrimitiveTypeContext(_ctx, getState());
- enterRule(_localctx, 32, RULE_primitiveType);
+ enterRule(_localctx, 38, RULE_primitiveType);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(217);
+ 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();
@@ -1932,26 +2179,26 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitResources(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitResources(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitResources(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ResourcesContext resources() throws RecognitionException {
ResourcesContext _localctx = new ResourcesContext(_ctx, getState());
- enterRule(_localctx, 34, RULE_resources);
+ enterRule(_localctx, 40, RULE_resources);
try {
enterOuterAlt(_localctx, 1);
{
- setState(219);
+ setState(247);
match(ResourceReference);
- setState(221);
- switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) {
+ setState(249);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
case 1:
{
- setState(220);
+ setState(248);
resourceParameters();
}
break;
@@ -1986,25 +2233,24 @@ public class BindingExpressionParser extends Parser {
if ( listener instanceof BindingExpressionListener ) ((BindingExpressionListener)listener).exitResourceParameters(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof BindingExpressionVisitor<?> ) return ((BindingExpressionVisitor<? extends Result>)visitor).visitResourceParameters(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof BindingExpressionVisitor ) return ((BindingExpressionVisitor<? extends T>)visitor).visitResourceParameters(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ResourceParametersContext resourceParameters() throws RecognitionException {
ResourceParametersContext _localctx = new ResourceParametersContext(_ctx, getState());
- enterRule(_localctx, 36, RULE_resourceParameters);
+ enterRule(_localctx, 42, RULE_resourceParameters);
try {
enterOuterAlt(_localctx, 1);
{
- setState(223);
- match(T__3);
- setState(224);
- expressionList();
- setState(225);
+ setState(251);
match(T__4);
+ setState(252);
+ expressionList();
+ setState(253);
+ match(T__5);
}
}
catch (RecognitionException re) {
@@ -2020,7 +2266,7 @@ public class BindingExpressionParser extends Parser {
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
switch (ruleIndex) {
- case 3:
+ case 6:
return expression_sempred((ExpressionContext)_localctx, predIndex);
}
return true;
@@ -2029,135 +2275,136 @@ public class BindingExpressionParser extends Parser {
switch (predIndex) {
case 0:
return precpred(_ctx, 13);
-
case 1:
return precpred(_ctx, 12);
-
case 2:
return precpred(_ctx, 11);
-
case 3:
return precpred(_ctx, 10);
-
case 4:
return precpred(_ctx, 8);
-
case 5:
return precpred(_ctx, 7);
-
case 6:
return precpred(_ctx, 6);
-
case 7:
return precpred(_ctx, 5);
-
case 8:
return precpred(_ctx, 4);
-
case 9:
return precpred(_ctx, 3);
-
case 10:
return precpred(_ctx, 2);
-
case 11:
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:\u00e6\4\2\t\2\4"+
+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\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\3\2\3\2\5\2+\n\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4"+
- "\5\4\65\n\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+
- "\5\3\5\3\5\3\5\5\5I\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+
- "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+
- "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+
- "\5\3\5\3\5\3\5\3\5\3\5\5\5\177\n\5\3\5\3\5\3\5\3\5\7\5\u0085\n\5\f\5\16"+
- "\5\u0088\13\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u0091\n\6\3\7\3\7\3\7\7"+
- "\7\u0096\n\7\f\7\16\7\u0099\13\7\3\b\3\b\5\b\u009d\n\b\3\t\3\t\3\n\3\n"+
- "\3\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\r\7\r\u00ac\n\r\f\r\16\r\u00af\13"+
- "\r\3\r\3\r\3\16\3\16\3\16\7\16\u00b6\n\16\f\16\16\16\u00b9\13\16\3\16"+
- "\3\16\3\16\7\16\u00be\n\16\f\16\16\16\u00c1\13\16\5\16\u00c3\n\16\3\17"+
- "\3\17\3\17\3\20\3\20\5\20\u00ca\n\20\3\20\3\20\3\21\3\21\5\21\u00d0\n"+
- "\21\3\21\3\21\3\21\5\21\u00d5\n\21\7\21\u00d7\n\21\f\21\16\21\u00da\13"+
- "\21\3\22\3\22\3\23\3\23\5\23\u00e0\n\23\3\24\3\24\3\24\3\24\3\24\2\2\3"+
- "\b\25\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\13\3\2\13\f\3\2\r\16\3\2\17\21\3\2\22\24\3\2\25\30"+
- "\3\2\32\33\4\2/\62\65\65\3\2\63\64\3\2&-\u00f9\2(\3\2\2\2\4,\3\2\2\2\6"+
- "\64\3\2\2\2\bH\3\2\2\2\n\u0090\3\2\2\2\f\u0092\3\2\2\2\16\u009c\3\2\2"+
- "\2\20\u009e\3\2\2\2\22\u00a0\3\2\2\2\24\u00a2\3\2\2\2\26\u00a4\3\2\2\2"+
- "\30\u00a7\3\2\2\2\32\u00c2\3\2\2\2\34\u00c4\3\2\2\2\36\u00c7\3\2\2\2 "+
- "\u00cd\3\2\2\2\"\u00db\3\2\2\2$\u00dd\3\2\2\2&\u00e1\3\2\2\2(*\5\b\5\2"+
- ")+\5\4\3\2*)\3\2\2\2*+\3\2\2\2+\3\3\2\2\2,-\7\3\2\2-.\7\4\2\2./\7\5\2"+
- "\2/\60\5\6\4\2\60\5\3\2\2\2\61\65\5\16\b\2\62\65\78\2\2\63\65\5\20\t\2"+
- "\64\61\3\2\2\2\64\62\3\2\2\2\64\63\3\2\2\2\65\7\3\2\2\2\66\67\b\5\1\2"+
- "\678\7\6\2\289\5\32\16\29:\7\7\2\2:;\5\b\5\22;I\3\2\2\2<=\t\2\2\2=I\5"+
- "\b\5\21>?\t\3\2\2?I\5\b\5\20@A\7\6\2\2AB\5\b\5\2BC\7\7\2\2CI\3\2\2\2D"+
- "I\5\16\b\2EI\5\20\t\2FI\5\n\6\2GI\5$\23\2H\66\3\2\2\2H<\3\2\2\2H>\3\2"+
- "\2\2H@\3\2\2\2HD\3\2\2\2HE\3\2\2\2HF\3\2\2\2HG\3\2\2\2I\u0086\3\2\2\2"+
- "JK\f\17\2\2KL\t\4\2\2L\u0085\5\b\5\20MN\f\16\2\2NO\t\2\2\2O\u0085\5\b"+
- "\5\17PQ\f\r\2\2QR\t\5\2\2R\u0085\5\b\5\16ST\f\f\2\2TU\t\6\2\2U\u0085\5"+
- "\b\5\rVW\f\n\2\2WX\t\7\2\2X\u0085\5\b\5\13YZ\f\t\2\2Z[\7\34\2\2[\u0085"+
- "\5\b\5\n\\]\f\b\2\2]^\7\35\2\2^\u0085\5\b\5\t_`\f\7\2\2`a\7\36\2\2a\u0085"+
- "\5\b\5\bbc\f\6\2\2cd\7\37\2\2d\u0085\5\b\5\7ef\f\5\2\2fg\7 \2\2g\u0085"+
- "\5\b\5\6hi\f\4\2\2ij\7!\2\2jk\5\b\5\2kl\7\"\2\2lm\5\b\5\4m\u0085\3\2\2"+
- "\2no\f\3\2\2op\7#\2\2p\u0085\5\b\5\4qr\f\25\2\2rs\7\b\2\2s\u0085\7\66"+
- "\2\2tu\f\24\2\2uv\7\t\2\2vw\5\b\5\2wx\7\n\2\2x\u0085\3\2\2\2yz\f\23\2"+
- "\2z{\7\b\2\2{|\7\66\2\2|~\7\6\2\2}\177\5\f\7\2~}\3\2\2\2~\177\3\2\2\2"+
- "\177\u0080\3\2\2\2\u0080\u0085\7\7\2\2\u0081\u0082\f\13\2\2\u0082\u0083"+
- "\7\31\2\2\u0083\u0085\5\32\16\2\u0084J\3\2\2\2\u0084M\3\2\2\2\u0084P\3"+
- "\2\2\2\u0084S\3\2\2\2\u0084V\3\2\2\2\u0084Y\3\2\2\2\u0084\\\3\2\2\2\u0084"+
- "_\3\2\2\2\u0084b\3\2\2\2\u0084e\3\2\2\2\u0084h\3\2\2\2\u0084n\3\2\2\2"+
- "\u0084q\3\2\2\2\u0084t\3\2\2\2\u0084y\3\2\2\2\u0084\u0081\3\2\2\2\u0085"+
- "\u0088\3\2\2\2\u0086\u0084\3\2\2\2\u0086\u0087\3\2\2\2\u0087\t\3\2\2\2"+
- "\u0088\u0086\3\2\2\2\u0089\u008a\5\32\16\2\u008a\u008b\7\b\2\2\u008b\u008c"+
- "\7$\2\2\u008c\u0091\3\2\2\2\u008d\u008e\7%\2\2\u008e\u008f\7\b\2\2\u008f"+
- "\u0091\7$\2\2\u0090\u0089\3\2\2\2\u0090\u008d\3\2\2\2\u0091\13\3\2\2\2"+
- "\u0092\u0097\5\b\5\2\u0093\u0094\7\3\2\2\u0094\u0096\5\b\5\2\u0095\u0093"+
- "\3\2\2\2\u0096\u0099\3\2\2\2\u0097\u0095\3\2\2\2\u0097\u0098\3\2\2\2\u0098"+
- "\r\3\2\2\2\u0099\u0097\3\2\2\2\u009a\u009d\5\22\n\2\u009b\u009d\5\24\13"+
- "\2\u009c\u009a\3\2\2\2\u009c\u009b\3\2\2\2\u009d\17\3\2\2\2\u009e\u009f"+
- "\7\66\2\2\u009f\21\3\2\2\2\u00a0\u00a1\t\b\2\2\u00a1\23\3\2\2\2\u00a2"+
- "\u00a3\t\t\2\2\u00a3\25\3\2\2\2\u00a4\u00a5\5\30\r\2\u00a5\u00a6\5\34"+
- "\17\2\u00a6\27\3\2\2\2\u00a7\u00a8\7\30\2\2\u00a8\u00ad\5\32\16\2\u00a9"+
- "\u00aa\7\3\2\2\u00aa\u00ac\5\32\16\2\u00ab\u00a9\3\2\2\2\u00ac\u00af\3"+
- "\2\2\2\u00ad\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\u00b0\3\2\2\2\u00af"+
- "\u00ad\3\2\2\2\u00b0\u00b1\7\27\2\2\u00b1\31\3\2\2\2\u00b2\u00b7\5 \21"+
- "\2\u00b3\u00b4\7\t\2\2\u00b4\u00b6\7\n\2\2\u00b5\u00b3\3\2\2\2\u00b6\u00b9"+
- "\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b7\u00b8\3\2\2\2\u00b8\u00c3\3\2\2\2\u00b9"+
- "\u00b7\3\2\2\2\u00ba\u00bf\5\"\22\2\u00bb\u00bc\7\t\2\2\u00bc\u00be\7"+
- "\n\2\2\u00bd\u00bb\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf\u00bd\3\2\2\2\u00bf"+
- "\u00c0\3\2\2\2\u00c0\u00c3\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c2\u00b2\3\2"+
- "\2\2\u00c2\u00ba\3\2\2\2\u00c3\33\3\2\2\2\u00c4\u00c5\7\66\2\2\u00c5\u00c6"+
- "\5\36\20\2\u00c6\35\3\2\2\2\u00c7\u00c9\7\6\2\2\u00c8\u00ca\5\f\7\2\u00c9"+
- "\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00cb\3\2\2\2\u00cb\u00cc\7\7"+
- "\2\2\u00cc\37\3\2\2\2\u00cd\u00cf\5\20\t\2\u00ce\u00d0\5\30\r\2\u00cf"+
- "\u00ce\3\2\2\2\u00cf\u00d0\3\2\2\2\u00d0\u00d8\3\2\2\2\u00d1\u00d2\7\b"+
- "\2\2\u00d2\u00d4\7\66\2\2\u00d3\u00d5\5\30\r\2\u00d4\u00d3\3\2\2\2\u00d4"+
- "\u00d5\3\2\2\2\u00d5\u00d7\3\2\2\2\u00d6\u00d1\3\2\2\2\u00d7\u00da\3\2"+
- "\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9\3\2\2\2\u00d9!\3\2\2\2\u00da\u00d8"+
- "\3\2\2\2\u00db\u00dc\t\n\2\2\u00dc#\3\2\2\2\u00dd\u00df\78\2\2\u00de\u00e0"+
- "\5&\24\2\u00df\u00de\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0%\3\2\2\2\u00e1"+
- "\u00e2\7\6\2\2\u00e2\u00e3\5\f\7\2\u00e3\u00e4\7\7\2\2\u00e4\'\3\2\2\2"+
- "\24*\64H~\u0084\u0086\u0090\u0097\u009c\u00ad\u00b7\u00bf\u00c2\u00c9"+
- "\u00cf\u00d4\u00d8\u00df";
+ "\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"+
+ "\3\2\5\2\64\n\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\5\4>\n\4\3\5\3\5\3\5\3"+
+ "\5\3\6\3\6\3\6\5\6G\n\6\3\6\5\6J\n\6\3\7\3\7\3\7\7\7O\n\7\f\7\16\7R\13"+
+ "\7\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\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\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\3\16"+
+ "\30\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,\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\2"+
+ "CJ\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\2"+
+ "IC\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\2"+
+ "OR\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\16\b\2VW\7\b\2\2Wg\3\2\2\2Xg\5\24\13\2Yg\7\60\2\2Zg\5\26\f\2[g"+
+ "\5\20\t\2\\g\5*\26\2]^\7\7\2\2^_\5 \21\2_`\7\b\2\2`a\5\16\b\22ag\3\2\2"+
+ "\2bc\t\2\2\2cg\5\16\b\21de\t\3\2\2eg\5\16\b\20fS\3\2\2\2fX\3\2\2\2fY\3"+
+ "\2\2\2fZ\3\2\2\2f[\3\2\2\2f\\\3\2\2\2f]\3\2\2\2fb\3\2\2\2fd\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 {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
}
} \ No newline at end of file
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 dfcf31dc..c7443648 100644
--- a/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
+++ b/compilerCommon/src/main/grammar-gen/android/databinding/parser/BindingExpressionVisitor.java
@@ -1,275 +1,274 @@
-// Generated from BindingExpression.g4 by ANTLR 4.5
+// Generated from BindingExpression.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link BindingExpressionParser}.
*
- * @param <Result> The return type of the visit operation. Use {@link Void} for
+ * @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
-public interface BindingExpressionVisitor<Result> extends ParseTreeVisitor<Result> {
+public interface BindingExpressionVisitor<T> extends ParseTreeVisitor<T> {
/**
- * Visit a parse tree produced by the {@code BracketOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Visit a parse tree produced by the {@code RootExpr}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitBracketOp(@NotNull BindingExpressionParser.BracketOpContext ctx);
-
+ T visitRootExpr(BindingExpressionParser.RootExprContext ctx);
/**
- * Visit a parse tree produced by the {@code Resource}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Visit a parse tree produced by the {@code RootLambda}
+ * labeled alternative in {@link BindingExpressionParser#bindingSyntax}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitResource(@NotNull BindingExpressionParser.ResourceContext ctx);
-
+ T visitRootLambda(BindingExpressionParser.RootLambdaContext ctx);
/**
- * Visit a parse tree produced by the {@code CastOp}
- * labeled alternative in {@link BindingExpressionParser#expression}.
+ * Visit a parse tree produced by {@link BindingExpressionParser#defaults}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx);
-
+ T visitDefaults(BindingExpressionParser.DefaultsContext ctx);
/**
- * Visit a parse tree produced by the {@code UnaryOp}
+ * Visit a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitConstantValue(BindingExpressionParser.ConstantValueContext ctx);
+ /**
+ * Visit a parse tree produced by {@link BindingExpressionParser#lambdaExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLambdaExpression(BindingExpressionParser.LambdaExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code SingleLambdaParameter}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSingleLambdaParameter(BindingExpressionParser.SingleLambdaParameterContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code LambdaParameterList}
+ * labeled alternative in {@link BindingExpressionParser#lambdaParameters}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLambdaParameterList(BindingExpressionParser.LambdaParameterListContext ctx);
+ /**
+ * Visit a parse tree produced by {@link BindingExpressionParser#inferredFormalParameterList}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitInferredFormalParameterList(BindingExpressionParser.InferredFormalParameterListContext ctx);
+ /**
+ * 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 visitUnaryOp(@NotNull BindingExpressionParser.UnaryOpContext ctx);
-
+ T visitCastOp(BindingExpressionParser.CastOpContext ctx);
/**
- * Visit a parse tree produced by the {@code AndOrOp}
+ * 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 visitAndOrOp(@NotNull BindingExpressionParser.AndOrOpContext ctx);
-
+ T visitComparisonOp(BindingExpressionParser.ComparisonOpContext ctx);
/**
- * Visit a parse tree produced by the {@code MethodInvocation}
+ * Visit a parse tree produced by the {@code UnaryOp}
* labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitMethodInvocation(@NotNull BindingExpressionParser.MethodInvocationContext ctx);
-
+ T visitUnaryOp(BindingExpressionParser.UnaryOpContext ctx);
/**
- * Visit a parse tree produced by the {@code Primary}
+ * 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 visitPrimary(@NotNull BindingExpressionParser.PrimaryContext ctx);
-
+ T visitBracketOp(BindingExpressionParser.BracketOpContext ctx);
/**
- * Visit a parse tree produced by the {@code Grouping}
+ * 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 visitGrouping(@NotNull BindingExpressionParser.GroupingContext ctx);
-
+ T visitResource(BindingExpressionParser.ResourceContext ctx);
/**
- * Visit a parse tree produced by the {@code TernaryOp}
+ * 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 visitTernaryOp(@NotNull BindingExpressionParser.TernaryOpContext ctx);
-
+ T visitQuestionQuestionOp(BindingExpressionParser.QuestionQuestionOpContext ctx);
/**
- * Visit a parse tree produced by the {@code ComparisonOp}
+ * 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 visitComparisonOp(@NotNull BindingExpressionParser.ComparisonOpContext ctx);
-
+ T visitGrouping(BindingExpressionParser.GroupingContext ctx);
/**
- * Visit a parse tree produced by the {@code DotOp}
+ * 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 visitDotOp(@NotNull BindingExpressionParser.DotOpContext ctx);
-
+ T visitMethodInvocation(BindingExpressionParser.MethodInvocationContext ctx);
/**
- * Visit a parse tree produced by the {@code MathOp}
+ * 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 visitMathOp(@NotNull BindingExpressionParser.MathOpContext ctx);
-
+ T visitBitShiftOp(BindingExpressionParser.BitShiftOpContext ctx);
/**
- * Visit a parse tree produced by the {@code QuestionQuestionOp}
+ * 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 visitQuestionQuestionOp(@NotNull BindingExpressionParser.QuestionQuestionOpContext ctx);
-
+ T visitAndOrOp(BindingExpressionParser.AndOrOpContext ctx);
/**
- * Visit a parse tree produced by the {@code BitShiftOp}
+ * 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 visitBitShiftOp(@NotNull BindingExpressionParser.BitShiftOpContext ctx);
-
+ T visitTernaryOp(BindingExpressionParser.TernaryOpContext ctx);
/**
- * Visit a parse tree produced by the {@code InstanceOfOp}
+ * 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 visitInstanceOfOp(@NotNull BindingExpressionParser.InstanceOfOpContext ctx);
-
+ T visitPrimary(BindingExpressionParser.PrimaryContext ctx);
/**
- * Visit a parse tree produced by the {@code BinaryOp}
+ * 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 visitBinaryOp(@NotNull BindingExpressionParser.BinaryOpContext ctx);
-
+ T visitDotOp(BindingExpressionParser.DotOpContext ctx);
/**
- * Visit a parse tree produced by {@link BindingExpressionParser#bindingSyntax}.
+ * 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 visitBindingSyntax(@NotNull BindingExpressionParser.BindingSyntaxContext ctx);
-
+ T visitMathOp(BindingExpressionParser.MathOpContext ctx);
/**
- * Visit a parse tree produced by {@link BindingExpressionParser#defaults}.
+ * Visit a parse tree produced by the {@code InstanceOfOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitDefaults(@NotNull BindingExpressionParser.DefaultsContext ctx);
-
+ T visitInstanceOfOp(BindingExpressionParser.InstanceOfOpContext ctx);
/**
- * Visit a parse tree produced by {@link BindingExpressionParser#constantValue}.
+ * Visit a parse tree produced by the {@code BinaryOp}
+ * labeled alternative in {@link BindingExpressionParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitConstantValue(@NotNull BindingExpressionParser.ConstantValueContext ctx);
-
+ T visitBinaryOp(BindingExpressionParser.BinaryOpContext ctx);
/**
- * Visit a parse tree produced by {@link BindingExpressionParser#expression}.
+ * 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 visitExpression(@NotNull BindingExpressionParser.ExpressionContext ctx);
-
+ T visitFunctionRef(BindingExpressionParser.FunctionRefContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#classExtraction}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitClassExtraction(@NotNull BindingExpressionParser.ClassExtractionContext ctx);
-
+ T visitClassExtraction(BindingExpressionParser.ClassExtractionContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#expressionList}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitExpressionList(@NotNull BindingExpressionParser.ExpressionListContext ctx);
-
+ T visitExpressionList(BindingExpressionParser.ExpressionListContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#literal}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitLiteral(@NotNull BindingExpressionParser.LiteralContext ctx);
-
+ T visitLiteral(BindingExpressionParser.LiteralContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#identifier}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx);
-
+ T visitIdentifier(BindingExpressionParser.IdentifierContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#javaLiteral}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitJavaLiteral(@NotNull BindingExpressionParser.JavaLiteralContext ctx);
-
+ T visitJavaLiteral(BindingExpressionParser.JavaLiteralContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#stringLiteral}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitStringLiteral(@NotNull BindingExpressionParser.StringLiteralContext ctx);
-
+ T visitStringLiteral(BindingExpressionParser.StringLiteralContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocation}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitExplicitGenericInvocation(@NotNull BindingExpressionParser.ExplicitGenericInvocationContext ctx);
-
+ T visitExplicitGenericInvocation(BindingExpressionParser.ExplicitGenericInvocationContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#typeArguments}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitTypeArguments(@NotNull BindingExpressionParser.TypeArgumentsContext ctx);
-
+ T visitTypeArguments(BindingExpressionParser.TypeArgumentsContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#type}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitType(@NotNull BindingExpressionParser.TypeContext ctx);
-
+ T visitType(BindingExpressionParser.TypeContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#explicitGenericInvocationSuffix}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitExplicitGenericInvocationSuffix(@NotNull BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
-
+ T visitExplicitGenericInvocationSuffix(BindingExpressionParser.ExplicitGenericInvocationSuffixContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#arguments}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitArguments(@NotNull BindingExpressionParser.ArgumentsContext ctx);
-
+ T visitArguments(BindingExpressionParser.ArgumentsContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#classOrInterfaceType}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitClassOrInterfaceType(@NotNull BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
-
+ T visitClassOrInterfaceType(BindingExpressionParser.ClassOrInterfaceTypeContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#primitiveType}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitPrimitiveType(@NotNull BindingExpressionParser.PrimitiveTypeContext ctx);
-
+ T visitPrimitiveType(BindingExpressionParser.PrimitiveTypeContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#resources}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitResources(@NotNull BindingExpressionParser.ResourcesContext ctx);
-
+ T visitResources(BindingExpressionParser.ResourcesContext ctx);
/**
* Visit a parse tree produced by {@link BindingExpressionParser#resourceParameters}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitResourceParameters(@NotNull BindingExpressionParser.ResourceParametersContext ctx);
+ T visitResourceParameters(BindingExpressionParser.ResourceParametersContext ctx);
} \ No newline at end of file
diff --git a/compilerCommon/src/main/java/android/databinding/tool/DataBindingBuilder.java b/compilerCommon/src/main/java/android/databinding/tool/DataBindingBuilder.java
index 0e5d757b..2a567df5 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/DataBindingBuilder.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/DataBindingBuilder.java
@@ -31,9 +31,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Properties;
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 a2ec898b..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 =
@@ -46,4 +46,18 @@ public class ErrorMessages {
"The expression %s cannot cannot be inverted: %s";
public static final String TWO_WAY_EVENT_ATTRIBUTE =
"The attribute %s is a two-way binding event attribute and cannot be assigned.";
+ public static final String CANNOT_FIND_ABSTRACT_METHOD =
+ "Cannot find the proper callback class for %s. Tried %s but it has %d abstract methods,"
+ + " should have %d abstract methods.";
+ public static final String CALLBACK_ARGUMENT_COUNT_MISMATCH = "The callback %s#%s has %s"
+ + " methods but the lambda defined has %d. It should have either 0 or equal number of"
+ + " parameters.";
+ public static final String UNDEFINED_CALLBACK_ARGUMENT =
+ "%s is not defined. It should either be a variable defined in the layout file or a"
+ + " parameter of the Callback.";
+ public static final String DUPLICATE_CALLBACK_ARGUMENT =
+ "Callback arguments must have unique names. %s is used twice or more.";
+ public static final String CALLBACK_VARIABLE_NAME_CLASH =
+ "%s in the callback definition will override the variable %s (%s) in the callback"
+ + " scope.";
}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java b/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
index 9e0a6924..98c8281d 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/Scope.java
@@ -24,6 +24,7 @@ import android.databinding.tool.util.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -40,7 +41,7 @@ public class Scope {
enter(new LocationScopeProvider() {
@Override
public List<Location> provideScopeLocation() {
- return Arrays.asList(location);
+ return Collections.singletonList(location);
}
});
}
@@ -162,7 +163,7 @@ public class Scope {
return null;
}
if (locations.size() == 1) {
- return Arrays.asList(locations.get(0).toAbsoluteLocation());
+ return Collections.singletonList(locations.get(0).toAbsoluteLocation());
}
// We have more than 1 location. Depending on the scope, we may or may not want all of them
List<Location> chosen = new ArrayList<Location>();
@@ -185,9 +186,11 @@ public class Scope {
}
List<Location> absoluteParents = findAbsoluteLocationFrom(parent,
(LocationScopeProvider) provider);
- for (Location location : absoluteParents) {
- if (location.contains(absLocation)) {
- return true;
+ if (absoluteParents != null) {
+ for (Location location : absoluteParents) {
+ if (location.contains(absLocation)) {
+ return true;
+ }
}
}
return false;
diff --git a/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java b/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
index 0f980729..a91c7ad8 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
@@ -64,7 +64,7 @@ public class ScopedException extends RuntimeException {
return sEncodeOutput ? createEncodedMessage() : createHumanReadableMessage();
}
- private String createHumanReadableMessage() {
+ public String createHumanReadableMessage() {
ScopedErrorReport scopedError = getScopedErrorReport();
StringBuilder sb = new StringBuilder();
sb.append(super.getMessage()).append("\n")
diff --git a/compilerCommon/src/main/java/android/databinding/tool/util/L.java b/compilerCommon/src/main/java/android/databinding/tool/util/L.java
index 37292b2b..b7c8f3de 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/util/L.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/L.java
@@ -16,7 +16,9 @@
package android.databinding.tool.util;
+import android.databinding.tool.processing.ScopedErrorReport;
import android.databinding.tool.processing.ScopedException;
+import android.databinding.tool.processing.scopes.LocationScopeProvider;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -113,6 +115,14 @@ public class L {
}
private static void printMessage(Element element, Diagnostic.Kind kind, String message) {
+ if (kind == Kind.WARNING) {
+ // try to convert it to a scoped message
+ ScopedException ex = new ScopedException(message);
+ if (ex.isValid()) {
+ sClient.printMessage(kind, ex.createHumanReadableMessage(), element);
+ return;
+ }
+ }
sClient.printMessage(kind, message, element);
if (kind == Diagnostic.Kind.ERROR) {
throw new RuntimeException("failure, see logs for details.\n" + message);
diff --git a/compilerCommon/src/main/java/android/databinding/tool/util/StringUtils.java b/compilerCommon/src/main/java/android/databinding/tool/util/StringUtils.java
index 5f535baf..5774183a 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/util/StringUtils.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/StringUtils.java
@@ -19,8 +19,6 @@ package android.databinding.tool.util;
import com.google.common.base.StandardSystemProperty;
import com.google.common.base.Strings;
-import org.antlr.v4.runtime.misc.Nullable;
-
public class StringUtils {
public static final String LINE_SEPARATOR = StandardSystemProperty.LINE_SEPARATOR.value();
@@ -41,7 +39,7 @@ public class StringUtils {
/** The entity for the line feed character */
private static final String LFEED_ENTITY = "&#xA;";
- public static boolean isNotBlank(@Nullable CharSequence string) {
+ public static boolean isNotBlank(CharSequence string) {
if (string == null) {
return false;
}
@@ -53,7 +51,7 @@ public class StringUtils {
return false;
}
- public static String capitalize(@Nullable String string) {
+ public static String capitalize(String string) {
if (Strings.isNullOrEmpty(string)) {
return string;
}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java b/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java
index e5a3da28..62554168 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/util/XmlEditor.java
@@ -16,6 +16,7 @@
package android.databinding.tool.util;
+import android.databinding.parser.BindingExpressionBaseVisitor;
import android.databinding.parser.BindingExpressionLexer;
import android.databinding.parser.BindingExpressionParser;
import android.databinding.parser.XMLLexer;
@@ -29,6 +30,7 @@ import com.google.common.xml.XmlEscapers;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.commons.io.FileUtils;
@@ -69,7 +71,7 @@ public class XmlEditor {
}
ArrayList<String> lines = new ArrayList<String>();
- lines.addAll(FileUtils.readLines(f, "utf-8"));
+ lines.addAll(FileUtils.readLines(f, encoding));
for (ElementContext it : dataNodes) {
replace(lines, toPosition(it.getStart()), toEndPosition(it.getStop()), "");
@@ -343,7 +345,14 @@ public class XmlEditor {
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax();
- BindingExpressionParser.DefaultsContext defaults = root.defaults();
+ BindingExpressionParser.DefaultsContext defaults = root
+ .accept(new BindingExpressionBaseVisitor<BindingExpressionParser.DefaultsContext>() {
+ @Override
+ public BindingExpressionParser.DefaultsContext visitDefaults(
+ @NotNull BindingExpressionParser.DefaultsContext ctx) {
+ return ctx;
+ }
+ });
if (defaults != null) {
BindingExpressionParser.ConstantValueContext constantValue = defaults
.constantValue();
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java
index b8c79bb7..352a2f10 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.java
@@ -1,13 +1,21 @@
-// Generated from XMLLexer.g4 by ANTLR 4.4
+// Generated from XMLLexer.g4 by ANTLR 4.5.3
package android.databinding.parser;
-
-import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
-import org.antlr.v4.runtime.atn.ATN;
-import org.antlr.v4.runtime.atn.ATNDeserializer;
-import org.antlr.v4.runtime.atn.LexerATNSimulator;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class XMLLexer extends Lexer {
+ static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
public static final int
COMMENT=1, CDATA=2, DTD=3, EntityRef=4, CharRef=5, SEA_WS=6, OPEN=7, XMLDeclOpen=8,
TEXT=9, CLOSE=10, SPECIAL_CLOSE=11, SLASH_CLOSE=12, SLASH=13, EQUALS=14,
@@ -18,11 +26,6 @@ public class XMLLexer extends Lexer {
"DEFAULT_MODE", "INSIDE", "PROC_INSTR"
};
- public static final String[] tokenNames = {
- "'\\u0000'", "'\\u0001'", "'\\u0002'", "'\\u0003'", "'\\u0004'", "'\\u0005'",
- "'\\u0006'", "'\\u0007'", "'\b'", "'\t'", "'\n'", "'\\u000B'", "'\f'",
- "'\r'", "'\\u000E'", "'\\u000F'", "'\\u0010'", "'\\u0011'", "'\\u0012'"
- };
public static final String[] ruleNames = {
"COMMENT", "CDATA", "DTD", "EntityRef", "CharRef", "SEA_WS", "OPEN", "XMLDeclOpen",
"SPECIAL_OPEN", "TEXT", "CLOSE", "SPECIAL_CLOSE", "SLASH_CLOSE", "SLASH",
@@ -30,19 +33,58 @@ public class XMLLexer extends Lexer {
"PI", "IGNORE"
};
+ private static final String[] _LITERAL_NAMES = {
+ null, null, null, null, null, null, null, "'<'", null, null, "'>'", null,
+ "'/>'", "'/'", "'='"
+ };
+ private static final String[] _SYMBOLIC_NAMES = {
+ null, "COMMENT", "CDATA", "DTD", "EntityRef", "CharRef", "SEA_WS", "OPEN",
+ "XMLDeclOpen", "TEXT", "CLOSE", "SPECIAL_CLOSE", "SLASH_CLOSE", "SLASH",
+ "EQUALS", "STRING", "Name", "S", "PI"
+ };
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "<INVALID>";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
public XMLLexer(CharStream input) {
super(input);
- _interp = new LexerATNSimulator(this,_ATN);
+ _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "XMLLexer.g4"; }
@Override
- public String[] getTokenNames() { return tokenNames; }
-
- @Override
public String[] getRuleNames() { return ruleNames; }
@Override
@@ -51,8 +93,11 @@ public class XMLLexer extends Lexer {
@Override
public String[] getModeNames() { return modeNames; }
+ @Override
+ public ATN getATN() { return _ATN; }
+
public static final String _serializedATN =
- "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\2\24\u00e9\b\1\b\1"+
+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\24\u00e9\b\1\b\1"+
"\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"+
@@ -69,68 +114,71 @@ public class XMLLexer extends Lexer {
"\13\21\3\21\5\21\u00c7\n\21\3\22\3\22\7\22\u00cb\n\22\f\22\16\22\u00ce"+
"\13\22\3\23\3\23\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\26\3\26\5\26"+
"\u00dc\n\26\3\27\5\27\u00df\n\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3"+
- "\31\3\31\5=Q^\2\2\32\5\2\3\7\2\4\t\2\5\13\2\6\r\2\7\17\2\b\21\2\t\23\2"+
- "\n\25\2\2\27\2\13\31\2\f\33\2\r\35\2\16\37\2\17!\2\20#\2\21%\2\22\'\2"+
- "\23)\2\2+\2\2-\2\2/\2\2\61\2\24\63\2\2\5\2\3\4\f\4\2\13\13\"\"\4\2((>"+
- ">\4\2$$>>\4\2))>>\5\2\13\f\17\17\"\"\5\2\62;CHch\3\2\62;\4\2/\60aa\5\2"+
- "\u00b9\u00b9\u0302\u0371\u2041\u2042\n\2<<C\\c|\u2072\u2191\u2c02\u2ff1"+
- "\u3003\ud801\uf902\ufdd1\ufdf2\uffff\u00f3\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\3\31\3\2\2\2\3\33\3\2\2\2\3\35\3\2\2\2\3"+
- "\37\3\2\2\2\3!\3\2\2\2\3#\3\2\2\2\3%\3\2\2\2\3\'\3\2\2\2\4\61\3\2\2\2"+
- "\4\63\3\2\2\2\5\65\3\2\2\2\7D\3\2\2\2\tX\3\2\2\2\13e\3\2\2\2\r~\3\2\2"+
- "\2\17\u0085\3\2\2\2\21\u0089\3\2\2\2\23\u008d\3\2\2\2\25\u0097\3\2\2\2"+
- "\27\u00a0\3\2\2\2\31\u00a4\3\2\2\2\33\u00a8\3\2\2\2\35\u00ad\3\2\2\2\37"+
- "\u00b2\3\2\2\2!\u00b4\3\2\2\2#\u00c6\3\2\2\2%\u00c8\3\2\2\2\'\u00cf\3"+
- "\2\2\2)\u00d3\3\2\2\2+\u00d5\3\2\2\2-\u00db\3\2\2\2/\u00de\3\2\2\2\61"+
- "\u00e0\3\2\2\2\63\u00e5\3\2\2\2\65\66\7>\2\2\66\67\7#\2\2\678\7/\2\28"+
- "9\7/\2\29=\3\2\2\2:<\13\2\2\2;:\3\2\2\2<?\3\2\2\2=>\3\2\2\2=;\3\2\2\2"+
- ">@\3\2\2\2?=\3\2\2\2@A\7/\2\2AB\7/\2\2BC\7@\2\2C\6\3\2\2\2DE\7>\2\2EF"+
- "\7#\2\2FG\7]\2\2GH\7E\2\2HI\7F\2\2IJ\7C\2\2JK\7V\2\2KL\7C\2\2LM\7]\2\2"+
- "MQ\3\2\2\2NP\13\2\2\2ON\3\2\2\2PS\3\2\2\2QR\3\2\2\2QO\3\2\2\2RT\3\2\2"+
- "\2SQ\3\2\2\2TU\7_\2\2UV\7_\2\2VW\7@\2\2W\b\3\2\2\2XY\7>\2\2YZ\7#\2\2Z"+
- "^\3\2\2\2[]\13\2\2\2\\[\3\2\2\2]`\3\2\2\2^_\3\2\2\2^\\\3\2\2\2_a\3\2\2"+
- "\2`^\3\2\2\2ab\7@\2\2bc\3\2\2\2cd\b\4\2\2d\n\3\2\2\2ef\7(\2\2fg\5%\22"+
- "\2gh\7=\2\2h\f\3\2\2\2ij\7(\2\2jk\7%\2\2km\3\2\2\2ln\5+\25\2ml\3\2\2\2"+
- "no\3\2\2\2om\3\2\2\2op\3\2\2\2pq\3\2\2\2qr\7=\2\2r\177\3\2\2\2st\7(\2"+
- "\2tu\7%\2\2uv\7z\2\2vx\3\2\2\2wy\5)\24\2xw\3\2\2\2yz\3\2\2\2zx\3\2\2\2"+
- "z{\3\2\2\2{|\3\2\2\2|}\7=\2\2}\177\3\2\2\2~i\3\2\2\2~s\3\2\2\2\177\16"+
- "\3\2\2\2\u0080\u0086\t\2\2\2\u0081\u0083\7\17\2\2\u0082\u0081\3\2\2\2"+
- "\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0086\7\f\2\2\u0085\u0080"+
- "\3\2\2\2\u0085\u0082\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0085\3\2\2\2\u0087"+
- "\u0088\3\2\2\2\u0088\20\3\2\2\2\u0089\u008a\7>\2\2\u008a\u008b\3\2\2\2"+
- "\u008b\u008c\b\b\3\2\u008c\22\3\2\2\2\u008d\u008e\7>\2\2\u008e\u008f\7"+
- "A\2\2\u008f\u0090\7z\2\2\u0090\u0091\7o\2\2\u0091\u0092\7n\2\2\u0092\u0093"+
- "\3\2\2\2\u0093\u0094\5\'\23\2\u0094\u0095\3\2\2\2\u0095\u0096\b\t\3\2"+
- "\u0096\24\3\2\2\2\u0097\u0098\7>\2\2\u0098\u0099\7A\2\2\u0099\u009a\3"+
- "\2\2\2\u009a\u009b\5%\22\2\u009b\u009c\3\2\2\2\u009c\u009d\b\n\4\2\u009d"+
- "\u009e\b\n\5\2\u009e\26\3\2\2\2\u009f\u00a1\n\3\2\2\u00a0\u009f\3\2\2"+
- "\2\u00a1\u00a2\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3\30"+
- "\3\2\2\2\u00a4\u00a5\7@\2\2\u00a5\u00a6\3\2\2\2\u00a6\u00a7\b\f\6\2\u00a7"+
- "\32\3\2\2\2\u00a8\u00a9\7A\2\2\u00a9\u00aa\7@\2\2\u00aa\u00ab\3\2\2\2"+
- "\u00ab\u00ac\b\r\6\2\u00ac\34\3\2\2\2\u00ad\u00ae\7\61\2\2\u00ae\u00af"+
- "\7@\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\b\16\6\2\u00b1\36\3\2\2\2\u00b2"+
- "\u00b3\7\61\2\2\u00b3 \3\2\2\2\u00b4\u00b5\7?\2\2\u00b5\"\3\2\2\2\u00b6"+
- "\u00ba\7$\2\2\u00b7\u00b9\n\4\2\2\u00b8\u00b7\3\2\2\2\u00b9\u00bc\3\2"+
- "\2\2\u00ba\u00b8\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb\u00bd\3\2\2\2\u00bc"+
- "\u00ba\3\2\2\2\u00bd\u00c7\7$\2\2\u00be\u00c2\7)\2\2\u00bf\u00c1\n\5\2"+
- "\2\u00c0\u00bf\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2\u00c0\3\2\2\2\u00c2\u00c3"+
- "\3\2\2\2\u00c3\u00c5\3\2\2\2\u00c4\u00c2\3\2\2\2\u00c5\u00c7\7)\2\2\u00c6"+
- "\u00b6\3\2\2\2\u00c6\u00be\3\2\2\2\u00c7$\3\2\2\2\u00c8\u00cc\5/\27\2"+
- "\u00c9\u00cb\5-\26\2\u00ca\u00c9\3\2\2\2\u00cb\u00ce\3\2\2\2\u00cc\u00ca"+
- "\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd&\3\2\2\2\u00ce\u00cc\3\2\2\2\u00cf"+
- "\u00d0\t\6\2\2\u00d0\u00d1\3\2\2\2\u00d1\u00d2\b\23\2\2\u00d2(\3\2\2\2"+
- "\u00d3\u00d4\t\7\2\2\u00d4*\3\2\2\2\u00d5\u00d6\t\b\2\2\u00d6,\3\2\2\2"+
- "\u00d7\u00dc\5/\27\2\u00d8\u00dc\t\t\2\2\u00d9\u00dc\5+\25\2\u00da\u00dc"+
- "\t\n\2\2\u00db\u00d7\3\2\2\2\u00db\u00d8\3\2\2\2\u00db\u00d9\3\2\2\2\u00db"+
- "\u00da\3\2\2\2\u00dc.\3\2\2\2\u00dd\u00df\t\13\2\2\u00de\u00dd\3\2\2\2"+
- "\u00df\60\3\2\2\2\u00e0\u00e1\7A\2\2\u00e1\u00e2\7@\2\2\u00e2\u00e3\3"+
- "\2\2\2\u00e3\u00e4\b\30\6\2\u00e4\62\3\2\2\2\u00e5\u00e6\13\2\2\2\u00e6"+
- "\u00e7\3\2\2\2\u00e7\u00e8\b\31\4\2\u00e8\64\3\2\2\2\25\2\3\4=Q^oz~\u0082"+
- "\u0085\u0087\u00a2\u00ba\u00c2\u00c6\u00cc\u00db\u00de\7\b\2\2\7\3\2\5"+
- "\2\2\7\4\2\6\2\2";
+ "\31\3\31\5=Q^\2\32\5\3\7\4\t\5\13\6\r\7\17\b\21\t\23\n\25\2\27\13\31\f"+
+ "\33\r\35\16\37\17!\20#\21%\22\'\23)\2+\2-\2/\2\61\24\63\2\5\2\3\4\f\4"+
+ "\2\13\13\"\"\4\2((>>\4\2$$>>\4\2))>>\5\2\13\f\17\17\"\"\5\2\62;CHch\3"+
+ "\2\62;\4\2/\60aa\5\2\u00b9\u00b9\u0302\u0371\u2041\u2042\n\2<<C\\c|\u2072"+
+ "\u2191\u2c02\u2ff1\u3003\ud801\uf902\ufdd1\ufdf2\uffff\u00f3\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\3\31\3\2\2\2\3\33\3\2"+
+ "\2\2\3\35\3\2\2\2\3\37\3\2\2\2\3!\3\2\2\2\3#\3\2\2\2\3%\3\2\2\2\3\'\3"+
+ "\2\2\2\4\61\3\2\2\2\4\63\3\2\2\2\5\65\3\2\2\2\7D\3\2\2\2\tX\3\2\2\2\13"+
+ "e\3\2\2\2\r~\3\2\2\2\17\u0085\3\2\2\2\21\u0089\3\2\2\2\23\u008d\3\2\2"+
+ "\2\25\u0097\3\2\2\2\27\u00a0\3\2\2\2\31\u00a4\3\2\2\2\33\u00a8\3\2\2\2"+
+ "\35\u00ad\3\2\2\2\37\u00b2\3\2\2\2!\u00b4\3\2\2\2#\u00c6\3\2\2\2%\u00c8"+
+ "\3\2\2\2\'\u00cf\3\2\2\2)\u00d3\3\2\2\2+\u00d5\3\2\2\2-\u00db\3\2\2\2"+
+ "/\u00de\3\2\2\2\61\u00e0\3\2\2\2\63\u00e5\3\2\2\2\65\66\7>\2\2\66\67\7"+
+ "#\2\2\678\7/\2\289\7/\2\29=\3\2\2\2:<\13\2\2\2;:\3\2\2\2<?\3\2\2\2=>\3"+
+ "\2\2\2=;\3\2\2\2>@\3\2\2\2?=\3\2\2\2@A\7/\2\2AB\7/\2\2BC\7@\2\2C\6\3\2"+
+ "\2\2DE\7>\2\2EF\7#\2\2FG\7]\2\2GH\7E\2\2HI\7F\2\2IJ\7C\2\2JK\7V\2\2KL"+
+ "\7C\2\2LM\7]\2\2MQ\3\2\2\2NP\13\2\2\2ON\3\2\2\2PS\3\2\2\2QR\3\2\2\2QO"+
+ "\3\2\2\2RT\3\2\2\2SQ\3\2\2\2TU\7_\2\2UV\7_\2\2VW\7@\2\2W\b\3\2\2\2XY\7"+
+ ">\2\2YZ\7#\2\2Z^\3\2\2\2[]\13\2\2\2\\[\3\2\2\2]`\3\2\2\2^_\3\2\2\2^\\"+
+ "\3\2\2\2_a\3\2\2\2`^\3\2\2\2ab\7@\2\2bc\3\2\2\2cd\b\4\2\2d\n\3\2\2\2e"+
+ "f\7(\2\2fg\5%\22\2gh\7=\2\2h\f\3\2\2\2ij\7(\2\2jk\7%\2\2km\3\2\2\2ln\5"+
+ "+\25\2ml\3\2\2\2no\3\2\2\2om\3\2\2\2op\3\2\2\2pq\3\2\2\2qr\7=\2\2r\177"+
+ "\3\2\2\2st\7(\2\2tu\7%\2\2uv\7z\2\2vx\3\2\2\2wy\5)\24\2xw\3\2\2\2yz\3"+
+ "\2\2\2zx\3\2\2\2z{\3\2\2\2{|\3\2\2\2|}\7=\2\2}\177\3\2\2\2~i\3\2\2\2~"+
+ "s\3\2\2\2\177\16\3\2\2\2\u0080\u0086\t\2\2\2\u0081\u0083\7\17\2\2\u0082"+
+ "\u0081\3\2\2\2\u0082\u0083\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0086\7\f"+
+ "\2\2\u0085\u0080\3\2\2\2\u0085\u0082\3\2\2\2\u0086\u0087\3\2\2\2\u0087"+
+ "\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\20\3\2\2\2\u0089\u008a\7>\2\2"+
+ "\u008a\u008b\3\2\2\2\u008b\u008c\b\b\3\2\u008c\22\3\2\2\2\u008d\u008e"+
+ "\7>\2\2\u008e\u008f\7A\2\2\u008f\u0090\7z\2\2\u0090\u0091\7o\2\2\u0091"+
+ "\u0092\7n\2\2\u0092\u0093\3\2\2\2\u0093\u0094\5\'\23\2\u0094\u0095\3\2"+
+ "\2\2\u0095\u0096\b\t\3\2\u0096\24\3\2\2\2\u0097\u0098\7>\2\2\u0098\u0099"+
+ "\7A\2\2\u0099\u009a\3\2\2\2\u009a\u009b\5%\22\2\u009b\u009c\3\2\2\2\u009c"+
+ "\u009d\b\n\4\2\u009d\u009e\b\n\5\2\u009e\26\3\2\2\2\u009f\u00a1\n\3\2"+
+ "\2\u00a0\u009f\3\2\2\2\u00a1\u00a2\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a2\u00a3"+
+ "\3\2\2\2\u00a3\30\3\2\2\2\u00a4\u00a5\7@\2\2\u00a5\u00a6\3\2\2\2\u00a6"+
+ "\u00a7\b\f\6\2\u00a7\32\3\2\2\2\u00a8\u00a9\7A\2\2\u00a9\u00aa\7@\2\2"+
+ "\u00aa\u00ab\3\2\2\2\u00ab\u00ac\b\r\6\2\u00ac\34\3\2\2\2\u00ad\u00ae"+
+ "\7\61\2\2\u00ae\u00af\7@\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\b\16\6\2"+
+ "\u00b1\36\3\2\2\2\u00b2\u00b3\7\61\2\2\u00b3 \3\2\2\2\u00b4\u00b5\7?\2"+
+ "\2\u00b5\"\3\2\2\2\u00b6\u00ba\7$\2\2\u00b7\u00b9\n\4\2\2\u00b8\u00b7"+
+ "\3\2\2\2\u00b9\u00bc\3\2\2\2\u00ba\u00b8\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb"+
+ "\u00bd\3\2\2\2\u00bc\u00ba\3\2\2\2\u00bd\u00c7\7$\2\2\u00be\u00c2\7)\2"+
+ "\2\u00bf\u00c1\n\5\2\2\u00c0\u00bf\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2\u00c0"+
+ "\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3\u00c5\3\2\2\2\u00c4\u00c2\3\2\2\2\u00c5"+
+ "\u00c7\7)\2\2\u00c6\u00b6\3\2\2\2\u00c6\u00be\3\2\2\2\u00c7$\3\2\2\2\u00c8"+
+ "\u00cc\5/\27\2\u00c9\u00cb\5-\26\2\u00ca\u00c9\3\2\2\2\u00cb\u00ce\3\2"+
+ "\2\2\u00cc\u00ca\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd&\3\2\2\2\u00ce\u00cc"+
+ "\3\2\2\2\u00cf\u00d0\t\6\2\2\u00d0\u00d1\3\2\2\2\u00d1\u00d2\b\23\2\2"+
+ "\u00d2(\3\2\2\2\u00d3\u00d4\t\7\2\2\u00d4*\3\2\2\2\u00d5\u00d6\t\b\2\2"+
+ "\u00d6,\3\2\2\2\u00d7\u00dc\5/\27\2\u00d8\u00dc\t\t\2\2\u00d9\u00dc\5"+
+ "+\25\2\u00da\u00dc\t\n\2\2\u00db\u00d7\3\2\2\2\u00db\u00d8\3\2\2\2\u00db"+
+ "\u00d9\3\2\2\2\u00db\u00da\3\2\2\2\u00dc.\3\2\2\2\u00dd\u00df\t\13\2\2"+
+ "\u00de\u00dd\3\2\2\2\u00df\60\3\2\2\2\u00e0\u00e1\7A\2\2\u00e1\u00e2\7"+
+ "@\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\b\30\6\2\u00e4\62\3\2\2\2\u00e5"+
+ "\u00e6\13\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\u00e8\b\31\4\2\u00e8\64\3\2"+
+ "\2\2\25\2\3\4=Q^oz~\u0082\u0085\u0087\u00a2\u00ba\u00c2\u00c6\u00cc\u00db"+
+ "\u00de\7\b\2\2\7\3\2\5\2\2\7\4\2\6\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
}
} \ No newline at end of file
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
index cd122a48..d80683d7 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLLexer.tokens
@@ -1,23 +1,23 @@
-OPEN=7
+COMMENT=1
CDATA=2
-SLASH=13
+DTD=3
+EntityRef=4
CharRef=5
SEA_WS=6
-SPECIAL_CLOSE=11
+OPEN=7
+XMLDeclOpen=8
+TEXT=9
CLOSE=10
-DTD=3
-Name=16
-EQUALS=14
-PI=18
-S=17
+SPECIAL_CLOSE=11
SLASH_CLOSE=12
-TEXT=9
-COMMENT=1
-XMLDeclOpen=8
-EntityRef=4
+SLASH=13
+EQUALS=14
STRING=15
-'='=14
-'/'=13
+Name=16
+S=17
+PI=18
'<'=7
-'/>'=12
'>'=10
+'/>'=12
+'/'=13
+'='=14
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
index a3757804..5eaad942 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.java
@@ -1,4 +1,4 @@
-// Generated from XMLParser.g4 by ANTLR 4.4
+// Generated from XMLParser.g4 by ANTLR 4.5.3
package android.databinding.parser;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
@@ -6,17 +6,20 @@ import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class XMLParser extends Parser {
+ static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
public static final int
- OPEN=7, CDATA=2, SLASH=13, CharRef=5, SEA_WS=6, SPECIAL_CLOSE=11, CLOSE=10,
- DTD=3, Name=16, EQUALS=14, PI=18, S=17, SLASH_CLOSE=12, TEXT=9, COMMENT=1,
- XMLDeclOpen=8, EntityRef=4, STRING=15;
- public static final String[] tokenNames = {
- "<INVALID>", "COMMENT", "CDATA", "DTD", "EntityRef", "CharRef", "SEA_WS",
- "'<'", "XMLDeclOpen", "TEXT", "'>'", "SPECIAL_CLOSE", "'/>'", "'/'", "'='",
- "STRING", "Name", "S", "PI"
- };
+ COMMENT=1, CDATA=2, DTD=3, EntityRef=4, CharRef=5, SEA_WS=6, OPEN=7, XMLDeclOpen=8,
+ TEXT=9, CLOSE=10, SPECIAL_CLOSE=11, SLASH_CLOSE=12, SLASH=13, EQUALS=14,
+ STRING=15, Name=16, S=17, PI=18;
public static final int
RULE_document = 0, RULE_prolog = 1, RULE_content = 2, RULE_element = 3,
RULE_reference = 4, RULE_attribute = 5, RULE_chardata = 6, RULE_misc = 7;
@@ -25,11 +28,50 @@ public class XMLParser extends Parser {
"chardata", "misc"
};
+ private static final String[] _LITERAL_NAMES = {
+ null, null, null, null, null, null, null, "'<'", null, null, "'>'", null,
+ "'/>'", "'/'", "'='"
+ };
+ private static final String[] _SYMBOLIC_NAMES = {
+ null, "COMMENT", "CDATA", "DTD", "EntityRef", "CharRef", "SEA_WS", "OPEN",
+ "XMLDeclOpen", "TEXT", "CLOSE", "SPECIAL_CLOSE", "SLASH_CLOSE", "SLASH",
+ "EQUALS", "STRING", "Name", "S", "PI"
+ };
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "<INVALID>";
+ }
+ }
+ }
+
@Override
- public String getGrammarFileName() { return "XMLParser.g4"; }
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
@Override
- public String[] getTokenNames() { return tokenNames; }
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+ @Override
+ public String getGrammarFileName() { return "XMLParser.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@@ -37,20 +79,23 @@ public class XMLParser extends Parser {
@Override
public String getSerializedATN() { return _serializedATN; }
+ @Override
+ public ATN getATN() { return _ATN; }
+
public XMLParser(TokenStream input) {
super(input);
- _interp = new ParserATNSimulator(this,_ATN);
+ _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
public static class DocumentContext extends ParserRuleContext {
public ElementContext element() {
return getRuleContext(ElementContext.class,0);
}
- public List<? extends MiscContext> misc() {
- return getRuleContexts(MiscContext.class);
- }
public PrologContext prolog() {
return getRuleContext(PrologContext.class,0);
}
+ public List<MiscContext> misc() {
+ return getRuleContexts(MiscContext.class);
+ }
public MiscContext misc(int i) {
return getRuleContext(MiscContext.class,i);
}
@@ -67,13 +112,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitDocument(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitDocument(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitDocument(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final DocumentContext document() throws RecognitionException {
DocumentContext _localctx = new DocumentContext(_ctx, getState());
enterRule(_localctx, 0, RULE_document);
@@ -85,7 +129,8 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if (_la==XMLDeclOpen) {
{
- setState(16); prolog();
+ setState(16);
+ prolog();
}
}
@@ -95,21 +140,24 @@ public class XMLParser extends Parser {
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << COMMENT) | (1L << SEA_WS) | (1L << PI))) != 0)) {
{
{
- setState(19); misc();
+ setState(19);
+ misc();
}
}
setState(24);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(25); element();
+ setState(25);
+ element();
setState(29);
_errHandler.sync(this);
_la = _input.LA(1);
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << COMMENT) | (1L << SEA_WS) | (1L << PI))) != 0)) {
{
{
- setState(26); misc();
+ setState(26);
+ misc();
}
}
setState(31);
@@ -130,14 +178,14 @@ public class XMLParser extends Parser {
}
public static class PrologContext extends ParserRuleContext {
+ public TerminalNode XMLDeclOpen() { return getToken(XMLParser.XMLDeclOpen, 0); }
public TerminalNode SPECIAL_CLOSE() { return getToken(XMLParser.SPECIAL_CLOSE, 0); }
- public List<? extends AttributeContext> attribute() {
+ public List<AttributeContext> attribute() {
return getRuleContexts(AttributeContext.class);
}
public AttributeContext attribute(int i) {
return getRuleContext(AttributeContext.class,i);
}
- public TerminalNode XMLDeclOpen() { return getToken(XMLParser.XMLDeclOpen, 0); }
public PrologContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -151,13 +199,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitProlog(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitProlog(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitProlog(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final PrologContext prolog() throws RecognitionException {
PrologContext _localctx = new PrologContext(_ctx, getState());
enterRule(_localctx, 2, RULE_prolog);
@@ -165,21 +212,24 @@ public class XMLParser extends Parser {
try {
enterOuterAlt(_localctx, 1);
{
- setState(32); match(XMLDeclOpen);
+ setState(32);
+ match(XMLDeclOpen);
setState(36);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==Name) {
{
{
- setState(33); attribute();
+ setState(33);
+ attribute();
}
}
setState(38);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(39); match(SPECIAL_CLOSE);
+ setState(39);
+ match(SPECIAL_CLOSE);
}
}
catch (RecognitionException re) {
@@ -194,35 +244,35 @@ public class XMLParser extends Parser {
}
public static class ContentContext extends ParserRuleContext {
- public List<? extends TerminalNode> PI() { return getTokens(XMLParser.PI); }
- public List<? extends TerminalNode> CDATA() { return getTokens(XMLParser.CDATA); }
- public List<? extends ElementContext> element() {
- return getRuleContexts(ElementContext.class);
+ public List<ChardataContext> chardata() {
+ return getRuleContexts(ChardataContext.class);
}
- public TerminalNode PI(int i) {
- return getToken(XMLParser.PI, i);
+ public ChardataContext chardata(int i) {
+ return getRuleContext(ChardataContext.class,i);
+ }
+ public List<ElementContext> element() {
+ return getRuleContexts(ElementContext.class);
}
public ElementContext element(int i) {
return getRuleContext(ElementContext.class,i);
}
- public TerminalNode COMMENT(int i) {
- return getToken(XMLParser.COMMENT, i);
- }
- public TerminalNode CDATA(int i) {
- return getToken(XMLParser.CDATA, i);
+ public List<ReferenceContext> reference() {
+ return getRuleContexts(ReferenceContext.class);
}
public ReferenceContext reference(int i) {
return getRuleContext(ReferenceContext.class,i);
}
- public List<? extends TerminalNode> COMMENT() { return getTokens(XMLParser.COMMENT); }
- public ChardataContext chardata(int i) {
- return getRuleContext(ChardataContext.class,i);
+ public List<TerminalNode> CDATA() { return getTokens(XMLParser.CDATA); }
+ public TerminalNode CDATA(int i) {
+ return getToken(XMLParser.CDATA, i);
}
- public List<? extends ChardataContext> chardata() {
- return getRuleContexts(ChardataContext.class);
+ public List<TerminalNode> PI() { return getTokens(XMLParser.PI); }
+ public TerminalNode PI(int i) {
+ return getToken(XMLParser.PI, i);
}
- public List<? extends ReferenceContext> reference() {
- return getRuleContexts(ReferenceContext.class);
+ public List<TerminalNode> COMMENT() { return getTokens(XMLParser.COMMENT); }
+ public TerminalNode COMMENT(int i) {
+ return getToken(XMLParser.COMMENT, i);
}
public ContentContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
@@ -237,13 +287,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitContent(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitContent(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitContent(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ContentContext content() throws RecognitionException {
ContentContext _localctx = new ContentContext(_ctx, getState());
enterRule(_localctx, 4, RULE_content);
@@ -256,7 +305,8 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if (_la==SEA_WS || _la==TEXT) {
{
- setState(41); chardata();
+ setState(41);
+ chardata();
}
}
@@ -271,28 +321,33 @@ public class XMLParser extends Parser {
switch (_input.LA(1)) {
case OPEN:
{
- setState(44); element();
+ setState(44);
+ element();
}
break;
case EntityRef:
case CharRef:
{
- setState(45); reference();
+ setState(45);
+ reference();
}
break;
case CDATA:
{
- setState(46); match(CDATA);
+ setState(46);
+ match(CDATA);
}
break;
case PI:
{
- setState(47); match(PI);
+ setState(47);
+ match(PI);
}
break;
case COMMENT:
{
- setState(48); match(COMMENT);
+ setState(48);
+ match(COMMENT);
}
break;
default:
@@ -302,7 +357,8 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if (_la==SEA_WS || _la==TEXT) {
{
- setState(51); chardata();
+ setState(51);
+ chardata();
}
}
@@ -328,18 +384,18 @@ public class XMLParser extends Parser {
public static class ElementContext extends ParserRuleContext {
public Token elmName;
- public List<? extends AttributeContext> attribute() {
- return getRuleContexts(AttributeContext.class);
- }
- public AttributeContext attribute(int i) {
- return getRuleContext(AttributeContext.class,i);
+ public ContentContext content() {
+ return getRuleContext(ContentContext.class,0);
}
+ public List<TerminalNode> Name() { return getTokens(XMLParser.Name); }
public TerminalNode Name(int i) {
return getToken(XMLParser.Name, i);
}
- public List<? extends TerminalNode> Name() { return getTokens(XMLParser.Name); }
- public ContentContext content() {
- return getRuleContext(ContentContext.class,0);
+ public List<AttributeContext> attribute() {
+ return getRuleContexts(AttributeContext.class);
+ }
+ public AttributeContext attribute(int i) {
+ return getRuleContext(AttributeContext.class,i);
}
public ElementContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
@@ -354,66 +410,78 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitElement(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitElement(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitElement(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ElementContext element() throws RecognitionException {
ElementContext _localctx = new ElementContext(_ctx, getState());
enterRule(_localctx, 6, RULE_element);
int _la;
try {
setState(83);
+ _errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(59); match(OPEN);
- setState(60); _localctx.elmName = match(Name);
+ setState(59);
+ match(OPEN);
+ setState(60);
+ ((ElementContext)_localctx).elmName = match(Name);
setState(64);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==Name) {
{
{
- setState(61); attribute();
+ setState(61);
+ attribute();
}
}
setState(66);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(67); match(CLOSE);
- setState(68); content();
- setState(69); match(OPEN);
- setState(70); match(SLASH);
- setState(71); match(Name);
- setState(72); match(CLOSE);
+ setState(67);
+ match(CLOSE);
+ setState(68);
+ content();
+ setState(69);
+ match(OPEN);
+ setState(70);
+ match(SLASH);
+ setState(71);
+ match(Name);
+ setState(72);
+ match(CLOSE);
}
break;
-
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(74); match(OPEN);
- setState(75); _localctx.elmName = match(Name);
+ setState(74);
+ match(OPEN);
+ setState(75);
+ ((ElementContext)_localctx).elmName = match(Name);
setState(79);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==Name) {
{
{
- setState(76); attribute();
+ setState(76);
+ attribute();
}
}
setState(81);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(82); match(SLASH_CLOSE);
+ setState(82);
+ match(SLASH_CLOSE);
}
break;
}
@@ -430,8 +498,8 @@ public class XMLParser extends Parser {
}
public static class ReferenceContext extends ParserRuleContext {
- public TerminalNode CharRef() { return getToken(XMLParser.CharRef, 0); }
public TerminalNode EntityRef() { return getToken(XMLParser.EntityRef, 0); }
+ public TerminalNode CharRef() { return getToken(XMLParser.CharRef, 0); }
public ReferenceContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -445,13 +513,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitReference(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitReference(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitReference(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ReferenceContext reference() throws RecognitionException {
ReferenceContext _localctx = new ReferenceContext(_ctx, getState());
enterRule(_localctx, 8, RULE_reference);
@@ -463,8 +530,9 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if ( !(_la==EntityRef || _la==CharRef) ) {
_errHandler.recoverInline(this);
+ } else {
+ consume();
}
- consume();
}
}
catch (RecognitionException re) {
@@ -496,22 +564,24 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitAttribute(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitAttribute(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitAttribute(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final AttributeContext attribute() throws RecognitionException {
AttributeContext _localctx = new AttributeContext(_ctx, getState());
enterRule(_localctx, 10, RULE_attribute);
try {
enterOuterAlt(_localctx, 1);
{
- setState(87); _localctx.attrName = match(Name);
- setState(88); match(EQUALS);
- setState(89); _localctx.attrValue = match(STRING);
+ setState(87);
+ ((AttributeContext)_localctx).attrName = match(Name);
+ setState(88);
+ match(EQUALS);
+ setState(89);
+ ((AttributeContext)_localctx).attrValue = match(STRING);
}
}
catch (RecognitionException re) {
@@ -526,8 +596,8 @@ public class XMLParser extends Parser {
}
public static class ChardataContext extends ParserRuleContext {
- public TerminalNode SEA_WS() { return getToken(XMLParser.SEA_WS, 0); }
public TerminalNode TEXT() { return getToken(XMLParser.TEXT, 0); }
+ public TerminalNode SEA_WS() { return getToken(XMLParser.SEA_WS, 0); }
public ChardataContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -541,13 +611,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitChardata(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitChardata(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitChardata(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final ChardataContext chardata() throws RecognitionException {
ChardataContext _localctx = new ChardataContext(_ctx, getState());
enterRule(_localctx, 12, RULE_chardata);
@@ -559,8 +628,9 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if ( !(_la==SEA_WS || _la==TEXT) ) {
_errHandler.recoverInline(this);
+ } else {
+ consume();
}
- consume();
}
}
catch (RecognitionException re) {
@@ -575,9 +645,9 @@ public class XMLParser extends Parser {
}
public static class MiscContext extends ParserRuleContext {
- public TerminalNode SEA_WS() { return getToken(XMLParser.SEA_WS, 0); }
- public TerminalNode PI() { return getToken(XMLParser.PI, 0); }
public TerminalNode COMMENT() { return getToken(XMLParser.COMMENT, 0); }
+ public TerminalNode PI() { return getToken(XMLParser.PI, 0); }
+ public TerminalNode SEA_WS() { return getToken(XMLParser.SEA_WS, 0); }
public MiscContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@@ -591,13 +661,12 @@ public class XMLParser extends Parser {
if ( listener instanceof XMLParserListener ) ((XMLParserListener)listener).exitMisc(this);
}
@Override
- public <Result> Result accept(ParseTreeVisitor<? extends Result> visitor) {
- if ( visitor instanceof XMLParserVisitor<?> ) return ((XMLParserVisitor<? extends Result>)visitor).visitMisc(this);
+ public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+ if ( visitor instanceof XMLParserVisitor ) return ((XMLParserVisitor<? extends T>)visitor).visitMisc(this);
else return visitor.visitChildren(this);
}
}
- @RuleVersion(0)
public final MiscContext misc() throws RecognitionException {
MiscContext _localctx = new MiscContext(_ctx, getState());
enterRule(_localctx, 14, RULE_misc);
@@ -609,8 +678,9 @@ public class XMLParser extends Parser {
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << COMMENT) | (1L << SEA_WS) | (1L << PI))) != 0)) ) {
_errHandler.recoverInline(this);
+ } else {
+ consume();
}
- consume();
}
}
catch (RecognitionException re) {
@@ -625,34 +695,38 @@ public class XMLParser extends Parser {
}
public static final String _serializedATN =
- "\3\uaf6f\u8320\u479d\ub75c\u4880\u1605\u191c\uab37\3\24b\4\2\t\2\4\3\t"+
+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\24b\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\3\2\5\2\24\n\2\3\2"+
"\7\2\27\n\2\f\2\16\2\32\13\2\3\2\3\2\7\2\36\n\2\f\2\16\2!\13\2\3\3\3\3"+
"\7\3%\n\3\f\3\16\3(\13\3\3\3\3\3\3\4\5\4-\n\4\3\4\3\4\3\4\3\4\3\4\5\4"+
"\64\n\4\3\4\5\4\67\n\4\7\49\n\4\f\4\16\4<\13\4\3\5\3\5\3\5\7\5A\n\5\f"+
"\5\16\5D\13\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\7\5P\n\5\f\5\16"+
"\5S\13\5\3\5\5\5V\n\5\3\6\3\6\3\7\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\t\2\2"+
- "\2\n\2\2\4\2\6\2\b\2\n\2\f\2\16\2\20\2\2\5\3\2\6\7\4\2\b\b\13\13\5\2\3"+
- "\3\b\b\24\24g\2\23\3\2\2\2\4\"\3\2\2\2\6,\3\2\2\2\bU\3\2\2\2\nW\3\2\2"+
- "\2\fY\3\2\2\2\16]\3\2\2\2\20_\3\2\2\2\22\24\5\4\3\2\23\22\3\2\2\2\23\24"+
- "\3\2\2\2\24\30\3\2\2\2\25\27\5\20\t\2\26\25\3\2\2\2\27\32\3\2\2\2\30\26"+
- "\3\2\2\2\30\31\3\2\2\2\31\33\3\2\2\2\32\30\3\2\2\2\33\37\5\b\5\2\34\36"+
- "\5\20\t\2\35\34\3\2\2\2\36!\3\2\2\2\37\35\3\2\2\2\37 \3\2\2\2 \3\3\2\2"+
- "\2!\37\3\2\2\2\"&\7\n\2\2#%\5\f\7\2$#\3\2\2\2%(\3\2\2\2&$\3\2\2\2&\'\3"+
- "\2\2\2\')\3\2\2\2(&\3\2\2\2)*\7\r\2\2*\5\3\2\2\2+-\5\16\b\2,+\3\2\2\2"+
- ",-\3\2\2\2-:\3\2\2\2.\64\5\b\5\2/\64\5\n\6\2\60\64\7\4\2\2\61\64\7\24"+
- "\2\2\62\64\7\3\2\2\63.\3\2\2\2\63/\3\2\2\2\63\60\3\2\2\2\63\61\3\2\2\2"+
- "\63\62\3\2\2\2\64\66\3\2\2\2\65\67\5\16\b\2\66\65\3\2\2\2\66\67\3\2\2"+
- "\2\679\3\2\2\28\63\3\2\2\29<\3\2\2\2:8\3\2\2\2:;\3\2\2\2;\7\3\2\2\2<:"+
- "\3\2\2\2=>\7\t\2\2>B\7\22\2\2?A\5\f\7\2@?\3\2\2\2AD\3\2\2\2B@\3\2\2\2"+
- "BC\3\2\2\2CE\3\2\2\2DB\3\2\2\2EF\7\f\2\2FG\5\6\4\2GH\7\t\2\2HI\7\17\2"+
- "\2IJ\7\22\2\2JK\7\f\2\2KV\3\2\2\2LM\7\t\2\2MQ\7\22\2\2NP\5\f\7\2ON\3\2"+
- "\2\2PS\3\2\2\2QO\3\2\2\2QR\3\2\2\2RT\3\2\2\2SQ\3\2\2\2TV\7\16\2\2U=\3"+
- "\2\2\2UL\3\2\2\2V\t\3\2\2\2WX\t\2\2\2X\13\3\2\2\2YZ\7\22\2\2Z[\7\20\2"+
- "\2[\\\7\21\2\2\\\r\3\2\2\2]^\t\3\2\2^\17\3\2\2\2_`\t\4\2\2`\21\3\2\2\2"+
- "\r\23\30\37&,\63\66:BQU";
+ "\n\2\4\6\b\n\f\16\20\2\5\3\2\6\7\4\2\b\b\13\13\5\2\3\3\b\b\24\24g\2\23"+
+ "\3\2\2\2\4\"\3\2\2\2\6,\3\2\2\2\bU\3\2\2\2\nW\3\2\2\2\fY\3\2\2\2\16]\3"+
+ "\2\2\2\20_\3\2\2\2\22\24\5\4\3\2\23\22\3\2\2\2\23\24\3\2\2\2\24\30\3\2"+
+ "\2\2\25\27\5\20\t\2\26\25\3\2\2\2\27\32\3\2\2\2\30\26\3\2\2\2\30\31\3"+
+ "\2\2\2\31\33\3\2\2\2\32\30\3\2\2\2\33\37\5\b\5\2\34\36\5\20\t\2\35\34"+
+ "\3\2\2\2\36!\3\2\2\2\37\35\3\2\2\2\37 \3\2\2\2 \3\3\2\2\2!\37\3\2\2\2"+
+ "\"&\7\n\2\2#%\5\f\7\2$#\3\2\2\2%(\3\2\2\2&$\3\2\2\2&\'\3\2\2\2\')\3\2"+
+ "\2\2(&\3\2\2\2)*\7\r\2\2*\5\3\2\2\2+-\5\16\b\2,+\3\2\2\2,-\3\2\2\2-:\3"+
+ "\2\2\2.\64\5\b\5\2/\64\5\n\6\2\60\64\7\4\2\2\61\64\7\24\2\2\62\64\7\3"+
+ "\2\2\63.\3\2\2\2\63/\3\2\2\2\63\60\3\2\2\2\63\61\3\2\2\2\63\62\3\2\2\2"+
+ "\64\66\3\2\2\2\65\67\5\16\b\2\66\65\3\2\2\2\66\67\3\2\2\2\679\3\2\2\2"+
+ "8\63\3\2\2\29<\3\2\2\2:8\3\2\2\2:;\3\2\2\2;\7\3\2\2\2<:\3\2\2\2=>\7\t"+
+ "\2\2>B\7\22\2\2?A\5\f\7\2@?\3\2\2\2AD\3\2\2\2B@\3\2\2\2BC\3\2\2\2CE\3"+
+ "\2\2\2DB\3\2\2\2EF\7\f\2\2FG\5\6\4\2GH\7\t\2\2HI\7\17\2\2IJ\7\22\2\2J"+
+ "K\7\f\2\2KV\3\2\2\2LM\7\t\2\2MQ\7\22\2\2NP\5\f\7\2ON\3\2\2\2PS\3\2\2\2"+
+ "QO\3\2\2\2QR\3\2\2\2RT\3\2\2\2SQ\3\2\2\2TV\7\16\2\2U=\3\2\2\2UL\3\2\2"+
+ "\2V\t\3\2\2\2WX\t\2\2\2X\13\3\2\2\2YZ\7\22\2\2Z[\7\20\2\2[\\\7\21\2\2"+
+ "\\\r\3\2\2\2]^\t\3\2\2^\17\3\2\2\2_`\t\4\2\2`\21\3\2\2\2\r\23\30\37&,"+
+ "\63\66:BQU";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
}
} \ No newline at end of file
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
index b1423a12..d80683d7 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParser.tokens
@@ -1,23 +1,23 @@
-OPEN=7
+COMMENT=1
CDATA=2
-SLASH=13
+DTD=3
+EntityRef=4
CharRef=5
SEA_WS=6
-SPECIAL_CLOSE=11
+OPEN=7
+XMLDeclOpen=8
+TEXT=9
CLOSE=10
-DTD=3
-Name=16
-EQUALS=14
-PI=18
+SPECIAL_CLOSE=11
SLASH_CLOSE=12
-S=17
-TEXT=9
-XMLDeclOpen=8
-COMMENT=1
-EntityRef=4
+SLASH=13
+EQUALS=14
STRING=15
-'='=14
+Name=16
+S=17
+PI=18
'<'=7
-'/'=13
-'/>'=12
'>'=10
+'/>'=12
+'/'=13
+'='=14
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
index 4c2bae2d..0d237e7e 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseListener.java
@@ -1,9 +1,7 @@
-// Generated from XMLParser.g4 by ANTLR 4.4
+// Generated from XMLParser.g4 by ANTLR 4.5.3
package android.databinding.parser;
import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -18,127 +16,120 @@ public class XMLParserBaseListener implements XMLParserListener {
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterContent(@NotNull XMLParser.ContentContext ctx) { }
+ @Override public void enterDocument(XMLParser.DocumentContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitContent(@NotNull XMLParser.ContentContext ctx) { }
-
+ @Override public void exitDocument(XMLParser.DocumentContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterElement(@NotNull XMLParser.ElementContext ctx) { }
+ @Override public void enterProlog(XMLParser.PrologContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitElement(@NotNull XMLParser.ElementContext ctx) { }
-
+ @Override public void exitProlog(XMLParser.PrologContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterProlog(@NotNull XMLParser.PrologContext ctx) { }
+ @Override public void enterContent(XMLParser.ContentContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitProlog(@NotNull XMLParser.PrologContext ctx) { }
-
+ @Override public void exitContent(XMLParser.ContentContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterDocument(@NotNull XMLParser.DocumentContext ctx) { }
+ @Override public void enterElement(XMLParser.ElementContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitDocument(@NotNull XMLParser.DocumentContext ctx) { }
-
+ @Override public void exitElement(XMLParser.ElementContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterAttribute(@NotNull XMLParser.AttributeContext ctx) { }
+ @Override public void enterReference(XMLParser.ReferenceContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitAttribute(@NotNull XMLParser.AttributeContext ctx) { }
-
+ @Override public void exitReference(XMLParser.ReferenceContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterChardata(@NotNull XMLParser.ChardataContext ctx) { }
+ @Override public void enterAttribute(XMLParser.AttributeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitChardata(@NotNull XMLParser.ChardataContext ctx) { }
-
+ @Override public void exitAttribute(XMLParser.AttributeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterReference(@NotNull XMLParser.ReferenceContext ctx) { }
+ @Override public void enterChardata(XMLParser.ChardataContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitReference(@NotNull XMLParser.ReferenceContext ctx) { }
-
+ @Override public void exitChardata(XMLParser.ChardataContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterMisc(@NotNull XMLParser.MiscContext ctx) { }
+ @Override public void enterMisc(XMLParser.MiscContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitMisc(@NotNull XMLParser.MiscContext ctx) { }
+ @Override public void exitMisc(XMLParser.MiscContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void enterEveryRule(@NotNull ParserRuleContext ctx) { }
+ @Override public void enterEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void exitEveryRule(@NotNull ParserRuleContext ctx) { }
+ @Override public void exitEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void visitTerminal(@NotNull TerminalNode node) { }
+ @Override public void visitTerminal(TerminalNode node) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
- @Override public void visitErrorNode(@NotNull ErrorNode node) { }
+ @Override public void visitErrorNode(ErrorNode node) { }
} \ No newline at end of file
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
index 6b04b77d..c89b2d30 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserBaseVisitor.java
@@ -1,7 +1,5 @@
-// Generated from XMLParser.g4 by ANTLR 4.4
+// Generated from XMLParser.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
@@ -9,71 +7,64 @@ import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
- * @param <Result> The return type of the visit operation. Use {@link Void} for
+ * @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
-public class XMLParserBaseVisitor<Result> extends AbstractParseTreeVisitor<Result> implements XMLParserVisitor<Result> {
+public class XMLParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements XMLParserVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitContent(@NotNull XMLParser.ContentContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitDocument(XMLParser.DocumentContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitElement(@NotNull XMLParser.ElementContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitProlog(XMLParser.PrologContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitProlog(@NotNull XMLParser.PrologContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitContent(XMLParser.ContentContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitDocument(@NotNull XMLParser.DocumentContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitElement(XMLParser.ElementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitAttribute(@NotNull XMLParser.AttributeContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitReference(XMLParser.ReferenceContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitChardata(@NotNull XMLParser.ChardataContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitAttribute(XMLParser.AttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitReference(@NotNull XMLParser.ReferenceContext ctx) { return visitChildren(ctx); }
-
+ @Override public T visitChardata(XMLParser.ChardataContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
- @Override public Result visitMisc(@NotNull XMLParser.MiscContext ctx) { return visitChildren(ctx); }
+ @Override public T visitMisc(XMLParser.MiscContext ctx) { return visitChildren(ctx); }
} \ No newline at end of file
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
index 6bee172c..c1b37e20 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserListener.java
@@ -1,7 +1,5 @@
-// Generated from XMLParser.g4 by ANTLR 4.4
+// Generated from XMLParser.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeListener;
/**
@@ -10,90 +8,83 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
*/
public interface XMLParserListener extends ParseTreeListener {
/**
- * Enter a parse tree produced by {@link XMLParser#content}.
+ * Enter a parse tree produced by {@link XMLParser#document}.
* @param ctx the parse tree
*/
- void enterContent(@NotNull XMLParser.ContentContext ctx);
+ void enterDocument(XMLParser.DocumentContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#content}.
+ * Exit a parse tree produced by {@link XMLParser#document}.
* @param ctx the parse tree
*/
- void exitContent(@NotNull XMLParser.ContentContext ctx);
-
+ void exitDocument(XMLParser.DocumentContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#element}.
+ * Enter a parse tree produced by {@link XMLParser#prolog}.
* @param ctx the parse tree
*/
- void enterElement(@NotNull XMLParser.ElementContext ctx);
+ void enterProlog(XMLParser.PrologContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#element}.
+ * Exit a parse tree produced by {@link XMLParser#prolog}.
* @param ctx the parse tree
*/
- void exitElement(@NotNull XMLParser.ElementContext ctx);
-
+ void exitProlog(XMLParser.PrologContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#prolog}.
+ * Enter a parse tree produced by {@link XMLParser#content}.
* @param ctx the parse tree
*/
- void enterProlog(@NotNull XMLParser.PrologContext ctx);
+ void enterContent(XMLParser.ContentContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#prolog}.
+ * Exit a parse tree produced by {@link XMLParser#content}.
* @param ctx the parse tree
*/
- void exitProlog(@NotNull XMLParser.PrologContext ctx);
-
+ void exitContent(XMLParser.ContentContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#document}.
+ * Enter a parse tree produced by {@link XMLParser#element}.
* @param ctx the parse tree
*/
- void enterDocument(@NotNull XMLParser.DocumentContext ctx);
+ void enterElement(XMLParser.ElementContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#document}.
+ * Exit a parse tree produced by {@link XMLParser#element}.
* @param ctx the parse tree
*/
- void exitDocument(@NotNull XMLParser.DocumentContext ctx);
-
+ void exitElement(XMLParser.ElementContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#attribute}.
+ * Enter a parse tree produced by {@link XMLParser#reference}.
* @param ctx the parse tree
*/
- void enterAttribute(@NotNull XMLParser.AttributeContext ctx);
+ void enterReference(XMLParser.ReferenceContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#attribute}.
+ * Exit a parse tree produced by {@link XMLParser#reference}.
* @param ctx the parse tree
*/
- void exitAttribute(@NotNull XMLParser.AttributeContext ctx);
-
+ void exitReference(XMLParser.ReferenceContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#chardata}.
+ * Enter a parse tree produced by {@link XMLParser#attribute}.
* @param ctx the parse tree
*/
- void enterChardata(@NotNull XMLParser.ChardataContext ctx);
+ void enterAttribute(XMLParser.AttributeContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#chardata}.
+ * Exit a parse tree produced by {@link XMLParser#attribute}.
* @param ctx the parse tree
*/
- void exitChardata(@NotNull XMLParser.ChardataContext ctx);
-
+ void exitAttribute(XMLParser.AttributeContext ctx);
/**
- * Enter a parse tree produced by {@link XMLParser#reference}.
+ * Enter a parse tree produced by {@link XMLParser#chardata}.
* @param ctx the parse tree
*/
- void enterReference(@NotNull XMLParser.ReferenceContext ctx);
+ void enterChardata(XMLParser.ChardataContext ctx);
/**
- * Exit a parse tree produced by {@link XMLParser#reference}.
+ * Exit a parse tree produced by {@link XMLParser#chardata}.
* @param ctx the parse tree
*/
- void exitReference(@NotNull XMLParser.ReferenceContext ctx);
-
+ void exitChardata(XMLParser.ChardataContext ctx);
/**
* Enter a parse tree produced by {@link XMLParser#misc}.
* @param ctx the parse tree
*/
- void enterMisc(@NotNull XMLParser.MiscContext ctx);
+ void enterMisc(XMLParser.MiscContext ctx);
/**
* Exit a parse tree produced by {@link XMLParser#misc}.
* @param ctx the parse tree
*/
- void exitMisc(@NotNull XMLParser.MiscContext ctx);
+ void exitMisc(XMLParser.MiscContext ctx);
} \ No newline at end of file
diff --git a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
index 6a76a004..a1abfb70 100644
--- a/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
+++ b/compilerCommon/src/main/xml-gen/android/databinding/parser/XMLParserVisitor.java
@@ -1,70 +1,61 @@
-// Generated from XMLParser.g4 by ANTLR 4.4
+// Generated from XMLParser.g4 by ANTLR 4.5.3
package android.databinding.parser;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link XMLParser}.
*
- * @param <Result> The return type of the visit operation. Use {@link Void} for
+ * @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
-public interface XMLParserVisitor<Result> extends ParseTreeVisitor<Result> {
+public interface XMLParserVisitor<T> extends ParseTreeVisitor<T> {
/**
- * Visit a parse tree produced by {@link XMLParser#content}.
+ * Visit a parse tree produced by {@link XMLParser#document}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitContent(@NotNull XMLParser.ContentContext ctx);
-
+ T visitDocument(XMLParser.DocumentContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#element}.
+ * Visit a parse tree produced by {@link XMLParser#prolog}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitElement(@NotNull XMLParser.ElementContext ctx);
-
+ T visitProlog(XMLParser.PrologContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#prolog}.
+ * Visit a parse tree produced by {@link XMLParser#content}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitProlog(@NotNull XMLParser.PrologContext ctx);
-
+ T visitContent(XMLParser.ContentContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#document}.
+ * Visit a parse tree produced by {@link XMLParser#element}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitDocument(@NotNull XMLParser.DocumentContext ctx);
-
+ T visitElement(XMLParser.ElementContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#attribute}.
+ * Visit a parse tree produced by {@link XMLParser#reference}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitAttribute(@NotNull XMLParser.AttributeContext ctx);
-
+ T visitReference(XMLParser.ReferenceContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#chardata}.
+ * Visit a parse tree produced by {@link XMLParser#attribute}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitChardata(@NotNull XMLParser.ChardataContext ctx);
-
+ T visitAttribute(XMLParser.AttributeContext ctx);
/**
- * Visit a parse tree produced by {@link XMLParser#reference}.
+ * Visit a parse tree produced by {@link XMLParser#chardata}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitReference(@NotNull XMLParser.ReferenceContext ctx);
-
+ T visitChardata(XMLParser.ChardataContext ctx);
/**
* Visit a parse tree produced by {@link XMLParser#misc}.
* @param ctx the parse tree
* @return the visitor result
*/
- Result visitMisc(@NotNull XMLParser.MiscContext ctx);
+ T visitMisc(XMLParser.MiscContext ctx);
} \ No newline at end of file
diff --git a/data-binding.iml b/data-binding.iml
deleted file mode 100644
index bebe401a..00000000
--- a/data-binding.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id="data-binding" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build" />
- <output-test url="file://$MODULE_DIR$/build" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module> \ No newline at end of file
diff --git a/dataBinding/dataBinding.iml b/dataBinding/dataBinding.iml
deleted file mode 100644
index 0d65182c..00000000
--- a/dataBinding/dataBinding.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":dataBinding" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="com.android.databinding" external.system.module.version="1.1" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build" />
- <output-test url="file://$MODULE_DIR$/build" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/build" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module> \ No newline at end of file
diff --git a/databinding.properties b/databinding.properties
index 120a93ee..b7e355b5 100644
--- a/databinding.properties
+++ b/databinding.properties
@@ -1,10 +1,14 @@
# global settings for projects
-kotlinVersion = 1.0.0-beta-4584
-extensionsVersion = 1.0-rc5
+kotlinVersion = 1.0.0
+extensionsVersion = 1.1
# we use a public plugin so that it does not need data binding while compiling library
androidPublicPluginVersion= 1.5.0
+# java versions for the code that runs on the device
javaTargetCompatibility = 1.6
javaSourceCompatibility = 1.6
+# java versions for the code that runs on the host machine
+compilerJavaTargetCompatibility = 1.8
+compilerJavaSourceCompatibility = 1.8
buildToolsVersion = 22.0.1
compileSdkVersionStr = 23
prebuildFolderName=prebuilds
diff --git a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy
index 4db1f39b..f883f68a 100644
--- a/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy
+++ b/developmentPlugins/localizeMavenPlugin/src/main/groovy/android/databinding/ExportLicensesTask.groovy
@@ -25,7 +25,7 @@ class ExportLicensesTask extends DefaultTask {
static def knownLicenses = [
[
libraries: ["kotlin-stdlib", "kotlin-runtime", "kotlin-annotation-processing", "kotlin-gradle-plugin", "kotlin-gradle-plugin-api",
- "kdoc", "kotlin-gradle-plugin-core", "kotlin-jdk-annotations", "kotlin-compiler", "kotlin-compiler-embeddable"],
+ "kdoc", "kotlin-gradle-plugin-core", "kotlin-jdk-annotations", "kotlin-compiler", "kotlin-compiler-embeddable", "kotlin-android-extensions"],
licenses : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/LICENSE.txt",
"http://www.apache.org/licenses/LICENSE-2.0.txt"],
notices : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/NOTICE.txt"]
diff --git a/extensions/baseAdapters/build.gradle b/extensions/baseAdapters/build.gradle
index d375aeba..b27457f4 100644
--- a/extensions/baseAdapters/build.gradle
+++ b/extensions/baseAdapters/build.gradle
@@ -41,7 +41,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
+ compileOptions {
+ sourceCompatibility dataBindingConfig.javaTargetCompatibility
+ targetCompatibility dataBindingConfig.javaSourceCompatibility
+ }
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'META-INF/LICENSE.txt'
diff --git a/extensions/library/build.gradle b/extensions/library/build.gradle
index 339a20fe..d1c686b5 100644
--- a/extensions/library/build.gradle
+++ b/extensions/library/build.gradle
@@ -46,8 +46,8 @@ android {
versionName "1.0"
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_6
- targetCompatibility JavaVersion.VERSION_1_6
+ sourceCompatibility dataBindingConfig.javaTargetCompatibility
+ targetCompatibility dataBindingConfig.javaSourceCompatibility
}
buildTypes {
release {
@@ -83,6 +83,8 @@ android.libraryVariants.all { variant ->
def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
source variant.javaCompile.source
+ options.showFromPublic()
+ options.tags = ['hide']
classpath = files(variant.javaCompile.classpath.files) + files(
"${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
}
diff --git a/extensions/library/src/main/java/android/databinding/ObservableField.java b/extensions/library/src/main/java/android/databinding/ObservableField.java
index 6de798b4..6b1021c3 100644
--- a/extensions/library/src/main/java/android/databinding/ObservableField.java
+++ b/extensions/library/src/main/java/android/databinding/ObservableField.java
@@ -22,7 +22,7 @@ import java.io.Serializable;
* <p>
* Observable field classes may be used instead of creating an Observable object:
* <pre><code>public class MyDataObject {
- * public final ObservableField&lt;String> name = new ObservableField&lt;String>();
+ * public final ObservableField&lt;String&gt; name = new ObservableField&lt;String&gt;();
* public final ObservableInt age = new ObservableInt();
* }</code></pre>
* Fields of this type should be declared final because bindings only detect changes in the
diff --git a/extensions/library/src/main/java/android/databinding/ObservableInt.java b/extensions/library/src/main/java/android/databinding/ObservableInt.java
index cb25c563..51502254 100644
--- a/extensions/library/src/main/java/android/databinding/ObservableInt.java
+++ b/extensions/library/src/main/java/android/databinding/ObservableInt.java
@@ -25,7 +25,7 @@ import java.io.Serializable;
* <p>
* Observable field classes may be used instead of creating an Observable object:
* <pre><code>public class MyDataObject {
- * public final ObservableField<String> name = new ObservableField<String>();
+ * public final ObservableField&lt;String&gt; name = new ObservableField&lt;String&gt;();
* public final ObservableInt age = new ObservableInt();
* }</code></pre>
* Fields of this type should be declared final because bindings only detect changes in the
diff --git a/extensions/library/src/main/java/android/databinding/ObservableParcelable.java b/extensions/library/src/main/java/android/databinding/ObservableParcelable.java
index 96eec274..96774102 100644
--- a/extensions/library/src/main/java/android/databinding/ObservableParcelable.java
+++ b/extensions/library/src/main/java/android/databinding/ObservableParcelable.java
@@ -26,7 +26,7 @@ import java.io.Serializable;
* <p>
* Observable field classes may be used instead of creating an Observable object:
* <pre><code>public class MyDataObject {
- * public final ObservableParcelable&lt;String> name = new ObservableParcelable&lt;String>();
+ * public final ObservableParcelable&lt;String&gt; name = new ObservableParcelable&lt;String&gt;();
* public final ObservableInt age = new ObservableInt();
* }</code></pre>
* Fields of this type should be declared final because bindings only detect changes in the
diff --git a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
index 5e760237..70c79c41 100644
--- a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
+++ b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java
@@ -570,29 +570,99 @@ public abstract class ViewDataBinding extends BaseObservable {
}
/** @hide */
- protected int getColorFromResource(int resourceId) {
+ protected static boolean parse(String str, boolean fallback) {
+ if (str == null) {
+ return fallback;
+ }
+ return Boolean.parseBoolean(str);
+ }
+
+ /** @hide */
+ protected static byte parse(String str, byte fallback) {
+ try {
+ return Byte.parseByte(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static short parse(String str, short fallback) {
+ try {
+ return Short.parseShort(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static int parse(String str, int fallback) {
+ try {
+ return Integer.parseInt(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static long parse(String str, long fallback) {
+ try {
+ return Long.parseLong(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static float parse(String str, float fallback) {
+ try {
+ return Float.parseFloat(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static double parse(String str, double fallback) {
+ try {
+ return Double.parseDouble(str);
+ } catch (NumberFormatException e) {
+ return fallback;
+ }
+ }
+
+ /** @hide */
+ protected static char parse(String str, char fallback) {
+ if (str == null || str.isEmpty()) {
+ return fallback;
+ }
+ return str.charAt(0);
+ }
+
+ /** @hide */
+ protected static int getColorFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.M) {
- return getRoot().getContext().getColor(resourceId);
+ return view.getContext().getColor(resourceId);
} else {
- return getRoot().getResources().getColor(resourceId);
+ return view.getResources().getColor(resourceId);
}
}
/** @hide */
- protected ColorStateList getColorStateListFromResource(int resourceId) {
+ protected static ColorStateList getColorStateListFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.M) {
- return getRoot().getContext().getColorStateList(resourceId);
+ return view.getContext().getColorStateList(resourceId);
} else {
- return getRoot().getResources().getColorStateList(resourceId);
+ return view.getResources().getColorStateList(resourceId);
}
}
/** @hide */
- protected Drawable getDrawableFromResource(int resourceId) {
+ protected static Drawable getDrawableFromResource(View view, int resourceId) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- return getRoot().getContext().getDrawable(resourceId);
+ return view.getContext().getDrawable(resourceId);
} else {
- return getRoot().getResources().getDrawable(resourceId);
+ return view.getResources().getDrawable(resourceId);
}
}
@@ -919,7 +989,8 @@ public abstract class ViewDataBinding extends BaseObservable {
if (existingBinding != null) {
return;
}
- final String tag = (String) view.getTag();
+ Object objTag = view.getTag();
+ final String tag = (objTag instanceof String) ? (String) objTag : null;
boolean isBound = false;
if (isRoot && tag != null && tag.startsWith("layout")) {
final int underscoreIndex = tag.lastIndexOf('_');
@@ -962,9 +1033,9 @@ public abstract class ViewDataBinding extends BaseObservable {
for (int i = 0; i < count; i++) {
final View child = viewGroup.getChildAt(i);
boolean isInclude = false;
- if (indexInIncludes >= 0) {
+ if (indexInIncludes >= 0 && child.getTag() instanceof String) {
String childTag = (String) child.getTag();
- if (childTag != null && childTag.endsWith("_0") &&
+ if (childTag.endsWith("_0") &&
childTag.startsWith("layout") && childTag.indexOf('/') > 0) {
// This *could* be an include. Test against the expected includes.
int includeIndex = findIncludeIndex(childTag, minInclude,
@@ -1024,7 +1095,8 @@ public abstract class ViewDataBinding extends BaseObservable {
int max = firstIncludedIndex;
for (int i = firstIncludedIndex + 1; i < count; i++) {
final View view = viewGroup.getChildAt(i);
- final String tag = (String) view.getTag();
+ final Object objTag = view.getTag();
+ final String tag = objTag instanceof String ? (String) view.getTag() : null;
if (tag != null && tag.startsWith(tagBase)) {
if (tag.length() == firstViewTag.length() && tag.charAt(tag.length() - 1) == '0') {
return max; // Found another instance of the include
diff --git a/integration-tests/MultiModuleTestApp/app/src/main/res/layout/another_layout.xml b/integration-tests/MultiModuleTestApp/app/src/main/res/layout/another_layout.xml
index 13323478..0aaf1b5e 100644
--- a/integration-tests/MultiModuleTestApp/app/src/main/res/layout/another_layout.xml
+++ b/integration-tests/MultiModuleTestApp/app/src/main/res/layout/another_layout.xml
@@ -26,6 +26,7 @@
<TextView
android:text='@{userName + " " + userLastName}'
android:layout_width="wrap_content"
+ android:onClick="@{() -> userName.length()}"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout> \ No newline at end of file
diff --git a/integration-tests/MultiModuleTestApp/testlibrary/src/main/java/android/databinding/testlibrary/TestLibObject.java b/integration-tests/MultiModuleTestApp/testlibrary/src/main/java/android/databinding/testlibrary/TestLibObject.java
index 8139b75e..bc4baef9 100644
--- a/integration-tests/MultiModuleTestApp/testlibrary/src/main/java/android/databinding/testlibrary/TestLibObject.java
+++ b/integration-tests/MultiModuleTestApp/testlibrary/src/main/java/android/databinding/testlibrary/TestLibObject.java
@@ -18,6 +18,7 @@ package android.databinding.testlibrary;
import android.databinding.Bindable;
import android.databinding.BaseObservable;
+import android.view.View;
public class TestLibObject extends BaseObservable {
@Bindable
@@ -31,4 +32,8 @@ public class TestLibObject extends BaseObservable {
this.mField = field;
notifyPropertyChanged(BR.field);
}
+
+ public void clickHandler(View view) {
+
+ }
}
diff --git a/integration-tests/MultiModuleTestApp/testlibrary/src/main/res/layout/library_only_layout.xml b/integration-tests/MultiModuleTestApp/testlibrary/src/main/res/layout/library_only_layout.xml
index 6b5fc565..02821f6f 100644
--- a/integration-tests/MultiModuleTestApp/testlibrary/src/main/res/layout/library_only_layout.xml
+++ b/integration-tests/MultiModuleTestApp/testlibrary/src/main/res/layout/library_only_layout.xml
@@ -29,7 +29,8 @@
tools:context=".TestLibraryMainActivity">
<TextView android:text="@{obj1.field}" android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:onClick="{(v) -> obj1.clickHandler(v)}"/>
</RelativeLayout>
</layout> \ No newline at end of file
diff --git a/integration-tests/TestApp/app/build.gradle b/integration-tests/TestApp/app/build.gradle
index 0701944d..1d3ba68d 100644
--- a/integration-tests/TestApp/app/build.gradle
+++ b/integration-tests/TestApp/app/build.gradle
@@ -10,6 +10,7 @@ android {
targetSdkVersion 21
versionCode 1
versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
dataBinding {
enabled = true
@@ -41,4 +42,14 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "com.android.support:support-v4:+"
+ androidTestCompile ('com.android.support.test:runner:0.4.1') {
+ exclude module: 'support-annotations'
+ }
+ androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.1') {
+ exclude module: 'support-annotations'
+ }
+ testCompile 'junit:junit:4.12'
+ androidTestCompile "org.mockito:mockito-core:1.9.5"
+ androidTestCompile "com.google.dexmaker:dexmaker:1.2"
+ androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
}
diff --git a/integration-tests/TestApp/app/src/androidTest/AndroidManifest.xml b/integration-tests/TestApp/app/src/androidTest/AndroidManifest.xml
new file mode 100644
index 00000000..e3270242
--- /dev/null
+++ b/integration-tests/TestApp/app/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.databinding.testapp">
+ <uses-sdk android:minSdkVersion="7" tools:overrideLibrary="android.support.test,
+ android.app, android.support.test.rule, android.support.test.espresso,
+ android.support.test.espresso.idling"/>
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ >
+ <activity android:name=".TestActivity"
+ android:screenOrientation="portrait"/>
+ </application>
+
+</manifest> \ No newline at end of file
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/BindableObservablesTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BindableObservablesTest.java
new file mode 100644
index 00000000..07e50754
--- /dev/null
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/BindableObservablesTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.databinding.testapp;
+
+import android.annotation.TargetApi;
+import android.databinding.ObservableField;
+import android.databinding.ObservableInt;
+import android.databinding.testapp.BR;
+import android.databinding.testapp.databinding.BindableObservablesBinding;
+import android.databinding.testapp.databinding.CallbacksBinding;
+import android.databinding.testapp.vo.ViewModel;
+import android.os.Build;
+import android.support.test.runner.AndroidJUnit4;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.CoreMatchers.*;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BindableObservablesTest {
+ @Rule
+ public DataBindingTestRule<BindableObservablesBinding> mBindingRule = new DataBindingTestRule<>(
+ R.layout.bindable_observables
+ );
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ @Test
+ public void publicBinding() {
+ ViewModel model = new ViewModel();
+ model.publicObservable.set(40);
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view1.getMaxLines(), is(40));
+ model.publicObservable.set(20);
+ mBindingRule.executePending();
+ assertThat(binding.view1.getMaxLines(), is(20));
+ }
+
+ @Test
+ public void fieldBinding() {
+ ViewModel model = new ViewModel();
+ model.getFieldObservable().set("abc");
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view2.getText().toString(), is("abc"));
+ model.getFieldObservable().set("def");
+ mBindingRule.executePending();
+ assertThat(binding.view2.getText().toString(), is("def"));
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ @Test
+ public void methodBinding() {
+ ViewModel model = new ViewModel();
+ model.getMethodObservable().set(30);
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view3.getMaxLines(), is(30));
+ model.getMethodObservable().set(15);
+ mBindingRule.executePending();
+ assertThat(binding.view3.getMaxLines(), is(15));
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ @Test
+ public void publicBindingChangeObservable() {
+ ViewModel model = new ViewModel();
+ model.publicObservable.set(40);
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view1.getMaxLines(), is(40));
+
+ model.publicObservable = new ObservableInt(20);
+
+ mBindingRule.executePending();
+ assertThat(binding.view1.getMaxLines(), is(40));
+
+ model.notifyPropertyChanged(BR.publicObservable);
+ mBindingRule.executePending();
+ assertThat(binding.view1.getMaxLines(), is(20));
+
+ }
+
+ @Test
+ public void fieldBindingChangeObservable() {
+ ViewModel model = new ViewModel();
+ model.getFieldObservable().set("abc");
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view2.getText().toString(), is("abc"));
+
+ model.setFieldObservable(new ObservableField<String>("def"));
+
+ mBindingRule.executePending();
+ assertThat(binding.view2.getText().toString(), is("abc"));
+
+ model.notifyPropertyChanged(BR.fieldObservable);
+ mBindingRule.executePending();
+ assertThat(binding.view2.getText().toString(), is("def"));
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ @Test
+ public void methodBindingChangeObservable() {
+ ViewModel model = new ViewModel();
+ model.getMethodObservable().set(30);
+ BindableObservablesBinding binding = mBindingRule.getBinding();
+ binding.setModel(model);
+ mBindingRule.executePending();
+ assertThat(binding.view3.getMaxLines(), is(30));
+
+ model.setMethodObservable(new ObservableInt(15));
+
+ mBindingRule.executePending();
+ assertThat(binding.view3.getMaxLines(), is(30));
+
+ model.notifyPropertyChanged(BR.methodObservable);
+ mBindingRule.executePending();
+ assertThat(binding.view3.getMaxLines(), is(15));
+ }
+}
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/CallbackTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/CallbackTest.java
new file mode 100644
index 00000000..ca08fc94
--- /dev/null
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/CallbackTest.java
@@ -0,0 +1,385 @@
+/*
+ * 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 static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.annotation.TargetApi;
+import android.databinding.testapp.databinding.CallbacksBinding;
+import android.databinding.testapp.vo.CallbackBindingObject;
+import android.databinding.testapp.vo.NotBindableVo;
+import android.os.Build;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.widget.ArrayAdapter;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@RunWith(AndroidJUnit4.class)
+public class CallbackTest {
+ @Rule
+ public DataBindingTestRule<CallbacksBinding> mBindingRule = new DataBindingTestRule<>(
+ R.layout.callbacks
+ );
+
+ CallbackBindingObject mObj;
+ NotBindableVo mOther;
+ CallbacksBinding mBinding;
+
+ @Before
+ public void setup() throws Throwable {
+ mBinding = mBindingRule.getBinding();
+ mObj = mock(CallbackBindingObject.class);
+ mOther = new NotBindableVo();
+ mBinding.setObj(mObj);
+ mBinding.setOtherObj(mOther);
+ mBindingRule.executePending();
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ verifyZeroInteractions(mObj);
+ }
+ });
+
+ }
+
+ @Test
+ public void testRegularClick() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view1.performClick();
+ verify(mObj, times(1)).onClick();
+ verify(mObj, never()).onClick(any(View.class));
+ verify(mObj, never()).onClickWithParam(any(NotBindableVo.class));
+ verify(mObj, never()).onClickWithParam(any(View.class), any(NotBindableVo.class));
+ }
+ });
+ }
+
+ @Test
+ public void testClickWithCallbackArg() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view2.performClick();
+ verify(mObj, never()).onClick();
+ verify(mObj, times(1)).onClick(mBinding.view2);
+ verify(mObj, never()).onClickWithParam(any(NotBindableVo.class));
+ verify(mObj, never()).onClickWithParam(any(View.class), any(NotBindableVo.class));
+ }
+ });
+ }
+
+ @Test
+ public void testClickWithAnotherVariableAsArg() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view3.performClick();
+ verify(mObj, never()).onClick();
+ verify(mObj, never()).onClick(any(View.class));
+ verify(mObj, times(1)).onClickWithParam(eq(mOther));
+ verify(mObj, never()).onClickWithParam(any(View.class), any(NotBindableVo.class));
+ }
+ });
+ }
+
+ @Test
+ public void testClickWithViewAndAnotherVariableAsArgs() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view4.performClick();
+ verify(mObj, never()).onClick();
+ verify(mObj, never()).onClick(any(View.class));
+ verify(mObj, never()).onClickWithParam(any(NotBindableVo.class));
+ verify(mObj, times(1)).onClickWithParam(mBinding.view4, mOther);
+ }
+ });
+ }
+
+ @Test
+ public void nullObjectInCallback() throws Throwable {
+ mBinding.setObj(null);
+ mBindingRule.executePending();
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view1.performClick();
+ mBinding.view2.performClick();
+ mBinding.view3.performClick();
+ mBinding.view4.performClick();
+
+ MatcherAssert.assertThat(mBinding.view1.performLongClick(), CoreMatchers.is(false));
+ MatcherAssert.assertThat(mBinding.view2.performLongClick(), CoreMatchers.is(false));
+ MatcherAssert.assertThat(mBinding.view3.performLongClick(), CoreMatchers.is(false));
+ MatcherAssert.assertThat(mBinding.view4.performLongClick(), CoreMatchers.is(false));
+
+ }
+ });
+ verifyZeroInteractions(mObj);
+ }
+
+ // long click
+ @Test
+ public void testRegularLongClick() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ when(mObj.onLongClick()).thenReturn(true);
+ MatcherAssert.assertThat(mBinding.view1.performLongClick(), CoreMatchers.is(true));
+ verify(mObj, times(1)).onLongClick();
+ verify(mObj, never()).onLongClick(any(View.class));
+ verify(mObj, never()).onLongClickWithParam(any(NotBindableVo.class));
+ verify(mObj, never()).onLongClickWithParam(any(View.class), any(NotBindableVo
+ .class));
+ }
+ });
+ }
+
+ @Test
+ public void testLongClickWithCallbackArg() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ when(mObj.onLongClick(mBinding.view2)).thenReturn(true);
+ MatcherAssert.assertThat(mBinding.view2.performLongClick(), CoreMatchers.is(true));
+ verify(mObj, never()).onLongClick();
+ verify(mObj, times(1)).onLongClick(mBinding.view2);
+ verify(mObj, never()).onLongClickWithParam(any(NotBindableVo.class));
+ verify(mObj, never()).onLongClickWithParam(any(View.class), any(NotBindableVo
+ .class));
+ }
+ });
+ }
+
+ @Test
+ public void testLongClickWithAnotherVariableAsArg() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ when(mObj.onLongClickWithParam(mOther)).thenReturn(true);
+ MatcherAssert.assertThat(mBinding.view3.performLongClick(), CoreMatchers.is(true));
+ verify(mObj, never()).onLongClick();
+ verify(mObj, never()).onLongClick(any(View.class));
+ verify(mObj, times(1)).onLongClickWithParam(mOther);
+ verify(mObj, never()).onLongClickWithParam(any(View.class), any(NotBindableVo
+ .class));
+ }
+ });
+ }
+
+ @Test
+ public void testLongClickWithViewAndAnotherVariableAsArgs() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ when(mObj.onLongClickWithParam(mBinding.view4, mOther)).thenReturn(true);
+ MatcherAssert.assertThat(mBinding.view4.performLongClick(), CoreMatchers.is(true));
+ verify(mObj, never()).onLongClick();
+ verify(mObj, never()).onLongClick(any(View.class));
+ verify(mObj, never()).onLongClickWithParam(any(NotBindableVo.class));
+ verify(mObj, times(1)).onLongClickWithParam(mBinding.view4, mOther);
+ }
+ });
+ }
+
+ @Test
+ public void testListViewOnScroll() throws Throwable {
+ final CallbackBindingObject obj2 = mock(CallbackBindingObject.class);
+ mBinding.setObj2(obj2);
+ mBindingRule.executePending();
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // this is going to trigger scroll
+ mBinding.listView.setAdapter(new ArrayAdapter<>(mBinding.listView.getContext(),
+ android.R.layout.simple_list_item_1, Arrays.asList("a", "b")));
+ }
+ });
+ mBindingRule.runOnUiThread(new Runnable() {
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ @Override
+ public void run() {
+ // setting listener also calls the callback
+ verify(obj2).onScrolled();
+ }
+ });
+ }
+
+ @Test
+ public void testProgressChange() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.seekBar.setProgress(20);
+ verify(mObj, times(1)).onProgressChanged(mBinding.seekBar, 20, false);
+ }
+ });
+ }
+
+ @Test
+ public void testStaticCallViaClass() throws Throwable {
+ staticCall(mBinding.view5);
+ }
+
+ @Test
+ public void testStaticCallViaInstance() throws Throwable {
+ staticCall(mBinding.view6);
+ }
+
+ @Test
+ public void testVariableOverride() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view8.performClick();
+ verify(mObj).onClick(mBinding.view8);
+ }
+ });
+ }
+
+ @Test
+ public void testArrayAccess() throws Throwable {
+ final CallbackBindingObject[] objects = new CallbackBindingObject[] {
+ mock(CallbackBindingObject.class),
+ mock(CallbackBindingObject.class),
+ mock(CallbackBindingObject.class),
+ };
+ mBinding.setObjArr(objects);
+ mBindingRule.executePending();
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ verifyZeroInteractions(objects);
+ mBinding.view7.performClick();
+ verify(objects[1]).onClick(mBinding.view7);
+ mBinding.view7.performLongClick();
+ verify(objects[2]).onLongClick(mBinding.view7);
+ verifyZeroInteractions(objects[0]);
+ }
+ });
+ }
+
+ @Test
+ public void testStaticVariableFullPackage() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view9.performClick();
+ verify(mObj).setVisible(View.VISIBLE);
+ }
+ });
+ }
+
+ @Test
+ public void testStaticVariableImported() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view10.performClick();
+ verify(mObj).setVisible(NotBindableVo.STATIC_VAL);
+ }
+ });
+ }
+
+ @Test
+ public void testTernary1() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view11.setFocusable(false);
+ mBinding.view11.performClick();
+ verify(mObj).onNotFocusable();
+ verify(mObj, never()).onFocusable();
+ }
+ });
+ }
+
+ @Test
+ public void testTernary2() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view11.setFocusable(true);
+ mBinding.view11.performClick();
+ verify(mObj).onFocusable();
+ verify(mObj, never()).onNotFocusable();
+ }
+ });
+ }
+
+ @Test
+ public void testTernary3() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view11.setFocusable(false);
+ when(mObj.onFocusable()).thenReturn(true, false);
+ when(mObj.onNotFocusable()).thenReturn(false, true);
+ MatcherAssert.assertThat(mBinding.view11.performLongClick(), CoreMatchers.is(false));
+ MatcherAssert.assertThat(mBinding.view11.performLongClick(), CoreMatchers.is(true));
+ mBinding.view11.setFocusable(true);
+ MatcherAssert.assertThat(mBinding.view11.performLongClick(), CoreMatchers.is(true));
+ MatcherAssert.assertThat(mBinding.view11.performLongClick(), CoreMatchers.is(false));
+ }
+ });
+ }
+
+ @Test
+ public void testTernary4() throws Throwable {
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.view11.setFocusable(true);
+ mBinding.view11.performClick();
+ verify(mObj).onFocusable();
+ verify(mObj, never()).onNotFocusable();
+ }
+ });
+ }
+
+ private void staticCall(final View view) throws Throwable {
+ final AtomicInteger counter = NotBindableVo.sStaticCounter;
+ final int start = counter.get();
+ mBindingRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ view.performClick();
+ MatcherAssert.assertThat(counter.get(), CoreMatchers.is(start + 1));
+ MatcherAssert.assertThat(view.performLongClick(), CoreMatchers.is(true));
+ MatcherAssert.assertThat(counter.get(), CoreMatchers.is(start + 2));
+ }
+ });
+ }
+}
diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/DataBindingTestRule.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/DataBindingTestRule.java
new file mode 100644
index 00000000..587897d1
--- /dev/null
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/DataBindingTestRule.java
@@ -0,0 +1,64 @@
+/*
+ * 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.DataBindingUtil;
+import android.databinding.ViewDataBinding;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+
+/**
+ * Convenience rule for tests that use data binding.
+ * @param <T> The type of the generated binding class
+ */
+public class DataBindingTestRule<T extends ViewDataBinding>
+ extends ActivityTestRule<TestActivity> {
+ final int mLayoutId;
+ private T mBinding;
+ public DataBindingTestRule(int layoutId) {
+ super(TestActivity.class);
+ mLayoutId = layoutId;
+ }
+
+ @Override
+ protected void afterActivityLaunched() {
+ super.afterActivityLaunched();
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mBinding = DataBindingUtil.setContentView(getActivity(), mLayoutId);
+ }
+ });
+ }
+
+ public T getBinding() {
+ return mBinding;
+ }
+
+ public void executePending() {
+ try {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinding.executePendingBindings();
+ }
+ });
+ } catch (Throwable throwable) {
+ throw new RuntimeException("unexpected problem in execute pending", throwable);
+ }
+ }
+}
diff --git a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/FindMethodTest.java b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/FindMethodTest.java
index a7799dc4..234ec1d2 100644
--- a/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/FindMethodTest.java
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/FindMethodTest.java
@@ -123,4 +123,11 @@ public class FindMethodTest
assertTrue(mBinder.textView27.getTag() instanceof Integer);
assertEquals((Integer)1, mBinder.textView27.getTag());
}
+
+ @UiThreadTest
+ public void testFindMethodBasedOnSecondParam() throws Throwable {
+ mBinder.executePendingBindings();
+ assertEquals("2", mBinder.textView28.getText().toString());
+ assertEquals("10", mBinder.textView29.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..0a1b14d2
--- /dev/null
+++ b/integration-tests/TestApp/app/src/androidTestApi7/java/android/databinding/testapp/TwoWayBindingAdapterTest.java
@@ -0,0 +1,813 @@
+/*
+ * 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.Calendar;
+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() {
+ assertTrue(mBindingObject.date.get() != 0);
+ assertDatesMatch(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);
+ }
+
+ assertDatesMatch(date[0], mBindingObject.date.get());
+ }
+
+ public void assertDatesMatch(long expectedTimeMillis, long testTimeMillis) {
+ Calendar expected = Calendar.getInstance();
+ expected.setTimeInMillis(expectedTimeMillis);
+ Calendar testValue = Calendar.getInstance();
+ testValue.setTimeInMillis(testTimeMillis);
+ assertEquals(expected.get(Calendar.YEAR), testValue.get(Calendar.YEAR));
+ assertEquals(expected.get(Calendar.MONTH), testValue.get(Calendar.MONTH));
+ assertEquals(expected.get(Calendar.DAY_OF_MONTH),
+ testValue.get(Calendar.DAY_OF_MONTH));
+ }
+
+ 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());
+ }
+ });
+ }
+
+ public void testStringConversions() throws Throwable {
+ makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
+ mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
+ mBinder.convertDouble, mBinder.convertChar);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinder.convertBool.setText("True");
+ mBinder.convertByte.setText("123");
+ mBinder.convertShort.setText("1234");
+ mBinder.convertInt.setText("12345");
+ mBinder.convertLong.setText("123456");
+ mBinder.convertFloat.setText("1.2345");
+ mBinder.convertDouble.setText("1.23456");
+ mBinder.convertChar.setText("a");
+ }
+ });
+
+ final long timeout = SystemClock.uptimeMillis() + 500;
+ while (!mBindingObject.booleanField.get() && SystemClock.uptimeMillis() < timeout) {
+ Thread.sleep(1);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertTrue(mBindingObject.booleanField.get());
+ assertEquals(123, mBindingObject.byteField.get());
+ assertEquals(1234, mBindingObject.shortField.get());
+ assertEquals(12345, mBindingObject.intField.get());
+ assertEquals(123456, mBindingObject.longField.get());
+ assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
+ assertEquals(1.23456, mBindingObject.doubleField.get(), 0.000001);
+ assertEquals('a', mBindingObject.charField.get());
+ }
+
+ public void testBadStringConversions() throws Throwable {
+ makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
+ mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
+ mBinder.convertDouble, mBinder.convertChar);
+ mBindingObject.booleanField.set(true);
+ mBindingObject.charField.set('1');
+ mBindingObject.byteField.set((byte) 1);
+ mBindingObject.shortField.set((short) 12);
+ mBindingObject.intField.set(123);
+ mBindingObject.longField.set(1234);
+ mBindingObject.floatField.set(1.2345f);
+ mBindingObject.doubleField.set(1.23456);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mBinder.executePendingBindings();
+ mBinder.convertBool.setText("foobar");
+ mBinder.convertByte.setText("fred");
+ mBinder.convertShort.setText("wilma");
+ mBinder.convertInt.setText("barney");
+ mBinder.convertLong.setText("betty");
+ mBinder.convertFloat.setText("pebbles");
+ mBinder.convertDouble.setText("bam-bam");
+ mBinder.convertChar.setText("");
+ }
+ });
+
+ final long timeout = SystemClock.uptimeMillis() + 500;
+ while (mBindingObject.booleanField.get() && SystemClock.uptimeMillis() < timeout) {
+ Thread.sleep(1);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mBindingObject.booleanField.get());
+ assertEquals(1, mBindingObject.byteField.get());
+ assertEquals(12, mBindingObject.shortField.get());
+ assertEquals(123, mBindingObject.intField.get());
+ assertEquals(1234, mBindingObject.longField.get());
+ assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
+ assertEquals(1.23456, mBindingObject.doubleField.get(), 0.00001);
+ assertEquals('1', mBindingObject.charField.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);
+ mBinder.convertBool.setVisibility(View.GONE);
+ mBinder.convertByte.setVisibility(View.GONE);
+ mBinder.convertShort.setVisibility(View.GONE);
+ mBinder.convertInt.setVisibility(View.GONE);
+ mBinder.convertLong.setVisibility(View.GONE);
+ mBinder.convertFloat.setVisibility(View.GONE);
+ mBinder.convertDouble.setVisibility(View.GONE);
+ mBinder.convertChar.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/CallbackBindingObject.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/CallbackBindingObject.java
new file mode 100644
index 00000000..8ff88e6c
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/CallbackBindingObject.java
@@ -0,0 +1,70 @@
+/*
+ * 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.BaseObservable;
+import android.databinding.ObservableBoolean;
+import android.graphics.Outline;
+import android.media.MediaPlayer;
+import android.text.Editable;
+import android.view.ContextMenu;
+import android.view.DragEvent;
+import android.view.KeyEvent;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewStub;
+import android.view.WindowInsets;
+import android.view.animation.Animation;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.CalendarView;
+import android.widget.Chronometer;
+import android.widget.CompoundButton;
+import android.widget.ExpandableListView;
+import android.widget.NumberPicker;
+import android.widget.RadioGroup;
+import android.widget.RatingBar;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.TimePicker;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public interface CallbackBindingObject {
+ void onClick();
+ void onClick(View view);
+ boolean onLongClick();
+ boolean onLongClick(View view);
+ boolean onClickWithParam(NotBindableVo other);
+ boolean onClickWithParam(View view, NotBindableVo other);
+ boolean onLongClickWithParam(NotBindableVo other);
+ boolean onLongClickWithParam(View view, NotBindableVo other);
+ void onScrolled();
+ void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser);
+
+ void setVisible(int visible);
+ boolean onFocusable();
+ boolean onNotFocusable();
+
+ void beforeTextChanged(CharSequence s, int start, int count, int after);
+
+ void onTextChanged(CharSequence s, int start, int before, int count);
+
+ void beforeTextChanged();
+ void onTextChanged();
+}
diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/FindMethodBindingObject.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/FindMethodBindingObject.java
index 515a3413..452ddcf3 100644
--- a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/FindMethodBindingObject.java
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/FindMethodBindingObject.java
@@ -16,7 +16,6 @@
package android.databinding.testapp.vo;
import android.databinding.BaseObservable;
-import android.databinding.Bindable;
import android.databinding.ObservableField;
import android.databinding.testapp.BR;
import android.util.ArrayMap;
@@ -67,6 +66,18 @@ public class FindMethodBindingObject extends FindMethodBindingObjectBase {
return vals;
}
+ public int argsClose(int i, String j) {
+ return i;
+ }
+
+ public float argsClose(int i, short j) {
+ return i;
+ }
+
+ public int argsClose(int i, int j) {
+ return j;
+ }
+
public static class Foo {
public final String bar = "hello world";
public static final String baz = "hello world";
diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/NotBindableVo.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/NotBindableVo.java
index 64d1a480..cfb52ebd 100644
--- a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/NotBindableVo.java
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/NotBindableVo.java
@@ -13,7 +13,12 @@
package android.databinding.testapp.vo;
+import android.view.View;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
public class NotBindableVo {
+ public static int STATIC_VAL = 101;
private int mIntValue;
private int mIntValueGetCount;
private boolean mBoolValue;
@@ -22,6 +27,7 @@ public class NotBindableVo {
private int mStringValueGetCount;
private final String mFinalString = "this has final content";
public final int publicField = 3;
+ public static AtomicInteger sStaticCounter = new AtomicInteger();
public NotBindableVo() {
}
@@ -85,4 +91,9 @@ public class NotBindableVo {
public int getStringValueGetCount() {
return mStringValueGetCount;
}
+
+ public static boolean incStaticCounter() {
+ sStaticCounter.incrementAndGet();
+ return true;
+ }
}
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..f3adbdd3
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/TwoWayBindingObject.java
@@ -0,0 +1,91 @@
+/*
+ * 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.ObservableByte;
+import android.databinding.ObservableChar;
+import android.databinding.ObservableDouble;
+import android.databinding.ObservableField;
+import android.databinding.ObservableFloat;
+import android.databinding.ObservableInt;
+import android.databinding.ObservableLong;
+import android.databinding.ObservableShort;
+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 final ObservableBoolean booleanField = new ObservableBoolean();
+ public final ObservableByte byteField = new ObservableByte();
+ public final ObservableShort shortField = new ObservableShort();
+ public final ObservableInt intField = new ObservableInt();
+ public final ObservableLong longField = new ObservableLong();
+ public final ObservableFloat floatField = new ObservableFloat();
+ public final ObservableDouble doubleField = new ObservableDouble();
+ public final ObservableChar charField = new ObservableChar();
+ 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/java/android/databinding/testapp/vo/ViewModel.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/ViewModel.java
new file mode 100644
index 00000000..2454fb9d
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/vo/ViewModel.java
@@ -0,0 +1,46 @@
+/*
+ * 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.vo;
+
+import android.databinding.BaseObservable;
+import android.databinding.Bindable;
+import android.databinding.ObservableField;
+import android.databinding.ObservableInt;
+
+public class ViewModel extends BaseObservable {
+ @Bindable
+ public ObservableInt publicObservable = new ObservableInt();
+
+ @Bindable
+ private ObservableField<String> fieldObservable = new ObservableField<>();
+
+ private ObservableInt methodObservable = new ObservableInt();
+
+
+ public ObservableField<String> getFieldObservable() {
+ return fieldObservable;
+ }
+
+ @Bindable
+ public ObservableInt getMethodObservable() {
+ return methodObservable;
+ }
+
+ public void setFieldObservable(ObservableField<String> fieldObservable) {
+ this.fieldObservable = fieldObservable;
+ }
+
+ public void setMethodObservable(ObservableInt methodObservable) {
+ this.methodObservable = methodObservable;
+ }
+}
diff --git a/integration-tests/TestApp/app/src/main/res/layout/bindable_observables.xml b/integration-tests/TestApp/app/src/main/res/layout/bindable_observables.xml
new file mode 100644
index 00000000..c325a23a
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/res/layout/bindable_observables.xml
@@ -0,0 +1,33 @@
+<?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">
+ <data>
+ <variable name="model" type="android.databinding.testapp.vo.ViewModel"/>
+ </data>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <TextView android:id="@+id/view1" android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="@{model.publicObservable}"/>
+ <TextView android:id="@+id/view2" android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{model.fieldObservable}"/>
+ <TextView android:id="@+id/view3" android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="@{model.methodObservable}"/>
+
+ </FrameLayout>
+</layout>
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/callbacks.xml b/integration-tests/TestApp/app/src/main/res/layout/callbacks.xml
new file mode 100644
index 00000000..f312ec60
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/res/layout/callbacks.xml
@@ -0,0 +1,109 @@
+<?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"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <data>
+ <import type="android.databinding.testapp.vo.NotBindableVo"/>
+ <variable name="otherObj" type="android.databinding.testapp.vo.NotBindableVo"/>
+ <variable name="obj" type="android.databinding.testapp.vo.CallbackBindingObject"/>
+ <variable name="obj2" type="android.databinding.testapp.vo.CallbackBindingObject"/>
+ <variable name="objArr" type="android.databinding.testapp.vo.CallbackBindingObject[]"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:id="@+id/view1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{() -> obj.onClick()}"
+ android:onLongClick="@{() -> obj.onLongClick()}"
+ />
+ <View
+ android:id="@+id/view2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{(v) -> obj.onClick(v)}"
+ android:onLongClick="@{(view) -> obj.onLongClick(view)}"
+ />
+
+ <View
+ android:id="@+id/view3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{(v) -> obj.onClickWithParam(otherObj)}"
+ android:onLongClick="@{(view) -> obj.onLongClickWithParam(otherObj)}"
+ />
+
+ <View
+ android:id="@+id/view4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{(v) -> obj.onClickWithParam(v, otherObj)}"
+ android:onLongClick="@{(view) -> obj.onLongClickWithParam(view, otherObj)}"
+ />
+
+ <!-- via adapter and also multiple params -->
+ <ListView
+ android:id="@+id/listView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onScroll="@{() -> obj2.onScrolled()}"/>
+
+ <SeekBar
+ android:id="@+id/seekBar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onProgressChanged="@{(seekBar, progress, fromUser) -> obj.onProgressChanged(seekBar, progress, fromUser)}"
+ />
+ <View
+ android:id="@+id/view5"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{(v) -> NotBindableVo.incStaticCounter()}"
+ android:onLongClick="@{(v) -> NotBindableVo.incStaticCounter()}"
+ />
+ <View
+ android:id="@+id/view6"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="@{(v) -> otherObj.incStaticCounter()}"
+ android:onLongClick="@{(v) -> otherObj.incStaticCounter()}"
+ />
+ <View android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:id="@+id/view7"
+ android:onClick="@{(v) -> objArr[1].onClick(v)}"
+ android:onLongClick="@{(view) -> objArr[2].onLongClick(view)}"/>
+
+ <!--variable override-->
+ <View android:layout_width="wrap_content" android:layout_height="match_parent"
+ android:id="@+id/view8"
+ android:onClick="@{(objArr) -> obj.onClick(objArr)}"/>
+
+ <View android:layout_width="wrap_content" android:layout_height="match_parent"
+ android:id="@+id/view9"
+ android:onClick="@{(v) -> obj.setVisible(android.view.View.VISIBLE)}"/>
+
+ <View android:layout_width="wrap_content" android:layout_height="match_parent"
+ android:id="@+id/view10"
+ android:onClick="@{(v) -> obj.setVisible(NotBindableVo.STATIC_VAL)}"/>
+
+ <View android:layout_width="wrap_content" android:layout_height="match_parent"
+ android:id="@+id/view11"
+ android:onClick="@{(v) -> v.focusable ? obj.onFocusable() : obj.onNotFocusable()}"
+ android:onLongClick="@{(v) -> v.focusable ? obj.onFocusable() : obj.onNotFocusable()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
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/find_method_test.xml b/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
index 509517f8..cc5a2c63 100644
--- a/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
+++ b/integration-tests/TestApp/app/src/main/res/layout/find_method_test.xml
@@ -139,5 +139,15 @@
android:id="@+id/textView27"
android:layout_width="wrap_content" android:layout_height="wrap_content"
app:tag="@{1}"/>
+ <TextView
+ android:id="@+id/textView28"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@{`` + ((Integer)obj.argsClose(1, 2))}"
+ />
+ <TextView
+ android:id="@+id/textView29"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@{`` + ((Integer)obj.argsClose(10, `Hello World`))}"
+ />
</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..ad12d58c
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/res/layout/two_way.xml
@@ -0,0 +1,223 @@
+<?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"/>
+ <EditText
+ android:id="@+id/convertBool"
+ android:text="@={`` + obj.booleanField}"
+ android:inputType="number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertByte"
+ android:text="@={`` + obj.byteField}"
+ android:inputType="number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertShort"
+ android:text="@={`` + obj.shortField}"
+ android:inputType="number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertInt"
+ android:text="@={`` + obj.intField}"
+ android:inputType="number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertLong"
+ android:text="@={`` + obj.longField}"
+ android:inputType="number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertFloat"
+ android:text="@={`` + obj.floatField}"
+ android:inputType="numberDecimal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertDouble"
+ android:text="@={`` + obj.doubleField}"
+ android:inputType="numberDecimal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <EditText
+ android:id="@+id/convertChar"
+ android:text="@={`` + obj.charField}"
+ android:inputType="number"
+ 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/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar
index e003a04a..56b9cc3f 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar
+++ b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar
Binary files differ
diff --git a/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.md5 b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.md5
index d93d95d4..602f2427 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.md5
+++ b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.md5
@@ -1 +1 @@
-4b81f88150cd2be1b1f6d886100af1c2 \ No newline at end of file
+655e10a4a34db4274d7731fccd675bad \ No newline at end of file
diff --git a/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.sha1 b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.sha1
index 77d54220..8cf3d004 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.sha1
+++ b/internal-prebuilts/com/android/databinding/localizemaven/1.1/localizemaven-1.1.jar.sha1
@@ -1 +1 @@
-6e19c0ca82802428346c624673e66479089c6814 \ No newline at end of file
+eb55fbfc70996f9645de075086df68794d96e4dc \ No newline at end of file
diff --git a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml
index 4f263e99..cf7e9ce8 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml
+++ b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml
@@ -2,11 +2,11 @@
<metadata>
<groupId>com.android.databinding</groupId>
<artifactId>localizemaven</artifactId>
- <version>1.1</version>
<versioning>
+ <release>1.1</release>
<versions>
<version>1.1</version>
</versions>
- <lastUpdated>20151104222707</lastUpdated>
+ <lastUpdated>20160212192012</lastUpdated>
</versioning>
</metadata>
diff --git a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.md5 b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.md5
index accb9a00..4c02386c 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.md5
+++ b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.md5
@@ -1 +1 @@
-71903e14023ca5e2adb851cf065715e7 \ No newline at end of file
+d6a9b7f884c713fa405cb4a3faf2c9fe \ No newline at end of file
diff --git a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.sha1 b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.sha1
index c2964b1a..b90a5d57 100644
--- a/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.sha1
+++ b/internal-prebuilts/com/android/databinding/localizemaven/maven-metadata.xml.sha1
@@ -1 +1 @@
-f30fef09adcbc55cf74ad44c7607accc884d87f9 \ No newline at end of file
+f5afd3a9fd6308b1fe4fdfbf54356a7afa344c0f \ No newline at end of file
diff --git a/propLoader.gradle b/propLoader.gradle
index 310d313e..d3e65cd9 100644
--- a/propLoader.gradle
+++ b/propLoader.gradle
@@ -14,9 +14,10 @@ def repoBase = databindingProperties.mavenRepoAbsolutePath == "." ? root : datab
databindingProperties.androidGradlePluginRepoDir = "${root}/../../${databindingProperties.androidGradlePluginOutRepo}"
databindingProperties.mavenRepoDir = "${databindingProperties.androidGradlePluginRepoDir}"
databindingProperties.internalPrebuiltsRepoDir = "${root}/${databindingProperties.internalPrebuiltsRepoName}"
-databindingProperties.runProguard = project.hasProperty('runProguard') && project.getProperty('runProguard').equals("true")
-databindingProperties.inReleaseBuild = project.ext.hasProperty('release') && project.ext.release
+databindingProperties.inReleaseBuild = project.hasProperty('release') && project.ext.release == "true"
+
+databindingProperties.runProguard = (project.hasProperty('runProguard') && project.getProperty('runProguard').equals("true"))
// load version from gradle build file
apply from: "$root/../buildSrc/base/version.gradle"
databindingProperties.androidPluginVersion=ext.buildVersion
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"