diff --git a/json/gen/com/intellij/json/_JsonLexer.flex b/json/gen/com/intellij/json/_JsonLexer.flex
index c59f27dbcbf0..7bcfc6015e1e 100644
--- a/json/gen/com/intellij/json/_JsonLexer.flex
+++ b/json/gen/com/intellij/json/_JsonLexer.flex
@@ -26,7 +26,7 @@ LINE_COMMENT="//".*
BLOCK_COMMENT="/"\*([^*]|\*+[^*/])*(\*+"/")?
DOUBLE_QUOTED_STRING=\"([^\\\"\r\n]|\\[^\r\n])*\"?
SINGLE_QUOTED_STRING='([^\\'\r\n]|\\[^\r\n])*'?
-NUMBER=-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?
+NUMBER=-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]*)?
INDENTIFIER=[:jletter:] [:jletterdigit:]*
%%
diff --git a/json/gen/com/intellij/json/_JsonLexer.java b/json/gen/com/intellij/json/_JsonLexer.java
index 3f341b1c2c15..0f0c24fdcac8 100644
--- a/json/gen/com/intellij/json/_JsonLexer.java
+++ b/json/gen/com/intellij/json/_JsonLexer.java
@@ -1,4 +1,4 @@
-/* The following code was generated by JFlex 1.4.3 on 10/1/14 5:02 PM */
+/* The following code was generated by JFlex 1.4.3 on 10/8/14 3:56 PM */
package com.intellij.json;
import com.intellij.lexer.*;
@@ -9,7 +9,7 @@ import static com.intellij.json.JsonElementTypes.*;
/**
* This class is a scanner generated by
* JFlex 1.4.3
- * on 10/1/14 5:02 PM from the specification file
+ * on 10/8/14 3:56 PM from the specification file
* /home/east825/develop/repos/IDEA/community/json/gen/com/intellij/json/_JsonLexer.flex
*/
public class _JsonLexer implements FlexLexer {
@@ -158,12 +158,11 @@ public class _JsonLexer implements FlexLexer {
private static final String ZZ_ACTION_PACKED_0 =
"\1\0\1\1\1\2\1\1\1\3\1\4\1\1\2\5"+
"\1\6\1\7\1\10\1\11\1\12\1\13\1\14\3\6"+
- "\1\15\1\16\1\3\2\0\1\4\2\0\3\6\1\0"+
- "\1\5\1\0\1\5\3\6\1\16\1\17\1\6\1\20"+
- "\1\21";
+ "\1\15\1\16\1\3\2\0\1\4\1\0\1\5\3\6"+
+ "\1\0\2\5\3\6\1\16\1\17\1\6\1\20\1\21";
private static int [] zzUnpackAction() {
- int [] result = new int[42];
+ int [] result = new int[41];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
@@ -192,11 +191,11 @@ public class _JsonLexer implements FlexLexer {
"\0\u0100\0\u0120\0\40\0\40\0\40\0\40\0\40\0\40"+
"\0\u0140\0\u0160\0\u0180\0\u01a0\0\u01c0\0\40\0\u01e0\0\u0200"+
"\0\40\0\u0220\0\u0240\0\u0260\0\u0280\0\u02a0\0\u02c0\0\u02e0"+
- "\0\u0300\0\u0300\0\u0320\0\u0340\0\u0360\0\40\0\u0120\0\u0380"+
- "\0\u0120\0\u0120";
+ "\0\u0300\0\u0320\0\u0340\0\u0360\0\40\0\u0120\0\u0380\0\u0120"+
+ "\0\u0120";
private static int [] zzUnpackRowMap() {
- int [] result = new int[42];
+ int [] result = new int[41];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
@@ -232,18 +231,18 @@ public class _JsonLexer implements FlexLexer {
"\1\0\2\12\6\0\5\12\1\35\3\12\12\0\2\12"+
"\1\0\1\12\1\0\2\12\6\0\2\12\1\36\6\12"+
"\2\24\1\0\35\24\5\25\1\37\32\25\1\5\2\0"+
- "\35\5\1\6\2\0\35\6\12\0\2\40\35\0\1\41"+
- "\2\42\2\0\1\41\33\0\2\12\1\0\1\12\1\0"+
- "\2\12\6\0\2\12\1\43\6\12\12\0\2\12\1\0"+
- "\1\12\1\0\2\12\6\0\6\12\1\44\2\12\12\0"+
- "\2\12\1\0\1\12\1\0\2\12\6\0\6\12\1\45"+
- "\2\12\4\25\1\46\1\37\32\25\12\0\2\40\1\0"+
- "\1\33\14\0\1\33\17\0\2\42\36\0\2\12\1\0"+
- "\1\12\1\0\2\12\6\0\3\12\1\47\5\12\12\0"+
- "\2\12\1\0\1\12\1\0\2\12\6\0\7\12\1\50"+
- "\1\12\12\0\2\12\1\0\1\12\1\0\2\12\6\0"+
- "\6\12\1\51\2\12\12\0\2\12\1\0\1\12\1\0"+
- "\2\12\6\0\3\12\1\52\5\12";
+ "\35\5\1\6\2\0\35\6\12\0\2\40\35\0\3\41"+
+ "\2\0\1\41\33\0\2\12\1\0\1\12\1\0\2\12"+
+ "\6\0\2\12\1\42\6\12\12\0\2\12\1\0\1\12"+
+ "\1\0\2\12\6\0\6\12\1\43\2\12\12\0\2\12"+
+ "\1\0\1\12\1\0\2\12\6\0\6\12\1\44\2\12"+
+ "\4\25\1\45\1\37\32\25\12\0\2\40\1\0\1\33"+
+ "\14\0\1\33\17\0\2\41\36\0\2\12\1\0\1\12"+
+ "\1\0\2\12\6\0\3\12\1\46\5\12\12\0\2\12"+
+ "\1\0\1\12\1\0\2\12\6\0\7\12\1\47\1\12"+
+ "\12\0\2\12\1\0\1\12\1\0\2\12\6\0\6\12"+
+ "\1\50\2\12\12\0\2\12\1\0\1\12\1\0\2\12"+
+ "\6\0\3\12\1\51\5\12";
private static int [] zzUnpackTrans() {
int [] result = new int[928];
@@ -288,10 +287,10 @@ public class _JsonLexer implements FlexLexer {
private static final String ZZ_ATTRIBUTE_PACKED_0 =
"\1\0\1\11\10\1\6\11\5\1\1\11\2\0\1\11"+
- "\2\0\3\1\1\0\1\1\1\0\4\1\1\11\4\1";
+ "\1\0\4\1\1\0\5\1\1\11\4\1";
private static int [] zzUnpackAttribute() {
- int [] result = new int[42];
+ int [] result = new int[41];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
diff --git a/json/src/com/intellij/json/JsonBundle.properties b/json/src/com/intellij/json/JsonBundle.properties
index 1537845b49e5..ac1d5bdcf1eb 100644
--- a/json/src/com/intellij/json/JsonBundle.properties
+++ b/json/src/com/intellij/json/JsonBundle.properties
@@ -1,6 +1,7 @@
msg.missing.closing.quote=Missing closing quote
msg.illegal.escape.sequence=Illegal escape sequence
msg.illegal.unicode.escape.sequence=Illegal unicode escape sequence
+msg.illegal.floating.point.literal=Illegal floating point literal
msg.compliance.problem.comments=JSON standard does not allow comments. Use JSMin or similar tool to remove comments before parsing.
msg.compliance.problem.single.quoted.strings=JSON standard does not allow single quoted strings
diff --git a/json/src/com/intellij/json/codeinsight/JsonStringLiteralAnnotator.java b/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java
similarity index 82%
rename from json/src/com/intellij/json/codeinsight/JsonStringLiteralAnnotator.java
rename to json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java
index e83d2b8a1268..335bb12c0e48 100644
--- a/json/src/com/intellij/json/codeinsight/JsonStringLiteralAnnotator.java
+++ b/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java
@@ -1,6 +1,7 @@
package com.intellij.json.codeinsight;
import com.intellij.json.JsonBundle;
+import com.intellij.json.psi.JsonNumberLiteral;
import com.intellij.json.psi.JsonPsiUtil;
import com.intellij.json.psi.JsonStringLiteral;
import com.intellij.lang.annotation.AnnotationHolder;
@@ -18,8 +19,9 @@ import java.util.regex.Pattern;
/**
* @author Mikhail Golubev
*/
-public class JsonStringLiteralAnnotator implements Annotator {
+public class JsonLiteralAnnotator implements Annotator {
private static final Pattern VALID_ESCAPE = Pattern.compile("\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4})");
+ private static final Pattern VALID_NUMBER_LITERAL = Pattern.compile("-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?");
private static boolean debug = ApplicationManager.getApplication().isUnitTestMode();
@@ -34,9 +36,10 @@ public class JsonStringLiteralAnnotator implements Annotator {
}
final String text = element.getText();
final int length = text.length();
+
// Check that string literal is closed properly
if (length <= 1 || text.charAt(0) != text.charAt(length - 1) || quoteEscaped(text, length - 1)) {
- holder.createErrorAnnotation(element.getTextRange(), JsonBundle.message("msg.missing.closing.quote"));
+ holder.createErrorAnnotation(element, JsonBundle.message("msg.missing.closing.quote"));
}
// Check escapes
@@ -54,6 +57,11 @@ public class JsonStringLiteralAnnotator implements Annotator {
}
}
}
+ else if (element instanceof JsonNumberLiteral) {
+ if (!VALID_NUMBER_LITERAL.matcher(element.getText()).matches()) {
+ holder.createErrorAnnotation(element, JsonBundle.message("msg.illegal.floating.point.literal"));
+ }
+ }
}
private static boolean quoteEscaped(String text, int quotePos) {
diff --git a/json/src/json.bnf b/json/src/json.bnf
index fe8b0fa85c1f..d85b0231e0f4 100644
--- a/json/src/json.bnf
+++ b/json/src/json.bnf
@@ -35,7 +35,7 @@
SINGLE_QUOTED_STRING="regexp:'([^\\\'\r\n]|\\[^\r\n])*'?"
// STRING='regexp:"([^\\"\r\n]|\\([\\"/bfnrt]|u[a-fA-F0-9]{4}))*"?'
- NUMBER='regexp:-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?'
+ NUMBER='regexp:-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d*)?'
TRUE='true'
FALSE='false'
NULL='null'
diff --git a/json/tests/test/com/intellij/json/JsonHighlightingTest.java b/json/tests/test/com/intellij/json/JsonHighlightingTest.java
index 6494a1d7cd34..55669514cf2d 100644
--- a/json/tests/test/com/intellij/json/JsonHighlightingTest.java
+++ b/json/tests/test/com/intellij/json/JsonHighlightingTest.java
@@ -35,6 +35,11 @@ public class JsonHighlightingTest extends JsonTestCase {
doTestHighlighting(false, true, true);
}
+ // WEB-13600
+ public void testIncompleteFloatingPointLiteralsWithExponent() {
+ doTestHighlighting(false, false, false);
+ }
+
// Moved from JavaScript
public void testJSON_with_comment() throws Exception {
diff --git a/json/tests/testData/highlighting/IncompleteFloatingPointLiteralsWithExponent.json b/json/tests/testData/highlighting/IncompleteFloatingPointLiteralsWithExponent.json
new file mode 100644
index 000000000000..f954b6a0db01
--- /dev/null
+++ b/json/tests/testData/highlighting/IncompleteFloatingPointLiteralsWithExponent.json
@@ -0,0 +1,7 @@
+[
+ 1.2e,
+ 1.2e+,
+ 1.2E-,
+ 1.2e+1,
+ 1.2E-1
+]
\ No newline at end of file
diff --git a/json/tests/testData/psi/NumberLiterals.txt b/json/tests/testData/psi/NumberLiterals.txt
index a4c9366f8e77..592f006f3ef5 100644
--- a/json/tests/testData/psi/NumberLiterals.txt
+++ b/json/tests/testData/psi/NumberLiterals.txt
@@ -63,11 +63,7 @@ JsonFile: NumberLiterals.json
PsiElement(,)(',')
PsiWhiteSpace('\n\n ')
JsonNumberLiteral
- PsiElement(NUMBER)('1')
- PsiErrorElement:',' or ']' expected, got 'e'
-
- JsonReferenceExpression
- PsiElement(INDENTIFIER)('e')
+ PsiElement(NUMBER)('1e')
PsiElement(,)(',')
PsiWhiteSpace('\n ')
JsonReferenceExpression
@@ -135,11 +131,7 @@ JsonFile: NumberLiterals.json
PsiElement(,)(',')
PsiWhiteSpace('\n ')
JsonNumberLiteral
- PsiElement(NUMBER)('1.2')
- PsiErrorElement:',' or ']' expected, got 'e'
-
- JsonReferenceExpression
- PsiElement(INDENTIFIER)('e')
+ PsiElement(NUMBER)('1.2e')
PsiElement(,)(',')
PsiWhiteSpace('\n ')
PsiErrorElement:'.' unexpected
diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml
index 0604be44c8ed..b693b3fb247f 100644
--- a/platform/platform-resources/src/META-INF/JsonPlugin.xml
+++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml
@@ -44,7 +44,7 @@
-
+