Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow <let/> in <constraint/> without requiring a sibling constraint #552

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions schema/metaschema/metaschema-module-metaschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,10 @@
<define-assembly name="assembly-constraints">
<use-name>constraint</use-name>
<model>
<assembly ref="constraint-let-expression" max-occurs="unbounded">
<group-as name="lets" in-json="ARRAY"/>
</assembly>
<choice-group min-occurs="1" max-occurs="unbounded">
<group-as name="rules" in-json="ARRAY"/>
<discriminator>object-type</discriminator>
<assembly ref="constraint-let-expression"/>
<assembly ref="targeted-allowed-values-constraint"/>
<assembly ref="targeted-expect-constraint"/>
<assembly ref="targeted-index-has-key-constraint"/>
Expand All @@ -857,12 +855,10 @@
<define-assembly name="field-constraints">
<use-name>constraint</use-name>
<model>
<assembly ref="constraint-let-expression" max-occurs="unbounded">
<group-as name="lets" in-json="ARRAY"/>
</assembly>
<choice-group min-occurs="1" max-occurs="unbounded">
<group-as name="rules" in-json="ARRAY"/>
<discriminator>object-type</discriminator>
<assembly ref="constraint-let-expression"/>
<assembly ref="targeted-allowed-values-constraint"/>
<assembly ref="targeted-expect-constraint"/>
<assembly ref="targeted-index-has-key-constraint"/>
Expand All @@ -874,12 +870,10 @@
<define-assembly name="flag-constraints">
<use-name>constraint</use-name>
<model>
<assembly ref="constraint-let-expression" max-occurs="unbounded">
<group-as name="lets" in-json="ARRAY"/>
</assembly>
<choice-group min-occurs="1" max-occurs="unbounded">
<group-as name="rules" in-json="ARRAY"/>
<discriminator>object-type</discriminator>
<assembly ref="constraint-let-expression"/>
<assembly ref="flag-allowed-values"/>
<assembly ref="flag-expect"/>
<assembly ref="flag-index-has-key"/>
Expand Down
29 changes: 13 additions & 16 deletions schema/xml/metaschema.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1167,20 +1167,14 @@
<xs:attribute name="expression" type="MetaschemaPathType" use="required"/>
</xs:complexType>

<xs:group name="LetExpressionGroup">
<xs:sequence>
<xs:element name="let" type="ConstraintLetType" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Declares a variable whose name is bound to the result of the Metapath expression. These variables can be used in target and other Metapath expressions used in constrains that are declared in the same context or in constraints declared in a child assembly, field, or flag.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:group>

<xs:complexType name="DefineFlagConstraintsType">
<xs:sequence>
<xs:group ref="LetExpressionGroup"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice maxOccurs="unbounded">
<xs:element name="let" type="ConstraintLetType">
<xs:annotation>
<xs:documentation>Declares a variable whose name is bound to the result of the Metapath expression. These variables can be used in target and other Metapath expressions used in constrains that are declared in the same context or in constraints declared in a child assembly, field, or flag.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" name="allowed-values" type="AllowedValuesType">
<xs:annotation>
<xs:documentation>Constrains the allowed values for the flag.</xs:documentation>
Expand Down Expand Up @@ -1208,6 +1202,11 @@

<xs:group name="TargetedCommonConstraintsGroup">
<xs:choice>
<xs:element name="let" type="ConstraintLetType">
<xs:annotation>
<xs:documentation>Declares a variable whose name is bound to the result of the Metapath expression. These variables can be used in target and other Metapath expressions used in constrains that are declared in the same context or in constraints declared in a child assembly, field, or flag.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="allowed-values" type="TargetedAllowedValuesConstraintType">
<xs:annotation>
<xs:documentation>Constrains the allowed values for the flag or field referenced by the scope attribute.</xs:documentation>
Expand Down Expand Up @@ -1253,8 +1252,7 @@

<xs:complexType name="DefineFieldConstraintsType">
<xs:sequence>
<xs:group ref="LetExpressionGroup"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:group ref="TargetedCommonConstraintsGroup"/>
</xs:choice>
<xs:element name="remarks" type="RemarksType" minOccurs="0"/>
Expand All @@ -1263,8 +1261,7 @@

<xs:complexType name="DefineAssemblyConstraintsType">
<xs:sequence>
<xs:group ref="LetExpressionGroup"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:group ref="TargetedCommonConstraintsGroup"/>
<xs:group ref="AssemblyConstraintsGroup"/>
</xs:choice>
Expand Down
4 changes: 3 additions & 1 deletion website/content/specification/syntax/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ A `let` statement has a REQUIRED `@var` flag, which defines the variable name.

A `let` statement has a REQUIRED `@expression` flag, which defines an [Metapath expression](/specification/syntax/metapath), whose result is used to define the variable's value in the evaluation context.

During constraint evaluation, each `let` statement MUST be evaluated in encounter order. If a previous variable is bound with the same name in the evaluation context, the new value MUST bound in a sub-context to avoid side effects. This sub-context MUST be made available to any constraints following the `let` statement declaration, and to any constraints defined on child nodes of the current context.
During constraint evaluation, each `let` statement MUST be evaluated in encountered order. If a previous variable is bound with the same name in the evaluation context, the new value MUST bound in a sub-context to avoid side effects. This sub-context MUST be made available to any constraints following the `let` statement declaration, and to any constraints defined on child nodes of the current context.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this is blocking and/or material to this PR or not.

This is technically out of scope for #548, but given today's conversation, do want to address this concern within this PR and adjust given discussion and around processing order here and now as it has been decided with scope rebinding being disallowed or defer that? Note, the diff on this paragraph is the result of me correcting encounter to encountered to be more grammatical. I think this was the intent.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, I had a comment here, somehow I dropped it.

Can we codify a rule that no two let element siblings have the same name?

Can we write a constraint for that?

@david-waltermire also grateful for your input here.


A `let` statement MAY be defined in a constraint assembly by itself, before, or after other constraint types. One or more `let` statements SHOULD be declared before any other constraint types as a best practice, but it is not required.

During evaluation, when a variable is bound for a `let` statement, the variables value MUST be set to the result of evaluating the `@expression` using the current node as the Metapath evaluation focus.

Expand Down
Loading