diff --git a/src/main/grammar/Aspect.bnf b/src/main/grammar/Aspect.bnf index de5d7962f16b7b1908d453908e075e55e24f717a..c471de69d420629910b673c403102346fda4d903 100644 --- a/src/main/grammar/Aspect.bnf +++ b/src/main/grammar/Aspect.bnf @@ -102,7 +102,7 @@ aspect_nested_class_declaration ::= modifiers class_declaration aspect_method_declaration ::= modifiers type_parameters? aspect_result_type IDENTIFIER DOT method_declarator (THROWS name_list)? (block | SEMICOLON) -aspect_refine_method_declaration ::= REFINE [IDENTIFIER] modifers type_parameters? aspect_result_type IDENTIFIER DOT method_declarator (THROWS name_list)? (block | SEMICOLON) +aspect_refine_method_declaration ::= REFINE [IDENTIFIER] modifiers type_parameters? aspect_result_type IDENTIFIER DOT method_declarator (THROWS name_list)? (block | SEMICOLON) aspect_constructor_declaration ::= modifiers IDENTIFIER DOT IDENTIFIER formal_parameters (THROWS name_list)? LBRACE JAVA_EXPLICIT_CONSTRUCTUR_BLOCK RBRACE @@ -190,7 +190,7 @@ expression ::= lambda_expression | ( conditional_expression (assignment_operator assignment_operator ::= ASSIGN | STARASSIGN | SLASHASSIGN | REMASSIGN | PLUSASSIGN | MINUSASSIGN | LSHIFTASSIGN | RSIGNEDSHIFTASSIGN | RUNSIGNEDSHIFTASSIGN | ANDASSIGN | XORASSIGN | ORASSIGN -conditional_expression ::= conditional_or_expression ( HOOK expression COLON conditional_expression)? +conditional_expression ::= conditional_or_expression ( QUESTIONMARK expression COLON conditional_expression)? conditional_or_expression ::= conditional_and_expression ( SC_OR expression COLON conditional_expression )* diff --git a/src/main/grammar/Aspect.flex b/src/main/grammar/Aspect.flex index 62522e2e366cb5b0f54b6697df6f6f67470ca994..8661742962d896a91f55986ca16e00600ffeb178 100644 --- a/src/main/grammar/Aspect.flex +++ b/src/main/grammar/Aspect.flex @@ -217,7 +217,7 @@ Identifier = [:jletter:] [:jletterdigit:]* "<" { return AspectTypes.LT; } "!" { return AspectTypes.BANG; } "~" { return AspectTypes.TILDE; } - "?" { return AspectTypes.HOOK; } + "?" { return AspectTypes.QUESTIONMARK; } ":" { return AspectTypes.COLON; } "==" { return AspectTypes.EQ; } "<=" { return AspectTypes.LE; } diff --git a/src/main/java/org/jastadd/tooling/aspect/AspectColorSettingsPage.java b/src/main/java/org/jastadd/tooling/aspect/AspectColorSettingsPage.java new file mode 100644 index 0000000000000000000000000000000000000000..84739a005fa10daf558ac231ec630dff95310fbf --- /dev/null +++ b/src/main/java/org/jastadd/tooling/aspect/AspectColorSettingsPage.java @@ -0,0 +1,91 @@ +package org.jastadd.tooling.aspect; + + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import org.jastadd.tooling.util.JastAddIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Map; + +public class AspectColorSettingsPage implements ColorSettingsPage { + + private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ + new AttributesDescriptor("Keyword", AspectSyntaxHighlighter.KEYWORD), + new AttributesDescriptor("Value-literal (true, false, null)", AspectSyntaxHighlighter.KEYWORD_LITERAL), + new AttributesDescriptor("Operator", AspectSyntaxHighlighter.OPERATOR), + new AttributesDescriptor("Comma", AspectSyntaxHighlighter.COMMA), + new AttributesDescriptor("Parenthesis", AspectSyntaxHighlighter.PARENTHESIS), + new AttributesDescriptor("Bracket", AspectSyntaxHighlighter.BRACKET), + new AttributesDescriptor("Brace", AspectSyntaxHighlighter.BRACE), + new AttributesDescriptor("Identifier", AspectSyntaxHighlighter.IDENTIFIER), + new AttributesDescriptor("Single-line comment", AspectSyntaxHighlighter.SINGLE_LINE_COMMENT), + new AttributesDescriptor("Block comment", AspectSyntaxHighlighter.MULTI_LINE_COMMENT), + new AttributesDescriptor("Doc-comment", AspectSyntaxHighlighter.FORMAL_COMMENT), + new AttributesDescriptor("Symbol", AspectSyntaxHighlighter.SYMBOL), + new AttributesDescriptor("Dot", AspectSyntaxHighlighter.DOT), + new AttributesDescriptor("Semicolon", AspectSyntaxHighlighter.SEMICOLON), + new AttributesDescriptor("Number", AspectSyntaxHighlighter.NUMBER), + new AttributesDescriptor("String literal", AspectSyntaxHighlighter.STRING_LITERAL), + new AttributesDescriptor("Character literal", AspectSyntaxHighlighter.CHARACTER_LITERAL), + new AttributesDescriptor("Bad value", AspectSyntaxHighlighter.BAD_CHARACTER) + }; + + @Nullable + @Override + public Icon getIcon() { + return JastAddIcons.FILE; + } + + @NotNull + @Override + public SyntaxHighlighter getHighlighter() { + return new AspectSyntaxHighlighter(); + } + + @NotNull + @Override + public String getDemoText() { + return "coll ArrayList<String> Program.errors();\n" + + "Div contributes\n" + + " \"Division by zero is not allowed!\"\n" + + " when getRight().isZero()\n" + + " to Program.errors();\n\n" + + "syn T A.x(int a) circular [bv];\n" + + "eq A.x(int a) = rv;\n\n" + + "inh T A.y(int a);\n" + + "eq C.getA().y(int a) {\n" + + " return Java-expr;\n" + + "}\n"; + } + + @Nullable + @Override + public Map<String, TextAttributesKey> getAdditionalHighlightingTagToDescriptorMap() { + return null; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return DESCRIPTORS; + } + + @NotNull + @Override + public ColorDescriptor[] getColorDescriptors() { + return ColorDescriptor.EMPTY_ARRAY; + } + + @NotNull + @Override + public String getDisplayName() { + return "Aspect"; + } + +} diff --git a/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighter.java b/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighter.java new file mode 100644 index 0000000000000000000000000000000000000000..f6a3c03147dfa3e1a48b0911fbef4e1f61b4764b --- /dev/null +++ b/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighter.java @@ -0,0 +1,176 @@ +package org.jastadd.tooling.aspect; + + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import org.jastadd.tooling.aspect.lexer.AspectLexerAdapter; +import org.jastadd.tooling.aspect.psi.AspectTypes; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey; + +public class AspectSyntaxHighlighter extends SyntaxHighlighterBase { + + private static final List<IElementType> javaKeywords = Arrays.asList( + AspectTypes.ABSTRACT, AspectTypes.BOOLEAN, AspectTypes.BYTE, AspectTypes.CHAR, AspectTypes.DOUBLE, + AspectTypes.EXTENDS, AspectTypes.FINAL, AspectTypes.FLOAT, AspectTypes.FOR, AspectTypes.IMPLEMENTS, + AspectTypes.IMPORT, AspectTypes.INSTANCEOF, AspectTypes.INT, AspectTypes.INTERFACE, AspectTypes.LONG, + AspectTypes.NATIVE, AspectTypes.NEW, AspectTypes.PRIVATE, AspectTypes.PROTECTED, AspectTypes.PUBLIC, + AspectTypes.SHORT, AspectTypes.STATIC, AspectTypes.STRICTFP, AspectTypes.SUPER, AspectTypes.SYNCHRONIZED, + AspectTypes.THIS, AspectTypes.THROWS, AspectTypes.TRANSIENT, AspectTypes.VOID, AspectTypes.VOLATILE); + // some java keywords are missing since they are not parsed by us + // assert break case catch class continue default do else enum finally if package return switch throw try while + + private static final List<IElementType> jastAddKeywords = Arrays.asList(AspectTypes.ASPECT, + AspectTypes.NTA, AspectTypes.CIRCULAR, AspectTypes.CONTRIBUTES, + AspectTypes.COLL, AspectTypes.CACHE, AspectTypes.EQUATION, + AspectTypes.INH, AspectTypes.SYN, + AspectTypes.UNCACHE, AspectTypes.REFINE, AspectTypes.REWRITE, + AspectTypes.TO, AspectTypes.WHEN, AspectTypes.WITH, + AspectTypes.ROOT, AspectTypes.LAZY, AspectTypes.EACH); + public static final TextAttributesKey KEYWORD = createTextAttributesKey("JASTADD_KEYWORD", DefaultLanguageHighlighterColors.KEYWORD); + private static final TextAttributesKey[] KEYWORD_KEYS = new TextAttributesKey[]{KEYWORD}; + + private static final List<IElementType> keywordLiterals = Arrays.asList(AspectTypes.TRUE, AspectTypes.FALSE, + AspectTypes.NULL); + public static final TextAttributesKey KEYWORD_LITERAL = createTextAttributesKey("ASPECT_KEYWORD", DefaultLanguageHighlighterColors.PREDEFINED_SYMBOL); + private static final TextAttributesKey[] KEYWORD_LITERAL_KEYS = new TextAttributesKey[]{KEYWORD_LITERAL}; + + private static final List<IElementType> operators = Arrays.asList(AspectTypes.ANDASSIGN, AspectTypes.ASSIGN, + AspectTypes.BIT_AND, AspectTypes.BIT_OR, AspectTypes.DECR, AspectTypes.EQ, AspectTypes.GE, AspectTypes.GT, + AspectTypes.INCR, AspectTypes.LE, AspectTypes.LT, AspectTypes.LSHIFT, AspectTypes.LSHIFTASSIGN, AspectTypes.PLUS, + AspectTypes.PLUSASSIGN, AspectTypes.MINUS, AspectTypes.MINUSASSIGN, AspectTypes.SLASH, AspectTypes.SLASHASSIGN, + AspectTypes.NE, AspectTypes.ORASSIGN, AspectTypes.XOR, AspectTypes.XORASSIGN, AspectTypes.STAR, + AspectTypes.STARASSIGN, AspectTypes.REM, AspectTypes.REMASSIGN, AspectTypes.SC_AND, AspectTypes.SC_OR, + AspectTypes.AMPERSAND, AspectTypes.RSIGNEDSHIFTASSIGN, AspectTypes.RUNSIGNEDSHIFTASSIGN, AspectTypes.TILDE, + AspectTypes.BANG, AspectTypes.ARROW, AspectTypes.DOTS); + public static final TextAttributesKey OPERATOR = createTextAttributesKey("JASTADD_OPERATOR", DefaultLanguageHighlighterColors.OPERATION_SIGN); + private static final TextAttributesKey[] OPERATOR_KEYS = new TextAttributesKey[]{OPERATOR}; + + public static final TextAttributesKey COMMA = createTextAttributesKey("JASTADD_COMMA", DefaultLanguageHighlighterColors.COMMA); + private static final TextAttributesKey[] COMMA_KEYS = new TextAttributesKey[]{COMMA}; + + private static final List<IElementType> parentheses = Arrays.asList(AspectTypes.LPAREN, AspectTypes.RPAREN); + public static final TextAttributesKey PARENTHESIS = createTextAttributesKey("JASTADD_PARENTHESIS", DefaultLanguageHighlighterColors.PARENTHESES); + private static final TextAttributesKey[] PARENTHESIS_KEYS = new TextAttributesKey[]{PARENTHESIS}; + + private static final List<IElementType> brackets = Arrays.asList(AspectTypes.LBRACKET, AspectTypes.RBRACKET); + public static final TextAttributesKey BRACKET = createTextAttributesKey("JASTADD_BRACKET", DefaultLanguageHighlighterColors.BRACKETS); + private static final TextAttributesKey[] BRACKET_KEYS = new TextAttributesKey[]{BRACKET}; + + private static final List<IElementType> braces = Arrays.asList(AspectTypes.LBRACE, AspectTypes.RBRACE); + public static final TextAttributesKey BRACE = createTextAttributesKey("JASTADD_BRACE", DefaultLanguageHighlighterColors.BRACES); + private static final TextAttributesKey[] BRACE_KEYS = new TextAttributesKey[]{BRACE}; + + public static final TextAttributesKey IDENTIFIER = createTextAttributesKey("JASTADD_IDENTIFIER", DefaultLanguageHighlighterColors.IDENTIFIER); + private static final TextAttributesKey[] IDENTIFIER_KEYS = new TextAttributesKey[]{IDENTIFIER}; + + public static final TextAttributesKey FORMAL_COMMENT = createTextAttributesKey("JASTADD_FORMAL_COMMENT", DefaultLanguageHighlighterColors.DOC_COMMENT); + private static final TextAttributesKey[] FORMAL_COMMENT_KEYS = new TextAttributesKey[]{FORMAL_COMMENT}; + public static final TextAttributesKey SINGLE_LINE_COMMENT = createTextAttributesKey("JASTADD_SINGLE_LINE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); + private static final TextAttributesKey[] SINGLE_LINE_COMMENT_KEYS = new TextAttributesKey[]{SINGLE_LINE_COMMENT}; + public static final TextAttributesKey MULTI_LINE_COMMENT = createTextAttributesKey("JASTADD_MULTI_LINE_COMMENT", DefaultLanguageHighlighterColors.BLOCK_COMMENT); + private static final TextAttributesKey[] MULTI_LINE_COMMENT_KEYS = new TextAttributesKey[]{MULTI_LINE_COMMENT}; + + // other symbols + private static final List<IElementType> symbols = Arrays.asList(AspectTypes.DOUBLECOLON, AspectTypes.QUESTIONMARK, AspectTypes.COLON, AspectTypes.DOUBLECOLON); + public static final TextAttributesKey SYMBOL = createTextAttributesKey("JASTADD_SYMBOL", DefaultLanguageHighlighterColors.PREDEFINED_SYMBOL); + private static final TextAttributesKey[] SYMBOL_KEYS = new TextAttributesKey[]{SYMBOL}; + + public static final TextAttributesKey DOT = createTextAttributesKey("JASTADD_DOT", DefaultLanguageHighlighterColors.DOT); + private static final TextAttributesKey[] DOT_KEYS = new TextAttributesKey[]{DOT}; + + public static final TextAttributesKey SEMICOLON = createTextAttributesKey("JASTADD_SEMICOLON", DefaultLanguageHighlighterColors.SEMICOLON); + private static final TextAttributesKey[] SEMICOLON_KEYS = new TextAttributesKey[]{SEMICOLON}; + + private static final List<IElementType> numbers = Arrays.asList(AspectTypes.INTEGER_LITERAL, AspectTypes.FLOATING_POINT_LITERAL); + public static final TextAttributesKey NUMBER = createTextAttributesKey("ASPECT_NUMBER", DefaultLanguageHighlighterColors.NUMBER); + private static final TextAttributesKey[] NUMBER_KEYS = new TextAttributesKey[]{NUMBER}; + + public static final TextAttributesKey STRING_LITERAL = createTextAttributesKey("ASPECT_STRING_LITERAL", DefaultLanguageHighlighterColors.STRING); + private static final TextAttributesKey[] STRING_LITERAL_KEYS = new TextAttributesKey[]{STRING_LITERAL}; + public static final TextAttributesKey CHARACTER_LITERAL = createTextAttributesKey("ASPECT_CHARACTER_LITERAL", DefaultLanguageHighlighterColors.STRING); + private static final TextAttributesKey[] CHARACTER_LITERAL_KEYS = new TextAttributesKey[]{CHARACTER_LITERAL}; + + // unclear + // TODO unclear IO + // TODO missing AT_NAME + // TODO unused NOTPARENTHESIS + // TODO combined DOT_CLASS + + // islands + // public static final TextAttributesKey CLASS_BODY_UNSUPPORTED = createTextAttributesKey("ASPECT_CLASS_BODY_UNSUPPORTED", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey CLASS_ANYTHING_LBRACE_ANYTHING_RBRACE = createTextAttributesKey("ASPECT_CLASS_ANYTHING_LBRACE_ANYTHING_RBRACE", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey INTERFACE_ANYTHING_LBRACE_ANYTHING_RBRACE = createTextAttributesKey("ASPECT_INTERFACE_ANYTHING_LBRACE_ANYTHING_RBRACE", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey AT_NAME_LPAREN_ANYTHING_RPAREN = createTextAttributesKey("ASPECT_AT_NAME_LPAREN_ANYTHING_RPAREN", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey AT_INTERFACE_ANYTHING_LBRACE_ANYTHING_RBRACE = createTextAttributesKey("ASPECT_AT_INTERFACE_ANYTHING_LBRACE_ANYTHING_RBRACE", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey ENUM_ANYTHING_LBRACE_ANYTHING_RBRACE = createTextAttributesKey("ASPECT_ENUM_ANYTHING_LBRACE_ANYTHING_RBRACE", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey STATEMENT = createTextAttributesKey("ASPECT_STATEMENT", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey LBRACE_ANYTHING_RBRACE = createTextAttributesKey("ASPECT_LBRACE_ANYTHING_RBRACE", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey LBRACKET_ANYTHING_RBRACKET = createTextAttributesKey("ASPECT_LBRACKET_ANYTHING_RBRACKET", DefaultLanguageHighlighterColors.); + // public static final TextAttributesKey JAVA_EXPLICIT_CONSTRUCTUR_BLOCK = createTextAttributesKey("ASPECT_JAVA_EXPLICIT_CONSTRUCTUR_BLOCK", DefaultLanguageHighlighterColors.); + + + public static final TextAttributesKey BAD_CHARACTER = + createTextAttributesKey("JASTADD_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER); + + + @NotNull + @Override + public Lexer getHighlightingLexer() { + return new AspectLexerAdapter(); + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (javaKeywords.contains(tokenType) || jastAddKeywords.contains(tokenType)) { + return KEYWORD_KEYS; + } else if (keywordLiterals.contains(tokenType)) { + return KEYWORD_LITERAL_KEYS; + } else if (operators.contains(tokenType)) { + return OPERATOR_KEYS; + } else if (tokenType.equals(AspectTypes.COMMA)) { + return COMMA_KEYS; + } else if (parentheses.contains(tokenType)) { + return PARENTHESIS_KEYS; + } else if (brackets.contains(tokenType)) { + return BRACKET_KEYS; + } else if (braces.contains(tokenType)) { + return BRACE_KEYS; + } else if (numbers.contains(tokenType)) { + return NUMBER_KEYS; + } else if (symbols.contains(tokenType)) { + return SYMBOL_KEYS; + } else if (tokenType.equals(AspectTypes.IDENTIFIER)) { + return IDENTIFIER_KEYS; + } else if (tokenType.equals(AspectTypes.FORMAL_COMMENT)) { + return FORMAL_COMMENT_KEYS; + } else if (tokenType.equals(AspectTypes.SINGLE_LINE_COMMENT)) { + return SINGLE_LINE_COMMENT_KEYS; + } else if (tokenType.equals(AspectTypes.MULTI_LINE_COMMENT)) { + return MULTI_LINE_COMMENT_KEYS; + } else if (tokenType.equals(AspectTypes.DOT)) { + return DOT_KEYS; + } else if (tokenType.equals(AspectTypes.SEMICOLON)) { + return SEMICOLON_KEYS; + } else if (tokenType.equals(AspectTypes.STRING_LITERAL)) { + return STRING_LITERAL_KEYS; + } else if (tokenType.equals(AspectTypes.CHARACTER_LITERAL)) { + return CHARACTER_LITERAL_KEYS; + } else if (tokenType.equals(TokenType.BAD_CHARACTER)) { + return new TextAttributesKey[]{BAD_CHARACTER}; + } else { + return new TextAttributesKey[0]; + } + } + +} diff --git a/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighterFactory.java b/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighterFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..aea553106014848fbf768e2c3613401f95de8e0c --- /dev/null +++ b/src/main/java/org/jastadd/tooling/aspect/AspectSyntaxHighlighterFactory.java @@ -0,0 +1,18 @@ +package org.jastadd.tooling.aspect; + + +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +public class AspectSyntaxHighlighterFactory extends SyntaxHighlighterFactory { + + @NotNull + @Override + public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { + return new AspectSyntaxHighlighter(); + } + +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 284b8d98e67152fd069f5dcbfc144ef1dd759184..9da0c36d2e3fdf311a753a4d6736218f31ffd93b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -68,6 +68,11 @@ <lang.parserDefinition language="JastAddAspect" implementationClass="org.jastadd.tooling.aspect.parser.AspectParserDefinition"/> <languageInjector implementation="org.jastadd.tooling.aspect.JavaBlockLanguageInjector"/> + + <lang.syntaxHighlighterFactory language="JastAddAspect" + implementationClass="org.jastadd.tooling.aspect.AspectSyntaxHighlighterFactory"/> + + <colorSettingsPage implementation="org.jastadd.tooling.aspect.AspectColorSettingsPage"/> </extensions> <actions>