<module fileurl="file://$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" filepath="$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" filepath="$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" filepath="$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" group="jps" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/json/json.iml" filepath="$PROJECT_DIR$/plugins/json/json.iml" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" filepath="$PROJECT_DIR$/java/jsp-spi/jsp-spi.iml" group="java" />
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.PsiBuilder.Marker;
+import com.intellij.lang.PsiParser;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+
+import static com.jetbrains.json.JsonParserTypes.*;
+import static com.jetbrains.json.JsonParserUtil.*;
+
+@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"})
+public class JsonParser implements PsiParser {
+
+ public static final Logger LOG_ = Logger.getInstance("com.jetbrains.json.JsonParser");
+
+ public ASTNode parse(IElementType root_, PsiBuilder builder_) {
+ int level_ = 0;
+ boolean result_;
+ builder_ = adapt_builder_(root_, builder_, this, EXTENDS_SETS_);
+ if (root_ == ARRAY) {
+ result_ = array(builder_, level_ + 1);
+ }
+ else if (root_ == BOOLEAN_LITERAL) {
+ result_ = boolean_literal(builder_, level_ + 1);
+ }
+ else if (root_ == LITERAL) {
+ result_ = literal(builder_, level_ + 1);
+ }
+ else if (root_ == NULL_LITERAL) {
+ result_ = null_literal(builder_, level_ + 1);
+ }
+ else if (root_ == NUMBER_LITERAL) {
+ result_ = number_literal(builder_, level_ + 1);
+ }
+ else if (root_ == OBJECT) {
+ result_ = object(builder_, level_ + 1);
+ }
+ else if (root_ == PROPERTY) {
+ result_ = property(builder_, level_ + 1);
+ }
+ else if (root_ == PROPERTY_NAME) {
+ result_ = property_name(builder_, level_ + 1);
+ }
+ else if (root_ == PROPERTY_VALUE) {
+ result_ = property_value(builder_, level_ + 1);
+ }
+ else if (root_ == STRING_LITERAL) {
+ result_ = string_literal(builder_, level_ + 1);
+ }
+ else {
+ Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
+ result_ = parse_root_(root_, builder_, level_);
+ exit_section_(builder_, level_, marker_, root_, result_, true, TOKEN_ADVANCER);
+ }
+ return builder_.getTreeBuilt();
+ }
+
+ protected boolean parse_root_(final IElementType root_, final PsiBuilder builder_, final int level_) {
+ return json(builder_, level_ + 1);
+ }
+
+ public static final TokenSet[] EXTENDS_SETS_ = new TokenSet[] {
+ create_token_set_(BOOLEAN_LITERAL, LITERAL, NULL_LITERAL, NUMBER_LITERAL,
+ STRING_LITERAL),
+ create_token_set_(ARRAY, BOOLEAN_LITERAL, LITERAL, NULL_LITERAL,
+ NUMBER_LITERAL, OBJECT, PROPERTY_VALUE, STRING_LITERAL),
+ };
+
+ /* ********************************************************** */
+ // L_BRAKET (property_value (COMMA property_value)*)? R_BRAKET
+ public static boolean array(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "array")) return false;
+ if (!nextTokenIs(builder_, L_BRAKET)) return false;
+ boolean result_ = false;
+ boolean pinned_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
+ result_ = consumeToken(builder_, L_BRAKET);
+ pinned_ = result_; // pin = 1
+ result_ = result_ && report_error_(builder_, array_1(builder_, level_ + 1));
+ result_ = pinned_ && consumeToken(builder_, R_BRAKET) && result_;
+ exit_section_(builder_, level_, marker_, ARRAY, result_, pinned_, null);
+ return result_ || pinned_;
+ }
+
+ // (property_value (COMMA property_value)*)?
+ private static boolean array_1(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "array_1")) return false;
+ array_1_0(builder_, level_ + 1);
+ return true;
+ }
+
+ // property_value (COMMA property_value)*
+ private static boolean array_1_0(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "array_1_0")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = property_value(builder_, level_ + 1);
+ result_ = result_ && array_1_0_1(builder_, level_ + 1);
+ exit_section_(builder_, marker_, null, result_);
+ return result_;
+ }
+
+ // (COMMA property_value)*
+ private static boolean array_1_0_1(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "array_1_0_1")) return false;
+ int offset_ = builder_.getCurrentOffset();
+ while (true) {
+ if (!array_1_0_1_0(builder_, level_ + 1)) break;
+ int next_offset_ = builder_.getCurrentOffset();
+ if (offset_ == next_offset_) {
+ empty_element_parsed_guard_(builder_, offset_, "array_1_0_1");
+ break;
+ }
+ offset_ = next_offset_;
+ }
+ return true;
+ }
+
+ // COMMA property_value
+ private static boolean array_1_0_1_0(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "array_1_0_1_0")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = consumeToken(builder_, COMMA);
+ result_ = result_ && property_value(builder_, level_ + 1);
+ exit_section_(builder_, marker_, null, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // TRUE | FALSE
+ public static boolean boolean_literal(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "boolean_literal")) return false;
+ if (!nextTokenIs(builder_, FALSE) && !nextTokenIs(builder_, TRUE)
+ && replaceVariants(builder_, 2, "<boolean literal>")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _COLLAPSE_, "<boolean literal>");
+ result_ = consumeToken(builder_, TRUE);
+ if (!result_) result_ = consumeToken(builder_, FALSE);
+ exit_section_(builder_, level_, marker_, BOOLEAN_LITERAL, result_, false, null);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // object | array
+ static boolean json(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "json")) return false;
+ if (!nextTokenIs(builder_, L_BRAKET) && !nextTokenIs(builder_, L_CURLY)) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = object(builder_, level_ + 1);
+ if (!result_) result_ = array(builder_, level_ + 1);
+ exit_section_(builder_, marker_, null, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // string_literal | number_literal | boolean_literal | null_literal
+ public static boolean literal(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "literal")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _COLLAPSE_, "<literal>");
+ result_ = string_literal(builder_, level_ + 1);
+ if (!result_) result_ = number_literal(builder_, level_ + 1);
+ if (!result_) result_ = boolean_literal(builder_, level_ + 1);
+ if (!result_) result_ = null_literal(builder_, level_ + 1);
+ exit_section_(builder_, level_, marker_, LITERAL, result_, false, null);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // NULL
+ public static boolean null_literal(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "null_literal")) return false;
+ if (!nextTokenIs(builder_, NULL)) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = consumeToken(builder_, NULL);
+ exit_section_(builder_, marker_, NULL_LITERAL, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // NUMBER
+ public static boolean number_literal(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "number_literal")) return false;
+ if (!nextTokenIs(builder_, NUMBER)) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = consumeToken(builder_, NUMBER);
+ exit_section_(builder_, marker_, NUMBER_LITERAL, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // L_CURLY (property (COMMA property)*)? R_CURLY
+ public static boolean object(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "object")) return false;
+ if (!nextTokenIs(builder_, L_CURLY)) return false;
+ boolean result_ = false;
+ boolean pinned_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
+ result_ = consumeToken(builder_, L_CURLY);
+ pinned_ = result_; // pin = 1
+ result_ = result_ && report_error_(builder_, object_1(builder_, level_ + 1));
+ result_ = pinned_ && consumeToken(builder_, R_CURLY) && result_;
+ exit_section_(builder_, level_, marker_, OBJECT, result_, pinned_, null);
+ return result_ || pinned_;
+ }
+
+ // (property (COMMA property)*)?
+ private static boolean object_1(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "object_1")) return false;
+ object_1_0(builder_, level_ + 1);
+ return true;
+ }
+
+ // property (COMMA property)*
+ private static boolean object_1_0(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "object_1_0")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = property(builder_, level_ + 1);
+ result_ = result_ && object_1_0_1(builder_, level_ + 1);
+ exit_section_(builder_, marker_, null, result_);
+ return result_;
+ }
+
+ // (COMMA property)*
+ private static boolean object_1_0_1(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "object_1_0_1")) return false;
+ int offset_ = builder_.getCurrentOffset();
+ while (true) {
+ if (!object_1_0_1_0(builder_, level_ + 1)) break;
+ int next_offset_ = builder_.getCurrentOffset();
+ if (offset_ == next_offset_) {
+ empty_element_parsed_guard_(builder_, offset_, "object_1_0_1");
+ break;
+ }
+ offset_ = next_offset_;
+ }
+ return true;
+ }
+
+ // COMMA property
+ private static boolean object_1_0_1_0(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "object_1_0_1_0")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = consumeToken(builder_, COMMA);
+ result_ = result_ && property(builder_, level_ + 1);
+ exit_section_(builder_, marker_, null, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // property_name COLON property_value
+ public static boolean property(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "property")) return false;
+ if (!nextTokenIs(builder_, STRING)) return false;
+ boolean result_ = false;
+ boolean pinned_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
+ result_ = property_name(builder_, level_ + 1);
+ pinned_ = result_; // pin = 1
+ result_ = result_ && report_error_(builder_, consumeToken(builder_, COLON));
+ result_ = pinned_ && property_value(builder_, level_ + 1) && result_;
+ exit_section_(builder_, level_, marker_, PROPERTY, result_, pinned_, null);
+ return result_ || pinned_;
+ }
+
+ /* ********************************************************** */
+ // string_literal
+ public static boolean property_name(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "property_name")) return false;
+ if (!nextTokenIs(builder_, STRING)) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = string_literal(builder_, level_ + 1);
+ exit_section_(builder_, marker_, PROPERTY_NAME, result_);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // object | array | literal
+ public static boolean property_value(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "property_value")) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_, level_, _COLLAPSE_, "<property value>");
+ result_ = object(builder_, level_ + 1);
+ if (!result_) result_ = array(builder_, level_ + 1);
+ if (!result_) result_ = literal(builder_, level_ + 1);
+ exit_section_(builder_, level_, marker_, PROPERTY_VALUE, result_, false, null);
+ return result_;
+ }
+
+ /* ********************************************************** */
+ // STRING
+ public static boolean string_literal(PsiBuilder builder_, int level_) {
+ if (!recursion_guard_(builder_, level_, "string_literal")) return false;
+ if (!nextTokenIs(builder_, STRING)) return false;
+ boolean result_ = false;
+ Marker marker_ = enter_section_(builder_);
+ result_ = consumeToken(builder_, STRING);
+ exit_section_(builder_, marker_, STRING_LITERAL, result_);
+ return result_;
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json;
+
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.PsiElement;
+import com.intellij.lang.ASTNode;
+import com.jetbrains.json.psi.impl.*;
+
+public interface JsonParserTypes {
+
+ IElementType ARRAY = new JsonElementType("ARRAY");
+ IElementType BOOLEAN_LITERAL = new JsonElementType("BOOLEAN_LITERAL");
+ IElementType LITERAL = new JsonElementType("LITERAL");
+ IElementType NULL_LITERAL = new JsonElementType("NULL_LITERAL");
+ IElementType NUMBER_LITERAL = new JsonElementType("NUMBER_LITERAL");
+ IElementType OBJECT = new JsonElementType("OBJECT");
+ IElementType PROPERTY = new JsonElementType("PROPERTY");
+ IElementType PROPERTY_NAME = new JsonElementType("PROPERTY_NAME");
+ IElementType PROPERTY_VALUE = new JsonElementType("PROPERTY_VALUE");
+ IElementType STRING_LITERAL = new JsonElementType("STRING_LITERAL");
+
+ IElementType COLON = new JsonTokenType(":");
+ IElementType COMMA = new JsonTokenType(",");
+ IElementType FALSE = new JsonTokenType("false");
+ IElementType L_BRAKET = new JsonTokenType("[");
+ IElementType L_CURLY = new JsonTokenType("{");
+ IElementType NULL = new JsonTokenType("null");
+ IElementType NUMBER = new JsonTokenType("NUMBER");
+ IElementType R_BRAKET = new JsonTokenType("]");
+ IElementType R_CURLY = new JsonTokenType("}");
+ IElementType STRING = new JsonTokenType("STRING");
+ IElementType TRUE = new JsonTokenType("true");
+
+ class Factory {
+ public static PsiElement createElement(ASTNode node) {
+ IElementType type = node.getElementType();
+ if (type == ARRAY) {
+ return new JsonArrayImpl(node);
+ }
+ else if (type == BOOLEAN_LITERAL) {
+ return new JsonBooleanLiteralImpl(node);
+ }
+ else if (type == LITERAL) {
+ return new JsonLiteralImpl(node);
+ }
+ else if (type == NULL_LITERAL) {
+ return new JsonNullLiteralImpl(node);
+ }
+ else if (type == NUMBER_LITERAL) {
+ return new JsonNumberLiteralImpl(node);
+ }
+ else if (type == OBJECT) {
+ return new JsonObjectImpl(node);
+ }
+ else if (type == PROPERTY) {
+ return new JsonPropertyImpl(node);
+ }
+ else if (type == PROPERTY_NAME) {
+ return new JsonPropertyNameImpl(node);
+ }
+ else if (type == PROPERTY_VALUE) {
+ return new JsonPropertyValueImpl(node);
+ }
+ else if (type == STRING_LITERAL) {
+ return new JsonStringLiteralImpl(node);
+ }
+ throw new AssertionError("Unknown element type: " + type);
+ }
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.lang.parser.GeneratedParserUtilBase;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonParserUtil extends GeneratedParserUtilBase {
+}
--- /dev/null
+/* The following code was generated by JFlex 1.4.3 on 10/28/13 8:52 PM */
+
+package com.jetbrains.json;
+import com.intellij.lexer.*;
+import com.intellij.psi.tree.IElementType;
+import static com.jetbrains.json.JsonParserTypes.*;
+
+
+/**
+ * This class is a scanner generated by
+ * <a href="http://www.jflex.de/">JFlex</a> 1.4.3
+ * on 10/28/13 8:52 PM from the specification file
+ * <tt>json.flex</tt>
+ */
+public class _JsonLexer implements FlexLexer {
+ /** initial size of the lookahead buffer */
+ private static final int ZZ_BUFFERSIZE = 16384;
+
+ /** lexical states */
+ public static final int YYINITIAL = 0;
+
+ /**
+ * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+ * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+ * at the beginning of a line
+ * l is of the form l = 2*k, k a non negative integer
+ */
+ private static final int ZZ_LEXSTATE[] = {
+ 0, 0
+ };
+
+ /**
+ * Translates characters to character classes
+ */
+ private static final String ZZ_CMAP_PACKED =
+ "\11\0\2\1\2\0\1\1\22\0\1\1\1\0\1\10\10\0\1\23"+
+ "\1\6\1\16\1\21\1\12\12\20\1\7\6\0\4\14\1\22\1\14"+
+ "\24\0\1\4\1\11\1\5\3\0\1\30\1\15\2\14\1\26\1\27"+
+ "\5\0\1\31\1\0\1\33\3\0\1\25\1\32\1\24\1\13\5\0"+
+ "\1\2\1\0\1\3\u05e2\0\12\17\206\0\12\17\306\0\12\17\u019c\0"+
+ "\12\17\166\0\12\17\166\0\12\17\166\0\12\17\166\0\12\17\166\0"+
+ "\12\17\166\0\12\17\166\0\12\17\166\0\12\17\340\0\12\17\166\0"+
+ "\12\17\106\0\12\17\u0116\0\12\17\106\0\12\17\u0746\0\12\17\46\0"+
+ "\12\17\u012c\0\12\17\200\0\12\17\246\0\12\17\6\0\12\17\266\0"+
+ "\12\17\126\0\12\17\206\0\12\17\6\0\12\17\u89c6\0\12\17\u02a6\0"+
+ "\12\17\46\0\12\17\306\0\12\17\166\0\12\17\u0196\0\12\17\u5316\0"+
+ "\12\17\346\0";
+
+ /**
+ * Translates characters to character classes
+ */
+ private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
+
+ /**
+ * Translates DFA states to action switch labels.
+ */
+ private static final int [] ZZ_ACTION = zzUnpackAction();
+
+ private static final String ZZ_ACTION_PACKED_0 =
+ "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7"+
+ "\1\10\2\1\1\11\3\1\1\0\1\12\6\0\1\11"+
+ "\5\0\1\13\1\0\1\14\2\0\1\11\1\15\1\0";
+
+ private static int [] zzUnpackAction() {
+ int [] result = new int[37];
+ int offset = 0;
+ offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAction(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /**
+ * Translates a state to a row index in the transition table
+ */
+ private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+ private static final String ZZ_ROWMAP_PACKED_0 =
+ "\0\0\0\34\0\70\0\34\0\34\0\34\0\34\0\34"+
+ "\0\34\0\124\0\160\0\214\0\250\0\304\0\340\0\124"+
+ "\0\34\0\374\0\u0118\0\u0134\0\u0150\0\u016c\0\u0188\0\u01a4"+
+ "\0\u01c0\0\u01dc\0\u01f8\0\u0214\0\u0230\0\34\0\u024c\0\34"+
+ "\0\u0268\0\u0284\0\u0284\0\34\0\u02a0";
+
+ private static int [] zzUnpackRowMap() {
+ int [] result = new int[37];
+ int offset = 0;
+ offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int high = packed.charAt(i++) << 16;
+ result[j++] = high | packed.charAt(i++);
+ }
+ return j;
+ }
+
+ /**
+ * The transition table of the DFA
+ */
+ private static final int [] ZZ_TRANS = zzUnpackTrans();
+
+ private static final String ZZ_TRANS_PACKED_0 =
+ "\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11"+
+ "\1\12\5\2\1\13\2\14\3\2\1\15\2\2\1\16"+
+ "\3\2\1\17\35\0\1\3\32\0\10\20\1\21\1\22"+
+ "\22\20\17\0\2\14\32\0\2\14\1\23\37\0\1\24"+
+ "\36\0\1\25\16\0\1\26\30\0\3\20\1\27\1\0"+
+ "\1\20\6\0\2\20\1\0\1\20\3\0\1\20\17\0"+
+ "\2\30\26\0\1\31\51\0\1\32\33\0\1\33\16\0"+
+ "\2\34\2\0\1\34\1\0\1\34\3\0\3\34\22\0"+
+ "\2\30\1\0\1\35\3\0\1\35\33\0\1\36\37\0"+
+ "\1\37\32\0\1\40\16\0\2\41\2\0\1\41\1\0"+
+ "\1\41\3\0\3\41\21\0\1\42\2\43\2\0\1\42"+
+ "\36\0\1\44\21\0\2\45\2\0\1\45\1\0\1\45"+
+ "\3\0\3\45\22\0\2\43\27\0\2\20\2\0\1\20"+
+ "\1\0\1\20\3\0\3\20\3\0";
+
+ private static int [] zzUnpackTrans() {
+ int [] result = new int[700];
+ int offset = 0;
+ offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackTrans(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ value--;
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /* error codes */
+ private static final int ZZ_UNKNOWN_ERROR = 0;
+ private static final int ZZ_NO_MATCH = 1;
+ private static final int ZZ_PUSHBACK_2BIG = 2;
+ private static final char[] EMPTY_BUFFER = new char[0];
+ private static final int YYEOF = -1;
+ private static java.io.Reader zzReader = null; // Fake
+
+ /* error messages for the codes above */
+ private static final String ZZ_ERROR_MSG[] = {
+ "Unkown internal scanner error",
+ "Error: could not match input",
+ "Error: pushback value was too large"
+ };
+
+ /**
+ * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+ */
+ private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+ private static final String ZZ_ATTRIBUTE_PACKED_0 =
+ "\1\0\1\11\1\1\6\11\6\1\1\0\1\11\6\0"+
+ "\1\1\5\0\1\11\1\0\1\11\2\0\1\1\1\11"+
+ "\1\0";
+
+ private static int [] zzUnpackAttribute() {
+ int [] result = new int[37];
+ int offset = 0;
+ offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAttribute(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+ /** the current state of the DFA */
+ private int zzState;
+
+ /** the current lexical state */
+ private int zzLexicalState = YYINITIAL;
+
+ /** this buffer contains the current text to be matched and is
+ the source of the yytext() string */
+ private CharSequence zzBuffer = "";
+
+ /** this buffer may contains the current text array to be matched when it is cheap to acquire it */
+ private char[] zzBufferArray;
+
+ /** the textposition at the last accepting state */
+ private int zzMarkedPos;
+
+ /** the textposition at the last state to be included in yytext */
+ private int zzPushbackPos;
+
+ /** the current text position in the buffer */
+ private int zzCurrentPos;
+
+ /** startRead marks the beginning of the yytext() string in the buffer */
+ private int zzStartRead;
+
+ /** endRead marks the last character in the buffer, that has been read
+ from input */
+ private int zzEndRead;
+
+ /**
+ * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+ */
+ private boolean zzAtBOL = true;
+
+ /** zzAtEOF == true <=> the scanner is at the EOF */
+ private boolean zzAtEOF;
+
+ /** denotes if the user-EOF-code has already been executed */
+ private boolean zzEOFDone;
+
+ /* user code: */
+ public _JsonLexer() {
+ this((java.io.Reader)null);
+ }
+
+
+ public _JsonLexer(java.io.Reader in) {
+ this.zzReader = in;
+ }
+
+ /**
+ * Creates a new scanner.
+ * There is also java.io.Reader version of this constructor.
+ *
+ * @param in the java.io.Inputstream to read input from.
+ */
+ public _JsonLexer(java.io.InputStream in) {
+ this(new java.io.InputStreamReader(in));
+ }
+
+ /**
+ * Unpacks the compressed character translation table.
+ *
+ * @param packed the packed character translation table
+ * @return the unpacked character translation table
+ */
+ private static char [] zzUnpackCMap(String packed) {
+ char [] map = new char[0x10000];
+ int i = 0; /* index in packed string */
+ int j = 0; /* index in unpacked array */
+ while (i < 224) {
+ int count = packed.charAt(i++);
+ char value = packed.charAt(i++);
+ do map[j++] = value; while (--count > 0);
+ }
+ return map;
+ }
+
+ public final int getTokenStart(){
+ return zzStartRead;
+ }
+
+ public final int getTokenEnd(){
+ return getTokenStart() + yylength();
+ }
+
+ public void reset(CharSequence buffer, int start, int end,int initialState){
+ zzBuffer = buffer;
+ zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer);
+ zzCurrentPos = zzMarkedPos = zzStartRead = start;
+ zzPushbackPos = 0;
+ zzAtEOF = false;
+ zzAtBOL = true;
+ zzEndRead = end;
+ yybegin(initialState);
+ }
+
+ /**
+ * Refills the input buffer.
+ *
+ * @return <code>false</code>, iff there was new input.
+ *
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ private boolean zzRefill() throws java.io.IOException {
+ return true;
+ }
+
+
+ /**
+ * Returns the current lexical state.
+ */
+ public final int yystate() {
+ return zzLexicalState;
+ }
+
+
+ /**
+ * Enters a new lexical state
+ *
+ * @param newState the new lexical state
+ */
+ public final void yybegin(int newState) {
+ zzLexicalState = newState;
+ }
+
+
+ /**
+ * Returns the text matched by the current regular expression.
+ */
+ public final CharSequence yytext() {
+ return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
+ }
+
+
+ /**
+ * Returns the character at position <tt>pos</tt> from the
+ * matched text.
+ *
+ * It is equivalent to yytext().charAt(pos), but faster
+ *
+ * @param pos the position of the character to fetch.
+ * A value from 0 to yylength()-1.
+ *
+ * @return the character at position pos
+ */
+ public final char yycharat(int pos) {
+ return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos);
+ }
+
+
+ /**
+ * Returns the length of the matched text region.
+ */
+ public final int yylength() {
+ return zzMarkedPos-zzStartRead;
+ }
+
+
+ /**
+ * Reports an error that occured while scanning.
+ *
+ * In a wellformed scanner (no or only correct usage of
+ * yypushback(int) and a match-all fallback rule) this method
+ * will only be called with things that "Can't Possibly Happen".
+ * If this method is called, something is seriously wrong
+ * (e.g. a JFlex bug producing a faulty scanner etc.).
+ *
+ * Usual syntax/scanner level error handling should be done
+ * in error fallback rules.
+ *
+ * @param errorCode the code of the errormessage to display
+ */
+ private void zzScanError(int errorCode) {
+ String message;
+ try {
+ message = ZZ_ERROR_MSG[errorCode];
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+ }
+
+ throw new Error(message);
+ }
+
+
+ /**
+ * Pushes the specified amount of characters back into the input stream.
+ *
+ * They will be read again by then next call of the scanning method
+ *
+ * @param number the number of characters to be read again.
+ * This number must not be greater than yylength()!
+ */
+ public void yypushback(int number) {
+ if ( number > yylength() )
+ zzScanError(ZZ_PUSHBACK_2BIG);
+
+ zzMarkedPos -= number;
+ }
+
+
+ /**
+ * Contains user EOF-code, which will be executed exactly once,
+ * when the end of file is reached
+ */
+ private void zzDoEOF() {
+ if (!zzEOFDone) {
+ zzEOFDone = true;
+
+ }
+ }
+
+
+ /**
+ * Resumes scanning until the next regular expression is matched,
+ * the end of input is encountered or an I/O-Error occurs.
+ *
+ * @return the next token
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ public IElementType advance() throws java.io.IOException {
+ int zzInput;
+ int zzAction;
+
+ // cached fields:
+ int zzCurrentPosL;
+ int zzMarkedPosL;
+ int zzEndReadL = zzEndRead;
+ CharSequence zzBufferL = zzBuffer;
+ char[] zzBufferArrayL = zzBufferArray;
+ char [] zzCMapL = ZZ_CMAP;
+
+ int [] zzTransL = ZZ_TRANS;
+ int [] zzRowMapL = ZZ_ROWMAP;
+ int [] zzAttrL = ZZ_ATTRIBUTE;
+
+ while (true) {
+ zzMarkedPosL = zzMarkedPos;
+
+ zzAction = -1;
+
+ zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+
+ zzState = ZZ_LEXSTATE[zzLexicalState];
+
+
+ zzForAction: {
+ while (true) {
+
+ if (zzCurrentPosL < zzEndReadL)
+ zzInput = zzBufferL.charAt(zzCurrentPosL++);
+ else if (zzAtEOF) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ // store back cached positions
+ zzCurrentPos = zzCurrentPosL;
+ zzMarkedPos = zzMarkedPosL;
+ boolean eof = zzRefill();
+ // get translated positions and possibly new buffer
+ zzCurrentPosL = zzCurrentPos;
+ zzMarkedPosL = zzMarkedPos;
+ zzBufferL = zzBuffer;
+ zzEndReadL = zzEndRead;
+ if (eof) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ zzInput = zzBufferL.charAt(zzCurrentPosL++);
+ }
+ }
+ int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
+ if (zzNext == -1) break zzForAction;
+ zzState = zzNext;
+
+ int zzAttributes = zzAttrL[zzState];
+ if ( (zzAttributes & 1) == 1 ) {
+ zzAction = zzState;
+ zzMarkedPosL = zzCurrentPosL;
+ if ( (zzAttributes & 8) == 8 ) break zzForAction;
+ }
+
+ }
+ }
+
+ // store back cached position
+ zzMarkedPos = zzMarkedPosL;
+
+ switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+ case 4:
+ { return R_CURLY;
+ }
+ case 14: break;
+ case 3:
+ { return L_CURLY;
+ }
+ case 15: break;
+ case 12:
+ { return NULL;
+ }
+ case 16: break;
+ case 5:
+ { return L_BRAKET;
+ }
+ case 17: break;
+ case 2:
+ { return com.intellij.psi.TokenType.WHITE_SPACE;
+ }
+ case 18: break;
+ case 7:
+ { return COMMA;
+ }
+ case 19: break;
+ case 1:
+ { return com.intellij.psi.TokenType.BAD_CHARACTER;
+ }
+ case 20: break;
+ case 6:
+ { return R_BRAKET;
+ }
+ case 21: break;
+ case 11:
+ { return TRUE;
+ }
+ case 22: break;
+ case 10:
+ { return STRING;
+ }
+ case 23: break;
+ case 8:
+ { return COLON;
+ }
+ case 24: break;
+ case 9:
+ { return NUMBER;
+ }
+ case 25: break;
+ case 13:
+ { return FALSE;
+ }
+ case 26: break;
+ default:
+ if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+ zzAtEOF = true;
+ zzDoEOF();
+ return null;
+ }
+ else {
+ zzScanError(ZZ_NO_MATCH);
+ }
+ }
+ }
+ }
+
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonArray extends JsonPropertyValue {
+
+ @NotNull
+ List<JsonPropertyValue> getPropertyValueList();
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonBooleanLiteral extends JsonLiteral {
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonLiteral extends JsonPropertyValue {
+
+ boolean isQuotedString();
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonNullLiteral extends JsonLiteral {
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonNumberLiteral extends JsonLiteral {
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonObject extends JsonPropertyValue {
+
+ @NotNull
+ List<JsonProperty> getPropertyList();
+
+ @Nullable
+ JsonProperty findProperty(String name);
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.json.psi.impl.JsonPropertyImpl;
+
+public interface JsonProperty extends PsiElement {
+
+ @NotNull
+ JsonPropertyName getPropertyName();
+
+ @Nullable
+ JsonPropertyValue getPropertyValue();
+
+ @NotNull
+ String getName();
+
+ @Nullable
+ JsonPropertyValue getValue();
+
+ void delete();
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonPropertyName extends PsiElement {
+
+ @NotNull
+ JsonStringLiteral getStringLiteral();
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonPropertyValue extends PsiElement {
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface JsonStringLiteral extends JsonLiteral {
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi;
+
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.PsiElement;
+
+public class JsonVisitor extends PsiElementVisitor {
+
+ public void visitArray(@NotNull JsonArray o) {
+ visitPropertyValue(o);
+ }
+
+ public void visitBooleanLiteral(@NotNull JsonBooleanLiteral o) {
+ visitLiteral(o);
+ }
+
+ public void visitLiteral(@NotNull JsonLiteral o) {
+ visitPropertyValue(o);
+ }
+
+ public void visitNullLiteral(@NotNull JsonNullLiteral o) {
+ visitLiteral(o);
+ }
+
+ public void visitNumberLiteral(@NotNull JsonNumberLiteral o) {
+ visitLiteral(o);
+ }
+
+ public void visitObject(@NotNull JsonObject o) {
+ visitPropertyValue(o);
+ }
+
+ public void visitProperty(@NotNull JsonProperty o) {
+ visitPsiElement(o);
+ }
+
+ public void visitPropertyName(@NotNull JsonPropertyName o) {
+ visitPsiElement(o);
+ }
+
+ public void visitPropertyValue(@NotNull JsonPropertyValue o) {
+ visitPsiElement(o);
+ }
+
+ public void visitStringLiteral(@NotNull JsonStringLiteral o) {
+ visitLiteral(o);
+ }
+
+ public void visitPsiElement(@NotNull PsiElement o) {
+ visitElement(o);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonArrayImpl extends JsonPropertyValueImpl implements JsonArray {
+
+ public JsonArrayImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitArray(this);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<JsonPropertyValue> getPropertyValueList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, JsonPropertyValue.class);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonBooleanLiteralImpl extends JsonLiteralImpl implements JsonBooleanLiteral {
+
+ public JsonBooleanLiteralImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitBooleanLiteral(this);
+ else super.accept(visitor);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonLiteralImpl extends JsonLiteralMixin implements JsonLiteral {
+
+ public JsonLiteralImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitLiteral(this);
+ else super.accept(visitor);
+ }
+
+ public boolean isQuotedString() {
+ return JsonPsiImplUtils.isQuotedString(this);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonNullLiteralImpl extends JsonLiteralImpl implements JsonNullLiteral {
+
+ public JsonNullLiteralImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitNullLiteral(this);
+ else super.accept(visitor);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonNumberLiteralImpl extends JsonLiteralImpl implements JsonNumberLiteral {
+
+ public JsonNumberLiteralImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitNumberLiteral(this);
+ else super.accept(visitor);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonObjectImpl extends JsonPropertyValueImpl implements JsonObject {
+
+ public JsonObjectImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitObject(this);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public List<JsonProperty> getPropertyList() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, JsonProperty.class);
+ }
+
+ @Nullable
+ public JsonProperty findProperty(String name) {
+ return JsonPsiImplUtils.findProperty(this, name);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.jetbrains.json.psi.*;
+
+public class JsonPropertyImpl extends ASTWrapperPsiElement implements JsonProperty {
+
+ public JsonPropertyImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitProperty(this);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public JsonPropertyName getPropertyName() {
+ return findNotNullChildByClass(JsonPropertyName.class);
+ }
+
+ @Override
+ @Nullable
+ public JsonPropertyValue getPropertyValue() {
+ return findChildByClass(JsonPropertyValue.class);
+ }
+
+ @NotNull
+ public String getName() {
+ return JsonPsiImplUtils.getName(this);
+ }
+
+ @Nullable
+ public JsonPropertyValue getValue() {
+ return JsonPsiImplUtils.getValue(this);
+ }
+
+ public void delete() {
+ JsonPsiImplUtils.delete(this);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.jetbrains.json.psi.*;
+
+public class JsonPropertyNameImpl extends ASTWrapperPsiElement implements JsonPropertyName {
+
+ public JsonPropertyNameImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitPropertyName(this);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @NotNull
+ public JsonStringLiteral getStringLiteral() {
+ return findNotNullChildByClass(JsonStringLiteral.class);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.jetbrains.json.psi.*;
+
+public class JsonPropertyValueImpl extends ASTWrapperPsiElement implements JsonPropertyValue {
+
+ public JsonPropertyValueImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitPropertyValue(this);
+ else super.accept(visitor);
+ }
+
+}
--- /dev/null
+// This is a generated file. Not intended for manual editing.
+package com.jetbrains.json.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static com.jetbrains.json.JsonParserTypes.*;
+import com.jetbrains.json.psi.*;
+
+public class JsonStringLiteralImpl extends JsonLiteralImpl implements JsonStringLiteral {
+
+ public JsonStringLiteralImpl(ASTNode node) {
+ super(node);
+ }
+
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof JsonVisitor) ((JsonVisitor)visitor).visitStringLiteral(this);
+ else super.accept(visitor);
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="core-api" />
+ <orderEntry type="module" module-name="platform-api" />
+ <orderEntry type="module" module-name="lang-impl" />
+ </component>
+</module>
+
--- /dev/null
+<idea-plugin version="2">
+ <id>com.intellij.json</id>
+ <name>JSON Support</name>
+ <version>1.0</version>
+ <vendor>JetBrains</vendor>
+
+ <depends>com.intellij.modules.xml</depends>
+
+ <description><![CDATA[
+ Provides highlighting and formatting for JSON files.
+ ]]></description>
+
+ <application-components>
+ <!-- Add your application components here -->
+ </application-components>
+
+ <project-components>
+ <!-- Add your project components here -->
+ </project-components>
+
+ <actions>
+ <!-- Add your actions here -->
+ </actions>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <fileTypeFactory implementation="com.jetbrains.json.JsonFileTypeFactory"/>
+ <lang.parserDefinition language="JSON" implementationClass="com.jetbrains.json.JsonParserDefinition"/>
+ <lang.syntaxHighlighterFactory key="JSON" implementationClass="com.jetbrains.json.JsonSyntaxHighlighterFactory"/>
+
+ <!-- Code style and formatting -->
+ <codeStyleSettingsProvider implementation="com.jetbrains.json.formatter.JsonCodeStyleSettingsProvider"/>
+ <langCodeStyleSettingsProvider implementation="com.jetbrains.json.formatter.JsonLanguageCodeStyleSettingsProvider"/>
+ <lang.formatter language="JSON" implementationClass="com.jetbrains.json.formatter.JsonFormattingBuilderModel"/>
+ </extensions>
+</idea-plugin>
\ No newline at end of file
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class JsonElementType extends IElementType {
+ public JsonElementType(@NotNull @NonNls String debugName) {
+ super(debugName, JsonLanguage.INSTANCE);
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.extapi.psi.PsiFileBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.psi.FileViewProvider;
+import org.jetbrains.annotations.NotNull;
+
+public class JsonFile extends PsiFileBase {
+
+ public JsonFile(FileViewProvider fileViewProvider) {
+ super(fileViewProvider, JsonLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public FileType getFileType() {
+ return JsonFileType.INSTANCE;
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.Icon;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonFileType extends LanguageFileType{
+ public static final JsonFileType INSTANCE = new JsonFileType();
+ public static final String DEFAULT_EXTENSION = "json";
+
+ public JsonFileType() {
+ super(JsonLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "JSON";
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "JSON language";
+ }
+
+ @NotNull
+ @Override
+ public String getDefaultExtension() {
+ return DEFAULT_EXTENSION;
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ // TODO: add JSON icon instead
+ return AllIcons.FileTypes.Json;
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.openapi.fileTypes.FileTypeConsumer;
+import com.intellij.openapi.fileTypes.FileTypeFactory;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonFileTypeFactory extends FileTypeFactory {
+ @Override
+ public void createFileTypes(@NotNull FileTypeConsumer consumer) {
+ consumer.consume(JsonFileType.INSTANCE, JsonFileType.DEFAULT_EXTENSION);
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.lang.Language;
+
+public class JsonLanguage extends Language {
+ public static final JsonLanguage INSTANCE = new JsonLanguage();
+
+ private JsonLanguage() {
+ super("JSON", "application/json");
+ }
+
+ @Override
+ public boolean isCaseSensitive() {
+ return true;
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lang.PsiParser;
+import com.intellij.lexer.FlexAdapter;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+
+public class JsonParserDefinition implements ParserDefinition {
+ public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE);
+ public static final TokenSet STRING_LITERALS = TokenSet.create(JsonParserTypes.STRING);
+ public static final IFileElementType FILE = new IFileElementType(JsonLanguage.INSTANCE);
+ public static final TokenSet CONTAINERS = TokenSet.create(JsonParserTypes.ARRAY, JsonParserTypes.OBJECT);
+
+
+ @NotNull
+ @Override
+ public Lexer createLexer(Project project) {
+ return new FlexAdapter(new _JsonLexer());
+ }
+
+ @Override
+ public PsiParser createParser(Project project) {
+ return new JsonParser();
+ }
+
+ @Override
+ public IFileElementType getFileNodeType() {
+ return FILE;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getWhitespaceTokens() {
+ return WHITE_SPACES;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ return TokenSet.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getStringLiteralElements() {
+ return STRING_LITERALS;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement createElement(ASTNode astNode) {
+ return JsonParserTypes.Factory.createElement(astNode);
+ }
+
+ @Override
+ public PsiFile createFile(FileViewProvider fileViewProvider) {
+ return new JsonFile(fileViewProvider);
+ }
+
+ @Override
+ public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode astNode, ASTNode astNode2) {
+ return SpaceRequirements.MAY;
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.lexer.FlexAdapter;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.jetbrains.json.JsonParserTypes.*;
+
+public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+ @NotNull
+ @Override
+ public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile) {
+ return new Highlighter();
+ }
+
+ private static class Highlighter extends SyntaxHighlighterBase {
+ private static final Map<IElementType, TextAttributesKey> ATTRIBUTES = new HashMap<IElementType, TextAttributesKey>();
+
+ static {
+ ATTRIBUTES.put(L_CURLY, DefaultLanguageHighlighterColors.BRACES);
+ ATTRIBUTES.put(R_CURLY, DefaultLanguageHighlighterColors.BRACES );
+ ATTRIBUTES.put(L_BRAKET, DefaultLanguageHighlighterColors.BRACKETS );
+ ATTRIBUTES.put(R_BRAKET, DefaultLanguageHighlighterColors.BRACES );
+ ATTRIBUTES.put(COMMA, DefaultLanguageHighlighterColors.COMMA);
+ ATTRIBUTES.put(COLON, DefaultLanguageHighlighterColors.SEMICOLON);
+ ATTRIBUTES.put(STRING, DefaultLanguageHighlighterColors.STRING);
+ ATTRIBUTES.put(NUMBER, DefaultLanguageHighlighterColors.NUMBER);
+ ATTRIBUTES.put(TRUE, DefaultLanguageHighlighterColors.KEYWORD);
+ ATTRIBUTES.put(FALSE, DefaultLanguageHighlighterColors.KEYWORD);
+ ATTRIBUTES.put(NULL, DefaultLanguageHighlighterColors.KEYWORD);
+ }
+
+ @NotNull
+ @Override
+ public Lexer getHighlightingLexer() {
+ return new FlexAdapter(new _JsonLexer());
+ }
+
+ @NotNull
+ @Override
+ public TextAttributesKey[] getTokenHighlights(IElementType type) {
+ return pack(ATTRIBUTES.get(type));
+ }
+ }
+}
--- /dev/null
+package com.jetbrains.json;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+public class JsonTokenType extends IElementType {
+ public JsonTokenType(@NotNull @NonNls String debugName) {
+ super(debugName, JsonLanguage.INSTANCE);
+ }
+}
--- /dev/null
+package com.jetbrains.json.formatter;
+
+import com.intellij.formatting.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.jetbrains.json.psi.JsonProperty;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+import static com.jetbrains.json.JsonParserDefinition.CONTAINERS;
+import static com.jetbrains.json.JsonParserTypes.*;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonBlock implements ASTBlock {
+ private static final TokenSet OPEN_BRACES = TokenSet.create(L_BRAKET, L_CURLY);
+ private static final TokenSet CLOSE_BRACES = TokenSet.create(R_BRAKET, R_CURLY);
+ private static final TokenSet BRACES = TokenSet.orSet(OPEN_BRACES, CLOSE_BRACES);
+ private JsonBlock myParent;
+
+
+ private ASTNode myNode;
+ private IElementType myNodeType;
+ private Alignment myAlignment;
+ private Indent myIndent;
+ private Wrap myWrap;
+ private CodeStyleSettings mySettings;
+ private SpacingBuilder mySpacingBuilder;
+ // lazy initialized on first call to #getSubBlocks()
+ private List<Block> mySubBlocks = null;
+
+ private Wrap myChildWrap = null;
+ private Alignment myChildAlignment = null;
+
+ public JsonBlock(JsonBlock parent, ASTNode node, CodeStyleSettings settings, Alignment alignment, Indent indent, Wrap wrap) {
+ myParent = parent;
+ myNode = node;
+ myNodeType = node.getElementType();
+ myAlignment = alignment;
+ myIndent = indent;
+ myWrap = wrap;
+ mySettings = settings;
+
+ mySpacingBuilder = JsonFormattingBuilderModel.createSpacingBuilder(settings);
+
+ if (CONTAINERS.contains(myNode.getElementType())) {
+ myChildWrap = Wrap.createWrap(WrapType.NORMAL, false);
+ myChildAlignment = Alignment.createAlignment();
+ }
+ }
+
+ @Override
+ public ASTNode getNode() {
+ return myNode;
+ }
+
+ @NotNull
+ @Override
+ public TextRange getTextRange() {
+ return myNode.getTextRange();
+ }
+
+ @NotNull
+ @Override
+ public List<Block> getSubBlocks() {
+ if (mySubBlocks == null) {
+ mySubBlocks = ContainerUtil.mapNotNull(myNode.getChildren(null), new Function<ASTNode, Block>() {
+ @Override
+ public Block fun(ASTNode node) {
+ if (node.getElementType() == TokenType.WHITE_SPACE || node.getTextLength() == 0) {
+ return null;
+ }
+ return createSubBlock(node);
+ }
+ });
+ }
+ return mySubBlocks;
+ }
+
+ private Block createSubBlock(ASTNode childNode) {
+ IElementType childNodeType = childNode.getElementType();
+
+ Indent indent = Indent.getNoneIndent();
+ Alignment alignment = null;
+ Wrap wrap = null;
+
+ if (CONTAINERS.contains(myNode.getElementType())) {
+ if (childNodeType != COMMA && !BRACES.contains(childNodeType)) {
+ wrap = Wrap.createWrap(WrapType.NORMAL, true);
+ alignment = myChildAlignment;
+ indent = Indent.getNormalIndent();
+ }
+ }
+ return new JsonBlock(this, childNode, mySettings, alignment, indent, wrap);
+ }
+
+ @Nullable
+ @Override
+ public Wrap getWrap() {
+ return myWrap;
+ }
+
+ @Nullable
+ @Override
+ public Indent getIndent() {
+ return myIndent;
+ }
+
+ @Nullable
+ @Override
+ public Alignment getAlignment() {
+ return myAlignment;
+ }
+
+ @Nullable
+ @Override
+ public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) {
+ return mySpacingBuilder.getSpacing(this, child1, child2);
+ }
+
+ @NotNull
+ @Override
+ public ChildAttributes getChildAttributes(int newChildIndex) {
+ Indent indent = Indent.getNormalIndent();
+ Alignment alignment = myChildAlignment;
+
+ if (CONTAINERS.contains(myNodeType) && newChildIndex != 0) {
+ IElementType prevChildType = ((JsonBlock)mySubBlocks.get(newChildIndex - 1)).myNode.getElementType();
+ if (OPEN_BRACES.contains(prevChildType)) {
+ indent = Indent.getNormalIndent();
+ }
+ }
+ return new ChildAttributes(indent, alignment);
+// return ChildAttributes.DELEGATE_TO_PREV_CHILD;
+ }
+
+ @Override
+ public boolean isIncomplete() {
+ IElementType nodeType = myNode.getElementType();
+ ASTNode lastChildNode = myNode.getLastChildNode();
+ PsiElement psiElement = myNode.getPsi();
+ if (nodeType == OBJECT) {
+ return lastChildNode != null && lastChildNode.getElementType() == R_CURLY;
+ }
+ else if (nodeType == ARRAY) {
+ return lastChildNode != null && lastChildNode.getElementType() == R_BRAKET;
+ }
+ else if (psiElement instanceof JsonProperty) {
+ return ((JsonProperty)psiElement).getValue() != null;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isLeaf() {
+ return myNode.getFirstChildNode() == null;
+ }
+}
--- /dev/null
+package com.jetbrains.json.formatter;
+
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
+import com.jetbrains.json.JsonLanguage;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonCodeStyleSettings extends CustomCodeStyleSettings {
+
+ // Standard option has awkward description "Code braces"
+ public boolean SPACE_WITHIN_BRACES = false;
+ public boolean SPACE_AFTER_COLON = true;
+ public boolean SPACE_BEFORE_COLON = false;
+
+
+ public JsonCodeStyleSettings(CodeStyleSettings container) {
+ super(JsonLanguage.INSTANCE.getID(), container);
+ }
+}
--- /dev/null
+package com.jetbrains.json.formatter;
+
+import com.intellij.application.options.CodeStyleAbstractConfigurable;
+import com.intellij.application.options.CodeStyleAbstractPanel;
+import com.intellij.application.options.TabbedLanguageCodeStylePanel;
+import com.intellij.lang.Language;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
+import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
+import com.jetbrains.json.JsonLanguage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonCodeStyleSettingsProvider extends CodeStyleSettingsProvider {
+ @NotNull
+ @Override
+ public Configurable createSettingsPage(CodeStyleSettings settings, CodeStyleSettings originalSettings) {
+ return new CodeStyleAbstractConfigurable(settings, originalSettings, "JSON") {
+ @Override
+ protected CodeStyleAbstractPanel createPanel(CodeStyleSettings settings) {
+ final Language language = JsonLanguage.INSTANCE;
+ final CodeStyleSettings currentSettings = getCurrentSettings();
+ return new TabbedLanguageCodeStylePanel(language, currentSettings, settings) {
+ @Override
+ protected void initTabs(CodeStyleSettings settings) {
+ addIndentOptionsTab(settings);
+ addSpacesTab(settings);
+ }
+ };
+ }
+
+ @Nullable
+ @Override
+ public String getHelpTopic() {
+ return null;
+ }
+ };
+ }
+
+ @Nullable
+ @Override
+ public String getConfigurableDisplayName() {
+ return JsonLanguage.INSTANCE.getDisplayName();
+ }
+
+ @Nullable
+ @Override
+ public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) {
+ return new JsonCodeStyleSettings(settings);
+ }
+}
--- /dev/null
+package com.jetbrains.json.formatter;
+
+import com.intellij.formatting.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.impl.DebugUtil;
+import com.jetbrains.json.JsonLanguage;
+import com.jetbrains.json.JsonParserTypes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static com.jetbrains.json.JsonParserTypes.*;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonFormattingBuilderModel implements FormattingModelBuilder {
+ private static final Logger LOG = Logger.getInstance(JsonFormattingBuilderModel.class);
+
+ @NotNull
+ @Override
+ public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("PSI Tree:\n" + DebugUtil.psiToString(element, false));
+ }
+
+ JsonBlock block = new JsonBlock(null, element.getNode(), settings, null, Indent.getNoneIndent(), null);
+ if (LOG.isDebugEnabled()) {
+ StringBuilder builder = new StringBuilder();
+ FormattingModelDumper.dumpFormattingModel(block, 2, builder);
+ LOG.debug("Format Model:\n" + builder.toString());
+ }
+ return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings);
+ }
+
+ @Nullable
+ @Override
+ public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
+ return null;
+ }
+
+ // create spacing model once for all subsequent blocks
+ static SpacingBuilder createSpacingBuilder(CodeStyleSettings settings) {
+ JsonCodeStyleSettings jsonSettings = settings.getCustomSettings(JsonCodeStyleSettings.class);
+ CommonCodeStyleSettings commonSettings = settings.getCommonSettings(JsonLanguage.INSTANCE);
+ return new SpacingBuilder(settings, JsonLanguage.INSTANCE)
+ .afterInside(COLON, JsonParserTypes.PROPERTY).spaceIf(jsonSettings.SPACE_AFTER_COLON)
+ .beforeInside(COLON, JsonParserTypes.PROPERTY).spaceIf(jsonSettings.SPACE_BEFORE_COLON)
+ .withinPair(L_BRAKET, R_BRAKET).spaceIf(commonSettings.SPACE_WITHIN_BRACKETS)
+ .withinPair(L_CURLY, R_CURLY).spaceIf(jsonSettings.SPACE_WITHIN_BRACES)
+ .after(COMMA).spaceIf(commonSettings.SPACE_AFTER_COMMA)
+ .before(COMMA).spaceIf(commonSettings.SPACE_BEFORE_COMMA);
+ }
+}
--- /dev/null
+package com.jetbrains.json.formatter;
+
+import com.intellij.application.options.IndentOptionsEditor;
+import com.intellij.application.options.SmartIndentOptionsEditor;
+import com.intellij.lang.Language;
+import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.jetbrains.json.JsonLanguage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable.SPACES_OTHER;
+import static com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable.SPACES_WITHIN;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider {
+ private static final String SAMPLE = "{\n" +
+ " \"json literals are\": {\n" +
+ " \"strings\": [\"foo\", \"bar\", \"\\u0062\\u0061\\u0072\"],\n" +
+ " \"numbers\": [42, 6.62606975e-34],\n" +
+ " \"boolean values\": [true, false],\n" +
+ " \"and null\": null\n" +
+ " }\n" +
+ "}";
+
+
+ @Override
+ public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) {
+ if (settingsType == SettingsType.SPACING_SETTINGS) {
+ consumer.showStandardOptions("SPACE_WITHIN_BRACKETS",
+ "SPACE_AFTER_COMMA",
+ "SPACE_BEFORE_COMMA");
+ consumer.showCustomOption(JsonCodeStyleSettings.class, "SPACE_WITHIN_BRACES", "Braces", SPACES_WITHIN);
+ consumer.showCustomOption(JsonCodeStyleSettings.class, "SPACE_BEFORE_COLON", "Before ':'", SPACES_OTHER);
+ consumer.showCustomOption(JsonCodeStyleSettings.class, "SPACE_AFTER_COLON", "After ':'", SPACES_OTHER);
+ }
+ super.customizeSettings(consumer, settingsType);
+ }
+
+ @NotNull
+ @Override
+ public Language getLanguage() {
+ return JsonLanguage.INSTANCE;
+ }
+
+ @Nullable
+ @Override
+ public IndentOptionsEditor getIndentOptionsEditor() {
+ // TODO: read sources of this one carefully
+ return new SmartIndentOptionsEditor();
+ }
+
+ @Override
+ public String getCodeSample(@NotNull SettingsType settingsType) {
+ return SAMPLE;
+ }
+}
--- /dev/null
+package com.jetbrains.json.psi;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.AbstractElementManipulator;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.IncorrectOperationException;
+
+public class JsonLiteralManipulator extends AbstractElementManipulator<JsonLiteral> {
+
+ @Override
+ public JsonLiteral handleContentChange(JsonLiteral element, TextRange range, String newContent) throws IncorrectOperationException {
+ String text = "{\"\":\"" + newContent + "\"}";
+
+ final PsiFile dummy = JsonPsiChangeUtils.createDummyFile(element, text);
+ JsonProperty property = PsiTreeUtil.findChildOfType(dummy, JsonProperty.class);
+ assert property != null;
+
+ JsonPropertyValue value = property.getPropertyValue();
+ assert value instanceof JsonLiteral;
+
+ return (JsonLiteral)element.replace(value);
+ }
+}
--- /dev/null
+package com.jetbrains.json.psi;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.psi.TokenType;
+import com.jetbrains.json.JsonFile;
+import com.jetbrains.json.JsonParserTypes;
+import org.jetbrains.annotations.NotNull;
+
+public class JsonPsiChangeUtils {
+ public static void removeCommaSeparatedFromList(final ASTNode myNode, final ASTNode parent) {
+ ASTNode from = myNode, to = myNode.getTreeNext();
+
+ boolean seenComma = false;
+
+ ASTNode toCandidate = to;
+ while (toCandidate != null && toCandidate.getElementType() == TokenType.WHITE_SPACE) {
+ toCandidate = toCandidate.getTreeNext();
+ }
+
+ if (toCandidate != null && toCandidate.getElementType() == JsonParserTypes.COMMA) {
+ toCandidate = toCandidate.getTreeNext();
+ to = toCandidate;
+ seenComma = true;
+
+ if (to != null && to.getElementType() == TokenType.WHITE_SPACE) {
+ to = to.getTreeNext();
+ }
+ }
+
+ if (!seenComma) {
+ ASTNode treePrev = from.getTreePrev();
+
+ while (treePrev != null && treePrev.getElementType() == TokenType.WHITE_SPACE) {
+ from = treePrev;
+ treePrev = treePrev.getTreePrev();
+ }
+ if (treePrev != null && treePrev.getElementType() == JsonParserTypes.COMMA) {
+ from = treePrev;
+ }
+ }
+
+ parent.removeRange(from, to);
+ }
+
+ @NotNull
+ public static PsiFile createDummyFile(JsonLiteral element, String text) {
+ Language language = element.getLanguage();
+ ParserDefinition def = LanguageParserDefinitions.INSTANCE.forLanguage(language);
+ assert def != null;
+ Project project = element.getProject();
+ final PsiFile dummyFile = PsiFileFactory.getInstance(project).createFileFromText("dummy.json", language, text, false, true);
+ assert dummyFile instanceof JsonFile;
+ return dummyFile;
+ }
+}
--- /dev/null
+package com.jetbrains.json.psi;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.json.JsonParserTypes;
+import com.jetbrains.json.psi.impl.JsonPropertyImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public class JsonPsiImplUtils {
+ public static boolean isQuotedString(@NotNull JsonLiteral literal) {
+ return literal.getNode().findChildByType(JsonParserTypes.STRING) != null;
+ }
+
+ @NotNull
+ public static String getName(@NotNull JsonProperty property) {
+ return StringUtil.unquoteString(property.getPropertyName().getText());
+ }
+
+ @Nullable
+ public static JsonPropertyValue getValue(JsonPropertyImpl property) {
+ return PsiTreeUtil.getChildOfType(property, JsonPropertyValue.class);
+ }
+
+ public static void delete(@NotNull JsonProperty property) {
+ final ASTNode myNode = property.getNode();
+ JsonPsiChangeUtils.removeCommaSeparatedFromList(myNode, myNode.getTreeParent());
+ }
+
+ @Nullable
+ public static JsonProperty findProperty(@NotNull JsonObject object, @NotNull String name) {
+ Collection<JsonProperty> properties = PsiTreeUtil.findChildrenOfType(object, JsonProperty.class);
+ for (JsonProperty property : properties) {
+ if (property.getName().equals(name)) {
+ return property;
+ }
+ }
+ return null;
+ }
+}
--- /dev/null
+package com.jetbrains.json.psi.impl;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
+import com.jetbrains.json.psi.JsonLiteral;
+import org.jetbrains.annotations.NotNull;
+
+abstract class JsonLiteralMixin extends JsonPropertyValueImpl implements JsonLiteral {
+ private final Object myRefLock = new Object();
+ private volatile PsiReference[] myRefs;
+ private volatile long myModCount = -1;
+
+ protected JsonLiteralMixin(ASTNode node) {
+ super(node);
+ }
+
+ @NotNull
+ @Override
+ public PsiReference[] getReferences() {
+ final long count = getManager().getModificationTracker().getModificationCount();
+ if (count != myModCount) {
+ synchronized (myRefLock) {
+ if (count != myModCount) {
+ myRefs = ReferenceProvidersRegistry.getReferencesFromProviders(this);
+ myModCount = count;
+ }
+ }
+ }
+
+ return myRefs;
+ }
+}
--- /dev/null
+{
+ parserClass='com.jetbrains.json.JsonParser'
+ parserUtilClass="com.jetbrains.json.JsonParserUtil"
+ psiPackage='com.jetbrains.json.psi'
+ psiImplPackage='com.jetbrains.json.psi.impl'
+
+ elementTypeHolderClass='com.jetbrains.json.JsonParserTypes'
+ elementTypeClass='com.jetbrains.json.JsonElementType'
+ psiClassPrefix="Json"
+
+ psiImplUtilClass='com.jetbrains.json.psi.JsonPsiImplUtils'
+ tokenTypeClass='com.jetbrains.json.JsonTokenType'
+
+ tokens = [
+ L_CURLY='{'
+ R_CURLY='}'
+ L_BRAKET='['
+ R_BRAKET=']'
+
+ COMMA=','
+ COLON=':'
+// COMMENT='regexp:"//.*|/\*.*?\*/"'
+ // else /\*(?:[^*]|\*[^/])*\*/
+ STRING='regexp:"([^\\"]|\\([\\"/bfnrt]|u[a-fA-F0-9]{4}))*"'
+ NUMBER='regexp:-?\d+(\.\d+([eE][+-]?\d+)?)?'
+ TRUE='true'
+ FALSE='false'
+ NULL='null'
+ ]
+
+ extends("object|array|literal")=property_value
+ extends("string_literal|number_literal|boolean_literal|null_literal")=literal
+}
+
+json ::= object | array
+
+object ::= L_CURLY (property (COMMA property)*)? R_CURLY {
+ pin=1
+// recoverUntil=closing_brace
+// recoverUntil=comma
+ methods=[
+ findProperty
+ ]
+}
+//private comma ::= ','
+//private closing_brace ::= !('}')
+
+property ::= property_name COLON property_value {
+ pin=1
+ methods=[
+ getName
+ getValue
+ delete
+ ]
+}
+
+array ::= L_BRAKET (property_value (COMMA property_value)*)? R_BRAKET {
+ pin=1
+// recoverUntil=comma
+}
+//private closing_bracket ::= !(']')
+
+
+property_name ::= string_literal
+property_value ::= object | array | literal
+
+string_literal ::= STRING
+number_literal ::= NUMBER
+boolean_literal ::= TRUE | FALSE
+null_literal ::= NULL
+
+literal ::= string_literal | number_literal | boolean_literal | null_literal {
+ methods=[isQuotedString]
+ mixin="com.jetbrains.json.psi.impl.JsonLiteralMixin"
+}
\ No newline at end of file
--- /dev/null
+package com.jetbrains.json;
+import com.intellij.lexer.*;
+import com.intellij.psi.tree.IElementType;
+import static com.jetbrains.json.JsonParserTypes.*;
+
+%%
+
+%{
+ public _JsonLexer() {
+ this((java.io.Reader)null);
+ }
+%}
+
+%public
+%class _JsonLexer
+%implements FlexLexer
+%function advance
+%type IElementType
+%unicode
+%eof{ return;
+%eof}
+
+WHITE_SPACE=[ \t\n\r]
+
+L_CURLY="{"
+R_CURLY="}"
+L_BRAKET="["
+R_BRAKET="]"
+COMMA=","
+COLON=":"
+STRING=\"([^\\\"]|\\([\\\"/bfnrt]|u[a-fA-F0-9]{4}))*\"
+NUMBER=-?[:digit:]+(\.[:digit:]+([eE][+-]?[:digit:]+)?)?
+TRUE="true"
+FALSE="false"
+NULL="null"
+
+
+%%
+<YYINITIAL> {
+{L_CURLY} { return L_CURLY; }
+{R_CURLY} { return R_CURLY; }
+{L_BRAKET} { return L_BRAKET; }
+{R_BRAKET} { return R_BRAKET; }
+{COMMA} { return COMMA; }
+{COLON} { return COLON; }
+{STRING} { return STRING; }
+{NUMBER} { return NUMBER; }
+{TRUE} { return TRUE; }
+{FALSE} { return FALSE; }
+{NULL} { return NULL; }
+
+{WHITE_SPACE}+ { return com.intellij.psi.TokenType.WHITE_SPACE; }
+[^] { return com.intellij.psi.TokenType.BAD_CHARACTER; }
+}