summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2015-10-07 13:37:23 -0700
committerYigit Boyar <yboyar@google.com>2015-10-07 13:44:56 -0700
commitfd8342a51a96282df315cd27055ba539e89a8c9e (patch)
tree091a7001896fe75286e672e64cfedfd10e143226
parent8510dab6a17ccd59a2a9cbc07f900dfc2f11ff2b (diff)
downloaddata-binding-fd8342a51a96282df315cd27055ba539e89a8c9e.tar.gz
Report syntax errors even though Antlr can recover
This CL makes Antlr parser more strict by not allowing errors. Antlr usually tries to recover from these errors but thats not what we really want for this use case. This CL also updates version codes to rc4 since rc3 is already out. Change-Id: I0d305e06a6cdcbae2f37573c3c6ae4233cdd7958
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java23
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_bad_syntax.xml28
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_completely_broken_syntax.xml24
-rw-r--r--compiler/src/main/java/android/databinding/tool/ExpressionParser.java14
-rw-r--r--compiler/src/main/java/android/databinding/tool/LayoutBinder.java9
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java1
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java3
-rw-r--r--databinding.properties4
8 files changed, 101 insertions, 5 deletions
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
index 8268a5ff..17e88e07 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
@@ -36,6 +36,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public class SimpleCompilationTest extends BaseCompilationTest {
@Test
@@ -123,6 +124,28 @@ public class SimpleCompilationTest extends BaseCompilationTest {
}
@Test
+ public void testBadSyntax() throws IOException, URISyntaxException, InterruptedException {
+ singleFileErrorTest("/layout/layout_with_bad_syntax.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "myVar.length())",
+ String.format(ErrorMessages.SYNTAX_ERROR,
+ "extraneous input ')' expecting {<EOF>, ',', '.', '[', '+', '-', '*', '/', "
+ + "'%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof', "
+ + "'==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
+ }
+
+ @Test
+ public void testBrokenSyntax() throws IOException, URISyntaxException, InterruptedException {
+ singleFileErrorTest("/layout/layout_with_completely_broken_syntax.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "new String()",
+ String.format(ErrorMessages.SYNTAX_ERROR,
+ "mismatched input 'String' expecting {<EOF>, ',', '.', '[', '+', '-', '*', "
+ + "'/', '%', '<<', '>>>', '>>', '<=', '>=', '>', '<', 'instanceof',"
+ + " '==', '!=', '&', '^', '|', '&&', '||', '?', '??'}"));
+ }
+
+ @Test
public void testUndefinedVariable() throws IOException, URISyntaxException,
InterruptedException {
ScopedException ex = singleFileErrorTest("/layout/undefined_variable_binding.xml",
diff --git a/compilationTests/src/test/resources/layout/layout_with_bad_syntax.xml b/compilationTests/src/test/resources/layout/layout_with_bad_syntax.xml
new file mode 100644
index 00000000..6a90af87
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_bad_syntax.xml
@@ -0,0 +1,28 @@
+<?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: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 -->
+ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@{myVar.length())}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compilationTests/src/test/resources/layout/layout_with_completely_broken_syntax.xml b/compilationTests/src/test/resources/layout/layout_with_completely_broken_syntax.xml
new file mode 100644
index 00000000..dca87ae2
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_completely_broken_syntax.xml
@@ -0,0 +1,24 @@
+<?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">
+ <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:text="@{new String()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
index 467f658b..27168a63 100644
--- a/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
+++ b/compiler/src/main/java/android/databinding/tool/ExpressionParser.java
@@ -17,17 +17,23 @@
package android.databinding.tool;
import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
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;
+import org.apache.commons.lang3.StringUtils;
import android.databinding.parser.BindingExpressionLexer;
import android.databinding.parser.BindingExpressionParser;
import android.databinding.tool.expr.Expr;
import android.databinding.tool.expr.ExprModel;
+import android.databinding.tool.processing.ErrorMessages;
import android.databinding.tool.store.Location;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
@@ -49,6 +55,14 @@ public class ExpressionParser {
BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
final BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
+ 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) {
+ L.e(ErrorMessages.SYNTAX_ERROR, msg);
+ }
+ });
BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax();
try {
mModel.setCurrentLocationInFile(locationInFile);
diff --git a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
index 1871577b..e099f286 100644
--- a/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
+++ b/compiler/src/main/java/android/databinding/tool/LayoutBinder.java
@@ -199,8 +199,13 @@ public class LayoutBinder implements FileScopeProvider {
final BindingTarget bindingTarget = createBindingTarget(targetBundle);
for (BindingTargetBundle.BindingBundle bindingBundle : targetBundle
.getBindingBundleList()) {
- bindingTarget.addBinding(bindingBundle.getName(),
- parse(bindingBundle.getExpr(), bindingBundle.getValueLocation()));
+ try {
+ Scope.enter(bindingBundle.getValueLocation());
+ bindingTarget.addBinding(bindingBundle.getName(),
+ parse(bindingBundle.getExpr(), bindingBundle.getValueLocation()));
+ } finally {
+ Scope.exit();
+ }
}
bindingTarget.resolveMultiSetters();
bindingTarget.resolveListeners();
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 6853ddba..5d7cb313 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/ErrorMessages.java
@@ -39,4 +39,5 @@ public class ErrorMessages {
public static final String ROOT_TAG_NOT_SUPPORTED = "android:tag is not supported on root " +
"elements of data bound layouts unless targeting API version 14 or greater. Value " +
"is '%s'";
+ public static final String SYNTAX_ERROR = "Syntax error: %s";
}
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 238a895b..d60c2d5f 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/processing/ScopedException.java
@@ -40,7 +40,8 @@ public class ScopedException extends RuntimeException {
private String mScopeLog;
public ScopedException(String message, Object... args) {
- super(message == null ? "unknown data binding exception" : String.format(message, args));
+ super(message == null ? "unknown data binding exception" :
+ args.length == 0 ? message : String.format(message, args));
mScopedErrorReport = Scope.createReport();
mScopeLog = L.isDebugEnabled() ? Scope.produceScopeLog() : null;
}
diff --git a/databinding.properties b/databinding.properties
index 844231b1..737324ed 100644
--- a/databinding.properties
+++ b/databinding.properties
@@ -1,7 +1,7 @@
# global settings for projects
kotlinVersion = 0.13.1514
-version = 1.0-rc3-SNAPSHOT
-releaseVersion = 1.0-rc3
+version = 1.0-rc4-SNAPSHOT
+releaseVersion = 1.0-rc4
androidPluginVersion = 1.4.0-beta5
javaTargetCompatibility = 1.7
javaSourceCompatibility = 1.7