@cratis/screenplay-language 4.192.0 → 4.194.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/bundles/command-read-completions.js +5 -0
  2. package/dist/bundles/command-read-completions.js.map +1 -0
  3. package/dist/bundles/compiler/Diagnostics/DiagnosticArgument.js +2 -0
  4. package/dist/bundles/compiler/Diagnostics/DiagnosticArgument.js.map +1 -0
  5. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +1 -1
  6. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -1
  7. package/dist/bundles/compiler/Files/PlayFolderMerge.js +1 -1
  8. package/dist/bundles/compiler/Files/PlayFolderMerge.js.map +1 -1
  9. package/dist/bundles/compiler/Parsing/CaptureParser.js +1 -1
  10. package/dist/bundles/compiler/Parsing/CaptureParser.js.map +1 -1
  11. package/dist/bundles/compiler/Parsing/ParserContext.js +1 -1
  12. package/dist/bundles/compiler/Parsing/ParserContext.js.map +1 -1
  13. package/dist/bundles/compiler/Parsing/ProducesParser.js +1 -1
  14. package/dist/bundles/compiler/Parsing/ProducesParser.js.map +1 -1
  15. package/dist/bundles/compiler/Parsing/ProjectionParser.js +1 -1
  16. package/dist/bundles/compiler/Parsing/ProjectionParser.js.map +1 -1
  17. package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js +1 -1
  18. package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js.map +1 -1
  19. package/dist/bundles/compiler/Parsing/ReactionParser.js +1 -1
  20. package/dist/bundles/compiler/Parsing/ReactionParser.js.map +1 -1
  21. package/dist/bundles/compiler/Parsing/ScreenplayParser.js +1 -1
  22. package/dist/bundles/compiler/Parsing/ScreenplayParser.js.map +1 -1
  23. package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js +1 -1
  24. package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js.map +1 -1
  25. package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js +1 -1
  26. package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js.map +1 -1
  27. package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js +1 -1
  28. package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js.map +1 -1
  29. package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js +1 -1
  30. package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js.map +1 -1
  31. package/dist/bundles/compiler/Parsing/SpecificationParser.js +1 -1
  32. package/dist/bundles/compiler/Parsing/SpecificationParser.js.map +1 -1
  33. package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js +1 -1
  34. package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js.map +1 -1
  35. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js +1 -1
  36. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js.map +1 -1
  37. package/dist/bundles/compiler/Syntax/Structure.js.map +1 -1
  38. package/dist/bundles/compiler/Syntax/SyntaxCollections.js +1 -1
  39. package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -1
  40. package/dist/bundles/compiler/Syntax/SyntaxJson.js +1 -1
  41. package/dist/bundles/compiler/Syntax/SyntaxJson.js.map +1 -1
  42. package/dist/bundles/compiler/index.js +1 -1
  43. package/dist/bundles/completion-items.js +1 -1
  44. package/dist/bundles/completion-items.js.map +1 -1
  45. package/dist/bundles/completion-planner.js +2 -2
  46. package/dist/bundles/completion-planner.js.map +1 -1
  47. package/dist/bundles/diagnostic-codes.js +1 -1
  48. package/dist/bundles/diagnostic-codes.js.map +1 -1
  49. package/dist/bundles/keyword-docs.js +1 -1
  50. package/dist/bundles/keyword-docs.js.map +1 -1
  51. package/dist/bundles/language.js +1 -1
  52. package/dist/bundles/language.js.map +1 -1
  53. package/dist/bundles/response-analysis.js +2 -2
  54. package/dist/bundles/response-analysis.js.map +1 -1
  55. package/dist/bundles/tokens.js +1 -1
  56. package/dist/bundles/tokens.js.map +1 -1
  57. package/dist/bundles/validation.js +1 -1
  58. package/dist/bundles/validation.js.map +1 -1
  59. package/dist/command-read-completions.d.ts +4 -0
  60. package/dist/command-read-completions.d.ts.map +1 -0
  61. package/dist/completion-items.d.ts.map +1 -1
  62. package/dist/completion-planner.d.ts.map +1 -1
  63. package/dist/diagnostic-codes.d.ts +1 -0
  64. package/dist/diagnostic-codes.d.ts.map +1 -1
  65. package/dist/keyword-docs.d.ts.map +1 -1
  66. package/dist/language.d.ts.map +1 -1
  67. package/dist/tokens.d.ts.map +1 -1
  68. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectionTargetValidator.js","names":["resolver","AuthoringProductionResolver","application","slices","imported","entry","events","eventDeclarations","slice","event","types","uniqueByName","scalar","concept","name","rest","path","properties","matches","value","views","segments","named","qualifiers","index","depth","scope","visible","reference","imports","resolution","candidate","context","DiagnosticCodes","location","block","blocks","reported","resolved","key","element","ownsEvents","effectiveHandlers","mappings","mapping","target","projection","capture","append","child","variants","variant"],"sources":["../../../../../../Compiler/Parsing/ProjectionTargetValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { ProjectionBlockSyntax } from '../Syntax/Projections';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\nimport { uniqueByName } from './ResponseValidator';\n\nexport function validateProjectionTargets(application: ApplicationSyntax, context: ParserContext): void {\n const resolver = new AuthoringProductionResolver(application);\n const slices = resolver.slices;\n const imported = new Set(application.imports.map(entry => entry.qualifiedName));\n const events = new Set([...slices.flatMap(({ slice }) => eventDeclarations(slice).map(event => event.name)), ...application.imports.map(entry => entry.qualifiedName.split('.').at(-1)!)]);\n const types = uniqueByName(application.types);\n const scalar = new Set(['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime', ...application.concepts.map(concept => concept.name)].filter(name => !types.has(name)));\n const property = (properties: readonly PropertySyntax[] | null, path: string): { value: PropertySyntax | null; missing: boolean } => {\n const [name, ...rest] = path.split('.');\n if (properties === null) return { value: null, missing: false };\n const matches = properties.filter(entry => entry.name === name);\n if (matches.length !== 1) return { value: null, missing: matches.length === 0 };\n const value = matches[0];\n if (rest.length === 0) return { value, missing: false };\n if (scalar.has(value.type.name)) return { value: null, missing: true };\n return property(types.get(value.type.name)?.properties ?? null, rest.join('.'));\n };\n const views = slices.flatMap(({ slice, scope }) => slice.readModels.map(node => ({ node, scope })));\n const viewProperties = (reference: string, scope: readonly string[]): readonly PropertySyntax[] | null => {\n const candidates = (name: string) => {\n const segments = name.split('.');\n const named = views.filter(entry => entry.node.name === segments.at(-1));\n const qualifiers = segments.slice(0, -1);\n if (qualifiers.length > 0) return named.filter(entry => qualifiers.length <= entry.scope.length && qualifiers.every((value, index) => entry.scope[entry.scope.length - qualifiers.length + index] === value));\n for (let depth = scope.length; depth >= 0; depth--) {\n const visible = named.filter(entry => depth <= entry.scope.length && scope.slice(0, depth).every((value, index) => entry.scope[index] === value));\n if (visible.length > 0) return visible;\n }\n return [];\n };\n let matches = candidates(reference);\n const imports = application.imports.filter(entry => entry.qualifiedName.split('.').at(-1) === reference);\n if (matches.length === 0 && imports.length === 1) matches = candidates(imports[0].qualifiedName);\n return matches.length === 1 ? matches[0].node.properties : null;\n };\n const unknownEvent = (name: string, location: SourceLocation, slice: SliceSyntax): void => {\n const resolution = resolver.resolve(name, slice);\n const declared = events.has(name) || imported.has(name) || resolution.declaration?.kind === AuthoringProductionKind.Event || resolution.candidates.some(candidate => candidate.kind === AuthoringProductionKind.Event);\n if (!declared) context.warning(DiagnosticCodes.UnknownEvent, `Unknown event '${name}' - declare it with 'event ${name}'`, location);\n };\n const removals = (blocks: readonly ProjectionBlockSyntax[], slice: SliceSyntax): void => {\n for (const block of blocks) {\n if (block.kind === 'RemoveWithSyntax' || block.kind === 'RemoveViaJoinSyntax') unknownEvent(block.event, block.location, slice);\n if ('blocks' in block) removals(block.blocks, slice);\n }\n };\n const reported = new Set<string>();\n const walk = (blocks: readonly ProjectionBlockSyntax[], properties: readonly PropertySyntax[] | null, element = false, effectiveHandlers = false): void => {\n const validate = (path: string, location: SourceLocation) => {\n const resolved = property(properties, path);\n const key = JSON.stringify([location.path, location.line, location.column]);\n if (resolved.missing && !reported.has(key)) {\n reported.add(key);\n context.warning(DiagnosticCodes.UnknownReadModelProperty, `Projection target '${path}' is not a declared ${element ? 'element' : 'read-model'} property`, location);\n }\n return resolved.value;\n };\n // An 'every' without local handlers only cascades into the element scopes.\n const ownsEvents = effectiveHandlers || blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n for (const block of blocks) {\n const mappings = block.kind === 'EverySyntax' && !ownsEvents ? [] : 'mappings' in block ? block.mappings : block.kind === 'JoinSyntax' ? block.events.flatMap(event => event.mappings) : [];\n for (const mapping of mappings) validate(mapping.property, mapping.location);\n if (block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax') {\n const target = validate(block.property, block.location);\n walk(block.blocks, target === null ? null : types.get(target.type.name)?.properties ?? null, true);\n }\n }\n };\n for (const { slice } of slices) {\n for (const projection of slice.projections) removals(projection.blocks, slice);\n for (const capture of slice.captures) {\n for (const append of [...capture.appends, ...capture.children.flatMap(child => child.appends), ...capture.nested.flatMap(child => child.appends)]) unknownEvent(append.event, append.location, slice);\n }\n }\n for (const { slice, scope } of slices) {\n for (const projection of slice.projections) {\n const variants = projection.blocks.filter(block => block.kind === 'ProjectionVariantSyntax');\n if (variants.length === 0) walk(projection.blocks, viewProperties(projection.readModel ?? projection.name, scope));\n for (const variant of variants) {\n const properties = viewProperties(variant.name, scope);\n walk(projection.blocks.filter(block => block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax'), properties);\n // Lowering combines shared handlers and turns entering events into From handlers.\n const ownsEvents = variant.entersOn.length > 0 || projection.blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n walk(variant.blocks, properties, false, ownsEvents);\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectionTargetValidator.js","names":["resolver","AuthoringProductionResolver","application","slices","imported","entry","events","eventDeclarations","slice","event","types","uniqueByName","scalar","concept","name","rest","path","properties","matches","value","views","segments","named","qualifiers","index","depth","scope","visible","reference","imports","resolution","candidate","context","DiagnosticCodes","location","block","blocks","reported","resolved","key","element","diagnosticText","ownsEvents","effectiveHandlers","mappings","mapping","target","projection","capture","append","child","variants","variant"],"sources":["../../../../../../Compiler/Parsing/ProjectionTargetValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { ProjectionBlockSyntax } from '../Syntax/Projections';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\nimport { uniqueByName } from './ResponseValidator';\n\nexport function validateProjectionTargets(application: ApplicationSyntax, context: ParserContext): void {\n const resolver = new AuthoringProductionResolver(application);\n const slices = resolver.slices;\n const imported = new Set(application.imports.map(entry => entry.qualifiedName));\n const events = new Set([...slices.flatMap(({ slice }) => eventDeclarations(slice).map(event => event.name)), ...application.imports.map(entry => entry.qualifiedName.split('.').at(-1)!)]);\n const types = uniqueByName(application.types);\n const scalar = new Set(['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime', ...application.concepts.map(concept => concept.name)].filter(name => !types.has(name)));\n const property = (properties: readonly PropertySyntax[] | null, path: string): { value: PropertySyntax | null; missing: boolean } => {\n const [name, ...rest] = path.split('.');\n if (properties === null) return { value: null, missing: false };\n const matches = properties.filter(entry => entry.name === name);\n if (matches.length !== 1) return { value: null, missing: matches.length === 0 };\n const value = matches[0];\n if (rest.length === 0) return { value, missing: false };\n if (scalar.has(value.type.name)) return { value: null, missing: true };\n return property(types.get(value.type.name)?.properties ?? null, rest.join('.'));\n };\n const views = slices.flatMap(({ slice, scope }) => slice.readModels.map(node => ({ node, scope })));\n const viewProperties = (reference: string, scope: readonly string[]): readonly PropertySyntax[] | null => {\n const candidates = (name: string) => {\n const segments = name.split('.');\n const named = views.filter(entry => entry.node.name === segments.at(-1));\n const qualifiers = segments.slice(0, -1);\n if (qualifiers.length > 0) return named.filter(entry => qualifiers.length <= entry.scope.length && qualifiers.every((value, index) => entry.scope[entry.scope.length - qualifiers.length + index] === value));\n for (let depth = scope.length; depth >= 0; depth--) {\n const visible = named.filter(entry => depth <= entry.scope.length && scope.slice(0, depth).every((value, index) => entry.scope[index] === value));\n if (visible.length > 0) return visible;\n }\n return [];\n };\n let matches = candidates(reference);\n const imports = application.imports.filter(entry => entry.qualifiedName.split('.').at(-1) === reference);\n if (matches.length === 0 && imports.length === 1) matches = candidates(imports[0].qualifiedName);\n return matches.length === 1 ? matches[0].node.properties : null;\n };\n const unknownEvent = (name: string, location: SourceLocation, slice: SliceSyntax): void => {\n const resolution = resolver.resolve(name, slice);\n const declared = events.has(name) || imported.has(name) || resolution.declaration?.kind === AuthoringProductionKind.Event || resolution.candidates.some(candidate => candidate.kind === AuthoringProductionKind.Event);\n if (!declared) context.warning(DiagnosticCodes.UnknownEvent, `Unknown event '${name}' - declare it with 'event ${name}'`, location);\n };\n const removals = (blocks: readonly ProjectionBlockSyntax[], slice: SliceSyntax): void => {\n for (const block of blocks) {\n if (block.kind === 'RemoveWithSyntax' || block.kind === 'RemoveViaJoinSyntax') unknownEvent(block.event, block.location, slice);\n if ('blocks' in block) removals(block.blocks, slice);\n }\n };\n const reported = new Set<string>();\n const walk = (blocks: readonly ProjectionBlockSyntax[], properties: readonly PropertySyntax[] | null, element = false, effectiveHandlers = false): void => {\n const validate = (path: string, location: SourceLocation) => {\n const resolved = property(properties, path);\n const key = JSON.stringify([location.path, location.line, location.column]);\n if (resolved.missing && !reported.has(key)) {\n reported.add(key);\n context.warning(DiagnosticCodes.UnknownReadModelProperty, `Projection target '${path}' is not a declared ${element ? 'element' : 'read-model'} property`, location, diagnosticText('property', path));\n }\n return resolved.value;\n };\n // An 'every' without local handlers only cascades into the element scopes.\n const ownsEvents = effectiveHandlers || blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n for (const block of blocks) {\n const mappings = block.kind === 'EverySyntax' && !ownsEvents ? [] : 'mappings' in block ? block.mappings : block.kind === 'JoinSyntax' ? block.events.flatMap(event => event.mappings) : [];\n for (const mapping of mappings) validate(mapping.property, mapping.location);\n if (block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax') {\n const target = validate(block.property, block.location);\n walk(block.blocks, target === null ? null : types.get(target.type.name)?.properties ?? null, true);\n }\n }\n };\n for (const { slice } of slices) {\n for (const projection of slice.projections) removals(projection.blocks, slice);\n for (const capture of slice.captures) {\n for (const append of [...capture.appends, ...capture.children.flatMap(child => child.appends), ...capture.nested.flatMap(child => child.appends)]) unknownEvent(append.event, append.location, slice);\n }\n }\n for (const { slice, scope } of slices) {\n for (const projection of slice.projections) {\n const variants = projection.blocks.filter(block => block.kind === 'ProjectionVariantSyntax');\n if (variants.length === 0) walk(projection.blocks, viewProperties(projection.readModel ?? projection.name, scope));\n for (const variant of variants) {\n const properties = viewProperties(variant.name, scope);\n walk(projection.blocks.filter(block => block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax'), properties);\n // Lowering combines shared handlers and turns entering events into From handlers.\n const ownsEvents = variant.entersOn.length > 0 || projection.blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n walk(variant.blocks, properties, false, ownsEvents);\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{nativePattern as t,pattern as n}from"../Text/patterns.js";import{locationOf as r}from"./SourceLine.js";import{dependencySources as i}from"../Syntax/DependencySources.js";import{parseModeledMappingSource as a}from"./ExpressionParser.js";import{firstWord as o}from"./LineText.js";import{parseDescription as s}from"./DescriptionParser.js";import{parseDocumentation as c}from"./DocumentationParser.js";import{parseCondition as l}from"./ConditionParser.js";import{ParserContext as u}from"./ParserContext.js";import{collectInputUses as d}from"./InputUses.js";import{isReactionIdentityLine as f,misplacedReactionIdentity as p,parseReactionIdentity as m}from"./ReactionIdentityParser.js";import{parseObserverFilter as h}from"./ObserverFilterParser.js";import{parseReads as g}from"./ReadsParser.js";import{parseProduces as _}from"./ProducesParser.js";import{parseTriggerData as v}from"./TriggerDataParser.js";const y=n(`^reaction\\s+([A-Za-z_]\\w*)$`),b=n(`^when\\s+([A-Za-z_]\\w*)$`),x=n(`^every\\s+(\\d+)\\s+(seconds?|minutes?|hours?|days?)$`),S=n(`^at\\s+(\\d{2}:\\d{2})(?:\\s+on\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\s+(\\d{1,2})))?$`),C=/* @__PURE__ */ new Set([`when`,`every`,`at`]),w=n(`^invokes\\s+([A-Z]\\w*)$`),T=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),E=t(`^on\\s+refused\\b(?=$|\\s+by\\b)`),D=t(`^on\\s+refused(?:\\s+by\\s+(validation|constraint|authorization)(?:\\s+([A-Za-z_]\\w*(?:\\.\\w+)*))?)?$`),O=n(`^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)`);function parseReaction(t,n){let i=y.exec(n.content)?.[1]??``;i===``&&t.error(e.InvalidReactionDeclaration,`Invalid reaction declaration '${n.content}' - expected 'reaction <Name>'`,r(n));let a=null,u=null,d=null,f=null,p=null,g=!1,_=[],v=/* @__PURE__ */ new Set,b=!1;for(let y=t.peekChild(n.indent);y!==void 0;y=t.peekChild(n.indent)){t.reader.takeSignificant();let n=o(y.content);if(n===`description`){a=s(t,y,a,`Reaction '${i}'`);continue}if(n===`documentation`){u=c(t,y,u,`Reaction '${i}'`);continue}if(n===`from`){f=h(t,y,f);continue}if(n===`runs`){p=m(t,y,g)??p,g=!0;continue}if(n===`where`){d=l(t,y.content.substring(5).trim(),r(y));continue}if(E.test(y.content)){t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,r(y)),t.skipBlock(y.indent),b=!0;continue}if(!C.has(n)){t.error(e.InvalidReactionTrigger,`Expected a trigger in reaction body, got '${y.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`,r(y)),t.skipBlock(y.indent),b=!0;continue}let x=parseTriggerSource(t,y);if(x===void 0){b=!0;continue}let S=sourceKey(x);v.has(S)?(t.error(e.DuplicateReactionTrigger,`Reaction '${i}' already declares '${y.content}' - a second says nothing the first did not`,r(y)),t.skipBlock(y.indent)):(v.add(S),_.push(parseTrigger(t,y,x)))}return _.length===0&&!b&&t.error(e.ReactionWithoutTrigger,`Reaction '${i}' must declare at least one trigger - nothing sets it off`,r(n)),{kind:`ReactionSyntax`,name:i,description:a,documentation:u,from:f,runsAs:p,where:d,triggers:_,location:r(n)}}function parseTrigger(t,n,c){let l=null,m=[],h=[],y=[],b=[],x=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){t.reader.takeSignificant();let n=o(i.content);if(n===`runs`&&f(i))p(t,i);else if(n===`description`)l=s(t,i,l,`Trigger '${i.content}'`);else if(n===`produces`){let e=_(t,i);e!==void 0&&m.push(e)}else if(n===`invokes`){let n=w.exec(i.content);if(n===null)t.error(e.InvalidInvokesDeclaration,`Invalid invokes declaration '${i.content}' - expected 'invokes <Command>'`,r(i)),t.skipBlock(i.indent);else{let o=new u(t.reader.fork(),t.path,t.languages);o.scope=t.scope,o.sourceOptions=t.sourceOptions,d(o,i),t.inputUses.push(...o.inputUses);let s=[],c=[];for(let n=t.peekChild(i.indent);n!==void 0;n=t.peekChild(i.indent)){if(t.reader.takeSignificant(),f(n)){p(t,n);continue}if(E.test(n.content)){let e=parseRefusal(t,n);e!==void 0&&c.push(e);continue}let i=T.exec(n.content);i===null?t.error(e.InvalidPropertyMapping,`Invalid property mapping '${n.content}' - expected '<property> = <source>'`,r(n)):s.push({kind:`PropertyMappingSyntax`,property:i[1].replaceAll(`@`,``),source:a(i[2],r(n),t.valueContext),location:r(n)})}h.push({kind:`InvokesSyntax`,command:n[1],mappings:s,onRefused:c,location:r(i)})}}else if(E.test(i.content))t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,r(i)),t.skipBlock(i.indent);else if(n===`reads`||n===`file`||i.content===`csharp`||i.content.startsWith("```")){x||=n===`file`||i.content===`csharp`||i.content.startsWith("```");let a=n===`reads`?g(t,i):void 0;a!==void 0&&y.push(a),O.test(i.content)&&t.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,r(i)),i.content.startsWith("```")&&t.skipFencedBody(),t.skipOpaqueBlock(i.indent)}else{let e=t.triggerData.length;v(t,i);for(let n of t.triggerData.slice(e))b.push({kind:`TriggerDataSyntax`,name:n.name,type:n.type,location:n.location})}}let S={kind:`ReactionTriggerSyntax`,source:c,description:l,produces:m,invokes:h,location:r(n)};return i.set(S,{reads:y,data:b,implementation:x}),S}function parseRefusal(t,n){let i=D.exec(n.content);if(i===null||i[2]!==void 0&&i[1]!==`constraint`){t.error(e.InvalidRefusalBranch,`Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.`,r(n)),t.skipBlock(n.indent);return}let a=[],s=!1,c=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent))if(t.reader.takeSignificant(),f(i))p(t,i),c=!0;else if(i.content===`acknowledge`)(s||a.length>0||t.peekChild(i.indent)!==void 0)&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.`,r(i)),c=!0),s=!0,t.skipBlock(i.indent);else if(o(i.content)===`produces`){s&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch cannot combine 'acknowledge' and 'produces'.`,r(i)),c=!0);let n=_(t,i);n===void 0?c=!0:a.push(n)}else t.error(e.InvalidRefusalBranchBody,`Expected 'acknowledge' or 'produces <Event>' in a refusal branch.`,r(i)),t.skipBlock(i.indent),c=!0;return!s&&a.length===0&&!c&&t.error(e.InvalidRefusalBranchBody,`A refusal branch must acknowledge or produce an event.`,r(n)),{kind:`InvocationRefusalSyntax`,selector:i[1]??`any`,constraint:i[2]??null,acknowledge:s,produces:a,location:r(n)}}function sourceKey(e){switch(e.kind){case`NamedTriggerSourceSyntax`:return JSON.stringify([e.kind,e.name]);case`IntervalTriggerSourceSyntax`:return JSON.stringify([e.kind,e.amount,e.unit]);case`ScheduleTriggerSourceSyntax`:return JSON.stringify([e.kind,e.time,e.dayOfWeek,e.dayOfMonth])}}function parseTriggerSource(t,n){let i=r(n);switch(o(n.content)){case`when`:{let r=b.exec(n.content);if(r===null){t.error(e.InvalidReactionTrigger,`Invalid trigger '${n.content}' - expected 'when <Name>'`,i),t.skipBlock(n.indent);return}return{kind:`NamedTriggerSourceSyntax`,name:r[1],location:i}}case`every`:{let r=x.exec(n.content),a=r===null?NaN:Number(r[1]);if(r===null||!Number.isInteger(a)||a<1||a>2147483647){t.error(e.InvalidIntervalTrigger,`Invalid interval '${n.content}' - expected 'every <n> <seconds|minutes|hours|days>'`,i),t.skipBlock(n.indent);return}return{kind:`IntervalTriggerSourceSyntax`,amount:a,unit:unitOf(r[2]),location:i}}default:return parseSchedule(t,n)}}function parseSchedule(t,n){let i=r(n),a=S.exec(n.content),o=a===null?void 0:timeOf(a[1]);if(a===null||o===void 0)t.error(e.InvalidScheduleTrigger,`Invalid schedule '${n.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`,i),t.skipBlock(n.indent);else{if(a[3]!==void 0){let r=Number(a[3]);if(r<1||r>31){t.error(e.InvalidScheduleTrigger,`Invalid day of month '${r}' in '${n.content}' - a day of the month is between 1 and 31`,i),t.skipBlock(n.indent);return}return{kind:`ScheduleTriggerSourceSyntax`,time:o,dayOfWeek:null,dayOfMonth:r,location:i}}return{kind:`ScheduleTriggerSourceSyntax`,time:o,dayOfWeek:a[2]??null,dayOfMonth:null,location:i}}}function timeOf(e){let[t,n]=e.split(`:`).map(Number);if(t>=0&&t<=23&&n>=0&&n<=59)return`${e}:00.0000000`}function unitOf(e){switch(e.replace(/s+$/,``)){case`second`:return`Seconds`;case`minute`:return`Minutes`;case`hour`:return`Hours`;default:return`Days`}}export{parseReaction,parseTriggerSource};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{nativePattern as t,pattern as n}from"../Text/patterns.js";import{locationOf as r}from"./SourceLine.js";import{dependencySources as i}from"../Syntax/DependencySources.js";import{parseModeledMappingSource as a}from"./ExpressionParser.js";import{diagnosticText as o}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as s}from"./LineText.js";import{parseDescription as c}from"./DescriptionParser.js";import{parseDocumentation as l}from"./DocumentationParser.js";import{parseCondition as u}from"./ConditionParser.js";import{ParserContext as d}from"./ParserContext.js";import{collectInputUses as f}from"./InputUses.js";import{isReactionIdentityLine as p,misplacedReactionIdentity as m,parseReactionIdentity as h}from"./ReactionIdentityParser.js";import{parseObserverFilter as g}from"./ObserverFilterParser.js";import{parseReads as _}from"./ReadsParser.js";import{parseProduces as v}from"./ProducesParser.js";import{parseTriggerData as y}from"./TriggerDataParser.js";const b=n(`^reaction\\s+([A-Za-z_]\\w*)$`),x=n(`^when\\s+([A-Za-z_]\\w*)$`),S=n(`^every\\s+(\\d+)\\s+(seconds?|minutes?|hours?|days?)$`),C=n(`^at\\s+(\\d{2}:\\d{2})(?:\\s+on\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\s+(\\d{1,2})))?$`),w=/* @__PURE__ */ new Set([`when`,`every`,`at`]),T=n(`^invokes\\s+([A-Z]\\w*)$`),E=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),D=t(`^on\\s+refused\\b(?=$|\\s+by\\b)`),O=t(`^on\\s+refused(?:\\s+by\\s+(validation|constraint|authorization)(?:\\s+([A-Za-z_]\\w*(?:\\.\\w+)*))?)?$`),k=n(`^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)`);function parseReaction(t,n){let i=b.exec(n.content)?.[1]??``;i===``&&t.error(e.InvalidReactionDeclaration,`Invalid reaction declaration '${n.content}' - expected 'reaction <Name>'`,r(n));let a=null,o=null,d=null,f=null,p=null,m=!1,_=[],v=/* @__PURE__ */ new Set,y=!1;for(let b=t.peekChild(n.indent);b!==void 0;b=t.peekChild(n.indent)){t.reader.takeSignificant();let n=s(b.content);if(n===`description`){a=c(t,b,a,`Reaction '${i}'`);continue}if(n===`documentation`){o=l(t,b,o,`Reaction '${i}'`);continue}if(n===`from`){f=g(t,b,f);continue}if(n===`runs`){p=h(t,b,m)??p,m=!0;continue}if(n===`where`){d=u(t,b.content.substring(5).trim(),r(b));continue}if(D.test(b.content)){t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,r(b)),t.skipBlock(b.indent),y=!0;continue}if(!w.has(n)){t.error(e.InvalidReactionTrigger,`Expected a trigger in reaction body, got '${b.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`,r(b)),t.skipBlock(b.indent),y=!0;continue}let x=parseTriggerSource(t,b);if(x===void 0){y=!0;continue}let S=sourceKey(x);v.has(S)?(t.error(e.DuplicateReactionTrigger,`Reaction '${i}' already declares '${b.content}' - a second says nothing the first did not`,r(b)),t.skipBlock(b.indent)):(v.add(S),_.push(parseTrigger(t,b,x)))}return _.length===0&&!y&&t.error(e.ReactionWithoutTrigger,`Reaction '${i}' must declare at least one trigger - nothing sets it off`,r(n)),{kind:`ReactionSyntax`,name:i,description:a,documentation:o,from:f,runsAs:p,where:d,triggers:_,location:r(n)}}function parseTrigger(t,n,l){let u=null,h=[],g=[],b=[],x=[],S=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){t.reader.takeSignificant();let n=s(i.content);if(n===`runs`&&p(i))m(t,i);else if(n===`description`)u=c(t,i,u,`Trigger '${i.content}'`);else if(n===`produces`){let e=v(t,i);e!==void 0&&h.push(e)}else if(n===`invokes`){let n=T.exec(i.content);if(n===null)t.error(e.InvalidInvokesDeclaration,`Invalid invokes declaration '${i.content}' - expected 'invokes <Command>'`,r(i)),t.skipBlock(i.indent);else{let s=new d(t.reader.fork(),t.path,t.languages);s.scope=t.scope,s.sourceOptions=t.sourceOptions,f(s,i),t.inputUses.push(...s.inputUses);let c=[],l=[];for(let n=t.peekChild(i.indent);n!==void 0;n=t.peekChild(i.indent)){if(t.reader.takeSignificant(),p(n)){m(t,n);continue}if(D.test(n.content)){let e=parseRefusal(t,n);e!==void 0&&l.push(e);continue}let i=E.exec(n.content);i===null?t.error(e.InvalidPropertyMapping,`Invalid property mapping '${n.content}' - expected '<property> = <source>'`,r(n),o(`text`,n.content)):c.push({kind:`PropertyMappingSyntax`,property:i[1].replaceAll(`@`,``),source:a(i[2],r(n),t.valueContext),location:r(n)})}g.push({kind:`InvokesSyntax`,command:n[1],mappings:c,onRefused:l,location:r(i)})}}else if(D.test(i.content))t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,r(i)),t.skipBlock(i.indent);else if(n===`reads`||n===`file`||i.content===`csharp`||i.content.startsWith("```")){S||=n===`file`||i.content===`csharp`||i.content.startsWith("```");let a=n===`reads`?_(t,i):void 0;a!==void 0&&b.push(a),k.test(i.content)&&t.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,r(i)),i.content.startsWith("```")&&t.skipFencedBody(),t.skipOpaqueBlock(i.indent)}else{let e=t.triggerData.length;y(t,i);for(let n of t.triggerData.slice(e))x.push({kind:`TriggerDataSyntax`,name:n.name,type:n.type,location:n.location})}}let C={kind:`ReactionTriggerSyntax`,source:l,description:u,produces:h,invokes:g,location:r(n)};return i.set(C,{reads:b,data:x,implementation:S}),C}function parseRefusal(t,n){let i=O.exec(n.content);if(i===null||i[2]!==void 0&&i[1]!==`constraint`){t.error(e.InvalidRefusalBranch,`Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.`,r(n)),t.skipBlock(n.indent);return}let a=[],o=!1,c=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent))if(t.reader.takeSignificant(),p(i))m(t,i),c=!0;else if(i.content===`acknowledge`)(o||a.length>0||t.peekChild(i.indent)!==void 0)&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.`,r(i)),c=!0),o=!0,t.skipBlock(i.indent);else if(s(i.content)===`produces`){o&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch cannot combine 'acknowledge' and 'produces'.`,r(i)),c=!0);let n=v(t,i);n===void 0?c=!0:a.push(n)}else t.error(e.InvalidRefusalBranchBody,`Expected 'acknowledge' or 'produces <Event>' in a refusal branch.`,r(i)),t.skipBlock(i.indent),c=!0;return!o&&a.length===0&&!c&&t.error(e.InvalidRefusalBranchBody,`A refusal branch must acknowledge or produce an event.`,r(n)),{kind:`InvocationRefusalSyntax`,selector:i[1]??`any`,constraint:i[2]??null,acknowledge:o,produces:a,location:r(n)}}function sourceKey(e){switch(e.kind){case`NamedTriggerSourceSyntax`:return JSON.stringify([e.kind,e.name]);case`IntervalTriggerSourceSyntax`:return JSON.stringify([e.kind,e.amount,e.unit]);case`ScheduleTriggerSourceSyntax`:return JSON.stringify([e.kind,e.time,e.dayOfWeek,e.dayOfMonth])}}function parseTriggerSource(t,n){let i=r(n);switch(s(n.content)){case`when`:{let r=x.exec(n.content);if(r===null){t.error(e.InvalidReactionTrigger,`Invalid trigger '${n.content}' - expected 'when <Name>'`,i),t.skipBlock(n.indent);return}return{kind:`NamedTriggerSourceSyntax`,name:r[1],location:i}}case`every`:{let r=S.exec(n.content),a=r===null?NaN:Number(r[1]);if(r===null||!Number.isInteger(a)||a<1||a>2147483647){t.error(e.InvalidIntervalTrigger,`Invalid interval '${n.content}' - expected 'every <n> <seconds|minutes|hours|days>'`,i),t.skipBlock(n.indent);return}return{kind:`IntervalTriggerSourceSyntax`,amount:a,unit:unitOf(r[2]),location:i}}default:return parseSchedule(t,n)}}function parseSchedule(t,n){let i=r(n),a=C.exec(n.content),o=a===null?void 0:timeOf(a[1]);if(a===null||o===void 0)t.error(e.InvalidScheduleTrigger,`Invalid schedule '${n.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`,i),t.skipBlock(n.indent);else{if(a[3]!==void 0){let r=Number(a[3]);if(r<1||r>31){t.error(e.InvalidScheduleTrigger,`Invalid day of month '${r}' in '${n.content}' - a day of the month is between 1 and 31`,i),t.skipBlock(n.indent);return}return{kind:`ScheduleTriggerSourceSyntax`,time:o,dayOfWeek:null,dayOfMonth:r,location:i}}return{kind:`ScheduleTriggerSourceSyntax`,time:o,dayOfWeek:a[2]??null,dayOfMonth:null,location:i}}}function timeOf(e){let[t,n]=e.split(`:`).map(Number);if(t>=0&&t<=23&&n>=0&&n<=59)return`${e}:00.0000000`}function unitOf(e){switch(e.replace(/s+$/,``)){case`second`:return`Seconds`;case`minute`:return`Minutes`;case`hour`:return`Hours`;default:return`Days`}}export{parseReaction,parseTriggerSource};
2
2
  //# sourceMappingURL=ReactionParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactionParser.js","names":["parseMappingSource","header","pattern","whenPattern","everyPattern","atPattern","clauseKeywords","invokesPattern","mappingPattern","nativePattern","refusalPrefix","refusalHeader","optionalReads","name","line","context","DiagnosticCodes","locationOf","description","documentation","where","from","runsAs","identityDeclared","triggers","sources","reported","child","keyword","firstWord","parseDescription","parseDocumentation","parseObserverFilter","parseReactionIdentity","parseCondition","source","key","produces","invokes","reads","data","implementation","isReactionIdentityLine","misplacedReactionIdentity","produced","parseProduces","match","uses","ParserContext","collectInputUses","mappings","onRefused","value","refusal","mapped","parseModeledMappingSource","read","parseReads","start","parseTriggerData","property","syntax","dependencySources","acknowledge","location","amount","time","day","hours","minutes","text"],"sources":["../../../../../../Compiler/Parsing/ReactionParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ConditionSyntax } from '../Syntax/Conditions';\nimport { PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { InvocationRefusalSyntax } from '../Syntax/InvocationRefusalSyntax';\nimport { parseCondition } from './ConditionParser';\nimport { ObserverFilterSyntax } from '../Syntax/ObserverFilterSyntax';\nimport { parseObserverFilter } from './ObserverFilterParser';\nimport { parseModeledMappingSource as parseMappingSource } from './ExpressionParser';\nimport { DayOfWeek, IntervalUnit, InvokesSyntax, ProducesSyntax, ReactionSyntax, ReactionTriggerSyntax, TriggerSourceSyntax } from '../Syntax/Reactions';\nimport { nativePattern, pattern } from '../Text/patterns';\nimport { ReactionIdentitySyntax } from '../Syntax/ReactionIdentitySyntax';\nimport { isReactionIdentityLine, misplacedReactionIdentity, parseReactionIdentity } from './ReactionIdentityParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { collectInputUses } from './InputUses';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseTriggerData } from './TriggerDataParser';\nimport { dependencySources, ReadsSyntax, TriggerDataSyntax } from '../Syntax/DependencySources';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^reaction\\\\s+([A-Za-z_]\\\\w*)$');\nconst whenPattern = pattern('^when\\\\s+([A-Za-z_]\\\\w*)$');\nconst everyPattern = pattern('^every\\\\s+(\\\\d+)\\\\s+(seconds?|minutes?|hours?|days?)$');\nconst atPattern = pattern('^at\\\\s+(\\\\d{2}:\\\\d{2})(?:\\\\s+on\\\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\\\s+(\\\\d{1,2})))?$');\nconst clauseKeywords = new Set(['when', 'every', 'at']);\nconst invokesPattern = pattern('^invokes\\\\s+([A-Z]\\\\w*)$');\nconst mappingPattern = nativePattern('^(@?[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst refusalPrefix = nativePattern('^on\\\\s+refused\\\\b(?=$|\\\\s+by\\\\b)');\nconst refusalHeader = nativePattern('^on\\\\s+refused(?:\\\\s+by\\\\s+(validation|constraint|authorization)(?:\\\\s+([A-Za-z_]\\\\w*(?:\\\\.\\\\w+)*))?)?$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\nexport function parseReaction(context: ParserContext, line: SourceLine): ReactionSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReactionDeclaration, `Invalid reaction declaration '${line.content}' - expected 'reaction <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n let documentation: string | null = null;\n let where: ConditionSyntax | null = null;\n let from: ObserverFilterSyntax | null = null;\n let runsAs: ReactionIdentitySyntax | null = null;\n let identityDeclared = false;\n const triggers: ReactionTriggerSyntax[] = [];\n const sources = new Set<string>();\n // A reaction whose only trigger is misspelled has no trigger, but saying so as well turns one mistake\n // into two diagnostics.\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'from') {\n from = parseObserverFilter(context, child, from);\n continue;\n }\n if (keyword === 'runs') {\n runsAs = parseReactionIdentity(context, child, identityDeclared) ?? runsAs;\n identityDeclared = true;\n continue;\n }\n if (keyword === 'where') {\n where = parseCondition(context, child.content.substring('where'.length).trim(), locationOf(child));\n continue;\n }\n if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n if (!clauseKeywords.has(keyword)) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Expected a trigger in reaction body, got '${child.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`, locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n const source = parseTriggerSource(context, child);\n if (source === undefined) {\n reported = true;\n continue;\n }\n const key = sourceKey(source);\n if (sources.has(key)) {\n context.error(DiagnosticCodes.DuplicateReactionTrigger, `Reaction '${name}' already declares '${child.content}' - a second says nothing the first did not`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n sources.add(key);\n triggers.push(parseTrigger(context, child, source));\n }\n if (triggers.length === 0 && !reported) {\n context.error(DiagnosticCodes.ReactionWithoutTrigger, `Reaction '${name}' must declare at least one trigger - nothing sets it off`, locationOf(line));\n }\n return { kind: 'ReactionSyntax', name, description, documentation, from, runsAs, where, triggers, location: locationOf(line) };\n}\n\n// What a trigger does - the events it produces and the commands it invokes - is read by name; its reads,\n// values and code are not modeled. The C# compiler remains the authority on whether what is skipped is valid.\nfunction parseTrigger(context: ParserContext, line: SourceLine, source: TriggerSourceSyntax): ReactionTriggerSyntax {\n let description: string | null = null;\n const produces: ProducesSyntax[] = [];\n const invokes: InvokesSyntax[] = [];\n const reads: ReadsSyntax[] = [];\n const data: TriggerDataSyntax[] = [];\n let implementation = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Trigger '${child.content}'`);\n } else if (keyword === 'produces') {\n const produced = parseProduces(context, child);\n if (produced !== undefined) {\n produces.push(produced);\n }\n } else if (keyword === 'invokes') {\n const match = invokesPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidInvokesDeclaration, `Invalid invokes declaration '${child.content}' - expected 'invokes <Command>'`, locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const uses = new ParserContext(context.reader.fork(), context.path, context.languages);\n uses.scope = context.scope;\n uses.sourceOptions = context.sourceOptions;\n collectInputUses(uses, child);\n context.inputUses.push(...uses.inputUses);\n const mappings: PropertyMappingSyntax[] = [];\n const onRefused: InvocationRefusalSyntax[] = [];\n for (let value = context.peekChild(child.indent); value !== undefined; value = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(value)) {\n misplacedReactionIdentity(context, value);\n continue;\n }\n if (refusalPrefix.test(value.content)) {\n const refusal = parseRefusal(context, value);\n if (refusal !== undefined) onRefused.push(refusal);\n continue;\n }\n const mapped = mappingPattern.exec(value.content);\n if (mapped !== null) mappings.push({ kind: 'PropertyMappingSyntax', property: mapped[1].replaceAll('@', ''), source: parseMappingSource(mapped[2], locationOf(value), context.valueContext), location: locationOf(value) });\n else context.error(DiagnosticCodes.InvalidPropertyMapping, `Invalid property mapping '${value.content}' - expected '<property> = <source>'`, locationOf(value));\n }\n invokes.push({ kind: 'InvokesSyntax', command: match[1], mappings, onRefused, location: locationOf(child) });\n }\n } else if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n } else if (keyword === 'reads' || keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```')) {\n implementation ||= keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```');\n const read = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (read !== undefined) reads.push(read);\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n if (child.content.startsWith('```')) {\n context.skipFencedBody();\n }\n context.skipOpaqueBlock(child.indent);\n } else {\n const start = context.triggerData.length;\n parseTriggerData(context, child);\n for (const property of context.triggerData.slice(start)) data.push({ kind: 'TriggerDataSyntax', name: property.name, type: property.type, location: property.location });\n }\n }\n const syntax: ReactionTriggerSyntax = { kind: 'ReactionTriggerSyntax', source, description, produces, invokes, location: locationOf(line) };\n dependencySources.set(syntax, { reads, data, implementation });\n return syntax;\n}\n\nfunction parseRefusal(context: ParserContext, line: SourceLine): InvocationRefusalSyntax | undefined {\n const match = refusalHeader.exec(line.content);\n if (match === null || (match[2] !== undefined && match[1] !== 'constraint')) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.\", locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n const produces: ProducesSyntax[] = [];\n let acknowledge = false;\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n reported = true;\n } else if (child.content === 'acknowledge') {\n if (acknowledge || produces.length > 0 || context.peekChild(child.indent) !== undefined) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.\", locationOf(child));\n reported = true;\n }\n acknowledge = true;\n context.skipBlock(child.indent);\n } else if (firstWord(child.content) === 'produces') {\n if (acknowledge) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch cannot combine 'acknowledge' and 'produces'.\", locationOf(child));\n reported = true;\n }\n const produced = parseProduces(context, child);\n if (produced !== undefined) produces.push(produced);\n else reported = true;\n } else {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"Expected 'acknowledge' or 'produces <Event>' in a refusal branch.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n }\n }\n if (!acknowledge && produces.length === 0 && !reported) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, 'A refusal branch must acknowledge or produce an event.', locationOf(line));\n }\n return { kind: 'InvocationRefusalSyntax', selector: match[1] ?? 'any', constraint: match[2] ?? null, acknowledge, produces, location: locationOf(line) };\n}\n\nfunction sourceKey(source: TriggerSourceSyntax): string {\n switch (source.kind) {\n case 'NamedTriggerSourceSyntax': return JSON.stringify([source.kind, source.name]);\n case 'IntervalTriggerSourceSyntax': return JSON.stringify([source.kind, source.amount, source.unit]);\n case 'ScheduleTriggerSourceSyntax': return JSON.stringify([source.kind, source.time, source.dayOfWeek, source.dayOfMonth]);\n }\n}\n\n// Reads a 'when', 'every' or 'at' clause - the port of the C# TriggerParser.ParseSource. The caller only\n// hands it a line starting with one of the three, so anything that is not 'when' or 'every' is 'at'.\nexport function parseTriggerSource(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'when': {\n const match = whenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Invalid trigger '${line.content}' - expected 'when <Name>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'NamedTriggerSourceSyntax', name: match[1], location };\n }\n case 'every': {\n const match = everyPattern.exec(line.content);\n const amount = match === null ? NaN : Number(match[1]);\n if (match === null || !Number.isInteger(amount) || amount < 1 || amount > 2147483647) {\n context.error(DiagnosticCodes.InvalidIntervalTrigger, `Invalid interval '${line.content}' - expected 'every <n> <seconds|minutes|hours|days>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'IntervalTriggerSourceSyntax', amount, unit: unitOf(match[2]), location };\n }\n default:\n return parseSchedule(context, line);\n }\n}\n\nfunction parseSchedule(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n const match = atPattern.exec(line.content);\n const time = match === null ? undefined : timeOf(match[1]);\n if (match === null || time === undefined) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid schedule '${line.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n if (match[3] !== undefined) {\n const day = Number(match[3]);\n if (day < 1 || day > 31) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid day of month '${day}' in '${line.content}' - a day of the month is between 1 and 31`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: null, dayOfMonth: day, location };\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: (match[2] as DayOfWeek | undefined) ?? null, dayOfMonth: null, location };\n}\n\n// 'HH:mm' as SyntaxJson writes a TimeOnly, or undefined when it is not a time of day.\nfunction timeOf(text: string): string | undefined {\n const [hours, minutes] = text.split(':').map(Number);\n if (!(hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59)) {\n return undefined;\n }\n return `${text}:00.0000000`;\n}\n\nfunction unitOf(text: string): IntervalUnit {\n switch (text.replace(/s+$/, '')) {\n case 'second':\n return 'Seconds';\n case 'minute':\n return 'Minutes';\n case 'hour':\n return 'Hours';\n default:\n return 'Days';\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactionParser.js","names":["parseMappingSource","header","pattern","whenPattern","everyPattern","atPattern","clauseKeywords","invokesPattern","mappingPattern","nativePattern","refusalPrefix","refusalHeader","optionalReads","name","line","context","DiagnosticCodes","locationOf","description","documentation","where","from","runsAs","identityDeclared","triggers","sources","reported","child","keyword","firstWord","parseDescription","parseDocumentation","parseObserverFilter","parseReactionIdentity","parseCondition","source","key","produces","invokes","reads","data","implementation","isReactionIdentityLine","misplacedReactionIdentity","produced","parseProduces","match","uses","ParserContext","collectInputUses","mappings","onRefused","value","refusal","mapped","diagnosticText","parseModeledMappingSource","read","parseReads","start","parseTriggerData","property","syntax","dependencySources","acknowledge","location","amount","time","day","hours","minutes","text"],"sources":["../../../../../../Compiler/Parsing/ReactionParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ConditionSyntax } from '../Syntax/Conditions';\nimport { PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { InvocationRefusalSyntax } from '../Syntax/InvocationRefusalSyntax';\nimport { parseCondition } from './ConditionParser';\nimport { ObserverFilterSyntax } from '../Syntax/ObserverFilterSyntax';\nimport { parseObserverFilter } from './ObserverFilterParser';\nimport { parseModeledMappingSource as parseMappingSource } from './ExpressionParser';\nimport { DayOfWeek, IntervalUnit, InvokesSyntax, ProducesSyntax, ReactionSyntax, ReactionTriggerSyntax, TriggerSourceSyntax } from '../Syntax/Reactions';\nimport { nativePattern, pattern } from '../Text/patterns';\nimport { ReactionIdentitySyntax } from '../Syntax/ReactionIdentitySyntax';\nimport { isReactionIdentityLine, misplacedReactionIdentity, parseReactionIdentity } from './ReactionIdentityParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { collectInputUses } from './InputUses';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseTriggerData } from './TriggerDataParser';\nimport { dependencySources, ReadsSyntax, TriggerDataSyntax } from '../Syntax/DependencySources';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^reaction\\\\s+([A-Za-z_]\\\\w*)$');\nconst whenPattern = pattern('^when\\\\s+([A-Za-z_]\\\\w*)$');\nconst everyPattern = pattern('^every\\\\s+(\\\\d+)\\\\s+(seconds?|minutes?|hours?|days?)$');\nconst atPattern = pattern('^at\\\\s+(\\\\d{2}:\\\\d{2})(?:\\\\s+on\\\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\\\s+(\\\\d{1,2})))?$');\nconst clauseKeywords = new Set(['when', 'every', 'at']);\nconst invokesPattern = pattern('^invokes\\\\s+([A-Z]\\\\w*)$');\nconst mappingPattern = nativePattern('^(@?[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst refusalPrefix = nativePattern('^on\\\\s+refused\\\\b(?=$|\\\\s+by\\\\b)');\nconst refusalHeader = nativePattern('^on\\\\s+refused(?:\\\\s+by\\\\s+(validation|constraint|authorization)(?:\\\\s+([A-Za-z_]\\\\w*(?:\\\\.\\\\w+)*))?)?$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\nexport function parseReaction(context: ParserContext, line: SourceLine): ReactionSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReactionDeclaration, `Invalid reaction declaration '${line.content}' - expected 'reaction <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n let documentation: string | null = null;\n let where: ConditionSyntax | null = null;\n let from: ObserverFilterSyntax | null = null;\n let runsAs: ReactionIdentitySyntax | null = null;\n let identityDeclared = false;\n const triggers: ReactionTriggerSyntax[] = [];\n const sources = new Set<string>();\n // A reaction whose only trigger is misspelled has no trigger, but saying so as well turns one mistake\n // into two diagnostics.\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'from') {\n from = parseObserverFilter(context, child, from);\n continue;\n }\n if (keyword === 'runs') {\n runsAs = parseReactionIdentity(context, child, identityDeclared) ?? runsAs;\n identityDeclared = true;\n continue;\n }\n if (keyword === 'where') {\n where = parseCondition(context, child.content.substring('where'.length).trim(), locationOf(child));\n continue;\n }\n if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n if (!clauseKeywords.has(keyword)) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Expected a trigger in reaction body, got '${child.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`, locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n const source = parseTriggerSource(context, child);\n if (source === undefined) {\n reported = true;\n continue;\n }\n const key = sourceKey(source);\n if (sources.has(key)) {\n context.error(DiagnosticCodes.DuplicateReactionTrigger, `Reaction '${name}' already declares '${child.content}' - a second says nothing the first did not`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n sources.add(key);\n triggers.push(parseTrigger(context, child, source));\n }\n if (triggers.length === 0 && !reported) {\n context.error(DiagnosticCodes.ReactionWithoutTrigger, `Reaction '${name}' must declare at least one trigger - nothing sets it off`, locationOf(line));\n }\n return { kind: 'ReactionSyntax', name, description, documentation, from, runsAs, where, triggers, location: locationOf(line) };\n}\n\n// What a trigger does - the events it produces and the commands it invokes - is read by name; its reads,\n// values and code are not modeled. The C# compiler remains the authority on whether what is skipped is valid.\nfunction parseTrigger(context: ParserContext, line: SourceLine, source: TriggerSourceSyntax): ReactionTriggerSyntax {\n let description: string | null = null;\n const produces: ProducesSyntax[] = [];\n const invokes: InvokesSyntax[] = [];\n const reads: ReadsSyntax[] = [];\n const data: TriggerDataSyntax[] = [];\n let implementation = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Trigger '${child.content}'`);\n } else if (keyword === 'produces') {\n const produced = parseProduces(context, child);\n if (produced !== undefined) {\n produces.push(produced);\n }\n } else if (keyword === 'invokes') {\n const match = invokesPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidInvokesDeclaration, `Invalid invokes declaration '${child.content}' - expected 'invokes <Command>'`, locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const uses = new ParserContext(context.reader.fork(), context.path, context.languages);\n uses.scope = context.scope;\n uses.sourceOptions = context.sourceOptions;\n collectInputUses(uses, child);\n context.inputUses.push(...uses.inputUses);\n const mappings: PropertyMappingSyntax[] = [];\n const onRefused: InvocationRefusalSyntax[] = [];\n for (let value = context.peekChild(child.indent); value !== undefined; value = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(value)) {\n misplacedReactionIdentity(context, value);\n continue;\n }\n if (refusalPrefix.test(value.content)) {\n const refusal = parseRefusal(context, value);\n if (refusal !== undefined) onRefused.push(refusal);\n continue;\n }\n const mapped = mappingPattern.exec(value.content);\n if (mapped !== null) mappings.push({ kind: 'PropertyMappingSyntax', property: mapped[1].replaceAll('@', ''), source: parseMappingSource(mapped[2], locationOf(value), context.valueContext), location: locationOf(value) });\n else context.error(DiagnosticCodes.InvalidPropertyMapping, `Invalid property mapping '${value.content}' - expected '<property> = <source>'`, locationOf(value), diagnosticText('text', value.content));\n }\n invokes.push({ kind: 'InvokesSyntax', command: match[1], mappings, onRefused, location: locationOf(child) });\n }\n } else if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n } else if (keyword === 'reads' || keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```')) {\n implementation ||= keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```');\n const read = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (read !== undefined) reads.push(read);\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n if (child.content.startsWith('```')) {\n context.skipFencedBody();\n }\n context.skipOpaqueBlock(child.indent);\n } else {\n const start = context.triggerData.length;\n parseTriggerData(context, child);\n for (const property of context.triggerData.slice(start)) data.push({ kind: 'TriggerDataSyntax', name: property.name, type: property.type, location: property.location });\n }\n }\n const syntax: ReactionTriggerSyntax = { kind: 'ReactionTriggerSyntax', source, description, produces, invokes, location: locationOf(line) };\n dependencySources.set(syntax, { reads, data, implementation });\n return syntax;\n}\n\nfunction parseRefusal(context: ParserContext, line: SourceLine): InvocationRefusalSyntax | undefined {\n const match = refusalHeader.exec(line.content);\n if (match === null || (match[2] !== undefined && match[1] !== 'constraint')) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.\", locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n const produces: ProducesSyntax[] = [];\n let acknowledge = false;\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n reported = true;\n } else if (child.content === 'acknowledge') {\n if (acknowledge || produces.length > 0 || context.peekChild(child.indent) !== undefined) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.\", locationOf(child));\n reported = true;\n }\n acknowledge = true;\n context.skipBlock(child.indent);\n } else if (firstWord(child.content) === 'produces') {\n if (acknowledge) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch cannot combine 'acknowledge' and 'produces'.\", locationOf(child));\n reported = true;\n }\n const produced = parseProduces(context, child);\n if (produced !== undefined) produces.push(produced);\n else reported = true;\n } else {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"Expected 'acknowledge' or 'produces <Event>' in a refusal branch.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n }\n }\n if (!acknowledge && produces.length === 0 && !reported) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, 'A refusal branch must acknowledge or produce an event.', locationOf(line));\n }\n return { kind: 'InvocationRefusalSyntax', selector: match[1] ?? 'any', constraint: match[2] ?? null, acknowledge, produces, location: locationOf(line) };\n}\n\nfunction sourceKey(source: TriggerSourceSyntax): string {\n switch (source.kind) {\n case 'NamedTriggerSourceSyntax': return JSON.stringify([source.kind, source.name]);\n case 'IntervalTriggerSourceSyntax': return JSON.stringify([source.kind, source.amount, source.unit]);\n case 'ScheduleTriggerSourceSyntax': return JSON.stringify([source.kind, source.time, source.dayOfWeek, source.dayOfMonth]);\n }\n}\n\n// Reads a 'when', 'every' or 'at' clause - the port of the C# TriggerParser.ParseSource. The caller only\n// hands it a line starting with one of the three, so anything that is not 'when' or 'every' is 'at'.\nexport function parseTriggerSource(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'when': {\n const match = whenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Invalid trigger '${line.content}' - expected 'when <Name>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'NamedTriggerSourceSyntax', name: match[1], location };\n }\n case 'every': {\n const match = everyPattern.exec(line.content);\n const amount = match === null ? NaN : Number(match[1]);\n if (match === null || !Number.isInteger(amount) || amount < 1 || amount > 2147483647) {\n context.error(DiagnosticCodes.InvalidIntervalTrigger, `Invalid interval '${line.content}' - expected 'every <n> <seconds|minutes|hours|days>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'IntervalTriggerSourceSyntax', amount, unit: unitOf(match[2]), location };\n }\n default:\n return parseSchedule(context, line);\n }\n}\n\nfunction parseSchedule(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n const match = atPattern.exec(line.content);\n const time = match === null ? undefined : timeOf(match[1]);\n if (match === null || time === undefined) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid schedule '${line.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n if (match[3] !== undefined) {\n const day = Number(match[3]);\n if (day < 1 || day > 31) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid day of month '${day}' in '${line.content}' - a day of the month is between 1 and 31`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: null, dayOfMonth: day, location };\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: (match[2] as DayOfWeek | undefined) ?? null, dayOfMonth: null, location };\n}\n\n// 'HH:mm' as SyntaxJson writes a TimeOnly, or undefined when it is not a time of day.\nfunction timeOf(text: string): string | undefined {\n const [hours, minutes] = text.split(':').map(Number);\n if (!(hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59)) {\n return undefined;\n }\n return `${text}:00.0000000`;\n}\n\nfunction unitOf(text: string): IntervalUnit {\n switch (text.replace(/s+$/, '')) {\n case 'second':\n return 'Seconds';\n case 'minute':\n return 'Minutes';\n case 'hour':\n return 'Hours';\n default:\n return 'Days';\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseEventSource as b}from"./EventSourceParser.js";import{isFileDirective as x}from"./FileReferences.js";import{parseSystem as S}from"./OperationParser.js";import{parseExample as C}from"./SpecificationExampleParser.js";import{isBlankPublicEventOrigin as w}from"../Syntax/PublicEventInvariants.js";import{parseType as T}from"./DeclarationParsers.js";import{parseValidate as E}from"./CommandParser.js";import{parseTriggerDeclaration as D}from"./TriggerDataParser.js";import{FeatureBody as O,featureBodyExpected as k}from"./FeatureBody.js";import{ModuleBody as A,moduleBodyExpected as j,modulePattern as M,parseModule as N}from"./ModuleBody.js";import{EnumerationMembers as P}from"./EnumerationMembers.js";import{parseGeneration as F}from"./GenerationParser.js";import{parseIdentity as I}from"./IdentityParser.js";import{parsePolicy as ee}from"./PolicyParser.js";import{parseSeed as L}from"./SeedParser.js";import{parseExposure as R,parseInstance as z}from"./CompositionParser.js";const B=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),V=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),H=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),U=r(`^@?[a-z_]\\w*$`),W=r(`^persona\\s+([A-Za-z_]\\w*)$`),G=r(`^policy\\s+([A-Za-z_]\\w*)$`),K=/^[ ]*\t/,q=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],J=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),Y=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new A(a[0]):void 0,s=a.length>1?new O(a[a.length-1]):void 0,l=o??s,u=null,p=null,x=!1,E=null,k=[],j=[],M=[],P=[],F=[],B=[],H=[],U=[],W=[],G=[],K=[],q=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`reaction`)x||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,x=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,E=parseDomain(t,r,E,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,j):l.tryParse(t,r);else if(s===`import`){let a=V.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&w(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),k.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?q.push(C(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(b(t,r));else if(s===`system`)F.push(S(t,r));else if(s===`concept`)M.push(parseConcept(t,r));else if(s===`type`)P.push(T(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)H.push(N(t,r));else if(s===`persona`)U.push(parsePersona(t,r));else if(s===`seed`)K.push(L(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=I(t,r,u);else if(s===`policy`)W.push(ee(t,r));else if(s===`exposure`)X.push(R(t,r));else if(s===`instance`)Z.push(z(t,r));else if(s===`trigger`){let e=D(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else J.has(s)?s===`behavior`||s===`layout`?v(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&H.unshift(place(a,s.build(t.start,!0),t.start)):H.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:E,imports:k,concepts:M,types:P,systems:F,eventSources:B,examples:q,modules:H,personas:U,policies:W,purposes:G,seeds:K,declaredTriggers:Y,fileImports:j,...X.length>0?{exposures:X}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?V.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||J.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=M.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=Y.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?j:k;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=B.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&K.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=H.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!q.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${q.join(`, `)} or Enum`,i(n));let m=[],h=new P,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(x(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=E(t,r,`concept`);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=F(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&U.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,n){let r=W.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${n.content}' - expected 'persona <Name>'`,i(n));let a=null,o=[];for(let s=t.peekChild(n.indent);s!==void 0;s=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(s.content);if(n===`description`)a=p(t,s,a,`Persona '${r}'`);else if(n===`policy`){let n=G.exec(s.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${s.content}' - expected 'policy <Name>'`,i(s)):o.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in persona body - expected description or policy`,i(s)),t.skipBlock(s.indent)}return{kind:`PersonaSyntax`,name:r,description:a,policies:o,location:i(n)}}export{parseApplication};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseEventSource as b}from"./EventSourceParser.js";import{isFileDirective as x}from"./FileReferences.js";import{parseSystem as S}from"./OperationParser.js";import{parseExample as C}from"./SpecificationExampleParser.js";import{isBlankPublicEventOrigin as w}from"../Syntax/PublicEventInvariants.js";import{parseType as ee}from"./DeclarationParsers.js";import{parseValidate as T}from"./CommandParser.js";import{parseTriggerDeclaration as E}from"./TriggerDataParser.js";import{FeatureBody as D,featureBodyExpected as O}from"./FeatureBody.js";import{ModuleBody as k,moduleBodyExpected as A,modulePattern as j,parseModule as M}from"./ModuleBody.js";import{EnumerationMembers as N}from"./EnumerationMembers.js";import{parseGeneration as P}from"./GenerationParser.js";import{parseIdentity as te}from"./IdentityParser.js";import{parsePolicy as ne}from"./PolicyParser.js";import{parseSeed as F}from"./SeedParser.js";import{parseExposure as I,parseInstance as L}from"./CompositionParser.js";const R=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),z=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),B=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),V=r(`^@?[a-z_]\\w*$`),H=r(`^persona\\s+([A-Za-z_]\\w*)$`),U=r(`^policy\\s+([A-Za-z_]\\w*)$`),W=/^[ ]*\t/,G=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],K=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),q=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new k(a[0]):void 0,s=a.length>1?new D(a[a.length-1]):void 0,l=o??s,u=null,p=null,x=!1,T=null,O=!1,A=null,j=[],N=[],P=[],R=[],B=[],V=[],H=[],U=[],W=[],G=[],q=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))O||!f(a)||!/^command\s+reads\s+protected$/.test(r.content)?t.error(e.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,i(r)):T=`Protected`,O=!0;else if(s===`reaction`)x||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,x=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,A=parseDomain(t,r,A,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,N):l.tryParse(t,r);else if(s===`import`){let a=z.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&w(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),j.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?J.push(C(t,r)):l.tryParse(t,r);else if(s===`eventsource`)V.push(b(t,r));else if(s===`system`)B.push(S(t,r));else if(s===`concept`)P.push(parseConcept(t,r));else if(s===`type`)R.push(ee(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)H.push(M(t,r));else if(s===`persona`)U.push(parsePersona(t,r));else if(s===`seed`)q.push(F(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=te(t,r,u);else if(s===`policy`)W.push(ne(t,r));else if(s===`exposure`)X.push(I(t,r));else if(s===`instance`)Z.push(L(t,r));else if(s===`trigger`){let e=E(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else K.has(s)?s===`behavior`||s===`layout`?v(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&H.unshift(place(a,s.build(t.start,!0),t.start)):H.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...T===null?{}:{commandReadMode:T},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:A,imports:j,concepts:P,types:R,systems:B,eventSources:V,examples:J,modules:H,personas:U,policies:W,purposes:G,seeds:q,declaredTriggers:Y,fileImports:N,...X.length>0?{exposures:X}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?z.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||K.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=j.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=q.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?A:O;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=R.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&W.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=B.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!G.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${G.join(`, `)} or Enum`,i(n));let m=[],h=new N,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(x(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=T(t,r,`concept`);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=P(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&V.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,n){let r=H.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${n.content}' - expected 'persona <Name>'`,i(n));let a=null,o=[];for(let s=t.peekChild(n.indent);s!==void 0;s=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(s.content);if(n===`description`)a=p(t,s,a,`Persona '${r}'`);else if(n===`policy`){let n=U.exec(s.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${s.content}' - expected 'policy <Name>'`,i(s)):o.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in persona body - expected description or policy`,i(s)),t.skipBlock(s.indent)}return{kind:`PersonaSyntax`,name:r,description:a,policies:o,location:i(n)}}export{parseApplication};
2
2
  //# sourceMappingURL=ScreenplayParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","importPattern","stringBodyPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","reactionProductionMode","sawReactionBatches","domain","imports","fileImports","concepts","types","systems","eventSources","modules","personas","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","misplacedReactionIdentity","isFileImport","parseFileImport","match","origin","unescapeString","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseType","parseModule","parseSeed","parsePurpose","parseIdentity","parsePolicy","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","policy"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n // Legacy policies were opaque: enrich their structure without adding diagnostics.\n policies.push(parsePolicy(context, line));\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept');\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Persona '${name}'`);\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description or policy`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return { kind: 'PersonaSyntax', name, description, policies, location: locationOf(line) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","importPattern","stringBodyPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","reactionProductionMode","sawReactionBatches","commandReadMode","sawCommandReads","domain","imports","fileImports","concepts","types","systems","eventSources","modules","personas","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","misplacedReactionIdentity","isFileImport","parseFileImport","match","origin","unescapeString","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseType","parseModule","parseSeed","parsePurpose","parseIdentity","parsePolicy","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","policy"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandReadMode } from '../Syntax/CommandReadMode';\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let commandReadMode: CommandReadMode | null = null;\n let sawCommandReads = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'command' && /^command\\s+reads(?:\\s|$)/.test(line.content)) {\n if (sawCommandReads || !isDocumentPlacement(placement) || !/^command\\s+reads\\s+protected$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidCommandReadsDeclaration, \"Declare 'command reads protected' once at the application root.\", locationOf(line));\n } else {\n commandReadMode = CommandReadMode.Protected;\n }\n sawCommandReads = true;\n continue;\n }\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n // Legacy policies were opaque: enrich their structure without adding diagnostics.\n policies.push(parsePolicy(context, line));\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(commandReadMode === null ? {} : { commandReadMode }), ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept');\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Persona '${name}'`);\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description or policy`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return { kind: 'PersonaSyntax', name, description, policies, location: locationOf(line) };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{parseProperty as i}from"./PropertyLineParser.js";import{parseConcrete as a}from"./SpecificationResponseParser.js";const o=new RegExp(t(`^case\\s+([A-Za-z_]\\w*)(?:\\s+(?<property>[\\w.]+)\\s*=(?!=|>)\\s*(?<value>.+))?$`).source,`du`),s=t(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),c=t(`^case\\.([a-z_]\\w*)$`);function containsCaseReference(e){return/\bcase\.[a-z_]\w*/.test(e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,``))}function parseSpecificationValue(t,n,i,a=!1){if(!t.startsWith(`case.`))return containsCaseReference(t)&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position; it cannot occur inside a structured value or expression.`,n),r(t,n,i,a);let o=c.exec(t);return o===null&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position: 'case.<parameter>'.`,n),{kind:`CaseValueExpressionSyntax`,parameter:o?.[1]??t.substring(5),location:n}}function parseParameter(t,r){let a=r.content.indexOf(` `)+1,o=a>0?i(t,{...r,content:r.content.substring(a),indent:r.indent+a}):void 0;if(o===void 0||o.isGenerated||o.isIdentifier)return t.error(e.InvalidSpecificationParameter,`Expected 'parameter <name> <Type>', with optional collection and optional modifiers.`,n(r)),t.skipOpaqueBlock(r.indent),null;let s=t.peekChild(r.indent);return s!==void 0&&(t.error(e.InvalidSpecificationParameter,`A parameter has no body or default.`,n(s)),t.skipOpaqueBlock(r.indent)),{kind:`SpecificationParameterSyntax`,name:o.name,type:o.type,location:n(r)}}function parseCase(t,r){let i=o.exec(r.content);if(i===null)return t.error(e.InvalidSpecificationCase,`Expected 'case <Name>' with at most one inline parameter assignment.`,n(r)),t.skipOpaqueBlock(r.indent),null;let c=[],add=(o,s,l)=>{let u=n(l),d={...u,column:u.column+l.content.indexOf(s,l.content.indexOf(`=`)+1)};if(s.startsWith(`case.`)){t.error(e.InvalidSpecificationCaseValue,`A case assigns concrete values, not case references.`,d);return}let f=a(t,s,d,e.InvalidSpecificationCaseValue);f!==null&&c.push({kind:`PropertyMappingSyntax`,property:o,source:f,location:l===r?{...u,column:u.column+i.indices.groups.property[0]}:u})};i.groups?.property!==void 0&&add(i.groups.property,i.groups.value,r);for(let i=t.peekChild(r.indent);i!==void 0;i=t.peekChild(r.indent)){t.reader.takeSignificant();let r=s.exec(i.content);if(r===null){t.error(e.InvalidSpecificationCaseAssignment,`Expected '<parameter> = <concrete value>' in a case.`,n(i)),t.skipOpaqueBlock(i.indent);continue}add(r[1],r[2],i);let a=t.peekChild(i.indent);a!==void 0&&(t.error(e.InvalidSpecificationCaseValue,`A case value must fit on one line.`,n(a)),t.skipOpaqueBlock(i.indent))}return{kind:`SpecificationCaseSyntax`,name:i[1],values:c,location:n(r)}}function caseReferences(e){return Array.isArray(e)?e.flatMap(caseReferences):typeof e!=`object`||!e?[]:`kind`in e&&e.kind===`CaseValueExpressionSyntax`?[e]:Object.values(e).flatMap(caseReferences)}function validateTable(t,n){let r=t.parameters??[],i=t.cases??[];r.length===0!=(i.length===0)&&n.error(e.IncompleteSpecificationTable,`A specification table requires parameters and at least one case.`,t.location),r.forEach((t,i)=>{r.slice(0,i).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationParameter,`Parameter '${t.name}' is declared more than once.`,t.location)}),i.forEach((t,a)=>{i.slice(0,a).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationCase,`Case '${t.name}' is declared more than once.`,t.location);for(let i of t.values.filter(e=>!r.some(t=>t.name===e.property)))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' assigns undeclared parameter '${i.property}'.`,i.location);for(let i of r.filter(e=>t.values.filter(t=>t.property===e.name).length!==1))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' must assign parameter '${i.name}' exactly once.`,t.location)});let a=caseReferences(t);for(let t of a)(i.length===0||!r.some(e=>e.name===t.parameter))&&n.error(e.InvalidSpecificationCaseReference,`Case reference '${t.parameter}' requires a declared parameter in a specification table.`,t.location);for(let t of r.filter(e=>!a.some(t=>t.parameter===e.name)))n.warning(e.UnusedSpecificationParameter,`Parameter '${t.name}' is never referenced.`,t.location);for(let r of caseReferences(t.whenRedelivered))n.error(e.InvalidSpecificationCaseReference,`Case references are not permitted in redelivery locators.`,r.location)}function substituteCase(e,t,n=/* @__PURE__ */ new WeakMap){if(typeof e==`object`&&e&&n.has(e))return n.get(e);if(Array.isArray(e)){let r=e.map(e=>substituteCase(e,t,n));return n.set(e,r),r}if(typeof e!=`object`||!e||!(`kind`in e))return e;if(e.kind===`CaseValueExpressionSyntax`){let n=e.parameter;return t.values.find(e=>e.property===n)?.source??e}let r=Object.fromEntries(Object.entries(e).map(([e,r])=>[e,substituteCase(r,t,n)]));if(e.kind===`SpecificationErrorSyntax`&&`caseValue`in e&&e.caseValue!==void 0){let e=r.caseValue;r.name=e.kind===`LiteralExpressionSyntax`?e.value:null,delete r.caseValue}return n.set(e,r),r}export{caseReferences,containsCaseReference,parseCase,parseParameter,parseSpecificationValue,substituteCase,validateTable};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{parseProperty as a}from"./PropertyLineParser.js";import{parseConcrete as o}from"./SpecificationResponseParser.js";const s=new RegExp(t(`^case\\s+([A-Za-z_]\\w*)(?:\\s+(?<property>[\\w.]+)\\s*=(?!=|>)\\s*(?<value>.+))?$`).source,`du`),c=t(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),l=t(`^case\\.([a-z_]\\w*)$`);function containsCaseReference(e){return/\bcase\.[a-z_]\w*/.test(e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,``))}function parseSpecificationValue(t,n,i,a=!1){if(!t.startsWith(`case.`))return containsCaseReference(t)&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position; it cannot occur inside a structured value or expression.`,n),r(t,n,i,a);let o=l.exec(t);return o===null&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position: 'case.<parameter>'.`,n),{kind:`CaseValueExpressionSyntax`,parameter:o?.[1]??t.substring(5),location:n}}function parseParameter(t,r){let i=r.content.indexOf(` `)+1,o=i>0?a(t,{...r,content:r.content.substring(i),indent:r.indent+i}):void 0;if(o===void 0||o.isGenerated||o.isIdentifier)return t.error(e.InvalidSpecificationParameter,`Expected 'parameter <name> <Type>', with optional collection and optional modifiers.`,n(r)),t.skipOpaqueBlock(r.indent),null;let s=t.peekChild(r.indent);return s!==void 0&&(t.error(e.InvalidSpecificationParameter,`A parameter has no body or default.`,n(s)),t.skipOpaqueBlock(r.indent)),{kind:`SpecificationParameterSyntax`,name:o.name,type:o.type,location:n(r)}}function parseCase(t,r){let a=s.exec(r.content);if(a===null)return t.error(e.InvalidSpecificationCase,`Expected 'case <Name>' with at most one inline parameter assignment.`,n(r)),t.skipOpaqueBlock(r.indent),null;let l=[],add=(s,c,u)=>{let d=n(u),f={...d,column:d.column+u.content.indexOf(c,u.content.indexOf(`=`)+1)};if(c.startsWith(`case.`)){t.error(e.InvalidSpecificationCaseValue,`A case assigns concrete values, not case references.`,f,i(`text`,c));return}let p=o(t,c,f,e.InvalidSpecificationCaseValue);p!==null&&l.push({kind:`PropertyMappingSyntax`,property:s,source:p,location:u===r?{...d,column:d.column+a.indices.groups.property[0]}:d})};a.groups?.property!==void 0&&add(a.groups.property,a.groups.value,r);for(let o=t.peekChild(r.indent);o!==void 0;o=t.peekChild(r.indent)){t.reader.takeSignificant();let r=c.exec(o.content);if(r===null){t.error(e.InvalidSpecificationCaseAssignment,`Expected '<parameter> = <concrete value>' in a case.`,n(o)),t.skipOpaqueBlock(o.indent);continue}add(r[1],r[2],o);let s=t.peekChild(o.indent);s!==void 0&&(t.error(e.InvalidSpecificationCaseValue,`A case value must fit on one line.`,n(s),{...i(`case`,a[1]),...i(`parameter`,r[1]),...i(`text`,s.content)}),t.skipOpaqueBlock(o.indent))}return{kind:`SpecificationCaseSyntax`,name:a[1],values:l,location:n(r)}}function caseReferences(e){return Array.isArray(e)?e.flatMap(caseReferences):typeof e!=`object`||!e?[]:`kind`in e&&e.kind===`CaseValueExpressionSyntax`?[e]:Object.values(e).flatMap(caseReferences)}function validateTable(t,n){let r=t.parameters??[],i=t.cases??[];r.length===0!=(i.length===0)&&n.error(e.IncompleteSpecificationTable,`A specification table requires parameters and at least one case.`,t.location),r.forEach((t,i)=>{r.slice(0,i).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationParameter,`Parameter '${t.name}' is declared more than once.`,t.location)}),i.forEach((t,a)=>{i.slice(0,a).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationCase,`Case '${t.name}' is declared more than once.`,t.location);for(let i of t.values.filter(e=>!r.some(t=>t.name===e.property)))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' assigns undeclared parameter '${i.property}'.`,i.location);for(let i of r.filter(e=>t.values.filter(t=>t.property===e.name).length!==1))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' must assign parameter '${i.name}' exactly once.`,t.location)});let a=caseReferences(t);for(let t of a)(i.length===0||!r.some(e=>e.name===t.parameter))&&n.error(e.InvalidSpecificationCaseReference,`Case reference '${t.parameter}' requires a declared parameter in a specification table.`,t.location);for(let t of r.filter(e=>!a.some(t=>t.parameter===e.name)))n.warning(e.UnusedSpecificationParameter,`Parameter '${t.name}' is never referenced.`,t.location);for(let r of caseReferences(t.whenRedelivered))n.error(e.InvalidSpecificationCaseReference,`Case references are not permitted in redelivery locators.`,r.location)}function substituteCase(e,t,n=/* @__PURE__ */ new WeakMap){if(typeof e==`object`&&e&&n.has(e))return n.get(e);if(Array.isArray(e)){let r=e.map(e=>substituteCase(e,t,n));return n.set(e,r),r}if(typeof e!=`object`||!e||!(`kind`in e))return e;if(e.kind===`CaseValueExpressionSyntax`){let n=e.parameter;return t.values.find(e=>e.property===n)?.source??e}let r=Object.fromEntries(Object.entries(e).map(([e,r])=>[e,substituteCase(r,t,n)]));if(e.kind===`SpecificationErrorSyntax`&&`caseValue`in e&&e.caseValue!==void 0){let e=r.caseValue;r.name=e.kind===`LiteralExpressionSyntax`?e.value:null,delete r.caseValue}return n.set(e,r),r}export{caseReferences,containsCaseReference,parseCase,parseParameter,parseSpecificationValue,substituteCase,validateTable};
2
2
  //# sourceMappingURL=SpecificationCaseParser.js.map