refine blocks detection
This commit is contained in:
@@ -233,6 +233,9 @@ export class EftlParser {
|
|||||||
case TokenType.VALUE_OF:
|
case TokenType.VALUE_OF:
|
||||||
case TokenType.SIZE_OF:
|
case TokenType.SIZE_OF:
|
||||||
case TokenType.HEADER:
|
case TokenType.HEADER:
|
||||||
|
if (!token.value.endsWith('/]')) {
|
||||||
|
this.pushBlock(token);
|
||||||
|
}
|
||||||
this.advance();
|
this.advance();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -249,6 +252,9 @@ export class EftlParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private pushBlock(token: Token): void {
|
private pushBlock(token: Token): void {
|
||||||
|
if (token.value.endsWith('/]')) {
|
||||||
|
return; // It's self-closing, don't push to stack
|
||||||
|
}
|
||||||
this.blockStack.push({ type: token.type, token });
|
this.blockStack.push({ type: token.type, token });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,6 +301,9 @@ export class EftlParser {
|
|||||||
[TokenType.TRIM_OPEN]: '[/TRIM]',
|
[TokenType.TRIM_OPEN]: '[/TRIM]',
|
||||||
[TokenType.CONTAINS_OPEN]: '[/CONTAINS]',
|
[TokenType.CONTAINS_OPEN]: '[/CONTAINS]',
|
||||||
[TokenType.FORMAT_OPEN]: '[/FORMAT]',
|
[TokenType.FORMAT_OPEN]: '[/FORMAT]',
|
||||||
|
[TokenType.VALUE_OF]: '[/VALUE_OF]',
|
||||||
|
[TokenType.SIZE_OF]: '[/SIZE_OF]',
|
||||||
|
[TokenType.HEADER]: '[/HEADER]',
|
||||||
[TokenType.EXPR_OPEN]: '%]',
|
[TokenType.EXPR_OPEN]: '%]',
|
||||||
[TokenType.EXPR_OUTPUT_OPEN]: '%]',
|
[TokenType.EXPR_OUTPUT_OPEN]: '%]',
|
||||||
[TokenType.COMMENT_OPEN]: '--]'
|
[TokenType.COMMENT_OPEN]: '--]'
|
||||||
|
|||||||
+2
-8
@@ -298,7 +298,7 @@ export class EftlTokenizer {
|
|||||||
|
|
||||||
private scanVarOpen(startLine: number, startColumn: number): void {
|
private scanVarOpen(startLine: number, startColumn: number): void {
|
||||||
let value = '[VAR';
|
let value = '[VAR';
|
||||||
// Scan until we find ] or ]
|
// Scan until we find ]
|
||||||
while (this.pos < this.source.length && this.peek() !== ']') {
|
while (this.pos < this.source.length && this.peek() !== ']') {
|
||||||
value += this.advance();
|
value += this.advance();
|
||||||
}
|
}
|
||||||
@@ -328,13 +328,7 @@ export class EftlTokenizer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch === ']') {
|
if (ch === ']') {
|
||||||
// Not self-closing, error
|
// Could be block start, let parser handle it if it's supposed to be self-closing
|
||||||
this.errors.push({
|
|
||||||
message: `Expected self-closing tag: [${tagName} ... /]`,
|
|
||||||
line: startLine,
|
|
||||||
column: startColumn,
|
|
||||||
length: value.length
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+122
-145
@@ -94,7 +94,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword.operator.arithmetic.eftl",
|
"name": "keyword.operator.arithmetic.eftl",
|
||||||
"match": "[+\\-*/%]"
|
"match": "([+\\-*%]|/(?!\\]))"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "keyword.operator.comparison.eftl",
|
"name": "keyword.operator.comparison.eftl",
|
||||||
@@ -129,45 +129,85 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tags": {
|
"attributes": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "meta.tag.data.eftl",
|
"comment": "name attribute",
|
||||||
"begin": "(\\[TAG\\])",
|
"match": "\\b(name)\\b\\s*(=)\\s*(\"(.*?)\")",
|
||||||
"end": "(\\[/TAG\\])",
|
"captures": {
|
||||||
"beginCaptures": {
|
"1": { "name": "entity.other.attribute-name.eftl" },
|
||||||
"1": { "name": "entity.name.tag.eftl" }
|
"2": { "name": "punctuation.separator.key-value.eftl" },
|
||||||
},
|
"3": { "name": "string.quoted.double.eftl" },
|
||||||
"endCaptures": {
|
"4": { "name": "variable.other.eftl" }
|
||||||
"1": { "name": "entity.name.tag.eftl" }
|
}
|
||||||
},
|
},
|
||||||
"patterns": [
|
{
|
||||||
{ "include": "#tag-content" }
|
"comment": "type attribute",
|
||||||
]
|
"match": "\\b(type)\\b\\s*(=)\\s*(\"(string|boolean|number|date|object|iterable)\")",
|
||||||
|
"captures": {
|
||||||
|
"1": { "name": "entity.other.attribute-name.eftl" },
|
||||||
|
"2": { "name": "punctuation.separator.key-value.eftl" },
|
||||||
|
"3": { "name": "string.quoted.double.eftl" },
|
||||||
|
"4": { "name": "support.type.primitive.eftl" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment": "generic attribute",
|
||||||
|
"match": "\\b([a-zA-Z_][a-zA-Z0-9_-]*)\\b\\s*(=)\\s*(\"(.*?)\")",
|
||||||
|
"captures": {
|
||||||
|
"1": { "name": "entity.other.attribute-name.eftl" },
|
||||||
|
"2": { "name": "punctuation.separator.key-value.eftl" },
|
||||||
|
"3": { "name": "string.quoted.double.eftl" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tag-content": {
|
"tag-open-context": {
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#attributes" },
|
||||||
|
{ "include": "#expressions" },
|
||||||
|
{ "include": "#functions" },
|
||||||
|
{ "include": "#tags" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "support.function.builtin.eftl",
|
"name": "meta.tag.block.eftl",
|
||||||
"match": "\\b(GETVALUEBYTAG|SCHEMAID|PLUGIN_DOM_PARAM)\\b"
|
"begin": "(\\[)(TAG)(?:\\s+[^\\x00]*?)?(?<!/)(\\])",
|
||||||
|
"end": "(\\[/)(TAG)(\\])",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": { "name": "entity.name.tag.eftl" },
|
||||||
|
"2": { "name": "entity.name.tag.eftl" },
|
||||||
|
"3": { "name": "entity.name.tag.eftl" }
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": { "name": "entity.name.tag.eftl" },
|
||||||
|
"2": { "name": "entity.name.tag.eftl" },
|
||||||
|
"3": { "name": "entity.name.tag.eftl" }
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#expressions" },
|
||||||
|
{ "include": "#tags" },
|
||||||
|
{ "include": "#functions" },
|
||||||
|
{ "include": "#control-structures" },
|
||||||
|
{ "include": "#variables" }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "variable.parameter.eftl",
|
"name": "meta.tag.eftl",
|
||||||
"match": "\\b(REQUEST|MODULE|IUQOID)\\b"
|
"begin": "(\\[)(TAG)\\b",
|
||||||
},
|
"end": "(/\\s*\\]|(?<!/)\\])",
|
||||||
{
|
"beginCaptures": {
|
||||||
"name": "constant.numeric.eftl",
|
"1": { "name": "entity.name.tag.eftl" },
|
||||||
"match": "\\b[0-9]+\\b"
|
"2": { "name": "entity.name.tag.eftl" }
|
||||||
},
|
},
|
||||||
{
|
"endCaptures": {
|
||||||
"name": "variable.other.eftl",
|
"0": { "name": "entity.name.tag.eftl" }
|
||||||
"match": "\\b(COL[0-9]+)\\b"
|
},
|
||||||
},
|
"patterns": [
|
||||||
{
|
{ "include": "#tag-open-context" }
|
||||||
"name": "punctuation.separator.eftl",
|
]
|
||||||
"match": ","
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -175,14 +215,18 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "meta.header.eftl",
|
"name": "meta.header.eftl",
|
||||||
"match": "(\\[HEADER)\\s+(name=\"[^\"]*\")\\s+(value=\"[^\"]*\")\\s+(type=\"[^\"]*\")\\s*(/\\])",
|
"begin": "(\\[)(HEADER)\\b",
|
||||||
"captures": {
|
"end": "(/\\s*\\]|(?<!/)\\])",
|
||||||
|
"beginCaptures": {
|
||||||
"1": { "name": "keyword.other.header.eftl" },
|
"1": { "name": "keyword.other.header.eftl" },
|
||||||
"2": { "name": "entity.other.attribute-name.eftl" },
|
"2": { "name": "keyword.other.header.eftl" }
|
||||||
"3": { "name": "string.quoted.double.eftl" },
|
},
|
||||||
"4": { "name": "entity.other.attribute-name.eftl" },
|
"endCaptures": {
|
||||||
"5": { "name": "punctuation.definition.tag.end.eftl" }
|
"0": { "name": "keyword.other.header.eftl" }
|
||||||
}
|
},
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#tag-open-context" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -201,146 +245,79 @@
|
|||||||
"variables": {
|
"variables": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "meta.variable.declaration.eftl",
|
"name": "meta.variable.block.eftl",
|
||||||
"begin": "(\\[VAR)",
|
"begin": "(\\[)(VAR)(?:\\s+[^\\x00]*?)?(?<!/)(\\])",
|
||||||
"end": "(\\[/VAR\\])",
|
"end": "(\\[/)(VAR)(\\])",
|
||||||
"beginCaptures": {
|
"beginCaptures": {
|
||||||
"1": { "name": "storage.type.variable.eftl" }
|
"1": { "name": "storage.type.variable.eftl" },
|
||||||
|
"2": { "name": "storage.type.variable.eftl" },
|
||||||
|
"3": { "name": "storage.type.variable.eftl" }
|
||||||
},
|
},
|
||||||
"endCaptures": {
|
"endCaptures": {
|
||||||
"1": { "name": "storage.type.variable.eftl" }
|
"1": { "name": "storage.type.variable.eftl" },
|
||||||
|
"2": { "name": "storage.type.variable.eftl" },
|
||||||
|
"3": { "name": "storage.type.variable.eftl" }
|
||||||
},
|
},
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{ "include": "#var-attributes" },
|
|
||||||
{ "include": "#expressions" },
|
{ "include": "#expressions" },
|
||||||
{ "include": "#functions" },
|
{ "include": "#functions" },
|
||||||
{ "include": "#tags" }
|
{ "include": "#tags" },
|
||||||
|
{ "include": "#control-structures" }
|
||||||
]
|
]
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"var-attributes": {
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"comment": "name attribute - variable name gets special color",
|
|
||||||
"match": "(name)(=)(\"([^\"]*)\")",
|
|
||||||
"captures": {
|
|
||||||
"1": { "name": "entity.other.attribute-name.name.eftl" },
|
|
||||||
"2": { "name": "punctuation.separator.key-value.eftl" },
|
|
||||||
"3": { "name": "string.quoted.double.eftl" },
|
|
||||||
"4": { "name": "variable.other.declaration.eftl" }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"comment": "type attribute with valid type values",
|
"name": "meta.variable.declaration.eftl",
|
||||||
"match": "(type)(=)(\"(string|boolean|number|date|object|iterable)\")",
|
"begin": "(\\[)(VAR)\\b",
|
||||||
"captures": {
|
"end": "(/\\s*\\]|(?<!/)\\])",
|
||||||
"1": { "name": "entity.other.attribute-name.type.eftl" },
|
"beginCaptures": {
|
||||||
"2": { "name": "punctuation.separator.key-value.eftl" },
|
"1": { "name": "storage.type.variable.eftl" },
|
||||||
"3": { "name": "string.quoted.double.eftl" },
|
"2": { "name": "storage.type.variable.eftl" }
|
||||||
"4": { "name": "support.type.primitive.eftl" }
|
},
|
||||||
}
|
"endCaptures": {
|
||||||
},
|
"0": { "name": "storage.type.variable.eftl" }
|
||||||
{
|
},
|
||||||
"comment": "unique attribute - boolean value",
|
"patterns": [
|
||||||
"match": "(unique)(=)(\"(true|false)\")",
|
{ "include": "#tag-open-context" }
|
||||||
"captures": {
|
]
|
||||||
"1": { "name": "entity.other.attribute-name.unique.eftl" },
|
|
||||||
"2": { "name": "punctuation.separator.key-value.eftl" },
|
|
||||||
"3": { "name": "string.quoted.double.eftl" },
|
|
||||||
"4": { "name": "constant.language.boolean.eftl" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "closing bracket of VAR open tag",
|
|
||||||
"match": "\\]",
|
|
||||||
"name": "punctuation.definition.tag.end.eftl"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"functions": {
|
"functions": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "meta.function.split.eftl",
|
"name": "meta.function.block.eftl",
|
||||||
"begin": "(\\[SPLIT)\\s+(regex=\"[^\"]*\")(\\])?",
|
"begin": "(\\[)(VALUE_OF|SIZE_OF|SPLIT|FORMAT|CONTAINS|TRIM)(?:\\s+[^\\x00]*?)?(?<!/)(\\])",
|
||||||
"end": "(\\[/SPLIT\\])",
|
"end": "(\\[/)(VALUE_OF|SIZE_OF|SPLIT|FORMAT|CONTAINS|TRIM)(\\])",
|
||||||
"beginCaptures": {
|
"beginCaptures": {
|
||||||
"1": { "name": "support.function.eftl" },
|
"1": { "name": "support.function.eftl" },
|
||||||
"2": { "name": "string.regexp.eftl" }
|
"2": { "name": "support.function.eftl" },
|
||||||
|
"3": { "name": "support.function.eftl" }
|
||||||
},
|
},
|
||||||
"endCaptures": {
|
"endCaptures": {
|
||||||
"1": { "name": "support.function.eftl" }
|
"1": { "name": "support.function.eftl" },
|
||||||
|
"2": { "name": "support.function.eftl" },
|
||||||
|
"3": { "name": "support.function.eftl" }
|
||||||
},
|
},
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{ "include": "#expressions" },
|
{ "include": "#expressions" },
|
||||||
|
{ "include": "#functions" },
|
||||||
{ "include": "#tags" },
|
{ "include": "#tags" },
|
||||||
{ "include": "#functions" }
|
{ "include": "#control-structures" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "meta.function.trim.eftl",
|
"name": "meta.function.eftl",
|
||||||
"begin": "(\\[TRIM\\])",
|
"begin": "(\\[)(VALUE_OF|SIZE_OF|SPLIT|FORMAT|CONTAINS|TRIM)\\b",
|
||||||
"end": "(\\[/TRIM\\])",
|
"end": "(/\\s*\\]|(?<!/)\\])",
|
||||||
"beginCaptures": {
|
|
||||||
"1": { "name": "support.function.eftl" }
|
|
||||||
},
|
|
||||||
"endCaptures": {
|
|
||||||
"1": { "name": "support.function.eftl" }
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{ "include": "#expressions" },
|
|
||||||
{ "include": "#tags" },
|
|
||||||
{ "include": "#functions" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta.function.contains.eftl",
|
|
||||||
"begin": "(\\[CONTAINS)\\s+(varname=\"[^\"]*\")(\\])?",
|
|
||||||
"end": "(\\[/CONTAINS\\])",
|
|
||||||
"beginCaptures": {
|
"beginCaptures": {
|
||||||
"1": { "name": "support.function.eftl" },
|
"1": { "name": "support.function.eftl" },
|
||||||
"2": { "name": "entity.other.attribute-name.eftl" }
|
"2": { "name": "support.function.eftl" }
|
||||||
},
|
},
|
||||||
"endCaptures": {
|
"endCaptures": {
|
||||||
"1": { "name": "support.function.eftl" }
|
"0": { "name": "support.function.eftl" }
|
||||||
},
|
},
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{ "include": "#functions" }
|
{ "include": "#tag-open-context" }
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta.function.value-of.eftl",
|
|
||||||
"match": "(\\[VALUE_OF)\\s+(varname=\"[^\"]*\")\\s*(index=\"?[^\"]*\"?)?\\s*(/\\])",
|
|
||||||
"captures": {
|
|
||||||
"1": { "name": "support.function.eftl" },
|
|
||||||
"2": { "name": "entity.other.attribute-name.eftl" },
|
|
||||||
"3": { "name": "entity.other.attribute-name.eftl" },
|
|
||||||
"4": { "name": "punctuation.definition.tag.end.eftl" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta.function.size-of.eftl",
|
|
||||||
"match": "(\\[SIZE_OF)\\s+(varname=\"[^\"]*\")\\s*(/\\])",
|
|
||||||
"captures": {
|
|
||||||
"1": { "name": "support.function.eftl" },
|
|
||||||
"2": { "name": "entity.other.attribute-name.eftl" },
|
|
||||||
"3": { "name": "punctuation.definition.tag.end.eftl" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta.function.format.eftl",
|
|
||||||
"begin": "(\\[FORMAT)\\s+(type=\"[^\"]*\")\\s*(pattern=\"[^\"]*\")?(\\])?",
|
|
||||||
"end": "(\\[/FORMAT\\])",
|
|
||||||
"beginCaptures": {
|
|
||||||
"1": { "name": "support.function.eftl" },
|
|
||||||
"2": { "name": "entity.other.attribute-name.eftl" },
|
|
||||||
"3": { "name": "string.other.pattern.eftl" }
|
|
||||||
},
|
|
||||||
"endCaptures": {
|
|
||||||
"1": { "name": "support.function.eftl" }
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{ "include": "#expressions" }
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user