From 6c26aab43c5fcd7ada2b3c84eed508f55f9f8fef Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Wed, 1 Nov 2023 16:31:31 +0100 Subject: [PATCH] Add support for mixins. (#230) --- code_mirror/toit.js | 29 ++++++++++++++++++++++------ start/vim/syntax/toit.vim | 4 ++-- vscode/syntaxes/toit.tmLanguage.json | 6 +++++- vscode/syntaxes/toit.tmLanguage.yaml | 4 +++- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/code_mirror/toit.js b/code_mirror/toit.js index 711a3fc..f531cd6 100644 --- a/code_mirror/toit.js +++ b/code_mirror/toit.js @@ -576,11 +576,13 @@ var CLASS_SIGNATURE_AFTER_NAME = 1; var CLASS_SIGNATURE_AFTER_EXTENDS = 2; var CLASS_SIGNATURE_AFTER_EXTENDS_TYPE = 3 - var CLASS_SIGNATURE_AFTER_IMPLEMENTS = 4; - var CLASS_SIGNATURE_AFTER_FIRST_IMPLEMENTS_NAME = 5; - var CLASS_BODY = 6; + var CLASS_SIGNATURE_AFTER_WITH = 4 + var CLASS_SIGNATURE_AFTER_FIRST_WITH_NAME = 5; + var CLASS_SIGNATURE_AFTER_IMPLEMENTS = 6; + var CLASS_SIGNATURE_AFTER_FIRST_IMPLEMENTS_NAME = 7; + var CLASS_BODY = 8; function tryClass(stream, state) { - if (stream.match(/(abstract[ ]+)?class\b/) || stream.match(/interface\b/)) { + if (stream.match(/(abstract[ ]+)?class\b/) || stream.match(/interface\b/) || stream.match(/mixin\b/) || stream.match(/monitor\b/)) { state.context.push([tokenizeClass, 2]); state.subState.push(CLASS_SIGNATURE_AFTER_CLASS); return "keyword" @@ -617,9 +619,13 @@ setSubState(state, CLASS_SIGNATURE_AFTER_EXTENDS); return "keyword"; } - // Fall through. + // Fall through. case CLASS_SIGNATURE_AFTER_EXTENDS_TYPE: + if (stream.match(/with\b/)) { + setSubState(state, CLASS_SIGNATURE_AFTER_WITH); + return "keyword"; + } if (stream.match(/implements\b/)) { setSubState(state, CLASS_SIGNATURE_AFTER_IMPLEMENTS); return "keyword"; @@ -635,12 +641,17 @@ setSubState(state, CLASS_SIGNATURE_AFTER_EXTENDS_TYPE); return tokenizeType(stream, state, false); + case CLASS_SIGNATURE_AFTER_WITH: case CLASS_SIGNATURE_AFTER_IMPLEMENTS: // The first *requires* an type. if (!stream.match(TYPE, false)) return signatureError(); - setSubState(state, CLASS_SIGNATURE_AFTER_FIRST_IMPLEMENTS_NAME); + const nextSubState = subState(state) == CLASS_SIGNATURE_AFTER_WITH + ? CLASS_SIGNATURE_AFTER_FIRST_WITH_NAME + : CLASS_SIGNATURE_AFTER_FIRST_IMPLEMENTS_NAME; + setSubState(state, nextSubState); return tokenizeType(stream, state, false); + case CLASS_SIGNATURE_AFTER_FIRST_WITH_NAME: case CLASS_SIGNATURE_AFTER_FIRST_IMPLEMENTS_NAME: if (stream.match(TYPE, false)) { return tokenizeType(stream, state, false); @@ -649,6 +660,12 @@ setSubState(state, CLASS_BODY); return "class_body_colon"; } + if (subState(state) == CLASS_SIGNATURE_AFTER_FIRST_WITH_NAME) { + if (stream.match(/implements\b/)) { + setSubState(state, CLASS_SIGNATURE_AFTER_IMPLEMENTS); + return "keyword"; + } + } return signatureError(); case CLASS_BODY: diff --git a/start/vim/syntax/toit.vim b/start/vim/syntax/toit.vim index 250f0e1..6c64d3f 100644 --- a/start/vim/syntax/toit.vim +++ b/start/vim/syntax/toit.vim @@ -29,7 +29,7 @@ syntax sync minlines=500 " TODO: Find out why 'syntax iskeyword' doesn't work. setlocal iskeyword=a-z,A-Z,48-57,_,- -syntax keyword toitKeyword it super extends implements as return abstract static unreachable break continue +syntax keyword toitKeyword it super extends implements as return abstract static unreachable break continue with highlight link toitKeyword Keyword syntax keyword toitNull null @@ -175,7 +175,7 @@ highlight link toitDeclaration Identifier syntax match toitToplevelDeclaration "\v^[a-zA-Z_][a-zA-Z0-9_-]*" highlight link toitToplevelDeclaration Identifier -syntax region toitClass matchgroup=toitStructure start=/\v(^|^abstract[ ]+)@<=(class|interface)>/ end=/\v^[^ ]@=/ contains=toitComment,toitMultiComment,toitMemberDeclaration,toitKeyword +syntax region toitClass matchgroup=toitStructure start=/\v(^|^abstract[ ]+)@<=(class|interface|mixin|monitor)>/ end=/\v^[^ ]@=/ contains=toitComment,toitMultiComment,toitMemberDeclaration,toitKeyword highlight link toitStructure Structure syntax region toitMemberBody start="" end=/\v(^ ? ?[a-zA-Z0-9_-])@=/ contained contains=TOP diff --git a/vscode/syntaxes/toit.tmLanguage.json b/vscode/syntaxes/toit.tmLanguage.json index 240b23d..8b64cad 100644 --- a/vscode/syntaxes/toit.tmLanguage.json +++ b/vscode/syntaxes/toit.tmLanguage.json @@ -69,7 +69,7 @@ }, "class-section": { "name": "meta.class.toit", - "begin": "^(?:(abstract)[ ]+)?(class|monitor|interface)(?!-)\\b", + "begin": "^(?:(abstract)[ ]+)?(class|interface|mixin|monitor)(?!-)\\b", "end": "^(?=[^\\s/]|/[^/*])", "beginCaptures": { "1": { @@ -129,6 +129,10 @@ "name": "keyword.control.implements.toit", "match": "\\b(?