diff --git a/json/json.iml b/json/json.iml index 465edb1c2347..558f2e07197d 100644 --- a/json/json.iml +++ b/json/json.iml @@ -14,6 +14,6 @@ + - - + \ No newline at end of file diff --git a/json/src/com/intellij/json/JsonSyntaxHighlighterFactory.java b/json/src/com/intellij/json/JsonSyntaxHighlighterFactory.java deleted file mode 100644 index 3fa4584f25d3..000000000000 --- a/json/src/com/intellij/json/JsonSyntaxHighlighterFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.intellij.json; - -import com.intellij.lexer.LayeredLexer; -import com.intellij.lexer.Lexer; -import com.intellij.lexer.StringLiteralLexer; -import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; -import com.intellij.openapi.editor.HighlighterColors; -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.TokenType; -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.intellij.json.JsonElementTypes.*; -import static com.intellij.psi.StringEscapesTokenTypes.*; - -public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory { - @NotNull - @Override - public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile) { - return new MyHighlighter(); - } - - private static class MyHighlighter extends SyntaxHighlighterBase { - private static final Map ourAttributes = new HashMap(); - - static { - fillMap(ourAttributes, DefaultLanguageHighlighterColors.BRACES, L_CURLY, R_CURLY); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.BRACKETS, L_BRACKET, R_BRACKET); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.COMMA, COMMA); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.SEMICOLON, COLON); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.STRING, DOUBLE_QUOTED_STRING); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.STRING, SINGLE_QUOTED_STRING); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.NUMBER, NUMBER); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.KEYWORD, TRUE, FALSE, NULL); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.LINE_COMMENT, LINE_COMMENT); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.BLOCK_COMMENT, BLOCK_COMMENT); - // TODO may be it's worth to add more sensible highlighting for identifiers - fillMap(ourAttributes, HighlighterColors.TEXT, INDENTIFIER); - fillMap(ourAttributes, HighlighterColors.BAD_CHARACTER, TokenType.BAD_CHARACTER); - - // StringLexer's tokens - fillMap(ourAttributes, DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE, VALID_STRING_ESCAPE_TOKEN); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE, INVALID_CHARACTER_ESCAPE_TOKEN); - fillMap(ourAttributes, DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE, INVALID_UNICODE_ESCAPE_TOKEN); - } - - @NotNull - @Override - public Lexer getHighlightingLexer() { - LayeredLexer layeredLexer = new LayeredLexer(new JsonLexer()); - layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\"', DOUBLE_QUOTED_STRING, false, "/", false, false), - new IElementType[]{DOUBLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY); - layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\'', SINGLE_QUOTED_STRING, false, "/", false, false), - new IElementType[]{SINGLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY); - return layeredLexer; - } - - @NotNull - @Override - public TextAttributesKey[] getTokenHighlights(IElementType type) { - return pack(ourAttributes.get(type)); - } - } -} diff --git a/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java b/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java index 335bb12c0e48..71025f4ab33d 100644 --- a/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java +++ b/json/src/com/intellij/json/codeinsight/JsonLiteralAnnotator.java @@ -1,13 +1,13 @@ package com.intellij.json.codeinsight; 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.JsonStringLiteral; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; @@ -23,7 +23,7 @@ public class JsonLiteralAnnotator implements Annotator { private static final Pattern VALID_ESCAPE = Pattern.compile("\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4})"); private static final Pattern VALID_NUMBER_LITERAL = Pattern.compile("-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?"); - private static boolean debug = ApplicationManager.getApplication().isUnitTestMode(); + private static final boolean DEBUG = ApplicationManager.getApplication().isUnitTestMode(); @Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { @@ -31,8 +31,7 @@ public class JsonLiteralAnnotator implements Annotator { final JsonStringLiteral stringLiteral = (JsonStringLiteral)element; final int elementOffset = element.getTextOffset(); if (JsonPsiUtil.isPropertyKey(element)) { - holder.createInfoAnnotation(element, debug ? "instance field" : null).setTextAttributes( - DefaultLanguageHighlighterColors.INSTANCE_FIELD); + holder.createInfoAnnotation(element, DEBUG ? "property key" : null).setTextAttributes(JsonSyntaxHighlighterFactory.JSON_PROPERTY_KEY); } final String text = element.getText(); final int length = text.length(); diff --git a/json/src/com/intellij/json/highlighting/JsonColorsPage.java b/json/src/com/intellij/json/highlighting/JsonColorsPage.java new file mode 100644 index 000000000000..e68c12f422fa --- /dev/null +++ b/json/src/com/intellij/json/highlighting/JsonColorsPage.java @@ -0,0 +1,106 @@ +package com.intellij.json.highlighting; + +import com.google.common.collect.ImmutableMap; +import com.intellij.application.options.colors.InspectionColorSettingsPage; +import com.intellij.icons.AllIcons; +import com.intellij.json.JsonLanguage; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import com.intellij.psi.codeStyle.DisplayPriority; +import com.intellij.psi.codeStyle.DisplayPrioritySortable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Map; + +import static com.intellij.json.highlighting.JsonSyntaxHighlighterFactory.*; + +/** + * @author Mikhail Golubev + */ +public class JsonColorsPage implements ColorSettingsPage, InspectionColorSettingsPage, DisplayPrioritySortable { + private static final Map ourAdditionalHighlighting = ImmutableMap.of("propertyKey", JSON_PROPERTY_KEY); + + private static final AttributesDescriptor[] ourAttributeDescriptors = new AttributesDescriptor[]{ + new AttributesDescriptor("Property key", JSON_PROPERTY_KEY), + + new AttributesDescriptor("Braces", JSON_BRACES), + new AttributesDescriptor("Brackets", JSON_BRACKETS), + new AttributesDescriptor("Comma", JSON_COMMA), + new AttributesDescriptor("Colon", JSON_COLON), + new AttributesDescriptor("Number", JSON_NUMBER), + new AttributesDescriptor("String", JSON_STRING), + new AttributesDescriptor("Keyword", JSON_KEYWORD), + new AttributesDescriptor("Line comment", JSON_LINE_COMMENT), + new AttributesDescriptor("Block comment", JSON_BLOCK_COMMENT), + //new AttributesDescriptor("", JSON_IDENTIFIER), + new AttributesDescriptor("Valid escape sequence", JSON_VALID_ESCAPE), + new AttributesDescriptor("Invalid escape sequence", JSON_INVALID_ESCAPE), + }; + + @Nullable + @Override + public Icon getIcon() { + return AllIcons.FileTypes.Json; + } + + @NotNull + @Override + public SyntaxHighlighter getHighlighter() { + return SyntaxHighlighterFactory.getSyntaxHighlighter(JsonLanguage.INSTANCE, null, null); + } + + @NotNull + @Override + public String getDemoText() { + return "{\n" + + " // Line comments are not included in standard but nonetheless allowed.\n" + + " /* As well as block comments. */\n" + + " \"the only keywords are\": [true, false, null],\n" + + " \"strings with\": {\n" + + " \"no excapes\": \"pseudopolinomiality\"\n" + + " \"valid escapes\": \"C-style\\r\\n and unicode\\u0021\",\n" + + " \"illegal escapes\": \"\\0377\\x\\\"\n" + + " },\n" + + " \"some numbers\": [\n" + + " 42,\n" + + " -0.0e-0,\n" + + " 6.626e-34\n" + + " ] \n" + + "}"; + } + + @Nullable + @Override + public Map getAdditionalHighlightingTagToDescriptorMap() { + return ourAdditionalHighlighting; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return ourAttributeDescriptors; + } + + @NotNull + @Override + public ColorDescriptor[] getColorDescriptors() { + return ColorDescriptor.EMPTY_ARRAY; + } + + @NotNull + @Override + public String getDisplayName() { + return "JSON"; + } + + @Override + public DisplayPriority getPriority() { + return DisplayPriority.LANGUAGE_SETTINGS; + } +} diff --git a/json/src/com/intellij/json/highlighting/JsonSyntaxHighlighterFactory.java b/json/src/com/intellij/json/highlighting/JsonSyntaxHighlighterFactory.java new file mode 100644 index 000000000000..0dc57070dda4 --- /dev/null +++ b/json/src/com/intellij/json/highlighting/JsonSyntaxHighlighterFactory.java @@ -0,0 +1,97 @@ +package com.intellij.json.highlighting; + +import com.intellij.json.JsonElementTypes; +import com.intellij.json.JsonLexer; +import com.intellij.lexer.LayeredLexer; +import com.intellij.lexer.Lexer; +import com.intellij.lexer.StringLiteralLexer; +import com.intellij.openapi.editor.HighlighterColors; +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.StringEscapesTokenTypes; +import com.intellij.psi.TokenType; +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.intellij.openapi.editor.DefaultLanguageHighlighterColors.*; + +public class JsonSyntaxHighlighterFactory extends SyntaxHighlighterFactory { + + public static final TextAttributesKey JSON_BRACKETS = TextAttributesKey.createTextAttributesKey("JSON.BRACKETS", BRACKETS); + public static final TextAttributesKey JSON_BRACES = TextAttributesKey.createTextAttributesKey("JSON.BRACES", BRACES); + public static final TextAttributesKey JSON_COMMA = TextAttributesKey.createTextAttributesKey("JSON.BRACES", COMMA); + public static final TextAttributesKey JSON_COLON = TextAttributesKey.createTextAttributesKey("JSON.COLON", SEMICOLON); + public static final TextAttributesKey JSON_NUMBER = TextAttributesKey.createTextAttributesKey("JSON.NUMBER", NUMBER); + public static final TextAttributesKey JSON_STRING = TextAttributesKey.createTextAttributesKey("JSON.STRING", STRING); + public static final TextAttributesKey JSON_KEYWORD = TextAttributesKey.createTextAttributesKey("JSON.KEYWORD", KEYWORD); + public static final TextAttributesKey JSON_LINE_COMMENT = TextAttributesKey.createTextAttributesKey("JSON.LINE_COMMENT", LINE_COMMENT); + public static final TextAttributesKey JSON_BLOCK_COMMENT = TextAttributesKey.createTextAttributesKey("JSON.BLOCK_COMMENT", BLOCK_COMMENT); + + // Artificial element type + public static final TextAttributesKey JSON_IDENTIFIER = TextAttributesKey.createTextAttributesKey("JSON.IDENTIFIER", IDENTIFIER); + + // Added by annotators + public static final TextAttributesKey JSON_PROPERTY_KEY = TextAttributesKey.createTextAttributesKey("JSON.PROPERTY_KEY", INSTANCE_FIELD); + + // String escapes + public static final TextAttributesKey JSON_VALID_ESCAPE = + TextAttributesKey.createTextAttributesKey("JSON.VALID_ESCAPE", VALID_STRING_ESCAPE); + public static final TextAttributesKey JSON_INVALID_ESCAPE = + TextAttributesKey.createTextAttributesKey("JSON.INVALID_ESCAPE", INVALID_STRING_ESCAPE); + + + @NotNull + @Override + public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile) { + return new MyHighlighter(); + } + + private static class MyHighlighter extends SyntaxHighlighterBase { + private static final Map ourAttributes = new HashMap(); + + static { + 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); + fillMap(ourAttributes, JSON_COLON, JsonElementTypes.COLON); + fillMap(ourAttributes, JSON_STRING, JsonElementTypes.DOUBLE_QUOTED_STRING); + fillMap(ourAttributes, JSON_STRING, JsonElementTypes.SINGLE_QUOTED_STRING); + fillMap(ourAttributes, JSON_NUMBER, JsonElementTypes.NUMBER); + fillMap(ourAttributes, JSON_KEYWORD, JsonElementTypes.TRUE, JsonElementTypes.FALSE, JsonElementTypes.NULL); + fillMap(ourAttributes, JSON_LINE_COMMENT, JsonElementTypes.LINE_COMMENT); + fillMap(ourAttributes, JSON_BLOCK_COMMENT, JsonElementTypes.BLOCK_COMMENT); + // TODO may be it's worth to add more sensible highlighting for identifiers + fillMap(ourAttributes, JSON_IDENTIFIER, JsonElementTypes.INDENTIFIER); + fillMap(ourAttributes, HighlighterColors.BAD_CHARACTER, TokenType.BAD_CHARACTER); + + fillMap(ourAttributes, JSON_VALID_ESCAPE, StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN); + fillMap(ourAttributes, JSON_INVALID_ESCAPE, StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN); + fillMap(ourAttributes, JSON_INVALID_ESCAPE, StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN); + } + + @NotNull + @Override + public Lexer getHighlightingLexer() { + LayeredLexer layeredLexer = new LayeredLexer(new JsonLexer()); + layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\"', JsonElementTypes.DOUBLE_QUOTED_STRING, false, "/", false, false), + new IElementType[]{JsonElementTypes.DOUBLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY); + layeredLexer.registerSelfStoppingLayer(new StringLiteralLexer('\'', JsonElementTypes.SINGLE_QUOTED_STRING, false, "/", false, false), + new IElementType[]{JsonElementTypes.SINGLE_QUOTED_STRING}, IElementType.EMPTY_ARRAY); + return layeredLexer; + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType type) { + return pack(ourAttributes.get(type)); + } + } +} diff --git a/json/tests/testData/highlighting/SemanticHighlighting.json b/json/tests/testData/highlighting/SemanticHighlighting.json index 66d55b3eec1d..07aa7fd4f4a9 100644 --- a/json/tests/testData/highlighting/SemanticHighlighting.json +++ b/json/tests/testData/highlighting/SemanticHighlighting.json @@ -1,3 +1,3 @@ { - "aaa":123 + "aaa":123 } \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index e54b5818dca7..62ade0b9a446 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -17,11 +17,12 @@ - + +