summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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