mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
WEB-12776 Support the JSON5 file type
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* The following code was generated by JFlex 1.7.0-SNAPSHOT tweaked for IntelliJ platform */
|
||||
/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
|
||||
|
||||
package com.intellij.json;
|
||||
|
||||
@@ -12,7 +12,7 @@ import static com.intellij.json.JsonElementTypes.*;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.7.0-SNAPSHOT
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.7.0
|
||||
* from the specification file <tt>_JsonLexer.flex</tt>
|
||||
*/
|
||||
public class _JsonLexer implements FlexLexer {
|
||||
@@ -600,71 +600,88 @@ public class _JsonLexer implements FlexLexer {
|
||||
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
|
||||
case 1:
|
||||
{ return BAD_CHARACTER;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 18: break;
|
||||
case 2:
|
||||
{ return WHITE_SPACE;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 19: break;
|
||||
case 3:
|
||||
{ return IDENTIFIER;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 20: break;
|
||||
case 4:
|
||||
{ return DOUBLE_QUOTED_STRING;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 21: break;
|
||||
case 5:
|
||||
{ return SINGLE_QUOTED_STRING;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 22: break;
|
||||
case 6:
|
||||
{ return NUMBER;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 23: break;
|
||||
case 7:
|
||||
{ return L_CURLY;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 24: break;
|
||||
case 8:
|
||||
{ return R_CURLY;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 25: break;
|
||||
case 9:
|
||||
{ return L_BRACKET;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 26: break;
|
||||
case 10:
|
||||
{ return R_BRACKET;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 27: break;
|
||||
case 11:
|
||||
{ return COMMA;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 28: break;
|
||||
case 12:
|
||||
{ return COLON;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 29: break;
|
||||
case 13:
|
||||
{ return LINE_COMMENT;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 30: break;
|
||||
case 14:
|
||||
{ return BLOCK_COMMENT;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 31: break;
|
||||
case 15:
|
||||
{ return TRUE;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 32: break;
|
||||
case 16:
|
||||
{ return NULL;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 33: break;
|
||||
case 17:
|
||||
{ return FALSE;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case 34: break;
|
||||
default:
|
||||
zzScanError(ZZ_NO_MATCH);
|
||||
|
||||
@@ -0,0 +1,723 @@
|
||||
/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
|
||||
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import static com.intellij.psi.TokenType.BAD_CHARACTER;
|
||||
import static com.intellij.psi.TokenType.WHITE_SPACE;
|
||||
import static com.intellij.json.JsonElementTypes.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.7.0
|
||||
* from the specification file <tt>_Json5Lexer.flex</tt>
|
||||
*/
|
||||
public class _Json5Lexer implements FlexLexer {
|
||||
|
||||
/** This character denotes the end of file */
|
||||
public static final int YYEOF = -1;
|
||||
|
||||
/** 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
|
||||
* Chosen bits are [12, 6, 3]
|
||||
* Total runtime size is 13376 bytes
|
||||
*/
|
||||
public static int ZZ_CMAP(int ch) {
|
||||
return ZZ_CMAP_A[(ZZ_CMAP_Y[(ZZ_CMAP_Z[ch>>9]<<6)|((ch>>3)&0x3f)]<<3)|(ch&0x7)];
|
||||
}
|
||||
|
||||
/* The ZZ_CMAP_Z table has 2176 entries */
|
||||
static final char ZZ_CMAP_Z[] = zzUnpackCMap(
|
||||
"\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17\1"+
|
||||
"\20\5\21\1\22\1\23\1\24\1\21\14\25\1\26\50\25\1\27\2\25\1\30\1\31\1\32\1\33"+
|
||||
"\25\25\1\34\20\21\1\35\1\36\1\37\1\40\1\41\1\42\1\43\1\21\1\44\1\45\1\46\1"+
|
||||
"\21\1\47\2\21\1\50\4\21\1\25\1\51\1\52\5\21\2\25\1\53\31\21\1\25\1\54\1\21"+
|
||||
"\1\55\40\21\1\56\17\21\1\57\1\60\1\61\1\62\13\21\1\63\10\21\123\25\1\64\7"+
|
||||
"\25\1\65\1\66\37\21\1\25\1\66\u0582\21\1\67\u017f\21");
|
||||
|
||||
/* The ZZ_CMAP_Y table has 3584 entries */
|
||||
static final char ZZ_CMAP_Y[] = zzUnpackCMap(
|
||||
"\1\0\1\1\1\0\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\0\1\11\1\12\1\13\1\14\1\15\1\16"+
|
||||
"\3\0\1\17\1\20\1\21\1\22\2\0\1\23\3\0\1\23\71\0\1\24\1\0\1\25\1\26\1\27\1"+
|
||||
"\30\2\26\16\0\1\31\1\32\1\33\1\34\2\0\1\35\11\0\1\36\21\0\1\35\1\37\23\0\1"+
|
||||
"\26\1\40\3\0\1\23\1\41\1\40\4\0\1\42\1\40\4\0\1\36\1\43\1\26\3\0\2\44\1\26"+
|
||||
"\1\27\1\45\1\0\1\44\11\0\1\24\14\0\1\46\1\36\1\0\1\47\1\0\1\50\1\26\1\42\7"+
|
||||
"\0\1\51\14\0\1\25\1\26\6\0\1\52\1\22\5\0\1\52\2\26\3\0\1\2\10\26\1\47\1\27"+
|
||||
"\6\26\1\53\2\0\1\23\14\0\1\54\1\0\2\40\1\55\1\50\1\56\2\0\1\47\1\57\1\60\1"+
|
||||
"\50\1\61\1\42\1\62\1\54\1\0\1\2\1\45\1\55\1\63\1\56\2\0\1\47\1\64\1\65\1\63"+
|
||||
"\1\66\1\41\1\67\1\70\1\0\1\52\1\26\1\55\1\36\1\35\2\0\1\47\1\71\1\60\1\36"+
|
||||
"\1\72\1\73\1\26\1\54\1\0\1\41\1\26\1\55\1\50\1\56\2\0\1\47\1\71\1\60\1\50"+
|
||||
"\1\66\1\70\1\62\1\54\1\0\1\41\1\26\1\74\1\75\1\76\1\77\1\100\1\75\1\0\1\24"+
|
||||
"\1\75\1\76\1\101\1\26\1\70\1\0\1\26\1\41\1\55\1\31\1\47\2\0\1\47\1\46\1\102"+
|
||||
"\1\31\1\76\1\103\1\25\1\54\1\0\2\26\1\74\1\31\1\47\2\0\1\47\1\46\1\60\1\31"+
|
||||
"\1\76\1\103\1\33\1\54\1\0\1\104\1\26\1\74\1\31\1\47\4\0\1\51\1\31\1\105\1"+
|
||||
"\42\1\26\1\54\1\0\1\26\1\37\1\74\1\0\1\23\1\37\2\0\1\35\1\106\1\23\1\107\1"+
|
||||
"\110\1\0\2\26\1\111\1\26\1\40\6\0\1\63\1\0\1\23\1\0\1\25\4\26\1\112\1\113"+
|
||||
"\1\53\1\40\1\114\1\74\1\0\1\72\1\110\1\52\1\0\1\60\4\26\1\73\2\26\1\25\1\0"+
|
||||
"\1\25\1\115\1\116\1\0\1\40\3\0\1\27\1\40\1\0\1\31\2\0\1\40\3\0\1\27\1\33\7"+
|
||||
"\26\11\0\1\25\11\0\1\52\4\0\1\36\1\21\5\0\1\117\51\0\1\76\1\23\1\76\5\0\1"+
|
||||
"\76\4\0\1\76\1\23\1\76\1\0\1\23\7\0\1\76\10\0\1\51\4\26\2\0\2\26\12\0\1\27"+
|
||||
"\1\26\1\40\114\0\1\50\2\0\1\120\2\0\1\44\11\0\1\75\1\73\1\26\1\0\1\31\1\27"+
|
||||
"\1\26\2\0\1\27\1\26\2\0\1\2\1\26\1\0\1\31\1\121\1\26\12\0\1\122\1\123\1\0"+
|
||||
"\1\25\3\26\1\123\1\0\1\25\13\0\1\26\5\0\1\44\10\0\1\52\1\26\3\0\1\27\1\0\1"+
|
||||
"\2\1\0\1\2\1\70\4\0\1\52\1\27\1\26\5\0\1\2\3\0\1\25\1\0\1\25\4\26\3\0\1\2"+
|
||||
"\7\0\1\23\3\0\1\50\1\0\1\25\1\0\1\25\1\42\13\26\11\0\1\2\1\0\1\25\1\26\1\124"+
|
||||
"\1\2\1\26\16\0\1\2\1\26\7\0\1\26\1\0\1\102\5\0\1\52\12\26\1\117\3\0\1\23\1"+
|
||||
"\26\34\0\1\23\2\26\1\53\42\0\2\52\4\0\2\52\1\0\1\125\3\0\1\52\6\0\1\31\1\110"+
|
||||
"\1\126\1\27\1\54\1\2\1\0\1\27\1\126\1\27\1\127\1\130\3\26\1\131\1\26\1\42"+
|
||||
"\1\73\1\26\1\132\1\133\1\27\1\37\1\41\1\42\2\26\1\0\1\27\3\0\1\44\2\26\1\0"+
|
||||
"\1\27\1\134\1\0\1\73\1\26\1\107\1\37\1\106\1\135\1\30\1\136\1\0\1\60\1\137"+
|
||||
"\1\140\2\26\5\0\1\73\116\26\5\0\1\23\5\0\1\23\20\0\1\27\1\124\1\2\1\26\4\0"+
|
||||
"\1\36\1\21\7\0\1\42\1\26\1\42\2\0\1\23\1\26\10\23\4\0\5\26\1\42\72\26\1\141"+
|
||||
"\3\26\1\40\1\0\1\135\1\27\1\40\11\0\1\23\1\142\1\40\12\0\1\117\1\137\4\0\1"+
|
||||
"\52\1\40\12\0\1\23\2\26\3\0\1\44\6\26\170\0\1\52\11\26\71\0\1\27\6\26\21\0"+
|
||||
"\1\27\10\26\5\0\1\52\41\0\1\27\3\0\1\2\2\26\6\0\1\53\1\36\3\0\1\42\12\0\1"+
|
||||
"\25\3\26\1\42\1\0\1\37\14\0\1\61\1\2\1\26\1\0\1\44\11\26\6\0\2\26\1\73\6\0"+
|
||||
"\1\2\1\26\10\0\1\27\1\26\1\0\1\25\3\0\1\45\5\0\1\52\4\0\1\2\1\26\3\0\1\27"+
|
||||
"\10\0\1\73\1\42\1\0\1\25\4\26\6\0\1\23\1\26\1\0\1\52\1\0\1\25\2\0\1\23\1\111"+
|
||||
"\10\0\1\44\2\26\1\123\2\0\1\143\1\26\3\144\1\26\2\23\22\26\5\0\1\145\1\0\1"+
|
||||
"\25\64\0\1\2\1\26\2\0\1\23\1\124\5\0\1\2\40\26\55\0\1\52\15\0\1\25\4\26\1"+
|
||||
"\23\1\26\1\124\1\137\1\0\1\47\1\23\1\110\1\146\15\0\1\25\3\26\1\124\54\0\1"+
|
||||
"\52\2\26\10\0\1\37\6\0\5\26\1\0\1\27\2\0\2\26\1\23\1\26\1\100\2\26\1\137\3"+
|
||||
"\26\1\41\1\31\20\0\1\50\1\132\1\26\1\0\1\25\1\40\2\0\1\63\1\40\2\0\1\44\1"+
|
||||
"\70\12\0\1\23\3\37\1\147\1\150\2\26\1\151\1\0\1\46\2\0\1\23\2\0\1\152\1\0"+
|
||||
"\1\52\1\0\1\52\4\26\17\0\1\44\10\26\6\0\1\27\20\26\1\21\20\26\3\0\1\27\6\0"+
|
||||
"\1\73\5\26\3\0\1\23\2\26\3\0\1\44\6\26\3\0\1\52\4\0\1\2\1\0\1\135\5\26\23"+
|
||||
"\0\1\52\1\0\1\25\52\26\1\52\1\47\4\0\1\36\1\153\2\0\1\52\25\26\2\0\1\52\1"+
|
||||
"\26\3\0\1\25\10\26\7\0\1\70\10\26\1\154\1\53\1\46\1\40\2\0\1\2\1\63\4\26\3"+
|
||||
"\0\1\27\20\26\6\0\1\52\1\26\2\0\1\52\1\26\2\0\1\44\21\26\11\0\1\73\66\26\10"+
|
||||
"\0\1\23\3\26\1\70\1\0\2\26\7\0\1\155\2\26\3\0\1\73\1\0\1\25\6\0\1\31\1\0\10"+
|
||||
"\26\10\0\1\27\1\26\1\0\1\25\24\26\7\0\1\26\1\0\1\25\46\26\55\0\1\23\22\26"+
|
||||
"\14\0\1\44\63\26\5\0\1\23\72\26\7\0\1\73\130\26\10\0\1\27\1\26\5\0\1\23\1"+
|
||||
"\26\1\42\2\0\14\26\1\25\153\26\1\137\1\102\2\0\1\51\1\2\3\26\1\32\22\26\1"+
|
||||
"\147\67\26\12\0\1\31\10\0\1\31\1\156\1\157\1\0\1\160\1\46\7\0\1\36\1\51\2"+
|
||||
"\31\3\0\1\161\1\110\1\37\1\47\51\0\1\52\3\0\1\47\2\0\1\117\3\0\1\117\2\0\1"+
|
||||
"\31\3\0\1\31\2\0\1\23\3\0\1\23\3\0\1\47\3\0\1\47\2\0\1\117\1\54\6\0\1\46\3"+
|
||||
"\0\1\112\1\40\1\117\1\162\1\107\1\163\1\112\1\125\1\112\2\117\1\67\1\0\1\35"+
|
||||
"\1\0\1\2\1\55\1\35\1\0\1\2\50\26\32\0\1\23\5\26\106\0\1\27\1\26\33\0\1\52"+
|
||||
"\74\26\1\41\3\26\14\0\20\26\36\0\2\26");
|
||||
|
||||
/* The ZZ_CMAP_A table has 928 entries */
|
||||
static final char ZZ_CMAP_A[] = zzUnpackCMap(
|
||||
"\11\35\1\12\1\2\1\1\1\7\1\3\6\35\4\0\1\12\1\35\1\13\1\0\1\35\2\0\1\15\2\35"+
|
||||
"\1\11\1\16\1\42\1\17\1\22\1\6\1\20\11\21\1\43\1\0\3\35\1\0\1\35\4\5\1\23\1"+
|
||||
"\5\2\35\1\25\4\35\1\33\1\35\1\24\2\35\1\40\1\14\1\41\2\35\1\0\1\34\3\5\1\46"+
|
||||
"\1\27\2\35\1\30\2\35\1\47\1\35\1\26\3\35\1\44\1\50\1\31\1\45\2\35\1\24\1\32"+
|
||||
"\1\35\1\36\1\0\1\37\7\35\1\10\2\35\1\4\1\0\4\35\4\0\1\35\2\0\1\35\7\0\1\35"+
|
||||
"\4\0\1\35\5\0\7\35\1\0\2\35\4\0\4\35\16\0\5\35\7\0\1\35\1\0\1\35\1\0\5\35"+
|
||||
"\1\0\2\35\2\0\4\35\10\0\1\35\1\0\3\35\1\0\1\35\1\0\4\35\1\0\13\35\1\0\1\35"+
|
||||
"\2\0\6\35\1\0\7\35\1\0\1\35\15\0\1\35\1\0\2\35\1\0\2\35\1\0\4\35\10\0\1\35"+
|
||||
"\4\0\4\35\1\0\4\35\1\0\13\35\2\0\4\35\2\0\11\35\6\0\10\35\2\0\2\35\1\0\3\35"+
|
||||
"\1\0\4\35\2\0\6\35\1\0\1\35\3\0\4\35\2\0\5\35\2\0\4\35\5\0\2\35\1\0\4\35\4"+
|
||||
"\0\2\35\1\0\2\35\1\0\2\35\1\0\2\35\2\0\1\35\1\0\3\35\2\0\3\35\3\0\4\35\1\0"+
|
||||
"\1\35\7\0\3\35\1\0\2\35\1\0\5\35\1\0\3\35\2\0\1\35\11\0\2\35\1\0\6\35\3\0"+
|
||||
"\3\35\1\0\4\35\3\0\2\35\1\0\1\35\1\0\2\35\3\0\2\35\3\0\1\35\6\0\3\35\3\0\3"+
|
||||
"\35\5\0\2\35\2\0\2\35\5\0\1\35\1\0\5\35\1\0\4\35\1\0\1\35\4\0\1\35\4\0\6\35"+
|
||||
"\1\0\1\35\3\0\2\35\5\0\2\35\1\0\1\35\2\0\2\35\1\0\1\35\2\0\1\35\3\0\3\35\1"+
|
||||
"\0\1\35\1\0\1\35\5\0\1\35\1\0\1\35\1\0\1\35\4\0\5\35\1\0\4\35\1\4\10\35\1"+
|
||||
"\0\2\35\4\0\4\35\3\0\1\35\3\0\3\35\5\0\5\35\1\0\1\35\1\0\1\35\1\0\1\35\1\0"+
|
||||
"\1\35\2\0\3\35\1\0\2\35\13\4\5\35\2\1\5\35\1\4\4\0\1\35\12\0\1\4\1\0\1\35"+
|
||||
"\3\0\3\35\1\0\5\35\2\0\1\35\1\0\4\35\1\0\1\35\5\0\5\35\4\0\1\35\1\0\1\4\4"+
|
||||
"\0\3\35\1\0\2\35\2\0\3\35\2\0\5\35\2\0\6\35\1\0\3\35\1\0\2\35\2\0\2\35\1\0"+
|
||||
"\2\35\1\0\2\35\2\0\3\35\3\0\2\35\3\0\2\35\2\0\3\35\4\0\3\35\1\0\2\35\1\0\2"+
|
||||
"\35\3\0\1\35\2\0\5\35\1\0\2\35\1\0\3\35\2\0\1\35\4\0\1\35\2\0\2\35\2\0\4\35"+
|
||||
"\1\0\4\35\1\0\1\35\1\0\5\35\1\0\4\35\2\0\1\35\1\0\1\35\5\0\1\35\1\0\1\35\1"+
|
||||
"\0\3\35");
|
||||
|
||||
/**
|
||||
* Translates DFA states to action switch labels.
|
||||
*/
|
||||
private static final int [] ZZ_ACTION = zzUnpackAction();
|
||||
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\1\1\1\2\1\3\2\4\1\3\1\5\1\6\6\1"+
|
||||
"\5\4\1\7\1\10\1\11\1\12\1\13\1\14\1\15"+
|
||||
"\1\16\1\5\2\0\1\6\5\1\1\4\2\1\5\4"+
|
||||
"\1\15\1\16\1\4\2\5\2\6\1\1\4\4\1\1"+
|
||||
"\1\0\1\16\1\4\1\17\1\4\1\20\1\16\1\4"+
|
||||
"\1\21\2\4";
|
||||
|
||||
private static int [] zzUnpackAction() {
|
||||
int [] result = new int[68];
|
||||
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\51\0\122\0\173\0\244\0\315\0\366\0\u011f"+
|
||||
"\0\u0148\0\u0171\0\u019a\0\u01c3\0\u01ec\0\u0215\0\u023e\0\u0267"+
|
||||
"\0\u0290\0\u02b9\0\u02e2\0\51\0\51\0\51\0\51\0\51"+
|
||||
"\0\51\0\u030b\0\u0334\0\51\0\u035d\0\u0386\0\51\0\u03af"+
|
||||
"\0\u03d8\0\u0401\0\u042a\0\u0453\0\u047c\0\u04a5\0\u04ce\0\u04f7"+
|
||||
"\0\u0520\0\u0549\0\u0572\0\u059b\0\u05c4\0\u05ed\0\u0616\0\u063f"+
|
||||
"\0\u0668\0\u0691\0\u06ba\0\u047c\0\u06e3\0\u070c\0\u0735\0\u075e"+
|
||||
"\0\173\0\u0787\0\173\0\u07b0\0\173\0\u07d9\0\173\0\51"+
|
||||
"\0\u0802\0\173\0\u082b\0\u0854";
|
||||
|
||||
private static int [] zzUnpackRowMap() {
|
||||
int [] result = new int[68];
|
||||
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\4\3\1\4\1\5\1\3\1\6\1\4\1\3"+
|
||||
"\1\7\1\2\1\10\1\11\1\12\1\13\1\14\1\15"+
|
||||
"\1\16\1\4\1\17\1\20\1\21\1\4\1\22\1\4"+
|
||||
"\1\23\2\4\1\24\1\25\1\26\1\27\1\30\1\31"+
|
||||
"\2\4\1\16\2\4\52\0\4\3\2\0\2\3\1\0"+
|
||||
"\1\3\43\0\2\4\1\0\2\4\5\0\17\4\6\0"+
|
||||
"\5\4\5\0\1\4\1\32\1\0\1\4\1\33\5\0"+
|
||||
"\17\4\6\0\5\4\1\0\4\3\2\4\1\3\1\6"+
|
||||
"\1\4\1\3\4\0\17\4\6\0\5\4\2\7\2\0"+
|
||||
"\7\7\1\34\1\35\34\7\2\10\2\0\10\10\1\36"+
|
||||
"\1\37\33\10\20\0\1\40\1\41\1\42\1\43\22\0"+
|
||||
"\1\43\7\0\2\4\1\0\2\4\5\0\1\4\1\44"+
|
||||
"\1\14\1\15\1\16\1\4\1\17\5\4\1\23\2\4"+
|
||||
"\6\0\2\4\1\16\2\4\5\0\2\4\1\0\2\4"+
|
||||
"\5\0\1\4\3\15\1\16\1\45\11\4\6\0\2\4"+
|
||||
"\1\16\2\4\5\0\2\4\1\0\2\4\5\0\1\4"+
|
||||
"\2\14\1\15\1\16\12\4\6\0\2\4\1\16\2\4"+
|
||||
"\5\0\2\4\1\0\2\4\5\0\1\4\2\15\1\4"+
|
||||
"\1\16\12\4\6\0\2\4\1\16\2\4\5\0\2\4"+
|
||||
"\1\0\2\4\4\0\1\46\3\47\14\4\6\0\5\4"+
|
||||
"\5\0\2\4\1\0\2\4\5\0\7\4\1\50\7\4"+
|
||||
"\6\0\5\4\5\0\2\4\1\0\2\4\5\0\17\4"+
|
||||
"\6\0\1\4\1\51\3\4\5\0\2\4\1\0\2\4"+
|
||||
"\5\0\15\4\1\52\1\4\6\0\5\4\5\0\2\4"+
|
||||
"\1\0\2\4\5\0\17\4\6\0\1\53\4\4\5\0"+
|
||||
"\2\4\1\0\2\4\5\0\15\4\1\54\1\4\6\0"+
|
||||
"\5\4\1\55\3\0\1\55\2\32\1\0\1\4\1\32"+
|
||||
"\5\55\17\32\6\55\5\32\5\56\2\33\1\56\1\33"+
|
||||
"\1\57\5\56\17\33\6\56\5\33\3\7\1\60\3\7"+
|
||||
"\1\61\2\7\1\61\36\7\3\10\1\62\3\10\1\63"+
|
||||
"\2\10\1\63\36\10\20\0\3\42\1\43\22\0\1\43"+
|
||||
"\22\0\2\41\1\42\1\43\22\0\1\43\22\0\2\42"+
|
||||
"\1\0\1\43\22\0\1\43\20\0\4\46\34\0\2\4"+
|
||||
"\1\0\2\4\5\0\1\4\3\15\1\16\12\4\6\0"+
|
||||
"\2\4\1\16\2\4\5\0\1\64\1\4\1\0\2\4"+
|
||||
"\5\0\1\4\2\64\1\4\1\64\3\4\1\64\4\4"+
|
||||
"\1\64\1\4\6\0\2\4\1\64\2\4\20\0\2\46"+
|
||||
"\34\0\2\4\1\0\2\4\5\0\1\4\2\47\14\4"+
|
||||
"\6\0\5\4\5\0\2\4\1\0\2\4\5\0\10\4"+
|
||||
"\1\65\6\4\6\0\5\4\5\0\2\4\1\0\2\4"+
|
||||
"\5\0\17\4\6\0\3\4\1\66\1\4\5\0\2\4"+
|
||||
"\1\0\2\4\5\0\17\4\6\0\3\4\1\67\1\4"+
|
||||
"\5\0\2\4\1\0\2\4\5\0\17\4\6\0\1\4"+
|
||||
"\1\70\3\4\5\0\2\4\1\0\2\4\5\0\14\4"+
|
||||
"\1\71\2\4\6\0\5\4\1\55\3\0\3\55\2\0"+
|
||||
"\40\55\11\56\1\72\44\56\1\33\1\73\1\56\1\33"+
|
||||
"\1\57\5\56\17\33\6\56\5\33\3\7\1\0\7\7"+
|
||||
"\1\34\1\35\37\7\1\60\3\7\1\61\2\7\1\61"+
|
||||
"\1\34\1\35\34\7\3\10\1\0\10\10\1\36\1\37"+
|
||||
"\36\10\1\62\3\10\1\63\2\10\1\63\1\10\1\36"+
|
||||
"\1\37\33\10\5\0\2\4\1\0\2\4\5\0\11\4"+
|
||||
"\1\74\5\4\6\0\5\4\5\0\2\4\1\0\2\4"+
|
||||
"\5\0\17\4\6\0\3\4\1\75\1\4\5\0\2\4"+
|
||||
"\1\0\2\4\5\0\17\4\6\0\4\4\1\76\5\0"+
|
||||
"\2\4\1\0\2\4\5\0\17\4\6\0\2\4\1\77"+
|
||||
"\2\4\6\56\1\100\2\56\1\72\37\56\5\0\2\4"+
|
||||
"\1\0\2\4\5\0\7\4\1\101\7\4\6\0\5\4"+
|
||||
"\5\0\2\4\1\0\2\4\5\0\17\4\6\0\2\4"+
|
||||
"\1\102\2\4\5\0\2\4\1\0\2\4\5\0\11\4"+
|
||||
"\1\103\5\4\6\0\5\4\5\0\2\4\1\0\2\4"+
|
||||
"\5\0\12\4\1\104\4\4\6\0\5\4\5\0\2\4"+
|
||||
"\1\0\2\4\5\0\13\4\1\71\3\4\6\0\5\4";
|
||||
|
||||
private static int [] zzUnpackTrans() {
|
||||
int [] result = new int[2173];
|
||||
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;
|
||||
|
||||
/* error messages for the codes above */
|
||||
private static final String[] ZZ_ERROR_MSG = {
|
||||
"Unknown 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\1\1\11\21\1\6\11\2\1\1\11\2\0\1\11"+
|
||||
"\32\1\1\0\5\1\1\11\4\1";
|
||||
|
||||
private static int [] zzUnpackAttribute() {
|
||||
int [] result = new int[68];
|
||||
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 input device */
|
||||
private java.io.Reader zzReader;
|
||||
|
||||
/** 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 = "";
|
||||
|
||||
/** the textposition at the last accepting state */
|
||||
private int zzMarkedPos;
|
||||
|
||||
/** 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 _Json5Lexer() {
|
||||
this((java.io.Reader)null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new scanner
|
||||
*
|
||||
* @param in the java.io.Reader to read input from.
|
||||
*/
|
||||
public _Json5Lexer(java.io.Reader in) {
|
||||
this.zzReader = 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) {
|
||||
int size = 0;
|
||||
for (int i = 0, length = packed.length(); i < length; i += 2) {
|
||||
size += packed.charAt(i);
|
||||
}
|
||||
char[] map = new char[size];
|
||||
int i = 0; /* index in packed string */
|
||||
int j = 0; /* index in unpacked array */
|
||||
while (i < packed.length()) {
|
||||
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;
|
||||
zzCurrentPos = zzMarkedPos = zzStartRead = start;
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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];
|
||||
|
||||
// set up zzAction for empty match case:
|
||||
int zzAttributes = zzAttrL[zzState];
|
||||
if ( (zzAttributes & 1) == 1 ) {
|
||||
zzAction = zzState;
|
||||
}
|
||||
|
||||
|
||||
zzForAction: {
|
||||
while (true) {
|
||||
|
||||
if (zzCurrentPosL < zzEndReadL) {
|
||||
zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
|
||||
zzCurrentPosL += Character.charCount(zzInput);
|
||||
}
|
||||
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 = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
|
||||
zzCurrentPosL += Character.charCount(zzInput);
|
||||
}
|
||||
}
|
||||
int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(zzInput) ];
|
||||
if (zzNext == -1) break zzForAction;
|
||||
zzState = zzNext;
|
||||
|
||||
zzAttributes = zzAttrL[zzState];
|
||||
if ( (zzAttributes & 1) == 1 ) {
|
||||
zzAction = zzState;
|
||||
zzMarkedPosL = zzCurrentPosL;
|
||||
if ( (zzAttributes & 8) == 8 ) break zzForAction;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// store back cached position
|
||||
zzMarkedPos = zzMarkedPosL;
|
||||
|
||||
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
|
||||
zzAtEOF = true;
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
|
||||
case 1:
|
||||
{ return NUMBER;
|
||||
}
|
||||
// fall through
|
||||
case 18: break;
|
||||
case 2:
|
||||
{ return BAD_CHARACTER;
|
||||
}
|
||||
// fall through
|
||||
case 19: break;
|
||||
case 3:
|
||||
{ return WHITE_SPACE;
|
||||
}
|
||||
// fall through
|
||||
case 20: break;
|
||||
case 4:
|
||||
{ return IDENTIFIER;
|
||||
}
|
||||
// fall through
|
||||
case 21: break;
|
||||
case 5:
|
||||
{ return DOUBLE_QUOTED_STRING;
|
||||
}
|
||||
// fall through
|
||||
case 22: break;
|
||||
case 6:
|
||||
{ return SINGLE_QUOTED_STRING;
|
||||
}
|
||||
// fall through
|
||||
case 23: break;
|
||||
case 7:
|
||||
{ return L_CURLY;
|
||||
}
|
||||
// fall through
|
||||
case 24: break;
|
||||
case 8:
|
||||
{ return R_CURLY;
|
||||
}
|
||||
// fall through
|
||||
case 25: break;
|
||||
case 9:
|
||||
{ return L_BRACKET;
|
||||
}
|
||||
// fall through
|
||||
case 26: break;
|
||||
case 10:
|
||||
{ return R_BRACKET;
|
||||
}
|
||||
// fall through
|
||||
case 27: break;
|
||||
case 11:
|
||||
{ return COMMA;
|
||||
}
|
||||
// fall through
|
||||
case 28: break;
|
||||
case 12:
|
||||
{ return COLON;
|
||||
}
|
||||
// fall through
|
||||
case 29: break;
|
||||
case 13:
|
||||
{ return LINE_COMMENT;
|
||||
}
|
||||
// fall through
|
||||
case 30: break;
|
||||
case 14:
|
||||
{ return BLOCK_COMMENT;
|
||||
}
|
||||
// fall through
|
||||
case 31: break;
|
||||
case 15:
|
||||
{ return NULL;
|
||||
}
|
||||
// fall through
|
||||
case 32: break;
|
||||
case 16:
|
||||
{ return TRUE;
|
||||
}
|
||||
// fall through
|
||||
case 33: break;
|
||||
case 17:
|
||||
{ return FALSE;
|
||||
}
|
||||
// fall through
|
||||
case 34: break;
|
||||
default:
|
||||
zzScanError(ZZ_NO_MATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection checks that JSON5 files conform to language specification (http://json5.org/).<br>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,7 +15,7 @@ import java.util.ResourceBundle;
|
||||
public class JsonBundle {
|
||||
|
||||
private static Reference<ResourceBundle> ourBundle;
|
||||
@NonNls private static final String BUNDLE = "com.intellij.json.JsonBundle";
|
||||
@NonNls public static final String BUNDLE = "com.intellij.json.JsonBundle";
|
||||
|
||||
private JsonBundle() {
|
||||
// empty
|
||||
|
||||
@@ -9,8 +9,10 @@ syntax.error.illegal.floating.point.literal=Illegal floating point literal
|
||||
|
||||
# Inspections
|
||||
json.inspection.group=JSON
|
||||
json.inspection5.group=JSON/JSON5
|
||||
|
||||
inspection.compliance.name=Compliance with JSON standard
|
||||
inspection.compliance5.name=Compliance with JSON5 standard
|
||||
inspection.compliance.msg.comments=JSON standard does not allow comments. Use JSMin or similar tool to remove comments before parsing.
|
||||
inspection.compliance.msg.single.quoted.strings=JSON standard does not allow single quoted strings
|
||||
inspection.compliance.msg.bad.token=JSON standard does not allow such tokens
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JsonDialectUtil {
|
||||
public static boolean isStandardJson(@NotNull PsiElement element) {
|
||||
return getLanguage(element) == JsonLanguage.INSTANCE;
|
||||
}
|
||||
|
||||
public static Language getLanguage(@NotNull PsiElement element) {
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (file == null) return JsonLanguage.INSTANCE;
|
||||
Language language = file.getLanguage();
|
||||
return language instanceof JsonLanguage ? language : JsonLanguage.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.intellij.json;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
@@ -14,6 +15,10 @@ public class JsonFileType extends LanguageFileType{
|
||||
public static final JsonFileType INSTANCE = new JsonFileType();
|
||||
public static final String DEFAULT_EXTENSION = "json";
|
||||
|
||||
protected JsonFileType(Language language) {
|
||||
super(language);
|
||||
}
|
||||
|
||||
public JsonFileType() {
|
||||
super(JsonLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import com.intellij.lang.Language;
|
||||
public class JsonLanguage extends Language {
|
||||
public static final JsonLanguage INSTANCE = new JsonLanguage();
|
||||
|
||||
protected JsonLanguage(String ID, String... mimeTypes) {
|
||||
super(INSTANCE, ID, mimeTypes);
|
||||
}
|
||||
|
||||
private JsonLanguage() {
|
||||
super("JSON", "application/json", "application/vnd.api+json", "application/hal+json");
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class JsonParserDefinition implements ParserDefinition {
|
||||
|
||||
@Override
|
||||
public PsiFile createFile(FileViewProvider fileViewProvider) {
|
||||
return new JsonFileImpl(fileViewProvider);
|
||||
return new JsonFileImpl(fileViewProvider, JsonLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.json.JsonBundle;
|
||||
import com.intellij.json.highlighting.JsonSyntaxHighlighterFactory;
|
||||
import com.intellij.json.psi.JsonNumberLiteral;
|
||||
import com.intellij.json.psi.JsonPsiUtil;
|
||||
import com.intellij.json.psi.JsonReferenceExpression;
|
||||
import com.intellij.json.psi.JsonStringLiteral;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
@@ -29,14 +30,11 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class JsonLiteralAnnotator implements Annotator {
|
||||
private static final Pattern VALID_ESCAPE = Pattern.compile("\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4})");
|
||||
private static final Pattern VALID_NUMBER_LITERAL = Pattern.compile("-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?");
|
||||
|
||||
private static class Holder {
|
||||
private static final boolean DEBUG = ApplicationManager.getApplication().isUnitTestMode();
|
||||
@@ -45,12 +43,14 @@ public class JsonLiteralAnnotator implements Annotator {
|
||||
@Override
|
||||
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||
final String text = JsonPsiUtil.getElementTextWithoutHostEscaping(element);
|
||||
if (element instanceof JsonStringLiteral) {
|
||||
JsonLiteralChecker[] extensions = JsonLiteralChecker.EP_NAME.getExtensions();
|
||||
if (element instanceof JsonReferenceExpression) {
|
||||
highlightPropertyKey(element, holder);
|
||||
}
|
||||
else if (element instanceof JsonStringLiteral) {
|
||||
final JsonStringLiteral stringLiteral = (JsonStringLiteral)element;
|
||||
final int elementOffset = element.getTextOffset();
|
||||
if (JsonPsiUtil.isPropertyKey(element)) {
|
||||
holder.createInfoAnnotation(element, Holder.DEBUG ? "property key" : null).setTextAttributes(JsonSyntaxHighlighterFactory.JSON_PROPERTY_KEY);
|
||||
}
|
||||
highlightPropertyKey(element, holder);
|
||||
final int length = text.length();
|
||||
|
||||
// Check that string literal is closed properly
|
||||
@@ -60,24 +60,31 @@ public class JsonLiteralAnnotator implements Annotator {
|
||||
|
||||
// Check escapes
|
||||
final List<Pair<TextRange, String>> fragments = stringLiteral.getTextFragments();
|
||||
for (Pair<TextRange, String> fragment : fragments) {
|
||||
final String fragmentText = fragment.getSecond();
|
||||
if (fragmentText.startsWith("\\") && fragmentText.length() > 1 && !VALID_ESCAPE.matcher(fragmentText).matches()) {
|
||||
final TextRange fragmentRange = fragment.getFirst();
|
||||
if (fragmentText.startsWith("\\u")) {
|
||||
holder.createErrorAnnotation(fragmentRange.shiftRight(elementOffset), JsonBundle.message(
|
||||
"syntax.error.illegal.unicode.escape.sequence"));
|
||||
}
|
||||
else {
|
||||
holder.createErrorAnnotation(fragmentRange.shiftRight(elementOffset), JsonBundle.message("syntax.error.illegal.escape.sequence"));
|
||||
for (Pair<TextRange, String> fragment: fragments) {
|
||||
for (JsonLiteralChecker checker: extensions) {
|
||||
if (!checker.isApplicable(element)) continue;
|
||||
String error = checker.getErrorForStringFragment(fragment.getSecond());
|
||||
if (error != null) {
|
||||
final TextRange fragmentRange = fragment.getFirst();
|
||||
holder.createErrorAnnotation(fragmentRange.shiftRight(elementOffset), error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element instanceof JsonNumberLiteral) {
|
||||
if (!VALID_NUMBER_LITERAL.matcher(text).matches()) {
|
||||
holder.createErrorAnnotation(element, JsonBundle.message("syntax.error.illegal.floating.point.literal"));
|
||||
for (JsonLiteralChecker checker: extensions) {
|
||||
if (!checker.isApplicable(element)) continue;
|
||||
String error = checker.getErrorForNumericLiteral(text);
|
||||
if (error != null) {
|
||||
holder.createErrorAnnotation(element, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void highlightPropertyKey(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||
if (JsonPsiUtil.isPropertyKey(element)) {
|
||||
holder.createInfoAnnotation(element, Holder.DEBUG ? "property key" : null).setTextAttributes(JsonSyntaxHighlighterFactory.JSON_PROPERTY_KEY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.codeinsight;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface JsonLiteralChecker {
|
||||
ExtensionPointName<JsonLiteralChecker> EP_NAME = ExtensionPointName.create("com.intellij.json.jsonLiteralChecker");
|
||||
|
||||
@Nullable
|
||||
String getErrorForNumericLiteral(String literalText);
|
||||
|
||||
@Nullable
|
||||
String getErrorForStringFragment(String fragmentText);
|
||||
|
||||
boolean isApplicable(PsiElement element);
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import com.intellij.codeHighlighting.HighlightDisplayLevel;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.json.JsonBundle;
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.json.JsonElementTypes;
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -66,69 +67,8 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new JsonElementVisitor() {
|
||||
@Override
|
||||
public void visitComment(PsiComment comment) {
|
||||
if (myWarnAboutComments) {
|
||||
if (JsonStandardComplianceProvider.shouldWarnAboutComment(comment)) {
|
||||
holder.registerProblem(comment, JsonBundle.message("inspection.compliance.msg.comments"), ProblemHighlightType.WEAK_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitStringLiteral(@NotNull JsonStringLiteral stringLiteral) {
|
||||
if (JsonPsiUtil.getElementTextWithoutHostEscaping(stringLiteral).startsWith("'")) {
|
||||
holder.registerProblem(stringLiteral, JsonBundle.message("inspection.compliance.msg.single.quoted.strings"),
|
||||
new AddDoubleQuotesFix());
|
||||
}
|
||||
// May be illegal property key as well
|
||||
super.visitStringLiteral(stringLiteral);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLiteral(@NotNull JsonLiteral literal) {
|
||||
if (JsonPsiUtil.isPropertyKey(literal) && !JsonPsiUtil.getElementTextWithoutHostEscaping(literal).startsWith("\"")) {
|
||||
holder.registerProblem(literal, JsonBundle.message("inspection.compliance.msg.illegal.property.key"), new AddDoubleQuotesFix());
|
||||
}
|
||||
super.visitLiteral(literal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull JsonReferenceExpression reference) {
|
||||
holder.registerProblem(reference, JsonBundle.message("inspection.compliance.msg.bad.token"), new AddDoubleQuotesFix());
|
||||
// May be illegal property key as well
|
||||
super.visitReferenceExpression(reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArray(@NotNull JsonArray array) {
|
||||
final PsiElement trailingComma = findTrailingComma(array, JsonElementTypes.R_BRACKET);
|
||||
if (trailingComma != null) {
|
||||
holder.registerProblem(trailingComma, JsonBundle.message("inspection.compliance.msg.trailing.comma"));
|
||||
}
|
||||
super.visitArray(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitObject(@NotNull JsonObject object) {
|
||||
final PsiElement trailingComma = findTrailingComma(object, JsonElementTypes.R_CURLY);
|
||||
if (trailingComma != null) {
|
||||
holder.registerProblem(trailingComma, JsonBundle.message("inspection.compliance.msg.trailing.comma"));
|
||||
}
|
||||
super.visitObject(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitValue(@NotNull JsonValue value) {
|
||||
if (value.getContainingFile() instanceof JsonFile) {
|
||||
final JsonFile jsonFile = (JsonFile)value.getContainingFile();
|
||||
if (myWarnAboutMultipleTopLevelValues && value.getParent() == jsonFile && value != jsonFile.getTopLevelValue()) {
|
||||
holder.registerProblem(value, JsonBundle.message("inspection.compliance.msg.multiple.top.level.values"));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!JsonDialectUtil.isStandardJson(holder.getFile())) return PsiElementVisitor.EMPTY_VISITOR;
|
||||
return new StandardJsonValidatingElementVisitor(holder);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -200,4 +140,87 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool {
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
protected class StandardJsonValidatingElementVisitor extends JsonElementVisitor {
|
||||
private final ProblemsHolder myHolder;
|
||||
|
||||
public StandardJsonValidatingElementVisitor(ProblemsHolder holder) {myHolder = holder;}
|
||||
|
||||
protected boolean allowComments() { return false; }
|
||||
protected boolean allowSingleQuotes() { return false; }
|
||||
protected boolean allowIdentifierPropertyNames() { return false; }
|
||||
protected boolean allowTrailingCommas() { return false; }
|
||||
|
||||
protected boolean isValidPropertyName(@NotNull PsiElement literal) {
|
||||
return literal instanceof JsonLiteral && JsonPsiUtil.getElementTextWithoutHostEscaping(literal).startsWith("\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitComment(PsiComment comment) {
|
||||
if (!allowComments() && myWarnAboutComments) {
|
||||
if (JsonStandardComplianceProvider.shouldWarnAboutComment(comment)) {
|
||||
myHolder.registerProblem(comment, JsonBundle.message("inspection.compliance.msg.comments"), ProblemHighlightType.WEAK_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitStringLiteral(@NotNull JsonStringLiteral stringLiteral) {
|
||||
if (!allowSingleQuotes() && JsonPsiUtil.getElementTextWithoutHostEscaping(stringLiteral).startsWith("'")) {
|
||||
myHolder.registerProblem(stringLiteral, JsonBundle.message("inspection.compliance.msg.single.quoted.strings"),
|
||||
new AddDoubleQuotesFix());
|
||||
}
|
||||
// May be illegal property key as well
|
||||
super.visitStringLiteral(stringLiteral);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLiteral(@NotNull JsonLiteral literal) {
|
||||
if (JsonPsiUtil.isPropertyKey(literal) && !isValidPropertyName(literal)) {
|
||||
myHolder.registerProblem(literal, JsonBundle.message("inspection.compliance.msg.illegal.property.key"), new AddDoubleQuotesFix());
|
||||
}
|
||||
super.visitLiteral(literal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull JsonReferenceExpression reference) {
|
||||
if (!allowIdentifierPropertyNames() || !JsonPsiUtil.isPropertyKey(reference) || !isValidPropertyName(reference)) {
|
||||
myHolder.registerProblem(reference, JsonBundle.message("inspection.compliance.msg.bad.token"), new AddDoubleQuotesFix());
|
||||
}
|
||||
// May be illegal property key as well
|
||||
super.visitReferenceExpression(reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArray(@NotNull JsonArray array) {
|
||||
if (!allowTrailingCommas()) {
|
||||
final PsiElement trailingComma = findTrailingComma(array, JsonElementTypes.R_BRACKET);
|
||||
if (trailingComma != null) {
|
||||
myHolder.registerProblem(trailingComma, JsonBundle.message("inspection.compliance.msg.trailing.comma"));
|
||||
}
|
||||
}
|
||||
super.visitArray(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitObject(@NotNull JsonObject object) {
|
||||
if (!allowTrailingCommas()) {
|
||||
final PsiElement trailingComma = findTrailingComma(object, JsonElementTypes.R_CURLY);
|
||||
if (trailingComma != null) {
|
||||
myHolder.registerProblem(trailingComma, JsonBundle.message("inspection.compliance.msg.trailing.comma"));
|
||||
}
|
||||
}
|
||||
super.visitObject(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitValue(@NotNull JsonValue value) {
|
||||
if (value.getContainingFile() instanceof JsonFile) {
|
||||
final JsonFile jsonFile = (JsonFile)value.getContainingFile();
|
||||
if (myWarnAboutMultipleTopLevelValues && value.getParent() == jsonFile && value != jsonFile.getTopLevelValue()) {
|
||||
myHolder.registerProblem(value, JsonBundle.message("inspection.compliance.msg.multiple.top.level.values"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.codeinsight;
|
||||
|
||||
import com.intellij.json.JsonBundle;
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class StandardJsonLiteralChecker implements JsonLiteralChecker {
|
||||
private static final Pattern VALID_ESCAPE = Pattern.compile("\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4})");
|
||||
private static final Pattern VALID_NUMBER_LITERAL = Pattern.compile("-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?");
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getErrorForNumericLiteral(String literalText) {
|
||||
if (!VALID_NUMBER_LITERAL.matcher(literalText).matches()) {
|
||||
return JsonBundle.message("syntax.error.illegal.floating.point.literal");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getErrorForStringFragment(String fragmentText) {
|
||||
return getStringError(fragmentText);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getStringError(String fragmentText) {
|
||||
if (fragmentText.startsWith("\\") && fragmentText.length() > 1 && !VALID_ESCAPE.matcher(fragmentText).matches()) {
|
||||
if (fragmentText.startsWith("\\u")) {
|
||||
return JsonBundle.message("syntax.error.illegal.unicode.escape.sequence");
|
||||
}
|
||||
else {
|
||||
return JsonBundle.message("syntax.error.illegal.escape.sequence");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(PsiElement element) {
|
||||
return JsonDialectUtil.isStandardJson(element);
|
||||
}
|
||||
}
|
||||
@@ -54,10 +54,9 @@ public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
|
||||
return new MyHighlighter();
|
||||
}
|
||||
|
||||
private static class MyHighlighter extends SyntaxHighlighterBase {
|
||||
private static final Map<IElementType, TextAttributesKey> ourAttributes = new HashMap<>();
|
||||
|
||||
static {
|
||||
private class MyHighlighter extends SyntaxHighlighterBase {
|
||||
private final Map<IElementType, TextAttributesKey> ourAttributes = new HashMap<>();
|
||||
{
|
||||
fillMap(ourAttributes, JSON_BRACES, JsonElementTypes.L_CURLY, JsonElementTypes.R_CURLY);
|
||||
fillMap(ourAttributes, JSON_BRACKETS, JsonElementTypes.L_BRACKET, JsonElementTypes.R_BRACKET);
|
||||
fillMap(ourAttributes, JSON_COMMA, JsonElementTypes.COMMA);
|
||||
@@ -80,10 +79,10 @@ public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
|
||||
@NotNull
|
||||
@Override
|
||||
public Lexer getHighlightingLexer() {
|
||||
LayeredLexer layeredLexer = new LayeredLexer(new JsonLexer());
|
||||
layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\"', JsonElementTypes.DOUBLE_QUOTED_STRING, false, "/", false, false),
|
||||
LayeredLexer layeredLexer = new LayeredLexer(getLexer());
|
||||
layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\"', JsonElementTypes.DOUBLE_QUOTED_STRING, isCanEscapeEol(), "/", false, false),
|
||||
new IElementType[]{JsonElementTypes.DOUBLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY);
|
||||
layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\'', JsonElementTypes.SINGLE_QUOTED_STRING, false, "/", false, false),
|
||||
layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\'', JsonElementTypes.SINGLE_QUOTED_STRING, isCanEscapeEol(), "/", false, false),
|
||||
new IElementType[]{JsonElementTypes.SINGLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY);
|
||||
return layeredLexer;
|
||||
}
|
||||
@@ -94,4 +93,13 @@ public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
|
||||
return pack(ourAttributes.get(type));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Lexer getLexer() {
|
||||
return new JsonLexer();
|
||||
}
|
||||
|
||||
protected boolean isCanEscapeEol() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.json.JsonFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5FileType extends JsonFileType {
|
||||
public static final Json5FileType INSTANCE = new Json5FileType();
|
||||
public static final String DEFAULT_EXTENSION = "json5";
|
||||
|
||||
public Json5FileType() {
|
||||
super(Json5Language.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "JSON5";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "JSON5 files";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDefaultExtension() {
|
||||
return DEFAULT_EXTENSION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileTypeConsumer;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5FileTypeFactory extends FileTypeFactory {
|
||||
@Override
|
||||
public void createFileTypes(@NotNull FileTypeConsumer consumer) {
|
||||
consumer.consume(Json5FileType.INSTANCE, Json5FileType.DEFAULT_EXTENSION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.json.JsonLanguage;
|
||||
|
||||
public class Json5Language extends JsonLanguage {
|
||||
public static final Json5Language INSTANCE = new Json5Language();
|
||||
|
||||
protected Json5Language() {
|
||||
super("JSON5", "application/json5");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.lexer.FlexAdapter;
|
||||
|
||||
public class Json5Lexer extends FlexAdapter {
|
||||
public Json5Lexer() {
|
||||
super(new _Json5Lexer());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.json.JsonParserDefinition;
|
||||
import com.intellij.json.psi.impl.JsonFileImpl;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.tree.IFileElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5ParserDefinition extends JsonParserDefinition {
|
||||
public static final IFileElementType FILE = new IFileElementType(Json5Language.INSTANCE);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Lexer createLexer(Project project) {
|
||||
return new Json5Lexer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile createFile(FileViewProvider fileViewProvider) {
|
||||
return new JsonFileImpl(fileViewProvider, Json5Language.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFileElementType getFileNodeType() {
|
||||
return FILE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionUtil;
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker;
|
||||
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalkerFactory;
|
||||
import com.jetbrains.jsonSchema.impl.JsonOriginalPsiWalker;
|
||||
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5PsiWalkerFactory implements JsonLikePsiWalkerFactory {
|
||||
@Override
|
||||
public boolean handles(@NotNull PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent == null) return false;
|
||||
return JsonDialectUtil.getLanguage(CompletionUtil.getOriginalOrSelf(parent)) == Json5Language.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsonLikePsiWalker create(@NotNull JsonSchemaObject schemaObject) {
|
||||
return new JsonOriginalPsiWalker() {
|
||||
@Override
|
||||
public boolean isNameQuoted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlyDoubleQuotesForStringLiterals() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import static com.intellij.psi.TokenType.BAD_CHARACTER;
|
||||
import static com.intellij.psi.TokenType.WHITE_SPACE;
|
||||
import static com.intellij.json.JsonElementTypes.*;
|
||||
|
||||
%%
|
||||
|
||||
%{
|
||||
public _Json5Lexer() {
|
||||
this((java.io.Reader)null);
|
||||
}
|
||||
%}
|
||||
|
||||
%public
|
||||
%class _Json5Lexer
|
||||
%implements FlexLexer
|
||||
%function advance
|
||||
%type IElementType
|
||||
%unicode
|
||||
|
||||
EOL=\R
|
||||
WHITE_SPACE=\s+
|
||||
HEX_DIGIT=[0-9A-Fa-f]
|
||||
|
||||
LINE_COMMENT="//".*
|
||||
BLOCK_COMMENT="/"\*([^*]|\*+[^*/])*(\*+"/")?
|
||||
LINE_TERMINATOR_SEQUENCE=\R
|
||||
CRLF= [\ \t \f]* {LINE_TERMINATOR_SEQUENCE}
|
||||
DOUBLE_QUOTED_STRING=\"([^\\\"\r\n]|\\[^\r\n]|\\{CRLF})*\"?
|
||||
SINGLE_QUOTED_STRING='([^\\'\r\n]|\\[^\r\n]|\\{CRLF})*'?
|
||||
JSON5_NUMBER=(\+|-)?(0|[1-9][0-9]*)?\.?([0-9]+)?([eE][+-]?[0-9]*)?
|
||||
HEX_DIGITS=({HEX_DIGIT})+
|
||||
HEX_INTEGER_LITERAL=0[Xx]({HEX_DIGITS})
|
||||
NUMBER={JSON5_NUMBER}|{HEX_INTEGER_LITERAL}|Infinity|-Infinity|\+Infinity|NaN|-NaN|\+NaN
|
||||
IDENTIFIER=[[:jletterdigit:]~!()*\-."/"@\^<>=]+
|
||||
|
||||
%%
|
||||
<YYINITIAL> {
|
||||
{WHITE_SPACE} { return WHITE_SPACE; }
|
||||
|
||||
"{" { return L_CURLY; }
|
||||
"}" { return R_CURLY; }
|
||||
"[" { return L_BRACKET; }
|
||||
"]" { return R_BRACKET; }
|
||||
"," { return COMMA; }
|
||||
":" { return COLON; }
|
||||
"true" { return TRUE; }
|
||||
"false" { return FALSE; }
|
||||
"null" { return NULL; }
|
||||
|
||||
{LINE_COMMENT} { return LINE_COMMENT; }
|
||||
{BLOCK_COMMENT} { return BLOCK_COMMENT; }
|
||||
{DOUBLE_QUOTED_STRING} { return DOUBLE_QUOTED_STRING; }
|
||||
{SINGLE_QUOTED_STRING} { return SINGLE_QUOTED_STRING; }
|
||||
{NUMBER} { return NUMBER; }
|
||||
{IDENTIFIER} { return IDENTIFIER; }
|
||||
|
||||
}
|
||||
|
||||
[^] { return BAD_CHARACTER; }
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5.codeinsight;
|
||||
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.json.codeinsight.JsonLiteralChecker;
|
||||
import com.intellij.json.codeinsight.StandardJsonLiteralChecker;
|
||||
import com.intellij.json.json5.Json5Language;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Json5JsonLiteralChecker implements JsonLiteralChecker {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getErrorForNumericLiteral(String literalText) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getErrorForStringFragment(String fragmentText) {
|
||||
if (fragmentText.startsWith("\\") && fragmentText.length() > 1 && fragmentText.endsWith("\n")) {
|
||||
if (StringUtil.isEmptyOrSpaces(fragmentText.substring(1, fragmentText.length() - 1))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return StandardJsonLiteralChecker.getStringError(fragmentText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(PsiElement element) {
|
||||
return JsonDialectUtil.getLanguage(element) == Json5Language.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5.codeinsight;
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.json.JsonBundle;
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.json.codeinsight.JsonStandardComplianceInspection;
|
||||
import com.intellij.json.psi.JsonLiteral;
|
||||
import com.intellij.json.psi.JsonPsiUtil;
|
||||
import com.intellij.json.psi.JsonReferenceExpression;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5StandardComplianceInspection extends JsonStandardComplianceInspection {
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return JsonBundle.message("inspection.compliance5.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
if (JsonDialectUtil.isStandardJson(holder.getFile())) return PsiElementVisitor.EMPTY_VISITOR;
|
||||
return new StandardJson5ValidatingElementVisitor(holder);
|
||||
}
|
||||
|
||||
private class StandardJson5ValidatingElementVisitor extends StandardJsonValidatingElementVisitor {
|
||||
public StandardJson5ValidatingElementVisitor(ProblemsHolder holder) {
|
||||
super(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowComments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowSingleQuotes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowIdentifierPropertyNames() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowTrailingCommas() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isValidPropertyName(@NotNull PsiElement literal) {
|
||||
if (literal instanceof JsonLiteral) {
|
||||
String textWithoutHostEscaping = JsonPsiUtil.getElementTextWithoutHostEscaping(literal);
|
||||
return textWithoutHostEscaping.startsWith("\"") || textWithoutHostEscaping.startsWith("'");
|
||||
}
|
||||
if (literal instanceof JsonReferenceExpression) {
|
||||
return StringUtil.isJavaIdentifier(literal.getText());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5.highlighting;
|
||||
|
||||
import com.intellij.json.highlighting.JsonSyntaxHighlighterFactory;
|
||||
import com.intellij.json.json5.Json5Lexer;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Json5SyntaxHighlightingFactory extends JsonSyntaxHighlighterFactory {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Lexer getLexer() {
|
||||
return new Json5Lexer();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCanEscapeEol() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.intellij.json.psi.impl;
|
||||
|
||||
import com.intellij.extapi.psi.PsiFileBase;
|
||||
import com.intellij.json.JsonLanguage;
|
||||
import com.intellij.json.psi.JsonFile;
|
||||
import com.intellij.json.psi.JsonValue;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -14,8 +14,8 @@ import java.util.List;
|
||||
|
||||
public class JsonFileImpl extends PsiFileBase implements JsonFile {
|
||||
|
||||
public JsonFileImpl(FileViewProvider fileViewProvider) {
|
||||
super(fileViewProvider, JsonLanguage.INSTANCE);
|
||||
public JsonFileImpl(FileViewProvider fileViewProvider, Language language) {
|
||||
super(fileViewProvider, language);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.jsonSchema.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionUtil;
|
||||
import com.intellij.json.JsonDialectUtil;
|
||||
import com.intellij.json.JsonElementTypes;
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -28,7 +30,9 @@ public class JsonOriginalPsiWalker implements JsonLikePsiWalker {
|
||||
public static final JsonOriginalPsiWalker INSTANCE = new JsonOriginalPsiWalker();
|
||||
|
||||
public boolean handles(@NotNull PsiElement element) {
|
||||
return element instanceof JsonElement || element instanceof LeafPsiElement && element.getParent() instanceof JsonElement;
|
||||
PsiElement parent = element.getParent();
|
||||
return parent != null && (element instanceof JsonElement || element instanceof LeafPsiElement && parent instanceof JsonElement)
|
||||
&& JsonDialectUtil.isStandardJson(CompletionUtil.getOriginalOrSelf(parent));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,7 +142,7 @@ public class JsonOriginalPsiWalker implements JsonLikePsiWalker {
|
||||
final JsonObject object = PsiTreeUtil.getParentOfType(element, JsonObject.class);
|
||||
if (object != null) {
|
||||
return object.getPropertyList().stream()
|
||||
.filter(p -> p.getNameElement() instanceof JsonStringLiteral)
|
||||
.filter(p -> !isNameQuoted() || p.getNameElement() instanceof JsonStringLiteral)
|
||||
.map(p -> StringUtil.unquoteString(p.getName())).collect(Collectors.toSet());
|
||||
}
|
||||
return Collections.emptySet();
|
||||
|
||||
@@ -6,14 +6,11 @@ import com.intellij.json.codeinsight.JsonStandardComplianceInspection;
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class JsonHighlightingTest extends JsonTestCase {
|
||||
public class JsonHighlightingTest extends JsonHighlightingTestBase {
|
||||
|
||||
private void doTest() {
|
||||
doTestHighlighting(true, true, true);
|
||||
}
|
||||
|
||||
private long doTestHighlighting(boolean checkInfo, boolean checkWeakWarning, boolean checkWarning) {
|
||||
return myFixture.testHighlighting(checkWarning, checkInfo, checkWeakWarning, "/highlighting/" + getTestName(false) + ".json");
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "json";
|
||||
}
|
||||
|
||||
private void enableStandardComplianceInspection(boolean checkComments, boolean checkTopLevelValues) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json;
|
||||
|
||||
public abstract class JsonHighlightingTestBase extends JsonTestCase {
|
||||
protected void doTest() {
|
||||
doTestHighlighting(true, true, true);
|
||||
}
|
||||
|
||||
protected abstract String getExtension();
|
||||
|
||||
protected void doTestHighlighting(boolean checkInfo, boolean checkWeakWarning, boolean checkWarning) {
|
||||
myFixture.testHighlighting(checkWarning, checkInfo, checkWeakWarning, "/highlighting/" + getTestName(false) + "." + getExtension());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.json.JsonHighlightingTestBase;
|
||||
import com.intellij.json.json5.codeinsight.Json5StandardComplianceInspection;
|
||||
|
||||
public class Json5HighlightingTest extends JsonHighlightingTestBase {
|
||||
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "json5";
|
||||
}
|
||||
|
||||
public void testJSON5() {
|
||||
myFixture.enableInspections(new Json5StandardComplianceInspection());
|
||||
doTestHighlighting(false, true, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.json.json5;
|
||||
|
||||
import com.intellij.json.JsonParserDefinition;
|
||||
import com.intellij.testFramework.ParsingTestCase;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
|
||||
@TestDataPath("$CONTENT_ROOT/testData/psi/")
|
||||
public class Json5ParsingTest extends ParsingTestCase {
|
||||
public Json5ParsingTest() {
|
||||
super("psi", "json5", new Json5ParserDefinition(), new JsonParserDefinition());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PlatformTestUtil.getCommunityPath() + "/json/tests/testData";
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testJson5Syntax() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.jsonSchema.json5;
|
||||
|
||||
import com.jetbrains.jsonSchema.impl.JsonBySchemaCompletionBaseTest;
|
||||
|
||||
public class Json5ByJsonSchemaCompletionTest extends JsonBySchemaCompletionBaseTest {
|
||||
public void testTopLevel() throws Exception {
|
||||
testBySchema("{\"properties\": {\"prima\": {}, \"proto\": {}, \"primus\": {}}}", "{pri<caret>}", "json5", "prima", "primus", "proto");
|
||||
}
|
||||
|
||||
public void testAlreadyInsertedProperty() throws Exception {
|
||||
testBySchema("{\"properties\": {\"prima\": {}, \"proto\": {}, \"primus\": {}}}", "{prima: 1, pri<caret>}", "json5", "primus", "proto");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// no errors in this file!
|
||||
{
|
||||
foo: 'bar',
|
||||
while: true,
|
||||
|
||||
this: 'is a \
|
||||
multi-line string',
|
||||
|
||||
// this is an inline comment
|
||||
here: 'is another', // inline comment
|
||||
|
||||
/* this is a block comment
|
||||
that continues on another line */
|
||||
|
||||
hex: 0xDEADbeef,
|
||||
half: .5,
|
||||
delta: +10,
|
||||
to: Infinity, // and beyond!
|
||||
|
||||
finally: 'a trailing comma',
|
||||
oh: [
|
||||
"we shouldn't forget",
|
||||
'arrays can have',
|
||||
'trailing commas too',
|
||||
],
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
foo: 'bar',
|
||||
while: true,
|
||||
|
||||
this: 'is a \
|
||||
multi-line string',
|
||||
|
||||
// this is an inline comment
|
||||
here: 'is another', // inline comment
|
||||
|
||||
/* this is a block comment
|
||||
that continues on another line */
|
||||
|
||||
hex: 0xDEADbeef,
|
||||
half: .5,
|
||||
delta: +10,
|
||||
to: Infinity, // and beyond!
|
||||
|
||||
finally: 'a trailing comma',
|
||||
oh: [
|
||||
"we shouldn't forget",
|
||||
'arrays can have',
|
||||
'trailing commas too',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
JsonFile: Json5Syntax.json5
|
||||
JsonObject
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''bar'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('while')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonBooleanLiteral
|
||||
PsiElement(true)('true')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('this')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''is a \\nmulti-line string'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(LINE_COMMENT)('// this is an inline comment')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('here')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''is another'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(LINE_COMMENT)('// inline comment')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiComment(BLOCK_COMMENT)('/* this is a block comment\n that continues on another line */')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('hex')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNumberLiteral
|
||||
PsiElement(NUMBER)('0xDEADbeef')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('half')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNumberLiteral
|
||||
PsiElement(NUMBER)('.5')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('delta')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNumberLiteral
|
||||
PsiElement(NUMBER)('+10')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('to')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonNumberLiteral
|
||||
PsiElement(NUMBER)('Infinity')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiComment(LINE_COMMENT)('// and beyond!')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('finally')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''a trailing comma'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonProperty
|
||||
JsonReferenceExpression
|
||||
PsiElement(IDENTIFIER)('oh')
|
||||
PsiElement(:)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
JsonArray
|
||||
PsiElement([)('[')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonStringLiteral
|
||||
PsiElement(DOUBLE_QUOTED_STRING)('"we shouldn't forget"')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''arrays can have'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
JsonStringLiteral
|
||||
PsiElement(SINGLE_QUOTED_STRING)(''trailing commas too'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(])(']')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(})('}')
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<fileTypeFactory implementation="com.intellij.json.JsonFileTypeFactory"/>
|
||||
<fileTypeFactory implementation="com.intellij.json.json5.Json5FileTypeFactory"/>
|
||||
<iconProvider implementation="com.jetbrains.jsonSchema.JsonSchemaIconProvider"/>
|
||||
<lang.parserDefinition language="JSON" implementationClass="com.intellij.json.JsonParserDefinition"/>
|
||||
<lang.parserDefinition language="JSON5" implementationClass="com.intellij.json.json5.Json5ParserDefinition"/>
|
||||
<lang.syntaxHighlighterFactory language="JSON" implementationClass="com.intellij.json.highlighting.JsonSyntaxHighlighterFactory"/>
|
||||
<lang.syntaxHighlighterFactory language="JSON5" implementationClass="com.intellij.json.json5.highlighting.Json5SyntaxHighlightingFactory"/>
|
||||
<psi.treeChangePreprocessor implementation="com.intellij.json.psi.impl.JsonTreeChangePreprocessor"/>
|
||||
|
||||
<!-- Code style and formatting -->
|
||||
@@ -48,6 +51,9 @@
|
||||
<extendWordSelectionHandler implementation="com.intellij.json.editor.selection.JsonStringLiteralSelectionHandler"/>
|
||||
<basicWordSelectionFilter implementation="com.intellij.json.editor.selection.JsonBasicWordSelectionFilter"/>
|
||||
|
||||
<json.jsonLiteralChecker implementation="com.intellij.json.codeinsight.StandardJsonLiteralChecker"/>
|
||||
<json.jsonLiteralChecker implementation="com.intellij.json.json5.codeinsight.Json5JsonLiteralChecker"/>
|
||||
|
||||
<!-- Annotators -->
|
||||
<annotator language="JSON" implementationClass="com.intellij.json.codeinsight.JsonLiteralAnnotator"/>
|
||||
|
||||
@@ -56,6 +62,10 @@
|
||||
bundle="com.intellij.json.JsonBundle" key="inspection.compliance.name" groupKey="json.inspection.group"
|
||||
enabledByDefault="true" level="ERROR"
|
||||
implementationClass="com.intellij.json.codeinsight.JsonStandardComplianceInspection"/>
|
||||
<localInspection language="JSON5" shortName="Json5StandardCompliance"
|
||||
bundle="com.intellij.json.JsonBundle" key="inspection.compliance5.name" groupKey="json.inspection5.group"
|
||||
enabledByDefault="true" level="ERROR"
|
||||
implementationClass="com.intellij.json.json5.codeinsight.Json5StandardComplianceInspection"/>
|
||||
<localInspection language="JSON" shortName="JsonDuplicatePropertyKeys"
|
||||
bundle="com.intellij.json.JsonBundle" key="inspection.duplicate.keys.name" groupKey="json.inspection.group"
|
||||
enabledByDefault="true" level="WARNING"
|
||||
@@ -83,11 +93,16 @@
|
||||
<JsonSchema.ProviderFactory implementation="com.jetbrains.jsonSchema.extension.JsonSchemaProjectSelfProviderFactory"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="Json">
|
||||
<Like.Psi.Walker.Factory implementation="com.intellij.json.json5.Json5PsiWalkerFactory"/>
|
||||
</extensions>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="com.intellij.json.jsonStandardComplianceProvider"
|
||||
interface="com.intellij.json.codeinsight.JsonStandardComplianceProvider"/>
|
||||
<extensionPoint qualifiedName="JavaScript.JsonSchema.ProviderFactory" interface="com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory"/>
|
||||
<extensionPoint qualifiedName="Json.Like.Psi.Walker.Factory" interface="com.jetbrains.jsonSchema.extension.JsonLikePsiWalkerFactory"/>
|
||||
<extensionPoint qualifiedName="com.intellij.json.jsonLiteralChecker" interface="com.intellij.json.codeinsight.JsonLiteralChecker"/>
|
||||
</extensionPoints>
|
||||
|
||||
</idea-plugin>
|
||||
Reference in New Issue
Block a user