@cratis/screenplay-language 4.255.0 → 4.256.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.
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +1 -1
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -1
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js +1 -1
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js.map +1 -1
- package/dist/bundles/compiler/Parsing/CaptureParser.js +1 -1
- package/dist/bundles/compiler/Parsing/CommandHandlerValidator.js +1 -1
- package/dist/bundles/compiler/Parsing/CommandHandlerValidator.js.map +1 -1
- package/dist/bundles/compiler/Parsing/CommandParser.js +1 -1
- package/dist/bundles/compiler/Parsing/CommandParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ImplementationParser.js +2 -2
- package/dist/bundles/compiler/Parsing/ImplementationParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/PossibleEventsParser.js +2 -0
- package/dist/bundles/compiler/Parsing/PossibleEventsParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ProducesParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ReadModelMemberTypeValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/ReadModelMemberTypeValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SliceParser.js +1 -1
- package/dist/bundles/compiler/ScreenplayCompiler.js +1 -1
- package/dist/bundles/compiler/ScreenplayCompiler.js.map +1 -1
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js +1 -1
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js.map +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxJson.js +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxJson.js.map +1 -1
- package/dist/bundles/compiler/index.js +1 -1
- package/dist/bundles/diagnostic-codes.js +1 -1
- package/dist/bundles/diagnostic-codes.js.map +1 -1
- package/dist/bundles/keyword-docs.js +1 -1
- package/dist/bundles/keyword-docs.js.map +1 -1
- package/dist/bundles/validation.js +1 -1
- package/dist/bundles/validation.js.map +1 -1
- package/dist/diagnostic-codes.d.ts +1 -0
- package/dist/diagnostic-codes.d.ts.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","calendarPrefix","calendarPattern","stringBodyPattern","severityPattern","messagePattern","rulePattern","operandPattern","ruleNamePattern","optionalReads","operandKinds","severities","opaqueDirectives","propertyShapedDirectives","names","lookahead","ParserContext","context","line","name","DiagnosticCodes","locationOf","properties","responses","identifier","validations","produces","reads","referenceReads","concurrency","description","documentation","authorize","handler","handlers","stream","streamCandidates","calendar","child","keyword","firstWord","asProperty","tryParseProperty","match","unescapeString","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","combineAuthorize","parseAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerOccurrences","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","file","parseFile","body","rule","isFileDirectiveAmongProperties","next","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","ownerName","checksum","valueContext","withSeverity","validateMatchOperand","matchSubject","wrapped","commandOwner","parseImplementationWrapper","isFile","isCode","extra","content","text","algorithm","operand","operator","parseMappingSource"],"sources":["../../../../../../Compiler/Parsing/CommandParser.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 { validateHandlerOccurrences } from './CommandHandlerValidator';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { RequirementSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { CommandSyntax, ValidateSyntax, ValidationRuleKind, ValidationRuleSyntax, ValidationSeverity } from '../Syntax/Commands';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { CommandCalendarSyntax } from '../Syntax/Calendar';\nimport { CommandStreamSyntax } from '../Syntax/EventSources';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { CommandResponseSyntax } from '../Syntax/Responses';\nimport { pattern } from '../Text/patterns';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { combineAuthorize, parseAuthorize } from './AuthorizeParser';\nimport { parseCommandResponse, scalarResponsePattern } from './CommandResponseParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { isCode, isFile, parseCode, parseFile, parseHandler, parseImplementationWrapper } from './ImplementationParser';\nimport { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { matchSubject, validateMatchOperand } from './MatchOperandValidation';\nimport { isReactionIdentityLine, misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { commandReadSources } from './CommandReadSources';\nimport { dependencySources, ReadsSyntax, ConcurrencySyntax } from '../Syntax/DependencySources';\nimport { captureConcurrency } from './DependencySourceParser';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { reportInvalidModifierOrder, reportLegacyOptionalSuffix, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst calendarPrefix = pattern('^calendar\\\\s+(?:\"|from\\\\s+\\\\$context\\\\.)');\nconst calendarPattern = pattern(`^calendar\\\\s+(?:\"(${stringBodyPattern})\"|from\\\\s+\\\\$context\\\\.([A-Za-z_][A-Za-z0-9_]*(?:\\\\.[A-Za-z_][A-Za-z0-9_]*)*))$`);\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\\\s*)(.*)$');\nconst ruleNamePattern = sourceStreamPattern('^[A-Za-z_]\\\\w*$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\n// Every operand the pattern matches has a kind, so an operand never goes unrecognized here.\nconst operandKinds: Record<string, ValidationRuleKind> = {\n max: 'Max',\n min: 'Min',\n '>': 'GreaterThan',\n '>=': 'GreaterThanOrEqual',\n '<': 'LessThan',\n '<=': 'LessThanOrEqual',\n '==': 'Equal',\n '!=': 'NotEqual',\n 'length ==': 'Length',\n 'decimals <=': 'DecimalPlaces',\n matches: 'Matches',\n contains: 'Contains',\n 'not contains': 'NotContains',\n 'starts with': 'StartsWith',\n 'ends with': 'EndsWith',\n 'all >': 'AllGreaterThan',\n 'all >=': 'AllGreaterThanOrEqual',\n};\n\nconst severities: Record<string, ValidationSeverity> = { information: 'Information', warning: 'Warning', error: 'Error' };\n\n// Command directives this compiler does not model. They are skipped whole.\nconst opaqueDirectives = new Set(['reads', 'concurrency']);\n\n// The bare directives cannot take a type reference, so a line with property shape is a property whatever\n// keyword it starts with - 'description String' declares a property called description.\nconst propertyShapedDirectives = new Set(['description', 'documentation', 'handler', 'concurrency']);\n\nexport function parseCommand(context: ParserContext, line: SourceLine): CommandSyntax {\n // Properties are leaves, not indentation owners. Resolve ambiguous returns spelling\n // before the committed pass decides whether its deeper lines belong to a response.\n const names = new Set<string>();\n const lookahead = new ParserContext(context.reader.fork(), context.path, context.languages);\n lookahead.sourceOptions = context.sourceOptions;\n lookahead.streamCandidates = context.streamCandidates;\n parseCommandBody(lookahead, line, undefined, names);\n return parseCommandBody(context, line, names);\n}\n\nfunction parseCommandBody(context: ParserContext, line: SourceLine, responseNames?: ReadonlySet<string>, discoveredNames?: Set<string>): CommandSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidCommandDeclaration, `Invalid command declaration '${line.content}' - expected 'command <Name>'`, locationOf(line));\n }\n const properties: PropertySyntax[] = [];\n const responses: { line: SourceLine; candidate: PropertySyntax | null; response: CommandResponseSyntax | null }[] = [];\n let identifier: PropertySyntax | undefined;\n const validations: ValidateSyntax[] = [];\n const produces: ProducesSyntax[] = [];\n const reads: { readModel: string; alias: string | null }[] = [];\n const referenceReads: ReadsSyntax[] = [];\n let concurrency: ConcurrencySyntax | undefined;\n let description: string | null = null;\n let documentation: string | null = null;\n let authorize: AuthorizeSyntax | null = null;\n let handler: HandlerSyntax | null = null;\n const handlers: { handler: HandlerSyntax | null; location: SourceLocation }[] = [];\n let stream: CommandStreamSyntax | null = null;\n const streamCandidates: CommandStreamSyntax[] = [];\n let calendar: CommandCalendarSyntax | 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 const asProperty = tryParseProperty(child);\n if (keyword === 'calendar' && calendarPrefix.test(child.content)) {\n const match = calendarPattern.exec(child.content);\n if (calendar !== null || match === null) {\n context.error(DiagnosticCodes.InvalidCommandCalendar, 'A command declares at most one \\'calendar \"<id>\"\\' or \\'calendar from $context.<member>\\'.', locationOf(child));\n } else {\n calendar = { kind: 'CommandCalendarSyntax', id: match[1] === undefined ? null : unescapeString(match[1]), contextMember: match[2] ?? null, location: locationOf(child) };\n }\n } else if (asProperty !== undefined && (propertyShapedDirectives.has(keyword) || (keyword === 'validate' && child.content !== 'validate csharp'))) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (keyword === 'returns') {\n const scalar = scalarResponsePattern.exec(child.content);\n if (scalar !== null && !scalar[1].startsWith('@') && asProperty !== undefined) {\n if (responseNames === undefined) {\n properties.push(asProperty);\n responses.push({ line: child, candidate: asProperty, response: null });\n } else if (responseNames.has(asProperty.type.name)) {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n } else {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n }\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (reportInvalidModifierOrder(context, child)) {\n context.skipBlock(child.indent);\n } else {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n }\n } else if (keyword === 'stream' && routeHeader.test(child.content) && asProperty !== undefined && context.streamCandidates?.hasSource(asProperty.type.name.split('.')[0]) === true) {\n const [source, streamName] = asProperty.type.name.split('.');\n const ambiguous = context.streamCandidates.hasPropertyType(asProperty.type.name) && context.streamCandidates.hasUniqueStream(source, streamName);\n const route = parseCommandStream(context, child, asProperty, ambiguous);\n if (stream !== null || streamCandidates.length > 0) context.error(DiagnosticCodes.InvalidCommandStream, 'A command declares at most one stream route.', locationOf(child));\n if (ambiguous || stream !== null) streamCandidates.push(route);\n else stream = route;\n } else if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Command '${name}'`);\n } else if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Command '${name}'`);\n } else if (keyword === 'authorize') {\n authorize = combineAuthorize(authorize, parseAuthorize(context, child));\n } else if (keyword === 'validate') {\n const validate = parseValidate(context, child, 'command', name);\n if (validate !== undefined) {\n validations.push(validate);\n }\n } else if (keyword === 'produces') {\n const production = parseProduces(context, child, true);\n if (production !== undefined) produces.push(production);\n } else if (keyword === 'handler') {\n handler = parseHandler(context, child);\n handlers.push({ handler, location: locationOf(child) });\n } else if (opaqueDirectives.has(keyword)) {\n const reference = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (reference !== undefined) referenceReads.push(reference);\n if (keyword === 'concurrency' && concurrency === undefined) concurrency = captureConcurrency(context, child);\n const read = /^reads\\s+([A-Z]\\w*)(?:\\s+as\\s+([a-z_]\\w*))?(?:\\s+by\\s+([a-z_]\\w*))?$/.exec(child.content);\n if (read !== null) reads.push({ readModel: read[1], alias: read[2] ?? null });\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n context.skipOpaqueBlock(child.indent);\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else {\n reportInvalidModifierOrder(context, child);\n context.error(DiagnosticCodes.UnknownCommandDirective, `Unexpected '${child.content}' in command body`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const candidates = new Set(responses.flatMap(entry => entry.candidate === null ? [] : [entry.candidate]));\n const names = new Set(properties.filter(property => !candidates.has(property)).map(property => property.name));\n if (responses.some(entry => entry.candidate !== null && !names.has(entry.candidate.type.name) && entry.candidate.type.name !== 'returns')) names.add('returns');\n for (const name of names) discoveredNames?.add(name);\n let response: CommandResponseSyntax | null = null;\n const removed = new Set<PropertySyntax>();\n for (const entry of responses) {\n let parsed = entry.response;\n if (entry.candidate !== null) {\n if (!names.has(entry.candidate.type.name)) continue;\n removed.add(entry.candidate);\n parsed = { kind: 'ScalarCommandResponseSyntax', source: { kind: 'PropertyResponseSourceSyntax', property: entry.candidate.type.name, location: entry.candidate.type.location }, location: locationOf(entry.line) };\n }\n if (parsed === null) continue;\n if (response !== null) {\n context.error(DiagnosticCodes.InvalidCommandResponse, 'A command declares at most one unconditional response.', locationOf(entry.line));\n } else {\n response = parsed;\n }\n }\n validateHandlerOccurrences(handlers, context);\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, ...(calendar === null ? {} : { calendar }), location: locationOf(line) };\n commandReadSources.set(syntax, reads);\n dependencySources.set(syntax, { reads: referenceReads, concurrency });\n return syntax;\n}\n\nfunction addProperty(context: ParserContext, properties: PropertySyntax[], property: PropertySyntax, commandName: string, line: SourceLine, identifier: PropertySyntax | undefined): PropertySyntax | undefined {\n reportLegacyOptionalSuffix(context, property.type, line);\n if (property.isIdentifier && identifier !== undefined) {\n context.error(DiagnosticCodes.DuplicateCommandIdentifier, `Command '${commandName}' already marks '${identifier.name}' as identifier - only one property can be the identifier`, property.location);\n property = { ...property, isIdentifier: false };\n }\n properties.push(property);\n return identifier ?? (property.isIdentifier ? property : undefined);\n}\n\nfunction parseValidationFile(context: ParserContext, header: SourceLine, body: SourceLine): ValidateSyntax | undefined {\n const file = parseFile(context, body);\n return file === undefined ? undefined : { kind: 'FileValidateSyntax', file, location: locationOf(header) };\n}\n\nfunction hasValidationOperand(line: SourceLine): boolean {\n const match = rulePattern.exec(line.content);\n if (match === null) return false;\n const rule = match[2];\n return (firstWord(rule) === 'not' && firstWord(rule.substring('not'.length).trimStart()) === 'empty') ||\n firstWord(rule) === 'checksum' || operandPattern.test(rule);\n}\n\nfunction isValidationFileBody(context: ParserContext, header: SourceLine, body: SourceLine): boolean {\n if (!isFileDirectiveAmongProperties(body) || hasValidationOperand(body)) return false;\n const lookahead = context.reader.fork();\n lookahead.takeSignificant();\n const next = lookahead.peekSignificant();\n return next === undefined || next.indent <= header.indent;\n}\n\n// Reads a 'validate' block: declarative rules, or code - which is recognized but not modeled.\nexport function parseValidate(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidateSyntax | undefined {\n if (line.content === 'validate') {\n const fence = context.peekChild(line.indent);\n if (fence !== undefined && isValidationFileBody(context, line, fence)) {\n context.reader.takeSignificant();\n return parseValidationFile(context, line, fence);\n }\n if (fence !== undefined && fence.content.startsWith('```')) {\n context.reader.takeSignificant();\n const code = parseCode(context.valueContext, fence);\n if (code === null) context.skipFencedBody();\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n const rules: ValidationRuleSyntax[] = [];\n const requirements: RequirementSyntax[] = [];\n let wrapperIndent: number | undefined;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (owner === 'concept') {\n if (context.sourceOptions.numericMode === 'legacy' && child.content.startsWith('```')) { context.skipFencedBody(); continue; }\n if (wrapperIndent !== undefined && child.indent <= wrapperIndent) wrapperIndent = undefined;\n if (wrapperIndent !== undefined || firstWord(child.content) === 'implementation') {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${child.content}'`, locationOf(child));\n wrapperIndent ??= child.indent;\n continue;\n }\n }\n if (firstWord(child.content) === 'require') {\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child));\n let message: string | null = null;\n let severity: ValidationSeverity = 'Error';\n let hasSeverity = false;\n for (let directive = context.peekChild(child.indent); directive !== undefined; directive = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n const matched = messagePattern.exec(directive.content);\n if (matched !== null && matched.index === 0) message = matched[1] !== undefined ? unescapeString(matched[1]) : matched[2];\n else if (firstWord(directive.content) === 'severity') {\n if (!hasSeverity) severity = severities[directive.content.substring('severity'.length).trim()] ?? 'Error';\n hasSeverity = true;\n } else context.skipOpaqueBlock(directive.indent);\n }\n if (condition !== null) requirements.push({ kind: 'RequirementSyntax', condition, message, severity, location: locationOf(child) });\n continue;\n }\n const rule = parseValidationRule(context, owner === 'concept' ? { ...child, content: `value ${child.content}` } : child, owner, ownerName);\n if (rule !== undefined) {\n rules.push(rule);\n }\n }\n return { kind: 'DeclarativeValidateSyntax', rules, requirements, location: locationOf(line) };\n }\n if (owner === 'concept' && firstWord(line.content.substring('validate'.length).trimStart()) === 'checksum') {\n const ruleLine = { ...line, content: `value ${line.content.substring('validate'.length).trimStart()}` };\n const rule = parseValidationRule(context, ruleLine, owner, ownerName);\n return rule === undefined ? undefined : { kind: 'DeclarativeValidateSyntax', rules: [rule], requirements: [], location: locationOf(line) };\n }\n if (line.content === 'validate csharp') {\n const code = parseCode(context.valueContext, { ...line, content: 'csharp' });\n if (code === null) context.skipOpaqueBlock(line.indent);\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n context.error(DiagnosticCodes.InvalidValidateDeclaration, `Invalid validate declaration '${line.content}' - expected 'validate' or 'validate csharp'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n}\n\nfunction parseValidationRule(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidationRuleSyntax | undefined {\n // Checksum is a new declaration, not enrichment of a formerly opaque Legacy rule.\n const checksum = firstWord(rulePattern.exec(line.content)?.[2] ?? '') === 'checksum';\n const valueContext = owner === 'concept' && !checksum ? context.valueContext : context;\n const { content: withSeverity, message } = splitMessage(line.content);\n const severity = splitSeverity(valueContext, line, withSeverity);\n if (severity === undefined) {\n return undefined;\n }\n const match = rulePattern.exec(severity.content);\n if (match === null) {\n valueContext.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const parsed = parseRule(valueContext, match[2], line);\n if (parsed === undefined) {\n return undefined;\n }\n if (parsed.kind === 'Matches' && parsed.value !== null) validateMatchOperand(context, parsed.value, locationOf(line), line.raw, matchSubject(context, owner, ownerName, match[1]));\n const source = parsed.kind === 'Rule' ? parseRuleImplementation(context, line, owner === 'command') : { file: null, code: null, implementation: null };\n return {\n kind: 'ValidationRuleSyntax',\n property: match[1],\n rule: parsed.kind,\n value: parsed.value,\n message,\n severity: severity.severity,\n ...source,\n location: locationOf(line),\n };\n}\n\nfunction parseRuleImplementation(context: ParserContext, rule: SourceLine, commandOwner: boolean): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax | null } {\n const body = context.peekChild(rule.indent);\n if (body === undefined) return { file: null, code: null, implementation: null };\n context.reader.takeSignificant();\n const wrapped = commandOwner && firstWord(body.content) === 'implementation';\n const source = wrapped ? parseImplementationWrapper(context, body) : {\n file: isFile(body) ? parseFile(context, body) : null,\n code: !isFile(body) && isCode(context, body) ? parseCode(context, body) : null,\n implementation: null,\n };\n if (!wrapped && source.file === null && source.code === null) {\n context.error(DiagnosticCodes.UnknownRuleImplementationDirective, `Unexpected '${body.content}' in rule implementation - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(body.indent);\n }\n for (let extra = context.peekChild(rule.indent); extra !== undefined && (wrapped || (commandOwner && firstWord(extra.content) === 'implementation')); extra = context.peekChild(rule.indent)) {\n context.reader.takeSignificant();\n context.error(wrapped && firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A named rule has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return source;\n}\n\nfunction splitMessage(content: string): { content: string; message: string | null } {\n const match = messagePattern.exec(content);\n if (match === null) {\n return { content, message: null };\n }\n const message = match[1] !== undefined ? unescapeString(match[1]) : match[2];\n return { content: content.substring(0, match.index).trimEnd(), message };\n}\n\nfunction splitSeverity(context: ParserContext, line: SourceLine, text: string): { content: string; severity: ValidationSeverity } | undefined {\n const match = severityPattern.exec(text);\n if (match === null) {\n return { content: text, severity: 'Error' };\n }\n const severity = severities[match[1]];\n if (severity === undefined) {\n context.error(DiagnosticCodes.InvalidValidationSeverity, `Unknown validation severity '${match[1]}' - expected information, warning or error`, locationOf(line));\n return undefined;\n }\n return { content: text.substring(0, match.index).trimEnd(), severity };\n}\n\nfunction parseRule(context: ParserContext, rule: string, line: SourceLine): { kind: ValidationRuleKind; value: ExpressionSyntax | null } | undefined {\n if (rule === 'not empty') {\n return { kind: 'NotEmpty', value: null };\n }\n if (firstWord(rule) === 'checksum') {\n const algorithm = rule.substring('checksum'.length).trim();\n if (algorithm !== 'luhn' && algorithm !== 'mod11' && algorithm !== 'mod97') {\n context.error(DiagnosticCodes.InvalidGenerationArgument, 'Checksum validation requires luhn, mod11 or mod97.', locationOf(line));\n return undefined;\n }\n return { kind: 'Checksum', value: { kind: 'LiteralExpressionSyntax', value: algorithm, location: locationOf(line) } };\n }\n const operand = operandPattern.exec(rule);\n if (operand === null) {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const operator = operand[1] ?? operand[2];\n if (operator === 'rule') {\n const name = operand[3].trim();\n if (!ruleNamePattern.test(name)) {\n context.error(DiagnosticCodes.InvalidRuleName, `Invalid rule name '${name}' in '${line.content}' - expected 'rule <Name>' with an identifier`, locationOf(line));\n return undefined;\n }\n return { kind: 'Rule', value: { kind: 'PathExpressionSyntax', path: name, location: locationOf(line) } };\n }\n return { kind: operandKinds[operator], value: parseMappingSource(operand[3], locationOf(line), context) };\n}\n"],"mappings":"wwDAwCA,MAAMA,EAASC,EAAQ,8BAA8B,EAC/CC,GAAcC,EAAoB,2CAA2C,EAC7EC,EAAiBH,EAAQ,0CAA0C,EACnEI,EAAkBJ,EAAQ,qBAAqBK,EAAkB,iFAAiF,EAClJC,EAAkBN,EAAQ,wBAAwB,EAClDO,EAAiBP,EAAQ,sBAAsBK,EAAkB,yBAAyB,EAC1FG,EAAcR,EAAQ,qBAAqB,EAC3CS,EAAiBT,EAAQ,2JAA2J,EACpLU,EAAkBR,EAAoB,iBAAiB,EACvDS,EAAgBX,EAAQ,0CAA0C,EAGlEY,EAAmD,CACrD,IAAK,MACL,IAAK,MACL,IAAK,cACL,KAAM,qBACN,IAAK,WACL,KAAM,kBACN,KAAM,QACN,KAAM,WACN,YAAa,SACb,cAAe,gBACf,QAAS,UACT,SAAU,WACV,eAAgB,cAChB,cAAe,aACf,YAAa,WACb,QAAS,iBACT,SAAU,uBACd,EAEMC,EAAiD,CAAE,YAAa,cAAe,QAAS,UAAW,MAAO,OAAQ,EAGlHC,kBAAmB,IAAI,IAAI,CAAC,QAAS,aAAa,CAAC,EAInDC,kBAA2B,IAAI,IAAI,CAAC,cAAe,gBAAiB,UAAW,aAAa,CAAC,EAEnG,SAAgB,aAAa,EAAwB,EAAiC,CAGlF,IAAMC,kBAAQ,IAAI,IACZC,EAAY,IAAIC,EAAcC,EAAQ,OAAO,KAAK,EAAGA,EAAQ,KAAMA,EAAQ,SAAS,EAI1F,MAHA,GAAU,cAAgBA,EAAQ,cAClC,EAAU,iBAAmBA,EAAQ,iBACrC,iBAAiBF,EAAWG,EAAM,IAAA,GAAWJ,CAAK,EAC3C,iBAAiBG,EAASC,EAAMJ,CAAK,CAChD,CAEA,SAAS,iBAAiB,EAAwB,EAAkB,EAAqC,EAA8C,CACnJ,IAAMK,EAAOtB,EAAO,KAAKqB,EAAK,OAAO,CAAC,GAAG,IAAM,GAC3CC,IAAS,IACTF,EAAQ,MAAMG,EAAgB,0BAA2B,gCAAgCF,EAAK,QAAQ,+BAAgCG,EAAWH,CAAI,CAAC,EAE1J,IAAMI,EAA+B,CAAC,EAChCC,EAA8G,CAAC,EACjHC,EACEC,EAAgC,CAAC,EACjCC,EAA6B,CAAC,EAC9BC,EAAuD,CAAC,EACxDC,EAAgC,CAAC,EACnCC,EACAC,EAA6B,KAC7BC,EAA+B,KAC/BC,EAAoC,KACpCC,EAAgC,KAC9BC,EAA0E,CAAC,EAC7EC,EAAqC,KACnCC,EAA0C,CAAC,EAC7CC,EAAyC,KAC7C,IAAK,IAAIC,EAAQrB,EAAQ,UAAUC,EAAK,MAAM,EAAGoB,IAAU,IAAA,GAAW,EAAQrB,EAAQ,UAAUC,EAAK,MAAM,EAAG,CAC1GD,EAAQ,OAAO,gBAAgB,EAC/B,IAAMsB,EAAUC,EAAUF,EAAM,OAAO,EACjCG,EAAaC,EAAiBJ,CAAK,EACzC,GAAIC,IAAY,YAActC,EAAe,KAAKqC,EAAM,OAAO,EAAG,CAC9D,IAAMK,EAAQzC,EAAgB,KAAKoC,EAAM,OAAO,EAC5CD,IAAa,MAAQM,IAAU,KAC/B1B,EAAQ,MAAMG,EAAgB,uBAAwB,yFAA8FC,EAAWiB,CAAK,CAAC,EAErK,EAAW,CAAE,KAAM,wBAAyB,GAAIK,EAAM,KAAO,IAAA,GAAY,KAAOC,EAAeD,EAAM,EAAE,EAAG,cAAeA,EAAM,IAAM,KAAM,SAAUtB,EAAWiB,CAAK,CAAE,CAE/K,MAAO,GAAIG,IAAe,IAAA,KAAc5B,EAAyB,IAAI0B,CAAO,GAAMA,IAAY,YAAcD,EAAM,UAAY,mBAC1H,EAAa,YAAYrB,EAASK,EAAYmB,EAAYtB,EAAMmB,EAAOd,CAAU,OAC9E,GAAIe,IAAY,UAAW,CAC9B,IAAMM,EAASC,EAAsB,KAAKR,EAAM,OAAO,EACnDO,IAAW,MAAQ,CAACA,EAAO,EAAE,CAAC,WAAW,GAAG,GAAKJ,IAAe,IAAA,GAC5DM,IAAkB,IAAA,IAClBzB,EAAW,KAAKmB,CAAU,EAC1BlB,EAAU,KAAK,CAAE,KAAMe,EAAO,UAAWG,EAAY,SAAU,IAAK,CAAC,GAC9DM,EAAc,IAAIN,EAAW,KAAK,IAAI,EAC7ClB,EAAU,KAAK,CAAE,KAAMe,EAAO,UAAW,KAAM,SAAUU,EAAqB/B,EAASqB,CAAK,CAAE,CAAC,EAE/F,EAAa,YAAYrB,EAASK,EAAYmB,EAAYtB,EAAMmB,EAAOd,CAAU,EAE9EiB,IAAe,IAAA,GAEfQ,EAA2BhC,EAASqB,CAAK,EAChDrB,EAAQ,UAAUqB,EAAM,MAAM,EAE9Bf,EAAU,KAAK,CAAE,KAAMe,EAAO,UAAW,KAAM,SAAUU,EAAqB/B,EAASqB,CAAK,CAAE,CAAC,EAJ/F,EAAa,YAAYrB,EAASK,EAAYmB,EAAYtB,EAAMmB,EAAOd,CAAU,CAMzF,MAAO,GAAIe,IAAY,UAAYxC,GAAY,KAAKuC,EAAM,OAAO,GAAKG,IAAe,IAAA,IAAaxB,EAAQ,kBAAkB,UAAUwB,EAAW,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,IAAM,GAAM,CAChL,GAAM,CAACS,EAAQC,GAAcV,EAAW,KAAK,KAAK,MAAM,GAAG,EACrDW,EAAYnC,EAAQ,iBAAiB,gBAAgBwB,EAAW,KAAK,IAAI,GAAKxB,EAAQ,iBAAiB,gBAAgBiC,EAAQC,CAAU,EACzIE,EAAQC,EAAmBrC,EAASqB,EAAOG,EAAYW,CAAS,GAClEjB,IAAW,MAAQC,EAAiB,OAAS,IAAGnB,EAAQ,MAAMG,EAAgB,qBAAsB,+CAAgDC,EAAWiB,CAAK,CAAC,EACrKc,GAAajB,IAAW,KAAMC,EAAiB,KAAKiB,CAAK,EACxD,EAASA,CAClB,MAAO,GAAId,IAAY,QAAUgB,EAAuBjB,CAAK,EACzDkB,EAA0BvC,EAASqB,CAAK,OACrC,GAAIC,IAAY,cACnB,EAAckB,EAAiBxC,EAASqB,EAAOR,EAAa,YAAYX,EAAK,EAAE,OAC5E,GAAIoB,IAAY,gBACnB,EAAgBmB,EAAmBzC,EAASqB,EAAOP,EAAe,YAAYZ,EAAK,EAAE,OAClF,GAAIoB,IAAY,YACnB,EAAYoB,EAAiB3B,EAAW4B,EAAe3C,EAASqB,CAAK,CAAC,OACnE,GAAIC,IAAY,WAAY,CAC/B,IAAMsB,EAAW,cAAc5C,EAASqB,EAAO,UAAWnB,CAAI,EAC1D0C,IAAa,IAAA,IACbpC,EAAY,KAAKoC,CAAQ,CAEjC,MAAO,GAAItB,IAAY,WAAY,CAC/B,IAAMuB,EAAaC,EAAc9C,EAASqB,EAAO,EAAI,EACjDwB,IAAe,IAAA,IAAWpC,EAAS,KAAKoC,CAAU,CAC1D,MAAO,GAAIvB,IAAY,UACnB,EAAUyB,EAAa/C,EAASqB,CAAK,EACrCJ,EAAS,KAAK,CAAE,UAAS,SAAUb,EAAWiB,CAAK,CAAE,CAAC,OACnD,GAAI1B,EAAiB,IAAI2B,CAAO,EAAG,CACtC,IAAM0B,EAAY1B,IAAY,QAAU2B,EAAWjD,EAASqB,CAAK,EAAI,IAAA,GACjE2B,IAAc,IAAA,IAAWrC,EAAe,KAAKqC,CAAS,EACtD1B,IAAY,eAAiBV,IAAgB,IAAA,KAAW,EAAcsC,EAAmBlD,EAASqB,CAAK,GAC3G,IAAM8B,EAAO,uEAAuE,KAAK9B,EAAM,OAAO,EAClG8B,IAAS,MAAMzC,EAAM,KAAK,CAAE,UAAWyC,EAAK,GAAI,MAAOA,EAAK,IAAM,IAAK,CAAC,EACxE3D,EAAc,KAAK6B,EAAM,OAAO,GAChCrB,EAAQ,MAAMG,EAAgB,0BAA2B,mDAAoDC,EAAWiB,CAAK,CAAC,EAElIrB,EAAQ,gBAAgBqB,EAAM,MAAM,CACxC,MAAWG,IAAe,IAAA,IAGtBQ,EAA2BhC,EAASqB,CAAK,EACzCrB,EAAQ,MAAMG,EAAgB,wBAAyB,eAAekB,EAAM,QAAQ,mBAAoBjB,EAAWiB,CAAK,CAAC,EACzHrB,EAAQ,UAAUqB,EAAM,MAAM,GAJ9B,EAAa,YAAYrB,EAASK,EAAYmB,EAAYtB,EAAMmB,EAAOd,CAAU,CAMzF,CACA,IAAM6C,EAAa,IAAI,IAAI9C,EAAU,QAAQ,GAAS+C,EAAM,YAAc,KAAO,CAAC,EAAI,CAACA,EAAM,SAAS,CAAC,CAAC,EAClGxD,EAAQ,IAAI,IAAIQ,EAAW,OAAO,GAAY,CAAC+C,EAAW,IAAIE,CAAQ,CAAC,CAAC,CAAC,IAAI,GAAYA,EAAS,IAAI,CAAC,EACzGhD,EAAU,KAAK,GAAS+C,EAAM,YAAc,MAAQ,CAACxD,EAAM,IAAIwD,EAAM,UAAU,KAAK,IAAI,GAAKA,EAAM,UAAU,KAAK,OAAS,SAAS,GAAGxD,EAAM,IAAI,SAAS,EAC9J,IAAK,IAAMK,KAAQL,EAAO0D,GAAiB,IAAIrD,CAAI,EACnD,IAAIsD,EAAyC,KACvCC,kBAAU,IAAI,IACpB,IAAK,IAAMJ,KAAS/C,EAAW,CAC3B,IAAIoD,EAASL,EAAM,SACnB,GAAIA,EAAM,YAAc,KAAM,CAC1B,GAAI,CAACxD,EAAM,IAAIwD,EAAM,UAAU,KAAK,IAAI,EAAG,SAC3CI,EAAQ,IAAIJ,EAAM,SAAS,EAC3B,EAAS,CAAE,KAAM,8BAA+B,OAAQ,CAAE,KAAM,+BAAgC,SAAUA,EAAM,UAAU,KAAK,KAAM,SAAUA,EAAM,UAAU,KAAK,QAAS,EAAG,SAAUjD,EAAWiD,EAAM,IAAI,CAAE,CACrN,CACIK,IAAW,OACXF,IAAa,KAGb,EAAWE,EAFX1D,EAAQ,MAAMG,EAAgB,uBAAwB,yDAA0DC,EAAWiD,EAAM,IAAI,CAAC,EAI9I,CACAM,EAA2B1C,EAAUjB,CAAO,EAC5C,IAAM4D,EAAwB,CAAE,KAAM,gBAAiB,OAAM,cAAa,gBAAe,YAAW,WAAYvD,EAAW,OAAO,GAAY,CAACoD,EAAQ,IAAIH,CAAQ,CAAC,EAAG,cAAa,WAAU,UAAS,WAAU,SAAQ,mBAAkB,GAAIlC,IAAa,KAAO,CAAC,EAAI,CAAE,UAAS,EAAI,SAAUhB,EAAWH,CAAI,CAAE,EAGlT,OAFA4D,EAAmB,IAAID,EAAQlD,CAAK,EACpCoD,EAAkB,IAAIF,EAAQ,CAAE,MAAOjD,EAAgB,aAAY,CAAC,EAC7DiD,CACX,CAEA,SAAS,YAAY,EAAwB,EAA8B,EAA0B,EAAqB,EAAkB,EAAoE,CAO5M,OANAG,EAA2B/D,EAASsD,EAAS,KAAMrD,CAAI,EACnDqD,EAAS,cAAgB/C,IAAe,IAAA,KACxCP,EAAQ,MAAMG,EAAgB,2BAA4B,YAAY6D,EAAY,mBAAmBzD,EAAW,KAAK,2DAA4D+C,EAAS,QAAQ,EAClM,EAAW,CAAE,GAAGA,EAAU,aAAc,EAAM,GAElDjD,EAAW,KAAKiD,CAAQ,EACjB/C,IAAe+C,EAAS,aAAeA,EAAW,IAAA,GAC7D,CAEA,SAAS,oBAAoB,EAAwB,EAAoB,EAA8C,CACnH,IAAMW,EAAOC,EAAUlE,EAASmE,CAAI,EACpC,OAAOF,IAAS,IAAA,GAAY,IAAA,GAAY,CAAE,KAAM,qBAAsB,OAAM,SAAU7D,EAAWxB,CAAM,CAAE,CAC7G,CAEA,SAAS,qBAAqB,EAA2B,CACrD,IAAM8C,EAAQrC,EAAY,KAAKY,EAAK,OAAO,EAC3C,GAAIyB,IAAU,KAAM,MAAO,GAC3B,IAAM0C,EAAO1C,EAAM,GACnB,OAAQH,EAAU6C,CAAI,IAAM,OAAS7C,EAAU6C,EAAK,UAAU,CAAY,CAAC,CAAC,UAAU,CAAC,IAAM,SACzF7C,EAAU6C,CAAI,IAAM,YAAc9E,EAAe,KAAK8E,CAAI,CAClE,CAEA,SAAS,qBAAqB,EAAwB,EAAoB,EAA2B,CACjG,GAAI,CAACC,EAA+BF,CAAI,GAAK,qBAAqBA,CAAI,EAAG,MAAO,GAChF,IAAMrE,EAAYE,EAAQ,OAAO,KAAK,EACtCF,EAAU,gBAAgB,EAC1B,IAAMwE,EAAOxE,EAAU,gBAAgB,EACvC,OAAOwE,IAAS,IAAA,IAAaA,EAAK,QAAU1F,EAAO,MACvD,CAGA,SAAgB,cAAc,EAAwB,EAAkB,EAA8B,EAA+C,CACjJ,GAAIqB,EAAK,UAAY,WAAY,CAC7B,IAAMsE,EAAQvE,EAAQ,UAAUC,EAAK,MAAM,EAC3C,GAAIsE,IAAU,IAAA,IAAa,qBAAqBvE,EAASC,EAAMsE,CAAK,EAEhE,OADAvE,EAAQ,OAAO,gBAAgB,EACxB,oBAAoBA,EAASC,EAAMsE,CAAK,EAEnD,GAAIA,IAAU,IAAA,IAAaA,EAAM,QAAQ,WAAW,KAAK,EAAG,CACxDvE,EAAQ,OAAO,gBAAgB,EAC/B,IAAMwE,EAAOC,EAAUzE,EAAQ,aAAcuE,CAAK,EAElD,OADIC,IAAS,MAAMxE,EAAQ,eAAe,EACnC,CAAE,KAAM,qBAAsB,OAAM,SAAUI,EAAWH,CAAI,CAAE,CAC1E,CACA,IAAMyE,EAAgC,CAAC,EACjCC,EAAoC,CAAC,EACvCC,EACJ,IAAK,IAAIvD,EAAQrB,EAAQ,UAAUC,EAAK,MAAM,EAAGoB,IAAU,IAAA,GAAW,EAAQrB,EAAQ,UAAUC,EAAK,MAAM,EAAG,CAE1G,GADAD,EAAQ,OAAO,gBAAgB,EAC3B6E,IAAU,UAAW,CACrB,GAAI7E,EAAQ,cAAc,cAAgB,UAAYqB,EAAM,QAAQ,WAAW,KAAK,EAAG,CAAErB,EAAQ,eAAe,EAAG,QAAU,CAE7H,GADI4E,IAAkB,IAAA,IAAavD,EAAM,QAAUuD,IAAe,EAAgB,IAAA,IAC9EA,IAAkB,IAAA,IAAarD,EAAUF,EAAM,OAAO,IAAM,iBAAkB,CAC9ErB,EAAQ,MAAMG,EAAgB,sBAAuB,4BAA4BkB,EAAM,QAAQ,GAAIjB,EAAWiB,CAAK,CAAC,EACpH,IAAkBA,EAAM,OACxB,QACJ,CACJ,CACA,GAAIE,EAAUF,EAAM,OAAO,IAAM,UAAW,CACxC,IAAMyD,EAAYC,EAAeF,IAAU,UAAY7E,EAAQ,aAAeA,EAASqB,EAAM,QAAQ,UAAU,CAAgB,CAAC,CAAC,KAAK,EAAGjB,EAAWiB,CAAK,CAAC,EACtJ2D,EAAyB,KACzBC,EAA+B,QAC/BC,EAAc,GAClB,IAAK,IAAIC,EAAYnF,EAAQ,UAAUqB,EAAM,MAAM,EAAG8D,IAAc,IAAA,GAAW,EAAYnF,EAAQ,UAAUqB,EAAM,MAAM,EAAG,CACxHrB,EAAQ,OAAO,gBAAgB,EAC/B,IAAMoF,EAAUhG,EAAe,KAAK+F,EAAU,OAAO,EACjDC,IAAY,MAAQA,EAAQ,QAAU,EAAG,EAAUA,EAAQ,KAAO,IAAA,GAAyCA,EAAQ,GAArCzD,EAAeyD,EAAQ,EAAE,EAClG7D,EAAU4D,EAAU,OAAO,IAAM,YACjCD,IAAa,EAAWxF,EAAWyF,EAAU,QAAQ,UAAU,CAAiB,CAAC,CAAC,KAAK,IAAM,SAClG,EAAc,IACXnF,EAAQ,gBAAgBmF,EAAU,MAAM,CACnD,CACIL,IAAc,MAAMH,EAAa,KAAK,CAAE,KAAM,oBAAqB,YAAW,UAAS,WAAU,SAAUvE,EAAWiB,CAAK,CAAE,CAAC,EAClI,QACJ,CACA,IAAM+C,EAAO,oBAAoBpE,EAAS6E,IAAU,UAAY,CAAE,GAAGxD,EAAO,QAAS,SAASA,EAAM,SAAU,EAAIA,EAAOwD,EAAOQ,CAAS,EACrIjB,IAAS,IAAA,IACTM,EAAM,KAAKN,CAAI,CAEvB,CACA,MAAO,CAAE,KAAM,4BAA6B,QAAO,eAAc,SAAUhE,EAAWH,CAAI,CAAE,CAChG,CACA,GAAI4E,IAAU,WAAatD,EAAUtB,EAAK,QAAQ,UAAU,CAAiB,CAAC,CAAC,UAAU,CAAC,IAAM,WAAY,CAExG,IAAMmE,EAAO,oBAAoBpE,EAAS,CADvB,GAAGC,EAAM,QAAS,SAASA,EAAK,QAAQ,UAAU,CAAiB,CAAC,CAAC,UAAU,GACjD,EAAG4E,EAAOQ,CAAS,EACpE,OAAOjB,IAAS,IAAA,GAAY,IAAA,GAAY,CAAE,KAAM,4BAA6B,MAAO,CAACA,CAAI,EAAG,aAAc,CAAC,EAAG,SAAUhE,EAAWH,CAAI,CAAE,CAC7I,CACA,GAAIA,EAAK,UAAY,kBAAmB,CACpC,IAAMuE,EAAOC,EAAUzE,EAAQ,aAAc,CAAE,GAAGC,EAAM,QAAS,QAAS,CAAC,EAE3E,OADIuE,IAAS,MAAMxE,EAAQ,gBAAgBC,EAAK,MAAM,EAC/C,CAAE,KAAM,qBAAsB,OAAM,SAAUG,EAAWH,CAAI,CAAE,CAC1E,CACAD,EAAQ,MAAMG,EAAgB,2BAA4B,iCAAiCF,EAAK,QAAQ,8CAA+CG,EAAWH,CAAI,CAAC,EACvKD,EAAQ,UAAUC,EAAK,MAAM,CAEjC,CAEA,SAAS,oBAAoB,EAAwB,EAAkB,EAA8B,EAAqD,CAEtJ,IAAMqF,EAAW/D,EAAUlC,EAAY,KAAKY,EAAK,OAAO,CAAC,GAAG,IAAM,EAAE,IAAM,WACpEsF,EAAeV,IAAU,WAAa,CAACS,EAAWtF,EAAQ,aAAeA,EACzE,CAAE,QAASwF,EAAc,WAAY,aAAavF,EAAK,OAAO,EAC9DgF,EAAW,cAAcM,EAActF,EAAMuF,CAAY,EAC/D,GAAIP,IAAa,IAAA,GACb,OAEJ,IAAMvD,EAAQrC,EAAY,KAAK4F,EAAS,OAAO,EAC/C,GAAIvD,IAAU,KAAM,CAChB6D,EAAa,MAAMpF,EAAgB,sBAAuB,4BAA4BF,EAAK,QAAQ,GAAIG,EAAWH,CAAI,CAAC,EACvH,MACJ,CACA,IAAMyD,EAAS,UAAU6B,EAAc7D,EAAM,GAAIzB,CAAI,EACrD,GAAIyD,IAAW,IAAA,GACX,OAEAA,EAAO,OAAS,WAAaA,EAAO,QAAU,MAAM+B,EAAqBzF,EAAS0D,EAAO,MAAOtD,EAAWH,CAAI,EAAGA,EAAK,IAAKyF,EAAa1F,EAAS6E,EAAOQ,EAAW3D,EAAM,EAAE,CAAC,EACjL,IAAMO,EAASyB,EAAO,OAAS,OAAS,wBAAwB1D,EAASC,EAAM4E,IAAU,SAAS,EAAI,CAAE,KAAM,KAAM,KAAM,KAAM,eAAgB,IAAK,EACrJ,MAAO,CACH,KAAM,uBACN,SAAUnD,EAAM,GAChB,KAAMgC,EAAO,KACb,MAAOA,EAAO,MACd,UACA,SAAUuB,EAAS,SACnB,GAAGhD,EACH,SAAU7B,EAAWH,CAAI,CAC7B,CACJ,CAEA,SAAS,wBAAwB,EAAwB,EAAkB,EAAwI,CAC/M,IAAMkE,EAAOnE,EAAQ,UAAUoE,EAAK,MAAM,EAC1C,GAAID,IAAS,IAAA,GAAW,MAAO,CAAE,KAAM,KAAM,KAAM,KAAM,eAAgB,IAAK,EAC9EnE,EAAQ,OAAO,gBAAgB,EAC/B,IAAM2F,EAAUC,GAAgBrE,EAAU4C,EAAK,OAAO,IAAM,iBACtDlC,EAAS0D,EAAUE,EAA2B7F,EAASmE,CAAI,EAAI,CACjE,KAAM2B,EAAO3B,CAAI,EAAID,EAAUlE,EAASmE,CAAI,EAAI,KAChD,KAAM,CAAC2B,EAAO3B,CAAI,GAAK4B,EAAO/F,EAASmE,CAAI,EAAIM,EAAUzE,EAASmE,CAAI,EAAI,KAC1E,eAAgB,IACpB,EACI,CAACwB,GAAW1D,EAAO,OAAS,MAAQA,EAAO,OAAS,OACpDjC,EAAQ,MAAMG,EAAgB,mCAAoC,eAAegE,EAAK,QAAQ,2EAA4E/D,EAAW+D,CAAI,CAAC,EAC1LnE,EAAQ,UAAUmE,EAAK,MAAM,GAEjC,IAAK,IAAI6B,EAAQhG,EAAQ,UAAUoE,EAAK,MAAM,EAAG4B,IAAU,IAAA,KAAcL,GAAYC,GAAgBrE,EAAUyE,EAAM,OAAO,IAAM,kBAAoB,EAAQhG,EAAQ,UAAUoE,EAAK,MAAM,EACvLpE,EAAQ,OAAO,gBAAgB,EAC/BA,EAAQ,MAAM2F,GAAWpE,EAAUyE,EAAM,OAAO,IAAM,iBAAmB7F,EAAgB,2BAA6BA,EAAgB,iCAClI,yFAA0FC,EAAW4F,CAAK,CAAC,EAC3GD,EAAO/F,EAASgG,CAAK,EAAGvB,EAAUzE,EAASgG,CAAK,EAC/ChG,EAAQ,UAAUgG,EAAM,MAAM,EAEvC,OAAO/D,CACX,CAEA,SAAS,aAAa,EAA8D,CAChF,IAAMP,EAAQtC,EAAe,KAAK6G,CAAO,EACzC,GAAIvE,IAAU,KACV,MAAO,CAAE,UAAS,QAAS,IAAK,EAEpC,IAAMsD,EAAUtD,EAAM,KAAO,IAAA,GAAuCA,EAAM,GAAjCC,EAAeD,EAAM,EAAE,EAChE,MAAO,CAAE,QAASuE,EAAQ,UAAU,EAAGvE,EAAM,KAAK,CAAC,CAAC,QAAQ,EAAG,SAAQ,CAC3E,CAEA,SAAS,cAAc,EAAwB,EAAkB,EAA6E,CAC1I,IAAMA,EAAQvC,EAAgB,KAAK+G,CAAI,EACvC,GAAIxE,IAAU,KACV,MAAO,CAAE,QAASwE,EAAM,SAAU,OAAQ,EAE9C,IAAMjB,EAAWvF,EAAWgC,EAAM,IAClC,GAAIuD,IAAa,IAAA,GACbjF,EAAQ,MAAMG,EAAgB,0BAA2B,gCAAgCuB,EAAM,GAAG,4CAA6CtB,EAAWH,CAAI,CAAC,OAGnK,MAAO,CAAE,QAASiG,EAAK,UAAU,EAAGxE,EAAM,KAAK,CAAC,CAAC,QAAQ,EAAG,UAAS,CACzE,CAEA,SAAS,UAAU,EAAwB,EAAc,EAA4F,CACjJ,GAAI0C,IAAS,YACT,MAAO,CAAE,KAAM,WAAY,MAAO,IAAK,EAE3C,GAAI7C,EAAU6C,CAAI,IAAM,WAAY,CAChC,IAAM+B,EAAY/B,EAAK,UAAU,CAAiB,CAAC,CAAC,KAAK,EACzD,GAAI+B,IAAc,QAAUA,IAAc,SAAWA,IAAc,QAAS,CACxEnG,EAAQ,MAAMG,EAAgB,0BAA2B,qDAAsDC,EAAWH,CAAI,CAAC,EAC/H,MACJ,CACA,MAAO,CAAE,KAAM,WAAY,MAAO,CAAE,KAAM,0BAA2B,MAAOkG,EAAW,SAAU/F,EAAWH,CAAI,CAAE,CAAE,CACxH,CACA,IAAMmG,EAAU9G,EAAe,KAAK8E,CAAI,EACxC,GAAIgC,IAAY,KAAM,CAClBpG,EAAQ,MAAMG,EAAgB,sBAAuB,4BAA4BF,EAAK,QAAQ,GAAIG,EAAWH,CAAI,CAAC,EAClH,MACJ,CACA,IAAMoG,EAAWD,EAAQ,IAAMA,EAAQ,GACvC,GAAIC,IAAa,OAAQ,CACrB,IAAMnG,EAAOkG,EAAQ,EAAE,CAAC,KAAK,EAC7B,GAAI,CAAC7G,EAAgB,KAAKW,CAAI,EAAG,CAC7BF,EAAQ,MAAMG,EAAgB,gBAAiB,sBAAsBD,EAAK,QAAQD,EAAK,QAAQ,+CAAgDG,EAAWH,CAAI,CAAC,EAC/J,MACJ,CACA,MAAO,CAAE,KAAM,OAAQ,MAAO,CAAE,KAAM,uBAAwB,KAAMC,EAAM,SAAUE,EAAWH,CAAI,CAAE,CAAE,CAC3G,CACA,MAAO,CAAE,KAAMR,EAAa4G,GAAW,MAAOC,EAAmBF,EAAQ,GAAIhG,EAAWH,CAAI,EAAGD,CAAO,CAAE,CAC5G"}
|
|
1
|
+
{"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","calendarPrefix","calendarPattern","stringBodyPattern","severityPattern","messagePattern","rulePattern","operandPattern","ruleNamePattern","optionalReads","operandKinds","severities","opaqueDirectives","propertyShapedDirectives","names","lookahead","ParserContext","context","line","name","DiagnosticCodes","locationOf","properties","responses","identifier","validations","produces","reads","referenceReads","concurrency","description","documentation","authorize","handler","handlers","stream","streamCandidates","calendar","child","keyword","firstWord","asProperty","tryParseProperty","match","unescapeString","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","combineAuthorize","parseAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerContracts","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","file","parseFile","body","rule","isFileDirectiveAmongProperties","next","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","ownerName","checksum","valueContext","withSeverity","validateMatchOperand","matchSubject","wrapped","commandOwner","parseImplementationWrapper","isFile","isCode","extra","content","text","algorithm","operand","operator","parseMappingSource"],"sources":["../../../../../../Compiler/Parsing/CommandParser.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 { validateHandlerContracts } from './CommandHandlerValidator';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { RequirementSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { CommandSyntax, ValidateSyntax, ValidationRuleKind, ValidationRuleSyntax, ValidationSeverity } from '../Syntax/Commands';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { CommandCalendarSyntax } from '../Syntax/Calendar';\nimport { CommandStreamSyntax } from '../Syntax/EventSources';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { CommandResponseSyntax } from '../Syntax/Responses';\nimport { pattern } from '../Text/patterns';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { combineAuthorize, parseAuthorize } from './AuthorizeParser';\nimport { parseCommandResponse, scalarResponsePattern } from './CommandResponseParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { isCode, isFile, parseCode, parseFile, parseHandler, parseImplementationWrapper } from './ImplementationParser';\nimport { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { matchSubject, validateMatchOperand } from './MatchOperandValidation';\nimport { isReactionIdentityLine, misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { commandReadSources } from './CommandReadSources';\nimport { dependencySources, ReadsSyntax, ConcurrencySyntax } from '../Syntax/DependencySources';\nimport { captureConcurrency } from './DependencySourceParser';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { reportInvalidModifierOrder, reportLegacyOptionalSuffix, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst calendarPrefix = pattern('^calendar\\\\s+(?:\"|from\\\\s+\\\\$context\\\\.)');\nconst calendarPattern = pattern(`^calendar\\\\s+(?:\"(${stringBodyPattern})\"|from\\\\s+\\\\$context\\\\.([A-Za-z_][A-Za-z0-9_]*(?:\\\\.[A-Za-z_][A-Za-z0-9_]*)*))$`);\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\\\s*)(.*)$');\nconst ruleNamePattern = sourceStreamPattern('^[A-Za-z_]\\\\w*$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\n// Every operand the pattern matches has a kind, so an operand never goes unrecognized here.\nconst operandKinds: Record<string, ValidationRuleKind> = {\n max: 'Max',\n min: 'Min',\n '>': 'GreaterThan',\n '>=': 'GreaterThanOrEqual',\n '<': 'LessThan',\n '<=': 'LessThanOrEqual',\n '==': 'Equal',\n '!=': 'NotEqual',\n 'length ==': 'Length',\n 'decimals <=': 'DecimalPlaces',\n matches: 'Matches',\n contains: 'Contains',\n 'not contains': 'NotContains',\n 'starts with': 'StartsWith',\n 'ends with': 'EndsWith',\n 'all >': 'AllGreaterThan',\n 'all >=': 'AllGreaterThanOrEqual',\n};\n\nconst severities: Record<string, ValidationSeverity> = { information: 'Information', warning: 'Warning', error: 'Error' };\n\n// Command directives this compiler does not model. They are skipped whole.\nconst opaqueDirectives = new Set(['reads', 'concurrency']);\n\n// The bare directives cannot take a type reference, so a line with property shape is a property whatever\n// keyword it starts with - 'description String' declares a property called description.\nconst propertyShapedDirectives = new Set(['description', 'documentation', 'handler', 'concurrency']);\n\nexport function parseCommand(context: ParserContext, line: SourceLine): CommandSyntax {\n // Properties are leaves, not indentation owners. Resolve ambiguous returns spelling\n // before the committed pass decides whether its deeper lines belong to a response.\n const names = new Set<string>();\n const lookahead = new ParserContext(context.reader.fork(), context.path, context.languages);\n lookahead.sourceOptions = context.sourceOptions;\n lookahead.streamCandidates = context.streamCandidates;\n parseCommandBody(lookahead, line, undefined, names);\n return parseCommandBody(context, line, names);\n}\n\nfunction parseCommandBody(context: ParserContext, line: SourceLine, responseNames?: ReadonlySet<string>, discoveredNames?: Set<string>): CommandSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidCommandDeclaration, `Invalid command declaration '${line.content}' - expected 'command <Name>'`, locationOf(line));\n }\n const properties: PropertySyntax[] = [];\n const responses: { line: SourceLine; candidate: PropertySyntax | null; response: CommandResponseSyntax | null }[] = [];\n let identifier: PropertySyntax | undefined;\n const validations: ValidateSyntax[] = [];\n const produces: ProducesSyntax[] = [];\n const reads: { readModel: string; alias: string | null }[] = [];\n const referenceReads: ReadsSyntax[] = [];\n let concurrency: ConcurrencySyntax | undefined;\n let description: string | null = null;\n let documentation: string | null = null;\n let authorize: AuthorizeSyntax | null = null;\n let handler: HandlerSyntax | null = null;\n const handlers: { handler: HandlerSyntax | null; location: SourceLocation }[] = [];\n let stream: CommandStreamSyntax | null = null;\n const streamCandidates: CommandStreamSyntax[] = [];\n let calendar: CommandCalendarSyntax | 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 const asProperty = tryParseProperty(child);\n if (keyword === 'calendar' && calendarPrefix.test(child.content)) {\n const match = calendarPattern.exec(child.content);\n if (calendar !== null || match === null) {\n context.error(DiagnosticCodes.InvalidCommandCalendar, 'A command declares at most one \\'calendar \"<id>\"\\' or \\'calendar from $context.<member>\\'.', locationOf(child));\n } else {\n calendar = { kind: 'CommandCalendarSyntax', id: match[1] === undefined ? null : unescapeString(match[1]), contextMember: match[2] ?? null, location: locationOf(child) };\n }\n } else if (asProperty !== undefined && (propertyShapedDirectives.has(keyword) || (keyword === 'validate' && child.content !== 'validate csharp'))) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (keyword === 'returns') {\n const scalar = scalarResponsePattern.exec(child.content);\n if (scalar !== null && !scalar[1].startsWith('@') && asProperty !== undefined) {\n if (responseNames === undefined) {\n properties.push(asProperty);\n responses.push({ line: child, candidate: asProperty, response: null });\n } else if (responseNames.has(asProperty.type.name)) {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n } else {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n }\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (reportInvalidModifierOrder(context, child)) {\n context.skipBlock(child.indent);\n } else {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n }\n } else if (keyword === 'stream' && routeHeader.test(child.content) && asProperty !== undefined && context.streamCandidates?.hasSource(asProperty.type.name.split('.')[0]) === true) {\n const [source, streamName] = asProperty.type.name.split('.');\n const ambiguous = context.streamCandidates.hasPropertyType(asProperty.type.name) && context.streamCandidates.hasUniqueStream(source, streamName);\n const route = parseCommandStream(context, child, asProperty, ambiguous);\n if (stream !== null || streamCandidates.length > 0) context.error(DiagnosticCodes.InvalidCommandStream, 'A command declares at most one stream route.', locationOf(child));\n if (ambiguous || stream !== null) streamCandidates.push(route);\n else stream = route;\n } else if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Command '${name}'`);\n } else if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Command '${name}'`);\n } else if (keyword === 'authorize') {\n authorize = combineAuthorize(authorize, parseAuthorize(context, child));\n } else if (keyword === 'validate') {\n const validate = parseValidate(context, child, 'command', name);\n if (validate !== undefined) {\n validations.push(validate);\n }\n } else if (keyword === 'produces') {\n const production = parseProduces(context, child, true);\n if (production !== undefined) produces.push(production);\n } else if (keyword === 'handler') {\n handler = parseHandler(context, child);\n handlers.push({ handler, location: locationOf(child) });\n } else if (opaqueDirectives.has(keyword)) {\n const reference = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (reference !== undefined) referenceReads.push(reference);\n if (keyword === 'concurrency' && concurrency === undefined) concurrency = captureConcurrency(context, child);\n const read = /^reads\\s+([A-Z]\\w*)(?:\\s+as\\s+([a-z_]\\w*))?(?:\\s+by\\s+([a-z_]\\w*))?$/.exec(child.content);\n if (read !== null) reads.push({ readModel: read[1], alias: read[2] ?? null });\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n context.skipOpaqueBlock(child.indent);\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else {\n reportInvalidModifierOrder(context, child);\n context.error(DiagnosticCodes.UnknownCommandDirective, `Unexpected '${child.content}' in command body`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const candidates = new Set(responses.flatMap(entry => entry.candidate === null ? [] : [entry.candidate]));\n const names = new Set(properties.filter(property => !candidates.has(property)).map(property => property.name));\n if (responses.some(entry => entry.candidate !== null && !names.has(entry.candidate.type.name) && entry.candidate.type.name !== 'returns')) names.add('returns');\n for (const name of names) discoveredNames?.add(name);\n let response: CommandResponseSyntax | null = null;\n const removed = new Set<PropertySyntax>();\n for (const entry of responses) {\n let parsed = entry.response;\n if (entry.candidate !== null) {\n if (!names.has(entry.candidate.type.name)) continue;\n removed.add(entry.candidate);\n parsed = { kind: 'ScalarCommandResponseSyntax', source: { kind: 'PropertyResponseSourceSyntax', property: entry.candidate.type.name, location: entry.candidate.type.location }, location: locationOf(entry.line) };\n }\n if (parsed === null) continue;\n if (response !== null) {\n context.error(DiagnosticCodes.InvalidCommandResponse, 'A command declares at most one unconditional response.', locationOf(entry.line));\n } else {\n response = parsed;\n }\n }\n validateHandlerContracts(handlers, handler, produces.length > 0, context);\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, ...(calendar === null ? {} : { calendar }), location: locationOf(line) };\n commandReadSources.set(syntax, reads);\n dependencySources.set(syntax, { reads: referenceReads, concurrency });\n return syntax;\n}\n\nfunction addProperty(context: ParserContext, properties: PropertySyntax[], property: PropertySyntax, commandName: string, line: SourceLine, identifier: PropertySyntax | undefined): PropertySyntax | undefined {\n reportLegacyOptionalSuffix(context, property.type, line);\n if (property.isIdentifier && identifier !== undefined) {\n context.error(DiagnosticCodes.DuplicateCommandIdentifier, `Command '${commandName}' already marks '${identifier.name}' as identifier - only one property can be the identifier`, property.location);\n property = { ...property, isIdentifier: false };\n }\n properties.push(property);\n return identifier ?? (property.isIdentifier ? property : undefined);\n}\n\nfunction parseValidationFile(context: ParserContext, header: SourceLine, body: SourceLine): ValidateSyntax | undefined {\n const file = parseFile(context, body);\n return file === undefined ? undefined : { kind: 'FileValidateSyntax', file, location: locationOf(header) };\n}\n\nfunction hasValidationOperand(line: SourceLine): boolean {\n const match = rulePattern.exec(line.content);\n if (match === null) return false;\n const rule = match[2];\n return (firstWord(rule) === 'not' && firstWord(rule.substring('not'.length).trimStart()) === 'empty') ||\n firstWord(rule) === 'checksum' || operandPattern.test(rule);\n}\n\nfunction isValidationFileBody(context: ParserContext, header: SourceLine, body: SourceLine): boolean {\n if (!isFileDirectiveAmongProperties(body) || hasValidationOperand(body)) return false;\n const lookahead = context.reader.fork();\n lookahead.takeSignificant();\n const next = lookahead.peekSignificant();\n return next === undefined || next.indent <= header.indent;\n}\n\n// Reads a 'validate' block: declarative rules, or code - which is recognized but not modeled.\nexport function parseValidate(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidateSyntax | undefined {\n if (line.content === 'validate') {\n const fence = context.peekChild(line.indent);\n if (fence !== undefined && isValidationFileBody(context, line, fence)) {\n context.reader.takeSignificant();\n return parseValidationFile(context, line, fence);\n }\n if (fence !== undefined && fence.content.startsWith('```')) {\n context.reader.takeSignificant();\n const code = parseCode(context.valueContext, fence);\n if (code === null) context.skipFencedBody();\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n const rules: ValidationRuleSyntax[] = [];\n const requirements: RequirementSyntax[] = [];\n let wrapperIndent: number | undefined;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (owner === 'concept') {\n if (context.sourceOptions.numericMode === 'legacy' && child.content.startsWith('```')) { context.skipFencedBody(); continue; }\n if (wrapperIndent !== undefined && child.indent <= wrapperIndent) wrapperIndent = undefined;\n if (wrapperIndent !== undefined || firstWord(child.content) === 'implementation') {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${child.content}'`, locationOf(child));\n wrapperIndent ??= child.indent;\n continue;\n }\n }\n if (firstWord(child.content) === 'require') {\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child));\n let message: string | null = null;\n let severity: ValidationSeverity = 'Error';\n let hasSeverity = false;\n for (let directive = context.peekChild(child.indent); directive !== undefined; directive = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n const matched = messagePattern.exec(directive.content);\n if (matched !== null && matched.index === 0) message = matched[1] !== undefined ? unescapeString(matched[1]) : matched[2];\n else if (firstWord(directive.content) === 'severity') {\n if (!hasSeverity) severity = severities[directive.content.substring('severity'.length).trim()] ?? 'Error';\n hasSeverity = true;\n } else context.skipOpaqueBlock(directive.indent);\n }\n if (condition !== null) requirements.push({ kind: 'RequirementSyntax', condition, message, severity, location: locationOf(child) });\n continue;\n }\n const rule = parseValidationRule(context, owner === 'concept' ? { ...child, content: `value ${child.content}` } : child, owner, ownerName);\n if (rule !== undefined) {\n rules.push(rule);\n }\n }\n return { kind: 'DeclarativeValidateSyntax', rules, requirements, location: locationOf(line) };\n }\n if (owner === 'concept' && firstWord(line.content.substring('validate'.length).trimStart()) === 'checksum') {\n const ruleLine = { ...line, content: `value ${line.content.substring('validate'.length).trimStart()}` };\n const rule = parseValidationRule(context, ruleLine, owner, ownerName);\n return rule === undefined ? undefined : { kind: 'DeclarativeValidateSyntax', rules: [rule], requirements: [], location: locationOf(line) };\n }\n if (line.content === 'validate csharp') {\n const code = parseCode(context.valueContext, { ...line, content: 'csharp' });\n if (code === null) context.skipOpaqueBlock(line.indent);\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n context.error(DiagnosticCodes.InvalidValidateDeclaration, `Invalid validate declaration '${line.content}' - expected 'validate' or 'validate csharp'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n}\n\nfunction parseValidationRule(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidationRuleSyntax | undefined {\n // Checksum is a new declaration, not enrichment of a formerly opaque Legacy rule.\n const checksum = firstWord(rulePattern.exec(line.content)?.[2] ?? '') === 'checksum';\n const valueContext = owner === 'concept' && !checksum ? context.valueContext : context;\n const { content: withSeverity, message } = splitMessage(line.content);\n const severity = splitSeverity(valueContext, line, withSeverity);\n if (severity === undefined) {\n return undefined;\n }\n const match = rulePattern.exec(severity.content);\n if (match === null) {\n valueContext.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const parsed = parseRule(valueContext, match[2], line);\n if (parsed === undefined) {\n return undefined;\n }\n if (parsed.kind === 'Matches' && parsed.value !== null) validateMatchOperand(context, parsed.value, locationOf(line), line.raw, matchSubject(context, owner, ownerName, match[1]));\n const source = parsed.kind === 'Rule' ? parseRuleImplementation(context, line, owner === 'command') : { file: null, code: null, implementation: null };\n return {\n kind: 'ValidationRuleSyntax',\n property: match[1],\n rule: parsed.kind,\n value: parsed.value,\n message,\n severity: severity.severity,\n ...source,\n location: locationOf(line),\n };\n}\n\nfunction parseRuleImplementation(context: ParserContext, rule: SourceLine, commandOwner: boolean): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax | null } {\n const body = context.peekChild(rule.indent);\n if (body === undefined) return { file: null, code: null, implementation: null };\n context.reader.takeSignificant();\n const wrapped = commandOwner && firstWord(body.content) === 'implementation';\n const source = wrapped ? parseImplementationWrapper(context, body) : {\n file: isFile(body) ? parseFile(context, body) : null,\n code: !isFile(body) && isCode(context, body) ? parseCode(context, body) : null,\n implementation: null,\n };\n if (!wrapped && source.file === null && source.code === null) {\n context.error(DiagnosticCodes.UnknownRuleImplementationDirective, `Unexpected '${body.content}' in rule implementation - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(body.indent);\n }\n for (let extra = context.peekChild(rule.indent); extra !== undefined && (wrapped || (commandOwner && firstWord(extra.content) === 'implementation')); extra = context.peekChild(rule.indent)) {\n context.reader.takeSignificant();\n context.error(wrapped && firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A named rule has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return source;\n}\n\nfunction splitMessage(content: string): { content: string; message: string | null } {\n const match = messagePattern.exec(content);\n if (match === null) {\n return { content, message: null };\n }\n const message = match[1] !== undefined ? unescapeString(match[1]) : match[2];\n return { content: content.substring(0, match.index).trimEnd(), message };\n}\n\nfunction splitSeverity(context: ParserContext, line: SourceLine, text: string): { content: string; severity: ValidationSeverity } | undefined {\n const match = severityPattern.exec(text);\n if (match === null) {\n return { content: text, severity: 'Error' };\n }\n const severity = severities[match[1]];\n if (severity === undefined) {\n context.error(DiagnosticCodes.InvalidValidationSeverity, `Unknown validation severity '${match[1]}' - expected information, warning or error`, locationOf(line));\n return undefined;\n }\n return { content: text.substring(0, match.index).trimEnd(), severity };\n}\n\nfunction parseRule(context: ParserContext, rule: string, line: SourceLine): { kind: ValidationRuleKind; value: ExpressionSyntax | null } | undefined {\n if (rule === 'not empty') {\n return { kind: 'NotEmpty', value: null };\n }\n if (firstWord(rule) === 'checksum') {\n const algorithm = rule.substring('checksum'.length).trim();\n if (algorithm !== 'luhn' && algorithm !== 'mod11' && algorithm !== 'mod97') {\n context.error(DiagnosticCodes.InvalidGenerationArgument, 'Checksum validation requires luhn, mod11 or mod97.', locationOf(line));\n return undefined;\n }\n return { kind: 'Checksum', value: { kind: 'LiteralExpressionSyntax', value: algorithm, location: locationOf(line) } };\n }\n const operand = operandPattern.exec(rule);\n if (operand === null) {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const operator = operand[1] ?? operand[2];\n if (operator === 'rule') {\n const name = operand[3].trim();\n if (!ruleNamePattern.test(name)) {\n context.error(DiagnosticCodes.InvalidRuleName, `Invalid rule name '${name}' in '${line.content}' - expected 'rule <Name>' with an identifier`, locationOf(line));\n return undefined;\n }\n return { kind: 'Rule', value: { kind: 'PathExpressionSyntax', path: name, location: locationOf(line) } };\n }\n return { kind: operandKinds[operator], value: parseMappingSource(operand[3], locationOf(line), context) };\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{unescapeString as t}from"../Text/StringLiteral.js";import{locationOf as n}from"./SourceLine.js";import{firstWord as r}from"./LineText.js";import{isBlankImplementationHint as i}from"../Text/ImplementationHintText.js";const
|
|
2
|
-
`),location:n(r)}}function parseHandler(t,i){let a=t.peekChild(i.indent);if(a===void 0)return t.error(e.HandlerWithoutImplementation,`Expected a 'file' directive or an inline code block in the handler`,n(i)),null;if(t.reader.takeSignificant(),r(a.content)===`implementation`)return parseImplementation(t,i,a);let o=isFile(a)?parseFile(t,a):null,s=o===null&&isCode(t,a)?parseCode(t,a):null;if(o!==null||s!==null){let a=t.peekChild(i.indent);return a!==void 0&&r(a.content)===`implementation`&&(t.error(e.ConflictingImplementationSources,`A handler cannot mix wrapped and direct sources.`,n(a)),t.skipBlock(i.indent)),{kind:`HandlerSyntax`,file:o,code:s,implementation:null,location:n(i)}}return t.error(e.UnknownHandlerDirective,`Unexpected '${a.content}' in handler - expected 'file <path>' or an inline code block`,n(a)),t.skipBlock(i.indent),null}function parseImplementation(t,i,a){let o=parseImplementationWrapper(t,a);for(let a=t.peekChild(i.indent);a!==void 0;a=t.peekChild(i.indent))t.reader.takeSignificant(),t.error(r(a.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A handler has one implementation wrapper and cannot mix wrapped and direct sources.`,n(a)),isCode(t,a)?parseCode(t,a):t.skipBlock(a.indent);return{kind:`HandlerSyntax`,...o,location:n(i)}}function parseImplementationWrapper(
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{unescapeString as t}from"../Text/StringLiteral.js";import{locationOf as n}from"./SourceLine.js";import{firstWord as r}from"./LineText.js";import{isBlankImplementationHint as i}from"../Text/ImplementationHintText.js";import{parsePossibleEvents as a}from"./PossibleEventsParser.js";const o=/* @__PURE__ */ RegExp(`^hint[\\u0009-\\u000d\\u0020\\u0085\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]+"((?:[^"\\\\\\r\\n]|\\\\[^\\r\\n])*)"$`),isFile=e=>r(e.content)===`file`&&e.content.substring(4).trim().length>0,isCode=(e,t)=>t.content.startsWith("```")||e.languages.has(t.content);function parseFile(t,r){let i=r.content.substring(4).trim();return/^(?:[/\\]|[A-Za-z]:[/\\]|~[/\\])/.test(i)&&t.warning(e.AbsoluteFileReference,`'${i}' is an absolute path - a file reference is relative to the repository root, so it means the same thing on every machine`,n(r)),{kind:`FileReferenceSyntax`,path:i,location:n(r)}}const isClosingCodeFence=e=>e.raw.trim()==="```";function parseCode(t,r){let i=r.content.startsWith("```")?r.content.substring(3):r.content;if(!t.languages.has(i))return t.error(e.ExpectedCodeFence,`Expected a registered language on the opening fence, not '${r.content}'`,n(r)),null;let a=r;if(!r.content.startsWith("```")){t.warning(e.LegacyInlineCodeFence,`'${i}' on its own line is deprecated - use '\`\`\`${i}' instead`,n(r));let o=t.reader.peekSignificant();if(o===void 0||o.indent<=r.indent||o.content!=="```"&&o.content!==`\`\`\`${i}`)return t.error(e.ExpectedCodeFence,`Expected an opening \`\`\`${i} fence after '${i}'`,n(r)),null;a=t.reader.takeSignificant()}let o=[];for(;;){let r=t.reader.takeRaw();if(r===void 0){t.error(e.UnclosedCodeBlock,"Unclosed inline code block - expected a closing ``` line",n(a));break}if(isClosingCodeFence(r))break;let i=0;for(;i<a.indent&&r.raw[i]===` `;)i++;o.push(r.raw.substring(i))}return{kind:`CodeBlockSyntax`,language:i,code:o.join(`
|
|
2
|
+
`),location:n(r)}}function parseHandler(e,t){let n=e.peekChild(t.indent)?.content===`may produce`?a(e,e.reader.takeSignificant()):null,r=parseHandlerBody(e,t);return r===null||n===null?r:{...r,possibleEvents:n}}function parseHandlerBody(t,i){let a=t.peekChild(i.indent);if(a===void 0)return t.error(e.HandlerWithoutImplementation,`Expected a 'file' directive or an inline code block in the handler`,n(i)),null;if(t.reader.takeSignificant(),r(a.content)===`implementation`)return parseImplementation(t,i,a);let o=isFile(a)?parseFile(t,a):null,s=o===null&&isCode(t,a)?parseCode(t,a):null;if(o!==null||s!==null){let a=t.peekChild(i.indent);return a!==void 0&&r(a.content)===`implementation`&&(t.error(e.ConflictingImplementationSources,`A handler cannot mix wrapped and direct sources.`,n(a)),t.skipBlock(i.indent)),{kind:`HandlerSyntax`,file:o,code:s,implementation:null,location:n(i)}}return t.error(e.UnknownHandlerDirective,`Unexpected '${a.content}' in handler - expected 'file <path>' or an inline code block`,n(a)),t.skipBlock(i.indent),null}function parseImplementation(t,i,a){let o=parseImplementationWrapper(t,a);for(let a=t.peekChild(i.indent);a!==void 0;a=t.peekChild(i.indent))t.reader.takeSignificant(),t.error(r(a.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A handler has one implementation wrapper and cannot mix wrapped and direct sources.`,n(a)),isCode(t,a)?parseCode(t,a):t.skipBlock(a.indent);return{kind:`HandlerSyntax`,...o,location:n(i)}}function parseImplementationWrapper(a,s){let c=[],l=null,u=null,d=!1;s.content!==`implementation`&&a.error(e.InvalidImplementationBlock,`Expected 'implementation' with no operand.`,n(s));for(let f=a.peekChild(s.indent);f!==void 0;f=a.peekChild(s.indent))if(a.reader.takeSignificant(),r(f.content)===`hint`||o.test(f.content)){let r=o.exec(f.content),s=r===null?null:t(r[1]);i(s)?a.error(e.InvalidImplementationHint,`Expected 'hint' followed by one nonblank quoted string.`,n(f)):c.push({kind:`ImplementationHintSyntax`,text:s,location:n(f)});let l=a.peekChild(f.indent);l!==void 0&&(a.error(e.InvalidImplementationHint,`A hint cannot have children.`,n(l)),a.skipBlock(f.indent))}else if(isFile(f)||f.content.startsWith("```")){d&&a.error(e.ConflictingImplementationSources,`An implementation has at most one file or inline payload.`,n(f));let t=isFile(f)?parseFile(a,f):null,r=t===null?parseCode(a,f):null;d||(l=t,u=r),d=!0;let i=a.peekChild(f.indent);t!==null&&i!==void 0&&(a.error(e.InvalidImplementationBlock,`A file directive cannot have children.`,n(i)),a.skipBlock(f.indent))}else a.error(e.InvalidImplementationBlock,`Unexpected '${f.content}' in implementation - expected hint, file or a tagged fence.`,n(f)),a.skipBlock(f.indent);return{file:l,code:u,implementation:{kind:`ImplementationSyntax`,hints:c,location:n(s)}}}export{isClosingCodeFence,isCode,isFile,parseCode,parseFile,parseHandler,parseImplementationWrapper};
|
|
3
3
|
//# sourceMappingURL=ImplementationParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImplementationParser.js","names":["hintPattern","firstWord","line","context","path","DiagnosticCodes","locationOf","language","tag","open","next","lines","strip","body","handler","file","code","extra","source","wrapper","hints","hasPayload","child","match","text","unescapeString","isBlankImplementationHint","nested","parsedFile","parsedCode"],"sources":["../../../../../../Compiler/Parsing/ImplementationParser.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 { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationHintSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { isBlankImplementationHint } from '../Text/ImplementationHintText';\nimport { unescapeString } from '../Text/StringLiteral';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\n// Match ImplementationHintText's White_Space set, not ECMAScript \\s. A hint stays on one CR/LF-delimited source line.\n// eslint-disable-next-line no-control-regex -- The shared whitespace set deliberately includes U+0009 through U+000D.\nconst hintPattern = new RegExp('^hint[\\\\u0009-\\\\u000d\\\\u0020\\\\u0085\\\\u00a0\\\\u1680\\\\u2000-\\\\u200a\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000]+\"((?:[^\"\\\\\\\\\\\\r\\\\n]|\\\\\\\\[^\\\\r\\\\n])*)\"$');\nexport const isFile = (line: SourceLine): boolean => firstWord(line.content) === 'file' && line.content.substring(4).trim().length > 0;\nexport const isCode = (context: ParserContext, line: SourceLine): boolean => line.content.startsWith('```') || context.languages.has(line.content);\n\nexport function parseFile(context: ParserContext, line: SourceLine): FileReferenceSyntax {\n const path = line.content.substring(4).trim();\n if (/^(?:[/\\\\]|[A-Za-z]:[/\\\\]|~[/\\\\])/.test(path)) {\n context.warning(DiagnosticCodes.AbsoluteFileReference, `'${path}' is an absolute path - a file reference is relative to the repository root, so it means the same thing on every machine`, locationOf(line));\n }\n return { kind: 'FileReferenceSyntax', path, location: locationOf(line) };\n}\n\nexport const isClosingCodeFence = (line: SourceLine): boolean => line.raw.trim() === '```';\n\nexport function parseCode(context: ParserContext, tag: SourceLine): CodeBlockSyntax | null {\n const language = tag.content.startsWith('```') ? tag.content.substring(3) : tag.content;\n if (!context.languages.has(language)) {\n context.error(DiagnosticCodes.ExpectedCodeFence, `Expected a registered language on the opening fence, not '${tag.content}'`, locationOf(tag));\n return null;\n }\n let open = tag;\n if (!tag.content.startsWith('```')) {\n context.warning(DiagnosticCodes.LegacyInlineCodeFence, `'${language}' on its own line is deprecated - use '\\`\\`\\`${language}' instead`, locationOf(tag));\n const next = context.reader.peekSignificant();\n if (next === undefined || next.indent <= tag.indent || (next.content !== '```' && next.content !== `\\`\\`\\`${language}`)) {\n context.error(DiagnosticCodes.ExpectedCodeFence, `Expected an opening \\`\\`\\`${language} fence after '${language}'`, locationOf(tag));\n return null;\n }\n open = context.reader.takeSignificant();\n }\n const lines: string[] = [];\n for (;;) {\n const line = context.reader.takeRaw();\n if (line === undefined) {\n context.error(DiagnosticCodes.UnclosedCodeBlock, 'Unclosed inline code block - expected a closing ``` line', locationOf(open));\n break;\n }\n if (isClosingCodeFence(line)) break;\n let strip = 0;\n while (strip < open.indent && line.raw[strip] === ' ') strip++;\n lines.push(line.raw.substring(strip));\n }\n return { kind: 'CodeBlockSyntax', language, code: lines.join('\\n'), location: locationOf(tag) };\n}\n\nexport function parseHandler(context: ParserContext, handler: SourceLine): HandlerSyntax | null {\n const body = context.peekChild(handler.indent);\n if (body === undefined) {\n context.error(DiagnosticCodes.HandlerWithoutImplementation, \"Expected a 'file' directive or an inline code block in the handler\", locationOf(handler));\n return null;\n }\n context.reader.takeSignificant();\n if (firstWord(body.content) === 'implementation') return parseImplementation(context, handler, body);\n const file = isFile(body) ? parseFile(context, body) : null;\n const code = file === null && isCode(context, body) ? parseCode(context, body) : null;\n if (file !== null || code !== null) {\n const extra = context.peekChild(handler.indent);\n if (extra !== undefined && firstWord(extra.content) === 'implementation') {\n context.error(DiagnosticCodes.ConflictingImplementationSources, 'A handler cannot mix wrapped and direct sources.', locationOf(extra));\n context.skipBlock(handler.indent);\n }\n return { kind: 'HandlerSyntax', file, code, implementation: null, location: locationOf(handler) };\n }\n context.error(DiagnosticCodes.UnknownHandlerDirective, `Unexpected '${body.content}' in handler - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(handler.indent);\n return null;\n}\n\nfunction parseImplementation(context: ParserContext, handler: SourceLine, wrapper: SourceLine): HandlerSyntax {\n const source = parseImplementationWrapper(context, wrapper);\n for (let extra = context.peekChild(handler.indent); extra !== undefined; extra = context.peekChild(handler.indent)) {\n context.reader.takeSignificant();\n context.error(firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A handler has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return { kind: 'HandlerSyntax', ...source, location: locationOf(handler) };\n}\n\nexport function parseImplementationWrapper(context: ParserContext, wrapper: SourceLine): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax } {\n const hints: ImplementationHintSyntax[] = [];\n let file: FileReferenceSyntax | null = null;\n let code: CodeBlockSyntax | null = null;\n let hasPayload = false;\n if (wrapper.content !== 'implementation') context.error(DiagnosticCodes.InvalidImplementationBlock, \"Expected 'implementation' with no operand.\", locationOf(wrapper));\n for (let child = context.peekChild(wrapper.indent); child !== undefined; child = context.peekChild(wrapper.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'hint' || hintPattern.test(child.content)) {\n const match = hintPattern.exec(child.content);\n const text = match === null ? null : unescapeString(match[1]);\n if (isBlankImplementationHint(text)) context.error(DiagnosticCodes.InvalidImplementationHint, \"Expected 'hint' followed by one nonblank quoted string.\", locationOf(child));\n else hints.push({ kind: 'ImplementationHintSyntax', text: text!, location: locationOf(child) });\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidImplementationHint, 'A hint cannot have children.', locationOf(nested));\n context.skipBlock(child.indent);\n }\n } else if (isFile(child) || child.content.startsWith('```')) {\n if (hasPayload) context.error(DiagnosticCodes.ConflictingImplementationSources, 'An implementation has at most one file or inline payload.', locationOf(child));\n const parsedFile = isFile(child) ? parseFile(context, child) : null;\n const parsedCode = parsedFile === null ? parseCode(context, child) : null;\n if (!hasPayload) { file = parsedFile; code = parsedCode; }\n hasPayload = true;\n const nested = context.peekChild(child.indent);\n if (parsedFile !== null && nested !== undefined) {\n context.error(DiagnosticCodes.InvalidImplementationBlock, 'A file directive cannot have children.', locationOf(nested));\n context.skipBlock(child.indent);\n }\n } else {\n context.error(DiagnosticCodes.InvalidImplementationBlock, `Unexpected '${child.content}' in implementation - expected hint, file or a tagged fence.`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return { file, code, implementation: { kind: 'ImplementationSyntax', hints, location: locationOf(wrapper) } };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ImplementationParser.js","names":["hintPattern","firstWord","line","context","path","DiagnosticCodes","locationOf","language","tag","open","next","lines","strip","possibleEvents","handler","parsePossibleEvents","parsed","body","file","code","extra","source","wrapper","hints","hasPayload","child","match","text","unescapeString","isBlankImplementationHint","nested","parsedFile","parsedCode"],"sources":["../../../../../../Compiler/Parsing/ImplementationParser.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 { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationHintSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { isBlankImplementationHint } from '../Text/ImplementationHintText';\nimport { unescapeString } from '../Text/StringLiteral';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parsePossibleEvents } from './PossibleEventsParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\n// Match ImplementationHintText's White_Space set, not ECMAScript \\s. A hint stays on one CR/LF-delimited source line.\n// eslint-disable-next-line no-control-regex -- The shared whitespace set deliberately includes U+0009 through U+000D.\nconst hintPattern = new RegExp('^hint[\\\\u0009-\\\\u000d\\\\u0020\\\\u0085\\\\u00a0\\\\u1680\\\\u2000-\\\\u200a\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000]+\"((?:[^\"\\\\\\\\\\\\r\\\\n]|\\\\\\\\[^\\\\r\\\\n])*)\"$');\nexport const isFile = (line: SourceLine): boolean => firstWord(line.content) === 'file' && line.content.substring(4).trim().length > 0;\nexport const isCode = (context: ParserContext, line: SourceLine): boolean => line.content.startsWith('```') || context.languages.has(line.content);\n\nexport function parseFile(context: ParserContext, line: SourceLine): FileReferenceSyntax {\n const path = line.content.substring(4).trim();\n if (/^(?:[/\\\\]|[A-Za-z]:[/\\\\]|~[/\\\\])/.test(path)) {\n context.warning(DiagnosticCodes.AbsoluteFileReference, `'${path}' is an absolute path - a file reference is relative to the repository root, so it means the same thing on every machine`, locationOf(line));\n }\n return { kind: 'FileReferenceSyntax', path, location: locationOf(line) };\n}\n\nexport const isClosingCodeFence = (line: SourceLine): boolean => line.raw.trim() === '```';\n\nexport function parseCode(context: ParserContext, tag: SourceLine): CodeBlockSyntax | null {\n const language = tag.content.startsWith('```') ? tag.content.substring(3) : tag.content;\n if (!context.languages.has(language)) {\n context.error(DiagnosticCodes.ExpectedCodeFence, `Expected a registered language on the opening fence, not '${tag.content}'`, locationOf(tag));\n return null;\n }\n let open = tag;\n if (!tag.content.startsWith('```')) {\n context.warning(DiagnosticCodes.LegacyInlineCodeFence, `'${language}' on its own line is deprecated - use '\\`\\`\\`${language}' instead`, locationOf(tag));\n const next = context.reader.peekSignificant();\n if (next === undefined || next.indent <= tag.indent || (next.content !== '```' && next.content !== `\\`\\`\\`${language}`)) {\n context.error(DiagnosticCodes.ExpectedCodeFence, `Expected an opening \\`\\`\\`${language} fence after '${language}'`, locationOf(tag));\n return null;\n }\n open = context.reader.takeSignificant();\n }\n const lines: string[] = [];\n for (;;) {\n const line = context.reader.takeRaw();\n if (line === undefined) {\n context.error(DiagnosticCodes.UnclosedCodeBlock, 'Unclosed inline code block - expected a closing ``` line', locationOf(open));\n break;\n }\n if (isClosingCodeFence(line)) break;\n let strip = 0;\n while (strip < open.indent && line.raw[strip] === ' ') strip++;\n lines.push(line.raw.substring(strip));\n }\n return { kind: 'CodeBlockSyntax', language, code: lines.join('\\n'), location: locationOf(tag) };\n}\n\nexport function parseHandler(context: ParserContext, handler: SourceLine): HandlerSyntax | null {\n const first = context.peekChild(handler.indent);\n const possibleEvents = first?.content === 'may produce' ? parsePossibleEvents(context, context.reader.takeSignificant()!) : null;\n const parsed = parseHandlerBody(context, handler);\n return parsed === null || possibleEvents === null ? parsed : { ...parsed, possibleEvents };\n}\n\nfunction parseHandlerBody(context: ParserContext, handler: SourceLine): HandlerSyntax | null {\n const body = context.peekChild(handler.indent);\n if (body === undefined) {\n context.error(DiagnosticCodes.HandlerWithoutImplementation, \"Expected a 'file' directive or an inline code block in the handler\", locationOf(handler));\n return null;\n }\n context.reader.takeSignificant();\n if (firstWord(body.content) === 'implementation') return parseImplementation(context, handler, body);\n const file = isFile(body) ? parseFile(context, body) : null;\n const code = file === null && isCode(context, body) ? parseCode(context, body) : null;\n if (file !== null || code !== null) {\n const extra = context.peekChild(handler.indent);\n if (extra !== undefined && firstWord(extra.content) === 'implementation') {\n context.error(DiagnosticCodes.ConflictingImplementationSources, 'A handler cannot mix wrapped and direct sources.', locationOf(extra));\n context.skipBlock(handler.indent);\n }\n return { kind: 'HandlerSyntax', file, code, implementation: null, location: locationOf(handler) };\n }\n context.error(DiagnosticCodes.UnknownHandlerDirective, `Unexpected '${body.content}' in handler - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(handler.indent);\n return null;\n}\n\nfunction parseImplementation(context: ParserContext, handler: SourceLine, wrapper: SourceLine): HandlerSyntax {\n const source = parseImplementationWrapper(context, wrapper);\n for (let extra = context.peekChild(handler.indent); extra !== undefined; extra = context.peekChild(handler.indent)) {\n context.reader.takeSignificant();\n context.error(firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A handler has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return { kind: 'HandlerSyntax', ...source, location: locationOf(handler) };\n}\n\nexport function parseImplementationWrapper(context: ParserContext, wrapper: SourceLine): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax } {\n const hints: ImplementationHintSyntax[] = [];\n let file: FileReferenceSyntax | null = null;\n let code: CodeBlockSyntax | null = null;\n let hasPayload = false;\n if (wrapper.content !== 'implementation') context.error(DiagnosticCodes.InvalidImplementationBlock, \"Expected 'implementation' with no operand.\", locationOf(wrapper));\n for (let child = context.peekChild(wrapper.indent); child !== undefined; child = context.peekChild(wrapper.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'hint' || hintPattern.test(child.content)) {\n const match = hintPattern.exec(child.content);\n const text = match === null ? null : unescapeString(match[1]);\n if (isBlankImplementationHint(text)) context.error(DiagnosticCodes.InvalidImplementationHint, \"Expected 'hint' followed by one nonblank quoted string.\", locationOf(child));\n else hints.push({ kind: 'ImplementationHintSyntax', text: text!, location: locationOf(child) });\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidImplementationHint, 'A hint cannot have children.', locationOf(nested));\n context.skipBlock(child.indent);\n }\n } else if (isFile(child) || child.content.startsWith('```')) {\n if (hasPayload) context.error(DiagnosticCodes.ConflictingImplementationSources, 'An implementation has at most one file or inline payload.', locationOf(child));\n const parsedFile = isFile(child) ? parseFile(context, child) : null;\n const parsedCode = parsedFile === null ? parseCode(context, child) : null;\n if (!hasPayload) { file = parsedFile; code = parsedCode; }\n hasPayload = true;\n const nested = context.peekChild(child.indent);\n if (parsedFile !== null && nested !== undefined) {\n context.error(DiagnosticCodes.InvalidImplementationBlock, 'A file directive cannot have children.', locationOf(nested));\n context.skipBlock(child.indent);\n }\n } else {\n context.error(DiagnosticCodes.InvalidImplementationBlock, `Unexpected '${child.content}' in implementation - expected hint, file or a tagged fence.`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return { file, code, implementation: { kind: 'ImplementationSyntax', hints, location: locationOf(wrapper) } };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{locationOf as t}from"./SourceLine.js";import{firstWord as n}from"./LineText.js";import{parseCommandStream as r}from"./EventSourceParser.js";import{parseTag as i}from"./DeclarationParsers.js";function parsePossibleEvents(n,r){let i=[],a=/* @__PURE__ */ new Set;for(;n.peekChild(r.indent)!==void 0;){let r=n.reader.takeSignificant(),o=/^([A-Z]\w*(?:\.[A-Za-z_]\w*)*)(?:\s+for\s+(?:(one\s+of)\s+)?([A-Za-z_]\w*))?$/.exec(r.content);if(o===null){invalid(n,r);continue}if(a.has(o[1])){n.error(e.InvalidPossibleEventsDeclaration,`Possible event '${o[1]}' is declared more than once; one destination rule is allowed per event type.`,t(r)),n.skipBlock(r.indent);continue}a.add(o[1]);let[s,c]=parseMetadata(n,r);i.push({kind:`PossibleEventSyntax`,event:o[1],property:o[3]??null,oneOf:o[2]!==void 0,stream:s,tags:c,location:t(r)})}return{kind:`PossibleEventsSyntax`,events:i,location:t(r)}}function parseMetadata(e,t){let r=null,i=[];for(;e.peekChild(t.indent)!==void 0;){let t=e.reader.takeSignificant();n(t.content)===`stream`?r=parseRoute(e,t,r):n(t.content)===`tag`?collectTag(e,t,i):invalid(e,t)}return[r,i]}function collectTag(e,t,n){let r=i(e,t,!1);r!==void 0&&n.push(r)}function parseRoute(n,i,a){let o=/^stream\s+([A-Za-z_]\w*\.[A-Za-z_]\w*)$/.exec(i.content);if(a!==null||o===null)return n.error(e.InvalidCommandStream,a===null?`Expected 'stream <Source>.<Stream>'.`:`A production can declare at most one stream route.`,t(i)),n.skipBlock(i.indent),a;let s=t(i),c={kind:`PropertySyntax`,name:`stream`,type:{kind:`TypeRefSyntax`,name:o[1],isCollection:!1,isOptional:!1,location:{...s,column:i.indent+i.content.indexOf(o[1])+1}},isIdentifier:!1,location:s};return r(n,i,c,!1)}function invalid(n,r){n.error(e.InvalidPossibleEventsDeclaration,`Expected an event name, optionally followed by 'for <property>' or 'for one of <collection property>'; entries accept only stream and tag children.`,t(r)),n.skipBlock(r.indent)}export{parsePossibleEvents};
|
|
2
|
+
//# sourceMappingURL=PossibleEventsParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PossibleEventsParser.js","names":["events","names","context","header","line","match","DiagnosticCodes","locationOf","stream","tags","child","firstWord","tag","parseTag","previous","location","candidate","parseCommandStream"],"sources":["../../../../../../Compiler/Parsing/PossibleEventsParser.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 { CommandStreamSyntax } from '../Syntax/CommandStreamSyntax';\nimport { PropertySyntax, TagSyntax } from '../Syntax/Declarations';\nimport { PossibleEventSyntax } from '../Syntax/PossibleEventSyntax';\nimport { PossibleEventsSyntax } from '../Syntax/PossibleEventsSyntax';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ParserContext } from './ParserContext';\nimport { firstWord } from './LineText';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { parseTag } from './DeclarationParsers';\n\nexport function parsePossibleEvents(context: ParserContext, header: SourceLine): PossibleEventsSyntax {\n const events: PossibleEventSyntax[] = [];\n const names = new Set<string>();\n while (context.peekChild(header.indent) !== undefined) {\n const line = context.reader.takeSignificant()!;\n const match = /^([A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*)(?:\\s+for\\s+(?:(one\\s+of)\\s+)?([A-Za-z_]\\w*))?$/.exec(line.content);\n if (match === null) {\n invalid(context, line);\n continue;\n }\n if (names.has(match[1])) {\n context.error(DiagnosticCodes.InvalidPossibleEventsDeclaration, `Possible event '${match[1]}' is declared more than once; one destination rule is allowed per event type.`, locationOf(line));\n context.skipBlock(line.indent);\n continue;\n }\n names.add(match[1]);\n const [stream, tags] = parseMetadata(context, line);\n events.push({ kind: 'PossibleEventSyntax', event: match[1], property: match[3] ?? null, oneOf: match[2] !== undefined, stream, tags, location: locationOf(line) });\n }\n return { kind: 'PossibleEventsSyntax', events, location: locationOf(header) };\n}\n\nfunction parseMetadata(context: ParserContext, line: SourceLine): [CommandStreamSyntax | null, TagSyntax[]] {\n let stream: CommandStreamSyntax | null = null;\n const tags: TagSyntax[] = [];\n while (context.peekChild(line.indent) !== undefined) {\n const child = context.reader.takeSignificant()!;\n if (firstWord(child.content) === 'stream') {\n stream = parseRoute(context, child, stream);\n } else if (firstWord(child.content) === 'tag') {\n collectTag(context, child, tags);\n } else {\n invalid(context, child);\n }\n }\n return [stream, tags];\n}\n\nfunction collectTag(context: ParserContext, line: SourceLine, tags: TagSyntax[]): void {\n const tag = parseTag(context, line, false);\n if (tag !== undefined) tags.push(tag);\n}\n\nfunction parseRoute(context: ParserContext, line: SourceLine, previous: CommandStreamSyntax | null): CommandStreamSyntax | null {\n const match = /^stream\\s+([A-Za-z_]\\w*\\.[A-Za-z_]\\w*)$/.exec(line.content);\n if (previous !== null || match === null) {\n context.error(DiagnosticCodes.InvalidCommandStream, previous !== null ? 'A production can declare at most one stream route.' : \"Expected 'stream <Source>.<Stream>'.\", locationOf(line));\n context.skipBlock(line.indent);\n return previous;\n }\n const location = locationOf(line);\n const candidate: PropertySyntax = { kind: 'PropertySyntax', name: 'stream', type: { kind: 'TypeRefSyntax', name: match[1], isCollection: false, isOptional: false, location: { ...location, column: line.indent + line.content.indexOf(match[1]) + 1 } }, isIdentifier: false, location };\n return parseCommandStream(context, line, candidate, false);\n}\n\nfunction invalid(context: ParserContext, line: SourceLine): void {\n context.error(DiagnosticCodes.InvalidPossibleEventsDeclaration, \"Expected an event name, optionally followed by 'for <property>' or 'for one of <collection property>'; entries accept only stream and tag children.\", locationOf(line));\n context.skipBlock(line.indent);\n}\n"],"mappings":"+TAcA,SAAgB,oBAAoB,EAAwB,EAA0C,CAClG,IAAMA,EAAgC,CAAC,EACjCC,kBAAQ,IAAI,IAClB,KAAOC,EAAQ,UAAUC,EAAO,MAAM,IAAM,IAAA,IAAW,CACnD,IAAMC,EAAOF,EAAQ,OAAO,gBAAgB,EACtCG,EAAQ,gFAAgF,KAAKD,EAAK,OAAO,EAC/G,GAAIC,IAAU,KAAM,CAChB,QAAQH,EAASE,CAAI,EACrB,QACJ,CACA,GAAIH,EAAM,IAAII,EAAM,EAAE,EAAG,CACrBH,EAAQ,MAAMI,EAAgB,iCAAkC,mBAAmBD,EAAM,GAAG,+EAAgFE,EAAWH,CAAI,CAAC,EAC5LF,EAAQ,UAAUE,EAAK,MAAM,EAC7B,QACJ,CACAH,EAAM,IAAII,EAAM,EAAE,EAClB,GAAM,CAACG,EAAQC,GAAQ,cAAcP,EAASE,CAAI,EAClDJ,EAAO,KAAK,CAAE,KAAM,sBAAuB,MAAOK,EAAM,GAAI,SAAUA,EAAM,IAAM,KAAM,MAAOA,EAAM,KAAO,IAAA,GAAW,SAAQ,OAAM,SAAUE,EAAWH,CAAI,CAAE,CAAC,CACrK,CACA,MAAO,CAAE,KAAM,uBAAwB,SAAQ,SAAUG,EAAWJ,CAAM,CAAE,CAChF,CAEA,SAAS,cAAc,EAAwB,EAA6D,CACxG,IAAIK,EAAqC,KACnCC,EAAoB,CAAC,EAC3B,KAAOP,EAAQ,UAAUE,EAAK,MAAM,IAAM,IAAA,IAAW,CACjD,IAAMM,EAAQR,EAAQ,OAAO,gBAAgB,EACzCS,EAAUD,EAAM,OAAO,IAAM,SAC7B,EAAS,WAAWR,EAASQ,EAAOF,CAAM,EACnCG,EAAUD,EAAM,OAAO,IAAM,MACpC,WAAWR,EAASQ,EAAOD,CAAI,EAE/B,QAAQP,EAASQ,CAAK,CAE9B,CACA,MAAO,CAACF,EAAQC,CAAI,CACxB,CAEA,SAAS,WAAW,EAAwB,EAAkB,EAAyB,CACnF,IAAMG,EAAMC,EAASX,EAASE,EAAM,EAAK,EACrCQ,IAAQ,IAAA,IAAWH,EAAK,KAAKG,CAAG,CACxC,CAEA,SAAS,WAAW,EAAwB,EAAkB,EAAkE,CAC5H,IAAMP,EAAQ,0CAA0C,KAAKD,EAAK,OAAO,EACzE,GAAIU,IAAa,MAAQT,IAAU,KAG/B,OAFAH,EAAQ,MAAMI,EAAgB,qBAAsBQ,IAAa,KAA8D,uCAAvD,qDAA+FP,EAAWH,CAAI,CAAC,EACvLF,EAAQ,UAAUE,EAAK,MAAM,EACtBU,EAEX,IAAMC,EAAWR,EAAWH,CAAI,EAC1BY,EAA4B,CAAE,KAAM,iBAAkB,KAAM,SAAU,KAAM,CAAE,KAAM,gBAAiB,KAAMX,EAAM,GAAI,aAAc,GAAO,WAAY,GAAO,SAAU,CAAE,GAAGU,EAAU,OAAQX,EAAK,OAASA,EAAK,QAAQ,QAAQC,EAAM,EAAE,EAAI,CAAE,CAAE,EAAG,aAAc,GAAO,UAAS,EACxR,OAAOY,EAAmBf,EAASE,EAAMY,EAAW,EAAK,CAC7D,CAEA,SAAS,QAAQ,EAAwB,EAAwB,CAC7Dd,EAAQ,MAAMI,EAAgB,iCAAkC,sJAAuJC,EAAWH,CAAI,CAAC,EACvOF,EAAQ,UAAUE,EAAK,MAAM,CACjC"}
|
|
@@ -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{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as a,unescapeIdentifier as o}from"./LineText.js";import{parseProperty as s}from"./PropertyLineParser.js";import{parseCondition as c}from"./ConditionParser.js";import{sourceStreamPattern as l}from"../Text/SourceStreamNames.js";import{parseCommandStream as u}from"./EventSourceParser.js";import{
|
|
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{firstWord as a,unescapeIdentifier as o}from"./LineText.js";import{parseProperty as s}from"./PropertyLineParser.js";import{parseCondition as c}from"./ConditionParser.js";import{sourceStreamPattern as l}from"../Text/SourceStreamNames.js";import{parseCommandStream as u}from"./EventSourceParser.js";import{EventMetadataParser as d}from"./EventMetadataParser.js";import{parseTag as f}from"./DeclarationParsers.js";import{parseOperation as p}from"./OperationParser.js";const m=t(`^produces\\s+operation(?:\\s|$)`),h=t(`^produces\\s+event\\s+([A-Za-z_]\\w*)(?:\\s+(generation)(?:\\s+.*)?)?$`),g=t(`^produces\\s+([A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),_=t(`^produces\\s+when\\s+(.+)$`),v=t(`^[A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*$`),y=t(`^for\\s+(\\S.*)$`),b=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),x=t(`^(.+?)\\s*=(?!=|>)\\s*(.+)$`),S=/* @__PURE__ */ new Set([`namespace`,`sequence`,`correlation`,`causation`,`causedBy`,`occurred`]);function parseProduces(t,C,w=!1){if(m.test(C.content)){if(!w){t.error(e.OperationOutsideCommand,`Operations can only be produced by commands.`,n(C)),t.skipOpaqueBlock(C.indent);return}let r=p(t,C,!0);return{kind:`ProducesSyntax`,when:null,event:r.operation.name,targetLocation:{...n(C),column:C.indent+C.content.match(/^produces\s+operation(?:\s+|$)/)[0].length+1},inlineEvent:null,inlineOperation:r.operation,mappings:r.mappings,for:null,tags:[],location:n(C)}}let T=h.exec(C.content),E=C,D=null,O,k;if(T!==null){if(!w){t.error(e.InlineEventOutsideCommand,`Inline events can only be declared inside commands`,n(C)),t.skipOpaqueBlock(C.indent);return}T[2]!==void 0&&t.error(e.InlineEventGeneration,`Inline events are generation 1 - extract the event before declaring generations`,n(C)),O=T[1],k=C.indent+C.content.match(/^produces\s+event\s+/)[0].length+1}else if(_.test(C.content)){D=c(t,_.exec(C.content)[1],n(C));let r=t.peekChild(C.indent);if(r===void 0||!v.test(r.content)){t.error(e.ProducesWhenWithoutEvent,`Expected an event name on the line after 'produces when'`,n(C)),t.skipOpaqueBlock(C.indent);return}t.reader.takeSignificant(),E=r,O=r.content,k=r.indent+1}else{let r=g.exec(C.content);if(r===null){t.error(e.InvalidProducesDeclaration,`Invalid produces declaration '${C.content}' - expected 'produces <EventType>' or 'produces when <condition>'`,n(C)),t.skipOpaqueBlock(C.indent);return}O=r[1],k=C.indent+C.content.match(/^produces\s+/)[0].length+1}let A=[],j=/* @__PURE__ */ new Set,M=[],N=[],P=new d(O),F=null,I=null;for(let c=t.peekChild(E.indent);c!==void 0;c=t.peekChild(E.indent)){t.reader.takeSignificant();let d=a(c.content),p=n(c);if(S.has(d)){t.error(e.ReservedProductionMetadata,`'${d}' is system-assigned production metadata and cannot be supplied here`,p),t.skipOpaqueBlock(c.indent);continue}if(T!==null&&(d===`generation`||d===`origin`)){t.error(d===`generation`?e.InlineEventGeneration:e.ReservedProductionMetadata,d===`generation`?`Inline events are generation 1 - extract the event before declaring generations`:`An inline event is local to its command and cannot declare origin`,p),t.skipOpaqueBlock(c.indent);continue}if(d===`stream`&&!c.content.includes(`=`)){let n=l(`^stream\\s+([A-Za-z_]\\w*\\.[A-Za-z_]\\w*)$`).exec(c.content);if(!w)t.error(e.ProductionRouteOutsideCommand,`Only command event productions can declare a stream route.`,p),t.skipBlock(c.indent);else if(I!==null)t.error(e.InvalidCommandStream,`A production can declare at most one stream route.`,p),t.skipBlock(c.indent);else if(n===null)t.error(e.InvalidCommandStream,`Expected 'stream <Source>.<Stream>'.`,p),t.skipBlock(c.indent);else{let e={...p,column:c.indent+c.content.indexOf(n[1])+1},r={kind:`PropertySyntax`,name:`stream`,type:{kind:`TypeRefSyntax`,name:n[1],isCollection:!1,isOptional:!1,location:e},isIdentifier:!1,location:p};I=u(t,c,r,!1)}continue}if(d===`tag`){let e=f(t,c,!1);e!==void 0&&N.push(e);continue}let m=y.exec(c.content);if(m!==null){F===null?F=r(m[1],p,t):t.error(e.DuplicateProducesTarget,`'${E.content}' already declares where it lands - an event is appended to one event source`,p);continue}let h=(T===null?b:x).exec(c.content),g=h===null||T===null?void 0:s(t,{...c,content:h[1].trimEnd()});if(h!==null&&(T===null||g!==void 0)){if(g!==void 0){g.isIdentifier&&(t.error(e.IdentifierOnEventProperty,`Property '${g.name}' of event '${O}' cannot be marked identifier - an event never carries its event source id`,p),g={...g,isIdentifier:!1});let n=g.name;j.has(n)&&t.error(e.DuplicateDeclaration,`Event '${O}' already declares property '${g.name}'`,p),j.add(n),A.push(g)}M.push({kind:`PropertyMappingSyntax`,property:g?.name??o(h[1]),source:r(h[2],{...p,column:c.indent+c.content.length-h[2].length+1},t),location:p})}else(T===null||!P.tryParse(t,c))&&t.error(e.InvalidPropertyMapping,`Invalid ${T===null?``:`inline `}property mapping '${c.content}' - expected '<property>${T===null?``:` <Type>`} = <source>'`,p,i(`text`,c.content))}return E!==C&&t.skipBlock(C.indent),{kind:`ProducesSyntax`,when:D,event:O,stream:I,targetLocation:{...n(E),column:k},inlineOperation:null,mappings:M,for:F,tags:T===null?N:[],location:n(C),inlineEvent:T===null?null:{kind:`EventSyntax`,name:O,properties:A,tags:N,generation:1,hasGenerationMarker:!1,...P.value,location:n(C)}}}export{parseProduces};
|
|
2
2
|
//# sourceMappingURL=ProducesParser.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as n}from"../Syntax/DependencySources.js";function validateReadModelMemberTypes(r,i){let a=/* @__PURE__ */ new Set([`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`,...r.concepts.map(e=>e.name),...r.types.map(e=>e.name),...r.imports.map(e=>e.qualifiedName.split(`.`).at(-1))]),o=new t(r).slices.map(({slice:e})=>e),s=o.flatMap(e=>e.readModels),c=/* @__PURE__ */ new Set([...s.map(e=>e.name),...o.flatMap(e=>(n(e).reducers??[]).map(e=>e.readModel)),...o.flatMap(e=>e.projections.flatMap(e=>{let t=e.blocks.filter(e=>e.kind===`ProjectionVariantSyntax`);return t.length>0?t.map(e=>e.name):[e.readModel??e.name]}))]);for(let t of s)for(let n of t.properties.filter(e=>!a.has(e.type.name)&&c.has(e.type.name)))i.error(e.InvalidSemanticBinding,`Read model '${t.name}' member '${n.name}' references unsupported type '${n.type.name}'. Use a primitive, concept or top-level 'type'; read-model shapes and slice-local 'type' declarations are not member types.`,n.type.location)}export{validateReadModelMemberTypes};
|
|
2
|
+
//# sourceMappingURL=ReadModelMemberTypeValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReadModelMemberTypeValidator.js","names":["types","application","concept","type","imported","slices","AuthoringProductionResolver","slice","models","readModels","model","dependencySourcesOf","reducer","variants","projection","block","variant","property","context","DiagnosticCodes"],"sources":["../../../../../../Compiler/Parsing/ReadModelMemberTypeValidator.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 { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\n\n// A read model has an identity; only primitives, concepts, top-level types and imported names\n// belong to the reusable value-type namespace. Validate after file composition.\nexport function validateReadModelMemberTypes(application: ApplicationSyntax, context: ParserContext): void {\n const types = new Set([\n 'Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime',\n ...application.concepts.map(concept => concept.name),\n ...application.types.map(type => type.name),\n ...application.imports.map(imported => imported.qualifiedName.split('.').at(-1)!),\n ]);\n const slices = new AuthoringProductionResolver(application).slices.map(({ slice }) => slice);\n const models = slices.flatMap(slice => slice.readModels);\n const readModels = new Set([\n ...models.map(model => model.name),\n ...slices.flatMap(slice => (dependencySourcesOf(slice).reducers ?? []).map(reducer => reducer.readModel)),\n ...slices.flatMap(slice => slice.projections.flatMap(projection => {\n const variants = projection.blocks.filter(block => block.kind === 'ProjectionVariantSyntax');\n return variants.length > 0 ? variants.map(variant => variant.name) : [projection.readModel ?? projection.name];\n })),\n ]);\n for (const model of models) {\n for (const property of model.properties.filter(property => !types.has(property.type.name) && readModels.has(property.type.name))) {\n context.error(DiagnosticCodes.InvalidSemanticBinding,\n `Read model '${model.name}' member '${property.name}' references unsupported type '${property.type.name}'. Use a primitive, concept or top-level 'type'; read-model shapes and slice-local 'type' declarations are not member types.`,\n property.type.location);\n }\n }\n}\n"],"mappings":"qRAWA,SAAgB,6BAA6B,EAAgC,EAA8B,CACvG,IAAMA,kBAAQ,IAAI,IAAI,CAClB,OAAQ,SAAU,MAAO,UAAW,OAAQ,OAAQ,WACpD,GAAGC,EAAY,SAAS,IAAI,GAAWC,EAAQ,IAAI,EACnD,GAAGD,EAAY,MAAM,IAAI,GAAQE,EAAK,IAAI,EAC1C,GAAGF,EAAY,QAAQ,IAAI,GAAYG,EAAS,cAAc,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAE,CACpF,CAAC,EACKC,EAAS,IAAIC,EAA4BL,CAAW,CAAC,CAAC,OAAO,KAAK,CAAE,WAAYM,CAAK,EACrFC,EAASH,EAAO,QAAQ,GAASE,EAAM,UAAU,EACjDE,kBAAa,IAAI,IAAI,CACvB,GAAGD,EAAO,IAAI,GAASE,EAAM,IAAI,EACjC,GAAGL,EAAO,QAAQ,IAAUM,EAAoBJ,CAAK,CAAC,CAAC,UAAY,CAAC,EAAA,CAAG,IAAI,GAAWK,EAAQ,SAAS,CAAC,EACxG,GAAGP,EAAO,QAAQ,GAASE,EAAM,YAAY,QAAQ,GAAc,CAC/D,IAAMM,EAAWC,EAAW,OAAO,OAAO,GAASC,EAAM,OAAS,yBAAyB,EAC3F,OAAOF,EAAS,OAAS,EAAIA,EAAS,IAAI,GAAWG,EAAQ,IAAI,EAAI,CAACF,EAAW,WAAaA,EAAW,IAAI,CACjH,CAAC,CAAC,CACN,CAAC,EACD,IAAK,IAAMJ,KAASF,EAChB,IAAK,IAAMS,KAAYP,EAAM,WAAW,OAAO,GAAY,CAACV,EAAM,IAAIiB,EAAS,KAAK,IAAI,GAAKR,EAAW,IAAIQ,EAAS,KAAK,IAAI,CAAC,EAC3HC,EAAQ,MAAMC,EAAgB,uBAC1B,eAAeT,EAAM,KAAK,YAAYO,EAAS,KAAK,iCAAiCA,EAAS,KAAK,KAAK,8HACxGA,EAAS,KAAK,QAAQ,CAGtC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseCanvasPair as b}from"./CanvasPlacement.js";import{parseEventSource as ee}from"./EventSourceParser.js";import{isFileDirective as x}from"./FileReferences.js";import{parseSystem as S}from"./OperationParser.js";import{parseExample as te}from"./SpecificationExampleParser.js";import{isBlankPublicEventOrigin as ne}from"../Syntax/PublicEventInvariants.js";import{parseType as re}from"./DeclarationParsers.js";import{parseValidate as C}from"./CommandParser.js";import{parseTriggerDeclaration as w}from"./TriggerDataParser.js";import{FeatureBody as T,featureBodyExpected as E}from"./FeatureBody.js";import{ModuleBody as D,moduleBodyExpected as O,modulePattern as k,parseModule as A}from"./ModuleBody.js";import{EnumerationMembers as j}from"./EnumerationMembers.js";import{parseGeneration as M}from"./GenerationParser.js";import{parseIdentity as N}from"./IdentityParser.js";import{parsePolicy as ie}from"./PolicyParser.js";import{parseSeed as ae}from"./SeedParser.js";import{parseExposure as oe,parseInstance as se}from"./CompositionParser.js";import{parseUiProfile as P}from"./UiProfileLegacyLayout.js";const F=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),I=r(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${t})"$`),L=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),R=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),z=r(`^@?[a-z_]\\w*$`),B=r(`^persona\\s+([A-Za-z_]\\w*)$`),V=r(`^policy\\s+([A-Za-z_]\\w*)$`),H=r(`^goal\\s+"(${t})"$`),U=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),W=r(`^colour\\s+(yellow|pink|green|blue)$`),G=/^[ ]*\t/,K=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],q=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),J=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new D(a[0]):void 0,s=a.length>1?new T(a[a.length-1]):void 0,l=o??s,u=null,p=null,b=!1,x=null,C=null,E=!1,O=!1,k=null,j=[],M=[],F=[],R=[],z=[],B=[],V=[],H=[],U=[],W=[],G=[],K=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))O||!f(a)||!/^command\s+reads\s+protected$/.test(r.content)?t.error(e.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,i(r)):x=`Protected`,O=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(r.content)){let o=I.exec(r.content);t.skipBlock(r.indent),E||!f(a)||o===null?t.error(e.InvalidTimeZoneDeclaration,`Declare 'time zone "<id>"' or 'time zone configurable default "<id>"' once at the application root.`,i(r)):C={kind:`TimeZoneSyntax`,id:n(o[2]),configurable:o[1]!==void 0,location:i(r)},E=!0}else if(s===`reaction`)b||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,b=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,k=parseDomain(t,r,k,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,M):l.tryParse(t,r);else if(s===`import`){let a=L.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&ne(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),j.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?J.push(te(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(ee(t,r));else if(s===`system`)z.push(S(t,r));else if(s===`concept`)F.push(parseConcept(t,r));else if(s===`type`)R.push(re(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(A(t,r));else if(s===`persona`)H.push(parsePersona(t,r));else if(s===`sticky`){let e=parseStickyNote(t,r);e!==null&&U.push(e)}else if(s===`seed`)K.push(ae(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=N(t,r,u);else if(s===`policy`){let n=ie(t,r);W.some(e=>e.name===n.name)&&t.error(e.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),W.push(n)}else if(s===`exposure`)X.push(oe(t,r));else if(s===`instance`)Z.push(se(t,r));else if(s===`trigger`){let e=w(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else q.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?P(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&V.unshift(place(a,s.build(t.start,!0),t.start)):V.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...x===null?{}:{commandReadMode:x},...C===null?{}:{timeZone:C},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:k,imports:j,concepts:F,types:R,systems:z,eventSources:B,examples:J,modules:V,personas:H,policies:W,purposes:G,seeds:K,declaredTriggers:Y,fileImports:M,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?L.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||q.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=k.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=J.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?O:E;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=F.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&G.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=R.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!K.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${K.join(`, `)} or Enum`,i(n));let m=[],h=new j,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(x(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=C(t,r,`concept`,a);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=M(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&z.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,r){let a=B.exec(r.content)?.[1]??``;a===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${r.content}' - expected 'persona <Name>'`,i(r));let o=null,s=[],l=[],u=null,d=null;for(let f=t.peekChild(r.indent);f!==void 0;f=t.peekChild(r.indent)){t.reader.takeSignificant();let r=c(f.content);if(r===`description`)o=p(t,f,o,`Persona '${a}'`);else if(r===`goal`){let r=H.exec(f.content);r===null?t.error(e.InvalidPersonaDeclaration,`Invalid goal '${f.content}' - expected 'goal "<text>"'`,i(f)):l.push(n(r[1]))}else if(r===`position`)u=b(t,f,`position`,`x`,`y`,u,!0)??u;else if(r===`size`)d=b(t,f,`size`,`width`,`height`,d,!1)??d;else if(r===`policy`){let n=V.exec(f.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${f.content}' - expected 'policy <Name>'`,i(f)):s.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${r}' in persona body - expected description, goal, policy, position or size`,i(f)),t.skipBlock(f.indent)}return{kind:`PersonaSyntax`,name:a,description:o,policies:s,...l.length>0?{goals:l}:{},...u===null?{}:{x:u[0],y:u[1]},...d===null?{}:{width:d[0],height:d[1]},location:i(r)}}function parseStickyNote(t,n){let r=U.exec(n.content);if(r===null)return t.error(e.InvalidPersonaDeclaration,`Invalid sticky note declaration '${n.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,i(n)),t.skipBlock(n.indent),null;let a=null,o=null,s=null,l=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(r.content);if(n===`description`)a=p(t,r,a,`A sticky note`);else if(n===`colour`){let n=W.exec(r.content);n===null?t.error(e.InvalidPersonaDeclaration,`Invalid colour '${r.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,i(r)):o=n[1]}else n===`position`?s=b(t,r,`position`,`x`,`y`,s,!0)??s:n===`size`?l=b(t,r,`size`,`width`,`height`,l,!1)??l:(t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in sticky note body - expected description, colour, position or size`,i(r)),t.skipBlock(r.indent))}return a===null||s===null?(t.error(e.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,i(n)),null):{kind:`StickyNoteSyntax`,canvas:r[1],text:a,colour:o,x:s[0],y:s[1],width:l===null?null:l[0],height:l===null?null:l[1],location:i(n)}}export{parseApplication};
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseCanvasPair as b}from"./CanvasPlacement.js";import{parseEventSource as ee}from"./EventSourceParser.js";import{isFileDirective as x}from"./FileReferences.js";import{isBlankPublicEventOrigin as S}from"../Syntax/PublicEventInvariants.js";import{parseType as te}from"./DeclarationParsers.js";import{parseSystem as ne}from"./OperationParser.js";import{parseExample as re}from"./SpecificationExampleParser.js";import{parseValidate as C}from"./CommandParser.js";import{parseTriggerDeclaration as w}from"./TriggerDataParser.js";import{FeatureBody as T,featureBodyExpected as E}from"./FeatureBody.js";import{ModuleBody as D,moduleBodyExpected as O,modulePattern as k,parseModule as A}from"./ModuleBody.js";import{EnumerationMembers as j}from"./EnumerationMembers.js";import{parseGeneration as M}from"./GenerationParser.js";import{parseIdentity as N}from"./IdentityParser.js";import{parsePolicy as ie}from"./PolicyParser.js";import{parseSeed as ae}from"./SeedParser.js";import{parseExposure as oe,parseInstance as se}from"./CompositionParser.js";import{parseUiProfile as P}from"./UiProfileLegacyLayout.js";const F=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),I=r(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${t})"$`),L=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),R=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),z=r(`^@?[a-z_]\\w*$`),B=r(`^persona\\s+([A-Za-z_]\\w*)$`),V=r(`^policy\\s+([A-Za-z_]\\w*)$`),H=r(`^goal\\s+"(${t})"$`),U=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),W=r(`^colour\\s+(yellow|pink|green|blue)$`),G=/^[ ]*\t/,K=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],q=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),J=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new D(a[0]):void 0,s=a.length>1?new T(a[a.length-1]):void 0,l=o??s,u=null,p=null,b=!1,x=null,C=null,E=!1,O=!1,k=null,j=[],M=[],F=[],R=[],z=[],B=[],V=[],H=[],U=[],W=[],G=[],K=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))O||!f(a)||!/^command\s+reads\s+protected$/.test(r.content)?t.error(e.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,i(r)):x=`Protected`,O=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(r.content)){let o=I.exec(r.content);t.skipBlock(r.indent),E||!f(a)||o===null?t.error(e.InvalidTimeZoneDeclaration,`Declare 'time zone "<id>"' or 'time zone configurable default "<id>"' once at the application root.`,i(r)):C={kind:`TimeZoneSyntax`,id:n(o[2]),configurable:o[1]!==void 0,location:i(r)},E=!0}else if(s===`reaction`)b||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,b=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,k=parseDomain(t,r,k,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,M):l.tryParse(t,r);else if(s===`import`){let a=L.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&S(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),j.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?J.push(re(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(ee(t,r));else if(s===`system`)z.push(ne(t,r));else if(s===`concept`)F.push(parseConcept(t,r));else if(s===`type`)R.push(te(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(A(t,r));else if(s===`persona`)H.push(parsePersona(t,r));else if(s===`sticky`){let e=parseStickyNote(t,r);e!==null&&U.push(e)}else if(s===`seed`)K.push(ae(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=N(t,r,u);else if(s===`policy`){let n=ie(t,r);W.some(e=>e.name===n.name)&&t.error(e.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),W.push(n)}else if(s===`exposure`)X.push(oe(t,r));else if(s===`instance`)Z.push(se(t,r));else if(s===`trigger`){let e=w(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else q.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?P(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&V.unshift(place(a,s.build(t.start,!0),t.start)):V.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...x===null?{}:{commandReadMode:x},...C===null?{}:{timeZone:C},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:k,imports:j,concepts:F,types:R,systems:z,eventSources:B,examples:J,modules:V,personas:H,policies:W,purposes:G,seeds:K,declaredTriggers:Y,fileImports:M,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?L.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||q.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=k.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=J.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?O:E;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=F.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&G.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=R.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!K.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${K.join(`, `)} or Enum`,i(n));let m=[],h=new j,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(x(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=C(t,r,`concept`,a);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=M(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&z.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,r){let a=B.exec(r.content)?.[1]??``;a===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${r.content}' - expected 'persona <Name>'`,i(r));let o=null,s=[],l=[],u=null,d=null;for(let f=t.peekChild(r.indent);f!==void 0;f=t.peekChild(r.indent)){t.reader.takeSignificant();let r=c(f.content);if(r===`description`)o=p(t,f,o,`Persona '${a}'`);else if(r===`goal`){let r=H.exec(f.content);r===null?t.error(e.InvalidPersonaDeclaration,`Invalid goal '${f.content}' - expected 'goal "<text>"'`,i(f)):l.push(n(r[1]))}else if(r===`position`)u=b(t,f,`position`,`x`,`y`,u,!0)??u;else if(r===`size`)d=b(t,f,`size`,`width`,`height`,d,!1)??d;else if(r===`policy`){let n=V.exec(f.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${f.content}' - expected 'policy <Name>'`,i(f)):s.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${r}' in persona body - expected description, goal, policy, position or size`,i(f)),t.skipBlock(f.indent)}return{kind:`PersonaSyntax`,name:a,description:o,policies:s,...l.length>0?{goals:l}:{},...u===null?{}:{x:u[0],y:u[1]},...d===null?{}:{width:d[0],height:d[1]},location:i(r)}}function parseStickyNote(t,n){let r=U.exec(n.content);if(r===null)return t.error(e.InvalidPersonaDeclaration,`Invalid sticky note declaration '${n.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,i(n)),t.skipBlock(n.indent),null;let a=null,o=null,s=null,l=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(r.content);if(n===`description`)a=p(t,r,a,`A sticky note`);else if(n===`colour`){let n=W.exec(r.content);n===null?t.error(e.InvalidPersonaDeclaration,`Invalid colour '${r.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,i(r)):o=n[1]}else n===`position`?s=b(t,r,`position`,`x`,`y`,s,!0)??s:n===`size`?l=b(t,r,`size`,`width`,`height`,l,!1)??l:(t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in sticky note body - expected description, colour, position or size`,i(r)),t.skipBlock(r.indent))}return a===null||s===null?(t.error(e.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,i(n)),null):{kind:`StickyNoteSyntax`,canvas:r[1],text:a,colour:o,x:s[0],y:s[1],width:l===null?null:l[0],height:l===null?null:l[1],location:i(n)}}export{parseApplication};
|
|
2
2
|
//# sourceMappingURL=ScreenplayParser.js.map
|