@cratis/screenplay-language 4.52.0 → 4.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +15 -0
  2. package/dist/TypeReferenceSymbol.d.ts +8 -0
  3. package/dist/TypeReferenceSymbol.d.ts.map +1 -0
  4. package/dist/bundles/chunk-GJX4NJYC.js +4836 -0
  5. package/dist/bundles/chunk-GJX4NJYC.js.map +7 -0
  6. package/dist/bundles/index.js +1417 -0
  7. package/dist/bundles/index.js.map +7 -0
  8. package/dist/bundles/sub-languages/capture/index.js +677 -0
  9. package/dist/bundles/sub-languages/capture/index.js.map +7 -0
  10. package/dist/bundles/sub-languages/projection/index.js +1647 -0
  11. package/dist/bundles/sub-languages/projection/index.js.map +7 -0
  12. package/dist/code-actions.d.ts +3 -0
  13. package/dist/code-actions.d.ts.map +1 -0
  14. package/dist/completion-items.d.ts +1 -0
  15. package/dist/completion-items.d.ts.map +1 -1
  16. package/dist/completion-planner.d.ts.map +1 -1
  17. package/dist/completions.d.ts.map +1 -1
  18. package/dist/diagnostic-codes.d.ts +3 -0
  19. package/dist/diagnostic-codes.d.ts.map +1 -1
  20. package/dist/diagnostics.d.ts.map +1 -1
  21. package/dist/hover-content.d.ts.map +1 -1
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/keyword-docs.d.ts.map +1 -1
  25. package/dist/language.d.ts +1 -0
  26. package/dist/language.d.ts.map +1 -1
  27. package/dist/production-destinations.d.ts.map +1 -1
  28. package/dist/symbols.d.ts +4 -0
  29. package/dist/symbols.d.ts.map +1 -1
  30. package/dist/tokens.d.ts.map +1 -1
  31. package/dist/validation.d.ts +1 -0
  32. package/dist/validation.d.ts.map +1 -1
  33. package/package.json +13 -9
  34. package/DestinationHint.ts +0 -8
  35. package/ProductionSymbol.ts +0 -11
  36. package/completion-items.ts +0 -261
  37. package/completion-planner.ts +0 -167
  38. package/completions.ts +0 -156
  39. package/diagnostic-codes.ts +0 -43
  40. package/diagnostics.ts +0 -55
  41. package/dist/DestinationHint.js +0 -4
  42. package/dist/DestinationHint.js.map +0 -1
  43. package/dist/ProductionSymbol.js +0 -4
  44. package/dist/ProductionSymbol.js.map +0 -1
  45. package/dist/completion-items.js +0 -228
  46. package/dist/completion-items.js.map +0 -1
  47. package/dist/completion-planner.js +0 -143
  48. package/dist/completion-planner.js.map +0 -1
  49. package/dist/completions.js +0 -101
  50. package/dist/completions.js.map +0 -1
  51. package/dist/diagnostic-codes.js +0 -41
  52. package/dist/diagnostic-codes.js.map +0 -1
  53. package/dist/diagnostics.js +0 -50
  54. package/dist/diagnostics.js.map +0 -1
  55. package/dist/document-context.js +0 -85
  56. package/dist/document-context.js.map +0 -1
  57. package/dist/event-analysis-source.js +0 -19
  58. package/dist/event-analysis-source.js.map +0 -1
  59. package/dist/event-context-catalog.js +0 -116
  60. package/dist/event-context-catalog.js.map +0 -1
  61. package/dist/event-context.js +0 -88
  62. package/dist/event-context.js.map +0 -1
  63. package/dist/file-imports.js +0 -58
  64. package/dist/file-imports.js.map +0 -1
  65. package/dist/file-references.js +0 -70
  66. package/dist/file-references.js.map +0 -1
  67. package/dist/hover-content.js +0 -98
  68. package/dist/hover-content.js.map +0 -1
  69. package/dist/hover.js +0 -15
  70. package/dist/hover.js.map +0 -1
  71. package/dist/index.js +0 -61
  72. package/dist/index.js.map +0 -1
  73. package/dist/inlay-hints.js +0 -15
  74. package/dist/inlay-hints.js.map +0 -1
  75. package/dist/inline-event-validation.js +0 -131
  76. package/dist/inline-event-validation.js.map +0 -1
  77. package/dist/keyword-docs.js +0 -148
  78. package/dist/keyword-docs.js.map +0 -1
  79. package/dist/language.js +0 -196
  80. package/dist/language.js.map +0 -1
  81. package/dist/production-destinations.js +0 -32
  82. package/dist/production-destinations.js.map +0 -1
  83. package/dist/sub-language-registry.js +0 -18
  84. package/dist/sub-language-registry.js.map +0 -1
  85. package/dist/sub-languages/capture/CompletionProvider.js +0 -332
  86. package/dist/sub-languages/capture/CompletionProvider.js.map +0 -1
  87. package/dist/sub-languages/capture/HoverProvider.js +0 -87
  88. package/dist/sub-languages/capture/HoverProvider.js.map +0 -1
  89. package/dist/sub-languages/capture/Validator.js +0 -72
  90. package/dist/sub-languages/capture/Validator.js.map +0 -1
  91. package/dist/sub-languages/capture/index.js +0 -58
  92. package/dist/sub-languages/capture/index.js.map +0 -1
  93. package/dist/sub-languages/capture/language.js +0 -160
  94. package/dist/sub-languages/capture/language.js.map +0 -1
  95. package/dist/sub-languages/cdl.js +0 -74
  96. package/dist/sub-languages/cdl.js.map +0 -1
  97. package/dist/sub-languages/pdl.js +0 -73
  98. package/dist/sub-languages/pdl.js.map +0 -1
  99. package/dist/sub-languages/projection/CodeActionProvider.js +0 -93
  100. package/dist/sub-languages/projection/CodeActionProvider.js.map +0 -1
  101. package/dist/sub-languages/projection/CompletionProvider.js +0 -595
  102. package/dist/sub-languages/projection/CompletionProvider.js.map +0 -1
  103. package/dist/sub-languages/projection/HoverProvider.js +0 -333
  104. package/dist/sub-languages/projection/HoverProvider.js.map +0 -1
  105. package/dist/sub-languages/projection/Validator.js +0 -388
  106. package/dist/sub-languages/projection/Validator.js.map +0 -1
  107. package/dist/sub-languages/projection/index.js +0 -160
  108. package/dist/sub-languages/projection/index.js.map +0 -1
  109. package/dist/sub-languages/projection/language.js +0 -171
  110. package/dist/sub-languages/projection/language.js.map +0 -1
  111. package/dist/symbols.js +0 -275
  112. package/dist/symbols.js.map +0 -1
  113. package/dist/themes/screenplay-dark.js +0 -30
  114. package/dist/themes/screenplay-dark.js.map +0 -1
  115. package/dist/themes/screenplay-light.js +0 -30
  116. package/dist/themes/screenplay-light.js.map +0 -1
  117. package/dist/tokens.js +0 -147
  118. package/dist/tokens.js.map +0 -1
  119. package/dist/validation.js +0 -248
  120. package/dist/validation.js.map +0 -1
  121. package/document-context.ts +0 -93
  122. package/event-analysis-source.ts +0 -18
  123. package/event-context-catalog.ts +0 -135
  124. package/event-context.ts +0 -119
  125. package/file-imports.ts +0 -70
  126. package/file-references.ts +0 -87
  127. package/for_documentContext/when_stripping_comments.ts +0 -32
  128. package/for_eventContext/when_resolving_generated_catalog_vectors.ts +0 -15
  129. package/for_eventGenerations/when_editing_event_generations.ts +0 -57
  130. package/for_fileImports/when_finding_file_imports.ts +0 -38
  131. package/for_fileReferences/when_recognizing_an_absolute_path/with_paths_of_every_shape.ts +0 -26
  132. package/for_fileReferences/when_scanning_a_document/inside_a_code_fence.ts +0 -26
  133. package/for_fileReferences/when_scanning_a_document/with_a_bare_file_keyword.ts +0 -19
  134. package/for_fileReferences/when_scanning_a_document/with_a_file_directive.ts +0 -30
  135. package/for_fileReferences/when_scanning_a_document/with_a_property_named_file.ts +0 -25
  136. package/for_fileReferences/when_scanning_a_document/with_a_trailing_comment.ts +0 -25
  137. package/for_fileReferences/when_scanning_a_document/with_directives_on_several_constructs.ts +0 -41
  138. package/for_importablePaths/when_listing_what_a_document_can_import.ts +0 -34
  139. package/for_inlineEvents/when_analyzing_many_inline_events.ts +0 -59
  140. package/for_inlineEvents/when_authoring_inline_events.ts +0 -149
  141. package/for_inlineEvents/when_completing_many_events.ts +0 -49
  142. package/for_inlineEvents/when_indexing_command_production_ownership.ts +0 -79
  143. package/for_planCompletions/when_completing_a_file_import.ts +0 -26
  144. package/for_planCompletions/when_completing_a_specification_query.ts +0 -24
  145. package/for_planCompletions/when_completing_a_specification_step.ts +0 -42
  146. package/for_planCompletions/when_completing_an_absent_read_model.ts +0 -14
  147. package/for_planCompletions/when_completing_reaction_reads.ts +0 -36
  148. package/for_projectionCompletionProvider/when_completing_an_event_context_path.ts +0 -102
  149. package/for_projectionHoverProvider/when_hovering_an_event_context_path.ts +0 -44
  150. package/for_projectionValidator/when_validating_a_projection_with_variants.ts +0 -128
  151. package/for_projectionValidator/when_validating_event_context_paths.ts +0 -31
  152. package/for_scanDocument/when_scanning_a_query/with_a_dotted_return_type.ts +0 -34
  153. package/for_scanDocument/when_scanning_aliased_reads.ts +0 -33
  154. package/for_scanDocument/when_scanning_many_commands.ts +0 -47
  155. package/for_tokens/when_highlighting_a_file_import.ts +0 -18
  156. package/for_tokens/when_highlighting_event_metadata.ts +0 -63
  157. package/for_tokens/when_highlighting_specification_steps.ts +0 -28
  158. package/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts +0 -77
  159. package/for_validateLines/when_validating_a_document/with_an_unknown_policy.ts +0 -33
  160. package/for_validateLines/when_validating_a_file_placed_by_an_import/with_names_declared_in_other_files.ts +0 -43
  161. package/for_validateLines/when_validating_event_context_paths/in_a_projection.ts +0 -97
  162. package/for_validateLines/when_validating_file_imports/at_every_level.ts +0 -36
  163. package/for_validateLines/when_validating_production_destinations/with_an_available_identifier.ts +0 -120
  164. package/hover-content.ts +0 -117
  165. package/hover.ts +0 -23
  166. package/index.ts +0 -125
  167. package/inlay-hints.ts +0 -17
  168. package/inline-event-validation.ts +0 -115
  169. package/keyword-docs.ts +0 -152
  170. package/language.ts +0 -212
  171. package/production-destinations.ts +0 -32
  172. package/sub-language-registry.ts +0 -42
  173. package/sub-languages/capture/CompletionProvider.ts +0 -365
  174. package/sub-languages/capture/HoverProvider.ts +0 -99
  175. package/sub-languages/capture/Validator.ts +0 -97
  176. package/sub-languages/capture/index.ts +0 -72
  177. package/sub-languages/capture/language.ts +0 -176
  178. package/sub-languages/cdl.ts +0 -76
  179. package/sub-languages/pdl.ts +0 -75
  180. package/sub-languages/projection/CodeActionProvider.ts +0 -123
  181. package/sub-languages/projection/CompletionProvider.ts +0 -660
  182. package/sub-languages/projection/HoverProvider.ts +0 -377
  183. package/sub-languages/projection/Validator.ts +0 -441
  184. package/sub-languages/projection/index.ts +0 -223
  185. package/sub-languages/projection/language.ts +0 -193
  186. package/symbols.ts +0 -374
  187. package/themes/screenplay-dark.ts +0 -33
  188. package/themes/screenplay-light.ts +0 -33
  189. package/tokens.ts +0 -174
  190. package/validation.ts +0 -443
  191. package/vitest.setup.ts +0 -5
@@ -1,193 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import type { languages } from 'monaco-editor';
5
-
6
- export const languageId = 'pdl';
7
-
8
- // Keywords for the Projection Declaration Language
9
- const KEYWORDS = [
10
- 'projection',
11
- 'sequence',
12
- 'all',
13
- 'every',
14
- 'on',
15
- 'from',
16
- 'key',
17
- 'parent',
18
- 'join',
19
- 'automap',
20
- 'no',
21
- 'children',
22
- 'nested',
23
- 'identified',
24
- 'by',
25
- 'add',
26
- 'subtract',
27
- 'remove',
28
- 'via',
29
- 'with',
30
- 'default',
31
- 'increment',
32
- 'decrement',
33
- 'count',
34
- 'set',
35
- 'unset',
36
- 'clear',
37
- 'events',
38
- 'id',
39
- 'exclude',
40
- 'variant',
41
- 'enters',
42
- ] as const;
43
-
44
- // Built-in expressions and functions
45
- const BUILTINS = [
46
- '$eventSourceId',
47
- '$causedBy',
48
- '$eventContext',
49
- ] as const;
50
-
51
- // Operators
52
- const OPERATORS = ['=', '+=', '-=', '=>', '.'];
53
-
54
- export const configuration: languages.LanguageConfiguration = {
55
- comments: {
56
- lineComment: '#',
57
- },
58
- brackets: [
59
- ['{', '}'],
60
- ['[', ']'],
61
- ['(', ')'],
62
- ],
63
- autoClosingPairs: [
64
- { open: '{', close: '}' },
65
- { open: '[', close: ']' },
66
- { open: '(', close: ')' },
67
- { open: '"', close: '"' },
68
- { open: "'", close: "'" },
69
- { open: '`', close: '`' },
70
- ],
71
- surroundingPairs: [
72
- { open: '{', close: '}' },
73
- { open: '[', close: ']' },
74
- { open: '(', close: ')' },
75
- { open: '"', close: '"' },
76
- { open: "'", close: "'" },
77
- { open: '`', close: '`' },
78
- ],
79
- indentationRules: {
80
- increaseIndentPattern: /^.*(:|\bon\b|\ball\b|\bevery\b|\bchildren\b|\bnested\b|\bparent\b|\bvariant\b)\s*$/,
81
- decreaseIndentPattern: /^.*\}.*$/,
82
- },
83
- folding: {
84
- offSide: true,
85
- markers: {
86
- start: /^\s*(projection|all|every|on|children|nested|parent|variant)/,
87
- end: /^\s*$/,
88
- },
89
- },
90
- wordPattern: /@?[a-zA-Z_$][\w$-]*/,
91
- };
92
-
93
- export const monarchLanguage: languages.IMonarchLanguage = {
94
- defaultToken: '',
95
- tokenPostfix: '.pdl',
96
-
97
- keywords: KEYWORDS,
98
- builtins: BUILTINS,
99
- operators: OPERATORS,
100
-
101
- // Symbols
102
- symbols: /[=><!~?:&|+\-*/^%]+/,
103
- escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
104
-
105
- tokenizer: {
106
- root: [
107
- // Whitespace
108
- { include: '@whitespace' },
109
-
110
- // Template strings with ${...} interpolation
111
- [/`/, { token: 'string.template', next: '@templateString' }],
112
-
113
- // Escaped identifiers (@ prefix allows using keywords as identifiers)
114
- [/@[a-zA-Z_$][\w$]*/, 'identifier.escape'],
115
-
116
- // Check for uppercase keywords (error case - keywords must be lowercase)
117
- [
118
- /[A-Z][a-zA-Z_$][\w$]*/,
119
- {
120
- cases: {
121
- '@keywords': 'invalid',
122
- '@default': 'identifier',
123
- },
124
- },
125
- ],
126
-
127
- // Identifiers and keywords (lowercase only for keywords)
128
- [
129
- /[a-z_$][\w$]*/,
130
- {
131
- cases: {
132
- '@keywords': 'keyword',
133
- '@builtins': 'variable.predefined',
134
- '@default': 'identifier',
135
- },
136
- },
137
- ],
138
-
139
- // Delimiters and operators
140
- [/[{}()[\]]/, '@brackets'],
141
- [/=>/, 'operator.arrow'],
142
- [
143
- /@symbols/,
144
- {
145
- cases: {
146
- '@operators': 'operator',
147
- '@default': '',
148
- },
149
- },
150
- ],
151
-
152
- // Numbers
153
- [/\d*\.\d+([eE][-+]?\d+)?/, 'number.float'],
154
- [/0[xX][0-9a-fA-F]+/, 'number.hex'],
155
- [/\d+/, 'number'],
156
-
157
- // Delimiter: after number because of .\d floats
158
- [/[;,.]/, 'delimiter'],
159
-
160
- // Strings
161
- [/"([^"\\]|\\.)*$/, 'string.invalid'],
162
- [/"/, { token: 'string.quote', next: '@string' }],
163
- ],
164
-
165
- whitespace: [
166
- [/[ \t\r\n]+/, ''],
167
- [/#.*$/, 'comment'],
168
- ],
169
-
170
- // Template string state
171
- templateString: [
172
- [/\$\{/, { token: 'delimiter.bracket', next: '@templateExpression' }],
173
- [/[^\\`$]+/, 'string.template'],
174
- [/@escapes/, 'string.template.escape'],
175
- [/\\./, 'string.template.escape.invalid'],
176
- [/`/, { token: 'string.template', next: '@pop' }],
177
- ],
178
-
179
- // Template expression inside ${}
180
- templateExpression: [
181
- [/\}/, { token: 'delimiter.bracket', next: '@pop' }],
182
- { include: '@root' },
183
- ],
184
-
185
- // Regular string state
186
- string: [
187
- [/[^\\"]+/, 'string'],
188
- [/@escapes/, 'string.escape'],
189
- [/\\./, 'string.escape.invalid'],
190
- [/"/, { token: 'string.quote', next: '@pop' }],
191
- ],
192
- },
193
- };
package/symbols.ts DELETED
@@ -1,374 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import { fenceMap, indentOf } from './document-context';
5
- import { eventAnalysisSource } from './event-analysis-source';
6
- import { clauseKeywords } from './language';
7
- import { ProductionSymbol } from './ProductionSymbol';
8
-
9
- export interface PropertySymbol {
10
- name: string;
11
- type: string;
12
- isIdentifier: boolean;
13
- line: number;
14
- }
15
-
16
- export interface ConceptSymbol {
17
- name: string;
18
- primitive: string;
19
- attributes: string[];
20
- attributeReasons: Record<string, string>;
21
- enumValues: string[];
22
- line: number;
23
- }
24
-
25
- export interface TypeSymbol {
26
- name: string;
27
- properties: PropertySymbol[];
28
- line: number;
29
- }
30
-
31
- export interface PolicySymbol {
32
- name: string;
33
- requires: string[];
34
- line: number;
35
- }
36
-
37
- export interface EventSymbol {
38
- name: string;
39
- generation?: number;
40
- inline?: boolean;
41
- properties: PropertySymbol[];
42
- line: number;
43
- }
44
-
45
- export interface CommandSymbol extends NamedSymbol {
46
- properties: PropertySymbol[];
47
- reads?: ReadSymbol[];
48
- produces?: ProductionSymbol[];
49
- productionHeaders?: number[];
50
- }
51
-
52
- export interface ReadSymbol {
53
- view: string;
54
- alias?: string;
55
- by?: string;
56
- line: number;
57
- }
58
-
59
- export interface NamedSymbol {
60
- name: string;
61
- line: number;
62
- }
63
-
64
- export interface QuerySymbol extends NamedSymbol {
65
- returnType: string;
66
- parameters: PropertySymbol[];
67
- }
68
-
69
- export interface ImportSymbol {
70
- qualifiedName: string;
71
- shortName: string;
72
- line: number;
73
- }
74
-
75
- export interface DocumentSymbols {
76
- imports: ImportSymbol[];
77
- concepts: ConceptSymbol[];
78
- types: TypeSymbol[];
79
- policies: PolicySymbol[];
80
- events: EventSymbol[];
81
- commands: CommandSymbol[];
82
- queries: QuerySymbol[];
83
- screens: NamedSymbol[];
84
- triggers: NamedSymbol[];
85
- }
86
-
87
- const conceptPattern = /^concept\s+(\w+)\s*:\s*(\w+)((?:\s+@\w+)*)\s*$/;
88
- const propertyPattern = /^\s*(@?[a-z_]\w*)\s+([\w.]+(?:\[\])?\??)(\s+identifier)?\s*$/;
89
- const attributeReasonPattern = /^([a-z_]\w*)\s+reason\s+"((?:[^"\\]|\\.)*)"\s*$/;
90
- const readPattern = /^\s*reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?\s*$/;
91
- const commandReserved = ['authorize', 'produces', 'reads'];
92
- // AuthorizeParser's continuation pattern, including the compiler's Unicode word characters.
93
- const authorizationContinuation = /^(?:(?:or|and)\s+)?[A-Za-z_(][\p{L}\p{Mn}\p{Nd}\p{Pc}\s()]*$/u;
94
- const eventReserved = clauseKeywords.filter(keyword => !['id', 'description', 'documentation'].includes(keyword));
95
- const queryParameterPattern =
96
- /^\s*(?:by|filter)\s+([a-z_]\w*)\s+([\w.]+(?:\[\])?\??)(?:\s+from\s+.+)?\s*$/;
97
-
98
- // Property-shaped clauses depend on their owner. Commands reserve only authorize,
99
- // produces and reads; bare directives such as description and handler can be properties.
100
- // The @ escape always denotes a property, and 'as' keeps its established property meaning.
101
- function propertiesIn(lines: string[], body: number[], reserved: readonly string[]): PropertySymbol[] {
102
- return body
103
- .map((index) => ({ index, match: lines[index].match(propertyPattern) }))
104
- .filter((entry): entry is { index: number; match: RegExpMatchArray } => entry.match !== null)
105
- .filter(({ match }) => match[1].startsWith('@') || match[1] === 'as' || !reserved.includes(match[1]))
106
- .map(({ index, match }) => ({
107
- name: match[1].replace(/^@/, ''),
108
- type: match[2],
109
- isIdentifier: match[3] !== undefined,
110
- line: index,
111
- }));
112
- }
113
-
114
- function collectBody(lines: string[], fences: boolean[], start: number, indent: number): number[] {
115
- const body: number[] = [];
116
- for (let index = start + 1; index < lines.length; index++) {
117
- if (fences[index]) {
118
- continue;
119
- }
120
- const line = lines[index];
121
- if (line.trim().length === 0) continue;
122
- if (indentOf(line) <= indent) break;
123
- body.push(index);
124
- }
125
- return body;
126
- }
127
-
128
- // Event/production parsers accept every greater indent, not just the smallest child indent.
129
- // Command block directives own their nested lines; properties do not. Fenced prose is never syntax.
130
- export function directBody(lines: string[], fences: boolean[], start: number, indent: number): number[] {
131
- const body = collectBody(lines, fences, start, indent).filter(index => !fences[index] && !/^\s*(?:\/\/|#)/.test(lines[index]));
132
- if (!/^\s*command\b/.test(lines[start])) return body;
133
- let blockIndent: number | undefined;
134
- let authorization = false;
135
- return body.filter(index => {
136
- const childIndent = indentOf(lines[index]);
137
- const text = lines[index].trim();
138
- // AuthorizeParser owns only consecutive deeper lines with requirement shape.
139
- // Unlike opaque blocks, a nonmatching line returns control to CommandParser.
140
- if (blockIndent !== undefined && childIndent > blockIndent &&
141
- (!authorization || authorizationContinuation.test(text))) return false;
142
- const property = text !== 'validate csharp' && propertiesIn(lines, [index], commandReserved).length > 0;
143
- // Description consumes only a quoted value or a fence (already excluded above).
144
- const leaf = property || /^description(?:\s|$)/.test(text);
145
- blockIndent = leaf ? undefined : childIndent;
146
- authorization = /^authorize(?:\s|$)/.test(text);
147
- return true;
148
- });
149
- }
150
-
151
- export function scanDocument(lines: string[]): DocumentSymbols {
152
- const symbols: DocumentSymbols = {
153
- imports: [],
154
- concepts: [],
155
- types: [],
156
- policies: [],
157
- events: [],
158
- commands: [],
159
- queries: [],
160
- screens: [],
161
- triggers: [],
162
- };
163
- // One normalization pass for every declaration, including comments on fence openers.
164
- lines = eventAnalysisSource(lines);
165
- const fences = fenceMap(lines);
166
- const eventLines = lines;
167
- const eventFences = fences;
168
- // Typed inline mappings share property syntax once their source expression is removed.
169
- // Do this once, never once per inline event.
170
- const eventPropertyLines = lines.map(line => line.replace(/\s*=(?!=|>).*/, ''));
171
-
172
- for (let index = 0; index < lines.length; index++) {
173
- if (fences[index]) continue;
174
- const line = lines[index];
175
- const trimmed = line.trim();
176
- const indent = indentOf(line);
177
-
178
- const importMatch = eventLines[index].trim().match(/^import\s+([\w.]+)\s*$/);
179
- if (importMatch && indent === 0) {
180
- const qualifiedName = importMatch[1];
181
- const shortName = qualifiedName.split('.').pop() ?? qualifiedName;
182
- symbols.imports.push({ qualifiedName, shortName, line: index });
183
- continue;
184
- }
185
-
186
- const conceptMatch = trimmed.match(conceptPattern);
187
- if (conceptMatch) {
188
- const body = collectBody(lines, fences, index, indent).map((i) => lines[i].trim());
189
- const attributeReasons: Record<string, string> = {};
190
- for (const line of body) {
191
- const reason = line.match(attributeReasonPattern);
192
- if (reason && attributeReasons[reason[1]] === undefined) {
193
- attributeReasons[reason[1]] = reason[2];
194
- }
195
- }
196
- const enumValues =
197
- conceptMatch[2] === 'Enum'
198
- ? body.filter((line) => !attributeReasonPattern.test(line))
199
- : [];
200
- symbols.concepts.push({
201
- name: conceptMatch[1],
202
- primitive: conceptMatch[2],
203
- attributes: conceptMatch[3].trim().split(/\s+/).filter(Boolean),
204
- attributeReasons,
205
- enumValues,
206
- line: index,
207
- });
208
- continue;
209
- }
210
-
211
- const typeMatch = trimmed.match(/^type\s+(\w+)\s*$/);
212
- if (typeMatch) {
213
- symbols.types.push({
214
- name: typeMatch[1],
215
- properties: propertiesIn(lines, collectBody(lines, fences, index, indent), clauseKeywords),
216
- line: index,
217
- });
218
- continue;
219
- }
220
-
221
- const policyMatch = trimmed.match(/^policy\s+(\w+)\s*$/);
222
- if (policyMatch) {
223
- const requires = collectBody(lines, fences, index, indent)
224
- .filter((i) => !fences[i])
225
- .map((i) => lines[i].trim());
226
- symbols.policies.push({ name: policyMatch[1], requires, line: index });
227
- continue;
228
- }
229
-
230
- const eventMatch = eventLines[index].trim().match(/^(?:produces\s+)?event\s+(\w+)(?:\s+generation\s+(\d+))?\s*$/);
231
- if (eventMatch) {
232
- symbols.events.push({
233
- name: eventMatch[1],
234
- ...(eventMatch[2] ? { generation: Number(eventMatch[2]) } : {}),
235
- inline: trimmed.startsWith('produces '),
236
- properties: propertiesIn(trimmed.startsWith('produces ') ? eventPropertyLines : eventLines,
237
- directBody(eventLines, eventFences, index, indent), eventReserved),
238
- line: index,
239
- });
240
- continue;
241
- }
242
-
243
- const commandMatch = eventLines[index].trim().match(/^command\s+(\w+)\s*$/);
244
- if (commandMatch) {
245
- // A command property is a leaf, not an indentation owner. Share the parser-shaped
246
- // body with properties, productions, advice and destination hints.
247
- const body = directBody(lines, fences, index, indent);
248
- const productionHeaders = body.filter(line => /^\s*produces\b/.test(lines[line]));
249
- symbols.commands.push({
250
- name: commandMatch[1],
251
- properties: propertiesIn(lines, body.filter(line => lines[line].trim() !== 'validate csharp'), commandReserved),
252
- productionHeaders,
253
- produces: productionHeaders.flatMap(line => {
254
- const header = eventLines[line].trim();
255
- const inline = /^produces\s+event\b/.test(header);
256
- const conditional = /^produces\s+when\b/.test(header);
257
- const eventLine = conditional ? directBody(eventLines, eventFences, line, indentOf(eventLines[line]))[0] : line;
258
- if (eventLine === undefined) return [];
259
- const name = conditional ? eventLines[eventLine].trim() : header.match(inline ? /^produces\s+event\s+([A-Za-z_]\w*)(?:\s+generation\s+\d+)?\s*$/ : /^produces\s+([A-Z]\w*)\s*$/)?.[1];
260
- if (name === undefined || !/^[A-Za-z_]\w*$/.test(name)) return [];
261
- const children = directBody(eventLines, eventFences, eventLine, indentOf(eventLines[eventLine]));
262
- const targets = children.map(index => eventLines[index].trim().match(/^for(?:\s+(.*))?$/)).filter(match => match !== null);
263
- // Empty or repeated targets are uncertain, not implicit destinations.
264
- const target = targets.length === 0 ? undefined : targets.length === 1 ? targets[0][1] ?? '' : '';
265
- const mappings = children.flatMap(index => {
266
- const match = eventLines[index].trim().match(inline ? /^(@?[a-z_]\w*)\s+[\w.[\]?]+\s*=(?!=|>)\s*(.+)$/ : /^(@?[\w.]+)\s*=(?!=|>)\s*(.+)$/);
267
- return match === null ? [] : [{ name: match[1].replace(/^@/, ''), source: match[2], line: index }];
268
- });
269
- return [{ name, inline, conditional, line, target, mappings }];
270
- }),
271
- reads: body.filter((line) => !fences[line])
272
- .map((line) => ({ line, match: lines[line].match(readPattern) }))
273
- .filter((entry): entry is { line: number; match: RegExpMatchArray } => entry.match !== null)
274
- .map(({ line, match }) => ({
275
- view: match[1],
276
- ...(match[2] ? { alias: match[2] } : {}),
277
- ...(match[3] ? { by: match[3] } : {}),
278
- line,
279
- })),
280
- line: index,
281
- });
282
- continue;
283
- }
284
-
285
- // The return type shape is the compiler's, dots and all - QueryParser's
286
- // ^query\s+([A-Za-z_]\w*)\s*=>\s*(observable\s+)?([\w.]+(?:\[\])?\??)$. A narrower one here
287
- // silently drops the query from the symbol table, and with it every check and completion that
288
- // reads from it.
289
- const queryMatch = trimmed.match(/^query\s+(\w+)\s*=>\s*(?:observable\s+)?([\w.]+(?:\[\])?\??)\s*$/);
290
- if (queryMatch) {
291
- // The return type names a read model, which no construct declares — only the
292
- // 'by' and 'filter' parameters resolve against the document's own types.
293
- const parameters = collectBody(lines, fences, index, indent)
294
- .map((i) => ({ index: i, match: lines[i].match(queryParameterPattern) }))
295
- .filter(
296
- (entry): entry is { index: number; match: RegExpMatchArray } =>
297
- entry.match !== null,
298
- )
299
- .map(({ index: line, match }) => ({
300
- name: match[1],
301
- type: match[2],
302
- isIdentifier: false,
303
- line,
304
- }));
305
- symbols.queries.push({
306
- name: queryMatch[1],
307
- returnType: queryMatch[2],
308
- parameters,
309
- line: index,
310
- });
311
- continue;
312
- }
313
-
314
- const screenMatch = trimmed.match(/^screen\s+(\w+)\s*$/);
315
- if (screenMatch) {
316
- symbols.screens.push({ name: screenMatch[1], line: index });
317
- continue;
318
- }
319
-
320
- const triggerMatch = trimmed.match(/^trigger\s+(\w+)\s*$/);
321
- if (triggerMatch && indent === 0) {
322
- symbols.triggers.push({ name: triggerMatch[1], line: index });
323
- }
324
- }
325
-
326
- return symbols;
327
- }
328
-
329
- // The symbols of several documents as one - what an application spread over files declares. Lines refer to
330
- // the document each symbol came from, so the result names things; it does not locate them.
331
- export function mergeSymbols(...documents: DocumentSymbols[]): DocumentSymbols {
332
- return {
333
- imports: documents.flatMap((document) => document.imports),
334
- concepts: documents.flatMap((document) => document.concepts),
335
- types: documents.flatMap((document) => document.types),
336
- policies: documents.flatMap((document) => document.policies),
337
- events: documents.flatMap((document) => document.events),
338
- commands: documents.flatMap((document) => document.commands),
339
- queries: documents.flatMap((document) => document.queries),
340
- screens: documents.flatMap((document) => document.screens),
341
- triggers: documents.flatMap((document) => document.triggers),
342
- };
343
- }
344
-
345
- export function knownEventNames(symbols: DocumentSymbols): string[] {
346
- return [
347
- ...symbols.events.map((event) => event.name),
348
- ...symbols.imports.map((imported) => imported.shortName),
349
- ];
350
- }
351
-
352
- // The built-in host signals, which have no declaration to scan for because every application has them.
353
- export const builtInTriggerNames = ['Startup', 'Shutdown'];
354
-
355
- // What a reaction's `when` may name: an event, a declared trigger, or a host signal. The compiler resolves
356
- // the three in that order, and the editor offers them the same way rather than guessing which was meant.
357
- export function knownTriggerNames(symbols: DocumentSymbols): string[] {
358
- return [
359
- ...knownEventNames(symbols),
360
- ...symbols.triggers.map((trigger) => trigger.name),
361
- ...builtInTriggerNames,
362
- ];
363
- }
364
-
365
- // Everything a property type reference can resolve to — the primitives, the declared
366
- // concepts and types, and the short names of the imports.
367
- export function knownTypeNames(symbols: DocumentSymbols, primitives: readonly string[]): string[] {
368
- return [
369
- ...primitives,
370
- ...symbols.concepts.map((concept) => concept.name),
371
- ...symbols.types.map((type) => type.name),
372
- ...symbols.imports.map((imported) => imported.shortName),
373
- ];
374
- }
@@ -1,33 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import type { editor } from 'monaco-editor';
5
-
6
- export const screenplayDarkThemeName = 'screenplay-dark';
7
-
8
- export const screenplayDark: editor.IStandaloneThemeData = {
9
- base: 'vs-dark',
10
- inherit: true,
11
- rules: [
12
- { token: 'keyword.play', foreground: 'C586C0' },
13
- { token: 'keyword.tag.play', foreground: '569CD6', fontStyle: 'italic' },
14
- { token: 'keyword.type.play', foreground: '4FC1FF', fontStyle: 'bold' },
15
- { token: 'type.play', foreground: '4EC9B0' },
16
- { token: 'type.identifier.play', foreground: '4EC9B0' },
17
- { token: 'identifier.play', foreground: '9CDCFE' },
18
- { token: 'annotation.play', foreground: 'DCDCAA' },
19
- { token: 'variable.predefined.play', foreground: 'D7BA7D' },
20
- { token: 'string.play', foreground: 'CE9178' },
21
- { token: 'string.link.play', foreground: 'CE9178', fontStyle: 'underline' },
22
- { token: 'string.invalid.play', foreground: 'F44747' },
23
- { token: 'string.quote.play', foreground: '6A9955' },
24
- { token: 'number.play', foreground: 'B5CEA8' },
25
- { token: 'number.float.play', foreground: 'B5CEA8' },
26
- { token: 'comment.play', foreground: '6A9955', fontStyle: 'italic' },
27
- { token: 'operator.play', foreground: 'D4D4D4' },
28
- { token: 'delimiter.play', foreground: 'CCCCCC' },
29
- ],
30
- colors: {
31
- 'editor.background': '#1E1E1E',
32
- },
33
- };
@@ -1,33 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import type { editor } from 'monaco-editor';
5
-
6
- export const screenplayLightThemeName = 'screenplay-light';
7
-
8
- export const screenplayLight: editor.IStandaloneThemeData = {
9
- base: 'vs',
10
- inherit: true,
11
- rules: [
12
- { token: 'keyword.play', foreground: 'AF00DB' },
13
- { token: 'keyword.tag.play', foreground: '0000FF', fontStyle: 'italic' },
14
- { token: 'keyword.type.play', foreground: '0070C1', fontStyle: 'bold' },
15
- { token: 'type.play', foreground: '267F99' },
16
- { token: 'type.identifier.play', foreground: '267F99' },
17
- { token: 'identifier.play', foreground: '001080' },
18
- { token: 'annotation.play', foreground: '795E26' },
19
- { token: 'variable.predefined.play', foreground: 'B45309' },
20
- { token: 'string.play', foreground: 'A31515' },
21
- { token: 'string.link.play', foreground: 'A31515', fontStyle: 'underline' },
22
- { token: 'string.invalid.play', foreground: 'CD3131' },
23
- { token: 'string.quote.play', foreground: '008000' },
24
- { token: 'number.play', foreground: '098658' },
25
- { token: 'number.float.play', foreground: '098658' },
26
- { token: 'comment.play', foreground: '008000', fontStyle: 'italic' },
27
- { token: 'operator.play', foreground: '000000' },
28
- { token: 'delimiter.play', foreground: '000000' },
29
- ],
30
- colors: {
31
- 'editor.background': '#FFFFFF',
32
- },
33
- };