Skip to content

Commit cea3838

Browse files
committed
basic parsing and lexing of svelte template expressions
1 parent d7cc120 commit cea3838

File tree

20 files changed

+764
-166
lines changed

20 files changed

+764
-166
lines changed

build.gradle

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,23 @@ idea {
5151
}
5252
}
5353

54+
task generateLexer(type: GenerateLexer) {
55+
// source flex file
56+
source = "src/main/jflex/technology/svelte/lexer//svelte.flex"
57+
58+
// target directory for lexer
59+
targetDir = "build/generated-src/jflex"
60+
61+
// target classname, target file will be targetDir/targetClass.java
62+
targetClass = "_SvelteLexer"
63+
64+
// optional, path to the task-specific skeleton file. Default: none
65+
skeleton = 'src/main/jflex/idea-flex.skeleton'
66+
67+
// if set, plugin will remove a lexer output file before generating new one. Default: false
68+
purgeOldFiles = true
69+
}
70+
5471
task generateTopLexer(type: GenerateLexer) {
5572
// source flex file
5673
source = "src/main/jflex/technology/svelte/lexer//svelte_top.flex"
@@ -86,8 +103,9 @@ task generateSubLexer(type: GenerateLexer) {
86103
}
87104

88105
task generateLexers {
89-
dependsOn generateTopLexer
90-
dependsOn generateSubLexer
106+
// dependsOn generateTopLexer
107+
// dependsOn generateSubLexer
108+
dependsOn generateLexer
91109
}
92110

93111
compileJava {
-665 Bytes
Binary file not shown.

src/main/java/technology/svelte/completion/KeywordCompletionProvider.java

Lines changed: 131 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -19,118 +19,144 @@
1919
* Provides keywords to be auto-completed
2020
*/
2121
public class KeywordCompletionProvider extends CompletionProvider<CompletionParameters> {
22-
// constant lists
23-
private static final String[] KEYWORDS = {
24-
// CoreMacros.php
25-
"if", "ifset", "for", "foreach", "while", "first", "last", "sep", "class", "attr", "captute",
26-
"var", "default", "dump", "debugbreak", "l", "r",
27-
28-
// FormMacros.php
29-
"form", "input", "label", "formContainer",
30-
31-
// UIMacros.php
32-
"include", "extends", "block", "define", "snippet", "widget", "control", "href", "link", "plink", "contentType", "status",
33-
};
34-
35-
private static final List<String> PAIR_MACROS = Arrays.asList(
36-
"if", "ifset", "for", "foreach", "while", "first", "last", "sep"
37-
);
38-
39-
private static final String[] FILTERS = {
40-
// static
41-
"normalize", "toascii", "webalize", "truncate", "lower", "upper", "firstupper", "capitalize", "trim", "padleft", "padright",
42-
"replacere", "url", "striptags", "nl2br", "substr", "repeat", "implode", "number",
43-
44-
// methods in Helpers.php
45-
"espaceHtml", "escapeHtmlComment", "escapeXML", "escapeCss", "escapeJs", "strip", "indent", "date", "bytes",
46-
"length", "replace", "dataStream", "null",
47-
};
48-
22+
// constant lists
23+
private static final String[] KEYWORDS = { "for", "foreach", "/for", "if", "else", "/if", "link", "plink" };
24+
private static final String[] FILTERS = { "date", "format", "replace", "url_encode", "json_encode", "title", "capitalize", "upper", "lower", "striptags", "join", "reverse", "length", "sort", "default", "keys", "escape", "raw", "merge" };
4925

5026
// CompletionResultSet wants list of LookupElements
51-
private List<LookupElementBuilder> KEYWORD_LOOKUPS = new ArrayList();
52-
private List<LookupElementBuilder> ATTR_LOOKUPS = new ArrayList();
53-
private List<LookupElementBuilder> FILTER_LOOKUPS = new ArrayList();
54-
private HashMap<String, LookupElementBuilder> CLOSING_LOOKUPS = new HashMap<String, LookupElementBuilder>();
55-
56-
public KeywordCompletionProvider() {
57-
super();
58-
59-
for(String keyword: KEYWORDS) {
60-
KEYWORD_LOOKUPS.add(LookupElementBuilder.create(keyword));
61-
ATTR_LOOKUPS.add(LookupElementBuilder.create("n:" + keyword));
62-
}
63-
for(String filter: FILTERS) FILTER_LOOKUPS.add(LookupElementBuilder.create(filter));
64-
}
65-
66-
@Override
67-
protected void addCompletions(@NotNull CompletionParameters params,
68-
ProcessingContext ctx,
69-
@NotNull CompletionResultSet results) {
27+
private List<LookupElementBuilder> KEYWORD_LOOKUPS = new ArrayList();
28+
private List<LookupElementBuilder> FILTER_LOOKUPS = new ArrayList();
7029

71-
PsiElement curr = params.getPosition().getOriginalElement();
7230

73-
// n: attributes
74-
if(curr.getParent() instanceof XmlAttribute) {
75-
for(LookupElementBuilder x: ATTR_LOOKUPS) results.addElement(x);
76-
return;
77-
}
31+
public KeywordCompletionProvider() {
32+
super();
7833

79-
// Keywords
80-
if(curr.getNode().getElementType() == SvelteTokenTypes.MACRO_NAME) {
81-
for(LookupElementBuilder x: KEYWORD_LOOKUPS) results.addElement(x);
82-
83-
HashSet<String> openedMacros = new HashSet<String>(); // macros which are opened before (should complete closing)
84-
HashSet<String> closedMacros = new HashSet<String>(); // which are closed (should not complete closing)
85-
86-
// Go up and find open keywords (and offer them for closing)
87-
PsiElement cursor = curr;
88-
while(cursor != null && (cursor.getPrevSibling() != null || cursor.getParent() != null)) {
89-
// macro found {xx} found
90-
if(cursor instanceof MacroNodeImpl) {
91-
MacroNodeImpl node = (MacroNodeImpl) cursor;
92-
String name = node.getMacroName();
93-
94-
if(name.charAt(0) == '/') { // closing macro
95-
closedMacros.add(name.substring(1));
96-
} else if(PAIR_MACROS.contains(name)) {
97-
if(closedMacros.contains(name)) closedMacros.remove(name); // is closed later
98-
else openedMacros.add(name); // not closed, let us close it
99-
}
100-
}
101-
102-
103-
PsiElement tmp;
104-
if((tmp = cursor.getPrevSibling()) != null) cursor = tmp; // Go prev if possible...
105-
else cursor = cursor.getParent(); // ... or up
106-
}
107-
108-
for(String name: openedMacros) {
109-
if(name.equals("if")) {
110-
results.addElement(reuseClosingTag("else"));
111-
results.addElement(reuseClosingTag("elseif"));
112-
}
113-
results.addElement(reuseClosingTag("/" + name));
114-
}
115-
116-
results.stopHere();
117-
}
34+
for(String keyword: KEYWORDS) KEYWORD_LOOKUPS.add(LookupElementBuilder.create(keyword));
35+
for(String filter: FILTERS) FILTER_LOOKUPS.add(LookupElementBuilder.create(filter));
36+
}
11837

119-
// Modifiers (if after pipe)
120-
PsiElement prev = curr.getPrevSibling();
121-
if(prev != null && prev instanceof PsiWhiteSpace) prev = prev.getPrevSibling();
122-
if(prev != null && prev.getNode().getElementType() == SvelteTokenTypes.MODIFIER) {
123-
for(LookupElementBuilder x: FILTER_LOOKUPS) results.addElement(x);
124-
results.stopHere();
125-
}
126-
}
38+
@Override
39+
protected void addCompletions(@NotNull CompletionParameters params,
40+
ProcessingContext ctx,
41+
@NotNull CompletionResultSet results) {
12742

128-
// Get closing tag
129-
private LookupElementBuilder reuseClosingTag(String name) {
130-
if(!CLOSING_LOOKUPS.containsKey(name)) {
131-
CLOSING_LOOKUPS.put(name, LookupElementBuilder.create(name));
43+
PsiElement currElement = params.getPosition().getOriginalElement();
44+
if(currElement.getNode().getElementType() == SvelteTokenTypes.BLOCK_STMT_NAME) {
45+
for(LookupElementBuilder x: KEYWORD_LOOKUPS) results.addElement(x);
13246
}
133-
134-
return CLOSING_LOOKUPS.get(name);
13547
}
48+
// // constant lists
49+
// private static final String[] KEYWORDS = {
50+
// // CoreMacros.php
51+
// "if", "ifset", "for", "foreach", "while", "first", "last", "sep", "class", "attr", "captute",
52+
// "var", "default", "dump", "debugbreak", "l", "r",
53+
//
54+
// // FormMacros.php
55+
// "form", "input", "label", "formContainer",
56+
//
57+
// // UIMacros.php
58+
// "include", "extends", "block", "define", "snippet", "widget", "control", "href", "link", "plink", "contentType", "status",
59+
// };
60+
//
61+
// private static final List<String> PAIR_MACROS = Arrays.asList(
62+
// "if", "ifset", "for", "foreach", "while", "first", "last", "sep"
63+
// );
64+
//
65+
// private static final String[] FILTERS = {
66+
// // static
67+
// "normalize", "toascii", "webalize", "truncate", "lower", "upper", "firstupper", "capitalize", "trim", "padleft", "padright",
68+
// "replacere", "url", "striptags", "nl2br", "substr", "repeat", "implode", "number",
69+
//
70+
// // methods in Helpers.php
71+
// "espaceHtml", "escapeHtmlComment", "escapeXML", "escapeCss", "escapeJs", "strip", "indent", "date", "bytes",
72+
// "length", "replace", "dataStream", "null",
73+
// };
74+
//
75+
//
76+
// // CompletionResultSet wants list of LookupElements
77+
// private List<LookupElementBuilder> KEYWORD_LOOKUPS = new ArrayList();
78+
// private List<LookupElementBuilder> ATTR_LOOKUPS = new ArrayList();
79+
// private List<LookupElementBuilder> FILTER_LOOKUPS = new ArrayList();
80+
// private HashMap<String, LookupElementBuilder> CLOSING_LOOKUPS = new HashMap<String, LookupElementBuilder>();
81+
//
82+
// public KeywordCompletionProvider() {
83+
// super();
84+
//
85+
// for(String keyword: KEYWORDS) {
86+
// KEYWORD_LOOKUPS.add(LookupElementBuilder.create(keyword));
87+
// ATTR_LOOKUPS.add(LookupElementBuilder.create("n:" + keyword));
88+
// }
89+
// for(String filter: FILTERS) FILTER_LOOKUPS.add(LookupElementBuilder.create(filter));
90+
// }
91+
//
92+
// @Override
93+
// protected void addCompletions(@NotNull CompletionParameters params,
94+
// ProcessingContext ctx,
95+
// @NotNull CompletionResultSet results) {
96+
//
97+
// PsiElement curr = params.getPosition().getOriginalElement();
98+
//
99+
// // n: attributes
100+
// if(curr.getParent() instanceof XmlAttribute) {
101+
// for(LookupElementBuilder x: ATTR_LOOKUPS) results.addElement(x);
102+
// return;
103+
// }
104+
//
105+
// // Keywords
106+
// if(curr.getNode().getElementType() == SvelteTokenTypes.MACRO_NAME) {
107+
// for(LookupElementBuilder x: KEYWORD_LOOKUPS) results.addElement(x);
108+
//
109+
// HashSet<String> openedMacros = new HashSet<String>(); // macros which are opened before (should complete closing)
110+
// HashSet<String> closedMacros = new HashSet<String>(); // which are closed (should not complete closing)
111+
//
112+
// // Go up and find open keywords (and offer them for closing)
113+
// PsiElement cursor = curr;
114+
// while(cursor != null && (cursor.getPrevSibling() != null || cursor.getParent() != null)) {
115+
// // macro found {xx} found
116+
// if(cursor instanceof MacroNodeImpl) {
117+
// MacroNodeImpl node = (MacroNodeImpl) cursor;
118+
// String name = node.getMacroName();
119+
//
120+
// if(name.charAt(0) == '/') { // closing macro
121+
// closedMacros.add(name.substring(1));
122+
// } else if(PAIR_MACROS.contains(name)) {
123+
// if(closedMacros.contains(name)) closedMacros.remove(name); // is closed later
124+
// else openedMacros.add(name); // not closed, let us close it
125+
// }
126+
// }
127+
//
128+
//
129+
// PsiElement tmp;
130+
// if((tmp = cursor.getPrevSibling()) != null) cursor = tmp; // Go prev if possible...
131+
// else cursor = cursor.getParent(); // ... or up
132+
// }
133+
//
134+
// for(String name: openedMacros) {
135+
// if(name.equals("if")) {
136+
// results.addElement(reuseClosingTag("else"));
137+
// results.addElement(reuseClosingTag("elseif"));
138+
// }
139+
// results.addElement(reuseClosingTag("/" + name));
140+
// }
141+
//
142+
// results.stopHere();
143+
// }
144+
//
145+
// // Modifiers (if after pipe)
146+
// PsiElement prev = curr.getPrevSibling();
147+
// if(prev != null && prev instanceof PsiWhiteSpace) prev = prev.getPrevSibling();
148+
// if(prev != null && prev.getNode().getElementType() == SvelteTokenTypes.MODIFIER) {
149+
// for(LookupElementBuilder x: FILTER_LOOKUPS) results.addElement(x);
150+
// results.stopHere();
151+
// }
152+
// }
153+
//
154+
// // Get closing tag
155+
// private LookupElementBuilder reuseClosingTag(String name) {
156+
// if(!CLOSING_LOOKUPS.containsKey(name)) {
157+
// CLOSING_LOOKUPS.put(name, LookupElementBuilder.create(name));
158+
// }
159+
//
160+
// return CLOSING_LOOKUPS.get(name);
161+
// }
136162
}

0 commit comments

Comments
 (0)