@cratis/screenplay-language 4.193.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 (30) hide show
  1. package/dist/bundles/compiler/Diagnostics/DiagnosticArgument.js +2 -0
  2. package/dist/bundles/compiler/Diagnostics/DiagnosticArgument.js.map +1 -0
  3. package/dist/bundles/compiler/Parsing/CaptureParser.js +1 -1
  4. package/dist/bundles/compiler/Parsing/CaptureParser.js.map +1 -1
  5. package/dist/bundles/compiler/Parsing/ParserContext.js +1 -1
  6. package/dist/bundles/compiler/Parsing/ParserContext.js.map +1 -1
  7. package/dist/bundles/compiler/Parsing/ProducesParser.js +1 -1
  8. package/dist/bundles/compiler/Parsing/ProducesParser.js.map +1 -1
  9. package/dist/bundles/compiler/Parsing/ProjectionParser.js +1 -1
  10. package/dist/bundles/compiler/Parsing/ProjectionParser.js.map +1 -1
  11. package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js +1 -1
  12. package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js.map +1 -1
  13. package/dist/bundles/compiler/Parsing/ReactionParser.js +1 -1
  14. package/dist/bundles/compiler/Parsing/ReactionParser.js.map +1 -1
  15. package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js +1 -1
  16. package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js.map +1 -1
  17. package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js +1 -1
  18. package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js.map +1 -1
  19. package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js +1 -1
  20. package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js.map +1 -1
  21. package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js +1 -1
  22. package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js.map +1 -1
  23. package/dist/bundles/compiler/Parsing/SpecificationParser.js +1 -1
  24. package/dist/bundles/compiler/Parsing/SpecificationParser.js.map +1 -1
  25. package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js +1 -1
  26. package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js.map +1 -1
  27. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js +1 -1
  28. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js.map +1 -1
  29. package/dist/bundles/compiler/index.js +1 -1
  30. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectionParser.js","names":["header","pattern","eventSpecPattern","joinPattern","withPattern","childrenPattern","nestedPattern","removeWithPattern","removeViaJoinPattern","clearWithPattern","variantPattern","entersOnPattern","keywordMappingPattern","arithmeticPattern","setPattern","assignmentPattern","keywordMappings","match","line","context","DiagnosticCodes","locationOf","firstWord","name","sequence","description","autoMap","key","blocks","child","isFileDirective","keyword","parseDescription","block","variants","byName","variant","duplicate","group","entering","entry","location","includeChildren","nestedScope","events","spec","splitTopLevel","text","unescapeIdentifier","parseProjectionExpression","mappings","parentKey","withMatch","property","viaJoin","entersOn","parts","expression","closing","extra","arithmetic","assigned"],"sources":["../../../../../../Compiler/Parsing/ProjectionParser.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 {\n AutoMapMode, ChildrenSyntax, ClearWithSyntax, EventSpecSyntax, FromSyntax, JoinEventSyntax, JoinSyntax, MappingKind, MappingSyntax, NestedSyntax,\n KeyPartSyntax, KeySyntax, ProjectionBlockSyntax, ProjectionEntersOnSyntax, ProjectionSyntax, ProjectionVariantSyntax,\n} from '../Syntax/Projections';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { pattern } from '../Text/patterns';\nimport { parseProjectionExpression } from './ProjectionExpressionParser';\nimport { isFileDirective } from './FileReferences';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord, splitTopLevel, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^projection\\\\s+(@?[\\\\w.]+)\\\\s*(?:=>\\\\s*([\\\\w.]+))?$');\nconst eventSpecPattern = pattern('^(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst joinPattern = pattern('^join\\\\s+(@?[\\\\w.]+)\\\\s+on\\\\s+(@?[\\\\w.]+)$');\nconst withPattern = pattern('^with\\\\s+(@?[\\\\w.]+)$');\nconst childrenPattern = pattern('^children\\\\s+(@?[\\\\w.]+)\\\\s+identified\\\\s+by\\\\s+(.+)$');\nconst nestedPattern = pattern('^nested\\\\s+(@?[\\\\w.]+)$');\nconst removeWithPattern = pattern('^remove\\\\s+with\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst removeViaJoinPattern = pattern('^remove\\\\s+via\\\\s+join\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst clearWithPattern = pattern('^clear\\\\s+with\\\\s+(@?[\\\\w.]+)$');\nconst variantPattern = pattern('^variant\\\\s+(@?[\\\\w.]+)\\\\s*$');\nconst entersOnPattern = pattern('^enters\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst keywordMappingPattern = pattern('^(increment|decrement|count|clear)\\\\s+(@?[$\\\\w.]+)$');\nconst arithmeticPattern = pattern('^(add|subtract)\\\\s+(@?[$\\\\w.]+)\\\\s+by\\\\s+(.+)$');\nconst setPattern = pattern('^set\\\\s+(@?[$\\\\w.]+)\\\\s+(?:=|to)\\\\s+(.+)$');\nconst assignmentPattern = pattern('^(@?[$\\\\w.@]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst keywordMappings: Record<string, MappingKind> = {\n increment: 'IncrementMappingSyntax',\n decrement: 'DecrementMappingSyntax',\n clear: 'ClearMappingSyntax',\n count: 'CountMappingSyntax',\n};\n\n// Reads a projection's structure: its name, the read model it builds, the events each block consumes, the\n// properties each mapping sets and where automap is turned on or off. Keys, and where a mapping takes its\n// value from, are recognized and skipped.\nexport function parseProjection(context: ParserContext, line: SourceLine): ProjectionSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionDeclaration, `Invalid projection declaration '${line.content}' - expected 'projection <Name> [=> <ReadModel>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name: firstWord(line.content), readModel: null, sequence: null, autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const name = match[1];\n let sequence: string | null = null;\n let description: string | null = null;\n let autoMap: AutoMapMode = 'Inherit';\n let key: KeySyntax | null = null;\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isFileDirective(child)) {\n continue;\n }\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Projection '${name}'`);\n } else if (keyword === 'sequence') {\n sequence = child.content.substring('sequence'.length).trim();\n } else if (keyword === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (keyword === 'key') {\n key = parseKey(context, child);\n } else if (keyword === 'variant') {\n blocks.push(parseVariant(context, child));\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n reportVariantConflicts(context, blocks, name);\n if (blocks.length === 0) {\n context.error(DiagnosticCodes.EmptyProjection, `Projection '${name}' must contain at least one directive`, locationOf(line));\n }\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name, readModel: match[2] ?? null, sequence, autoMap, key, blocks, description, location: locationOf(line) };\n}\n\nfunction reportVariantConflicts(context: ParserContext, blocks: readonly ProjectionBlockSyntax[], name: string): void {\n // Grouped by name in the order each name first appears, as the C# parser reports them.\n const variants = blocks.filter((block): block is ProjectionVariantSyntax => block.kind === 'ProjectionVariantSyntax');\n const byName = new Map<string, ProjectionVariantSyntax[]>();\n variants.forEach(variant => byName.set(variant.name, [...(byName.get(variant.name) ?? []), variant]));\n for (const duplicate of [...byName.values()].flatMap(group => group.slice(1))) {\n context.error(DiagnosticCodes.DuplicateProjectionVariant, `Duplicate variant '${duplicate.name}' - a variant name is declared once`, duplicate.location);\n }\n const entering = new Set<string>();\n for (const entry of blocks.flatMap(block => block.kind === 'ProjectionVariantSyntax' ? block.entersOn : [])) {\n if (entry.event.length > 0 && entering.has(entry.event)) {\n context.error(DiagnosticCodes.DuplicateVariantEnteringEvent, `Entering event '${entry.event}' is claimed more than once in projection '${name}'`, entry.location);\n }\n entering.add(entry.event);\n }\n}\n\nfunction parseBlock(context: ParserContext, line: SourceLine, nestedScope: boolean): ProjectionBlockSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'from':\n return parseFrom(context, line);\n case 'every': {\n let includeChildren = true;\n const { autoMap, mappings } = parseMappingBlock(context, line, child => {\n if (child.content !== 'exclude children') {\n return false;\n }\n includeChildren = false;\n return true;\n });\n return { kind: 'EverySyntax', includeChildren, autoMap, mappings, location };\n }\n case 'all': {\n const { autoMap, mappings } = parseMappingBlock(context, line);\n return { kind: 'AllSyntax', autoMap, mappings, location };\n }\n case 'join':\n return parseJoin(context, line);\n case 'children':\n return parseChildren(context, line);\n case 'nested':\n return parseNested(context, line);\n case 'remove':\n return parseRemove(context, line);\n case 'clear':\n if (!nestedScope) {\n context.error(DiagnosticCodes.ClearWithOutsideNestedBlock, '\\'clear with\\' is only valid inside a nested block', location);\n }\n return parseClearWith(context, line);\n default:\n context.error(DiagnosticCodes.UnknownProjectionDirective, `Unexpected '${firstWord(line.content)}' in projection body`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n}\n\nfunction parseFrom(context: ParserContext, line: SourceLine): FromSyntax {\n const events: EventSpecSyntax[] = [];\n for (const spec of splitTopLevel(line.content.substring('from'.length), ',')) {\n const text = spec.trim();\n if (text.length === 0) {\n context.error(DiagnosticCodes.FromWithoutEvent, 'Expected an event type after \\'from\\'', locationOf(line));\n continue;\n }\n const match = eventSpecPattern.exec(text);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventReference, `Invalid event reference '${text}'`, locationOf(line));\n continue;\n }\n events.push({ kind: 'EventSpecSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) });\n }\n const mappings: MappingSyntax[] = [];\n let key: KeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\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 === 'key') key = parseKey(context, child);\n else if (keyword === 'parent') parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n else pushMapping(context, child, mappings);\n }\n return { kind: 'FromSyntax', events, key, parentKey, mappings, location: locationOf(line) };\n}\n\nfunction parseJoin(context: ParserContext, line: SourceLine): JoinSyntax {\n const match = joinPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidJoinDeclaration, `Invalid join declaration '${line.content}' - expected 'join <property> on <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'JoinSyntax', property: '', on: '', events: [], location: locationOf(line) };\n }\n const events: JoinEventSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const withMatch = withPattern.exec(child.content);\n if (withMatch === null) {\n context.error(DiagnosticCodes.JoinWithoutEvent, `Expected 'with <EventType>' in join block, got '${child.content}'`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n const { autoMap, mappings } = parseMappingBlock(context, child);\n events.push({ kind: 'JoinEventSyntax', event: unescapeIdentifier(withMatch[1]), autoMap, mappings, location: locationOf(child) });\n }\n return { kind: 'JoinSyntax', property: unescapeIdentifier(match[1]), on: unescapeIdentifier(match[2]), events, location: locationOf(line) };\n}\n\nfunction parseChildren(context: ParserContext, line: SourceLine): ChildrenSyntax {\n const match = childrenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidChildrenDeclaration, `Invalid children declaration '${line.content}' - expected 'children <collection> identified by <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ChildrenSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const { autoMap, blocks } = parseChildBlocks(context, line);\n return { kind: 'ChildrenSyntax', property: unescapeIdentifier(match[1]), identifiedBy: parseProjectionExpression(match[2], locationOf(line), context), autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseNested(context: ParserContext, line: SourceLine): NestedSyntax {\n const match = nestedPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidNestedDeclaration, `Invalid nested declaration '${line.content}' - expected 'nested <property>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'NestedSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const property = unescapeIdentifier(match[1]);\n const { autoMap, blocks } = parseChildBlocks(context, line);\n if (!blocks.some(block => block.kind === 'FromSyntax')) {\n context.error(DiagnosticCodes.NestedBlockWithoutFrom, `Nested block '${property}' must contain at least one 'from' directive`, locationOf(line));\n }\n return { kind: 'NestedSyntax', property, autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseChildBlocks(context: ParserContext, line: SourceLine): { autoMap: AutoMapMode; blocks: ProjectionBlockSyntax[] } {\n const blocks: ProjectionBlockSyntax[] = [];\n let autoMap: AutoMapMode = 'Inherit';\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n continue;\n }\n if (child.content === 'no automap') {\n autoMap = 'Disabled';\n continue;\n }\n const block = parseBlock(context, child, true);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n return { autoMap, blocks };\n}\n\nfunction parseRemove(context: ParserContext, line: SourceLine): ProjectionBlockSyntax | undefined {\n const viaJoin = removeViaJoinPattern.exec(line.content);\n if (viaJoin !== null) {\n return { kind: 'RemoveViaJoinSyntax', event: unescapeIdentifier(viaJoin[1]), key: viaJoin[2] === undefined ? null : parseProjectionExpression(viaJoin[2], locationOf(line), context), location: locationOf(line) };\n }\n const match = removeWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidRemoveDeclaration, `Invalid remove declaration '${line.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'parent') {\n parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n } else {\n context.error(DiagnosticCodes.UnknownRemoveDirective, `Unexpected '${child.content}' in remove block - only 'parent' is allowed`, locationOf(child));\n }\n }\n return { kind: 'RemoveWithSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), parentKey, location: locationOf(line) };\n}\n\nfunction parseClearWith(context: ParserContext, line: SourceLine): ClearWithSyntax {\n const match = clearWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidClearDeclaration, `Invalid clear declaration '${line.content}' - expected 'clear with <EventType>'`, locationOf(line));\n return { kind: 'ClearWithSyntax', event: '', location: locationOf(line) };\n }\n return { kind: 'ClearWithSyntax', event: unescapeIdentifier(match[1]), location: locationOf(line) };\n}\n\nfunction parseVariant(context: ParserContext, line: SourceLine): ProjectionVariantSyntax {\n const match = variantPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionVariantDeclaration, `Invalid variant declaration '${line.content}' - expected 'variant <Name>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionVariantSyntax', name: firstWord(line.content), entersOn: [], blocks: [], location: locationOf(line) };\n }\n const name = unescapeIdentifier(match[1]);\n const entersOn: ProjectionEntersOnSyntax[] = [];\n const blocks: ProjectionBlockSyntax[] = [];\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 === 'enters') {\n entersOn.push(parseEntersOn(context, child));\n } else if (keyword === 'variant') {\n context.error(DiagnosticCodes.NestedProjectionVariantNotAllowed, 'A variant cannot be declared inside another variant', locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n if (entersOn.length === 0) {\n context.error(DiagnosticCodes.VariantRequiresEnteringEvent, `Variant '${name}' must declare at least one 'enters on' event`, locationOf(line));\n }\n return { kind: 'ProjectionVariantSyntax', name, entersOn, blocks, location: locationOf(line) };\n}\n\nfunction parseEntersOn(context: ParserContext, line: SourceLine): ProjectionEntersOnSyntax {\n const match = entersOnPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEntersOnDeclaration, `Invalid 'enters on' declaration '${line.content}' - expected 'enters on <EventType> [key <expression>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionEntersOnSyntax', event: '', key: null, location: locationOf(line) };\n }\n return { kind: 'ProjectionEntersOnSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) };\n}\n\n// A key with a body is a composite key: its parts, then a closing '}' at the key's own indent.\nfunction parseKey(context: ParserContext, line: SourceLine): KeySyntax {\n const text = line.content.substring('key'.length).trim();\n if (context.peekChild(line.indent) === undefined) return { kind: 'ExpressionKeySyntax', expression: parseProjectionExpression(text, locationOf(line), context), location: locationOf(line) };\n const parts: KeyPartSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === '}') continue;\n const match = assignmentPattern.exec(child.content);\n if (match === null) {\n if (context.sourceOptions.numericMode === 'exact') context.error(DiagnosticCodes.InvalidCompositeKeyPart, `Invalid composite key part '${child.content}' - expected '<property> = <expression>'`, locationOf(child));\n continue;\n }\n const expression = parseProjectionExpression(match[2], locationOf(child), context);\n if (context.sourceOptions.numericMode === 'exact' && expression.kind === 'TemplateExpressionSyntax') context.error(DiagnosticCodes.TemplateInCompositeKey, 'Template expressions are not allowed in composite keys', locationOf(child));\n parts.push({ kind: 'KeyPartSyntax', property: unescapeIdentifier(match[1]), expression, location: locationOf(child) });\n }\n const closing = context.reader.peekSignificant();\n if (closing !== undefined && closing.indent === line.indent && closing.content === '}') context.reader.takeSignificant();\n if (context.sourceOptions.numericMode === 'exact' && parts.length === 0) context.error(DiagnosticCodes.EmptyCompositeKey, 'Composite keys must contain at least one part', locationOf(line));\n return { kind: 'CompositeKeySyntax', type: text.replace(/\\{$/, '').trim(), parts, location: locationOf(line) };\n}\n\n// Mapping lines carry no body, so a mapping block is its direct children. The last automap setting wins;\n// a line 'extra' claims is not a mapping.\nfunction parseMappingBlock(context: ParserContext, line: SourceLine, extra: (child: SourceLine) => boolean = () => false): { autoMap: AutoMapMode; mappings: MappingSyntax[] } {\n let autoMap: AutoMapMode = 'Inherit';\n const mappings: MappingSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (!extra(child)) {\n pushMapping(context, child, mappings);\n }\n }\n return { autoMap, mappings };\n}\n\n// The property one mapping line sets, and how - the port of the C# ParseMappingLine. Exact reports\n// malformed mappings; Legacy keeps the existing skip behavior.\nfunction pushMapping(context: ParserContext, line: SourceLine, mappings: MappingSyntax[]): void {\n const location = locationOf(line);\n const keyword = keywordMappingPattern.exec(line.content);\n if (keyword !== null) {\n if (keyword[1] !== 'clear' || keyword[2] !== 'with') {\n mappings.push({ kind: keywordMappings[keyword[1]], property: unescapeIdentifier(keyword[2]), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`, location);\n }\n return;\n }\n const arithmetic = arithmeticPattern.exec(line.content);\n if (arithmetic !== null) {\n mappings.push({ kind: arithmetic[1] === 'add' ? 'AddMappingSyntax' : 'SubtractMappingSyntax', property: unescapeIdentifier(arithmetic[2]), value: parseProjectionExpression(arithmetic[3], location, context), location });\n return;\n }\n const assigned = setPattern.exec(line.content) ?? assignmentPattern.exec(line.content);\n if (assigned !== null) {\n mappings.push({ kind: 'SetMappingSyntax', property: unescapeIdentifier(assigned[1]), source: parseProjectionExpression(assigned[2], location, context), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}'`, location);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectionParser.js","names":["header","pattern","eventSpecPattern","joinPattern","withPattern","childrenPattern","nestedPattern","removeWithPattern","removeViaJoinPattern","clearWithPattern","variantPattern","entersOnPattern","keywordMappingPattern","arithmeticPattern","setPattern","assignmentPattern","keywordMappings","match","line","context","DiagnosticCodes","locationOf","firstWord","name","sequence","description","autoMap","key","blocks","child","isFileDirective","keyword","parseDescription","block","variants","byName","variant","duplicate","group","entering","entry","location","includeChildren","nestedScope","events","spec","splitTopLevel","text","unescapeIdentifier","parseProjectionExpression","mappings","parentKey","withMatch","property","viaJoin","entersOn","parts","expression","closing","extra","diagnosticText","arithmetic","assigned"],"sources":["../../../../../../Compiler/Parsing/ProjectionParser.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 {\n AutoMapMode, ChildrenSyntax, ClearWithSyntax, EventSpecSyntax, FromSyntax, JoinEventSyntax, JoinSyntax, MappingKind, MappingSyntax, NestedSyntax,\n KeyPartSyntax, KeySyntax, ProjectionBlockSyntax, ProjectionEntersOnSyntax, ProjectionSyntax, ProjectionVariantSyntax,\n} from '../Syntax/Projections';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { pattern } from '../Text/patterns';\nimport { parseProjectionExpression } from './ProjectionExpressionParser';\nimport { isFileDirective } from './FileReferences';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord, splitTopLevel, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^projection\\\\s+(@?[\\\\w.]+)\\\\s*(?:=>\\\\s*([\\\\w.]+))?$');\nconst eventSpecPattern = pattern('^(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst joinPattern = pattern('^join\\\\s+(@?[\\\\w.]+)\\\\s+on\\\\s+(@?[\\\\w.]+)$');\nconst withPattern = pattern('^with\\\\s+(@?[\\\\w.]+)$');\nconst childrenPattern = pattern('^children\\\\s+(@?[\\\\w.]+)\\\\s+identified\\\\s+by\\\\s+(.+)$');\nconst nestedPattern = pattern('^nested\\\\s+(@?[\\\\w.]+)$');\nconst removeWithPattern = pattern('^remove\\\\s+with\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst removeViaJoinPattern = pattern('^remove\\\\s+via\\\\s+join\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst clearWithPattern = pattern('^clear\\\\s+with\\\\s+(@?[\\\\w.]+)$');\nconst variantPattern = pattern('^variant\\\\s+(@?[\\\\w.]+)\\\\s*$');\nconst entersOnPattern = pattern('^enters\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst keywordMappingPattern = pattern('^(increment|decrement|count|clear)\\\\s+(@?[$\\\\w.]+)$');\nconst arithmeticPattern = pattern('^(add|subtract)\\\\s+(@?[$\\\\w.]+)\\\\s+by\\\\s+(.+)$');\nconst setPattern = pattern('^set\\\\s+(@?[$\\\\w.]+)\\\\s+(?:=|to)\\\\s+(.+)$');\nconst assignmentPattern = pattern('^(@?[$\\\\w.@]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst keywordMappings: Record<string, MappingKind> = {\n increment: 'IncrementMappingSyntax',\n decrement: 'DecrementMappingSyntax',\n clear: 'ClearMappingSyntax',\n count: 'CountMappingSyntax',\n};\n\n// Reads a projection's structure: its name, the read model it builds, the events each block consumes, the\n// properties each mapping sets and where automap is turned on or off. Keys, and where a mapping takes its\n// value from, are recognized and skipped.\nexport function parseProjection(context: ParserContext, line: SourceLine): ProjectionSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionDeclaration, `Invalid projection declaration '${line.content}' - expected 'projection <Name> [=> <ReadModel>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name: firstWord(line.content), readModel: null, sequence: null, autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const name = match[1];\n let sequence: string | null = null;\n let description: string | null = null;\n let autoMap: AutoMapMode = 'Inherit';\n let key: KeySyntax | null = null;\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isFileDirective(child)) {\n continue;\n }\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Projection '${name}'`);\n } else if (keyword === 'sequence') {\n sequence = child.content.substring('sequence'.length).trim();\n } else if (keyword === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (keyword === 'key') {\n key = parseKey(context, child);\n } else if (keyword === 'variant') {\n blocks.push(parseVariant(context, child));\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n reportVariantConflicts(context, blocks, name);\n if (blocks.length === 0) {\n context.error(DiagnosticCodes.EmptyProjection, `Projection '${name}' must contain at least one directive`, locationOf(line));\n }\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name, readModel: match[2] ?? null, sequence, autoMap, key, blocks, description, location: locationOf(line) };\n}\n\nfunction reportVariantConflicts(context: ParserContext, blocks: readonly ProjectionBlockSyntax[], name: string): void {\n // Grouped by name in the order each name first appears, as the C# parser reports them.\n const variants = blocks.filter((block): block is ProjectionVariantSyntax => block.kind === 'ProjectionVariantSyntax');\n const byName = new Map<string, ProjectionVariantSyntax[]>();\n variants.forEach(variant => byName.set(variant.name, [...(byName.get(variant.name) ?? []), variant]));\n for (const duplicate of [...byName.values()].flatMap(group => group.slice(1))) {\n context.error(DiagnosticCodes.DuplicateProjectionVariant, `Duplicate variant '${duplicate.name}' - a variant name is declared once`, duplicate.location);\n }\n const entering = new Set<string>();\n for (const entry of blocks.flatMap(block => block.kind === 'ProjectionVariantSyntax' ? block.entersOn : [])) {\n if (entry.event.length > 0 && entering.has(entry.event)) {\n context.error(DiagnosticCodes.DuplicateVariantEnteringEvent, `Entering event '${entry.event}' is claimed more than once in projection '${name}'`, entry.location);\n }\n entering.add(entry.event);\n }\n}\n\nfunction parseBlock(context: ParserContext, line: SourceLine, nestedScope: boolean): ProjectionBlockSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'from':\n return parseFrom(context, line);\n case 'every': {\n let includeChildren = true;\n const { autoMap, mappings } = parseMappingBlock(context, line, child => {\n if (child.content !== 'exclude children') {\n return false;\n }\n includeChildren = false;\n return true;\n });\n return { kind: 'EverySyntax', includeChildren, autoMap, mappings, location };\n }\n case 'all': {\n const { autoMap, mappings } = parseMappingBlock(context, line);\n return { kind: 'AllSyntax', autoMap, mappings, location };\n }\n case 'join':\n return parseJoin(context, line);\n case 'children':\n return parseChildren(context, line);\n case 'nested':\n return parseNested(context, line);\n case 'remove':\n return parseRemove(context, line);\n case 'clear':\n if (!nestedScope) {\n context.error(DiagnosticCodes.ClearWithOutsideNestedBlock, '\\'clear with\\' is only valid inside a nested block', location);\n }\n return parseClearWith(context, line);\n default:\n context.error(DiagnosticCodes.UnknownProjectionDirective, `Unexpected '${firstWord(line.content)}' in projection body`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n}\n\nfunction parseFrom(context: ParserContext, line: SourceLine): FromSyntax {\n const events: EventSpecSyntax[] = [];\n for (const spec of splitTopLevel(line.content.substring('from'.length), ',')) {\n const text = spec.trim();\n if (text.length === 0) {\n context.error(DiagnosticCodes.FromWithoutEvent, 'Expected an event type after \\'from\\'', locationOf(line));\n continue;\n }\n const match = eventSpecPattern.exec(text);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventReference, `Invalid event reference '${text}'`, locationOf(line));\n continue;\n }\n events.push({ kind: 'EventSpecSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) });\n }\n const mappings: MappingSyntax[] = [];\n let key: KeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\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 === 'key') key = parseKey(context, child);\n else if (keyword === 'parent') parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n else pushMapping(context, child, mappings);\n }\n return { kind: 'FromSyntax', events, key, parentKey, mappings, location: locationOf(line) };\n}\n\nfunction parseJoin(context: ParserContext, line: SourceLine): JoinSyntax {\n const match = joinPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidJoinDeclaration, `Invalid join declaration '${line.content}' - expected 'join <property> on <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'JoinSyntax', property: '', on: '', events: [], location: locationOf(line) };\n }\n const events: JoinEventSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const withMatch = withPattern.exec(child.content);\n if (withMatch === null) {\n context.error(DiagnosticCodes.JoinWithoutEvent, `Expected 'with <EventType>' in join block, got '${child.content}'`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n const { autoMap, mappings } = parseMappingBlock(context, child);\n events.push({ kind: 'JoinEventSyntax', event: unescapeIdentifier(withMatch[1]), autoMap, mappings, location: locationOf(child) });\n }\n return { kind: 'JoinSyntax', property: unescapeIdentifier(match[1]), on: unescapeIdentifier(match[2]), events, location: locationOf(line) };\n}\n\nfunction parseChildren(context: ParserContext, line: SourceLine): ChildrenSyntax {\n const match = childrenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidChildrenDeclaration, `Invalid children declaration '${line.content}' - expected 'children <collection> identified by <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ChildrenSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const { autoMap, blocks } = parseChildBlocks(context, line);\n return { kind: 'ChildrenSyntax', property: unescapeIdentifier(match[1]), identifiedBy: parseProjectionExpression(match[2], locationOf(line), context), autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseNested(context: ParserContext, line: SourceLine): NestedSyntax {\n const match = nestedPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidNestedDeclaration, `Invalid nested declaration '${line.content}' - expected 'nested <property>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'NestedSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const property = unescapeIdentifier(match[1]);\n const { autoMap, blocks } = parseChildBlocks(context, line);\n if (!blocks.some(block => block.kind === 'FromSyntax')) {\n context.error(DiagnosticCodes.NestedBlockWithoutFrom, `Nested block '${property}' must contain at least one 'from' directive`, locationOf(line));\n }\n return { kind: 'NestedSyntax', property, autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseChildBlocks(context: ParserContext, line: SourceLine): { autoMap: AutoMapMode; blocks: ProjectionBlockSyntax[] } {\n const blocks: ProjectionBlockSyntax[] = [];\n let autoMap: AutoMapMode = 'Inherit';\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n continue;\n }\n if (child.content === 'no automap') {\n autoMap = 'Disabled';\n continue;\n }\n const block = parseBlock(context, child, true);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n return { autoMap, blocks };\n}\n\nfunction parseRemove(context: ParserContext, line: SourceLine): ProjectionBlockSyntax | undefined {\n const viaJoin = removeViaJoinPattern.exec(line.content);\n if (viaJoin !== null) {\n return { kind: 'RemoveViaJoinSyntax', event: unescapeIdentifier(viaJoin[1]), key: viaJoin[2] === undefined ? null : parseProjectionExpression(viaJoin[2], locationOf(line), context), location: locationOf(line) };\n }\n const match = removeWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidRemoveDeclaration, `Invalid remove declaration '${line.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'parent') {\n parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n } else {\n context.error(DiagnosticCodes.UnknownRemoveDirective, `Unexpected '${child.content}' in remove block - only 'parent' is allowed`, locationOf(child));\n }\n }\n return { kind: 'RemoveWithSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), parentKey, location: locationOf(line) };\n}\n\nfunction parseClearWith(context: ParserContext, line: SourceLine): ClearWithSyntax {\n const match = clearWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidClearDeclaration, `Invalid clear declaration '${line.content}' - expected 'clear with <EventType>'`, locationOf(line));\n return { kind: 'ClearWithSyntax', event: '', location: locationOf(line) };\n }\n return { kind: 'ClearWithSyntax', event: unescapeIdentifier(match[1]), location: locationOf(line) };\n}\n\nfunction parseVariant(context: ParserContext, line: SourceLine): ProjectionVariantSyntax {\n const match = variantPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionVariantDeclaration, `Invalid variant declaration '${line.content}' - expected 'variant <Name>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionVariantSyntax', name: firstWord(line.content), entersOn: [], blocks: [], location: locationOf(line) };\n }\n const name = unescapeIdentifier(match[1]);\n const entersOn: ProjectionEntersOnSyntax[] = [];\n const blocks: ProjectionBlockSyntax[] = [];\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 === 'enters') {\n entersOn.push(parseEntersOn(context, child));\n } else if (keyword === 'variant') {\n context.error(DiagnosticCodes.NestedProjectionVariantNotAllowed, 'A variant cannot be declared inside another variant', locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n if (entersOn.length === 0) {\n context.error(DiagnosticCodes.VariantRequiresEnteringEvent, `Variant '${name}' must declare at least one 'enters on' event`, locationOf(line));\n }\n return { kind: 'ProjectionVariantSyntax', name, entersOn, blocks, location: locationOf(line) };\n}\n\nfunction parseEntersOn(context: ParserContext, line: SourceLine): ProjectionEntersOnSyntax {\n const match = entersOnPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEntersOnDeclaration, `Invalid 'enters on' declaration '${line.content}' - expected 'enters on <EventType> [key <expression>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionEntersOnSyntax', event: '', key: null, location: locationOf(line) };\n }\n return { kind: 'ProjectionEntersOnSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) };\n}\n\n// A key with a body is a composite key: its parts, then a closing '}' at the key's own indent.\nfunction parseKey(context: ParserContext, line: SourceLine): KeySyntax {\n const text = line.content.substring('key'.length).trim();\n if (context.peekChild(line.indent) === undefined) return { kind: 'ExpressionKeySyntax', expression: parseProjectionExpression(text, locationOf(line), context), location: locationOf(line) };\n const parts: KeyPartSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === '}') continue;\n const match = assignmentPattern.exec(child.content);\n if (match === null) {\n if (context.sourceOptions.numericMode === 'exact') context.error(DiagnosticCodes.InvalidCompositeKeyPart, `Invalid composite key part '${child.content}' - expected '<property> = <expression>'`, locationOf(child));\n continue;\n }\n const expression = parseProjectionExpression(match[2], locationOf(child), context);\n if (context.sourceOptions.numericMode === 'exact' && expression.kind === 'TemplateExpressionSyntax') context.error(DiagnosticCodes.TemplateInCompositeKey, 'Template expressions are not allowed in composite keys', locationOf(child));\n parts.push({ kind: 'KeyPartSyntax', property: unescapeIdentifier(match[1]), expression, location: locationOf(child) });\n }\n const closing = context.reader.peekSignificant();\n if (closing !== undefined && closing.indent === line.indent && closing.content === '}') context.reader.takeSignificant();\n if (context.sourceOptions.numericMode === 'exact' && parts.length === 0) context.error(DiagnosticCodes.EmptyCompositeKey, 'Composite keys must contain at least one part', locationOf(line));\n return { kind: 'CompositeKeySyntax', type: text.replace(/\\{$/, '').trim(), parts, location: locationOf(line) };\n}\n\n// Mapping lines carry no body, so a mapping block is its direct children. The last automap setting wins;\n// a line 'extra' claims is not a mapping.\nfunction parseMappingBlock(context: ParserContext, line: SourceLine, extra: (child: SourceLine) => boolean = () => false): { autoMap: AutoMapMode; mappings: MappingSyntax[] } {\n let autoMap: AutoMapMode = 'Inherit';\n const mappings: MappingSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (!extra(child)) {\n pushMapping(context, child, mappings);\n }\n }\n return { autoMap, mappings };\n}\n\n// The property one mapping line sets, and how - the port of the C# ParseMappingLine. Exact reports\n// malformed mappings; Legacy keeps the existing skip behavior.\nfunction pushMapping(context: ParserContext, line: SourceLine, mappings: MappingSyntax[]): void {\n const location = locationOf(line);\n const keyword = keywordMappingPattern.exec(line.content);\n if (keyword !== null) {\n if (keyword[1] !== 'clear' || keyword[2] !== 'with') {\n mappings.push({ kind: keywordMappings[keyword[1]], property: unescapeIdentifier(keyword[2]), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`, location, diagnosticText('text', line.content));\n }\n return;\n }\n const arithmetic = arithmeticPattern.exec(line.content);\n if (arithmetic !== null) {\n mappings.push({ kind: arithmetic[1] === 'add' ? 'AddMappingSyntax' : 'SubtractMappingSyntax', property: unescapeIdentifier(arithmetic[2]), value: parseProjectionExpression(arithmetic[3], location, context), location });\n return;\n }\n const assigned = setPattern.exec(line.content) ?? assignmentPattern.exec(line.content);\n if (assigned !== null) {\n mappings.push({ kind: 'SetMappingSyntax', property: unescapeIdentifier(assigned[1]), source: parseProjectionExpression(assigned[2], location, context), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}'`, location, diagnosticText('text', line.content));\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{eventDeclarations as t}from"../Syntax/EventDeclarations.js";import{AuthoringProductionResolver as n}from"../Syntax/AuthoringProductionResolver.js";import{uniqueByName as r}from"./ResponseValidator.js";function validateProjectionTargets(i,a){let o=new n(i),s=o.slices,c=new Set(i.imports.map(e=>e.qualifiedName)),l=/* @__PURE__ */ new Set([...s.flatMap(({slice:e})=>t(e).map(e=>e.name)),...i.imports.map(e=>e.qualifiedName.split(`.`).at(-1))]),u=r(i.types),d=new Set([`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`,...i.concepts.map(e=>e.name)].filter(e=>!u.has(e))),property=(e,t)=>{let[n,...r]=t.split(`.`);if(e===null)return{value:null,missing:!1};let i=e.filter(e=>e.name===n);if(i.length!==1)return{value:null,missing:i.length===0};let a=i[0];return r.length===0?{value:a,missing:!1}:d.has(a.type.name)?{value:null,missing:!0}:property(u.get(a.type.name)?.properties??null,r.join(`.`))},f=s.flatMap(({slice:e,scope:t})=>e.readModels.map(e=>({node:e,scope:t}))),viewProperties=(e,t)=>{let candidates=e=>{let n=e.split(`.`),r=f.filter(e=>e.node.name===n.at(-1)),i=n.slice(0,-1);if(i.length>0)return r.filter(e=>i.length<=e.scope.length&&i.every((t,n)=>e.scope[e.scope.length-i.length+n]===t));for(let e=t.length;e>=0;e--){let n=r.filter(n=>e<=n.scope.length&&t.slice(0,e).every((e,t)=>n.scope[t]===e));if(n.length>0)return n}return[]},n=candidates(e),r=i.imports.filter(t=>t.qualifiedName.split(`.`).at(-1)===e);return n.length===0&&r.length===1&&(n=candidates(r[0].qualifiedName)),n.length===1?n[0].node.properties:null},unknownEvent=(t,n,r)=>{let i=o.resolve(t,r);l.has(t)||c.has(t)||i.declaration?.kind===`event`||i.candidates.some(e=>e.kind===`event`)||a.warning(e.UnknownEvent,`Unknown event '${t}' - declare it with 'event ${t}'`,n)},removals=(e,t)=>{for(let n of e)(n.kind===`RemoveWithSyntax`||n.kind===`RemoveViaJoinSyntax`)&&unknownEvent(n.event,n.location,t),`blocks`in n&&removals(n.blocks,t)},p=/* @__PURE__ */ new Set,walk=(t,n,r=!1,i=!1)=>{let validate=(t,i)=>{let o=property(n,t),s=JSON.stringify([i.path,i.line,i.column]);return o.missing&&!p.has(s)&&(p.add(s),a.warning(e.UnknownReadModelProperty,`Projection target '${t}' is not a declared ${r?`element`:`read-model`} property`,i)),o.value},o=i||t.some(e=>e.kind===`FromSyntax`||e.kind===`JoinSyntax`||e.kind===`AllSyntax`);for(let e of t){let t=e.kind===`EverySyntax`&&!o?[]:`mappings`in e?e.mappings:e.kind===`JoinSyntax`?e.events.flatMap(e=>e.mappings):[];for(let e of t)validate(e.property,e.location);if(e.kind===`ChildrenSyntax`||e.kind===`NestedSyntax`){let t=validate(e.property,e.location);walk(e.blocks,t===null?null:u.get(t.type.name)?.properties??null,!0)}}};for(let{slice:e}of s){for(let t of e.projections)removals(t.blocks,e);for(let t of e.captures)for(let n of[...t.appends,...t.children.flatMap(e=>e.appends),...t.nested.flatMap(e=>e.appends)])unknownEvent(n.event,n.location,e)}for(let{slice:e,scope:t}of s)for(let n of e.projections){let e=n.blocks.filter(e=>e.kind===`ProjectionVariantSyntax`);e.length===0&&walk(n.blocks,viewProperties(n.readModel??n.name,t));for(let r of e){let e=viewProperties(r.name,t);walk(n.blocks.filter(e=>e.kind===`ChildrenSyntax`||e.kind===`NestedSyntax`),e);let i=r.entersOn.length>0||n.blocks.some(e=>e.kind===`FromSyntax`||e.kind===`JoinSyntax`||e.kind===`AllSyntax`);walk(r.blocks,e,!1,i)}}}export{validateProjectionTargets};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{eventDeclarations as t}from"../Syntax/EventDeclarations.js";import{AuthoringProductionResolver as n}from"../Syntax/AuthoringProductionResolver.js";import{diagnosticText as r}from"../Diagnostics/DiagnosticArgument.js";import{uniqueByName as i}from"./ResponseValidator.js";function validateProjectionTargets(a,o){let s=new n(a),c=s.slices,l=new Set(a.imports.map(e=>e.qualifiedName)),u=/* @__PURE__ */ new Set([...c.flatMap(({slice:e})=>t(e).map(e=>e.name)),...a.imports.map(e=>e.qualifiedName.split(`.`).at(-1))]),d=i(a.types),f=new Set([`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`,...a.concepts.map(e=>e.name)].filter(e=>!d.has(e))),property=(e,t)=>{let[n,...r]=t.split(`.`);if(e===null)return{value:null,missing:!1};let i=e.filter(e=>e.name===n);if(i.length!==1)return{value:null,missing:i.length===0};let a=i[0];return r.length===0?{value:a,missing:!1}:f.has(a.type.name)?{value:null,missing:!0}:property(d.get(a.type.name)?.properties??null,r.join(`.`))},p=c.flatMap(({slice:e,scope:t})=>e.readModels.map(e=>({node:e,scope:t}))),viewProperties=(e,t)=>{let candidates=e=>{let n=e.split(`.`),r=p.filter(e=>e.node.name===n.at(-1)),i=n.slice(0,-1);if(i.length>0)return r.filter(e=>i.length<=e.scope.length&&i.every((t,n)=>e.scope[e.scope.length-i.length+n]===t));for(let e=t.length;e>=0;e--){let n=r.filter(n=>e<=n.scope.length&&t.slice(0,e).every((e,t)=>n.scope[t]===e));if(n.length>0)return n}return[]},n=candidates(e),r=a.imports.filter(t=>t.qualifiedName.split(`.`).at(-1)===e);return n.length===0&&r.length===1&&(n=candidates(r[0].qualifiedName)),n.length===1?n[0].node.properties:null},unknownEvent=(t,n,r)=>{let i=s.resolve(t,r);u.has(t)||l.has(t)||i.declaration?.kind===`event`||i.candidates.some(e=>e.kind===`event`)||o.warning(e.UnknownEvent,`Unknown event '${t}' - declare it with 'event ${t}'`,n)},removals=(e,t)=>{for(let n of e)(n.kind===`RemoveWithSyntax`||n.kind===`RemoveViaJoinSyntax`)&&unknownEvent(n.event,n.location,t),`blocks`in n&&removals(n.blocks,t)},m=/* @__PURE__ */ new Set,walk=(t,n,i=!1,a=!1)=>{let validate=(t,a)=>{let s=property(n,t),c=JSON.stringify([a.path,a.line,a.column]);return s.missing&&!m.has(c)&&(m.add(c),o.warning(e.UnknownReadModelProperty,`Projection target '${t}' is not a declared ${i?`element`:`read-model`} property`,a,r(`property`,t))),s.value},s=a||t.some(e=>e.kind===`FromSyntax`||e.kind===`JoinSyntax`||e.kind===`AllSyntax`);for(let e of t){let t=e.kind===`EverySyntax`&&!s?[]:`mappings`in e?e.mappings:e.kind===`JoinSyntax`?e.events.flatMap(e=>e.mappings):[];for(let e of t)validate(e.property,e.location);if(e.kind===`ChildrenSyntax`||e.kind===`NestedSyntax`){let t=validate(e.property,e.location);walk(e.blocks,t===null?null:d.get(t.type.name)?.properties??null,!0)}}};for(let{slice:e}of c){for(let t of e.projections)removals(t.blocks,e);for(let t of e.captures)for(let n of[...t.appends,...t.children.flatMap(e=>e.appends),...t.nested.flatMap(e=>e.appends)])unknownEvent(n.event,n.location,e)}for(let{slice:e,scope:t}of c)for(let n of e.projections){let e=n.blocks.filter(e=>e.kind===`ProjectionVariantSyntax`);e.length===0&&walk(n.blocks,viewProperties(n.readModel??n.name,t));for(let r of e){let e=viewProperties(r.name,t);walk(n.blocks.filter(e=>e.kind===`ChildrenSyntax`||e.kind===`NestedSyntax`),e);let i=r.entersOn.length>0||n.blocks.some(e=>e.kind===`FromSyntax`||e.kind===`JoinSyntax`||e.kind===`AllSyntax`);walk(r.blocks,e,!1,i)}}}export{validateProjectionTargets};
2
2
  //# sourceMappingURL=ProjectionTargetValidator.js.map
@@ -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{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
@@ -1 +1 @@
1
- {"version":3,"file":"SpecificationCaseParser.js","names":["caseHeader","pattern","assignment","reference","text","context","DiagnosticCodes","location","parseMappingSource","nativeIdentifiers","match","offset","line","property","parseProperty","locationOf","child","values","owner","valueLocation","source","parseConcrete","value","nested","parameters","specification","cases","index","prior","parameter","row","references","copies","result","item","key"],"sources":["../../../../../../Compiler/Parsing/SpecificationCaseParser.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 { CaseValueExpressionSyntax, ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationCaseSyntax, SpecificationParameterSyntax, SpecificationSyntax } from '../Syntax/Specifications';\nimport { pattern } from '../Text/patterns';\nimport { parseMappingSource } from './ExpressionParser';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { parseConcrete } from './SpecificationResponseParser';\n\nconst caseHeader = new RegExp(pattern('^case\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(?<property>[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(?<value>.+))?$').source, 'du');\nconst assignment = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reference = pattern('^case\\\\.([a-z_]\\\\w*)$');\n\nexport function containsCaseReference(text: string): boolean {\n return /\\bcase\\.[a-z_]\\w*/.test(text.replace(/\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/g, ''));\n}\n\nexport function parseSpecificationValue(text: string, location: SourceLocation, context: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n if (!text.startsWith('case.')) {\n if (containsCaseReference(text)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'A case reference fills a whole value position; it cannot occur inside a structured value or expression.', location);\n return parseMappingSource(text, location, context, nativeIdentifiers);\n }\n const match = reference.exec(text);\n if (match === null) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, \"A case reference fills a whole value position: 'case.<parameter>'.\", location);\n return { kind: 'CaseValueExpressionSyntax', parameter: match?.[1] ?? text.substring(5), location };\n}\n\nexport function parseParameter(context: ParserContext, line: SourceLine): SpecificationParameterSyntax | null {\n const offset = line.content.indexOf(' ') + 1;\n const property = offset > 0 ? parseProperty(context, { ...line, content: line.content.substring(offset), indent: line.indent + offset }) : undefined;\n if (property === undefined || property.isGenerated || property.isIdentifier) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, \"Expected 'parameter <name> <Type>', with optional collection and optional modifiers.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const child = context.peekChild(line.indent);\n if (child !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, 'A parameter has no body or default.', locationOf(child));\n context.skipOpaqueBlock(line.indent);\n }\n return { kind: 'SpecificationParameterSyntax', name: property.name, type: property.type, location: locationOf(line) };\n}\n\nexport function parseCase(context: ParserContext, line: SourceLine): SpecificationCaseSyntax | null {\n const match = caseHeader.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCase, \"Expected 'case <Name>' with at most one inline parameter assignment.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const values: PropertyMappingSyntax[] = [];\n const add = (property: string, text: string, owner: SourceLine) => {\n const location = locationOf(owner);\n const valueLocation = { ...location, column: location.column + owner.content.indexOf(text, owner.content.indexOf('=') + 1) };\n if (text.startsWith('case.')) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case assigns concrete values, not case references.', valueLocation);\n return;\n }\n const source = parseConcrete(context, text, valueLocation, DiagnosticCodes.InvalidSpecificationCaseValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: owner === line ? { ...location, column: location.column + match.indices!.groups!.property[0] } : location });\n };\n if (match.groups?.property !== undefined) add(match.groups.property, match.groups.value, line);\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const value = assignment.exec(child.content);\n if (value === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, \"Expected '<parameter> = <concrete value>' in a case.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n continue;\n }\n add(value[1], value[2], child);\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case value must fit on one line.', locationOf(nested));\n context.skipOpaqueBlock(child.indent);\n }\n }\n return { kind: 'SpecificationCaseSyntax', name: match[1], values, location: locationOf(line) };\n}\n\nexport function caseReferences(value: unknown): CaseValueExpressionSyntax[] {\n if (Array.isArray(value)) return value.flatMap(caseReferences);\n if (value === null || typeof value !== 'object') return [];\n if ('kind' in value && value.kind === 'CaseValueExpressionSyntax') return [value as CaseValueExpressionSyntax];\n return Object.values(value).flatMap(caseReferences);\n}\n\nexport function validateTable(specification: SpecificationSyntax, context: ParserContext): void {\n const parameters = specification.parameters ?? [];\n const cases = specification.cases ?? [];\n if ((parameters.length === 0) !== (cases.length === 0)) context.error(DiagnosticCodes.IncompleteSpecificationTable, 'A specification table requires parameters and at least one case.', specification.location);\n parameters.forEach((parameter, index) => {\n if (parameters.slice(0, index).some(prior => prior.name === parameter.name)) context.error(DiagnosticCodes.DuplicateSpecificationParameter, `Parameter '${parameter.name}' is declared more than once.`, parameter.location);\n });\n cases.forEach((row, index) => {\n if (cases.slice(0, index).some(prior => prior.name === row.name)) context.error(DiagnosticCodes.DuplicateSpecificationCase, `Case '${row.name}' is declared more than once.`, row.location);\n for (const value of row.values.filter(value => !parameters.some(parameter => parameter.name === value.property))) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' assigns undeclared parameter '${value.property}'.`, value.location);\n for (const parameter of parameters.filter(parameter => row.values.filter(value => value.property === parameter.name).length !== 1)) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' must assign parameter '${parameter.name}' exactly once.`, row.location);\n });\n const references = caseReferences(specification);\n for (const value of references) {\n if (cases.length === 0 || !parameters.some(parameter => parameter.name === value.parameter)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, `Case reference '${value.parameter}' requires a declared parameter in a specification table.`, value.location);\n }\n for (const parameter of parameters.filter(parameter => !references.some(value => value.parameter === parameter.name))) context.warning(DiagnosticCodes.UnusedSpecificationParameter, `Parameter '${parameter.name}' is never referenced.`, parameter.location);\n for (const value of caseReferences(specification.whenRedelivered)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in redelivery locators.', value.location);\n}\n\nexport function substituteCase<T>(value: T, row: SpecificationCaseSyntax, copies = new WeakMap<object, unknown>()): T {\n if (value !== null && typeof value === 'object' && copies.has(value)) return copies.get(value) as T;\n if (Array.isArray(value)) {\n const result = value.map(item => substituteCase(item, row, copies));\n copies.set(value, result);\n return result as T;\n }\n if (value === null || typeof value !== 'object' || !('kind' in value)) return value;\n if (value.kind === 'CaseValueExpressionSyntax') {\n const parameter = (value as unknown as CaseValueExpressionSyntax).parameter;\n return (row.values.find(value => value.property === parameter)?.source ?? value) as T;\n }\n const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, substituteCase(item, row, copies)]));\n if (value.kind === 'SpecificationErrorSyntax' && 'caseValue' in value && value.caseValue !== undefined) {\n const source = result.caseValue as ExpressionSyntax;\n result.name = source.kind === 'LiteralExpressionSyntax' ? source.value : null;\n delete result.caseValue;\n }\n copies.set(value, result);\n return result as T;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SpecificationCaseParser.js","names":["caseHeader","pattern","assignment","reference","text","context","DiagnosticCodes","location","parseMappingSource","nativeIdentifiers","match","offset","line","property","parseProperty","locationOf","child","values","owner","valueLocation","diagnosticText","source","parseConcrete","value","nested","parameters","specification","cases","index","prior","parameter","row","references","copies","result","item","key"],"sources":["../../../../../../Compiler/Parsing/SpecificationCaseParser.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 { CaseValueExpressionSyntax, ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationCaseSyntax, SpecificationParameterSyntax, SpecificationSyntax } from '../Syntax/Specifications';\nimport { pattern } from '../Text/patterns';\nimport { parseMappingSource } from './ExpressionParser';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { parseConcrete } from './SpecificationResponseParser';\n\nconst caseHeader = new RegExp(pattern('^case\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(?<property>[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(?<value>.+))?$').source, 'du');\nconst assignment = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reference = pattern('^case\\\\.([a-z_]\\\\w*)$');\n\nexport function containsCaseReference(text: string): boolean {\n return /\\bcase\\.[a-z_]\\w*/.test(text.replace(/\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/g, ''));\n}\n\nexport function parseSpecificationValue(text: string, location: SourceLocation, context: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n if (!text.startsWith('case.')) {\n if (containsCaseReference(text)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'A case reference fills a whole value position; it cannot occur inside a structured value or expression.', location);\n return parseMappingSource(text, location, context, nativeIdentifiers);\n }\n const match = reference.exec(text);\n if (match === null) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, \"A case reference fills a whole value position: 'case.<parameter>'.\", location);\n return { kind: 'CaseValueExpressionSyntax', parameter: match?.[1] ?? text.substring(5), location };\n}\n\nexport function parseParameter(context: ParserContext, line: SourceLine): SpecificationParameterSyntax | null {\n const offset = line.content.indexOf(' ') + 1;\n const property = offset > 0 ? parseProperty(context, { ...line, content: line.content.substring(offset), indent: line.indent + offset }) : undefined;\n if (property === undefined || property.isGenerated || property.isIdentifier) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, \"Expected 'parameter <name> <Type>', with optional collection and optional modifiers.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const child = context.peekChild(line.indent);\n if (child !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, 'A parameter has no body or default.', locationOf(child));\n context.skipOpaqueBlock(line.indent);\n }\n return { kind: 'SpecificationParameterSyntax', name: property.name, type: property.type, location: locationOf(line) };\n}\n\nexport function parseCase(context: ParserContext, line: SourceLine): SpecificationCaseSyntax | null {\n const match = caseHeader.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCase, \"Expected 'case <Name>' with at most one inline parameter assignment.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const values: PropertyMappingSyntax[] = [];\n const add = (property: string, text: string, owner: SourceLine) => {\n const location = locationOf(owner);\n const valueLocation = { ...location, column: location.column + owner.content.indexOf(text, owner.content.indexOf('=') + 1) };\n if (text.startsWith('case.')) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case assigns concrete values, not case references.', valueLocation, diagnosticText('text', text));\n return;\n }\n const source = parseConcrete(context, text, valueLocation, DiagnosticCodes.InvalidSpecificationCaseValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: owner === line ? { ...location, column: location.column + match.indices!.groups!.property[0] } : location });\n };\n if (match.groups?.property !== undefined) add(match.groups.property, match.groups.value, line);\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const value = assignment.exec(child.content);\n if (value === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, \"Expected '<parameter> = <concrete value>' in a case.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n continue;\n }\n add(value[1], value[2], child);\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case value must fit on one line.', locationOf(nested), { ...diagnosticText('case', match[1]), ...diagnosticText('parameter', value[1]), ...diagnosticText('text', nested.content) });\n context.skipOpaqueBlock(child.indent);\n }\n }\n return { kind: 'SpecificationCaseSyntax', name: match[1], values, location: locationOf(line) };\n}\n\nexport function caseReferences(value: unknown): CaseValueExpressionSyntax[] {\n if (Array.isArray(value)) return value.flatMap(caseReferences);\n if (value === null || typeof value !== 'object') return [];\n if ('kind' in value && value.kind === 'CaseValueExpressionSyntax') return [value as CaseValueExpressionSyntax];\n return Object.values(value).flatMap(caseReferences);\n}\n\nexport function validateTable(specification: SpecificationSyntax, context: ParserContext): void {\n const parameters = specification.parameters ?? [];\n const cases = specification.cases ?? [];\n if ((parameters.length === 0) !== (cases.length === 0)) context.error(DiagnosticCodes.IncompleteSpecificationTable, 'A specification table requires parameters and at least one case.', specification.location);\n parameters.forEach((parameter, index) => {\n if (parameters.slice(0, index).some(prior => prior.name === parameter.name)) context.error(DiagnosticCodes.DuplicateSpecificationParameter, `Parameter '${parameter.name}' is declared more than once.`, parameter.location);\n });\n cases.forEach((row, index) => {\n if (cases.slice(0, index).some(prior => prior.name === row.name)) context.error(DiagnosticCodes.DuplicateSpecificationCase, `Case '${row.name}' is declared more than once.`, row.location);\n for (const value of row.values.filter(value => !parameters.some(parameter => parameter.name === value.property))) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' assigns undeclared parameter '${value.property}'.`, value.location);\n for (const parameter of parameters.filter(parameter => row.values.filter(value => value.property === parameter.name).length !== 1)) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' must assign parameter '${parameter.name}' exactly once.`, row.location);\n });\n const references = caseReferences(specification);\n for (const value of references) {\n if (cases.length === 0 || !parameters.some(parameter => parameter.name === value.parameter)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, `Case reference '${value.parameter}' requires a declared parameter in a specification table.`, value.location);\n }\n for (const parameter of parameters.filter(parameter => !references.some(value => value.parameter === parameter.name))) context.warning(DiagnosticCodes.UnusedSpecificationParameter, `Parameter '${parameter.name}' is never referenced.`, parameter.location);\n for (const value of caseReferences(specification.whenRedelivered)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in redelivery locators.', value.location);\n}\n\nexport function substituteCase<T>(value: T, row: SpecificationCaseSyntax, copies = new WeakMap<object, unknown>()): T {\n if (value !== null && typeof value === 'object' && copies.has(value)) return copies.get(value) as T;\n if (Array.isArray(value)) {\n const result = value.map(item => substituteCase(item, row, copies));\n copies.set(value, result);\n return result as T;\n }\n if (value === null || typeof value !== 'object' || !('kind' in value)) return value;\n if (value.kind === 'CaseValueExpressionSyntax') {\n const parameter = (value as unknown as CaseValueExpressionSyntax).parameter;\n return (row.values.find(value => value.property === parameter)?.source ?? value) as T;\n }\n const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, substituteCase(item, row, copies)]));\n if (value.kind === 'SpecificationErrorSyntax' && 'caseValue' in value && value.caseValue !== undefined) {\n const source = result.caseValue as ExpressionSyntax;\n result.name = source.kind === 'LiteralExpressionSyntax' ? source.value : null;\n delete result.caseValue;\n }\n copies.set(value, result);\n return result as T;\n}\n"],"mappings":"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"}