@cratis/screenplay-language 5.2.0 → 5.3.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/PlayFolderMerge.js +1 -1
- package/dist/bundles/compiler/Files/PlayFolderMerge.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ApplicationContextParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ApplicationContextParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DeclarationParsers.js +1 -1
- package/dist/bundles/compiler/Parsing/DeclarationParsers.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ExpressionParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ExpressionParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ScreenplayParser.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/Structure.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/completion-items.js +18 -17
- package/dist/bundles/completion-items.js.map +1 -1
- package/dist/bundles/completion-planner.js +2 -2
- package/dist/bundles/completion-planner.js.map +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/language.js +1 -1
- package/dist/bundles/language.js.map +1 -1
- package/dist/bundles/response-analysis.js +1 -1
- package/dist/bundles/response-analysis.js.map +1 -1
- package/dist/bundles/scope-items.js +1 -1
- package/dist/bundles/scope-items.js.map +1 -1
- package/dist/bundles/tokens.js +1 -1
- package/dist/bundles/tokens.js.map +1 -1
- package/dist/bundles/validation.js +1 -1
- package/dist/bundles/validation.js.map +1 -1
- package/dist/completion-items.d.ts +1 -0
- package/dist/completion-items.d.ts.map +1 -1
- package/dist/completion-planner.d.ts.map +1 -1
- package/dist/diagnostic-codes.d.ts +5 -0
- package/dist/diagnostic-codes.d.ts.map +1 -1
- package/dist/keyword-docs.d.ts.map +1 -1
- package/dist/language.d.ts.map +1 -1
- package/dist/scope-items.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeclarationParsers.js","names":["typeHeader","pattern","eventHeader","stringBodyPattern","readModelHeader","typeShapedPattern","tagIdentifierPattern","firstWord","line","tryParseProperty","property","context","code","message","locationOf","name","header","DiagnosticCodes","properties","description","parseDescription","isFileDirectiveAmongProperties","parseProperty","match","origin","unescapeString","visibility","isBlankPublicEventOrigin","hasGenerationMarker","generation","declared","tags","metadata","EventMetadataParser","eventBodyReservedWords","tag","value","eventDeclaration","expression","parseMappingSource","bodyIndent","documentation","parseDocumentation"],"sources":["../../../../../../Compiler/Parsing/DeclarationParsers.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 { EventSyntax, PropertySyntax, ReadModelSyntax, TagSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { pattern } from '../Text/patterns';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { eventBodyReservedWords } from '../Text/ReservedWords';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst typeHeader = pattern('^type\\\\s+([A-Za-z_]\\\\w*)$');\nconst eventHeader = pattern(`^(?:(?<public>public)\\\\s+)?event\\\\s+(?<name>[A-Za-z_]\\\\w*)(?:\\\\s+generation\\\\s+(?<generation>[0-9]+))?(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst readModelHeader = pattern('^readmodel\\\\s+([A-Za-z_]\\\\w*)$');\nconst maximumGeneration = 4294967295;\nconst typeShapedPattern = pattern('^[A-Z]\\\\w*(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?$');\nconst tagIdentifierPattern = pattern('^[A-Za-z_]\\\\w*$');\n\n// 'description' takes no type reference, so a line with property shape is a property named description.\nconst isDescription = (line: SourceLine): boolean => firstWord(line.content) === 'description' && tryParseProperty(line) === undefined;\n\nfunction withoutIdentifier(context: ParserContext, property: PropertySyntax, line: SourceLine, code: string, message: string): PropertySyntax {\n if (!property.isIdentifier) {\n return property;\n }\n context.error(code, message, locationOf(line));\n return { ...property, isIdentifier: false };\n}\n\nexport function parseType(context: ParserContext, header: SourceLine): TypeSyntax {\n const name = typeHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidTypeDeclaration, `Invalid type declaration '${header.content}' - expected 'type <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Type '${name}'`);\n continue;\n }\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of type '${name}' cannot be marked identifier - only a command property can be`));\n }\n if (properties.length === 0) {\n context.error(DiagnosticCodes.TypeWithoutProperties, `Type '${name}' must declare at least one property`, locationOf(header));\n }\n return { kind: 'TypeSyntax', name, properties, description, location: locationOf(header) };\n}\n\nexport function parseEvent(context: ParserContext, header: SourceLine): EventSyntax {\n const match = eventHeader.exec(header.content);\n const name = match?.groups?.name ?? '';\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, `Invalid event declaration '${header.content}' - expected '[public] event <Name> [generation <N>] [from \"<origin>\"]'`, locationOf(header));\n }\n const origin = match?.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n const visibility = match?.groups?.public !== undefined || origin !== null ? EventVisibility.Public : EventVisibility.Private;\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, 'An event origin must be a nonblank quoted string', locationOf(header));\n }\n const hasGenerationMarker = match?.groups?.generation !== undefined;\n let generation = 1;\n if (hasGenerationMarker) {\n const declared = Number(match!.groups!.generation);\n if (!Number.isSafeInteger(declared) || declared === 0 || declared >= maximumGeneration) {\n context.error(DiagnosticCodes.InvalidEventGeneration, `Event '${name}' must declare a generation between 1 and ${maximumGeneration - 1}`, locationOf(header));\n } else {\n generation = declared;\n }\n }\n const properties: PropertySyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n if (eventBodyReservedWords.includes(firstWord(line.content))) {\n const tag = parseTag(context, line);\n if (tag !== undefined) {\n tags.push(tag);\n }\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n if (!metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n }\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOnEventProperty,\n `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`));\n }\n return { kind: 'EventSyntax', name, properties, tags, visibility, origin, generation, hasGenerationMarker, ...metadata.value, location: locationOf(header) };\n}\n\n// 'tag <value>' - the port of the C# TagParser, with the warning the C# EventParser gives for a tag whose\n// value looks like a type, which is almost always a property named tag written without its '@'.\nexport function parseTag(context: ParserContext, line: SourceLine, eventDeclaration = true): TagSyntax | undefined {\n const value = line.content.substring('tag'.length).trim();\n if (eventDeclaration && typeShapedPattern.test(value)) {\n context.warning(DiagnosticCodes.TagPropertyReadAsTag,\n `'${line.content}' declares a static tag with the value '${value}', not a property named 'tag' - write 'tag \"${value}\"' for the tag, or '@${line.content}' for the property`,\n locationOf(line));\n }\n if (value.length === 0) {\n context.error(DiagnosticCodes.TagWithoutValue, 'Expected a value after \\'tag\\' - an identifier, a string literal or a context expression', locationOf(line));\n return undefined;\n }\n if (tagIdentifierPattern.test(value)) {\n return { kind: 'TagSyntax', value: { kind: 'LiteralExpressionSyntax', value, location: locationOf(line) }, location: locationOf(line) };\n }\n const expression = parseMappingSource(value, locationOf(line), context);\n if (expression.kind === 'RawExpressionSyntax') {\n context.error(DiagnosticCodes.InvalidTagValue, `Invalid tag value '${value}' - expected an identifier, a string literal or a context expression`, locationOf(line));\n return undefined;\n }\n return { kind: 'TagSyntax', value: expression, location: locationOf(line) };\n}\n\nexport function parseReadModel(context: ParserContext, header: SourceLine): ReadModelSyntax {\n let bodyIndent: number | undefined;\n const name = readModelHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReadModelDeclaration, `Invalid read model declaration '${header.content}' - expected 'readmodel <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n let documentation: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n bodyIndent ??= line.indent;\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Read model '${name}'`);\n } else if (firstWord(line.content) === 'documentation' && tryParseProperty(line) === undefined) {\n documentation = parseDocumentation(context, line, documentation, `Read model '${name}'`);\n } else if (isFileDirectiveAmongProperties(line)) {\n continue;\n } else {\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n if (property.isKey && line.indent > bodyIndent) {\n context.error(DiagnosticCodes.InvalidReadModelKey, 'The key modifier is only valid on top-level read-model properties.', property.location);\n }\n properties.push(withoutIdentifier(context, line.indent > bodyIndent ? { ...property, isKey: false } : property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of read model '${name}' cannot be marked identifier - only a command property can be`));\n }\n }\n return { kind: 'ReadModelSyntax', name, properties, description, documentation, location: locationOf(header) };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DeclarationParsers.js","names":["typeHeader","pattern","eventHeader","stringBodyPattern","readModelHeader","typeShapedPattern","tagIdentifierPattern","firstWord","line","tryParseProperty","property","context","code","message","locationOf","name","header","DiagnosticCodes","properties","description","parseDescription","isFileDirectiveAmongProperties","parseProperty","match","origin","unescapeString","visibility","isBlankPublicEventOrigin","hasGenerationMarker","generation","declared","tags","metadata","EventMetadataParser","eventBodyReservedWords","tag","value","eventDeclaration","expression","parseMappingSource","bodyIndent","passive","documentation","parseDocumentation","model"],"sources":["../../../../../../Compiler/Parsing/DeclarationParsers.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 { EventSyntax, PropertySyntax, ReadModelSyntax, TagSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { pattern } from '../Text/patterns';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { eventBodyReservedWords } from '../Text/ReservedWords';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst typeHeader = pattern('^type\\\\s+([A-Za-z_]\\\\w*)$');\nconst eventHeader = pattern(`^(?:(?<public>public)\\\\s+)?event\\\\s+(?<name>[A-Za-z_]\\\\w*)(?:\\\\s+generation\\\\s+(?<generation>[0-9]+))?(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst readModelHeader = pattern('^readmodel\\\\s+([A-Za-z_]\\\\w*)$');\nconst maximumGeneration = 4294967295;\nconst typeShapedPattern = pattern('^[A-Z]\\\\w*(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?$');\nconst tagIdentifierPattern = pattern('^[A-Za-z_]\\\\w*$');\n\n// 'description' takes no type reference, so a line with property shape is a property named description.\nconst isDescription = (line: SourceLine): boolean => firstWord(line.content) === 'description' && tryParseProperty(line) === undefined;\n\nfunction withoutIdentifier(context: ParserContext, property: PropertySyntax, line: SourceLine, code: string, message: string): PropertySyntax {\n if (!property.isIdentifier) {\n return property;\n }\n context.error(code, message, locationOf(line));\n return { ...property, isIdentifier: false };\n}\n\nexport function parseType(context: ParserContext, header: SourceLine): TypeSyntax {\n const name = typeHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidTypeDeclaration, `Invalid type declaration '${header.content}' - expected 'type <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Type '${name}'`);\n continue;\n }\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of type '${name}' cannot be marked identifier - only a command property can be`));\n }\n if (properties.length === 0) {\n context.error(DiagnosticCodes.TypeWithoutProperties, `Type '${name}' must declare at least one property`, locationOf(header));\n }\n return { kind: 'TypeSyntax', name, properties, description, location: locationOf(header) };\n}\n\nexport function parseEvent(context: ParserContext, header: SourceLine): EventSyntax {\n const match = eventHeader.exec(header.content);\n const name = match?.groups?.name ?? '';\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, `Invalid event declaration '${header.content}' - expected '[public] event <Name> [generation <N>] [from \"<origin>\"]'`, locationOf(header));\n }\n const origin = match?.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n const visibility = match?.groups?.public !== undefined || origin !== null ? EventVisibility.Public : EventVisibility.Private;\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, 'An event origin must be a nonblank quoted string', locationOf(header));\n }\n const hasGenerationMarker = match?.groups?.generation !== undefined;\n let generation = 1;\n if (hasGenerationMarker) {\n const declared = Number(match!.groups!.generation);\n if (!Number.isSafeInteger(declared) || declared === 0 || declared >= maximumGeneration) {\n context.error(DiagnosticCodes.InvalidEventGeneration, `Event '${name}' must declare a generation between 1 and ${maximumGeneration - 1}`, locationOf(header));\n } else {\n generation = declared;\n }\n }\n const properties: PropertySyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n if (eventBodyReservedWords.includes(firstWord(line.content))) {\n const tag = parseTag(context, line);\n if (tag !== undefined) {\n tags.push(tag);\n }\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n if (!metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n }\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOnEventProperty,\n `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`));\n }\n return { kind: 'EventSyntax', name, properties, tags, visibility, origin, generation, hasGenerationMarker, ...metadata.value, location: locationOf(header) };\n}\n\n// 'tag <value>' - the port of the C# TagParser, with the warning the C# EventParser gives for a tag whose\n// value looks like a type, which is almost always a property named tag written without its '@'.\nexport function parseTag(context: ParserContext, line: SourceLine, eventDeclaration = true): TagSyntax | undefined {\n const value = line.content.substring('tag'.length).trim();\n if (eventDeclaration && typeShapedPattern.test(value)) {\n context.warning(DiagnosticCodes.TagPropertyReadAsTag,\n `'${line.content}' declares a static tag with the value '${value}', not a property named 'tag' - write 'tag \"${value}\"' for the tag, or '@${line.content}' for the property`,\n locationOf(line));\n }\n if (value.length === 0) {\n context.error(DiagnosticCodes.TagWithoutValue, 'Expected a value after \\'tag\\' - an identifier, a string literal or a context expression', locationOf(line));\n return undefined;\n }\n if (tagIdentifierPattern.test(value)) {\n return { kind: 'TagSyntax', value: { kind: 'LiteralExpressionSyntax', value, location: locationOf(line) }, location: locationOf(line) };\n }\n const expression = parseMappingSource(value, locationOf(line), context);\n if (expression.kind === 'RawExpressionSyntax') {\n context.error(DiagnosticCodes.InvalidTagValue, `Invalid tag value '${value}' - expected an identifier, a string literal or a context expression`, locationOf(line));\n return undefined;\n }\n return { kind: 'TagSyntax', value: expression, location: locationOf(line) };\n}\n\nexport function parseReadModel(context: ParserContext, header: SourceLine): ReadModelSyntax {\n let bodyIndent: number | undefined;\n let passive = false;\n const name = readModelHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReadModelDeclaration, `Invalid read model declaration '${header.content}' - expected 'readmodel <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n let documentation: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n bodyIndent ??= line.indent;\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Read model '${name}'`);\n } else if (firstWord(line.content) === 'documentation' && tryParseProperty(line) === undefined) {\n documentation = parseDocumentation(context, line, documentation, `Read model '${name}'`);\n } else if (line.content === 'passive') {\n if (passive) {\n context.warning(DiagnosticCodes.RepeatedPassiveDirective, \"A read model repeats 'passive'; the directive is idempotent.\", locationOf(line));\n }\n passive = true;\n } else if (firstWord(line.content) === 'passive' && ['true', 'false'].includes(line.content.slice('passive'.length).trim())) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n } else if (isFileDirectiveAmongProperties(line)) {\n continue;\n } else {\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n if (property.isKey && line.indent > bodyIndent) {\n context.error(DiagnosticCodes.InvalidReadModelKey, 'The key modifier is only valid on top-level read-model properties.', property.location);\n }\n properties.push(withoutIdentifier(context, line.indent > bodyIndent ? { ...property, isKey: false } : property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of read model '${name}' cannot be marked identifier - only a command property can be`));\n }\n }\n const model: ReadModelSyntax = { kind: 'ReadModelSyntax', name, properties, description, documentation, location: locationOf(header) };\n return passive ? { ...model, isPassive: true } : model;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{unescapeString as t}from"../Text/StringLiteral.js";import{nativePattern as n,pattern as r}from"../Text/patterns.js";import{isExactNumberToken as i,parseExactNumber as a}from"../Syntax/ExactNumber.js";import{InvalidStructuredValue as o,StructuredValueParser as s}from"./StructuredValueParser.js";const c=r(`^@?[A-Za-z_]\\w*(\\.@?[A-Za-z_$]\\w*)*$`),l=n(`^@?[A-Za-z_]\\w*(\\.@?[A-Za-z_$]\\w*)*$`),u=r(`^-?\\d+(\\.\\d+)?$`),d=[`command`,`arguments`,`tenant`,`causedBy`,`causation`,`occurred`,`identity`],f=[`subject`,`name`,`userName`],p=[`id`,`name`,`userName`,`isAuthenticated`,`roles`,`claims`],m=`Screenplay has no JSON values - write the object or list as an indented block: one 'member = value' line per member, one 'item' line per list element, and '<name> none' for an empty list`;function parseModeledMappingSource(e,t,n){return parseMappingSource(e,t,n,!0)}function parseMappingSource(t,n,r,i=!1){if(t=t.trim(),t===`$refusal`||t.startsWith(`$refusal.`))return{kind:`RefusalExpressionSyntax`,member:t===`$refusal`?``:t.substring(9),location:n};if(t===`$eventSourceId`)return{kind:`EventSourceIdExpressionSyntax`,location:n};if(t===`$eventContext.eventSourceId`)return{kind:`EventContextExpressionSyntax`,path:`eventSourceId`,location:n};if(t===`$identity`||t===`$identity.`)return r?.error(e.InvalidExpression,`Invalid expression '${t}'`,n),{kind:`RawExpressionSyntax`,text:t,location:n};if(t.startsWith(`$identity.`)){let e=t.substring(10);return r?.deferIdentityValidation!==!0&&warnOnUnknownIdentityProperty(e.split(`.`)[0],`$identity`,n,r),{kind:`IdentityExpressionSyntax`,path:e,location:n}}if(t.startsWith(`$context.`)){let e=t.substring(9);return warnOnUnknownContextPath(e,n,r),{kind:`ContextExpressionSyntax`,path:e,location:n}}if(t.startsWith(`$env.`))return{kind:`EnvironmentExpressionSyntax`,name:t.substring(5),location:n};if(t.startsWith(`$strings.`))return{kind:`StringsExpressionSyntax`,key:t.substring(9),location:n};if(t.startsWith(`$.`))return{kind:`SourceItemExpressionSyntax`,path:t.substring(2),location:n};if(t.startsWith(`{`)||t.startsWith(`[`)){r?.error(e.InlineJsonValue,m,n);try{return new s(t,n,r).parse()}catch(i){if(!(i instanceof o))throw i;return r?.error(e.InvalidStructuredValue,`Invalid inline structured value: ${i.message}`,n),{kind:`RawExpressionSyntax`,text:t,location:n}}}let a=r===void 0?parseLiteral(t,n):parseLiteral(t,n,r);return a===void 0?(i||r?.sourceOptions.numericMode===`exact`?l:c).test(t)?{kind:`PathExpressionSyntax`,path:t,location:n}:{kind:`RawExpressionSyntax`,text:t,location:n}:a}function warnOnUnknownContextPath(t,n,r){let[i,a]=t.split(`.`);d.includes(i)?a!==void 0&&i===`causedBy`&&!f.includes(a)?r?.warning(e.UnknownContextCausedByProperty,`Unknown $context.causedBy property '${a}' - expected ${f.join(`, `)}`,n):a!==void 0&&i===`identity`&&warnOnUnknownIdentityProperty(a,`$context.identity`,n,r):r?.warning(e.UnknownContextPath,`Unknown $context path '${t}' - expected one of ${d.join(`, `)}`,n)}function warnOnUnknownIdentityProperty(t,n,r,i){p.includes(t)||i?.warning(e.UnknownContextIdentityProperty,`Unknown ${n} property '${t}' - expected ${p.join(`, `)}`,r)}function parseLiteral(n,r,o){let literal=e=>({kind:`LiteralExpressionSyntax`,value:e,location:r});switch(n){case`true`:return literal(!0);case`false`:return literal(!1);case`null`:return literal(null)}if(n.length>=2&&(n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)))return literal(t(n.substring(1,n.length-1)));if(o?.sourceOptions.numericMode===`exact`){if(!i(n))return;let t=a(n);return t===void 0?(o.error(e.InexactNumericLiteral,`Numeric literal is not exactly representable in the bounded Decimal domain.`,r),{kind:`RawExpressionSyntax`,text:n,location:r}):literal(t)}if(u.test(n)&&!Number.isNaN(Number(n)))return literal(Number(n))}export{p as identityProperties,m as inlineJsonMessage,parseLiteral,parseMappingSource,parseModeledMappingSource};
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{unescapeString as t}from"../Text/StringLiteral.js";import{nativePattern as n,pattern as r}from"../Text/patterns.js";import{isExactNumberToken as i,parseExactNumber as a}from"../Syntax/ExactNumber.js";import{InvalidStructuredValue as o,StructuredValueParser as s}from"./StructuredValueParser.js";const c=r(`^@?[A-Za-z_]\\w*(\\.@?[A-Za-z_$]\\w*)*$`),l=n(`^@?[A-Za-z_]\\w*(\\.@?[A-Za-z_$]\\w*)*$`),u=r(`^-?\\d+(\\.\\d+)?$`),d=[`command`,`arguments`,`tenant`,`causedBy`,`causation`,`occurred`,`identity`],f=[`subject`,`name`,`userName`],p=[`id`,`name`,`userName`,`isAuthenticated`,`roles`,`claims`],m=`Screenplay has no JSON values - write the object or list as an indented block: one 'member = value' line per member, one 'item' line per list element, and '<name> none' for an empty list`;function parseModeledMappingSource(e,t,n){return parseMappingSource(e,t,n,!0)}function parseMappingSource(t,n,r,i=!1){if(t=t.trim(),t===`$refusal`||t.startsWith(`$refusal.`))return{kind:`RefusalExpressionSyntax`,member:t===`$refusal`?``:t.substring(9),location:n};if(t===`$eventSourceId`)return{kind:`EventSourceIdExpressionSyntax`,location:n};if(t===`$eventContext.eventSourceId`)return{kind:`EventContextExpressionSyntax`,path:`eventSourceId`,location:n};if(t===`$identity`||t===`$identity.`)return r?.error(e.InvalidExpression,`Invalid expression '${t}'`,n),{kind:`RawExpressionSyntax`,text:t,location:n};if(t.startsWith(`$identity.`)){let e=t.substring(10);return r?.deferIdentityValidation!==!0&&warnOnUnknownIdentityProperty(e.split(`.`)[0],`$identity`,n,r),{kind:`IdentityExpressionSyntax`,path:e,location:n}}if(t.startsWith(`$context.`)){let e=t.substring(9);return warnOnUnknownContextPath(e,n,r),{kind:`ContextExpressionSyntax`,path:e,location:n}}if(t.startsWith(`$env.`))return{kind:`EnvironmentExpressionSyntax`,name:t.substring(5),location:n};if(t.startsWith(`$strings.`))return{kind:`StringsExpressionSyntax`,key:t.substring(9),location:n};if(t.startsWith(`$.`))return{kind:`SourceItemExpressionSyntax`,path:t.substring(2),location:n};if(t.startsWith(`{`)||t.startsWith(`[`)){r?.error(e.InlineJsonValue,m,n);try{return new s(t,n,r).parse()}catch(i){if(!(i instanceof o))throw i;return r?.error(e.InvalidStructuredValue,`Invalid inline structured value: ${i.message}`,n),{kind:`RawExpressionSyntax`,text:t,location:n}}}let a=r===void 0?parseLiteral(t,n):parseLiteral(t,n,r);return a===void 0?(i||r?.sourceOptions.numericMode===`exact`?l:c).test(t)?{kind:`PathExpressionSyntax`,path:t,location:n}:{kind:`RawExpressionSyntax`,text:t,location:n}:a}function warnOnUnknownContextPath(t,n,r){let[i,a]=t.split(`.`);d.includes(i)?a!==void 0&&i===`causedBy`&&!f.includes(a)?r?.warning(e.UnknownContextCausedByProperty,`Unknown $context.causedBy property '${a}' - expected ${f.join(`, `)}`,n):a!==void 0&&i===`identity`&&warnOnUnknownIdentityProperty(a,`$context.identity`,n,r):r?.warning(e.UnknownContextPath,`Unknown $context path '${t}' - expected one of ${d.join(`, `)}`,n)}function warnOnUnknownIdentityProperty(t,n,r,i){p.includes(t)||i?.warning(e.UnknownContextIdentityProperty,`Unknown ${n} property '${t}' - expected ${p.join(`, `)}`,r)}function parseLiteral(n,r,o){let literal=e=>({kind:`LiteralExpressionSyntax`,value:e,location:r});switch(n){case`true`:return literal(!0);case`false`:return literal(!1);case`null`:return literal(null)}if(n.length>=2&&(n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)))return literal(t(n.substring(1,n.length-1)));if(o?.sourceOptions.numericMode===`exact`){if(!i(n))return;let t=a(n);return t===void 0?(o.error(e.InexactNumericLiteral,`Numeric literal is not exactly representable in the bounded Decimal domain.`,r),{kind:`RawExpressionSyntax`,text:n,location:r}):literal(t)}if(u.test(n)&&!Number.isNaN(Number(n)))return literal(Number(n))}export{d as contextRoots,p as identityProperties,m as inlineJsonMessage,parseLiteral,parseMappingSource,parseModeledMappingSource};
|
|
2
2
|
//# sourceMappingURL=ExpressionParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressionParser.js","names":["pathPattern","pattern","nativePathPattern","nativePattern","numberPattern","contextRoots","causedByProperties","identityProperties","inlineJsonMessage","text","location","context","DiagnosticCodes","path","StructuredValueParser","error","InvalidStructuredValue","literal","nativeIdentifiers","root","member","unescapeString","isExactNumberToken","number","parseExactNumber"],"sources":["../../../../../../Compiler/Parsing/ExpressionParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { ExpressionSyntax, LiteralExpressionSyntax } from '../Syntax/Expressions';\nimport { ExactNumber, isExactNumberToken, parseExactNumber } from '../Syntax/ExactNumber';\nimport { nativePattern, pattern } from '../Text/patterns';\nimport { unescapeString } from '../Text/StringLiteral';\nimport { ParserContext } from './ParserContext';\nimport { InvalidStructuredValue, StructuredValueParser } from './StructuredValueParser';\n\nconst pathPattern = pattern('^@?[A-Za-z_]\\\\w*(\\\\.@?[A-Za-z_$]\\\\w*)*$');\nconst nativePathPattern = nativePattern('^@?[A-Za-z_]\\\\w*(\\\\.@?[A-Za-z_$]\\\\w*)*$');\nconst numberPattern = pattern('^-?\\\\d+(\\\\.\\\\d+)?$');\nconst contextRoots = ['command', 'arguments', 'tenant', 'causedBy', 'causation', 'occurred', 'identity'];\nconst causedByProperties = ['subject', 'name', 'userName'];\nexport const identityProperties = ['id', 'name', 'userName', 'isAuthenticated', 'roles', 'claims'];\n\n// Reads the right-hand side of a mapping or a rule operand - the port of the C# ExpressionParser's\n// ParseMappingSource. With a context it also reports what the C# compiler reports while reading one: an\n// unknown $context path, and an inline structured value that is not valid JSON.\nexport const inlineJsonMessage = \"Screenplay has no JSON values - write the object or list as an indented block: one 'member = value' line per member, one 'item' line per list element, and '<name> none' for an empty list\";\n\nexport function parseModeledMappingSource(text: string, location: SourceLocation, context: ParserContext): ExpressionSyntax {\n return parseMappingSource(text, location, context, true);\n}\n\nexport function parseMappingSource(text: string, location: SourceLocation, context?: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n text = text.trim();\n if (text === '$refusal' || text.startsWith('$refusal.')) {\n return { kind: 'RefusalExpressionSyntax', member: text === '$refusal' ? '' : text.substring('$refusal.'.length), location };\n }\n if (text === '$eventSourceId') {\n return { kind: 'EventSourceIdExpressionSyntax', location };\n }\n if (text === '$eventContext.eventSourceId') {\n return { kind: 'EventContextExpressionSyntax', path: 'eventSourceId', location };\n }\n if (text === '$identity' || text === '$identity.') {\n context?.error(DiagnosticCodes.InvalidExpression, `Invalid expression '${text}'`, location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n if (text.startsWith('$identity.')) {\n const path = text.substring('$identity.'.length);\n if (context?.deferIdentityValidation !== true) warnOnUnknownIdentityProperty(path.split('.')[0], '$identity', location, context);\n return { kind: 'IdentityExpressionSyntax', path, location };\n }\n if (text.startsWith('$context.')) {\n const path = text.substring('$context.'.length);\n warnOnUnknownContextPath(path, location, context);\n return { kind: 'ContextExpressionSyntax', path, location };\n }\n if (text.startsWith('$env.')) {\n return { kind: 'EnvironmentExpressionSyntax', name: text.substring('$env.'.length), location };\n }\n if (text.startsWith('$strings.')) {\n return { kind: 'StringsExpressionSyntax', key: text.substring('$strings.'.length), location };\n }\n if (text.startsWith('$.')) {\n return { kind: 'SourceItemExpressionSyntax', path: text.substring('$.'.length), location };\n }\n if (text.startsWith('{') || text.startsWith('[')) {\n // Screenplay has no JSON. The value is still read so the tree stays whole and printing it writes the block form.\n context?.error(DiagnosticCodes.InlineJsonValue, inlineJsonMessage, location);\n try {\n return new StructuredValueParser(text, location, context).parse();\n } catch (error) {\n if (!(error instanceof InvalidStructuredValue)) {\n throw error;\n }\n context?.error(DiagnosticCodes.InvalidStructuredValue, `Invalid inline structured value: ${error.message}`, location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n }\n const literal = context === undefined ? parseLiteral(text, location) : parseLiteral(text, location, context);\n if (literal !== undefined) {\n return literal;\n }\n if ((nativeIdentifiers || context?.sourceOptions.numericMode === 'exact' ? nativePathPattern : pathPattern).test(text)) {\n return { kind: 'PathExpressionSyntax', path: text, location };\n }\n return { kind: 'RawExpressionSyntax', text, location };\n}\n\nfunction warnOnUnknownContextPath(path: string, location: SourceLocation, context: ParserContext | undefined): void {\n const [root, member] = path.split('.');\n if (!contextRoots.includes(root)) {\n context?.warning(DiagnosticCodes.UnknownContextPath, `Unknown $context path '${path}' - expected one of ${contextRoots.join(', ')}`, location);\n } else if (member !== undefined && root === 'causedBy' && !causedByProperties.includes(member)) {\n context?.warning(DiagnosticCodes.UnknownContextCausedByProperty,\n `Unknown $context.causedBy property '${member}' - expected ${causedByProperties.join(', ')}`, location);\n } else if (member !== undefined && root === 'identity') {\n warnOnUnknownIdentityProperty(member, '$context.identity', location, context);\n }\n}\n\nfunction warnOnUnknownIdentityProperty(member: string, root: string, location: SourceLocation, context: ParserContext | undefined): void {\n if (!identityProperties.includes(member)) {\n context?.warning(DiagnosticCodes.UnknownContextIdentityProperty,\n `Unknown ${root} property '${member}' - expected ${identityProperties.join(', ')}`, location);\n }\n}\n\nexport function parseLiteral(text: string, location: SourceLocation): LiteralExpressionSyntax | undefined;\nexport function parseLiteral(text: string, location: SourceLocation, context: ParserContext): ExpressionSyntax | undefined;\nexport function parseLiteral(text: string, location: SourceLocation, context?: ParserContext): ExpressionSyntax | undefined {\n const literal = (value: string | number | boolean | null | ExactNumber): LiteralExpressionSyntax => ({ kind: 'LiteralExpressionSyntax', value, location });\n switch (text) {\n case 'true':\n return literal(true);\n case 'false':\n return literal(false);\n case 'null':\n return literal(null);\n }\n const quoted = text.length >= 2 && ((text.startsWith('\"') && text.endsWith('\"')) || (text.startsWith('\\'') && text.endsWith('\\'')));\n if (quoted) {\n return literal(unescapeString(text.substring(1, text.length - 1)));\n }\n if (context?.sourceOptions.numericMode === 'exact') {\n if (!isExactNumberToken(text)) return undefined;\n const number = parseExactNumber(text);\n if (number !== undefined) return literal(number);\n context.error(DiagnosticCodes.InexactNumericLiteral, 'Numeric literal is not exactly representable in the bounded Decimal domain.', location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n // .NET also parses digits from other scripts; JavaScript's Number does not, so such a number is left to\n // be read as raw text - a divergence no real document is expected to meet.\n if (numberPattern.test(text) && !Number.isNaN(Number(text))) {\n return literal(Number(text));\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ExpressionParser.js","names":["pathPattern","pattern","nativePathPattern","nativePattern","numberPattern","contextRoots","causedByProperties","identityProperties","inlineJsonMessage","text","location","context","DiagnosticCodes","path","StructuredValueParser","error","InvalidStructuredValue","literal","nativeIdentifiers","root","member","unescapeString","isExactNumberToken","number","parseExactNumber"],"sources":["../../../../../../Compiler/Parsing/ExpressionParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { ExpressionSyntax, LiteralExpressionSyntax } from '../Syntax/Expressions';\nimport { ExactNumber, isExactNumberToken, parseExactNumber } from '../Syntax/ExactNumber';\nimport { nativePattern, pattern } from '../Text/patterns';\nimport { unescapeString } from '../Text/StringLiteral';\nimport { ParserContext } from './ParserContext';\nimport { InvalidStructuredValue, StructuredValueParser } from './StructuredValueParser';\n\nconst pathPattern = pattern('^@?[A-Za-z_]\\\\w*(\\\\.@?[A-Za-z_$]\\\\w*)*$');\nconst nativePathPattern = nativePattern('^@?[A-Za-z_]\\\\w*(\\\\.@?[A-Za-z_$]\\\\w*)*$');\nconst numberPattern = pattern('^-?\\\\d+(\\\\.\\\\d+)?$');\nexport const contextRoots = ['command', 'arguments', 'tenant', 'causedBy', 'causation', 'occurred', 'identity'];\nconst causedByProperties = ['subject', 'name', 'userName'];\nexport const identityProperties = ['id', 'name', 'userName', 'isAuthenticated', 'roles', 'claims'];\n\n// Reads the right-hand side of a mapping or a rule operand - the port of the C# ExpressionParser's\n// ParseMappingSource. With a context it also reports what the C# compiler reports while reading one: an\n// unknown $context path, and an inline structured value that is not valid JSON.\nexport const inlineJsonMessage = \"Screenplay has no JSON values - write the object or list as an indented block: one 'member = value' line per member, one 'item' line per list element, and '<name> none' for an empty list\";\n\nexport function parseModeledMappingSource(text: string, location: SourceLocation, context: ParserContext): ExpressionSyntax {\n return parseMappingSource(text, location, context, true);\n}\n\nexport function parseMappingSource(text: string, location: SourceLocation, context?: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n text = text.trim();\n if (text === '$refusal' || text.startsWith('$refusal.')) {\n return { kind: 'RefusalExpressionSyntax', member: text === '$refusal' ? '' : text.substring('$refusal.'.length), location };\n }\n if (text === '$eventSourceId') {\n return { kind: 'EventSourceIdExpressionSyntax', location };\n }\n if (text === '$eventContext.eventSourceId') {\n return { kind: 'EventContextExpressionSyntax', path: 'eventSourceId', location };\n }\n if (text === '$identity' || text === '$identity.') {\n context?.error(DiagnosticCodes.InvalidExpression, `Invalid expression '${text}'`, location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n if (text.startsWith('$identity.')) {\n const path = text.substring('$identity.'.length);\n if (context?.deferIdentityValidation !== true) warnOnUnknownIdentityProperty(path.split('.')[0], '$identity', location, context);\n return { kind: 'IdentityExpressionSyntax', path, location };\n }\n if (text.startsWith('$context.')) {\n const path = text.substring('$context.'.length);\n warnOnUnknownContextPath(path, location, context);\n return { kind: 'ContextExpressionSyntax', path, location };\n }\n if (text.startsWith('$env.')) {\n return { kind: 'EnvironmentExpressionSyntax', name: text.substring('$env.'.length), location };\n }\n if (text.startsWith('$strings.')) {\n return { kind: 'StringsExpressionSyntax', key: text.substring('$strings.'.length), location };\n }\n if (text.startsWith('$.')) {\n return { kind: 'SourceItemExpressionSyntax', path: text.substring('$.'.length), location };\n }\n if (text.startsWith('{') || text.startsWith('[')) {\n // Screenplay has no JSON. The value is still read so the tree stays whole and printing it writes the block form.\n context?.error(DiagnosticCodes.InlineJsonValue, inlineJsonMessage, location);\n try {\n return new StructuredValueParser(text, location, context).parse();\n } catch (error) {\n if (!(error instanceof InvalidStructuredValue)) {\n throw error;\n }\n context?.error(DiagnosticCodes.InvalidStructuredValue, `Invalid inline structured value: ${error.message}`, location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n }\n const literal = context === undefined ? parseLiteral(text, location) : parseLiteral(text, location, context);\n if (literal !== undefined) {\n return literal;\n }\n if ((nativeIdentifiers || context?.sourceOptions.numericMode === 'exact' ? nativePathPattern : pathPattern).test(text)) {\n return { kind: 'PathExpressionSyntax', path: text, location };\n }\n return { kind: 'RawExpressionSyntax', text, location };\n}\n\nfunction warnOnUnknownContextPath(path: string, location: SourceLocation, context: ParserContext | undefined): void {\n const [root, member] = path.split('.');\n if (!contextRoots.includes(root)) {\n context?.warning(DiagnosticCodes.UnknownContextPath, `Unknown $context path '${path}' - expected one of ${contextRoots.join(', ')}`, location);\n } else if (member !== undefined && root === 'causedBy' && !causedByProperties.includes(member)) {\n context?.warning(DiagnosticCodes.UnknownContextCausedByProperty,\n `Unknown $context.causedBy property '${member}' - expected ${causedByProperties.join(', ')}`, location);\n } else if (member !== undefined && root === 'identity') {\n warnOnUnknownIdentityProperty(member, '$context.identity', location, context);\n }\n}\n\nfunction warnOnUnknownIdentityProperty(member: string, root: string, location: SourceLocation, context: ParserContext | undefined): void {\n if (!identityProperties.includes(member)) {\n context?.warning(DiagnosticCodes.UnknownContextIdentityProperty,\n `Unknown ${root} property '${member}' - expected ${identityProperties.join(', ')}`, location);\n }\n}\n\nexport function parseLiteral(text: string, location: SourceLocation): LiteralExpressionSyntax | undefined;\nexport function parseLiteral(text: string, location: SourceLocation, context: ParserContext): ExpressionSyntax | undefined;\nexport function parseLiteral(text: string, location: SourceLocation, context?: ParserContext): ExpressionSyntax | undefined {\n const literal = (value: string | number | boolean | null | ExactNumber): LiteralExpressionSyntax => ({ kind: 'LiteralExpressionSyntax', value, location });\n switch (text) {\n case 'true':\n return literal(true);\n case 'false':\n return literal(false);\n case 'null':\n return literal(null);\n }\n const quoted = text.length >= 2 && ((text.startsWith('\"') && text.endsWith('\"')) || (text.startsWith('\\'') && text.endsWith('\\'')));\n if (quoted) {\n return literal(unescapeString(text.substring(1, text.length - 1)));\n }\n if (context?.sourceOptions.numericMode === 'exact') {\n if (!isExactNumberToken(text)) return undefined;\n const number = parseExactNumber(text);\n if (number !== undefined) return literal(number);\n context.error(DiagnosticCodes.InexactNumericLiteral, 'Numeric literal is not exactly representable in the bounded Decimal domain.', location);\n return { kind: 'RawExpressionSyntax', text, location };\n }\n // .NET also parses digits from other scripts; JavaScript's Number does not, so such a number is left to\n // be read as raw text - a divergence no real document is expected to meet.\n if (numberPattern.test(text) && !Number.isNaN(Number(text))) {\n return literal(Number(text));\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{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 C}from"./DeclarationParsers.js";import{parseSystem as te}from"./OperationParser.js";import{parseExample as ne}from"./SpecificationExampleParser.js";import{parseValidate as w}from"./CommandParser.js";import{parseTriggerDeclaration as re}from"./TriggerDataParser.js";import{FeatureBody as T,featureBodyExpected as E}from"./FeatureBody.js";import{ModuleBody as ie,moduleBodyExpected as D,modulePattern as O,parseModule as ae}from"./ModuleBody.js";import{EnumerationMembers as k}from"./EnumerationMembers.js";import{parseGeneration as A}from"./GenerationParser.js";import{parseIdentity as oe}from"./IdentityParser.js";import{parsePolicy as j}from"./PolicyParser.js";import{parseSeed as M}from"./SeedParser.js";import{parseStateMachine as se}from"./StateMachineParser.js";import{parseWorkflow as ce}from"./WorkflowParser.js";import{parseExposure as le,parseInstance as ue}from"./CompositionParser.js";import{parseUiProfile as N}from"./UiProfileLegacyLayout.js";const P=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),de=r(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${t})"$`),F=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),I=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),L=r(`^@?[a-z_]\\w*$`),R=r(`^persona\\s+([A-Za-z_]\\w*)$`),z=r(`^policy\\s+([A-Za-z_]\\w*)$`),B=r(`^goal\\s+"(${t})"$`),V=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),H=r(`^colour\\s+(yellow|pink|green|blue)$`),U=/^[ ]*\t/,W=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],G=/* @__PURE__ */ new Set([`policy`,`authentication`,`onboarding`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),K=/* @__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 ie(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,w=null,E=!1,D=!1,O=null,k=[],A=[],P=[],I=[],L=[],R=[],z=[],B=[],V=[],H=[],U=[],W=[],K=[],q=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))D||!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`,D=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(r.content)){let o=de.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)):w={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,O=parseDomain(t,r,O,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,A):l.tryParse(t,r);else if(s===`import`){let a=F.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)),k.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(ne(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(ee(t,r));else if(s===`system`)L.push(te(t,r));else if(s===`statemachine`)R.push(se(t,r));else if(s===`workflow`)z.push(ce(t,r));else if(s===`concept`)P.push(parseConcept(t,r));else if(s===`type`)I.push(C(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(ae(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`)q.push(M(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)K.push(m(t,r));else if(s===`identity`)u=oe(t,r,u);else if(s===`policy`){let n=j(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(le(t,r));else if(s===`instance`)Z.push(ue(t,r));else if(s===`trigger`){let e=re(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else G.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?N(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},...w===null?{}:{timeZone:w},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:O,imports:k,concepts:P,types:I,systems:L,...R.length>0?{stateMachines:R}:{},...z.length>0?{workflows:z}:{},eventSources:B,examples:J,modules:V,personas:H,policies:W,purposes:K,seeds:q,declaredTriggers:Y,fileImports:A,...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`?F.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===`statemachine`||e===`workflow`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||G.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=O.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=K.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, onboarding, 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?D: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=P.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&&U.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=I.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`&&!W.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${W.join(`, `)} or Enum`,i(n));let m=[],h=new k,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=w(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=A(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&L.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=R.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=B.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=z.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=V.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=H.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 te}from"../Syntax/PublicEventInvariants.js";import{parseType as ne}from"./DeclarationParsers.js";import{parseSystem as re}from"./OperationParser.js";import{parseExample as ie}from"./SpecificationExampleParser.js";import{parseValidate as S}from"./CommandParser.js";import{parseTriggerDeclaration as ae}from"./TriggerDataParser.js";import{FeatureBody as C,featureBodyExpected as w}from"./FeatureBody.js";import{ModuleBody as oe,moduleBodyExpected as T,modulePattern as E,parseModule as D}from"./ModuleBody.js";import{EnumerationMembers as O}from"./EnumerationMembers.js";import{parseGeneration as k}from"./GenerationParser.js";import{parseIdentity as se}from"./IdentityParser.js";import{parseApplicationContext as ce}from"./ApplicationContextParser.js";import{parsePolicy as le}from"./PolicyParser.js";import{parseSeed as ue}from"./SeedParser.js";import{parseStateMachine as de}from"./StateMachineParser.js";import{parseWorkflow as fe}from"./WorkflowParser.js";import{parseExposure as A,parseInstance as j}from"./CompositionParser.js";import{parseUiProfile as M}from"./UiProfileLegacyLayout.js";const N=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),pe=r(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${t})"$`),P=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),F=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),I=r(`^@?[a-z_]\\w*$`),L=r(`^persona\\s+([A-Za-z_]\\w*)$`),R=r(`^policy\\s+([A-Za-z_]\\w*)$`),z=r(`^goal\\s+"(${t})"$`),B=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),V=r(`^colour\\s+(yellow|pink|green|blue)$`),H=/^[ ]*\t/,U=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],W=/* @__PURE__ */ new Set([`policy`,`authentication`,`onboarding`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),G=/* @__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 oe(a[0]):void 0,s=a.length>1?new C(a[a.length-1]):void 0,l=o??s,u=null,p=null,b=null,x=!1,S=null,w=null,T=!1,E=!1,O=null,k=[],N=[],F=[],I=[],L=[],R=[],z=[],B=[],V=[],H=[],U=[],G=[],K=[],q=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))E||!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)):S=`Protected`,E=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(r.content)){let o=pe.exec(r.content);t.skipBlock(r.indent),T||!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)):w={kind:`TimeZoneSyntax`,id:n(o[2]),configurable:o[1]!==void 0,location:i(r)},T=!0}else if(s===`reaction`)x||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):b=`Atomic`,x=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,O=parseDomain(t,r,O,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,N):l.tryParse(t,r);else if(s===`import`){let a=P.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&&te(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),k.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?J.push(ie(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(ee(t,r));else if(s===`system`)L.push(re(t,r));else if(s===`statemachine`)R.push(de(t,r));else if(s===`workflow`)z.push(fe(t,r));else if(s===`concept`)F.push(parseConcept(t,r));else if(s===`type`)I.push(ne(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(D(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`)q.push(ue(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)K.push(m(t,r));else if(s===`context`)p=ce(t,r,p,a);else if(s===`identity`)u=se(t,r,u);else if(s===`policy`){let n=le(t,r);G.some(e=>e.name===n.name)&&t.error(e.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),G.push(n)}else if(s===`exposure`)X.push(A(t,r));else if(s===`instance`)Z.push(j(t,r));else if(s===`trigger`){let e=ae(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else W.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?M(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`,...S===null?{}:{commandReadMode:S},...w===null?{}:{timeZone:w},...p===null?{}:{context:p},...b===null?{}:{reactionProductionMode:b},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:O,imports:k,concepts:F,types:I,systems:L,...R.length>0?{stateMachines:R}:{},...z.length>0?{workflows:z}:{},eventSources:B,examples:J,modules:V,personas:H,policies:G,purposes:K,seeds:q,declaredTriggers:Y,fileImports:N,...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`?P.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`context`?t.content===`context`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`statemachine`||e===`workflow`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||W.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=E.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=G.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, onboarding, identity, context, 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?T:w;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=N.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&&H.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=F.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`&&!U.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${U.join(`, `)} or Enum`,i(n));let m=[],h=new O,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=S(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=k(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&I.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=L.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=z.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=R.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=B.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=V.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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","timeZonePattern","stringBodyPattern","importPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","personaGoalPattern","stickyNotePattern","stickyNoteColourPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","reactionProductionMode","sawReactionBatches","commandReadMode","timeZone","sawTimeZone","sawCommandReads","domain","imports","fileImports","concepts","types","systems","stateMachines","workflows","eventSources","modules","personas","stickyNotes","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","match","unescapeString","misplacedReactionIdentity","isFileImport","parseFileImport","origin","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseStateMachine","parseWorkflow","parseType","parseModule","stickyNote","parseSeed","parsePurpose","parseIdentity","policy","parsePolicy","previous","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","parseUiProfile","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","goals","position","size","goal","parseCanvasPair","canvasMatch","text","colour"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandReadMode } from '../Syntax/CommandReadMode';\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax, StickyNoteSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { TimeZoneSyntax } from '../Syntax/Calendar';\nimport { ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { parseStateMachine } from './StateMachineParser';\nimport { parseWorkflow } from './WorkflowParser';\nimport { StateMachineSyntax, WorkflowSyntax } from '../Syntax/Lifecycles';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { parseUiProfile } from './UiProfileLegacyLayout';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst timeZonePattern = pattern(`^time\\\\s+zone\\\\s+(configurable\\\\s+default\\\\s+)?\"(${stringBodyPattern})\"$`);\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaGoalPattern = pattern(`^goal\\\\s+\"(${stringBodyPattern})\"$`);\nconst stickyNotePattern = pattern('^sticky\\\\s+note\\\\s+on\\\\s+(personas|eventsources|givencontexts|seeddata)$');\nconst stickyNoteColourPattern = pattern('^colour\\\\s+(yellow|pink|green|blue)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'onboarding', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let commandReadMode: CommandReadMode | null = null;\n let timeZone: TimeZoneSyntax | null = null;\n let sawTimeZone = false;\n let sawCommandReads = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const stateMachines: StateMachineSyntax[] = [];\n const workflows: WorkflowSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const stickyNotes: StickyNoteSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'command' && /^command\\s+reads(?:\\s|$)/.test(line.content)) {\n if (sawCommandReads || !isDocumentPlacement(placement) || !/^command\\s+reads\\s+protected$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidCommandReadsDeclaration, \"Declare 'command reads protected' once at the application root.\", locationOf(line));\n } else {\n commandReadMode = CommandReadMode.Protected;\n }\n sawCommandReads = true;\n continue;\n }\n if (keyword === 'time' && /^time\\s+zone(?:\\s|$)/.test(line.content)) {\n const match = timeZonePattern.exec(line.content);\n context.skipBlock(line.indent);\n if (sawTimeZone || !isDocumentPlacement(placement) || match === null) {\n context.error(DiagnosticCodes.InvalidTimeZoneDeclaration, \"Declare 'time zone \\\"<id>\\\"' or 'time zone configurable default \\\"<id>\\\"' once at the application root.\", locationOf(line));\n } else {\n timeZone = { kind: 'TimeZoneSyntax', id: unescapeString(match[2]), configurable: match[1] !== undefined, location: locationOf(line) };\n }\n sawTimeZone = true;\n continue;\n }\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'statemachine') {\n stateMachines.push(parseStateMachine(context, line));\n } else if (keyword === 'workflow') {\n workflows.push(parseWorkflow(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'sticky') {\n const stickyNote = parseStickyNote(context, line);\n if (stickyNote !== null) stickyNotes.push(stickyNote);\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n const policy = parsePolicy(context, line);\n if (policies.some(previous => previous.name === policy.name)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Duplicate declaration of policy '${policy.name}' - policy names must be unique`, policy.location);\n }\n policies.push(policy);\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else if (keyword === 'ui') parseUiProfile(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(commandReadMode === null ? {} : { commandReadMode }), ...(timeZone === null ? {} : { timeZone }), ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, ...(stateMachines.length > 0 ? { stateMachines } : {}), ...(workflows.length > 0 ? { workflows } : {}), eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(stickyNotes.length > 0 ? { stickyNotes } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'statemachine' || keyword === 'workflow' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || keyword === 'sticky' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, sticky note, authentication, onboarding, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept', name);\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n const goals: string[] = [];\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Persona '${name}'`);\n } else if (keyword === 'goal') {\n const goal = personaGoalPattern.exec(child.content);\n if (goal === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid goal '${child.content}' - expected 'goal \"<text>\"'`, locationOf(child));\n } else {\n goals.push(unescapeString(goal[1]));\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description, goal, policy, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return {\n kind: 'PersonaSyntax', name, description, policies,\n ...(goals.length > 0 ? { goals } : {}),\n ...(position === null ? {} : { x: position[0], y: position[1] }),\n ...(size === null ? {} : { width: size[0], height: size[1] }),\n location: locationOf(line),\n };\n}\n\n// 'sticky note on <canvas>' with the text it carries, an optional colour and where it sits on that canvas - the port of the C# ParseStickyNote.\nfunction parseStickyNote(context: ParserContext, line: SourceLine): StickyNoteSyntax | null {\n const canvasMatch = stickyNotePattern.exec(line.content);\n if (canvasMatch === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid sticky note declaration '${line.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`, locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n let text: string | null = null;\n let colour: string | null = null;\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n text = parseDescription(context, child, text, 'A sticky note');\n } else if (keyword === 'colour') {\n const match = stickyNoteColourPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid colour '${child.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`, locationOf(child));\n } else {\n colour = match[1];\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in sticky note body - expected description, colour, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n if (text === null || position === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, 'A sticky note needs a description (the text on it) and a position', locationOf(line));\n return null;\n }\n return { kind: 'StickyNoteSyntax', canvas: canvasMatch[1] as StickyNoteSyntax['canvas'], text, colour, x: position[0], y: position[1], width: size === null ? null : size[0], height: size === null ? null : size[1], location: locationOf(line) };\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","timeZonePattern","stringBodyPattern","importPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","personaGoalPattern","stickyNotePattern","stickyNoteColourPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","applicationContext","reactionProductionMode","sawReactionBatches","commandReadMode","timeZone","sawTimeZone","sawCommandReads","domain","imports","fileImports","concepts","types","systems","stateMachines","workflows","eventSources","modules","personas","stickyNotes","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","match","unescapeString","misplacedReactionIdentity","isFileImport","parseFileImport","origin","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseStateMachine","parseWorkflow","parseType","parseModule","stickyNote","parseSeed","parsePurpose","parseApplicationContext","parseIdentity","policy","parsePolicy","previous","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","parseUiProfile","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","goals","position","size","goal","parseCanvasPair","canvasMatch","text","colour"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandReadMode } from '../Syntax/CommandReadMode';\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { parseApplicationContext } from './ApplicationContextParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax, StickyNoteSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { TimeZoneSyntax } from '../Syntax/Calendar';\nimport { ApplicationContextSyntax, ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { parseStateMachine } from './StateMachineParser';\nimport { parseWorkflow } from './WorkflowParser';\nimport { StateMachineSyntax, WorkflowSyntax } from '../Syntax/Lifecycles';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { parseUiProfile } from './UiProfileLegacyLayout';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst timeZonePattern = pattern(`^time\\\\s+zone\\\\s+(configurable\\\\s+default\\\\s+)?\"(${stringBodyPattern})\"$`);\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaGoalPattern = pattern(`^goal\\\\s+\"(${stringBodyPattern})\"$`);\nconst stickyNotePattern = pattern('^sticky\\\\s+note\\\\s+on\\\\s+(personas|eventsources|givencontexts|seeddata)$');\nconst stickyNoteColourPattern = pattern('^colour\\\\s+(yellow|pink|green|blue)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'onboarding', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let applicationContext: ApplicationContextSyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let commandReadMode: CommandReadMode | null = null;\n let timeZone: TimeZoneSyntax | null = null;\n let sawTimeZone = false;\n let sawCommandReads = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const stateMachines: StateMachineSyntax[] = [];\n const workflows: WorkflowSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const stickyNotes: StickyNoteSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'command' && /^command\\s+reads(?:\\s|$)/.test(line.content)) {\n if (sawCommandReads || !isDocumentPlacement(placement) || !/^command\\s+reads\\s+protected$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidCommandReadsDeclaration, \"Declare 'command reads protected' once at the application root.\", locationOf(line));\n } else {\n commandReadMode = CommandReadMode.Protected;\n }\n sawCommandReads = true;\n continue;\n }\n if (keyword === 'time' && /^time\\s+zone(?:\\s|$)/.test(line.content)) {\n const match = timeZonePattern.exec(line.content);\n context.skipBlock(line.indent);\n if (sawTimeZone || !isDocumentPlacement(placement) || match === null) {\n context.error(DiagnosticCodes.InvalidTimeZoneDeclaration, \"Declare 'time zone \\\"<id>\\\"' or 'time zone configurable default \\\"<id>\\\"' once at the application root.\", locationOf(line));\n } else {\n timeZone = { kind: 'TimeZoneSyntax', id: unescapeString(match[2]), configurable: match[1] !== undefined, location: locationOf(line) };\n }\n sawTimeZone = true;\n continue;\n }\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'statemachine') {\n stateMachines.push(parseStateMachine(context, line));\n } else if (keyword === 'workflow') {\n workflows.push(parseWorkflow(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'sticky') {\n const stickyNote = parseStickyNote(context, line);\n if (stickyNote !== null) stickyNotes.push(stickyNote);\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'context') {\n applicationContext = parseApplicationContext(context, line, applicationContext, placement);\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n const policy = parsePolicy(context, line);\n if (policies.some(previous => previous.name === policy.name)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Duplicate declaration of policy '${policy.name}' - policy names must be unique`, policy.location);\n }\n policies.push(policy);\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else if (keyword === 'ui') parseUiProfile(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(commandReadMode === null ? {} : { commandReadMode }), ...(timeZone === null ? {} : { timeZone }), ...(applicationContext === null ? {} : { context: applicationContext }), ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, ...(stateMachines.length > 0 ? { stateMachines } : {}), ...(workflows.length > 0 ? { workflows } : {}), eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(stickyNotes.length > 0 ? { stickyNotes } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n if (keyword === 'context') return line.content === 'context';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'statemachine' || keyword === 'workflow' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || keyword === 'sticky' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, sticky note, authentication, onboarding, identity, context, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept', name);\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n const goals: string[] = [];\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Persona '${name}'`);\n } else if (keyword === 'goal') {\n const goal = personaGoalPattern.exec(child.content);\n if (goal === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid goal '${child.content}' - expected 'goal \"<text>\"'`, locationOf(child));\n } else {\n goals.push(unescapeString(goal[1]));\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description, goal, policy, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return {\n kind: 'PersonaSyntax', name, description, policies,\n ...(goals.length > 0 ? { goals } : {}),\n ...(position === null ? {} : { x: position[0], y: position[1] }),\n ...(size === null ? {} : { width: size[0], height: size[1] }),\n location: locationOf(line),\n };\n}\n\n// 'sticky note on <canvas>' with the text it carries, an optional colour and where it sits on that canvas - the port of the C# ParseStickyNote.\nfunction parseStickyNote(context: ParserContext, line: SourceLine): StickyNoteSyntax | null {\n const canvasMatch = stickyNotePattern.exec(line.content);\n if (canvasMatch === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid sticky note declaration '${line.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`, locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n let text: string | null = null;\n let colour: string | null = null;\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n text = parseDescription(context, child, text, 'A sticky note');\n } else if (keyword === 'colour') {\n const match = stickyNoteColourPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid colour '${child.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`, locationOf(child));\n } else {\n colour = match[1];\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in sticky note body - expected description, colour, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n if (text === null || position === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, 'A sticky note needs a description (the text on it) and a position', locationOf(line));\n return null;\n }\n return { kind: 'StickyNoteSyntax', canvas: canvasMatch[1] as StickyNoteSyntax['canvas'], text, colour, x: position[0], y: position[1], width: size === null ? null : size[0], height: size === null ? null : size[1], location: locationOf(line) };\n}\n\n"],"mappings":"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"}
|