Merge remote-tracking branch 'origin/master' into json-support
authorMikhail Golubev <mikhail.golubev@jetbrains.com>
Mon, 18 Nov 2013 12:26:50 +0000 (16:26 +0400)
committerMikhail Golubev <mikhail.golubev@jetbrains.com>
Mon, 18 Nov 2013 12:26:50 +0000 (16:26 +0400)
47 files changed:
.idea/modules.xml
plugins/json/gen/com/jetbrains/json/JsonParser.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/JsonParserTypes.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/JsonParserUtil.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/_JsonLexer.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonArray.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonBooleanLiteral.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonLiteral.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonNullLiteral.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonNumberLiteral.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonObject.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonProperty.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonPropertyName.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonPropertyValue.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonStringLiteral.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/JsonVisitor.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonArrayImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonBooleanLiteralImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonLiteralImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonNullLiteralImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonNumberLiteralImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonObjectImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyNameImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyValueImpl.java [new file with mode: 0644]
plugins/json/gen/com/jetbrains/json/psi/impl/JsonStringLiteralImpl.java [new file with mode: 0644]
plugins/json/json.iml [new file with mode: 0644]
plugins/json/src/META-INF/plugin.xml [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonElementType.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonFile.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonFileType.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonFileTypeFactory.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonLanguage.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonParserDefinition.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonSyntaxHighlighterFactory.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/JsonTokenType.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/formatter/JsonBlock.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettings.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettingsProvider.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/formatter/JsonFormattingBuilderModel.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/formatter/JsonLanguageCodeStyleSettingsProvider.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/psi/JsonLiteralManipulator.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/psi/JsonPsiChangeUtils.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/psi/JsonPsiImplUtils.java [new file with mode: 0644]
plugins/json/src/com/jetbrains/json/psi/impl/JsonLiteralMixin.java [new file with mode: 0644]
plugins/json/src/json.bnf [new file with mode: 0644]
plugins/json/src/json.flex [new file with mode: 0644]

index 7173cae34b58c33c74e91eef7ee546e49cdf3bed..0ccca44778a90e9037e164f82e391a1b0a5f67fd 100644 (file)
@@ -94,6 +94,7 @@
       <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" />
diff --git a/plugins/json/gen/com/jetbrains/json/JsonParser.java b/plugins/json/gen/com/jetbrains/json/JsonParser.java
new file mode 100644 (file)
index 0000000..6b3c529
--- /dev/null
@@ -0,0 +1,313 @@
+// 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_;
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/JsonParserTypes.java b/plugins/json/gen/com/jetbrains/json/JsonParserTypes.java
new file mode 100644 (file)
index 0000000..2cfb0e1
--- /dev/null
@@ -0,0 +1,70 @@
+// 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);
+    }
+  }
+}
diff --git a/plugins/json/gen/com/jetbrains/json/JsonParserUtil.java b/plugins/json/gen/com/jetbrains/json/JsonParserUtil.java
new file mode 100644 (file)
index 0000000..dd82e3a
--- /dev/null
@@ -0,0 +1,9 @@
+package com.jetbrains.json;
+
+import com.intellij.lang.parser.GeneratedParserUtilBase;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JsonParserUtil extends GeneratedParserUtilBase {
+}
diff --git a/plugins/json/gen/com/jetbrains/json/_JsonLexer.java b/plugins/json/gen/com/jetbrains/json/_JsonLexer.java
new file mode 100644 (file)
index 0000000..f5601db
--- /dev/null
@@ -0,0 +1,558 @@
+/* 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);
+          }
+      }
+    }
+  }
+
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonArray.java b/plugins/json/gen/com/jetbrains/json/psi/JsonArray.java
new file mode 100644 (file)
index 0000000..33dd7c3
--- /dev/null
@@ -0,0 +1,13 @@
+// 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();
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonBooleanLiteral.java b/plugins/json/gen/com/jetbrains/json/psi/JsonBooleanLiteral.java
new file mode 100644 (file)
index 0000000..c7eccd0
--- /dev/null
@@ -0,0 +1,10 @@
+// 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 {
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonLiteral.java b/plugins/json/gen/com/jetbrains/json/psi/JsonLiteral.java
new file mode 100644 (file)
index 0000000..9fd27f7
--- /dev/null
@@ -0,0 +1,12 @@
+// 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();
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonNullLiteral.java b/plugins/json/gen/com/jetbrains/json/psi/JsonNullLiteral.java
new file mode 100644 (file)
index 0000000..d42112d
--- /dev/null
@@ -0,0 +1,10 @@
+// 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 {
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonNumberLiteral.java b/plugins/json/gen/com/jetbrains/json/psi/JsonNumberLiteral.java
new file mode 100644 (file)
index 0000000..296f375
--- /dev/null
@@ -0,0 +1,10 @@
+// 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 {
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonObject.java b/plugins/json/gen/com/jetbrains/json/psi/JsonObject.java
new file mode 100644 (file)
index 0000000..626e224
--- /dev/null
@@ -0,0 +1,16 @@
+// 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);
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonProperty.java b/plugins/json/gen/com/jetbrains/json/psi/JsonProperty.java
new file mode 100644 (file)
index 0000000..6c4cecb
--- /dev/null
@@ -0,0 +1,25 @@
+// 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();
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonPropertyName.java b/plugins/json/gen/com/jetbrains/json/psi/JsonPropertyName.java
new file mode 100644 (file)
index 0000000..3c7a9fc
--- /dev/null
@@ -0,0 +1,13 @@
+// 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();
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonPropertyValue.java b/plugins/json/gen/com/jetbrains/json/psi/JsonPropertyValue.java
new file mode 100644 (file)
index 0000000..3a0a3e5
--- /dev/null
@@ -0,0 +1,10 @@
+// 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 {
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonStringLiteral.java b/plugins/json/gen/com/jetbrains/json/psi/JsonStringLiteral.java
new file mode 100644 (file)
index 0000000..ade19da
--- /dev/null
@@ -0,0 +1,10 @@
+// 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 {
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/JsonVisitor.java b/plugins/json/gen/com/jetbrains/json/psi/JsonVisitor.java
new file mode 100644 (file)
index 0000000..e039595
--- /dev/null
@@ -0,0 +1,54 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonArrayImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonArrayImpl.java
new file mode 100644 (file)
index 0000000..0464708
--- /dev/null
@@ -0,0 +1,30 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonBooleanLiteralImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonBooleanLiteralImpl.java
new file mode 100644 (file)
index 0000000..6112add
--- /dev/null
@@ -0,0 +1,24 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonLiteralImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonLiteralImpl.java
new file mode 100644 (file)
index 0000000..36ec18b
--- /dev/null
@@ -0,0 +1,28 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonNullLiteralImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonNullLiteralImpl.java
new file mode 100644 (file)
index 0000000..7324d26
--- /dev/null
@@ -0,0 +1,24 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonNumberLiteralImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonNumberLiteralImpl.java
new file mode 100644 (file)
index 0000000..a712487
--- /dev/null
@@ -0,0 +1,24 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonObjectImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonObjectImpl.java
new file mode 100644 (file)
index 0000000..81312a1
--- /dev/null
@@ -0,0 +1,35 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyImpl.java
new file mode 100644 (file)
index 0000000..523f65c
--- /dev/null
@@ -0,0 +1,51 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyNameImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyNameImpl.java
new file mode 100644 (file)
index 0000000..86a9a2f
--- /dev/null
@@ -0,0 +1,31 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyValueImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonPropertyValueImpl.java
new file mode 100644 (file)
index 0000000..fa56852
--- /dev/null
@@ -0,0 +1,25 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/gen/com/jetbrains/json/psi/impl/JsonStringLiteralImpl.java b/plugins/json/gen/com/jetbrains/json/psi/impl/JsonStringLiteralImpl.java
new file mode 100644 (file)
index 0000000..907521d
--- /dev/null
@@ -0,0 +1,24 @@
+// 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);
+  }
+
+}
diff --git a/plugins/json/json.iml b/plugins/json/json.iml
new file mode 100644 (file)
index 0000000..05d4fec
--- /dev/null
@@ -0,0 +1,16 @@
+<?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>
+
diff --git a/plugins/json/src/META-INF/plugin.xml b/plugins/json/src/META-INF/plugin.xml
new file mode 100644 (file)
index 0000000..328b7dd
--- /dev/null
@@ -0,0 +1,35 @@
+<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
diff --git a/plugins/json/src/com/jetbrains/json/JsonElementType.java b/plugins/json/src/com/jetbrains/json/JsonElementType.java
new file mode 100644 (file)
index 0000000..f05720d
--- /dev/null
@@ -0,0 +1,11 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonFile.java b/plugins/json/src/com/jetbrains/json/JsonFile.java
new file mode 100644 (file)
index 0000000..ec192b2
--- /dev/null
@@ -0,0 +1,19 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonFileType.java b/plugins/json/src/com/jetbrains/json/JsonFileType.java
new file mode 100644 (file)
index 0000000..8379ed7
--- /dev/null
@@ -0,0 +1,45 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonFileTypeFactory.java b/plugins/json/src/com/jetbrains/json/JsonFileTypeFactory.java
new file mode 100644 (file)
index 0000000..0930485
--- /dev/null
@@ -0,0 +1,15 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonLanguage.java b/plugins/json/src/com/jetbrains/json/JsonLanguage.java
new file mode 100644 (file)
index 0000000..c9788b7
--- /dev/null
@@ -0,0 +1,16 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonParserDefinition.java b/plugins/json/src/com/jetbrains/json/JsonParserDefinition.java
new file mode 100644 (file)
index 0000000..12054b3
--- /dev/null
@@ -0,0 +1,73 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonSyntaxHighlighterFactory.java b/plugins/json/src/com/jetbrains/json/JsonSyntaxHighlighterFactory.java
new file mode 100644 (file)
index 0000000..4e12c96
--- /dev/null
@@ -0,0 +1,57 @@
+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));
+    }
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/JsonTokenType.java b/plugins/json/src/com/jetbrains/json/JsonTokenType.java
new file mode 100644 (file)
index 0000000..51238ab
--- /dev/null
@@ -0,0 +1,11 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/formatter/JsonBlock.java b/plugins/json/src/com/jetbrains/json/formatter/JsonBlock.java
new file mode 100644 (file)
index 0000000..d47096e
--- /dev/null
@@ -0,0 +1,168 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettings.java b/plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettings.java
new file mode 100644 (file)
index 0000000..0d2d144
--- /dev/null
@@ -0,0 +1,21 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettingsProvider.java b/plugins/json/src/com/jetbrains/json/formatter/JsonCodeStyleSettingsProvider.java
new file mode 100644 (file)
index 0000000..68b530e
--- /dev/null
@@ -0,0 +1,55 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/formatter/JsonFormattingBuilderModel.java b/plugins/json/src/com/jetbrains/json/formatter/JsonFormattingBuilderModel.java
new file mode 100644 (file)
index 0000000..d8fa957
--- /dev/null
@@ -0,0 +1,59 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/formatter/JsonLanguageCodeStyleSettingsProvider.java b/plugins/json/src/com/jetbrains/json/formatter/JsonLanguageCodeStyleSettingsProvider.java
new file mode 100644 (file)
index 0000000..7e8cc51
--- /dev/null
@@ -0,0 +1,59 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/psi/JsonLiteralManipulator.java b/plugins/json/src/com/jetbrains/json/psi/JsonLiteralManipulator.java
new file mode 100644 (file)
index 0000000..5145130
--- /dev/null
@@ -0,0 +1,24 @@
+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);
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/psi/JsonPsiChangeUtils.java b/plugins/json/src/com/jetbrains/json/psi/JsonPsiChangeUtils.java
new file mode 100644 (file)
index 0000000..c6ed696
--- /dev/null
@@ -0,0 +1,61 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/psi/JsonPsiImplUtils.java b/plugins/json/src/com/jetbrains/json/psi/JsonPsiImplUtils.java
new file mode 100644 (file)
index 0000000..be58ae9
--- /dev/null
@@ -0,0 +1,43 @@
+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;
+  }
+}
diff --git a/plugins/json/src/com/jetbrains/json/psi/impl/JsonLiteralMixin.java b/plugins/json/src/com/jetbrains/json/psi/impl/JsonLiteralMixin.java
new file mode 100644 (file)
index 0000000..c242639
--- /dev/null
@@ -0,0 +1,33 @@
+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;
+  }
+}
diff --git a/plugins/json/src/json.bnf b/plugins/json/src/json.bnf
new file mode 100644 (file)
index 0000000..7555981
--- /dev/null
@@ -0,0 +1,75 @@
+{
+  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
diff --git a/plugins/json/src/json.flex b/plugins/json/src/json.flex
new file mode 100644 (file)
index 0000000..f59e64c
--- /dev/null
@@ -0,0 +1,54 @@
+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; }
+}