@@ -3,15 +3,18 @@ import {
33    DataModel , 
44    DataModelAttribute , 
55    DataModelField , 
6+     Expression , 
67    isArrayExpr , 
78    isBooleanLiteral , 
89    isDataModel , 
910    isDataModelField , 
1011    isInvocationExpr , 
1112    isNumberLiteral , 
13+     isObjectExpr , 
1214    isReferenceExpr , 
1315    isStringLiteral , 
1416    isTypeDef , 
17+     ObjectExpr , 
1518    ReferenceExpr , 
1619    TypeDef , 
1720    TypeDefField , 
@@ -20,6 +23,7 @@ import type { RuntimeAttribute } from '@zenstackhq/runtime';
2023import  {  lowerCaseFirst  }  from  '@zenstackhq/runtime/local-helpers' ; 
2124import  {  streamAst  }  from  'langium' ; 
2225import  {  FunctionDeclarationStructure ,  OptionalKind ,  Project ,  VariableDeclarationKind  }  from  'ts-morph' ; 
26+ import  {  match  }  from  'ts-pattern' ; 
2327import  { 
2428    CodeWriter , 
2529    ExpressionContext , 
@@ -362,20 +366,9 @@ function getAttributes(target: DataModelField | DataModel | TypeDefField): Runti
362366        . map ( ( attr )  =>  { 
363367            const  args : Array < {  name ?: string ;  value : unknown  } >  =  [ ] ; 
364368            for  ( const  arg  of  attr . args )  { 
365-                 if  ( isNumberLiteral ( arg . value ) )  { 
366-                     let  v  =  parseInt ( arg . value . value ) ; 
367-                     if  ( isNaN ( v ) )  { 
368-                         v  =  parseFloat ( arg . value . value ) ; 
369-                     } 
370-                     if  ( isNaN ( v ) )  { 
371-                         throw  new  Error ( `Invalid number literal: ${ arg . value . value }  ) ; 
372-                     } 
373-                     args . push ( {  name : arg . name ,  value : v  } ) ; 
374-                 }  else  if  ( isStringLiteral ( arg . value )  ||  isBooleanLiteral ( arg . value ) )  { 
375-                     args . push ( {  name : arg . name ,  value : arg . value . value  } ) ; 
376-                 }  else  { 
377-                     // non-literal args are ignored 
378-                 } 
369+                 const  argName  =  arg . $resolvedParam ?. name  ??  arg . name ; 
370+                 const  argValue  =  exprToValue ( arg . value ) ; 
371+                 args . push ( {  name : argName ,  value : argValue  } ) ; 
379372            } 
380373            return  {  name : resolved ( attr . decl ) . name ,  args } ; 
381374        } ) 
@@ -602,3 +595,26 @@ function getOnUpdateAction(fieldInfo: DataModelField) {
602595    } 
603596    return  undefined ; 
604597} 
598+ 
599+ function  exprToValue ( value : Expression ) : unknown  { 
600+     return  match ( value ) 
601+         . when ( isStringLiteral ,  ( v )  =>  v . value ) 
602+         . when ( isBooleanLiteral ,  ( v )  =>  v . value ) 
603+         . when ( isNumberLiteral ,  ( v )  =>  { 
604+             let  num  =  parseInt ( v . value ) ; 
605+             if  ( isNaN ( num ) )  { 
606+                 num  =  parseFloat ( v . value ) ; 
607+             } 
608+             if  ( isNaN ( num ) )  { 
609+                 return  undefined ; 
610+             } 
611+             return  num ; 
612+         } ) 
613+         . when ( isArrayExpr ,  ( v )  =>  v . items . map ( ( item )  =>  exprToValue ( item ) ) ) 
614+         . when ( isObjectExpr ,  ( v )  =>  exprToObject ( v ) ) 
615+         . otherwise ( ( )  =>  undefined ) ; 
616+ } 
617+ 
618+ function  exprToObject ( value : ObjectExpr ) : unknown  { 
619+     return  Object . fromEntries ( value . fields . map ( ( field )  =>  [ field . name ,  exprToValue ( field . value ) ] ) ) ; 
620+ } 
0 commit comments