mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 06:39:38 +07:00
Change JSON grammar to allow usage of any literals and identifiers as property keys
This commit is contained in:
@@ -297,14 +297,13 @@ public class JsonParser implements PsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// string_literal (':' value)
|
||||
// property_name (':' value)
|
||||
public static boolean property(PsiBuilder builder_, int level_) {
|
||||
if (!recursion_guard_(builder_, level_, "property")) return false;
|
||||
if (!nextTokenIs(builder_, "<property>", DOUBLE_QUOTED_STRING, SINGLE_QUOTED_STRING)) return false;
|
||||
boolean result_;
|
||||
boolean pinned_;
|
||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, "<property>");
|
||||
result_ = string_literal(builder_, level_ + 1);
|
||||
result_ = property_name(builder_, level_ + 1);
|
||||
pinned_ = result_; // pin = 1
|
||||
result_ = result_ && property_1(builder_, level_ + 1);
|
||||
exit_section_(builder_, level_, marker_, PROPERTY, result_, pinned_, null);
|
||||
@@ -324,6 +323,18 @@ public class JsonParser implements PsiParser {
|
||||
return result_ || pinned_;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// literal | reference_expression
|
||||
static boolean property_name(PsiBuilder builder_, int level_) {
|
||||
if (!recursion_guard_(builder_, level_, "property_name")) return false;
|
||||
boolean result_;
|
||||
Marker marker_ = enter_section_(builder_);
|
||||
result_ = literal(builder_, level_ + 1);
|
||||
if (!result_) result_ = reference_expression(builder_, level_ + 1);
|
||||
exit_section_(builder_, marker_, null, result_);
|
||||
return result_;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// INDENTIFIER
|
||||
public static boolean reference_expression(PsiBuilder builder_, int level_) {
|
||||
|
||||
@@ -12,7 +12,7 @@ public interface JsonProperty extends JsonElement, PsiNamedElement {
|
||||
String getName();
|
||||
|
||||
@NotNull
|
||||
JsonStringLiteral getNameElement();
|
||||
JsonValue getNameElement();
|
||||
|
||||
@Nullable
|
||||
JsonValue getValue();
|
||||
|
||||
@@ -27,7 +27,7 @@ public class JsonPropertyImpl extends JsonPropertyMixin implements JsonProperty
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsonStringLiteral getNameElement() {
|
||||
public JsonValue getNameElement() {
|
||||
return JsonPsiImplUtils.getNameElement(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.intellij.json.editor.smartEnter;
|
||||
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.json.psi.JsonArray;
|
||||
import com.intellij.json.psi.JsonFile;
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
import com.intellij.json.psi.JsonValue;
|
||||
import com.intellij.lang.SmartEnterProcessorWithFixers;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -91,7 +94,7 @@ public class JsonSmartEnterProcessor extends SmartEnterProcessorWithFixers {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final JsonStringLiteral propertyKey = ((JsonProperty)element).getNameElement();
|
||||
final JsonValue propertyKey = ((JsonProperty)element).getNameElement();
|
||||
final int keyEndOffset = propertyKey.getTextRange().getEndOffset();
|
||||
//processor.myFirstErrorOffset = keyEndOffset;
|
||||
if (terminatedOnCurrentLine(editor, propertyKey) && !isFollowedByTerminal(propertyKey, COLON)) {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class JsonElementGenerator {
|
||||
* @param <T> type of the JSON value desired
|
||||
* @return element created from given text
|
||||
*
|
||||
* @see {@link com.intellij.json.psi.JsonElementGenerator#createStringLiteral(String)}
|
||||
* @see #createStringLiteral(String)
|
||||
*/
|
||||
@NotNull
|
||||
public <T extends JsonValue> T createValue(@NotNull String content) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.json.JsonParserDefinition;
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -16,9 +17,18 @@ public class JsonPsiImplUtils {
|
||||
return StringUtil.stripQuotesAroundValue(property.getNameElement().getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually only JSON string literal should be accepted as valid name of property according to standard,
|
||||
* but for compatibility with JavaScript integration any JSON literals as well as identifiers (unquoted words)
|
||||
* are possible and highlighted as error later.
|
||||
*
|
||||
* @see com.intellij.json.codeinsight.JsonStandardComplianceAnnotator
|
||||
*/
|
||||
@NotNull
|
||||
public static JsonStringLiteral getNameElement(@NotNull JsonProperty property) {
|
||||
return (JsonStringLiteral)property.getFirstChild();
|
||||
public static JsonValue getNameElement(@NotNull JsonProperty property) {
|
||||
final PsiElement firstChild = property.getFirstChild();
|
||||
assert firstChild instanceof JsonLiteral || firstChild instanceof JsonReferenceExpression;
|
||||
return (JsonValue)firstChild;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -69,7 +69,7 @@ private object_element ::= property (','|&'}') {
|
||||
pin = 1
|
||||
}
|
||||
|
||||
property ::= string_literal (':' value) {
|
||||
property ::= property_name (':' value) {
|
||||
methods=[
|
||||
getName
|
||||
getNameElement
|
||||
@@ -81,6 +81,8 @@ property ::= string_literal (':' value) {
|
||||
pin(".*")=1
|
||||
}
|
||||
|
||||
private property_name ::= literal | reference_expression
|
||||
|
||||
array ::= '[' array_element* ']' { pin=1 }
|
||||
|
||||
private array_element ::= value (','|&']') {
|
||||
|
||||
@@ -58,6 +58,10 @@ public class JsonParsingTest extends ParsingTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNonStandardPropertyKeyValues() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// Moved from JavaScript
|
||||
|
||||
public void testSimple1() {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
42: null,
|
||||
null: null,
|
||||
false: null,
|
||||
true: null,
|
||||
identifier: null
|
||||
}
|
||||
49
json/tests/testData/psi/NonStandardPropertyKeyValues.txt
Normal file
49
json/tests/testData/psi/NonStandardPropertyKeyValues.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
JsonFile: NonStandardPropertyKeyValues.json
|
||||
JsonObject
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonNumberLiteral
|
||||
PsiElement(NUMBER)('42')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonBooleanLiteral
|
||||
PsiElement(false)('false')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonBooleanLiteral
|
||||
PsiElement(true)('true')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(INDENTIFIER)('identifier')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNullLiteral
|
||||
PsiElement(null)('null')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(})('}')
|
||||
Reference in New Issue
Block a user