From 6b16c222e44a8b29b21029300bd9133723eb6209 Mon Sep 17 00:00:00 2001 From: Peter Judge Date: Thu, 22 Feb 2024 21:46:16 -0500 Subject: [PATCH] Fixes for FINALLY blocks; additional FOR terminators --- abl.tmLanguage.json | 57 +++++++++++-- spec/blocks/finally-blocks.spec.js | 51 ++++++++++++ spec/db-table-and-field/foreach.spec.js | 93 +++++++++++++++++++++- spec/db-table-and-field/issue#88.spec.js | 14 ++++ spec/method-definition/constructor.spec.js | 2 +- spec/method-definition/method.spec.js | 2 +- 6 files changed, 210 insertions(+), 9 deletions(-) create mode 100644 spec/blocks/finally-blocks.spec.js diff --git a/abl.tmLanguage.json b/abl.tmLanguage.json index 94bea88..700cf1b 100644 --- a/abl.tmLanguage.json +++ b/abl.tmLanguage.json @@ -79,7 +79,7 @@ } }, "comment": "The lookahead on the regex for the closing colon is required to make this scope end properly", - "end": "\\s*(?=:)", + "end": "(?=:)", "patterns": [ { "include": "#access-modifier" @@ -326,6 +326,9 @@ { "include": "#block-label" }, + { + "include": "#end-block" + }, { "include": "#end-function-procedure-method-block" }, @@ -497,6 +500,9 @@ }, { "include": "#variable-name" + }, + { + "include": "#punctuation-period" } ] }, @@ -1751,7 +1757,7 @@ "name": "storage.data.table.abl" } }, - "end": "(?i)\\s*(?=where|no-lock|share-lock|exclusive-lock|tenant-where|use-index|table-scan|using|no-prefetch|left|outer-join|,|:)\\s*", + "end": "(?i)\\s*(?=where|no-lock|share-lock|exclusive-lock|tenant-where|use-index|table-scan|using|no-prefetch|left|outer-join|break|by|transaction,|:)\\s*", "patterns": [ { "include": "#fields-except-list" @@ -1789,7 +1795,7 @@ "name": "keyword.other.abl" } }, - "end": "(?i)\\s*(?=where|no-lock|share-lock|exclusive-lock|tenant-where|use-index|table-scan|using|no-prefetch|left|outer-join|,|:)\\s*", + "end": "(?i)\\s*(?=where|no-lock|share-lock|exclusive-lock|tenant-where|use-index|table-scan|using|no-prefetch|left|outer-join|break|by|transaction|,|:)\\s*", "patterns": [ { "match": "(?i)\\s*(each|first|last|of)\\s*", @@ -1963,6 +1969,9 @@ { "include": "#block-statement" }, + { + "include": "#end-block" + }, { "include": "#property-call" }, @@ -2107,8 +2116,16 @@ "name": "keyword.other.abl" } }, - "end": "(?<=\\s)", + "end": "(?=\\s|\\)|\\.)", "patterns": [ + { + "match": "(?i)\\s*(class)\\s*", + "captures": { + "1": { + "name": "keyword.other.abl" + } + } + }, { "include": "#dll-type" }, @@ -2123,6 +2140,18 @@ }, { "include": "#type-name" + }, + { + "include": "#parens" + }, + { + "include": "#string" + }, + { + "include": "#punctuation-period" + }, + { + "include": "#punctuation-comma" } ] }, @@ -2581,8 +2610,20 @@ } } }, + "end-block": { + "comment": "Certain blocks have the option of END ", + "match": "(?i)\\s*(end)\\s+(CASE|CATCH|CLASS|CONSTRUCTOR|DESTRUCTOR|ENUM|FINALLY|FUNCTION|GET|INTERFACE|METHOD|PROCEDURE|SET|TRIGGERS)\\s*", + "captures": { + "1": { + "name": "keyword.other.abl" + }, + "2": { + "name": "keyword.other.abl" + } + } + }, "block-statement": { - "begin": "(?i)\\s*(do|repeat)\\s*", + "begin": "(?i)(? { + let statement = `FINALLY: + ASSIGN oBusinessEntityDescriptor = ?. +END FINALLY.`; + let expectedTokens = [ + [ + { "startIndex": 0, "endIndex": 7, "scopes": ["source.abl", "meta.block.abl", "keyword.other.abl"] }, // 'FINALLY' + { "startIndex": 7, "endIndex": 9, "scopes": ["source.abl"] } // ':' + ], + [ + { "startIndex": 0, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 10, "scopes": ["source.abl", "keyword.other.abl"] }, // 'ASSIGN' + { "startIndex": 10, "endIndex": 11, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 11, "endIndex": 36, "scopes": ["source.abl", "variable.other.abl"] }, // 'oBusinessEntityDescriptor' + { "startIndex": 36, "endIndex": 37, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 37, "endIndex": 38, "scopes": ["source.abl", "keyword.operator.source.abl"] }, // '=' + { "startIndex": 38, "endIndex": 39, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 39, "endIndex": 40, "scopes": ["source.abl", "constant.language.abl"] }, // '?' + { "startIndex": 40, "endIndex": 41, "scopes": ["source.abl", "punctuation.terminator.abl"] } // '.' + ], + [ + { "startIndex": 0, "endIndex": 3, "scopes": ["source.abl", "keyword.other.abl"] }, // 'END' + { "startIndex": 3, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 11, "scopes": ["source.abl", "keyword.other.abl"] }, // 'FINALLY' + { "startIndex": 11, "endIndex": 12, "scopes": ["source.abl", "punctuation.terminator.abl"] } // '.' + ] + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) + +describe('', () => { + let statement = `FINALLY: + END. // no finally on END`; + let expectedTokens = [ + [ + { "startIndex": 0, "endIndex": 7, "scopes": ["source.abl", "meta.block.abl", "keyword.other.abl"] }, // 'FINALLY' + { "startIndex": 7, "endIndex": 9, "scopes": ["source.abl"] } // ':' + ], + [ + { "startIndex": 0, "endIndex": 2, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 2, "endIndex": 5, "scopes": ["source.abl", "keyword.other.abl"] }, // 'END' + { "startIndex": 5, "endIndex": 6, "scopes": ["source.abl", "punctuation.terminator.abl"] }, // '.' + { "startIndex": 6, "endIndex": 7, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 7, "endIndex": 27, "scopes": ["source.abl", "comment.line.double-slash.abl"] } // '// no finally on END' + ] + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) diff --git a/spec/db-table-and-field/foreach.spec.js b/spec/db-table-and-field/foreach.spec.js index c776d77..4044739 100644 --- a/spec/db-table-and-field/foreach.spec.js +++ b/spec/db-table-and-field/foreach.spec.js @@ -433,4 +433,95 @@ describe('', () => { { "startIndex": 0, "endIndex": 11, "scopes": ["source.abl"] } // ' @Befor' ]; shared.itShouldMatchExpectedScopes(statement, expectedTokens); -}) \ No newline at end of file +}) + +describe('', () => { + let statement = `FOR EACH ttTaskMethods + BREAK BY ttTaskMethods.ClassName:`; + let expectedTokens = [ + [ + { "startIndex": 0, "endIndex": 3, "scopes": ["source.abl", "keyword.other.abl"] }, // 'FOR' + { "startIndex": 3, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 8, "scopes": ["source.abl", "keyword.other.abl"] }, // 'EACH' + { "startIndex": 8, "endIndex": 9, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 9, "endIndex": 22, "scopes": ["source.abl", "storage.data.table.abl"] } // 'ttTaskMethods' + ], + [ + { "startIndex": 0, "endIndex": 8, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 8, "endIndex": 13, "scopes": ["source.abl", "keyword.other.abl"] }, // 'BREAK' + { "startIndex": 13, "endIndex": 14, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 14, "endIndex": 16, "scopes": ["source.abl", "keyword.other.abl"] }, // 'BY' + { "startIndex": 16, "endIndex": 17, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 17, "endIndex": 40, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods.ClassName' + { "startIndex": 40, "endIndex": 42, "scopes": ["source.abl"] } // ':' + ] + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) + +describe('', () => { + let statement = `FOR EACH ttTaskMethods BY ttTaskMethods.ClassName:`; + let expectedTokens = [ + { "startIndex": 0, "endIndex": 3, "scopes": ["source.abl", "keyword.other.abl"] }, // 'FOR' + { "startIndex": 3, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 8, "scopes": ["source.abl", "keyword.other.abl"] }, // 'EACH' + { "startIndex": 8, "endIndex": 9, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 9, "endIndex": 22, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods' + { "startIndex": 22, "endIndex": 23, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 23, "endIndex": 25, "scopes": ["source.abl", "keyword.other.abl"] }, // 'BY' + { "startIndex": 25, "endIndex": 26, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 26, "endIndex": 49, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods.ClassName' + { "startIndex": 49, "endIndex": 51, "scopes": ["source.abl"] } // ':' + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) + +describe('', () => { + let statement = `FOR EACH ttTaskMethods transACTION:`; + let expectedTokens = [ + { "startIndex": 0, "endIndex": 3, "scopes": ["source.abl", "keyword.other.abl"] }, // 'FOR' + { "startIndex": 3, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 8, "scopes": ["source.abl", "keyword.other.abl"] }, // 'EACH' + { "startIndex": 8, "endIndex": 9, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 9, "endIndex": 22, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods' + { "startIndex": 22, "endIndex": 23, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 23, "endIndex": 34, "scopes": ["source.abl", "keyword.other.abl"] }, // 'transACTION' + { "startIndex": 34, "endIndex": 36, "scopes": ["source.abl"] } // ':' + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) + +describe('', () => { + let statement = `FOR EACH ttTaskMethods WHERE ttTaskMethods.field <> ? + BY ttTaskMethods.ClassName + TRANSACTION:`; + let expectedTokens = [ + [ + { "startIndex": 0, "endIndex": 3, "scopes": ["source.abl", "keyword.other.abl"] }, // 'FOR' + { "startIndex": 3, "endIndex": 4, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 4, "endIndex": 8, "scopes": ["source.abl", "keyword.other.abl"] }, // 'EACH' + { "startIndex": 8, "endIndex": 9, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 9, "endIndex": 22, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods' + { "startIndex": 22, "endIndex": 23, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 23, "endIndex": 28, "scopes": ["source.abl", "keyword.other.abl"] }, // 'WHERE' + { "startIndex": 28, "endIndex": 29, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 29, "endIndex": 48, "scopes": ["source.abl", "storage.data.table.abl"] }, // 'ttTaskMethods.field' + { "startIndex": 48, "endIndex": 49, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 49, "endIndex": 51, "scopes": ["source.abl", "keyword.operator.source.abl"] }, // '<>' + { "startIndex": 51, "endIndex": 52, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 52, "endIndex": 53, "scopes": ["source.abl", "constant.language.abl"] } // '?' + ], + [ + { "startIndex": 0, "endIndex": 2, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 2, "endIndex": 4, "scopes": ["source.abl", "keyword.other.abl"] }, // 'BY' + { "startIndex": 4, "endIndex": 5, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 5, "endIndex": 28, "scopes": ["source.abl", "storage.data.table.abl"] } // 'ttTaskMethods.ClassName' + ], + [ + { "startIndex": 0, "endIndex": 2, "scopes": ["source.abl"] }, // ' ' + { "startIndex": 2, "endIndex": 13, "scopes": ["source.abl", "meta.block.label.abl"] }, // 'TRANSACTION' + { "startIndex": 13, "endIndex": 15, "scopes": ["source.abl"] } // ':' + ] + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) diff --git a/spec/db-table-and-field/issue#88.spec.js b/spec/db-table-and-field/issue#88.spec.js index 5f58ab2..f86379d 100644 --- a/spec/db-table-and-field/issue#88.spec.js +++ b/spec/db-table-and-field/issue#88.spec.js @@ -103,4 +103,18 @@ describe('', () => { ] ]; shared.itShouldMatchExpectedScopes(statement, expectedTokens); +}) + +describe('', () => { + let statement = `//exclusive-lock: +//no-lock:`; + let expectedTokens = [ + [ + { "startIndex": 0, "endIndex": 17, "scopes": ["source.abl", "comment.line.double-slash.abl"] } // '//exclusive-lock:' + ], + [ + { "startIndex": 0, "endIndex": 10, "scopes": ["source.abl", "comment.line.double-slash.abl"] } // '//no-lock:' + ] + ]; + shared.itShouldMatchExpectedScopes(statement, expectedTokens); }) \ No newline at end of file diff --git a/spec/method-definition/constructor.spec.js b/spec/method-definition/constructor.spec.js index e2946a0..e3f8943 100644 --- a/spec/method-definition/constructor.spec.js +++ b/spec/method-definition/constructor.spec.js @@ -65,7 +65,7 @@ end constructor.`; { "startIndex": 68, "endIndex": 69, "scopes": ["source.abl", "meta.define.method.abl"] }, // ' ' { "startIndex": 69, "endIndex": 71, "scopes": ["source.abl", "meta.define.method.abl", "keyword.other.abl"] }, // 'as' { "startIndex": 71, "endIndex": 72, "scopes": ["source.abl", "meta.define.method.abl"] }, // ' ' - { "startIndex": 72, "endIndex": 78, "scopes": ["source.abl", "meta.define.method.abl", "keyword.other.abl"] }, // 'Object' + { "startIndex": 72, "endIndex": 78, "scopes": ["source.abl", "meta.define.method.abl", "entity.name.type.abl"] }, // 'Object' { "startIndex": 78, "endIndex": 79, "scopes": ["source.abl", "meta.define.method.abl", "meta.brace.round.js"] }, // ')' { "startIndex": 79, "endIndex": 81, "scopes": ["source.abl"] } // ':' ], diff --git a/spec/method-definition/method.spec.js b/spec/method-definition/method.spec.js index 7aa61fd..cc0d0b6 100644 --- a/spec/method-definition/method.spec.js +++ b/spec/method-definition/method.spec.js @@ -68,7 +68,7 @@ end method.`; { "startIndex": 64, "endIndex": 65, "scopes": ["source.abl", "meta.define.method.abl"] }, // ' ' { "startIndex": 65, "endIndex": 67, "scopes": ["source.abl", "meta.define.method.abl", "keyword.other.abl"] }, // 'as' { "startIndex": 67, "endIndex": 68, "scopes": ["source.abl", "meta.define.method.abl"] }, // ' ' - { "startIndex": 68, "endIndex": 74, "scopes": ["source.abl", "meta.define.method.abl", "keyword.other.abl"] }, // 'Object' + { "startIndex": 68, "endIndex": 74, "scopes": ["source.abl", "meta.define.method.abl", "entity.name.type.abl"] }, // 'Object' { "startIndex": 74, "endIndex": 75, "scopes": ["source.abl", "meta.define.method.abl", "meta.brace.round.js"] }, // ')' { "startIndex": 75, "endIndex": 77, "scopes": ["source.abl"] } // ':' ],