From a3d82924a904c2b09c0fcee486c452acca5dc5fb Mon Sep 17 00:00:00 2001 From: olane Date: Fri, 10 Aug 2018 13:17:45 +0100 Subject: [PATCH] Create case variations of the keywords Apex is case insensitive, but we can't make the highlighter case insensitive without breaking the heuristic which assumes that identifiers starting with an upper case letter are types. As a compromise, create the common case variations of the keywords and match on all of them. --- src/apex/apex.test.ts | 35 +++++ src/apex/apex.ts | 299 ++++++++++++++++++++++-------------------- 2 files changed, 191 insertions(+), 143 deletions(-) diff --git a/src/apex/apex.test.ts b/src/apex/apex.test.ts index 9c6c9b8f..5f9f6c8f 100644 --- a/src/apex/apex.test.ts +++ b/src/apex/apex.test.ts @@ -251,6 +251,41 @@ testTokenization('apex', [ ] }], + // Keywords with case variations + [{ + line: 'Package test; CLASS Program { Static void main(String[] args) {} } }', + tokens: [ + { startIndex: 0, type: 'keyword.Package.apex' }, + { startIndex: 7, type: '' }, + { startIndex: 8, type: 'identifier.apex' }, + { startIndex: 12, type: 'delimiter.apex' }, + { startIndex: 13, type: '' }, + { startIndex: 14, type: 'keyword.CLASS.apex' }, + { startIndex: 19, type: '' }, + { startIndex: 20, type: 'type.identifier.apex' }, + { startIndex: 27, type: '' }, + { startIndex: 28, type: 'delimiter.curly.apex' }, + { startIndex: 29, type: '' }, + { startIndex: 30, type: 'keyword.Static.apex' }, + { startIndex: 36, type: '' }, + { startIndex: 37, type: 'keyword.void.apex' }, + { startIndex: 41, type: '' }, + { startIndex: 42, type: 'identifier.apex' }, + { startIndex: 46, type: 'delimiter.parenthesis.apex' }, + { startIndex: 47, type: 'type.identifier.apex' }, + { startIndex: 53, type: 'delimiter.square.apex' }, + { startIndex: 55, type: '' }, + { startIndex: 56, type: 'identifier.apex' }, + { startIndex: 60, type: 'delimiter.parenthesis.apex' }, + { startIndex: 61, type: '' }, + { startIndex: 62, type: 'delimiter.curly.apex' }, + { startIndex: 64, type: '' }, + { startIndex: 65, type: 'delimiter.curly.apex' }, + { startIndex: 66, type: '' }, + { startIndex: 67, type: 'delimiter.curly.apex' } + ] + }], + // Numbers [{ line: '0', diff --git a/src/apex/apex.ts b/src/apex/apex.ts index b22fd9b4..c02eddd9 100644 --- a/src/apex/apex.ts +++ b/src/apex/apex.ts @@ -43,153 +43,166 @@ export const conf: IRichLanguageConfiguration = { } }; +const keywords = [ + 'abstract', + 'activate', + 'and', + 'any', + 'array', + 'as', + 'asc', + 'assert', + 'autonomous', + 'begin', + 'bigdecimal', + 'blob', + 'boolean', + 'break', + 'bulk', + 'by', + 'case', + 'cast', + 'catch', + 'char', + 'class', + 'collect', + 'commit', + 'const', + 'continue', + 'convertcurrency', + 'decimal', + 'default', + 'delete', + 'desc', + 'do', + 'double', + 'else', + 'end', + 'enum', + 'exception', + 'exit', + 'export', + 'extends', + 'false', + 'final', + 'finally', + 'float', + 'for', + 'from', + 'future', + 'get', + 'global', + 'goto', + 'group', + 'having', + 'hint', + 'if', + 'implements', + 'import', + 'in', + 'inner', + 'insert', + 'instanceof', + 'int', + 'interface', + 'into', + 'join', + 'last_90_days', + 'last_month', + 'last_n_days', + 'last_week', + 'like', + 'limit', + 'list', + 'long', + 'loop', + 'map', + 'merge', + 'native', + 'new', + 'next_90_days', + 'next_month', + 'next_n_days', + 'next_week', + 'not', + 'null', + 'nulls', + 'number', + 'object', + 'of', + 'on', + 'or', + 'outer', + 'override', + 'package', + 'parallel', + 'pragma', + 'private', + 'protected', + 'public', + 'retrieve', + 'return', + 'returning', + 'rollback', + 'savepoint', + 'search', + 'select', + 'set', + 'short', + 'sort', + 'stat', + 'static', + 'strictfp', + 'super', + 'switch', + 'synchronized', + 'system', + 'testmethod', + 'then', + 'this', + 'this_month', + 'this_week', + 'throw', + 'throws', + 'today', + 'tolabel', + 'tomorrow', + 'transaction', + 'transient', + 'trigger', + 'true', + 'try', + 'type', + 'undelete', + 'update', + 'upsert', + 'using', + 'virtual', + 'void', + 'volatile', + 'webservice', + 'when', + 'where', + 'while', + 'yesterday' +]; + +// create case variations of the keywords - apex is case insensitive, but we can't make the highlighter case insensitive +// because we use a heuristic to assume that identifiers starting with an upper case letter are types. +const uppercaseFirstLetter = (lowercase) => lowercase.charAt(0).toUpperCase() + lowercase.substr(1); + +let keywordsWithCaseVariations = []; +keywords.forEach(lowercase => { + keywordsWithCaseVariations.push(lowercase); + keywordsWithCaseVariations.push(lowercase.toUpperCase()); + keywordsWithCaseVariations.push(uppercaseFirstLetter(lowercase)); +}) + export const language = { defaultToken: '', tokenPostfix: '.apex', - keywords: [ - 'abstract', - 'activate', - 'and', - 'any', - 'array', - 'as', - 'asc', - 'assert', - 'autonomous', - 'begin', - 'bigdecimal', - 'blob', - 'boolean', - 'break', - 'bulk', - 'by', - 'case', - 'cast', - 'catch', - 'char', - 'class', - 'collect', - 'commit', - 'const', - 'continue', - 'convertcurrency', - 'decimal', - 'default', - 'delete', - 'desc', - 'do', - 'double', - 'else', - 'end', - 'enum', - 'exception', - 'exit', - 'export', - 'extends', - 'false', - 'final', - 'finally', - 'float', - 'for', - 'from', - 'future', - 'get', - 'global', - 'goto', - 'group', - 'having', - 'hint', - 'if', - 'implements', - 'import', - 'in', - 'inner', - 'insert', - 'instanceof', - 'int', - 'interface', - 'into', - 'join', - 'last_90_days', - 'last_month', - 'last_n_days', - 'last_week', - 'like', - 'limit', - 'list', - 'long', - 'loop', - 'map', - 'merge', - 'native', - 'new', - 'next_90_days', - 'next_month', - 'next_n_days', - 'next_week', - 'not', - 'null', - 'nulls', - 'number', - 'object', - 'of', - 'on', - 'or', - 'outer', - 'override', - 'package', - 'parallel', - 'pragma', - 'private', - 'protected', - 'public', - 'retrieve', - 'return', - 'returning', - 'rollback', - 'savepoint', - 'search', - 'select', - 'set', - 'short', - 'sort', - 'stat', - 'static', - 'strictfp', - 'super', - 'switch', - 'synchronized', - 'system', - 'testmethod', - 'then', - 'this', - 'this_month', - 'this_week', - 'throw', - 'throws', - 'today', - 'tolabel', - 'tomorrow', - 'transaction', - 'transient', - 'trigger', - 'true', - 'try', - 'type', - 'undelete', - 'update', - 'upsert', - 'using', - 'virtual', - 'void', - 'volatile', - 'webservice', - 'when', - 'where', - 'while', - 'yesterday' - ], + keywords: keywordsWithCaseVariations, operators: [ '=', '>', '<', '!', '~', '?', ':',