Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2aea320

Browse files
committed
Added Expression Language support
1 parent 5d6fd5d commit 2aea320

16 files changed

+555
-1
lines changed

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ out/
33
/.idea/misc.xml
44
/.gradle
55
/build
6+
/src/main/gen

‎build.gradle

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
2+
import org.jetbrains.grammarkit.tasks.*
23

34
plugins {
45
id "org.jetbrains.intellij" version "0.4.11"
56
id 'com.palantir.git-version' version "0.11.0"
7+
id "org.jetbrains.grammarkit" version "2021年1月3日"
68
}
79

810
def htmlFixer = { htmlFile -> file(htmlFile).text.replace('<html>', '').replace('</html>', '') }
@@ -14,6 +16,7 @@ sourceCompatibility = JavaVersion.VERSION_11
1416
targetCompatibility = JavaVersion.VERSION_11
1517

1618
apply plugin: 'org.jetbrains.intellij'
19+
apply plugin: 'org.jetbrains.grammarkit'
1720

1821
intellij {
1922
version ideaVersion
@@ -53,6 +56,24 @@ publishPlugin {
5356
token System.getenv('IJ_TOKEN')
5457
}
5558

59+
task generateExpressionLanguageLexer(type: GenerateLexer) {
60+
source = 'src/main/java/fr/adrienbrault/idea/symfony2plugin/expressionLanguage/ExpressionLanguage.flex'
61+
targetDir = 'src/main/gen/fr/adrienbrault/idea/symfony2plugin/expressionLanguage/'
62+
targetClass = 'ExpressionLanguageLexer'
63+
}
64+
65+
task generateExpressionLanguageParser(type: GenerateParser) {
66+
source = 'src/main/java/fr/adrienbrault/idea/symfony2plugin/expressionLanguage/ExpressionLanguage.bnf'
67+
targetRoot = 'src/main/gen'
68+
pathToParser = 'src/main/gen/fr/adrienbrault/idea/symfony2plugin/expressionLanguage/ExpressionLanguageParser.java'
69+
pathToPsiRoot = 'src/main/gen/fr/adrienbrault/idea/symfony2plugin/expressionLanguage/psi'
70+
}
71+
72+
compileJava {
73+
dependsOn generateExpressionLanguageLexer
74+
dependsOn generateExpressionLanguageParser
75+
}
76+
5677
group 'fr.adrienbrault.idea.symfony2plugin'
5778

5879
def details = versionDetails()
@@ -67,3 +88,6 @@ wrapper {
6788
}
6889

6990
test.testLogging.exceptionFormat = TestExceptionFormat.FULL
91+
92+
// Include the generated files in the source set
93+
sourceSets.main.java.srcDirs 'src/main/gen'
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
{
2+
parserClass="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.ExpressionLanguageParser"
3+
4+
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
5+
6+
psiClassPrefix="ExpressionLanguage"
7+
psiImplClassSuffix="Impl"
8+
psiPackage="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi"
9+
psiImplPackage="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.impl"
10+
11+
elementTypeHolderClass="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.ExpressionLanguageTypes"
12+
elementTypeClass="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.ExpressionLanguageElementType"
13+
tokenTypeClass="fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.ExpressionLanguageTokenType"
14+
15+
extends(".*expr")=expr
16+
tokens=[
17+
space='regexp:\s+'
18+
number='regexp:\d+(\.\d*)?'
19+
null="regexp:NULL|null"
20+
true="regexp:TRUE|true"
21+
false="regexp:FALSE|false"
22+
id='regexp:\p{Alpha}\w*'
23+
string="regexp:('([^'\\]|\\.)*'|\"([^\"\\]|\\.)*\")"
24+
OP_OR="regexp:or|\|\|"
25+
OP_AND="regexp:and|&&"
26+
OP_BIT_OR="|"
27+
OP_BIT_XOR="^"
28+
OP_BIT_AND="&"
29+
OP_IDENTICAL="==="
30+
OP_EQ="=="
31+
OP_NOT_IDENTICAL="!=="
32+
OP_NEQ="!="
33+
OP_LT="<"
34+
OP_GT=">"
35+
OP_GTE=">="
36+
OP_LTE="<="
37+
OP_NOT_IN="not in"
38+
OP_IN="in"
39+
OP_MATCHES="matches"
40+
OP_RANGE=".."
41+
OP_PLUS="+"
42+
OP_MINUS="-"
43+
OP_CONCAT="~"
44+
OP_MUL="*"
45+
OP_DIV="/"
46+
OP_MOD="%"
47+
OP_POW="**"
48+
OP_NOT='regexp:not|\!'
49+
50+
L_ROUND_BRACKET="("
51+
R_ROUND_BRACKET=")"
52+
L_CURLY_BRACKET="{"
53+
R_CURLY_BRACKET="}"
54+
L_SQUARE_BRACKET="["
55+
R_SQUARE_BRACKET="]"
56+
57+
syntax='regexp:[?:.,]'
58+
]
59+
}
60+
61+
root ::= expr
62+
63+
expr ::= ternary_group
64+
| or_expr
65+
| and_expr
66+
| bit_or_expr
67+
| bit_xor_expr
68+
| bit_and_expr
69+
| rel_group
70+
| range_expr
71+
| add_group
72+
| concat_expr
73+
| mul_group
74+
| not_expr
75+
| exp_expr
76+
| sign_group
77+
| qualification_expr
78+
| array_access_expr
79+
| primary_group
80+
81+
private sign_group ::= unary_plus_expr | unary_min_expr
82+
private mul_group ::= mul_expr | div_expr | mod_expr
83+
private add_group ::= plus_expr | minus_expr
84+
private ternary_group ::= ternary_expr | elvis_expr
85+
86+
private rel_group ::= eq_strict_expr
87+
| eq_expr
88+
| neq_strict_expr
89+
| neq_expr
90+
| gte_expr
91+
| gt_expr
92+
| lt_expr
93+
| lte_expr
94+
| not_in_expr
95+
| in_expr
96+
| matches_expr
97+
98+
private primary_group ::= simple_ref_expr | literal_expr | array_expr | hash_expr | call_expr | paren_expr
99+
100+
not_expr ::= OP_NOT expr
101+
unary_min_expr ::= OP_MINUS expr
102+
unary_plus_expr ::= OP_PLUS expr
103+
div_expr ::= expr OP_DIV expr
104+
mul_expr ::= expr OP_MUL expr
105+
mod_expr ::= expr OP_MOD expr
106+
concat_expr ::= expr OP_CONCAT expr
107+
minus_expr ::= expr OP_MINUS expr
108+
plus_expr ::= expr OP_PLUS expr
109+
range_expr ::= expr OP_RANGE expr
110+
eq_strict_expr ::= expr OP_IDENTICAL expr
111+
neq_strict_expr ::= expr OP_NOT_IDENTICAL expr
112+
eq_expr ::= expr OP_EQ expr
113+
neq_expr ::= expr OP_NEQ expr
114+
gt_expr ::= expr OP_GT expr
115+
gte_expr ::= expr OP_GTE expr
116+
lt_expr ::= expr OP_LT expr
117+
lte_expr ::= expr OP_LTE expr
118+
not_in_expr ::= expr OP_NOT_IN expr
119+
in_expr ::= expr OP_IN expr
120+
matches_expr ::= expr OP_MATCHES expr
121+
or_expr ::= expr OP_OR expr
122+
and_expr ::= expr OP_AND expr
123+
bit_and_expr ::= expr OP_BIT_AND expr
124+
bit_or_expr ::= expr OP_BIT_OR expr
125+
bit_xor_expr ::= expr OP_BIT_XOR expr
126+
exp_expr ::= expr (OP_POW expr)+
127+
paren_expr ::= L_ROUND_BRACKET expr R_ROUND_BRACKET
128+
ternary_expr ::= expr '?' expr (':' expr)?
129+
elvis_expr ::= expr '?:' expr
130+
131+
fake ref_expr ::= expr? '.' identifier
132+
simple_ref_expr ::= identifier {extends=ref_expr elementType=ref_expr}
133+
qualification_expr ::= expr '.' identifier {extends=ref_expr elementType=ref_expr}
134+
array_access_expr ::= expr L_SQUARE_BRACKET expr R_SQUARE_BRACKET {extends=ref_expr elementType=ref_expr}
135+
136+
literal_expr ::= number | string | true | false | null
137+
array_expr ::= L_SQUARE_BRACKET expr_list? R_SQUARE_BRACKET
138+
hash_expr ::= L_CURLY_BRACKET hash_entries? R_CURLY_BRACKET
139+
140+
call_expr ::= expr L_ROUND_BRACKET expr_list? R_ROUND_BRACKET
141+
142+
private hash_entries ::= hash_entry (',' hash_entry)*
143+
private hash_entry ::= identifier ':' expr
144+
private expr_list ::= expr (',' expr_list)*
145+
146+
identifier ::= id
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package fr.adrienbrault.idea.symfony2plugin.expressionLanguage;
2+
3+
import com.intellij.lexer.FlexLexer;
4+
import com.intellij.psi.tree.IElementType;
5+
6+
import static com.intellij.psi.TokenType.BAD_CHARACTER;
7+
import static com.intellij.psi.TokenType.WHITE_SPACE;
8+
import static fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.ExpressionLanguageTypes.*;
9+
10+
%%
11+
12+
%{
13+
public ExpressionLanguageLexer() {
14+
this((java.io.Reader)null);
15+
}
16+
%}
17+
18+
%public
19+
%class ExpressionLanguageLexer
20+
%implements FlexLexer
21+
%function advance
22+
%type IElementType
23+
%unicode
24+
25+
EOL=\R
26+
WHITE_SPACE=\s+
27+
28+
SPACE=[ \t\n\x0B\f\r]+
29+
NUMBER=[0-9]+(\.[0-9]*)?
30+
NULL=NULL|null
31+
TRUE=TRUE|true
32+
FALSE=FALSE|false
33+
ID=[:letter:][a-zA-Z_0-9]*
34+
STRING=('([^'\\]|\\.)*'|\"([^\"\\]|\\.)*\")
35+
OP_OR=or|\|\|
36+
OP_AND=and|&&
37+
OP_NOT=not|\!
38+
SYNTAX=[?:.,]
39+
40+
%%
41+
<YYINITIAL> {
42+
{WHITE_SPACE} { return WHITE_SPACE; }
43+
44+
"|" { return OP_BIT_OR; }
45+
"^" { return OP_BIT_XOR; }
46+
"&" { return OP_BIT_AND; }
47+
"===" { return OP_IDENTICAL; }
48+
"==" { return OP_EQ; }
49+
"!==" { return OP_NOT_IDENTICAL; }
50+
"!=" { return OP_NEQ; }
51+
"<" { return OP_LT; }
52+
">" { return OP_GT; }
53+
">=" { return OP_GTE; }
54+
"<=" { return OP_LTE; }
55+
"not in" { return OP_NOT_IN; }
56+
"in" { return OP_IN; }
57+
"matches" { return OP_MATCHES; }
58+
".." { return OP_RANGE; }
59+
"+" { return OP_PLUS; }
60+
"-" { return OP_MINUS; }
61+
"~" { return OP_CONCAT; }
62+
"*" { return OP_MUL; }
63+
"/" { return OP_DIV; }
64+
"%" { return OP_MOD; }
65+
"**" { return OP_POW; }
66+
"(" { return L_ROUND_BRACKET; }
67+
")" { return R_ROUND_BRACKET; }
68+
"{" { return L_CURLY_BRACKET; }
69+
"}" { return R_CURLY_BRACKET; }
70+
"[" { return L_SQUARE_BRACKET; }
71+
"]" { return R_SQUARE_BRACKET; }
72+
73+
{SPACE} { return SPACE; }
74+
{NUMBER} { return NUMBER; }
75+
{NULL} { return NULL; }
76+
{TRUE} { return TRUE; }
77+
{FALSE} { return FALSE; }
78+
{ID} { return ID; }
79+
{STRING} { return STRING; }
80+
{OP_OR} { return OP_OR; }
81+
{OP_AND} { return OP_AND; }
82+
{OP_NOT} { return OP_NOT; }
83+
{SYNTAX} { return SYNTAX; }
84+
85+
}
86+
87+
[^] { return BAD_CHARACTER; }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package fr.adrienbrault.idea.symfony2plugin.expressionLanguage;
2+
3+
import com.intellij.lang.Language;
4+
5+
public class ExpressionLanguage extends Language {
6+
7+
public static final ExpressionLanguage INSTANCE = new ExpressionLanguage();
8+
9+
private ExpressionLanguage() {
10+
super("Symfony Expression Language");
11+
}
12+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package fr.adrienbrault.idea.symfony2plugin.expressionLanguage;
2+
3+
import com.intellij.lang.BracePair;
4+
import com.intellij.lang.PairedBraceMatcher;
5+
import com.intellij.psi.PsiFile;
6+
import com.intellij.psi.tree.IElementType;
7+
import fr.adrienbrault.idea.symfony2plugin.expressionLanguage.psi.ExpressionLanguageTypes;
8+
import org.jetbrains.annotations.NotNull;
9+
import org.jetbrains.annotations.Nullable;
10+
11+
public class ExpressionLanguageBraceMatcher implements PairedBraceMatcher {
12+
private static BracePair[] PAIRS = {
13+
new BracePair(
14+
ExpressionLanguageTypes.L_ROUND_BRACKET,
15+
ExpressionLanguageTypes.R_ROUND_BRACKET,
16+
true
17+
),
18+
new BracePair(
19+
ExpressionLanguageTypes.L_SQUARE_BRACKET,
20+
ExpressionLanguageTypes.R_SQUARE_BRACKET,
21+
true
22+
),
23+
new BracePair(
24+
ExpressionLanguageTypes.L_CURLY_BRACKET,
25+
ExpressionLanguageTypes.R_CURLY_BRACKET,
26+
true
27+
),
28+
};
29+
30+
@Override
31+
public BracePair[] getPairs() {
32+
return PAIRS;
33+
}
34+
35+
@Override
36+
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
37+
return false;
38+
}
39+
40+
@Override
41+
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
42+
return openingBraceOffset;
43+
}
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package fr.adrienbrault.idea.symfony2plugin.expressionLanguage;
2+
3+
import com.intellij.openapi.fileTypes.LanguageFileType;
4+
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
5+
import org.jetbrains.annotations.NotNull;
6+
import org.jetbrains.annotations.Nullable;
7+
8+
import javax.swing.*;
9+
10+
public class ExpressionLanguageFileType extends LanguageFileType {
11+
12+
public static final ExpressionLanguageFileType INSTANCE = new ExpressionLanguageFileType();
13+
14+
private ExpressionLanguageFileType() {
15+
super(ExpressionLanguage.INSTANCE);
16+
}
17+
18+
@NotNull
19+
@Override
20+
public String getName() {
21+
return "Expression Language File";
22+
}
23+
24+
@NotNull
25+
@Override
26+
public String getDescription() {
27+
return "Expression Language file";
28+
}
29+
30+
@NotNull
31+
@Override
32+
public String getDefaultExtension() {
33+
return "sfel";
34+
}
35+
36+
@Override
37+
@Nullable
38+
public Icon getIcon() {
39+
return Symfony2Icons.SYMFONY;
40+
}
41+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /