From c4ff071e26f99f964431b873889b051d6d88c98c Mon Sep 17 00:00:00 2001 From: sanny-io Date: Thu, 13 Aug 2026 03:53:35 +0000 Subject: [PATCH 1/6] fix: procedure syntax highlighting --- packages/language/src/zmodel-semantic.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index 7910c78af..b0b10d266 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -21,6 +21,8 @@ import { isPluginField, isReferenceExpr, isTypeDef, + isProcedure, + isFunctionParamType, type AstNode, } from './ast'; @@ -62,7 +64,7 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'name', type: SemanticTokenTypes.variable, }); - } else if (isDataFieldType(node)) { + } else if (isDataFieldType(node) || isFunctionParamType(node)) { if (node.type) { acceptor({ node, @@ -88,7 +90,7 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'function', type: SemanticTokenTypes.function, }); - } else if (isFunctionDecl(node) || isAttribute(node)) { + } else if (isFunctionDecl(node) || isAttribute(node) || isProcedure(node)) { acceptor({ node, property: 'name', From d47fa2b70e4b9a6b913aa7360d4b5578e5f912bd Mon Sep 17 00:00:00 2001 From: sanny-io Date: Thu, 13 Aug 2026 22:42:04 +0000 Subject: [PATCH 2/6] fix: attribute param highlighting --- packages/language/src/zmodel-semantic.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index b0b10d266..0d70b0edd 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -23,6 +23,7 @@ import { isTypeDef, isProcedure, isFunctionParamType, + isAttributeParamType, type AstNode, } from './ast'; @@ -64,7 +65,7 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'name', type: SemanticTokenTypes.variable, }); - } else if (isDataFieldType(node) || isFunctionParamType(node)) { + } else if (isDataFieldType(node) || isFunctionParamType(node) || isAttributeParamType(node)) { if (node.type) { acceptor({ node, From aea4ad52aadab6494f3fe6c654fbec960599acec Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 14 Aug 2026 02:33:08 +0000 Subject: [PATCH 3/6] fix: binary, unary, boolean, number, null, collection predicate, and params --- packages/language/src/zmodel-semantic.ts | 91 ++++++++++++++++++++---- 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index 0d70b0edd..5f6254f36 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -24,6 +24,15 @@ import { isProcedure, isFunctionParamType, isAttributeParamType, + isUnaryExpr, + isBinaryExpr, + isBooleanLiteral, + isNumberLiteral, + isNullExpr, + isCollectionPredicateBinding, + isFunctionParam, + isAttributeParam, + isProcedureParam, type AstNode, } from './ast'; @@ -47,23 +56,17 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'baseModel', type: SemanticTokenTypes.type, }); - } else if (isDataSource(node) || isGeneratorDecl(node) || isPlugin(node) || isEnum(node) || isTypeDef(node)) { + } else if (isDataSource(node) || isGeneratorDecl(node) || isPlugin(node) || isTypeDef(node)) { acceptor({ node, property: 'name', type: SemanticTokenTypes.type, }); - } else if ( - isDataField(node) || - isConfigField(node) || - isAttributeArg(node) || - isPluginField(node) || - isEnumField(node) - ) { + } else if (isDataField(node) || isConfigField(node) || isPluginField(node)) { acceptor({ node, property: 'name', - type: SemanticTokenTypes.variable, + type: SemanticTokenTypes.property, }); } else if (isDataFieldType(node) || isFunctionParamType(node) || isAttributeParamType(node)) { if (node.type) { @@ -83,7 +86,21 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { acceptor({ node, property: 'decl', - type: SemanticTokenTypes.function, + type: SemanticTokenTypes.decorator, + }); + + if (node.decl.$refText === '@regex' && node.args[0]) { + acceptor({ + node: node.args[0], + property: 'value', + type: SemanticTokenTypes.regexp, + }); + } + } else if (isAttribute(node)) { + acceptor({ + node, + property: 'name', + type: SemanticTokenTypes.decorator, }); } else if (isInvocationExpr(node)) { acceptor({ @@ -91,17 +108,25 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'function', type: SemanticTokenTypes.function, }); - } else if (isFunctionDecl(node) || isAttribute(node) || isProcedure(node)) { + } else if (isFunctionDecl(node) || isProcedure(node)) { acceptor({ node, property: 'name', type: SemanticTokenTypes.function, }); + + if ('mutation' in node && node.mutation) { + acceptor({ + node, + property: 'mutation', + type: SemanticTokenTypes.modifier, + }); + } } else if (isReferenceExpr(node)) { acceptor({ node, property: 'target', - type: SemanticTokenTypes.variable, + type: SemanticTokenTypes.property, }); } else if (isMemberAccessExpr(node)) { acceptor({ @@ -109,6 +134,48 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'member', type: SemanticTokenTypes.property, }); + } else if (isNumberLiteral(node)) { + acceptor({ + node, + property: 'value', + type: SemanticTokenTypes.number, + }); + } else if (isBooleanLiteral(node) || isNullExpr(node)) { + acceptor({ + node, + property: 'value', + type: SemanticTokenTypes.keyword, + }); + } else if (isUnaryExpr(node) || isBinaryExpr(node)) { + acceptor({ + node, + property: 'operator', + type: SemanticTokenTypes.operator, + }); + } else if (isEnumField(node)) { + acceptor({ + node, + property: 'name', + type: SemanticTokenTypes.enumMember, + }); + } else if (isEnum(node)) { + acceptor({ + node, + property: 'name', + type: SemanticTokenTypes.enum, + }); + } else if (isFunctionParam(node) || isAttributeArg(node) || isAttributeParam(node) || isProcedureParam(node)) { + acceptor({ + node, + property: 'name', + type: SemanticTokenTypes.parameter, + }); + } else if (isCollectionPredicateBinding(node)) { + acceptor({ + node, + property: 'name', + type: SemanticTokenTypes.variable, + }); } } } From 1ba8e9559fff6f2ef739fb924b538cf7ad76d054 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 14 Aug 2026 04:17:46 +0000 Subject: [PATCH 4/6] fix: reference exprs --- packages/language/src/zmodel-semantic.ts | 30 ++++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index 5f6254f36..5e3b8c188 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -123,11 +123,31 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { }); } } else if (isReferenceExpr(node)) { - acceptor({ - node, - property: 'target', - type: SemanticTokenTypes.property, - }); + if (isEnumField(node.target.ref)) { + acceptor({ + node, + property: 'target', + type: SemanticTokenTypes.enumMember, + }); + } else if (isFunctionParam(node.target.ref)) { + acceptor({ + node, + property: 'target', + type: SemanticTokenTypes.parameter, + }); + } else if (isCollectionPredicateBinding(node.target.ref)) { + acceptor({ + node, + property: 'target', + type: SemanticTokenTypes.variable, + }); + } else { + acceptor({ + node, + property: 'target', + type: SemanticTokenTypes.property, + }); + } } else if (isMemberAccessExpr(node)) { acceptor({ node, From 521f3f61acf55616223c2138c155a7f9dc478a51 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 14 Aug 2026 04:18:58 +0000 Subject: [PATCH 5/6] fix: `in` operator --- packages/language/src/zmodel-semantic.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index 5e3b8c188..eb90c0cf3 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -167,11 +167,19 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { type: SemanticTokenTypes.keyword, }); } else if (isUnaryExpr(node) || isBinaryExpr(node)) { - acceptor({ - node, - property: 'operator', - type: SemanticTokenTypes.operator, - }); + if (node.operator === 'in') { + acceptor({ + node, + property: 'operator', + type: SemanticTokenTypes.keyword, + }); + } else { + acceptor({ + node, + property: 'operator', + type: SemanticTokenTypes.operator, + }); + } } else if (isEnumField(node)) { acceptor({ node, From d55b1cb6e7ece6159c50d9484525d9ac63c5a8e1 Mon Sep 17 00:00:00 2001 From: sanny-io Date: Fri, 14 Aug 2026 04:29:29 +0000 Subject: [PATCH 6/6] fix: data field params --- packages/language/src/zmodel-semantic.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/language/src/zmodel-semantic.ts b/packages/language/src/zmodel-semantic.ts index eb90c0cf3..a2d84386f 100644 --- a/packages/language/src/zmodel-semantic.ts +++ b/packages/language/src/zmodel-semantic.ts @@ -34,6 +34,7 @@ import { isAttributeParam, isProcedureParam, type AstNode, + isDataFieldParam, } from './ast'; export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { @@ -192,7 +193,13 @@ export class ZModelSemanticTokenProvider extends AbstractSemanticTokenProvider { property: 'name', type: SemanticTokenTypes.enum, }); - } else if (isFunctionParam(node) || isAttributeArg(node) || isAttributeParam(node) || isProcedureParam(node)) { + } else if ( + isFunctionParam(node) || + isAttributeArg(node) || + isAttributeParam(node) || + isProcedureParam(node) || + isDataFieldParam(node) + ) { acceptor({ node, property: 'name',