Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 077f03f

Browse files
mwillbanksymc9
andauthored
feat(zmodel): collection predicate binding (#548)
* feat: audit policy collection aliases provides a means to alias collections in @@Allow collections by extending the ast this allows for utilizing collections inside of @@Allow like: ``` memberships?[m, auth().memberships?[ tenantId == m.tenantId ... ] ] ``` * fix: code review comments + syntax fixes * refactor: extract collection predicate binding to its own language construct (#2) - adjusted language processing chain accordingly - fixed several issues in policy transformer/evaluator - more test cases * addressing PR comments --------- Co-authored-by: Yiming Cao <yiming@whimslab.io> Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
1 parent 2c1ffac commit 077f03f

18 files changed

Lines changed: 1290 additions & 212 deletions

packages/language/src/generated/ast.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export function isMemberAccessTarget(item: unknown): item is MemberAccessTarget
144144
return reflection.isInstance(item, MemberAccessTarget);
145145
}
146146

147-
export type ReferenceTarget = DataField | EnumField | FunctionParam;
147+
export type ReferenceTarget = CollectionPredicateBinding | DataField | EnumField | FunctionParam;
148148

149149
export const ReferenceTarget = 'ReferenceTarget';
150150

@@ -258,6 +258,7 @@ export function isAttributeParamType(item: unknown): item is AttributeParamType
258258
export interface BinaryExpr extends langium.AstNode {
259259
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr;
260260
readonly $type: 'BinaryExpr';
261+
binding?: CollectionPredicateBinding;
261262
left: Expression;
262263
operator: '!' | '!=' | '&&' | '<' | '<=' | '==' | '>' | '>=' | '?' | '^' | 'in' | '||';
263264
right: Expression;
@@ -281,6 +282,18 @@ export function isBooleanLiteral(item: unknown): item is BooleanLiteral {
281282
return reflection.isInstance(item, BooleanLiteral);
282283
}
283284

285+
export interface CollectionPredicateBinding extends langium.AstNode {
286+
readonly $container: BinaryExpr;
287+
readonly $type: 'CollectionPredicateBinding';
288+
name: RegularID;
289+
}
290+
291+
export const CollectionPredicateBinding = 'CollectionPredicateBinding';
292+
293+
export function isCollectionPredicateBinding(item: unknown): item is CollectionPredicateBinding {
294+
return reflection.isInstance(item, CollectionPredicateBinding);
295+
}
296+
284297
export interface ConfigArrayExpr extends langium.AstNode {
285298
readonly $container: ConfigField;
286299
readonly $type: 'ConfigArrayExpr';
@@ -775,6 +788,7 @@ export type ZModelAstType = {
775788
AttributeParamType: AttributeParamType
776789
BinaryExpr: BinaryExpr
777790
BooleanLiteral: BooleanLiteral
791+
CollectionPredicateBinding: CollectionPredicateBinding
778792
ConfigArrayExpr: ConfigArrayExpr
779793
ConfigExpr: ConfigExpr
780794
ConfigField: ConfigField
@@ -822,7 +836,7 @@ export type ZModelAstType = {
822836
export class ZModelAstReflection extends langium.AbstractAstReflection {
823837

824838
getAllTypes(): string[] {
825-
return [AbstractDeclaration, Argument, ArrayExpr, Attribute, AttributeArg, AttributeParam, AttributeParamType, BinaryExpr, BooleanLiteral, ConfigArrayExpr, ConfigExpr, ConfigField, ConfigInvocationArg, ConfigInvocationExpr, DataField, DataFieldAttribute, DataFieldType, DataModel, DataModelAttribute, DataSource, Enum, EnumField, Expression, FieldInitializer, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl, InternalAttribute, InvocationExpr, LiteralExpr, MemberAccessExpr, MemberAccessTarget, Model, ModelImport, NullExpr, NumberLiteral, ObjectExpr, Plugin, PluginField, Procedure, ProcedureParam, ReferenceArg, ReferenceExpr, ReferenceTarget, StringLiteral, ThisExpr, TypeDeclaration, TypeDef, UnaryExpr, UnsupportedFieldType];
839+
return [AbstractDeclaration, Argument, ArrayExpr, Attribute, AttributeArg, AttributeParam, AttributeParamType, BinaryExpr, BooleanLiteral, CollectionPredicateBinding, ConfigArrayExpr, ConfigExpr, ConfigField, ConfigInvocationArg, ConfigInvocationExpr, DataField, DataFieldAttribute, DataFieldType, DataModel, DataModelAttribute, DataSource, Enum, EnumField, Expression, FieldInitializer, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl, InternalAttribute, InvocationExpr, LiteralExpr, MemberAccessExpr, MemberAccessTarget, Model, ModelImport, NullExpr, NumberLiteral, ObjectExpr, Plugin, PluginField, Procedure, ProcedureParam, ReferenceArg, ReferenceExpr, ReferenceTarget, StringLiteral, ThisExpr, TypeDeclaration, TypeDef, UnaryExpr, UnsupportedFieldType];
826840
}
827841

828842
protected override computeIsSubtype(subtype: string, supertype: string): boolean {
@@ -850,6 +864,11 @@ export class ZModelAstReflection extends langium.AbstractAstReflection {
850864
case StringLiteral: {
851865
return this.isSubtype(LiteralExpr, supertype);
852866
}
867+
case CollectionPredicateBinding:
868+
case EnumField:
869+
case FunctionParam: {
870+
return this.isSubtype(ReferenceTarget, supertype);
871+
}
853872
case ConfigArrayExpr: {
854873
return this.isSubtype(ConfigExpr, supertype);
855874
}
@@ -861,10 +880,6 @@ export class ZModelAstReflection extends langium.AbstractAstReflection {
861880
case TypeDef: {
862881
return this.isSubtype(AbstractDeclaration, supertype) || this.isSubtype(TypeDeclaration, supertype);
863882
}
864-
case EnumField:
865-
case FunctionParam: {
866-
return this.isSubtype(ReferenceTarget, supertype);
867-
}
868883
case InvocationExpr:
869884
case LiteralExpr: {
870885
return this.isSubtype(ConfigExpr, supertype) || this.isSubtype(Expression, supertype);
@@ -975,6 +990,7 @@ export class ZModelAstReflection extends langium.AbstractAstReflection {
975990
return {
976991
name: BinaryExpr,
977992
properties: [
993+
{ name: 'binding' },
978994
{ name: 'left' },
979995
{ name: 'operator' },
980996
{ name: 'right' }
@@ -989,6 +1005,14 @@ export class ZModelAstReflection extends langium.AbstractAstReflection {
9891005
]
9901006
};
9911007
}
1008+
case CollectionPredicateBinding: {
1009+
return {
1010+
name: CollectionPredicateBinding,
1011+
properties: [
1012+
{ name: 'name' }
1013+
]
1014+
};
1015+
}
9921016
case ConfigArrayExpr: {
9931017
return {
9941018
name: ConfigArrayExpr,

0 commit comments

Comments
 (0)