diff options
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>@={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 = "
"; - 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<String> name = new ObservableField<String>(); + * public final ObservableField<String> name = new ObservableField<String>(); * 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<String> name = new ObservableField<String>(); * 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<String> name = new ObservableParcelable<String>(); + * public final ObservableParcelable<String> name = new ObservableParcelable<String>(); * 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 Binary files differindex 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 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" |