@cratis/screenplay-language 4.218.2 → 4.220.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/code-actions.js +1 -1
- package/dist/bundles/code-actions.js.map +1 -1
- package/dist/bundles/compiler/Authoring/QuickFixes.js +1 -1
- package/dist/bundles/compiler/Authoring/QuickFixes.js.map +1 -1
- package/dist/bundles/compiler/Authoring/TimelineQuickFixContext.js +7 -0
- package/dist/bundles/compiler/Authoring/TimelineQuickFixContext.js.map +1 -0
- package/dist/bundles/compiler/Authoring/TimelineQuickFixImports.js +5 -0
- package/dist/bundles/compiler/Authoring/TimelineQuickFixImports.js.map +1 -0
- package/dist/bundles/compiler/Authoring/TimelineQuickFixes.js +2 -0
- package/dist/bundles/compiler/Authoring/TimelineQuickFixes.js.map +1 -0
- package/dist/bundles/compiler/Files/AuthoredOrder.js +1 -1
- package/dist/bundles/compiler/Files/AuthoredOrder.js.map +1 -1
- package/dist/bundles/compiler/Files/OrderingRoot.js +2 -1
- package/dist/bundles/compiler/Files/OrderingRoot.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js +1 -1
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js.map +1 -1
- package/dist/bundles/compiler/Files/PlayDocumentSource.js +2 -0
- package/dist/bundles/compiler/Files/PlayDocumentSource.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayGlob.js +2 -0
- package/dist/bundles/compiler/Files/PlayGlob.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayImports.js +2 -1
- package/dist/bundles/compiler/Files/PlayImports.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayPlacement.js +1 -1
- package/dist/bundles/compiler/Files/PlayPlacement.js.map +1 -1
- package/dist/bundles/compiler/Files/TimelineOrder.js +1 -1
- package/dist/bundles/compiler/Files/TimelineOrder.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ImportDiscovery.js +2 -1
- package/dist/bundles/compiler/Parsing/ImportDiscovery.js.map +1 -0
- package/dist/bundles/compiler/ScreenplayCompiler.js +1 -1
- package/dist/bundles/compiler/ScreenplayCompiler.js.map +1 -1
- package/dist/bundles/compiler/index.js +1 -1
- package/dist/code-actions.d.ts +2 -2
- package/dist/code-actions.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"./compiler/Diagnostics/DiagnosticCodes.js";import{isQuickFixDiagnostic as t,prepareQuickFixes as n}from"./compiler/Authoring/QuickFixes.js";import"./compiler/index.js";const r=`source.screenplay.migrateOptional`,i=`source.screenplay.migrateCompliance`,migrationKind=t=>t===e.LegacyComplianceMarker?i:r,containsKind=(e,t)=>e===``||e===t||t.startsWith(`${e}.`);function intersects(e,t){return(e.startLineNumber<t.endLineNumber||e.startLineNumber===t.endLineNumber&&e.startColumn<=t.endColumn)&&(t.startLineNumber<e.endLineNumber||t.startLineNumber===e.endLineNumber&&t.startColumn<=e.endColumn)}function createCodeActionProvider(a){let
|
|
1
|
+
import"./_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"./compiler/Diagnostics/DiagnosticCodes.js";import{isQuickFixDiagnostic as t,prepareQuickFixes as n}from"./compiler/Authoring/QuickFixes.js";import"./compiler/index.js";const r=`source.screenplay.migrateOptional`,i=`source.screenplay.migrateCompliance`,migrationKind=t=>t===e.LegacyComplianceMarker?i:r,containsKind=(e,t)=>e===``||e===t||t.startsWith(`${e}.`);function intersects(e,t){return(e.startLineNumber<t.endLineNumber||e.startLineNumber===t.endLineNumber&&e.startColumn<=t.endColumn)&&(t.startLineNumber<e.endLineNumber||t.startLineNumber===e.endLineNumber&&t.startColumn<=e.endColumn)}function createCodeActionProvider(a,o){let s=/* @__PURE__ */ new WeakMap;return{provideCodeActions(c,l,u,d){let f=u.only!==void 0&&[r,i].some(e=>containsKind(u.only,e)),p=u.only!==void 0&&f&&!containsKind(u.only,`quickfix`);if(d.isCancellationRequested||u.only!==void 0&&!f&&!containsKind(u.only,`quickfix`))return{actions:[],dispose(){}};let m=u.markers.filter(e=>{let n=typeof e.code==`object`?e.code.value:e.code;return t(n)&&intersects(e,l)});if(!f&&m.length===0)return{actions:[],dispose(){}};let h=c.getVersionId(),g=o?.(),_=g===void 0?void 0:[...g].find(([,e])=>e===c)?.[0];if(g!==void 0&&_===void 0)return{actions:[],dispose(){}};let v=new Map([...g?.values()??[c]].map(e=>[e,e.getVersionId()])),y=JSON.stringify([a,g===void 0?void 0:[...g].map(([e,t])=>[e,t.uri.toString(),v.get(t)])]),b=s.get(c);(b?.version!==h||b.placement!==y)&&(b={version:h,placement:y,fixes:n(c.getValue(),{placement:a,path:_,documents:g===void 0?void 0:new Map([...g].map(([e,t])=>[e,t.getValue()]))})},s.set(c,b));let x=[...p?[]:b.fixes(m.map(e=>({line:e.startLineNumber,diagnosticCode:String(typeof e.code==`object`?e.code.value:e.code)}))).filter(e=>e.scope===`occurrence`),...u.only===void 0||f?[e.LegacyOptionalSuffix,e.LegacyComplianceMarker].flatMap(e=>b.fixes(void 0,e)):[]].filter(e=>u.only===void 0||containsKind(u.only,e.scope===`document`?migrationKind(e.diagnosticCode):`quickfix`));return d.isCancellationRequested||[...v].some(([e,t])=>e.getVersionId()!==t)?{actions:[],dispose(){}}:{actions:x.filter(e=>e.edits.every(e=>e.path===void 0||g?.has(e.path))).map(t=>({title:t.title,kind:t.scope===`document`?migrationKind(t.diagnosticCode):`quickfix`,isPreferred:t.scope===`occurrence`,edit:{edits:t.edits.map(e=>{let t=e.path===void 0?c:g.get(e.path),n=t.getPositionAt(e.start),r=t.getPositionAt(e.start+e.length);return{resource:t.uri,versionId:v.get(t),textEdit:{range:{startLineNumber:n.lineNumber,startColumn:n.column,endLineNumber:r.lineNumber,endColumn:r.column},text:e.text}}}).concat(t.diagnosticCode!==e.EventFromLaterSlice||g===void 0?[]:[...g].filter(([e])=>!t.edits.some(t=>t.path===e)).map(([,e])=>({resource:e.uri,versionId:v.get(e),textEdit:{range:{startLineNumber:1,startColumn:1,endLineNumber:1,endColumn:1},text:``}})))}})),dispose(){}}}}}export{createCodeActionProvider};
|
|
2
2
|
//# sourceMappingURL=code-actions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-actions.js","names":["migrateOptional","migrateCompliance","code","DiagnosticCodes","requested","kind","left","right","cache","migrationRequested","context","migrationOnly","token","diagnostics","marker","isQuickFixDiagnostic","range","version","model","placementKey","placement","analysis","prepareQuickFixes","fixes","diagnostic","fix","start","edit","end"],"sources":["../../code-actions.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 type { editor, IRange, languages } from 'monaco-editor';\nimport { DiagnosticCodes, isQuickFixDiagnostic, prepareQuickFixes } from '@cratis/screenplay-compiler';\n\nconst migrateOptional = 'source.screenplay.migrateOptional';\nconst migrateCompliance = 'source.screenplay.migrateCompliance';\nconst migrationKind = (code: string) => code === DiagnosticCodes.LegacyComplianceMarker ? migrateCompliance : migrateOptional;\nconst containsKind = (requested: string, kind: string) => requested === '' || requested === kind || kind.startsWith(`${requested}.`);\n\nfunction intersects(left: IRange, right: IRange): boolean {\n return (left.startLineNumber < right.endLineNumber || (left.startLineNumber === right.endLineNumber && left.startColumn <= right.endColumn)) &&\n (right.startLineNumber < left.endLineNumber || (right.startLineNumber === left.endLineNumber && right.startColumn <= left.endColumn));\n}\n\n// The compiler owns recipes and verification. The adapter only translates verified offsets and pins\n// edits to the analyzed buffer version, so future fixes need no editor-specific parsing or .NET bridge.\nexport function createCodeActionProvider(placement?: readonly string[]): languages.CodeActionProvider {\n const cache = new WeakMap<editor.ITextModel, { version: number; placement: string; fixes: ReturnType<typeof prepareQuickFixes> }>();\n return {\n provideCodeActions(model, range, context, token) {\n const migrationRequested = context.only !== undefined && [migrateOptional, migrateCompliance].some(kind => containsKind(context.only!, kind));\n const migrationOnly = context.only !== undefined && migrationRequested && !containsKind(context.only, 'quickfix');\n if (token.isCancellationRequested || (context.only !== undefined && !migrationRequested && !containsKind(context.only, 'quickfix'))) return { actions: [], dispose() {} };\n const diagnostics = context.markers.filter(marker => {\n const code = typeof marker.code === 'object' ? marker.code.value : marker.code;\n return isQuickFixDiagnostic(code) && intersects(marker, range);\n });\n if (!migrationRequested && diagnostics.length === 0) return { actions: [], dispose() {} };\n const version = model.getVersionId();\n const placementKey = JSON.stringify(placement) ?? '';\n let analysis = cache.get(model);\n if (analysis?.version !== version || analysis.placement !== placementKey) {\n analysis = { version, placement: placementKey, fixes: prepareQuickFixes(model.getValue(), { placement }) };\n cache.set(model, analysis);\n }\n const occurrences = migrationOnly ? [] : analysis.fixes(diagnostics.map(diagnostic => ({\n line: diagnostic.startLineNumber,\n diagnosticCode: String(typeof diagnostic.code === 'object' ? diagnostic.code.value : diagnostic.code),\n }))).filter(fix => fix.scope === 'occurrence');\n const requested = [...occurrences, ...(context.only === undefined || migrationRequested ? [DiagnosticCodes.LegacyOptionalSuffix, DiagnosticCodes.LegacyComplianceMarker].flatMap(code => analysis.fixes(undefined, code)) : [])];\n const fixes = requested.filter(fix => context.only === undefined || containsKind(context.only, fix.scope === 'document' ? migrationKind(fix.diagnosticCode) : 'quickfix'));\n if (token.isCancellationRequested || model.getVersionId() !== version) return { actions: [], dispose() {} };\n return {\n actions: fixes.map(fix => ({\n title: fix.title,\n kind: fix.scope === 'document' ? migrationKind(fix.diagnosticCode) : 'quickfix',\n isPreferred: fix.scope === 'occurrence',\n edit: { edits: fix.edits.map(edit => {\n const start = model.getPositionAt(edit.start);\n const end = model.getPositionAt(edit.start + edit.length);\n return { resource: model.uri, versionId: version, textEdit: {\n range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column },\n text: edit.text,\n } };\n }) },\n })),\n dispose() {},\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"code-actions.js","names":["migrateOptional","migrateCompliance","code","DiagnosticCodes","requested","kind","left","right","cache","migrationRequested","context","migrationOnly","token","diagnostics","marker","isQuickFixDiagnostic","range","version","model","models","applicationModels","path","document","versions","placementKey","placement","analysis","prepareQuickFixes","fixes","diagnostic","fix","edit","start","end"],"sources":["../../code-actions.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 type { editor, IRange, languages } from 'monaco-editor';\nimport { DiagnosticCodes, isQuickFixDiagnostic, prepareQuickFixes } from '@cratis/screenplay-compiler';\n\nconst migrateOptional = 'source.screenplay.migrateOptional';\nconst migrateCompliance = 'source.screenplay.migrateCompliance';\nconst migrationKind = (code: string) => code === DiagnosticCodes.LegacyComplianceMarker ? migrateCompliance : migrateOptional;\nconst containsKind = (requested: string, kind: string) => requested === '' || requested === kind || kind.startsWith(`${requested}.`);\n\nfunction intersects(left: IRange, right: IRange): boolean {\n return (left.startLineNumber < right.endLineNumber || (left.startLineNumber === right.endLineNumber && left.startColumn <= right.endColumn)) &&\n (right.startLineNumber < left.endLineNumber || (right.startLineNumber === left.endLineNumber && right.startColumn <= left.endColumn));\n}\n\n// The compiler owns recipes and verification. The adapter only translates verified offsets and pins\n// edits to the analyzed buffer version, so future fixes need no editor-specific parsing or .NET bridge.\nexport function createCodeActionProvider(placement?: readonly string[], applicationModels?: () => ReadonlyMap<string, editor.ITextModel>): languages.CodeActionProvider {\n const cache = new WeakMap<editor.ITextModel, { version: number; placement: string; fixes: ReturnType<typeof prepareQuickFixes> }>();\n return {\n provideCodeActions(model, range, context, token) {\n const migrationRequested = context.only !== undefined && [migrateOptional, migrateCompliance].some(kind => containsKind(context.only!, kind));\n const migrationOnly = context.only !== undefined && migrationRequested && !containsKind(context.only, 'quickfix');\n if (token.isCancellationRequested || (context.only !== undefined && !migrationRequested && !containsKind(context.only, 'quickfix'))) return { actions: [], dispose() {} };\n const diagnostics = context.markers.filter(marker => {\n const code = typeof marker.code === 'object' ? marker.code.value : marker.code;\n return isQuickFixDiagnostic(code) && intersects(marker, range);\n });\n if (!migrationRequested && diagnostics.length === 0) return { actions: [], dispose() {} };\n const version = model.getVersionId();\n const models = applicationModels?.();\n const path = models === undefined ? undefined : [...models].find(([, document]) => document === model)?.[0];\n if (models !== undefined && path === undefined) return { actions: [], dispose() {} };\n const versions = new Map([...(models?.values() ?? [model])].map(document => [document, document.getVersionId()]));\n const placementKey = JSON.stringify([placement, models === undefined ? undefined : [...models].map(([path, document]) => [path, document.uri.toString(), versions.get(document)])]);\n let analysis = cache.get(model);\n if (analysis?.version !== version || analysis.placement !== placementKey) {\n analysis = { version, placement: placementKey, fixes: prepareQuickFixes(model.getValue(), { placement, path, documents: models === undefined ? undefined : new Map([...models].map(([path, document]) => [path, document.getValue()])) }) };\n cache.set(model, analysis);\n }\n const occurrences = migrationOnly ? [] : analysis.fixes(diagnostics.map(diagnostic => ({\n line: diagnostic.startLineNumber,\n diagnosticCode: String(typeof diagnostic.code === 'object' ? diagnostic.code.value : diagnostic.code),\n }))).filter(fix => fix.scope === 'occurrence');\n const requested = [...occurrences, ...(context.only === undefined || migrationRequested ? [DiagnosticCodes.LegacyOptionalSuffix, DiagnosticCodes.LegacyComplianceMarker].flatMap(code => analysis.fixes(undefined, code)) : [])];\n const fixes = requested.filter(fix => context.only === undefined || containsKind(context.only, fix.scope === 'document' ? migrationKind(fix.diagnosticCode) : 'quickfix'));\n if (token.isCancellationRequested || [...versions].some(([document, version]) => document.getVersionId() !== version)) return { actions: [], dispose() {} };\n const supported = fixes.filter(fix => fix.edits.every(edit => edit.path === undefined || models?.has(edit.path)));\n return {\n actions: supported.map(fix => ({\n title: fix.title,\n kind: fix.scope === 'document' ? migrationKind(fix.diagnosticCode) : 'quickfix',\n isPreferred: fix.scope === 'occurrence',\n edit: { edits: fix.edits.map(edit => {\n const document = edit.path === undefined ? model : models!.get(edit.path)!;\n const start = document.getPositionAt(edit.start);\n const end = document.getPositionAt(edit.start + edit.length);\n return { resource: document.uri, versionId: versions.get(document)!, textEdit: {\n range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column },\n text: edit.text,\n } };\n }).concat(fix.diagnosticCode !== DiagnosticCodes.EventFromLaterSlice || models === undefined ? [] : [...models].filter(([path]) => !fix.edits.some(edit => edit.path === path)).map(([, document]) => ({\n // A sibling change can invalidate the ordering proof. Empty edits pin every\n // analyzed model, including those whose source is not changed by the repair.\n resource: document.uri, versionId: versions.get(document)!, textEdit: { range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }, text: '' },\n }))) },\n })),\n dispose() {},\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{checkPortableMatchPattern as t}from"../Parsing/checkPortableMatchPattern.js";import{stringBodyPattern as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{complianceWireName as i}from"../Parsing/ConceptComplianceParser.js";import{commentStart as a,splitLines as o}from"../Parsing/SourceLineSplitter.js";import{ScreenplaySyntaxWalker as s}from"../Syntax/ScreenplaySyntaxWalker.js";import{parseForAuthoring as c}from"../ScreenplayCompiler.js";function isQuickFixDiagnostic(t){return t===e.DeprecatedStudioTextRulePattern||t===e.DuplicateComplianceMarker||t===e.LegacyOptionalSuffix||t===e.LegacyComplianceMarker||t===e.RedundantEventId||t===e.PublicTranslationRequiresDirection||t===e.LegacyProfileLayout}function legacyOptionalTypeLength(t,n){return n.code===e.LegacyOptionalSuffix?/^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?\?/u.exec(t.slice(n.location.column-1))?.[0].length??0:0}function prepareQuickFixes(r,i={}){let l=c(r,void 0,i.placement),u=new Set(Array.from({length:14},(e,t)=>`PLAY0${607+t}`)),acceptable=e=>e.success||e.diagnostics.every(e=>e.severity!==`error`||u.has(e.code)),errorCodes=e=>new Set(e.diagnostics.filter(e=>e.severity===`error`).map(e=>e.code));if(!acceptable(l))return()=>[];let d=o(r),f=/* @__PURE__ */ new Map,p=/* @__PURE__ */ new Map,m=/* @__PURE__ */ new Map;new class extends s{visitValidationRule(e){m.set(e.location.line,e),super.visitValidationRule(e)}visitEvent(e){f.set(e.location.line,e)}visitSlice(e){p.set(e.location.line,e),super.visitSlice(e)}}().visitApplication(l.value);let h=/* @__PURE__ */ new Map,g=/* @__PURE__ */ new Map,_=/* @__PURE__ */ new Map,v=/* @__PURE__ */ new Map,y=/* @__PURE__ */ new Map,b;for(let e of d)b=f.get(e.number)??b,b!==void 0&&y.set(e.number,b);for(let o of l.diagnostics){h.set(o.code,(h.get(o.code)??0)+1);let s=d[o.location.line-1];if(o.code===e.DuplicateComplianceMarker){let e=duplicateComplianceMarkerEdit(s.raw,s.startOffset);e!==void 0&&_.set(s.number,{diagnosticCode:o.code,title:`Remove duplicate compliance markers`,scope:`occurrence`,edits:[e]})}let u=legacyOptionalTypeLength(s.raw,o);if(u>0)g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use 'optional' instead of '?'`,scope:`occurrence`,edits:[{start:s.startOffset+o.location.column+u-2,length:1,text:` optional`}]}});else if(o.code===e.DeprecatedStudioTextRulePattern){let e=m.get(s.number);if(e?.rule!==`Matches`||e.value?.kind!==`LiteralExpressionSyntax`||typeof e.value.value!=`string`)continue;let r=t(e.value.value).replacement,i=RegExp(`\\bmatches\\s+"${n}"`).exec(s.raw);if(r===void 0||i===null)continue;let a={Equal:`==`,NotEqual:`!=`,Contains:`contains`,NotContains:`not contains`,StartsWith:`starts with`,EndsWith:`ends with`},c=`"`+r.value.replace(/["\\\n\r\t]/g,e=>JSON.stringify(e).slice(1,-1))+`"`;g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use the equivalent ordinal text rule`,scope:`occurrence`,edits:[{start:s.startOffset+i.index,length:i[0].length,text:a[r.kind]+` `+c}]},change:{node:e,replacement:{...e,rule:r.kind,value:{...e.value,value:r.value}}}})}else if(o.code===e.LegacyComplianceMarker){let e=complianceMarkerEdit(s.raw,s.startOffset);e!==void 0&&g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use bare pii and secret compliance markers`,scope:`occurrence`,edits:[e]}})}else if(o.code===e.PublicTranslationRequiresDirection){let t=p.get(s.number),n=/^\s*/.exec(s.raw)[0],a=r.includes(`\r
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{checkPortableMatchPattern as t}from"../Parsing/checkPortableMatchPattern.js";import{stringBodyPattern as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{complianceWireName as i}from"../Parsing/ConceptComplianceParser.js";import{commentStart as a,splitLines as o}from"../Parsing/SourceLineSplitter.js";import{ScreenplaySyntaxWalker as s}from"../Syntax/ScreenplaySyntaxWalker.js";import{parseForAuthoring as c}from"../ScreenplayCompiler.js";import{prepareTimelineQuickFixes as l}from"./TimelineQuickFixes.js";function isQuickFixDiagnostic(t){return t===e.EventFromLaterSlice||t===e.DeprecatedStudioTextRulePattern||t===e.DuplicateComplianceMarker||t===e.LegacyOptionalSuffix||t===e.LegacyComplianceMarker||t===e.RedundantEventId||t===e.PublicTranslationRequiresDirection||t===e.LegacyProfileLayout}function legacyOptionalTypeLength(t,n){return n.code===e.LegacyOptionalSuffix?/^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?\?/u.exec(t.slice(n.location.column-1))?.[0].length??0:0}function prepareQuickFixes(t,n={}){let r=prepareLocalQuickFixes(t,n),i;return(a,o)=>{let s=typeof a==`number`?[{line:a,diagnosticCode:o}]:a??[],c=r(a,o),u=s.filter(t=>t.diagnosticCode===e.EventFromLaterSlice||t.diagnosticCode===void 0&&c.length===0),d=u.length===0?[]:[...new Set(u.map(e=>e.line))].flatMap(e=>(i??=l(t,n))(e));return[...c,...d]}}function prepareLocalQuickFixes(r,i){let l=c(r,void 0,i.placement),u=new Set(Array.from({length:14},(e,t)=>`PLAY0${607+t}`)),acceptable=e=>e.success||e.diagnostics.every(e=>e.severity!==`error`||u.has(e.code)),errorCodes=e=>new Set(e.diagnostics.filter(e=>e.severity===`error`).map(e=>e.code));if(!acceptable(l))return()=>[];let d=o(r),f=/* @__PURE__ */ new Map,p=/* @__PURE__ */ new Map,m=/* @__PURE__ */ new Map;new class extends s{visitValidationRule(e){m.set(e.location.line,e),super.visitValidationRule(e)}visitEvent(e){f.set(e.location.line,e)}visitSlice(e){p.set(e.location.line,e),super.visitSlice(e)}}().visitApplication(l.value);let h=/* @__PURE__ */ new Map,g=/* @__PURE__ */ new Map,_=/* @__PURE__ */ new Map,v=/* @__PURE__ */ new Map,y=/* @__PURE__ */ new Map,b;for(let e of d)b=f.get(e.number)??b,b!==void 0&&y.set(e.number,b);for(let o of l.diagnostics){h.set(o.code,(h.get(o.code)??0)+1);let s=d[o.location.line-1];if(o.code===e.DuplicateComplianceMarker){let e=duplicateComplianceMarkerEdit(s.raw,s.startOffset);e!==void 0&&_.set(s.number,{diagnosticCode:o.code,title:`Remove duplicate compliance markers`,scope:`occurrence`,edits:[e]})}let u=legacyOptionalTypeLength(s.raw,o);if(u>0)g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use 'optional' instead of '?'`,scope:`occurrence`,edits:[{start:s.startOffset+o.location.column+u-2,length:1,text:` optional`}]}});else if(o.code===e.DeprecatedStudioTextRulePattern){let e=m.get(s.number);if(e?.rule!==`Matches`||e.value?.kind!==`LiteralExpressionSyntax`||typeof e.value.value!=`string`)continue;let r=t(e.value.value).replacement,i=RegExp(`\\bmatches\\s+"${n}"`).exec(s.raw);if(r===void 0||i===null)continue;let a={Equal:`==`,NotEqual:`!=`,Contains:`contains`,NotContains:`not contains`,StartsWith:`starts with`,EndsWith:`ends with`},c=`"`+r.value.replace(/["\\\n\r\t]/g,e=>JSON.stringify(e).slice(1,-1))+`"`;g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use the equivalent ordinal text rule`,scope:`occurrence`,edits:[{start:s.startOffset+i.index,length:i[0].length,text:a[r.kind]+` `+c}]},change:{node:e,replacement:{...e,rule:r.kind,value:{...e.value,value:r.value}}}})}else if(o.code===e.LegacyComplianceMarker){let e=complianceMarkerEdit(s.raw,s.startOffset);e!==void 0&&g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Use bare pii and secret compliance markers`,scope:`occurrence`,edits:[e]}})}else if(o.code===e.PublicTranslationRequiresDirection){let t=p.get(s.number),n=/^\s*/.exec(s.raw)[0],a=r.includes(`\r
|
|
2
2
|
`)?`\r
|
|
3
3
|
`:`
|
|
4
4
|
`,u=[`Inbound`,`Outbound`].map(e=>({direction:e,text:`${a}${n} direction ${e===`Inbound`?`inbound`:`outbound`}`})).filter(t=>{let n=applyQuickFixEdits(r,[{start:s.startOffset+s.raw.length,length:0,text:t.text}]),a=c(n,void 0,i.placement),o=errorCodes(l);return acceptable(a)&&![...errorCodes(a)].some(t=>t===e.PublicTranslationRequiresDirection||!o.has(t))});if(u.length===1){let[{direction:e,text:n}]=u;g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Declare 'direction ${e===`Inbound`?`inbound`:`outbound`}'`,scope:`occurrence`,edits:[{start:s.startOffset+s.raw.length,length:0,text:n}]},change:{node:t,replacement:{...t,direction:e}}})}}else if(o.code===e.LegacyProfileLayout){let e=legacyProfileLayoutFix(d,s.number-1,o.code);e!==void 0&&g.set(s.number,{line:s.number,fix:e})}else if(o.code===e.RedundantEventId&&a(s.raw)<0){let e=y.get(s.number);if(e?.id!==e?.name||e===void 0)continue;g.set(s.number,{line:s.number,fix:{diagnosticCode:o.code,title:`Remove the redundant event id`,scope:`occurrence`,edits:[{start:s.startOffset,length:(d[s.number]?.startOffset??r.length)-s.startOffset,text:``}]},change:{node:e,replacement:{...e,id:null}}})}}let x=[e.LegacyOptionalSuffix,e.LegacyComplianceMarker],S=verificationShape(l),C=/* @__PURE__ */ new Map,w,T=/* @__PURE__ */ new Set,E=/* @__PURE__ */ new Map,verify=(e,t)=>{let n=applyQuickFixEdits(r,e.edits);if(n===void 0)return;let a=c(n,void 0,i.placement);if(acceptable(a)&&verificationShape(a)===(t===void 0?S:verificationShape(l,[t])))return a.diagnostics.filter(t=>t.code===e.diagnosticCode).length===(h.get(e.diagnosticCode)??0)-e.edits.length?e:void 0};return(t,n)=>{let a=typeof t==`number`||t===void 0?void 0:t,o=a===void 0?typeof t==`number`&&(n===void 0||n===e.DuplicateComplianceMarker)?[t]:[]:a.filter(t=>t.diagnosticCode===e.DuplicateComplianceMarker).map(e=>e.line),s=[...new Set(o)].flatMap(e=>{let t=_.get(e);if(t===void 0)return[];v.has(e)||v.set(e,verify(t));let n=v.get(e);return n===void 0?[]:[n]}),u=x.filter(e=>a===void 0?n===void 0||n===e:a.some(t=>t.diagnosticCode===e));for(let t of u.filter(e=>!T.has(e))){let n=[...g.values()].filter(e=>e.fix.diagnosticCode===t);if(n.length>0){let r=verify({diagnosticCode:t,title:t===e.LegacyOptionalSuffix?`Use 'optional' throughout this document`:`Use bare pii and secret throughout this document`,scope:`document`,edits:n.flatMap(e=>e.fix.edits)});r!==void 0&&E.set(t,r)}T.add(t)}let f=u.flatMap(e=>E.has(e)?[E.get(e)]:[]);if(a!==void 0){if(w===void 0){w=/* @__PURE__ */ new Map;let e=d.flatMap(e=>g.has(e.number)?[g.get(e.number)]:[]),t=e.flatMap(e=>e.fix.edits),n=applyQuickFixEdits(r,t);if(t.length>0&&n!==void 0){let t=c(n,void 0,i.placement),r=e.flatMap(e=>e.change===void 0?[]:[e.change]);if(acceptable(t)&&verificationShape(t)===verificationShape(l,r)){let n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map;for(let e of t.diagnostics)n.set(e.code,(n.get(e.code)??0)+1);for(let t of e)r.set(t.fix.diagnosticCode,(r.get(t.fix.diagnosticCode)??0)+t.fix.edits.length);if([...r].every(([e,t])=>(n.get(e)??0)===(h.get(e)??0)-t))for(let t of e)w.set(t.line,t.fix)}}}let e=/* @__PURE__ */ new Map;for(let t of a){let n=w.get(t.line);n?.diagnosticCode===t.diagnosticCode&&e.set(t.line,n)}return[...e.values(),...s,...f]}let p=typeof t==`number`?t:void 0,m=p===void 0?void 0:g.get(p),y;return m!==void 0&&p!==void 0&&(n===void 0||m.fix.diagnosticCode===n)&&(C.has(p)||(C.size===32&&C.delete(C.keys().next().value),C.set(p,verify(m.fix,m.change))),y=C.get(p)),[...y===void 0?[]:[y],...s,...f]}}function legacyProfileLayoutFix(e,t,n){let indentOf=e=>/^\s*/.exec(e)[0].length,r=indentOf(e[t].raw),i,a=!1;for(let n=t+1;n<e.length;n++){let t=e[n].raw;if(t.trim().length!==0){if(indentOf(t)<=r)break;i===void 0&&/^\s*layout\s+[A-Za-z_]\w*\s*$/.test(t)&&(i={index:n,indent:indentOf(t)}),/^\s*root\s+template(\s|$)/.test(t)&&(a=!0)}}if(i===void 0)return;let o=e[i.index];return a?{diagnosticCode:n,title:`Remove the ignored layout line`,scope:`occurrence`,edits:[{start:o.startOffset,length:(e[i.index+1]?.startOffset??o.startOffset+o.raw.length)-o.startOffset,text:``}]}:{diagnosticCode:n,title:`Use 'root template' instead of 'layout'`,scope:`occurrence`,edits:[{start:o.startOffset+i.indent,length:6,text:`root template`}]}}function duplicateComplianceMarkerEdit(e,t){let n=r(`^(\\s*concept\\s+\\w+\\s*:\\s*\\w+)((?:[^\\S\\r\\n]+@?\\w+)*)`).exec(e);if(n===null)return;let a=n[2],o=/* @__PURE__ */ new Set,s=a.replace(new RegExp(r(`[^\\S\\r\\n]+(@?\\w+)`).source,`gu`),(e,t)=>{let n=i(t);return o.has(n)?``:(o.add(n),e)});return s===a?void 0:{start:t+n[1].length,length:a.length,text:s}}function complianceMarkerEdit(e,t){let n=r(`^(\\s*concept\\s+\\w+\\s*:\\s*\\w+)((?:[^\\S\\r\\n]+@?\\w+)*)`).exec(e);if(n!==null){let e=n[2],r=e.replace(/@pii\b|@?sensitive\b/g,e=>e===`@pii`?`pii`:`secret`);return r===e?void 0:{start:t+n[1].length,length:e.length,text:r}}let i=r(`^(\\s*)(@pii|@?sensitive)\\b`).exec(e);return i===null?void 0:{start:t+i[1].length,length:i[2].length,text:i[2]===`@pii`?`pii`:`secret`}}function verificationShape(e,t=[]){let n=new Map(t.map(e=>[e.node,e.replacement]));return JSON.stringify([e.value,e.triggerData],(e,t)=>[`location`,`usesLocation`,`targetLocation`].includes(e)?void 0:n.get(t)??t)}function applyQuickFixEdits(e,t){let n=[],r=0;for(let i of t){if(i.start<r||i.start<0||i.length<0||i.start+i.length>e.length)return;n.push(e.slice(r,i.start),i.text),r=i.start+i.length}return n.push(e.slice(r)),n.join(``)}export{applyQuickFixEdits,isQuickFixDiagnostic,legacyOptionalTypeLength,prepareQuickFixes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuickFixes.js","names":["code","DiagnosticCodes","diagnostic","line","original","parseForAuthoring","source","options","publicEventCodes","index","parsed","lines","splitLines","eventsByLine","slicesByLine","rulesByLine","ScreenplaySyntaxWalker","rule","event","slice","counts","byLine","duplicateByLine","duplicateVerdicts","events","edit","length","replacement","checkPortableMatchPattern","match","stringBodyPattern","spellings","quoted","character","indent","ending","candidates","direction","edited","candidate","originalCodes","fix","commentStart","declaration","spellingCodes","syntax","verified","rangeVerdicts","documentChecked","documentFixes","change","requests","duplicateLines","diagnosticCode","request","duplicates","number","selectedCodes","documents","edits","candidateSource","changes","remaining","removed","count","selected","occurrenceLine","occurrenceFix","raw","headerIndent","headerIndex","layout","hasRoot","header","pattern","suffix","seen","text","wire","complianceWireName","marker","token","startOffset","directive","replacements","key","value","parts","end"],"sources":["../../../../../../Compiler/Authoring/QuickFixes.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { PlayPlacement } from '../Files/PlayPlacement';\nimport { checkPortableMatchPattern } from '../Parsing/checkPortableMatchPattern';\nimport { ValidationRuleSyntax } from '../Syntax/Commands';\nimport { stringBodyPattern } from '../Text/StringLiteral';\nimport { complianceWireName } from '../Parsing/ConceptComplianceParser';\nimport { commentStart, splitLines } from '../Parsing/SourceLineSplitter';\nimport { parseForAuthoring } from '../ScreenplayCompiler';\nimport { EventSyntax } from '../Syntax/Declarations';\nimport { SliceSyntax } from '../Syntax/Structure';\nimport { TranslationDirection } from '../Syntax/TranslationDirection';\nimport { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker';\nimport { pattern } from '../Text/patterns';\nimport { QuickFixCandidate } from './QuickFixCandidate';\n\nexport interface QuickFixEdit {\n readonly start: number;\n readonly length: number;\n readonly text: string;\n}\n\nexport interface QuickFix {\n readonly diagnosticCode: string;\n readonly title: string;\n readonly scope: 'occurrence' | 'document';\n readonly edits: readonly QuickFixEdit[];\n}\n\nexport interface QuickFixOptions {\n readonly line?: number;\n readonly placement?: PlayPlacement;\n readonly diagnosticCode?: string;\n}\n\nexport function isQuickFixDiagnostic(code: unknown): code is string {\n return code === DiagnosticCodes.DeprecatedStudioTextRulePattern || code === DiagnosticCodes.DuplicateComplianceMarker || code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.LegacyComplianceMarker || code === DiagnosticCodes.RedundantEventId || code === DiagnosticCodes.PublicTranslationRequiresDirection || code === DiagnosticCodes.LegacyProfileLayout;\n}\n\n// Diagnostics point at the complete type, not at the suffix. Never derive edits from message text.\nexport function legacyOptionalTypeLength(line: string, diagnostic: Diagnostic): number {\n if (diagnostic.code !== DiagnosticCodes.LegacyOptionalSuffix) return 0;\n return /^[\\p{L}\\p{Mn}\\p{Nd}\\p{Pc}.]+(?:\\[\\])?\\?/u.exec(line.slice(diagnostic.location.column - 1))?.[0].length ?? 0;\n}\n\nexport function findQuickFixes(source: string, options: QuickFixOptions = {}): QuickFix[] {\n return prepareQuickFixes(source, options)(options.line, options.diagnosticCode);\n}\n\n// One immutable buffer version owns the analysis and document verdict. Cursor moves reuse them;\n// single-occurrence verdicts have a bounded cache. Range requests verify the independent recipes\n// together once per version, rather than reparsing N times for N intersecting markers.\nexport function prepareQuickFixes(source: string, options: Pick<QuickFixOptions, 'placement'> = {}): (line?: number | readonly { line: number; diagnosticCode: string }[], diagnosticCode?: string) => QuickFix[] {\n const original = parseForAuthoring(source, undefined, options.placement);\n // PLAY0614 and the public-event boundary errors that follow from a missing direction are errors the repair itself removes,\n // so a document whose only errors are public-event boundary errors stays repairable.\n const publicEventCodes: ReadonlySet<string> = new Set(Array.from({ length: 14 }, (_, index) => `PLAY0${607 + index}`));\n const acceptable = (parsed: ReturnType<typeof parseForAuthoring>): boolean => parsed.success || parsed.diagnostics.every(diagnostic => diagnostic.severity !== 'error' || publicEventCodes.has(diagnostic.code));\n const errorCodes = (parsed: ReturnType<typeof parseForAuthoring>): Set<string> => new Set(parsed.diagnostics.filter(diagnostic => diagnostic.severity === 'error').map(diagnostic => diagnostic.code));\n if (!acceptable(original)) return () => [];\n const lines = splitLines(source);\n const eventsByLine = new Map<number, EventSyntax>();\n const slicesByLine = new Map<number, SliceSyntax>();\n const rulesByLine = new Map<number, ValidationRuleSyntax>();\n // Index inline and standalone declarations once, without scanning the tree per diagnostic.\n const walker = new class extends ScreenplaySyntaxWalker {\n override visitValidationRule(rule: ValidationRuleSyntax): void { rulesByLine.set(rule.location.line, rule); super.visitValidationRule(rule); }\n override visitEvent(event: EventSyntax): void { eventsByLine.set(event.location.line, event); }\n override visitSlice(slice: SliceSyntax): void { slicesByLine.set(slice.location.line, slice); super.visitSlice(slice); }\n }();\n walker.visitApplication(original.value);\n const counts = new Map<string, number>();\n const byLine = new Map<number, QuickFixCandidate>();\n // Duplicate removal and legacy spelling can share a header. Keep their independently verified recipes separate.\n const duplicateByLine = new Map<number, QuickFix>();\n const duplicateVerdicts = new Map<number, QuickFix | undefined>();\n const events = new Map<number, EventSyntax>();\n let event: EventSyntax | undefined;\n for (const line of lines) {\n event = eventsByLine.get(line.number) ?? event;\n if (event !== undefined) events.set(line.number, event);\n }\n for (const diagnostic of original.diagnostics) {\n counts.set(diagnostic.code, (counts.get(diagnostic.code) ?? 0) + 1);\n const line = lines[diagnostic.location.line - 1];\n if (diagnostic.code === DiagnosticCodes.DuplicateComplianceMarker) {\n const edit = duplicateComplianceMarkerEdit(line.raw, line.startOffset);\n if (edit !== undefined) duplicateByLine.set(line.number, { diagnosticCode: diagnostic.code, title: 'Remove duplicate compliance markers', scope: 'occurrence', edits: [edit] });\n }\n const length = legacyOptionalTypeLength(line.raw, diagnostic);\n if (length > 0) {\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: \"Use 'optional' instead of '?'\", scope: 'occurrence', edits: [{ start: line.startOffset + diagnostic.location.column + length - 2, length: 1, text: ' optional' }] } });\n } else if (diagnostic.code === DiagnosticCodes.DeprecatedStudioTextRulePattern) {\n const rule = rulesByLine.get(line.number);\n if (rule?.rule !== 'Matches' || rule.value?.kind !== 'LiteralExpressionSyntax' || typeof rule.value.value !== 'string') continue;\n const replacement = checkPortableMatchPattern(rule.value.value).replacement;\n const match = new RegExp(`\\\\bmatches\\\\s+\"${stringBodyPattern}\"`).exec(line.raw);\n if (replacement === undefined || match === null) continue;\n const spellings = { Equal: '==', NotEqual: '!=', Contains: 'contains', NotContains: 'not contains', StartsWith: 'starts with', EndsWith: 'ends with' };\n const quoted = '\"' + replacement.value.replace(/[\"\\\\\\n\\r\\t]/g, character => JSON.stringify(character).slice(1, -1)) + '\"';\n byLine.set(line.number, { line: line.number,\n fix: { diagnosticCode: diagnostic.code, title: 'Use the equivalent ordinal text rule', scope: 'occurrence', edits: [{ start: line.startOffset + match.index, length: match[0].length, text: spellings[replacement.kind] + ' ' + quoted }] },\n change: { node: rule, replacement: { ...rule, rule: replacement.kind, value: { ...rule.value, value: replacement.value } } as ValidationRuleSyntax } });\n } else if (diagnostic.code === DiagnosticCodes.LegacyComplianceMarker) {\n const edit = complianceMarkerEdit(line.raw, line.startOffset);\n if (edit !== undefined) byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: 'Use bare pii and secret compliance markers', scope: 'occurrence', edits: [edit] } });\n } else if (diagnostic.code === DiagnosticCodes.PublicTranslationRequiresDirection) {\n // PLAY0614 is only reported on the declaration line of a Translate slice that has no direction.\n const slice = slicesByLine.get(line.number)!;\n // Offer a direction only when exactly one is consistent with the slice: the other would add errors.\n const indent = /^\\s*/.exec(line.raw)![0];\n const ending = source.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const candidates = [TranslationDirection.Inbound, TranslationDirection.Outbound].map(direction => ({ direction, text: `${ending}${indent} direction ${direction === TranslationDirection.Inbound ? 'inbound' : 'outbound'}` }))\n .filter(candidate => {\n // The insertion point is the end of an existing line, so the edit is always in bounds.\n const edited = applyQuickFixEdits(source, [{ start: line.startOffset + line.raw.length, length: 0, text: candidate.text }])!;\n const parsed = parseForAuthoring(edited, undefined, options.placement);\n const originalCodes = errorCodes(original);\n // Valid when the missing-direction error is gone and the direction introduces no kind of error the document lacked.\n return acceptable(parsed) && ![...errorCodes(parsed)].some(code => code === DiagnosticCodes.PublicTranslationRequiresDirection || !originalCodes.has(code));\n });\n if (candidates.length === 1) {\n const [{ direction, text }] = candidates;\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: `Declare 'direction ${direction === TranslationDirection.Inbound ? 'inbound' : 'outbound'}'`, scope: 'occurrence', edits: [{ start: line.startOffset + line.raw.length, length: 0, text }] },\n change: { node: slice, replacement: { ...slice, direction } as SliceSyntax } });\n }\n } else if (diagnostic.code === DiagnosticCodes.LegacyProfileLayout) {\n const fix = legacyProfileLayoutFix(lines, line.number - 1, diagnostic.code);\n if (fix !== undefined) byLine.set(line.number, { line: line.number, fix });\n } else if (diagnostic.code === DiagnosticCodes.RedundantEventId && commentStart(line.raw) < 0) {\n const declaration = events.get(line.number);\n if (declaration?.id !== declaration?.name || declaration === undefined) continue;\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: 'Remove the redundant event id', scope: 'occurrence', edits: [{ start: line.startOffset, length: (lines[line.number]?.startOffset ?? source.length) - line.startOffset, text: '' }] },\n change: { node: declaration, replacement: { ...declaration, id: null } as EventSyntax } });\n }\n }\n const spellingCodes = [DiagnosticCodes.LegacyOptionalSuffix, DiagnosticCodes.LegacyComplianceMarker];\n const syntax = verificationShape(original);\n const verified = new Map<number, QuickFix | undefined>();\n let rangeVerdicts: Map<number, QuickFix> | undefined;\n const documentChecked = new Set<string>();\n const documentFixes = new Map<string, QuickFix>();\n const verify = (fix: QuickFix, change?: QuickFixCandidate['change']): QuickFix | undefined => {\n const candidate = applyQuickFixEdits(source, fix.edits);\n if (candidate === undefined) return undefined;\n const parsed = parseForAuthoring(candidate, undefined, options.placement);\n if (!acceptable(parsed) || verificationShape(parsed) !== (change === undefined ? syntax : verificationShape(original, [change]))) return undefined;\n return parsed.diagnostics.filter(diagnostic => diagnostic.code === fix.diagnosticCode).length === (counts.get(fix.diagnosticCode) ?? 0) - fix.edits.length ? fix : undefined;\n };\n return (line, diagnosticCode) => {\n const requests = typeof line === 'number' || line === undefined ? undefined : line;\n const duplicateLines = requests === undefined\n ? typeof line === 'number' && (diagnosticCode === undefined || diagnosticCode === DiagnosticCodes.DuplicateComplianceMarker) ? [line] : []\n : requests.filter(request => request.diagnosticCode === DiagnosticCodes.DuplicateComplianceMarker).map(request => request.line);\n const duplicates = [...new Set(duplicateLines)].flatMap(number => {\n const fix = duplicateByLine.get(number);\n if (fix === undefined) return [];\n if (!duplicateVerdicts.has(number)) duplicateVerdicts.set(number, verify(fix));\n const verified = duplicateVerdicts.get(number);\n return verified === undefined ? [] : [verified];\n });\n const selectedCodes = spellingCodes.filter(code => requests === undefined ? diagnosticCode === undefined || diagnosticCode === code : requests.some(request => request.diagnosticCode === code));\n for (const code of selectedCodes.filter(code => !documentChecked.has(code))) {\n const candidates = [...byLine.values()].filter(candidate => candidate.fix.diagnosticCode === code);\n if (candidates.length > 0) {\n const fix = verify({ diagnosticCode: code, title: code === DiagnosticCodes.LegacyOptionalSuffix ? \"Use 'optional' throughout this document\" : 'Use bare pii and secret throughout this document', scope: 'document', edits: candidates.flatMap(candidate => candidate.fix.edits) });\n if (fix !== undefined) documentFixes.set(code, fix);\n }\n documentChecked.add(code);\n }\n const documents = selectedCodes.flatMap(code => documentFixes.has(code) ? [documentFixes.get(code)!] : []);\n if (requests !== undefined) {\n if (rangeVerdicts === undefined) {\n rangeVerdicts = new Map();\n // Source order gives ordered, non-overlapping edits without sorting. Recipes replace\n // distinct nodes/lines; the batch must preserve every other modeled member and remove\n // exactly the expected diagnostics before any of its occurrence edits can be offered.\n const candidates = lines.flatMap(line => byLine.has(line.number) ? [byLine.get(line.number)!] : []);\n const edits = candidates.flatMap(candidate => candidate.fix.edits);\n const candidateSource = applyQuickFixEdits(source, edits);\n if (edits.length > 0 && candidateSource !== undefined) {\n const parsed = parseForAuthoring(candidateSource, undefined, options.placement);\n const changes = candidates.flatMap(candidate => candidate.change === undefined ? [] : [candidate.change]);\n if (acceptable(parsed) && verificationShape(parsed) === verificationShape(original, changes)) {\n const remaining = new Map<string, number>();\n const removed = new Map<string, number>();\n for (const diagnostic of parsed.diagnostics) remaining.set(diagnostic.code, (remaining.get(diagnostic.code) ?? 0) + 1);\n for (const candidate of candidates) removed.set(candidate.fix.diagnosticCode, (removed.get(candidate.fix.diagnosticCode) ?? 0) + candidate.fix.edits.length);\n if ([...removed].every(([code, count]) => (remaining.get(code) ?? 0) === (counts.get(code) ?? 0) - count)) {\n for (const candidate of candidates) rangeVerdicts.set(candidate.line, candidate.fix);\n }\n }\n }\n }\n const selected = new Map<number, QuickFix>();\n for (const request of requests) {\n const fix = rangeVerdicts.get(request.line);\n if (fix?.diagnosticCode === request.diagnosticCode) selected.set(request.line, fix);\n }\n return [...selected.values(), ...duplicates, ...documents];\n }\n const occurrenceLine = typeof line === 'number' ? line : undefined;\n const selected = occurrenceLine === undefined ? undefined : byLine.get(occurrenceLine);\n let occurrenceFix: QuickFix | undefined;\n if (selected !== undefined && occurrenceLine !== undefined && (diagnosticCode === undefined || selected.fix.diagnosticCode === diagnosticCode)) {\n if (!verified.has(occurrenceLine)) {\n if (verified.size === 32) verified.delete(verified.keys().next().value!);\n verified.set(occurrenceLine, verify(selected.fix, selected.change));\n }\n occurrenceFix = verified.get(occurrenceLine);\n }\n return [...(occurrenceFix === undefined ? [] : [occurrenceFix]), ...duplicates, ...documents];\n };\n}\n\n// PLAY0791 is reported on the `ui profile` line. The canonical form is `root template <Name>`; beside a root template the legacy line is ignored, so it is removed.\nfunction legacyProfileLayoutFix(lines: readonly { readonly number: number; readonly raw: string; readonly startOffset: number }[], headerIndex: number, diagnosticCode: string): QuickFix | undefined {\n const indentOf = (raw: string): number => /^\\s*/.exec(raw)![0].length;\n const headerIndent = indentOf(lines[headerIndex].raw);\n let layout: { readonly index: number; readonly indent: number } | undefined;\n let hasRoot = false;\n for (let index = headerIndex + 1; index < lines.length; index++) {\n const raw = lines[index].raw;\n if (raw.trim().length === 0) continue;\n if (indentOf(raw) <= headerIndent) break;\n if (layout === undefined && /^\\s*layout\\s+[A-Za-z_]\\w*\\s*$/.test(raw)) layout = { index, indent: indentOf(raw) };\n if (/^\\s*root\\s+template(\\s|$)/.test(raw)) hasRoot = true;\n }\n if (layout === undefined) return undefined;\n const line = lines[layout.index];\n return hasRoot\n ? { diagnosticCode, title: 'Remove the ignored layout line', scope: 'occurrence', edits: [{ start: line.startOffset, length: (lines[layout.index + 1]?.startOffset ?? line.startOffset + line.raw.length) - line.startOffset, text: '' }] }\n : { diagnosticCode, title: \"Use 'root template' instead of 'layout'\", scope: 'occurrence', edits: [{ start: line.startOffset + layout.indent, length: 'layout'.length, text: 'root template' }] };\n}\n\nfunction duplicateComplianceMarkerEdit(raw: string, startOffset: number): QuickFixEdit | undefined {\n const header = pattern('^(\\\\s*concept\\\\s+\\\\w+\\\\s*:\\\\s*\\\\w+)((?:[^\\\\S\\\\r\\\\n]+@?\\\\w+)*)').exec(raw);\n if (header === null) return undefined;\n const suffix = header[2];\n const seen = new Set<string>();\n const text = suffix.replace(new RegExp(pattern('[^\\\\S\\\\r\\\\n]+(@?\\\\w+)').source, 'gu'), (token, marker: string) => {\n const wire = complianceWireName(marker);\n if (seen.has(wire)) return '';\n seen.add(wire);\n return token;\n });\n return text === suffix ? undefined : { start: startOffset + header[1].length, length: suffix.length, text };\n}\n\nfunction complianceMarkerEdit(raw: string, startOffset: number): QuickFixEdit | undefined {\n // Restrict rewriting to the suffix or leading directive marker, never comments or quoted reasons.\n const header = pattern('^(\\\\s*concept\\\\s+\\\\w+\\\\s*:\\\\s*\\\\w+)((?:[^\\\\S\\\\r\\\\n]+@?\\\\w+)*)').exec(raw);\n if (header !== null) {\n const suffix = header[2];\n const text = suffix.replace(/@pii\\b|@?sensitive\\b/g, marker => marker === '@pii' ? 'pii' : 'secret');\n return text === suffix ? undefined : { start: startOffset + header[1].length, length: suffix.length, text };\n }\n const directive = pattern('^(\\\\s*)(@pii|@?sensitive)\\\\b').exec(raw);\n return directive === null ? undefined : { start: startOffset + directive[1].length, length: directive[2].length, text: directive[2] === '@pii' ? 'pii' : 'secret' };\n}\n\nfunction verificationShape(parsed: ReturnType<typeof parseForAuthoring>, changes: readonly NonNullable<QuickFixCandidate['change']>[] = []): string {\n // Compare every modeled member (including trigger data), ignoring only source locations. A recipe\n // may replace only its original node; no other id or destination is normalized away.\n const replacements = new Map(changes.map(change => [change.node, change.replacement]));\n return JSON.stringify([parsed.value, parsed.triggerData], (key, value: unknown) => ['location', 'usesLocation', 'targetLocation'].includes(key) ? undefined : replacements.get(value as NonNullable<QuickFixCandidate['change']>['node']) ?? value);\n}\n\n// One forward pass; applying N edits by repeatedly slicing the document would be quadratic.\nexport function applyQuickFixEdits(source: string, edits: readonly QuickFixEdit[]): string | undefined {\n const parts: string[] = [];\n let end = 0;\n for (const edit of edits) {\n if (edit.start < end || edit.start < 0 || edit.length < 0 || edit.start + edit.length > source.length) return undefined;\n parts.push(source.slice(end, edit.start), edit.text);\n end = edit.start + edit.length;\n }\n parts.push(source.slice(end));\n return parts.join('');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QuickFixes.js","names":["code","DiagnosticCodes","diagnostic","line","local","source","options","timeline","requests","localFixes","diagnosticCode","selected","request","fixes","prepareTimelineQuickFixes","original","parseForAuthoring","publicEventCodes","index","parsed","lines","splitLines","eventsByLine","slicesByLine","rulesByLine","ScreenplaySyntaxWalker","rule","event","slice","counts","byLine","duplicateByLine","duplicateVerdicts","events","edit","length","replacement","checkPortableMatchPattern","match","stringBodyPattern","spellings","quoted","character","indent","ending","candidates","direction","edited","candidate","originalCodes","fix","commentStart","declaration","spellingCodes","syntax","verified","rangeVerdicts","documentChecked","documentFixes","change","duplicateLines","duplicates","number","selectedCodes","documents","edits","candidateSource","changes","remaining","removed","count","occurrenceLine","occurrenceFix","raw","headerIndent","headerIndex","layout","hasRoot","header","pattern","suffix","seen","text","wire","complianceWireName","marker","token","startOffset","directive","replacements","key","value","parts","end"],"sources":["../../../../../../Compiler/Authoring/QuickFixes.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { PlayPlacement } from '../Files/PlayPlacement';\nimport { checkPortableMatchPattern } from '../Parsing/checkPortableMatchPattern';\nimport { ValidationRuleSyntax } from '../Syntax/Commands';\nimport { stringBodyPattern } from '../Text/StringLiteral';\nimport { complianceWireName } from '../Parsing/ConceptComplianceParser';\nimport { commentStart, splitLines } from '../Parsing/SourceLineSplitter';\nimport { parseForAuthoring } from '../ScreenplayCompiler';\nimport { EventSyntax } from '../Syntax/Declarations';\nimport { SliceSyntax } from '../Syntax/Structure';\nimport { TranslationDirection } from '../Syntax/TranslationDirection';\nimport { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker';\nimport { pattern } from '../Text/patterns';\nimport { QuickFixCandidate } from './QuickFixCandidate';\nimport { prepareTimelineQuickFixes } from './TimelineQuickFixes';\n\nexport interface QuickFixEdit {\n /** Destination document for an application-snapshot repair; absent for a buffer-local edit. */\n readonly path?: string;\n readonly start: number;\n readonly length: number;\n readonly text: string;\n}\n\nexport interface QuickFix {\n /** Original diagnostic line, which may differ from the edited import's line. */\n readonly line?: number;\n readonly diagnosticCode: string;\n readonly title: string;\n readonly scope: 'occurrence' | 'document';\n readonly edits: readonly QuickFixEdit[];\n}\n\nexport interface QuickFixOptions {\n readonly path?: string;\n readonly documents?: ReadonlyMap<string, string>;\n readonly line?: number;\n readonly placement?: PlayPlacement;\n readonly diagnosticCode?: string;\n}\n\nexport function isQuickFixDiagnostic(code: unknown): code is string {\n return code === DiagnosticCodes.EventFromLaterSlice || code === DiagnosticCodes.DeprecatedStudioTextRulePattern || code === DiagnosticCodes.DuplicateComplianceMarker || code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.LegacyComplianceMarker || code === DiagnosticCodes.RedundantEventId || code === DiagnosticCodes.PublicTranslationRequiresDirection || code === DiagnosticCodes.LegacyProfileLayout;\n}\n\n// Diagnostics point at the complete type, not at the suffix. Never derive edits from message text.\nexport function legacyOptionalTypeLength(line: string, diagnostic: Diagnostic): number {\n if (diagnostic.code !== DiagnosticCodes.LegacyOptionalSuffix) return 0;\n return /^[\\p{L}\\p{Mn}\\p{Nd}\\p{Pc}.]+(?:\\[\\])?\\?/u.exec(line.slice(diagnostic.location.column - 1))?.[0].length ?? 0;\n}\n\nexport function findQuickFixes(source: string, options: QuickFixOptions = {}): QuickFix[] {\n return prepareQuickFixes(source, options)(options.line, options.diagnosticCode);\n}\n\n// One immutable buffer version owns the analysis and document verdict. Cursor moves reuse them;\n// single-occurrence verdicts have a bounded cache. Range requests verify the independent recipes\n// together once per version, rather than reparsing N times for N intersecting markers.\nexport function prepareQuickFixes(source: string, options: Pick<QuickFixOptions, 'placement' | 'path' | 'documents'> = {}): (line?: number | readonly { line: number; diagnosticCode: string }[], diagnosticCode?: string) => QuickFix[] {\n const local = prepareLocalQuickFixes(source, options);\n let timeline: ReturnType<typeof prepareTimelineQuickFixes> | undefined;\n return (line, diagnosticCode) => {\n const requests = typeof line === 'number' ? [{ line, diagnosticCode }] : line ?? [];\n const localFixes = local(line, diagnosticCode);\n const selected = requests.filter(request => request.diagnosticCode === DiagnosticCodes.EventFromLaterSlice || (request.diagnosticCode === undefined && localFixes.length === 0));\n const fixes = selected.length === 0 ? [] : [...new Set(selected.map(request => request.line))].flatMap(line => (timeline ??= prepareTimelineQuickFixes(source, options))(line));\n return [...localFixes, ...fixes];\n };\n}\n\nfunction prepareLocalQuickFixes(source: string, options: Pick<QuickFixOptions, 'placement'>): (line?: number | readonly { line: number; diagnosticCode: string }[], diagnosticCode?: string) => QuickFix[] {\n const original = parseForAuthoring(source, undefined, options.placement);\n // PLAY0614 and the public-event boundary errors that follow from a missing direction are errors the repair itself removes,\n // so a document whose only errors are public-event boundary errors stays repairable.\n const publicEventCodes: ReadonlySet<string> = new Set(Array.from({ length: 14 }, (_, index) => `PLAY0${607 + index}`));\n const acceptable = (parsed: ReturnType<typeof parseForAuthoring>): boolean => parsed.success || parsed.diagnostics.every(diagnostic => diagnostic.severity !== 'error' || publicEventCodes.has(diagnostic.code));\n const errorCodes = (parsed: ReturnType<typeof parseForAuthoring>): Set<string> => new Set(parsed.diagnostics.filter(diagnostic => diagnostic.severity === 'error').map(diagnostic => diagnostic.code));\n if (!acceptable(original)) return () => [];\n const lines = splitLines(source);\n const eventsByLine = new Map<number, EventSyntax>();\n const slicesByLine = new Map<number, SliceSyntax>();\n const rulesByLine = new Map<number, ValidationRuleSyntax>();\n // Index inline and standalone declarations once, without scanning the tree per diagnostic.\n const walker = new class extends ScreenplaySyntaxWalker {\n override visitValidationRule(rule: ValidationRuleSyntax): void { rulesByLine.set(rule.location.line, rule); super.visitValidationRule(rule); }\n override visitEvent(event: EventSyntax): void { eventsByLine.set(event.location.line, event); }\n override visitSlice(slice: SliceSyntax): void { slicesByLine.set(slice.location.line, slice); super.visitSlice(slice); }\n }();\n walker.visitApplication(original.value);\n const counts = new Map<string, number>();\n const byLine = new Map<number, QuickFixCandidate>();\n // Duplicate removal and legacy spelling can share a header. Keep their independently verified recipes separate.\n const duplicateByLine = new Map<number, QuickFix>();\n const duplicateVerdicts = new Map<number, QuickFix | undefined>();\n const events = new Map<number, EventSyntax>();\n let event: EventSyntax | undefined;\n for (const line of lines) {\n event = eventsByLine.get(line.number) ?? event;\n if (event !== undefined) events.set(line.number, event);\n }\n for (const diagnostic of original.diagnostics) {\n counts.set(diagnostic.code, (counts.get(diagnostic.code) ?? 0) + 1);\n const line = lines[diagnostic.location.line - 1];\n if (diagnostic.code === DiagnosticCodes.DuplicateComplianceMarker) {\n const edit = duplicateComplianceMarkerEdit(line.raw, line.startOffset);\n if (edit !== undefined) duplicateByLine.set(line.number, { diagnosticCode: diagnostic.code, title: 'Remove duplicate compliance markers', scope: 'occurrence', edits: [edit] });\n }\n const length = legacyOptionalTypeLength(line.raw, diagnostic);\n if (length > 0) {\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: \"Use 'optional' instead of '?'\", scope: 'occurrence', edits: [{ start: line.startOffset + diagnostic.location.column + length - 2, length: 1, text: ' optional' }] } });\n } else if (diagnostic.code === DiagnosticCodes.DeprecatedStudioTextRulePattern) {\n const rule = rulesByLine.get(line.number);\n if (rule?.rule !== 'Matches' || rule.value?.kind !== 'LiteralExpressionSyntax' || typeof rule.value.value !== 'string') continue;\n const replacement = checkPortableMatchPattern(rule.value.value).replacement;\n const match = new RegExp(`\\\\bmatches\\\\s+\"${stringBodyPattern}\"`).exec(line.raw);\n if (replacement === undefined || match === null) continue;\n const spellings = { Equal: '==', NotEqual: '!=', Contains: 'contains', NotContains: 'not contains', StartsWith: 'starts with', EndsWith: 'ends with' };\n const quoted = '\"' + replacement.value.replace(/[\"\\\\\\n\\r\\t]/g, character => JSON.stringify(character).slice(1, -1)) + '\"';\n byLine.set(line.number, { line: line.number,\n fix: { diagnosticCode: diagnostic.code, title: 'Use the equivalent ordinal text rule', scope: 'occurrence', edits: [{ start: line.startOffset + match.index, length: match[0].length, text: spellings[replacement.kind] + ' ' + quoted }] },\n change: { node: rule, replacement: { ...rule, rule: replacement.kind, value: { ...rule.value, value: replacement.value } } as ValidationRuleSyntax } });\n } else if (diagnostic.code === DiagnosticCodes.LegacyComplianceMarker) {\n const edit = complianceMarkerEdit(line.raw, line.startOffset);\n if (edit !== undefined) byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: 'Use bare pii and secret compliance markers', scope: 'occurrence', edits: [edit] } });\n } else if (diagnostic.code === DiagnosticCodes.PublicTranslationRequiresDirection) {\n // PLAY0614 is only reported on the declaration line of a Translate slice that has no direction.\n const slice = slicesByLine.get(line.number)!;\n // Offer a direction only when exactly one is consistent with the slice: the other would add errors.\n const indent = /^\\s*/.exec(line.raw)![0];\n const ending = source.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const candidates = [TranslationDirection.Inbound, TranslationDirection.Outbound].map(direction => ({ direction, text: `${ending}${indent} direction ${direction === TranslationDirection.Inbound ? 'inbound' : 'outbound'}` }))\n .filter(candidate => {\n // The insertion point is the end of an existing line, so the edit is always in bounds.\n const edited = applyQuickFixEdits(source, [{ start: line.startOffset + line.raw.length, length: 0, text: candidate.text }])!;\n const parsed = parseForAuthoring(edited, undefined, options.placement);\n const originalCodes = errorCodes(original);\n // Valid when the missing-direction error is gone and the direction introduces no kind of error the document lacked.\n return acceptable(parsed) && ![...errorCodes(parsed)].some(code => code === DiagnosticCodes.PublicTranslationRequiresDirection || !originalCodes.has(code));\n });\n if (candidates.length === 1) {\n const [{ direction, text }] = candidates;\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: `Declare 'direction ${direction === TranslationDirection.Inbound ? 'inbound' : 'outbound'}'`, scope: 'occurrence', edits: [{ start: line.startOffset + line.raw.length, length: 0, text }] },\n change: { node: slice, replacement: { ...slice, direction } as SliceSyntax } });\n }\n } else if (diagnostic.code === DiagnosticCodes.LegacyProfileLayout) {\n const fix = legacyProfileLayoutFix(lines, line.number - 1, diagnostic.code);\n if (fix !== undefined) byLine.set(line.number, { line: line.number, fix });\n } else if (diagnostic.code === DiagnosticCodes.RedundantEventId && commentStart(line.raw) < 0) {\n const declaration = events.get(line.number);\n if (declaration?.id !== declaration?.name || declaration === undefined) continue;\n byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: 'Remove the redundant event id', scope: 'occurrence', edits: [{ start: line.startOffset, length: (lines[line.number]?.startOffset ?? source.length) - line.startOffset, text: '' }] },\n change: { node: declaration, replacement: { ...declaration, id: null } as EventSyntax } });\n }\n }\n const spellingCodes = [DiagnosticCodes.LegacyOptionalSuffix, DiagnosticCodes.LegacyComplianceMarker];\n const syntax = verificationShape(original);\n const verified = new Map<number, QuickFix | undefined>();\n let rangeVerdicts: Map<number, QuickFix> | undefined;\n const documentChecked = new Set<string>();\n const documentFixes = new Map<string, QuickFix>();\n const verify = (fix: QuickFix, change?: QuickFixCandidate['change']): QuickFix | undefined => {\n const candidate = applyQuickFixEdits(source, fix.edits);\n if (candidate === undefined) return undefined;\n const parsed = parseForAuthoring(candidate, undefined, options.placement);\n if (!acceptable(parsed) || verificationShape(parsed) !== (change === undefined ? syntax : verificationShape(original, [change]))) return undefined;\n return parsed.diagnostics.filter(diagnostic => diagnostic.code === fix.diagnosticCode).length === (counts.get(fix.diagnosticCode) ?? 0) - fix.edits.length ? fix : undefined;\n };\n return (line, diagnosticCode) => {\n const requests = typeof line === 'number' || line === undefined ? undefined : line;\n const duplicateLines = requests === undefined\n ? typeof line === 'number' && (diagnosticCode === undefined || diagnosticCode === DiagnosticCodes.DuplicateComplianceMarker) ? [line] : []\n : requests.filter(request => request.diagnosticCode === DiagnosticCodes.DuplicateComplianceMarker).map(request => request.line);\n const duplicates = [...new Set(duplicateLines)].flatMap(number => {\n const fix = duplicateByLine.get(number);\n if (fix === undefined) return [];\n if (!duplicateVerdicts.has(number)) duplicateVerdicts.set(number, verify(fix));\n const verified = duplicateVerdicts.get(number);\n return verified === undefined ? [] : [verified];\n });\n const selectedCodes = spellingCodes.filter(code => requests === undefined ? diagnosticCode === undefined || diagnosticCode === code : requests.some(request => request.diagnosticCode === code));\n for (const code of selectedCodes.filter(code => !documentChecked.has(code))) {\n const candidates = [...byLine.values()].filter(candidate => candidate.fix.diagnosticCode === code);\n if (candidates.length > 0) {\n const fix = verify({ diagnosticCode: code, title: code === DiagnosticCodes.LegacyOptionalSuffix ? \"Use 'optional' throughout this document\" : 'Use bare pii and secret throughout this document', scope: 'document', edits: candidates.flatMap(candidate => candidate.fix.edits) });\n if (fix !== undefined) documentFixes.set(code, fix);\n }\n documentChecked.add(code);\n }\n const documents = selectedCodes.flatMap(code => documentFixes.has(code) ? [documentFixes.get(code)!] : []);\n if (requests !== undefined) {\n if (rangeVerdicts === undefined) {\n rangeVerdicts = new Map();\n // Source order gives ordered, non-overlapping edits without sorting. Recipes replace\n // distinct nodes/lines; the batch must preserve every other modeled member and remove\n // exactly the expected diagnostics before any of its occurrence edits can be offered.\n const candidates = lines.flatMap(line => byLine.has(line.number) ? [byLine.get(line.number)!] : []);\n const edits = candidates.flatMap(candidate => candidate.fix.edits);\n const candidateSource = applyQuickFixEdits(source, edits);\n if (edits.length > 0 && candidateSource !== undefined) {\n const parsed = parseForAuthoring(candidateSource, undefined, options.placement);\n const changes = candidates.flatMap(candidate => candidate.change === undefined ? [] : [candidate.change]);\n if (acceptable(parsed) && verificationShape(parsed) === verificationShape(original, changes)) {\n const remaining = new Map<string, number>();\n const removed = new Map<string, number>();\n for (const diagnostic of parsed.diagnostics) remaining.set(diagnostic.code, (remaining.get(diagnostic.code) ?? 0) + 1);\n for (const candidate of candidates) removed.set(candidate.fix.diagnosticCode, (removed.get(candidate.fix.diagnosticCode) ?? 0) + candidate.fix.edits.length);\n if ([...removed].every(([code, count]) => (remaining.get(code) ?? 0) === (counts.get(code) ?? 0) - count)) {\n for (const candidate of candidates) rangeVerdicts.set(candidate.line, candidate.fix);\n }\n }\n }\n }\n const selected = new Map<number, QuickFix>();\n for (const request of requests) {\n const fix = rangeVerdicts.get(request.line);\n if (fix?.diagnosticCode === request.diagnosticCode) selected.set(request.line, fix);\n }\n return [...selected.values(), ...duplicates, ...documents];\n }\n const occurrenceLine = typeof line === 'number' ? line : undefined;\n const selected = occurrenceLine === undefined ? undefined : byLine.get(occurrenceLine);\n let occurrenceFix: QuickFix | undefined;\n if (selected !== undefined && occurrenceLine !== undefined && (diagnosticCode === undefined || selected.fix.diagnosticCode === diagnosticCode)) {\n if (!verified.has(occurrenceLine)) {\n if (verified.size === 32) verified.delete(verified.keys().next().value!);\n verified.set(occurrenceLine, verify(selected.fix, selected.change));\n }\n occurrenceFix = verified.get(occurrenceLine);\n }\n return [...(occurrenceFix === undefined ? [] : [occurrenceFix]), ...duplicates, ...documents];\n };\n}\n\n// PLAY0791 is reported on the `ui profile` line. The canonical form is `root template <Name>`; beside a root template the legacy line is ignored, so it is removed.\nfunction legacyProfileLayoutFix(lines: readonly { readonly number: number; readonly raw: string; readonly startOffset: number }[], headerIndex: number, diagnosticCode: string): QuickFix | undefined {\n const indentOf = (raw: string): number => /^\\s*/.exec(raw)![0].length;\n const headerIndent = indentOf(lines[headerIndex].raw);\n let layout: { readonly index: number; readonly indent: number } | undefined;\n let hasRoot = false;\n for (let index = headerIndex + 1; index < lines.length; index++) {\n const raw = lines[index].raw;\n if (raw.trim().length === 0) continue;\n if (indentOf(raw) <= headerIndent) break;\n if (layout === undefined && /^\\s*layout\\s+[A-Za-z_]\\w*\\s*$/.test(raw)) layout = { index, indent: indentOf(raw) };\n if (/^\\s*root\\s+template(\\s|$)/.test(raw)) hasRoot = true;\n }\n if (layout === undefined) return undefined;\n const line = lines[layout.index];\n return hasRoot\n ? { diagnosticCode, title: 'Remove the ignored layout line', scope: 'occurrence', edits: [{ start: line.startOffset, length: (lines[layout.index + 1]?.startOffset ?? line.startOffset + line.raw.length) - line.startOffset, text: '' }] }\n : { diagnosticCode, title: \"Use 'root template' instead of 'layout'\", scope: 'occurrence', edits: [{ start: line.startOffset + layout.indent, length: 'layout'.length, text: 'root template' }] };\n}\n\nfunction duplicateComplianceMarkerEdit(raw: string, startOffset: number): QuickFixEdit | undefined {\n const header = pattern('^(\\\\s*concept\\\\s+\\\\w+\\\\s*:\\\\s*\\\\w+)((?:[^\\\\S\\\\r\\\\n]+@?\\\\w+)*)').exec(raw);\n if (header === null) return undefined;\n const suffix = header[2];\n const seen = new Set<string>();\n const text = suffix.replace(new RegExp(pattern('[^\\\\S\\\\r\\\\n]+(@?\\\\w+)').source, 'gu'), (token, marker: string) => {\n const wire = complianceWireName(marker);\n if (seen.has(wire)) return '';\n seen.add(wire);\n return token;\n });\n return text === suffix ? undefined : { start: startOffset + header[1].length, length: suffix.length, text };\n}\n\nfunction complianceMarkerEdit(raw: string, startOffset: number): QuickFixEdit | undefined {\n // Restrict rewriting to the suffix or leading directive marker, never comments or quoted reasons.\n const header = pattern('^(\\\\s*concept\\\\s+\\\\w+\\\\s*:\\\\s*\\\\w+)((?:[^\\\\S\\\\r\\\\n]+@?\\\\w+)*)').exec(raw);\n if (header !== null) {\n const suffix = header[2];\n const text = suffix.replace(/@pii\\b|@?sensitive\\b/g, marker => marker === '@pii' ? 'pii' : 'secret');\n return text === suffix ? undefined : { start: startOffset + header[1].length, length: suffix.length, text };\n }\n const directive = pattern('^(\\\\s*)(@pii|@?sensitive)\\\\b').exec(raw);\n return directive === null ? undefined : { start: startOffset + directive[1].length, length: directive[2].length, text: directive[2] === '@pii' ? 'pii' : 'secret' };\n}\n\nfunction verificationShape(parsed: ReturnType<typeof parseForAuthoring>, changes: readonly NonNullable<QuickFixCandidate['change']>[] = []): string {\n // Compare every modeled member (including trigger data), ignoring only source locations. A recipe\n // may replace only its original node; no other id or destination is normalized away.\n const replacements = new Map(changes.map(change => [change.node, change.replacement]));\n return JSON.stringify([parsed.value, parsed.triggerData], (key, value: unknown) => ['location', 'usesLocation', 'targetLocation'].includes(key) ? undefined : replacements.get(value as NonNullable<QuickFixCandidate['change']>['node']) ?? value);\n}\n\n// One forward pass; applying N edits by repeatedly slicing the document would be quadratic.\nexport function applyQuickFixEdits(source: string, edits: readonly QuickFixEdit[]): string | undefined {\n const parts: string[] = [];\n let end = 0;\n for (const edit of edits) {\n if (edit.start < end || edit.start < 0 || edit.length < 0 || edit.start + edit.length > source.length) return undefined;\n parts.push(source.slice(end, edit.start), edit.text);\n end = edit.start + edit.length;\n }\n parts.push(source.slice(end));\n return parts.join('');\n}\n"],"mappings":"iqBA6CA,SAAgB,qBAAqB,EAA+B,CAChE,OAAOA,IAASC,EAAgB,qBAAuBD,IAASC,EAAgB,iCAAmCD,IAASC,EAAgB,2BAA6BD,IAASC,EAAgB,sBAAwBD,IAASC,EAAgB,wBAA0BD,IAASC,EAAgB,kBAAoBD,IAASC,EAAgB,oCAAsCD,IAASC,EAAgB,mBACtZ,CAGA,SAAgB,yBAAyB,EAAc,EAAgC,CAEnF,OADIC,EAAW,OAASD,EAAgB,qBACjC,2CAA2C,KAAKE,EAAK,MAAMD,EAAW,SAAS,OAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAU,EAD7C,CAEzE,CASA,SAAgB,kBAAkB,EAAgB,EAAqE,CAAC,EAAiH,CACrO,IAAME,EAAQ,uBAAuBC,EAAQC,CAAO,EAChDC,EACJ,OAAQ,EAAM,IAAmB,CAC7B,IAAMC,EAAW,OAAOL,GAAS,SAAW,CAAC,CAAE,OAAM,gBAAe,CAAC,EAAIA,GAAQ,CAAC,EAC5EM,EAAaL,EAAMD,EAAMO,CAAc,EACvCC,EAAWH,EAAS,OAAO,GAAWI,EAAQ,iBAAmBX,EAAgB,qBAAwBW,EAAQ,iBAAmB,IAAA,IAAaH,EAAW,SAAW,CAAE,EACzKI,EAAQF,EAAS,SAAW,EAAI,CAAC,EAAI,CAAC,GAAG,IAAI,IAAIA,EAAS,IAAI,GAAWC,EAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAS,IAAaE,EAA0BT,EAAQC,CAAO,EAAA,CAAGH,CAAI,CAAC,EAC9K,MAAO,CAAC,GAAGM,EAAY,GAAGI,CAAK,CACnC,CACJ,CAEA,SAAS,uBAAuB,EAAgB,EAA2J,CACvM,IAAME,EAAWC,EAAkBX,EAAQ,IAAA,GAAWC,EAAQ,SAAS,EAGjEW,EAAwC,IAAI,IAAI,MAAM,KAAK,CAAE,OAAQ,EAAG,GAAI,EAAG,IAAU,QAAQ,IAAMC,GAAO,CAAC,EAC/G,WAAc,GAA0DC,EAAO,SAAWA,EAAO,YAAY,MAAM,GAAcjB,EAAW,WAAa,SAAWe,EAAiB,IAAIf,EAAW,IAAI,CAAC,EACzM,WAAc,GAA8D,IAAI,IAAIiB,EAAO,YAAY,OAAO,GAAcjB,EAAW,WAAa,OAAO,CAAC,CAAC,IAAI,GAAcA,EAAW,IAAI,CAAC,EACrM,GAAI,CAAC,WAAWa,CAAQ,EAAG,UAAa,CAAC,EACzC,IAAMK,EAAQC,EAAWhB,CAAM,EACzBiB,kBAAe,IAAI,IACnBC,kBAAe,IAAI,IACnBC,kBAAc,IAAI,IAOxB,IALmB,cAAcC,CAAuB,CACpD,oBAA6B,EAAkC,CAAED,EAAY,IAAIE,EAAK,SAAS,KAAMA,CAAI,EAAG,MAAM,oBAAoBA,CAAI,CAAG,CAC7I,WAAoB,EAA0B,CAAEJ,EAAa,IAAIK,EAAM,SAAS,KAAMA,CAAK,CAAG,CAC9F,WAAoB,EAA0B,CAAEJ,EAAa,IAAIK,EAAM,SAAS,KAAMA,CAAK,EAAG,MAAM,WAAWA,CAAK,CAAG,CAC3H,EACK,CAAC,CAAC,iBAAiBb,EAAS,KAAK,EACtC,IAAMc,kBAAS,IAAI,IACbC,kBAAS,IAAI,IAEbC,kBAAkB,IAAI,IACtBC,kBAAoB,IAAI,IACxBC,kBAAS,IAAI,IACfN,EACJ,IAAK,IAAMxB,KAAQiB,EACf,EAAQE,EAAa,IAAInB,EAAK,MAAM,GAAKwB,EACrCA,IAAU,IAAA,IAAWM,EAAO,IAAI9B,EAAK,OAAQwB,CAAK,EAE1D,IAAK,IAAMzB,KAAca,EAAS,YAAa,CAC3Cc,EAAO,IAAI3B,EAAW,MAAO2B,EAAO,IAAI3B,EAAW,IAAI,GAAK,GAAK,CAAC,EAClE,IAAMC,EAAOiB,EAAMlB,EAAW,SAAS,KAAO,GAC9C,GAAIA,EAAW,OAASD,EAAgB,0BAA2B,CAC/D,IAAMiC,EAAO,8BAA8B/B,EAAK,IAAKA,EAAK,WAAW,EACjE+B,IAAS,IAAA,IAAWH,EAAgB,IAAI5B,EAAK,OAAQ,CAAE,eAAgBD,EAAW,KAAM,MAAO,sCAAuC,MAAO,aAAc,MAAO,CAACgC,CAAI,CAAE,CAAC,CAClL,CACA,IAAMC,EAAS,yBAAyBhC,EAAK,IAAKD,CAAU,EAC5D,GAAIiC,EAAS,EACTL,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OAAQ,IAAK,CAAE,eAAgBD,EAAW,KAAM,MAAO,gCAAiC,MAAO,aAAc,MAAO,CAAC,CAAE,MAAOC,EAAK,YAAcD,EAAW,SAAS,OAASiC,EAAS,EAAG,OAAQ,EAAG,KAAM,WAAY,CAAC,CAAE,CAAE,CAAC,OAC/P,GAAIjC,EAAW,OAASD,EAAgB,gCAAiC,CAC5E,IAAMyB,EAAOF,EAAY,IAAIrB,EAAK,MAAM,EACxC,GAAIuB,GAAM,OAAS,WAAaA,EAAK,OAAO,OAAS,2BAA6B,OAAOA,EAAK,MAAM,OAAU,SAAU,SACxH,IAAMU,EAAcC,EAA0BX,EAAK,MAAM,KAAK,CAAC,CAAC,YAC1DY,EAAY,OAAO,kBAAkBC,EAAkB,EAAE,CAAC,CAAC,KAAKpC,EAAK,GAAG,EAC9E,GAAIiC,IAAgB,IAAA,IAAaE,IAAU,KAAM,SACjD,IAAME,EAAY,CAAE,MAAO,KAAM,SAAU,KAAM,SAAU,WAAY,YAAa,eAAgB,WAAY,cAAe,SAAU,WAAY,EAC/IC,EAAS,IAAML,EAAY,MAAM,QAAQ,eAAgB,GAAa,KAAK,UAAUM,CAAS,CAAC,CAAC,MAAM,EAAG,EAAE,CAAC,EAAI,IACtHZ,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OACjC,IAAK,CAAE,eAAgBD,EAAW,KAAM,MAAO,uCAAwC,MAAO,aAAc,MAAO,CAAC,CAAE,MAAOC,EAAK,YAAcmC,EAAM,MAAO,OAAQA,EAAM,EAAE,CAAC,OAAQ,KAAME,EAAUJ,EAAY,MAAQ,IAAMK,CAAO,CAAC,CAAE,EAC1O,OAAQ,CAAE,KAAMf,EAAM,YAAa,CAAE,GAAGA,EAAM,KAAMU,EAAY,KAAM,MAAO,CAAE,GAAGV,EAAK,MAAO,MAAOU,EAAY,KAAM,CAAE,CAA0B,CAAE,CAAC,CAC9J,MAAO,GAAIlC,EAAW,OAASD,EAAgB,uBAAwB,CACnE,IAAMiC,EAAO,qBAAqB/B,EAAK,IAAKA,EAAK,WAAW,EACxD+B,IAAS,IAAA,IAAWJ,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OAAQ,IAAK,CAAE,eAAgBD,EAAW,KAAM,MAAO,6CAA8C,MAAO,aAAc,MAAO,CAACgC,CAAI,CAAE,CAAE,CAAC,CAC5M,MAAO,GAAIhC,EAAW,OAASD,EAAgB,mCAAoC,CAE/E,IAAM2B,EAAQL,EAAa,IAAIpB,EAAK,MAAM,EAEpCwC,EAAS,OAAO,KAAKxC,EAAK,GAAG,CAAC,CAAE,GAChCyC,EAASvC,EAAO,SAAS;CAAM,EAAI;EAAS;EAC5CwC,EAAa,CAAA,UAAA,UAA4D,CAAC,CAAC,IAAI,IAAc,CAAE,YAAW,KAAM,GAAGD,IAASD,EAAO,cAAcG,IAAA,UAA6C,UAAY,YAAa,EAAE,CAAC,CAC3N,OAAO,GAAa,CAEjB,IAAMC,EAAS,mBAAmB1C,EAAQ,CAAC,CAAE,MAAOF,EAAK,YAAcA,EAAK,IAAI,OAAQ,OAAQ,EAAG,KAAM6C,EAAU,IAAK,CAAC,CAAC,EACpH7B,EAASH,EAAkB+B,EAAQ,IAAA,GAAWzC,EAAQ,SAAS,EAC/D2C,EAAgB,WAAWlC,CAAQ,EAEzC,OAAO,WAAWI,CAAM,GAAK,CAAC,CAAC,GAAG,WAAWA,CAAM,CAAC,CAAC,CAAC,KAAK,GAAQnB,IAASC,EAAgB,oCAAsC,CAACgD,EAAc,IAAIjD,CAAI,CAAC,CAC9J,CAAC,EACL,GAAI6C,EAAW,SAAW,EAAG,CACzB,GAAM,CAAC,CAAE,YAAW,SAAUA,EAC9Bf,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OAAQ,IAAK,CAAE,eAAgBD,EAAW,KAAM,MAAO,sBAAsB4C,IAAA,UAA6C,UAAY,WAAW,GAAI,MAAO,aAAc,MAAO,CAAC,CAAE,MAAO3C,EAAK,YAAcA,EAAK,IAAI,OAAQ,OAAQ,EAAG,MAAK,CAAC,CAAE,EACnR,OAAQ,CAAE,KAAMyB,EAAO,YAAa,CAAE,GAAGA,EAAO,WAAU,CAAiB,CAAE,CAAC,CACtF,CACJ,MAAO,GAAI1B,EAAW,OAASD,EAAgB,oBAAqB,CAChE,IAAMiD,EAAM,uBAAuB9B,EAAOjB,EAAK,OAAS,EAAGD,EAAW,IAAI,EACtEgD,IAAQ,IAAA,IAAWpB,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OAAQ,KAAI,CAAC,CAC7E,MAAO,GAAID,EAAW,OAASD,EAAgB,kBAAoBkD,EAAahD,EAAK,GAAG,EAAI,EAAG,CAC3F,IAAMiD,EAAcnB,EAAO,IAAI9B,EAAK,MAAM,EAC1C,GAAIiD,GAAa,KAAOA,GAAa,MAAQA,IAAgB,IAAA,GAAW,SACxEtB,EAAO,IAAI3B,EAAK,OAAQ,CAAE,KAAMA,EAAK,OAAQ,IAAK,CAAE,eAAgBD,EAAW,KAAM,MAAO,gCAAiC,MAAO,aAAc,MAAO,CAAC,CAAE,MAAOC,EAAK,YAAa,QAASiB,EAAMjB,EAAK,OAAO,EAAE,aAAeE,EAAO,QAAUF,EAAK,YAAa,KAAM,EAAG,CAAC,CAAE,EAC5Q,OAAQ,CAAE,KAAMiD,EAAa,YAAa,CAAE,GAAGA,EAAa,GAAI,IAAK,CAAiB,CAAE,CAAC,CACjG,CACJ,CACA,IAAMC,EAAgB,CAACpD,EAAgB,qBAAsBA,EAAgB,sBAAsB,EAC7FqD,EAAS,kBAAkBvC,CAAQ,EACnCwC,kBAAW,IAAI,IACjBC,EACEC,kBAAkB,IAAI,IACtBC,kBAAgB,IAAI,IACpB,QAAU,EAAe,IAA+D,CAC1F,IAAMV,EAAY,mBAAmB3C,EAAQ6C,EAAI,KAAK,EACtD,GAAIF,IAAc,IAAA,GAAW,OAC7B,IAAM7B,EAASH,EAAkBgC,EAAW,IAAA,GAAW1C,EAAQ,SAAS,EACxE,GAAK,WAAWa,CAAM,GAAK,kBAAkBA,CAAM,KAAOwC,IAAW,IAAA,GAAYL,EAAS,kBAAkBvC,EAAU,CAAC4C,CAAM,CAAC,GAC9H,OAAOxC,EAAO,YAAY,OAAO,GAAcjB,EAAW,OAASgD,EAAI,cAAc,CAAC,CAAC,UAAYrB,EAAO,IAAIqB,EAAI,cAAc,GAAK,GAAKA,EAAI,MAAM,OAASA,EAAM,IAAA,EACvK,EACA,OAAQ,EAAM,IAAmB,CAC7B,IAAM1C,EAAW,OAAOL,GAAS,UAAYA,IAAS,IAAA,GAAY,IAAA,GAAYA,EACxEyD,EAAiBpD,IAAa,IAAA,GAC9B,OAAOL,GAAS,WAAaO,IAAmB,IAAA,IAAaA,IAAmBT,EAAgB,2BAA6B,CAACE,CAAI,EAAI,CAAC,EACvIK,EAAS,OAAO,GAAWI,EAAQ,iBAAmBX,EAAgB,yBAAyB,CAAC,CAAC,IAAI,GAAWW,EAAQ,IAAI,EAC5HiD,EAAa,CAAC,GAAG,IAAI,IAAID,CAAc,CAAC,CAAC,CAAC,QAAQ,GAAU,CAC9D,IAAMV,EAAMnB,EAAgB,IAAI+B,CAAM,EACtC,GAAIZ,IAAQ,IAAA,GAAW,MAAO,CAAC,EAC1BlB,EAAkB,IAAI8B,CAAM,GAAG9B,EAAkB,IAAI8B,EAAQ,OAAOZ,CAAG,CAAC,EAC7E,IAAMK,EAAWvB,EAAkB,IAAI8B,CAAM,EAC7C,OAAOP,IAAa,IAAA,GAAY,CAAC,EAAI,CAACA,CAAQ,CAClD,CAAC,EACKQ,EAAgBV,EAAc,OAAO,GAAQ7C,IAAa,IAAA,GAAYE,IAAmB,IAAA,IAAaA,IAAmBV,EAAOQ,EAAS,KAAK,GAAWI,EAAQ,iBAAmBZ,CAAI,CAAC,EAC/L,IAAK,IAAMA,KAAQ+D,EAAc,OAAO,GAAQ,CAACN,EAAgB,IAAIzD,CAAI,CAAC,EAAG,CACzE,IAAM6C,EAAa,CAAC,GAAGf,EAAO,OAAO,CAAC,CAAC,CAAC,OAAO,GAAakB,EAAU,IAAI,iBAAmBhD,CAAI,EACjG,GAAI6C,EAAW,OAAS,EAAG,CACvB,IAAMK,EAAM,OAAO,CAAE,eAAgBlD,EAAM,MAAOA,IAASC,EAAgB,qBAAuB,0CAA4C,mDAAoD,MAAO,WAAY,MAAO4C,EAAW,QAAQ,GAAaG,EAAU,IAAI,KAAK,CAAE,CAAC,EAC9QE,IAAQ,IAAA,IAAWQ,EAAc,IAAI1D,EAAMkD,CAAG,CACtD,CACAO,EAAgB,IAAIzD,CAAI,CAC5B,CACA,IAAMgE,EAAYD,EAAc,QAAQ,GAAQL,EAAc,IAAI1D,CAAI,EAAI,CAAC0D,EAAc,IAAI1D,CAAI,CAAE,EAAI,CAAC,CAAC,EACzG,GAAIQ,IAAa,IAAA,GAAW,CACxB,GAAIgD,IAAkB,IAAA,GAAW,CAC7B,kBAAgB,IAAI,IAIpB,IAAMX,EAAazB,EAAM,QAAQ,GAAQU,EAAO,IAAI3B,EAAK,MAAM,EAAI,CAAC2B,EAAO,IAAI3B,EAAK,MAAM,CAAE,EAAI,CAAC,CAAC,EAC5F8D,EAAQpB,EAAW,QAAQ,GAAaG,EAAU,IAAI,KAAK,EAC3DkB,EAAkB,mBAAmB7D,EAAQ4D,CAAK,EACxD,GAAIA,EAAM,OAAS,GAAKC,IAAoB,IAAA,GAAW,CACnD,IAAM/C,EAASH,EAAkBkD,EAAiB,IAAA,GAAW5D,EAAQ,SAAS,EACxE6D,EAAUtB,EAAW,QAAQ,GAAaG,EAAU,SAAW,IAAA,GAAY,CAAC,EAAI,CAACA,EAAU,MAAM,CAAC,EACxG,GAAI,WAAW7B,CAAM,GAAK,kBAAkBA,CAAM,IAAM,kBAAkBJ,EAAUoD,CAAO,EAAG,CAC1F,IAAMC,kBAAY,IAAI,IAChBC,kBAAU,IAAI,IACpB,IAAK,IAAMnE,KAAciB,EAAO,YAAaiD,EAAU,IAAIlE,EAAW,MAAOkE,EAAU,IAAIlE,EAAW,IAAI,GAAK,GAAK,CAAC,EACrH,IAAK,IAAM8C,KAAaH,EAAYwB,EAAQ,IAAIrB,EAAU,IAAI,gBAAiBqB,EAAQ,IAAIrB,EAAU,IAAI,cAAc,GAAK,GAAKA,EAAU,IAAI,MAAM,MAAM,EAC3J,GAAI,CAAC,GAAGqB,CAAO,CAAC,CAAC,OAAO,CAACrE,EAAMsE,MAAYF,EAAU,IAAIpE,CAAI,GAAK,MAAQ6B,EAAO,IAAI7B,CAAI,GAAK,GAAKsE,CAAK,EACpG,IAAK,IAAMtB,KAAaH,EAAYW,EAAc,IAAIR,EAAU,KAAMA,EAAU,GAAG,CAE3F,CACJ,CACJ,CACA,IAAMrC,kBAAW,IAAI,IACrB,IAAK,IAAMC,KAAWJ,EAAU,CAC5B,IAAM0C,EAAMM,EAAc,IAAI5C,EAAQ,IAAI,EACtCsC,GAAK,iBAAmBtC,EAAQ,gBAAgBD,EAAS,IAAIC,EAAQ,KAAMsC,CAAG,CACtF,CACA,MAAO,CAAC,GAAGvC,EAAS,OAAO,EAAG,GAAGkD,EAAY,GAAGG,CAAS,CAC7D,CACA,IAAMO,EAAiB,OAAOpE,GAAS,SAAWA,EAAO,IAAA,GACnDQ,EAAW4D,IAAmB,IAAA,GAAY,IAAA,GAAYzC,EAAO,IAAIyC,CAAc,EACjFC,EAQJ,OAPI7D,IAAa,IAAA,IAAa4D,IAAmB,IAAA,KAAc7D,IAAmB,IAAA,IAAaC,EAAS,IAAI,iBAAmBD,KACtH6C,EAAS,IAAIgB,CAAc,IACxBhB,EAAS,OAAS,IAAIA,EAAS,OAAOA,EAAS,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAM,EACvEA,EAAS,IAAIgB,EAAgB,OAAO5D,EAAS,IAAKA,EAAS,MAAM,CAAC,GAEtE,EAAgB4C,EAAS,IAAIgB,CAAc,GAExC,CAAC,GAAIC,IAAkB,IAAA,GAAY,CAAC,EAAI,CAACA,CAAa,EAAI,GAAGX,EAAY,GAAGG,CAAS,CAChG,CACJ,CAGA,SAAS,uBAAuB,EAAmG,EAAqB,EAA8C,CAClM,IAAM,SAAY,GAAwB,OAAO,KAAKS,CAAG,CAAC,CAAE,EAAE,CAAC,OACzDC,EAAe,SAAStD,EAAMuD,EAAY,CAAC,GAAG,EAChDC,EACAC,EAAU,GACd,IAAK,IAAI3D,EAAQyD,EAAc,EAAGzD,EAAQE,EAAM,OAAQ,IAAS,CAC7D,IAAMqD,EAAMrD,EAAMF,EAAM,CAAC,IACzB,GAAIuD,EAAI,KAAK,CAAC,CAAC,SAAW,EAC1B,IAAI,SAASA,CAAG,GAAKC,EAAc,MAC/BE,IAAW,IAAA,IAAa,gCAAgC,KAAKH,CAAG,IAAG,EAAS,CAAE,QAAO,OAAQ,SAASA,CAAG,CAAE,GAC3G,4BAA4B,KAAKA,CAAG,IAAG,EAAU,GAFlB,CAGvC,CACA,GAAIG,IAAW,IAAA,GAAW,OAC1B,IAAMzE,EAAOiB,EAAMwD,EAAO,OAC1B,OAAOC,EACD,CAAE,iBAAgB,MAAO,iCAAkC,MAAO,aAAc,MAAO,CAAC,CAAE,MAAO1E,EAAK,YAAa,QAASiB,EAAMwD,EAAO,MAAQ,EAAE,EAAE,aAAezE,EAAK,YAAcA,EAAK,IAAI,QAAUA,EAAK,YAAa,KAAM,EAAG,CAAC,CAAE,EACxO,CAAE,iBAAgB,MAAO,0CAA2C,MAAO,aAAc,MAAO,CAAC,CAAE,MAAOA,EAAK,YAAcyE,EAAO,OAAQ,OAAQ,EAAiB,KAAM,eAAgB,CAAC,CAAE,CACxM,CAEA,SAAS,8BAA8B,EAAa,EAA+C,CAC/F,IAAME,EAASC,EAAQ,+DAA+D,CAAC,CAAC,KAAKN,CAAG,EAChG,GAAIK,IAAW,KAAM,OACrB,IAAME,EAASF,EAAO,GAChBG,kBAAO,IAAI,IACXC,EAAOF,EAAO,QAAQ,IAAI,OAAOD,EAAQ,uBAAuB,CAAC,CAAC,OAAQ,IAAI,GAAI,EAAO,IAAmB,CAC9G,IAAMI,EAAOC,EAAmBC,CAAM,EAGtC,OAFIJ,EAAK,IAAIE,CAAI,EAAU,IAC3BF,EAAK,IAAIE,CAAI,EACNG,EACX,CAAC,EACD,OAAOJ,IAASF,EAAS,IAAA,GAAY,CAAE,MAAOO,EAAcT,EAAO,EAAE,CAAC,OAAQ,OAAQE,EAAO,OAAQ,MAAK,CAC9G,CAEA,SAAS,qBAAqB,EAAa,EAA+C,CAEtF,IAAMF,EAASC,EAAQ,+DAA+D,CAAC,CAAC,KAAKN,CAAG,EAChG,GAAIK,IAAW,KAAM,CACjB,IAAME,EAASF,EAAO,GAChBI,EAAOF,EAAO,QAAQ,wBAAyB,GAAUK,IAAW,OAAS,MAAQ,QAAQ,EACnG,OAAOH,IAASF,EAAS,IAAA,GAAY,CAAE,MAAOO,EAAcT,EAAO,EAAE,CAAC,OAAQ,OAAQE,EAAO,OAAQ,MAAK,CAC9G,CACA,IAAMQ,EAAYT,EAAQ,8BAA8B,CAAC,CAAC,KAAKN,CAAG,EAClE,OAAOe,IAAc,KAAO,IAAA,GAAY,CAAE,MAAOD,EAAcC,EAAU,EAAE,CAAC,OAAQ,OAAQA,EAAU,EAAE,CAAC,OAAQ,KAAMA,EAAU,KAAO,OAAS,MAAQ,QAAS,CACtK,CAEA,SAAS,kBAAkB,EAA8C,EAA+D,CAAC,EAAW,CAGhJ,IAAMC,EAAe,IAAI,IAAItB,EAAQ,IAAI,GAAU,CAACR,EAAO,KAAMA,EAAO,WAAW,CAAC,CAAC,EACrF,OAAO,KAAK,UAAU,CAACxC,EAAO,MAAOA,EAAO,WAAW,GAAI,EAAK,IAAmB,CAAC,WAAY,eAAgB,gBAAgB,CAAC,CAAC,SAASuE,CAAG,EAAI,IAAA,GAAYD,EAAa,IAAIE,CAAyD,GAAKA,CAAK,CACtP,CAGA,SAAgB,mBAAmB,EAAgB,EAAoD,CACnG,IAAMC,EAAkB,CAAC,EACrBC,EAAM,EACV,IAAK,IAAM3D,KAAQ+B,EAAO,CACtB,GAAI/B,EAAK,MAAQ2D,GAAO3D,EAAK,MAAQ,GAAKA,EAAK,OAAS,GAAKA,EAAK,MAAQA,EAAK,OAAS7B,EAAO,OAAQ,OACvGuF,EAAM,KAAKvF,EAAO,MAAMwF,EAAK3D,EAAK,KAAK,EAAGA,EAAK,IAAI,EACnD,EAAMA,EAAK,MAAQA,EAAK,MAC5B,CAEA,OADA0D,EAAM,KAAKvF,EAAO,MAAMwF,CAAG,CAAC,EACrBD,EAAM,KAAK,EAAE,CACxB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{splitLines as e}from"../Parsing/SourceLineSplitter.js";import{authoredOrderOf as t,authoredOriginsOf as n,sameAuthoredStep as r}from"../Files/AuthoredOrder.js";import{timelineOrderFindings as i}from"../Files/TimelineOrder.js";import{parseForAuthoring as a}from"../ScreenplayCompiler.js";import{compileApplication as o}from"../Files/PlayApplicationAssembly.js";import{applyQuickFixEdits as s}from"./QuickFixes.js";var TimelineQuickFixContext=class{documents;compiled;ranks;origins;findings;#e=/* @__PURE__ */ new Map;constructor(e,r){this.documents=e,this.compiled=r,this.ranks=t(r.value),this.origins=n(r.value),this.findings=i(r.value)}block(e,t=!1){return[...this.ranks].sort((e,t)=>e[1]-t[1]).filter(([n])=>this.origins.get(n).some(n=>t?n.path===e.path&&n.node.kind===e.node.kind&&n.node.location.line===e.node.location.line&&n.node.location.column===e.node.location.column:r(n,e))).map(([e])=>e)}move(e,t,n){let r=[...this.ranks].sort((e,t)=>e[1]-t[1]).map(([e])=>e),contiguous=e=>e.length>0&&e.every((t,n)=>r[r.indexOf(e[0])+n]===t);if(!contiguous(e)||!contiguous(t)||e.some(e=>t.includes(e)))return;let i=r.filter(t=>!e.includes(t));return i.splice(i.indexOf(n?t.at(-1):t[0])+ +!!n,0,...e),new Map(i.map((e,t)=>[e,t]))}safe(e,t){let n=new Set(this.findings.filter(e=>e.key!==t.key).map(e=>e.key));return i(this.compiled.value,e).every(e=>n.has(e.key))}parsed(e){return this.#e.has(e)||this.#e.set(e,a(this.documents.get(e),e,this.compiled.documents.find(t=>t.path===e).placement,!1)),this.#e.get(e)}entries(e){let t=[],visit=e=>{for(let n of[`modules`,`features`,`slices`,`fileImports`])(e[n]??[]).forEach((r,i)=>{t.push({node:r,parent:e,member:n,index:i}),(r.kind===`ModuleSyntax`||r.kind===`FeatureSyntax`)&&visit(r)})};return visit(this.parsed(e).value),t}entry(e,t){let n=t.filter(t=>t.node.kind===e.node.kind&&t.node.location.line===e.node.location.line&&t.node.location.column===e.node.location.column);return n.length===1?n[0]:void 0}verify(e,n,r,c){let l=s(this.documents.get(n),e.fix.edits);if(l===void 0)return!1;let u=this.parsed(n),d=a(l,n,this.compiled.documents.find(e=>e.path===n).placement,!1),shape=(t,n=!1)=>JSON.stringify(t,(t,r)=>[`location`,`usesLocation`,`targetLocation`].includes(t)?void 0:n&&e.change!==void 0&&r===e.change.node?e.change.replacement:r);if(shape([u.value,u.triggerData],!0)!==shape([d.value,d.triggerData]))return!1;let f=new Map(this.documents).set(n,l),p=o(f);if(p.success!==this.compiled.success||p.documents.length!==this.compiled.documents.length||p.documents.some(e=>{let t=this.compiled.documents.find(t=>t.path===e.path);return t===void 0||t.isPlacementResolved!==e.isPlacementResolved||JSON.stringify(t.placement)!==JSON.stringify(e.placement)}))return!1;let m=t(p.value);if(m.size!==r.size||[...r].some(([e,t])=>m.get(e)!==t))return!1;let problems=e=>e.diagnostics.filter(e=>e.severity!==`information`).map(e=>JSON.stringify([e.code,e.severity,e.message,e.location.path])),h=problems(this.compiled),g=problems(p);if(g.some(e=>g.filter(t=>t===e).length>h.filter(t=>t===e).length))return!1;let _=new Set(this.findings.filter(e=>e.key!==c.key).map(e=>e.key));return i(p.value).every(e=>_.has(e.key))}};function moveTimelineText(t,n,r,i){let a=e(t),span=e=>{let n=a[e.location.line-1],r=/^\s*/.exec(n.raw)[0].length,i=a.slice(e.location.line).find(e=>e.raw.trim().length>0&&!e.raw.trimStart().startsWith(`//`)&&/^\s*/.exec(e.raw)[0].length<=r);return{start:n.startOffset,end:i?.startOffset??t.length}},o=span(n),s=span(r),c=i?s.end:s.start,l=t.includes(`\r
|
|
2
|
+
`)?`\r
|
|
3
|
+
`:`
|
|
4
|
+
`,u=t.slice(o.start,o.end);return c<t.length&&!u.endsWith(`
|
|
5
|
+
`)&&(u+=l),c===t.length&&!t.endsWith(`
|
|
6
|
+
`)&&(u=l+u.replace(/\r?\n$/,``)),c<o.start?t.slice(0,c)+u+t.slice(c,o.start)+t.slice(o.end):t.slice(0,o.start)+t.slice(o.end,c)+u+t.slice(c)}export{TimelineQuickFixContext,moveTimelineText};
|
|
7
|
+
//# sourceMappingURL=TimelineQuickFixContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelineQuickFixContext.js","names":["documents","compiled","authoredOrderOf","authoredOriginsOf","timelineOrderFindings","left","right","key","occurrence","origin","step","sameAuthoredStep","keys","block","index","moved","anchor","result","after","allowed","finding","target","ranks","#parsed","path","parseForAuthoring","document","member","parent","node","found","entries","entry","source","applyQuickFixEdits","candidate","original","parsed","value","replace","compileApplication","before","actual","rank","application","diagnostic","problem","lines","splitLines","line","indent","next","ending"],"sources":["../../../../../../Compiler/Authoring/TimelineQuickFixContext.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 { ApplicationCompilation, compileApplication } from '../Files/PlayApplicationAssembly';\nimport { AuthoredOrderStep, authoredOrderOf, authoredOriginsOf, sameAuthoredStep } from '../Files/AuthoredOrder';\nimport { TimelineFinding, timelineOrderFindings } from '../Files/TimelineOrder';\nimport { parseForAuthoring } from '../ScreenplayCompiler';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\nimport { ApplicationSyntax, FeatureSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { splitLines } from '../Parsing/SourceLineSplitter';\nimport { QuickFixCandidate } from './QuickFixCandidate';\nimport { applyQuickFixEdits } from './QuickFixes';\n\nexport interface TimelineEntry {\n readonly node: SyntaxNode;\n readonly parent: ApplicationSyntax | ModuleSyntax | FeatureSyntax;\n readonly member: 'modules' | 'features' | 'slices' | 'fileImports';\n readonly index: number;\n}\n\nexport class TimelineQuickFixContext {\n readonly ranks: ReadonlyMap<string, number>;\n readonly origins: ReadonlyMap<string, readonly AuthoredOrderStep[]>;\n readonly findings: readonly TimelineFinding[];\n readonly #parsed = new Map<string, ReturnType<typeof parseForAuthoring>>();\n constructor(readonly documents: ReadonlyMap<string, string>, readonly compiled: ApplicationCompilation) {\n this.ranks = authoredOrderOf(compiled.value);\n this.origins = authoredOriginsOf(compiled.value);\n this.findings = timelineOrderFindings(compiled.value);\n }\n block(step: AuthoredOrderStep, occurrence = false): string[] {\n return [...this.ranks].sort((left, right) => left[1] - right[1]).filter(([key]) => this.origins.get(key)!.some(origin => occurrence\n ? origin.path === step.path && origin.node.kind === step.node.kind && origin.node.location.line === step.node.location.line && origin.node.location.column === step.node.location.column\n : sameAuthoredStep(origin, step))).map(([key]) => key);\n }\n move(moved: readonly string[], anchor: readonly string[], after: boolean): ReadonlyMap<string, number> | undefined {\n const keys = [...this.ranks].sort((left, right) => left[1] - right[1]).map(([key]) => key);\n const contiguous = (block: readonly string[]) => block.length > 0 && block.every((key, index) => keys[keys.indexOf(block[0]) + index] === key);\n if (!contiguous(moved) || !contiguous(anchor) || moved.some(key => anchor.includes(key))) return undefined;\n const result = keys.filter(key => !moved.includes(key));\n result.splice(result.indexOf(after ? anchor.at(-1)! : anchor[0]) + (after ? 1 : 0), 0, ...moved);\n return new Map(result.map((key, index) => [key, index]));\n }\n safe(ranks: ReadonlyMap<string, number>, target: TimelineFinding): boolean {\n const allowed = new Set(this.findings.filter(finding => finding.key !== target.key).map(finding => finding.key));\n return timelineOrderFindings(this.compiled.value, ranks).every(finding => allowed.has(finding.key));\n }\n parsed(path: string): ReturnType<typeof parseForAuthoring> {\n if (!this.#parsed.has(path)) this.#parsed.set(path, parseForAuthoring(this.documents.get(path)!, path, this.compiled.documents.find(document => document.path === path)!.placement, false));\n return this.#parsed.get(path)!;\n }\n entries(path: string): TimelineEntry[] {\n const result: TimelineEntry[] = [];\n const visit = (parent: ApplicationSyntax | ModuleSyntax | FeatureSyntax) => {\n for (const member of ['modules', 'features', 'slices', 'fileImports'] as const) {\n const children = (parent as unknown as Record<string, readonly SyntaxNode[]>)[member] ?? [];\n children.forEach((node, index) => {\n result.push({ node, parent, member, index });\n if (node.kind === 'ModuleSyntax' || node.kind === 'FeatureSyntax') visit(node as ModuleSyntax | FeatureSyntax);\n });\n }\n };\n visit(this.parsed(path).value);\n return result;\n }\n entry(step: AuthoredOrderStep, entries: readonly TimelineEntry[]): TimelineEntry | undefined {\n const found = entries.filter(entry => entry.node.kind === step.node.kind && entry.node.location.line === step.node.location.line && entry.node.location.column === step.node.location.column);\n return found.length === 1 ? found[0] : undefined;\n }\n verify(candidate: QuickFixCandidate, path: string, ranks: ReadonlyMap<string, number>, finding: TimelineFinding): boolean {\n const source = applyQuickFixEdits(this.documents.get(path)!, candidate.fix.edits);\n if (source === undefined) return false;\n const original = this.parsed(path);\n const parsed = parseForAuthoring(source, path, this.compiled.documents.find(document => document.path === path)!.placement, false);\n const shape = (value: unknown, replace = false) => JSON.stringify(value, (key, node: unknown) => ['location', 'usesLocation', 'targetLocation'].includes(key) ? undefined : replace && candidate.change !== undefined && node === candidate.change.node ? candidate.change.replacement : node);\n if (shape([original.value, original.triggerData], true) !== shape([parsed.value, parsed.triggerData])) return false;\n const documents = new Map(this.documents).set(path, source);\n const compiled = compileApplication(documents);\n if (compiled.success !== this.compiled.success || compiled.documents.length !== this.compiled.documents.length || compiled.documents.some(document => {\n const before = this.compiled.documents.find(original => original.path === document.path);\n return before === undefined || before.isPlacementResolved !== document.isPlacementResolved || JSON.stringify(before.placement) !== JSON.stringify(document.placement);\n })) return false;\n const actual = authoredOrderOf(compiled.value);\n if (actual.size !== ranks.size || [...ranks].some(([key, rank]) => actual.get(key) !== rank)) return false;\n const problems = (application: ApplicationCompilation) => application.diagnostics.filter(diagnostic => diagnostic.severity !== 'information').map(diagnostic => JSON.stringify([diagnostic.code, diagnostic.severity, diagnostic.message, diagnostic.location.path]));\n const before = problems(this.compiled), after = problems(compiled);\n if (after.some(problem => after.filter(value => value === problem).length > before.filter(value => value === problem).length)) return false;\n const allowed = new Set(this.findings.filter(original => original.key !== finding.key).map(original => original.key));\n return timelineOrderFindings(compiled.value).every(candidate => allowed.has(candidate.key));\n }\n}\n\n/** Move intact physical text blocks; keep the enclosing source and its line-ending convention. */\nexport function moveTimelineText(source: string, moved: SyntaxNode, anchor: SyntaxNode, after: boolean): string {\n const lines = splitLines(source);\n const span = (node: SyntaxNode) => {\n const line = lines[node.location.line - 1];\n const indent = /^\\s*/.exec(line.raw)![0].length;\n const next = lines.slice(node.location.line).find(candidate => candidate.raw.trim().length > 0 && !candidate.raw.trimStart().startsWith('//') && /^\\s*/.exec(candidate.raw)![0].length <= indent);\n return { start: line.startOffset, end: next?.startOffset ?? source.length };\n };\n const left = span(moved), right = span(anchor);\n const target = after ? right.end : right.start;\n const ending = source.includes('\\r\\n') ? '\\r\\n' : '\\n';\n let block = source.slice(left.start, left.end);\n if (target < source.length && !block.endsWith('\\n')) block += ending;\n if (target === source.length && !source.endsWith('\\n')) block = ending + block.replace(/\\r?\\n$/, '');\n return target < left.start ? source.slice(0, target) + block + source.slice(target, left.start) + source.slice(left.end)\n : source.slice(0, left.start) + source.slice(left.end, target) + block + source.slice(target);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{commentStart as e,splitLines as t}from"../Parsing/SourceLineSplitter.js";import{matchesPlayPattern as n,resolvePlayPattern as r}from"../Files/PlayGlob.js";const hasMetacharacters=e=>/[*?[\]{}]/.test(e),relativePath=(e,t)=>{let n=e.split(`/`).slice(0,-1),r=t.split(`/`);for(;n.length>0&&n[0]===r[0];)n.shift(),r.shift();return[...n.map(()=>`..`),...r].join(`/`)};function timelineImportFix(i,a,o,s,c,l){let u=i.documents.get(o.path),d=t(u),f=d[c.node.location.line-1],p=/^\s*/.exec(f.raw)[0],m=u.includes(`\r
|
|
2
|
+
`)?`\r
|
|
3
|
+
`:`
|
|
4
|
+
`,h=c.parent.fileImports,propose=(t,n,r,s)=>{if(t.some(hasMetacharacters))return;let l=t.map(e=>({kind:`FileImportSyntax`,pattern:relativePath(o.path,e),location:c.node.location})),g={...c.parent,fileImports:[...h.slice(0,c.index),...l,...h.slice(c.index+r)]},_=r===0?f.startOffset:d[h[c.index+r-1].location.line]?.startOffset??u.length,v=new Set(h.slice(c.index,c.index+r).map(e=>e.location.line)),y=(r===0?[]:d.filter(e=>e.startOffset>=f.startOffset&&e.startOffset<_).flatMap(t=>{if(!v.has(t.number))return[u.slice(t.startOffset,d[t.number]?.startOffset??u.length)];let n=e(t.raw);return n<0?[]:[`${p}${t.raw.slice(n)}${m}`]})).join(``)+l.map(e=>`${p}import ${JSON.stringify(e.pattern)}${m}`).join(``),b={line:a.diagnostic.location.line,change:{node:c.parent,replacement:g},fix:{diagnosticCode:a.diagnostic.code,title:s,scope:`occurrence`,line:a.diagnostic.location.line,edits:[{path:o.path,start:f.startOffset,length:_-f.startOffset,text:y}]}};return i.verify(b,o.path,n,a)?b:void 0};if(c.index===l.index){let e=[...new Map([...i.origins.values()].flatMap(e=>e).filter(e=>e.path===o.path&&e.node.kind===`FileImportSyntax`&&e.node.location.line===o.node.location.line).map(e=>[e.targetPath,e])).values()].sort((e,t)=>e.matchIndex-t.matchIndex);if(e.length<2)return;let t=e.map(e=>e.targetPath),n=[...i.ranks].sort((e,t)=>e[1]-t[1]).map(([e])=>e),r=e.flatMap(e=>i.block(e)),c=n.indexOf(r[0]);if(!r.every((e,t)=>n[c+t]===e))return;let ranksFor=a=>{let o=[...a,...t.filter(e=>!a.includes(e))].flatMap(t=>i.block(e.find(e=>e.targetPath===t))),s=[...n];return s.splice(c,r.length,...o),new Map(s.map((e,t)=>[e,t]))},l=ranksFor([s.targetPath]);if(i.safe(l,a))return propose([s.targetPath],l,0,`Pin timeline order before the glob (new files remain imported)`);for(let e of[!1,!0]){let n=[...t],r=e?o.targetPath:s.targetPath,c=e?s.targetPath:o.targetPath;n.splice(n.indexOf(r),1),n.splice(n.indexOf(c)+ +!!e,0,r);let l=ranksFor(n);if(i.safe(l,a))for(let e=1;e<=n.length;e++){let t=n.slice(0,e),r=ranksFor(t);if(![...l].some(([e,t])=>r.get(e)!==t))return propose(t,r,0,`Pin timeline order before the glob (new files remain imported)`)}}return}if(c.index>l.index)return;let g=h.slice(c.index,l.index+1);if(!g.some(e=>hasMetacharacters(e.pattern)))return;let _=g.flatMap(e=>i.compiled.documents.filter(t=>t.path!==o.path&&n(r(o.path,e.pattern),t.path)).map(e=>e.path).sort());if(new Set(_).size===_.length)for(let e of[!1,!0]){let t=i.move(i.block(e?o:s),i.block(e?s:o),e);if(t===void 0||!i.safe(t,a))continue;let n=[..._],r=e?o.targetPath:s.targetPath,c=e?s.targetPath:o.targetPath;if(!n.includes(r)||!n.includes(c))continue;n.splice(n.indexOf(r),1),n.splice(n.indexOf(c)+ +!!e,0,r);let l=propose(n,t,g.length,`Replace timeline globs with ordered imports (new files need explicit imports)`);if(l!==void 0)return l}}export{timelineImportFix};
|
|
5
|
+
//# sourceMappingURL=TimelineQuickFixImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelineQuickFixImports.js","names":["path","folder","document","parts","target","source","context","left","lines","splitLines","line","entry","indent","ending","imports","paths","nodes","replacement","remove","last","importLines","imported","text","candidate","comment","commentStart","node","finding","ranks","other","steps","chain","step","right","keys","key","all","position","index","ordered","prefix","result","single","after","desired","moved","anchor","count","rank","selected","matchesPlayPattern","resolvePlayPattern"],"sources":["../../../../../../Compiler/Authoring/TimelineQuickFixImports.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 { AuthoredOrderStep } from '../Files/AuthoredOrder';\nimport { TimelineFinding } from '../Files/TimelineOrder';\nimport { matchesPlayPattern, resolvePlayPattern } from '../Files/PlayGlob';\nimport { FileImportSyntax } from '../Syntax/Structure';\nimport { commentStart, splitLines } from '../Parsing/SourceLineSplitter';\nimport { QuickFixCandidate } from './QuickFixCandidate';\nimport { TimelineEntry, TimelineQuickFixContext } from './TimelineQuickFixContext';\n\nconst hasMetacharacters = (path: string) => /[*?[\\]{}]/.test(path);\nconst relativePath = (document: string, target: string): string => {\n const folder = document.split('/').slice(0, -1), parts = target.split('/');\n while (folder.length > 0 && folder[0] === parts[0]) { folder.shift(); parts.shift(); }\n return [...folder.map(() => '..'), ...parts].join('/');\n};\n\nexport function timelineImportFix(context: TimelineQuickFixContext, finding: TimelineFinding, left: AuthoredOrderStep, right: AuthoredOrderStep, entry: TimelineEntry, other: TimelineEntry): QuickFixCandidate | undefined {\n const source = context.documents.get(left.path)!;\n const lines = splitLines(source);\n const line = lines[entry.node.location.line - 1];\n const indent = /^\\s*/.exec(line.raw)![0];\n const ending = source.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const imports = (entry.parent as unknown as { fileImports: readonly FileImportSyntax[] }).fileImports;\n const propose = (paths: readonly string[], ranks: ReadonlyMap<string, number>, remove: number, title: string): QuickFixCandidate | undefined => {\n if (paths.some(hasMetacharacters)) return undefined;\n const nodes = paths.map(path => ({ kind: 'FileImportSyntax' as const, pattern: relativePath(left.path, path), location: entry.node.location }));\n const replacement = { ...entry.parent, fileImports: [...imports.slice(0, entry.index), ...nodes, ...imports.slice(entry.index + remove)] };\n const last = remove === 0 ? line.startOffset : lines[imports[entry.index + remove - 1].location.line]?.startOffset ?? source.length;\n // Keep comments attached to each replaced import exactly once. Pins leave the original line intact.\n const importLines = new Set(imports.slice(entry.index, entry.index + remove).map(imported => imported.location.line));\n const comments = remove === 0 ? [] : lines.filter(candidate => candidate.startOffset >= line.startOffset && candidate.startOffset < last).flatMap(candidate => {\n if (!importLines.has(candidate.number)) return [source.slice(candidate.startOffset, lines[candidate.number]?.startOffset ?? source.length)];\n const comment = commentStart(candidate.raw);\n return comment < 0 ? [] : [`${indent}${candidate.raw.slice(comment)}${ending}`];\n });\n const text = comments.join('') + nodes.map(node => `${indent}import ${JSON.stringify(node.pattern)}${ending}`).join('');\n const candidate: QuickFixCandidate = { line: finding.diagnostic.location.line, change: { node: entry.parent, replacement }, fix: {\n diagnosticCode: finding.diagnostic.code, title, scope: 'occurrence', line: finding.diagnostic.location.line,\n edits: [{ path: left.path, start: line.startOffset, length: last - line.startOffset, text }],\n } };\n return context.verify(candidate, left.path, ranks, finding) ? candidate : undefined;\n };\n if (entry.index === other.index) {\n const steps = [...new Map([...context.origins.values()].flatMap(chain => chain).filter(step => step.path === left.path && step.node.kind === 'FileImportSyntax' && step.node.location.line === left.node.location.line).map(step => [step.targetPath!, step])).values()].sort((left, right) => left.matchIndex! - right.matchIndex!);\n if (steps.length < 2) return undefined;\n const paths = steps.map(step => step.targetPath!);\n const keys = [...context.ranks].sort((left, right) => left[1] - right[1]).map(([key]) => key);\n const all = steps.flatMap(step => context.block(step));\n const position = keys.indexOf(all[0]);\n if (!all.every((key, index) => keys[position + index] === key)) return undefined;\n const ranksFor = (prefix: readonly string[]) => {\n const ordered = [...prefix, ...paths.filter(path => !prefix.includes(path))].flatMap(path => context.block(steps.find(step => step.targetPath === path)!));\n const result = [...keys];\n result.splice(position, all.length, ...ordered);\n return new Map(result.map((key, index) => [key, index]));\n };\n const single = ranksFor([right.targetPath!]);\n if (context.safe(single, finding)) return propose([right.targetPath!], single, 0, 'Pin timeline order before the glob (new files remain imported)');\n for (const after of [false, true]) {\n const desired = [...paths];\n const moved = after ? left.targetPath! : right.targetPath!, anchor = after ? right.targetPath! : left.targetPath!;\n desired.splice(desired.indexOf(moved), 1);\n desired.splice(desired.indexOf(anchor) + (after ? 1 : 0), 0, moved);\n const ranks = ranksFor(desired);\n if (!context.safe(ranks, finding)) continue;\n for (let count = 1; count <= desired.length; count++) {\n const prefix = desired.slice(0, count);\n const candidate = ranksFor(prefix);\n if ([...ranks].some(([key, rank]) => candidate.get(key) !== rank)) continue;\n return propose(prefix, candidate, 0, 'Pin timeline order before the glob (new files remain imported)');\n }\n }\n return undefined;\n }\n // Freeze only the affected adjacent import interval. Include files with no ranked declaration.\n if (entry.index > other.index) return undefined;\n const selected = imports.slice(entry.index, other.index + 1);\n if (!selected.some(imported => hasMetacharacters(imported.pattern))) return undefined;\n const paths = selected.flatMap(imported => context.compiled.documents.filter(document => document.path !== left.path && matchesPlayPattern(resolvePlayPattern(left.path, imported.pattern), document.path)).map(document => document.path).sort());\n if (new Set(paths).size !== paths.length) return undefined;\n for (const after of [false, true]) {\n const ranks = context.move(context.block(after ? left : right), context.block(after ? right : left), after);\n if (ranks === undefined || !context.safe(ranks, finding)) continue;\n const desired = [...paths];\n const moved = after ? left.targetPath! : right.targetPath!, anchor = after ? right.targetPath! : left.targetPath!;\n if (!desired.includes(moved) || !desired.includes(anchor)) continue;\n desired.splice(desired.indexOf(moved), 1);\n desired.splice(desired.indexOf(anchor) + (after ? 1 : 0), 0, moved);\n const candidate = propose(desired, ranks, selected.length, 'Replace timeline globs with ordered imports (new files need explicit imports)');\n if (candidate !== undefined) return candidate;\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{authoredOrderKey as t,sameAuthoredStep as n}from"../Files/AuthoredOrder.js";import{compileApplication as r}from"../Files/PlayApplicationAssembly.js";import{TimelineQuickFixContext as i,moveTimelineText as a}from"./TimelineQuickFixContext.js";import{timelineImportFix as o}from"./TimelineQuickFixImports.js";function prepareTimelineQuickFixes(s,c){let l=c.path??`application.play`,u=new Map(c.documents??[[l,s]]);if(u.get(l)!==s||c.documents===void 0&&(c.placement?.length??0)>0)return()=>[];let d=r(u);if(!d.success||d.documents.some(e=>e.isPlacementResolved===!1))return()=>[];let f=new i(u,d),p=/* @__PURE__ */ new Map;return r=>{if(p.has(r))return p.get(r);let i=f.findings.filter(t=>t.diagnostic.code===e.EventFromLaterSlice&&t.diagnostic.location.path===l&&t.diagnostic.location.line===r),s=[];if(i.length===1&&!i[0].ownSubFeature){let e=i[0],l=f.origins.get(t(e.consumerScope)),d=f.origins.get(t(e.producerScope));if(l!==void 0&&d!==void 0){let t=0;for(;t<l.length&&t<d.length&&n(l[t],d[t]);)t++;let i=l[t],p=d[t];if(i!==void 0&&p!==void 0&&i.path===p.path){let t=f.entries(i.path),n=f.entry(i,t),l=f.entry(p,t);if(n!==void 0&&l!==void 0&&n.parent===l.parent&&n.member===l.member){let t;if(n.index!==l.index)for(let o of[!1,!0]){let s=o?n:l,c=o?l:n,d=o?i:p,m=o?p:i,h=f.move(f.block(d,d.node.kind===`FileImportSyntax`),f.block(m,m.node.kind===`FileImportSyntax`),o);if(h===void 0||!f.safe(h,e))continue;let g=[...n.parent[n.member]];g.splice(s.index,1),g.splice(g.indexOf(c.node)+ +!!o,0,s.node);let _={...n.parent,[n.member]:g},v=u.get(i.path);if(t={line:r,change:{node:n.parent,replacement:_},fix:{diagnosticCode:e.diagnostic.code,line:r,title:e.readModel?`Draw the read-model builder before its reader`:`Draw the event producer before its consumer`,scope:`occurrence`,edits:[{path:i.path,start:0,length:v.length,text:a(v,s.node,c.node,o)}]}},f.verify(t,i.path,h,e))break;t=void 0}t===void 0&&i.node.kind===`FileImportSyntax`&&p.node.kind===`FileImportSyntax`&&(t=o(f,e,i,p,n,l)),t!==void 0&&s.push(c.documents===void 0?{...t.fix,edits:t.fix.edits.map(({path:e,...t})=>t)}:t.fix)}}}}return p.size===32&&p.delete(p.keys().next().value),p.set(r,s),s}}export{prepareTimelineQuickFixes};
|
|
2
|
+
//# sourceMappingURL=TimelineQuickFixes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelineQuickFixes.js","names":["path","options","documents","source","compiled","compileApplication","document","context","TimelineQuickFixContext","cache","line","findings","finding","DiagnosticCodes","candidates","consumer","authoredOrderKey","producer","common","sameAuthoredStep","left","right","entries","first","second","candidate","after","moved","anchor","movedStep","anchorStep","ranks","siblings","replacement","original","moveTimelineText","timelineImportFix","_path","edit"],"sources":["../../../../../../Compiler/Authoring/TimelineQuickFixes.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 { authoredOrderKey, sameAuthoredStep } from '../Files/AuthoredOrder';\nimport { compileApplication } from '../Files/PlayApplicationAssembly';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { QuickFix, QuickFixOptions } from './QuickFixes';\nimport { QuickFixCandidate } from './QuickFixCandidate';\nimport { TimelineQuickFixContext, moveTimelineText } from './TimelineQuickFixContext';\nimport { timelineImportFix } from './TimelineQuickFixImports';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\n\n/** Owns one immutable application snapshot. No recipe is derived from diagnostic message text. */\nexport function prepareTimelineQuickFixes(source: string, options: QuickFixOptions): (line: number) => QuickFix[] {\n const path = options.path ?? 'application.play';\n const documents = new Map(options.documents ?? [[path, source]]);\n if (documents.get(path) !== source || (options.documents === undefined && (options.placement?.length ?? 0) > 0)) return () => [];\n const compiled = compileApplication(documents);\n if (!compiled.success || compiled.documents.some(document => document.isPlacementResolved === false)) return () => [];\n const context = new TimelineQuickFixContext(documents, compiled);\n const cache = new Map<number, QuickFix[]>();\n return line => {\n if (cache.has(line)) return cache.get(line)!;\n const findings = context.findings.filter(finding => finding.diagnostic.code === DiagnosticCodes.EventFromLaterSlice && finding.diagnostic.location.path === path && finding.diagnostic.location.line === line);\n const candidates: QuickFix[] = [];\n // Several event references on one line cannot be addressed unambiguously by this line-only API.\n if (findings.length === 1 && !findings[0].ownSubFeature) {\n const finding = findings[0];\n const consumer = context.origins.get(authoredOrderKey(finding.consumerScope));\n const producer = context.origins.get(authoredOrderKey(finding.producerScope));\n if (consumer !== undefined && producer !== undefined) {\n let common = 0;\n while (common < consumer.length && common < producer.length && sameAuthoredStep(consumer[common], producer[common])) common++;\n const left = consumer[common], right = producer[common];\n if (left !== undefined && right !== undefined && left.path === right.path) {\n const entries = context.entries(left.path);\n const first = context.entry(left, entries), second = context.entry(right, entries);\n if (first !== undefined && second !== undefined && first.parent === second.parent && first.member === second.member) {\n let candidate: QuickFixCandidate | undefined;\n if (first.index !== second.index) {\n for (const after of [false, true]) {\n const moved = after ? first : second, anchor = after ? second : first;\n const movedStep = after ? left : right, anchorStep = after ? right : left;\n const ranks = context.move(context.block(movedStep, movedStep.node.kind === 'FileImportSyntax'), context.block(anchorStep, anchorStep.node.kind === 'FileImportSyntax'), after);\n if (ranks === undefined || !context.safe(ranks, finding)) continue;\n const siblings = [...(first.parent as unknown as Record<string, readonly SyntaxNode[]>)[first.member]];\n siblings.splice(moved.index, 1);\n siblings.splice(siblings.indexOf(anchor.node) + (after ? 1 : 0), 0, moved.node);\n const replacement = { ...first.parent, [first.member]: siblings };\n const original = documents.get(left.path)!;\n candidate = { line, change: { node: first.parent, replacement }, fix: {\n diagnosticCode: finding.diagnostic.code, line, title: finding.readModel ? 'Draw the read-model builder before its reader' : 'Draw the event producer before its consumer', scope: 'occurrence',\n edits: [{ path: left.path, start: 0, length: original.length, text: moveTimelineText(original, moved.node, anchor.node, after) }],\n } };\n if (context.verify(candidate, left.path, ranks, finding)) break;\n candidate = undefined;\n }\n }\n if (candidate === undefined && left.node.kind === 'FileImportSyntax' && right.node.kind === 'FileImportSyntax') candidate = timelineImportFix(context, finding, left, right, first, second);\n if (candidate !== undefined) candidates.push(options.documents === undefined ? { ...candidate.fix, edits: candidate.fix.edits.map(({ path: _path, ...edit }) => edit) } : candidate.fix);\n }\n }\n }\n }\n if (cache.size === 32) cache.delete(cache.keys().next().value!);\n cache.set(line, candidates);\n return candidates;\n };\n}\n"],"mappings":"mbAaA,SAAgB,0BAA0B,EAAgB,EAAwD,CAC9G,IAAMA,EAAOC,EAAQ,MAAQ,mBACvBC,EAAY,IAAI,IAAID,EAAQ,WAAa,CAAC,CAACD,EAAMG,CAAM,CAAC,CAAC,EAC/D,GAAID,EAAU,IAAIF,CAAI,IAAMG,GAAWF,EAAQ,YAAc,IAAA,KAAcA,EAAQ,WAAW,QAAU,GAAK,EAAI,UAAa,CAAC,EAC/H,IAAMG,EAAWC,EAAmBH,CAAS,EAC7C,GAAI,CAACE,EAAS,SAAWA,EAAS,UAAU,KAAK,GAAYE,EAAS,sBAAwB,EAAK,EAAG,UAAa,CAAC,EACpH,IAAMC,EAAU,IAAIC,EAAwBN,EAAWE,CAAQ,EACzDK,kBAAQ,IAAI,IAClB,MAAO,IAAQ,CACX,GAAIA,EAAM,IAAIC,CAAI,EAAG,OAAOD,EAAM,IAAIC,CAAI,EAC1C,IAAMC,EAAWJ,EAAQ,SAAS,OAAO,GAAWK,EAAQ,WAAW,OAASC,EAAgB,qBAAuBD,EAAQ,WAAW,SAAS,OAASZ,GAAQY,EAAQ,WAAW,SAAS,OAASF,CAAI,EACvMI,EAAyB,CAAC,EAEhC,GAAIH,EAAS,SAAW,GAAK,CAACA,EAAS,EAAE,CAAC,cAAe,CACrD,IAAMC,EAAUD,EAAS,GACnBI,EAAWR,EAAQ,QAAQ,IAAIS,EAAiBJ,EAAQ,aAAa,CAAC,EACtEK,EAAWV,EAAQ,QAAQ,IAAIS,EAAiBJ,EAAQ,aAAa,CAAC,EAC5E,GAAIG,IAAa,IAAA,IAAaE,IAAa,IAAA,GAAW,CAClD,IAAIC,EAAS,EACb,KAAOA,EAASH,EAAS,QAAUG,EAASD,EAAS,QAAUE,EAAiBJ,EAASG,GAASD,EAASC,EAAO,GAAG,IACrH,IAAME,EAAOL,EAASG,GAASG,EAAQJ,EAASC,GAChD,GAAIE,IAAS,IAAA,IAAaC,IAAU,IAAA,IAAaD,EAAK,OAASC,EAAM,KAAM,CACvE,IAAMC,EAAUf,EAAQ,QAAQa,EAAK,IAAI,EACnCG,EAAQhB,EAAQ,MAAMa,EAAME,CAAO,EAAGE,EAASjB,EAAQ,MAAMc,EAAOC,CAAO,EACjF,GAAIC,IAAU,IAAA,IAAaC,IAAW,IAAA,IAAaD,EAAM,SAAWC,EAAO,QAAUD,EAAM,SAAWC,EAAO,OAAQ,CACjH,IAAIC,EACJ,GAAIF,EAAM,QAAUC,EAAO,MACvB,IAAK,IAAME,IAAS,CAAC,GAAO,EAAI,EAAG,CAC/B,IAAMC,EAAQD,EAAQH,EAAQC,EAAQI,EAASF,EAAQF,EAASD,EAC1DM,EAAYH,EAAQN,EAAOC,EAAOS,EAAaJ,EAAQL,EAAQD,EAC/DW,EAAQxB,EAAQ,KAAKA,EAAQ,MAAMsB,EAAWA,EAAU,KAAK,OAAS,kBAAkB,EAAGtB,EAAQ,MAAMuB,EAAYA,EAAW,KAAK,OAAS,kBAAkB,EAAGJ,CAAK,EAC9K,GAAIK,IAAU,IAAA,IAAa,CAACxB,EAAQ,KAAKwB,EAAOnB,CAAO,EAAG,SAC1D,IAAMoB,EAAW,CAAC,GAAIT,EAAM,OAA4DA,EAAM,OAAO,EACrGS,EAAS,OAAOL,EAAM,MAAO,CAAC,EAC9BK,EAAS,OAAOA,EAAS,QAAQJ,EAAO,IAAI,GAAK,KAAgB,EAAGD,EAAM,IAAI,EAC9E,IAAMM,EAAc,CAAE,GAAGV,EAAM,QAASA,EAAM,QAASS,CAAS,EAC1DE,EAAWhC,EAAU,IAAIkB,EAAK,IAAI,EAKxC,GAJA,EAAY,CAAE,OAAM,OAAQ,CAAE,KAAMG,EAAM,OAAQ,aAAY,EAAG,IAAK,CAClE,eAAgBX,EAAQ,WAAW,KAAM,OAAM,MAAOA,EAAQ,UAAY,gDAAkD,8CAA+C,MAAO,aAClL,MAAO,CAAC,CAAE,KAAMQ,EAAK,KAAM,MAAO,EAAG,OAAQc,EAAS,OAAQ,KAAMC,EAAiBD,EAAUP,EAAM,KAAMC,EAAO,KAAMF,CAAK,CAAE,CAAC,CACpI,CAAE,EACEnB,EAAQ,OAAOkB,EAAWL,EAAK,KAAMW,EAAOnB,CAAO,EAAG,MAC1D,EAAY,IAAA,EAChB,CAEAa,IAAc,IAAA,IAAaL,EAAK,KAAK,OAAS,oBAAsBC,EAAM,KAAK,OAAS,qBAAoB,EAAYe,EAAkB7B,EAASK,EAASQ,EAAMC,EAAOE,EAAOC,CAAM,GACtLC,IAAc,IAAA,IAAWX,EAAW,KAAKb,EAAQ,YAAc,IAAA,GAAY,CAAE,GAAGwB,EAAU,IAAK,MAAOA,EAAU,IAAI,MAAM,KAAK,CAAE,KAAMY,EAAO,GAAGC,KAAWA,CAAI,CAAE,EAAIb,EAAU,GAAG,CAC3L,CACJ,CACJ,CACJ,CAGA,OAFIhB,EAAM,OAAS,IAAIA,EAAM,OAAOA,EAAM,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAM,EAC9DA,EAAM,IAAIC,EAAMI,CAAU,EACnBA,CACX,CACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import"../Parsing/ImportDiscovery.js";import"../ScreenplayCompiler.js";const e=/* @__PURE__ */ new WeakMap,authoredOrderKey=e=>JSON.stringify(e);function authoredOrderOf(t){return e.get(t)
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{samePlacement as e}from"./PlayPlacement.js";import{placementFrom as t}from"../Parsing/ImportDiscovery.js";import{matchesPlayPattern as n,normalizePlayPath as r,resolvePlayPattern as i}from"./PlayGlob.js";import{discoverImports as a,parseForAuthoring as o}from"../ScreenplayCompiler.js";const s=/* @__PURE__ */ new WeakMap,authoredOriginsOf=e=>s.get(e)??/* @__PURE__ */ new Map,sameAuthoredStep=(e,t)=>e.path===t.path&&e.node.kind===t.node.kind&&e.node.location.line===t.node.location.line&&e.node.location.column===t.node.location.column&&e.targetPath===t.targetPath,c=/* @__PURE__ */ new WeakMap,authoredOrderKey=e=>JSON.stringify(e);function authoredOrderOf(e){return c.get(e)??/* @__PURE__ */ new Map}function declarations(e){let t=[],feature=(e,n,r)=>{let i=[...n,e.name],a=e.isPlacement?r:[...r,e];t.push({scope:i,...e.location,implicit:e.isPlacement,isContainer:!0,chain:a}),e.features.forEach(e=>feature(e,i,a)),e.slices.forEach(e=>t.push({scope:[...i,e.name],...e.location,implicit:!1,isContainer:!1,chain:[...a,e]}))};return e.modules.forEach(e=>{let n=e.isPlacement?[]:[e];t.push({scope:[e.name],...e.location,implicit:e.isPlacement,isContainer:!0,chain:n}),e.features.forEach(t=>feature(t,[e.name],n))}),t}function containerOwners(e,t){let n=/* @__PURE__ */ new Map;for(let[r,i]of e){let e=r.split(`/`),a=e[e.length-1].slice(0,-5);for(let o of i.filter(e=>e.isContainer&&!e.implicit)){let i=o.scope.indexOf(a);if(!t.has(r)&&i===-1)continue;let s=t.has(r)?0:i+1,c=authoredOrderKey(o.scope),l=n.get(c);(l===void 0||s<l.priority||s===l.priority&&e.length<l.depth)&&n.set(c,{path:r,priority:s,depth:e.length})}}return new Map([...n].map(([e,t])=>[e,t.path]))}function recordAuthoredOrder(l,u,d,f,p,m){let h=new Map(d.map(e=>[e.path,e])),g=new Map(d.filter(e=>e.isPlacementResolved!==!1).map(e=>[e.path,declarations(p?.get(e.path)??o(e.source,e.path,e.placement,!1,void 0,f).value)])),_=containerOwners(g,new Set(u.map(r))),v=new Set([...g.values()].flat().filter(e=>!e.implicit).map(e=>authoredOrderKey(e.scope))),y=/* @__PURE__ */ new Map,b=/* @__PURE__ */ new Map,x=/* @__PURE__ */ new Set,visit=(r,o)=>{let s=h.get(r);s===void 0||s.isPlacementResolved===!1||x.has(r)||(x.add(r),[...(g.get(r)??[]).filter(e=>{let t=authoredOrderKey(e.scope);return(!e.implicit||!v.has(t))&&(!e.isContainer||!_.has(t)||_.get(t)===r)}).map(e=>({line:e.line,column:e.column,run:()=>{let t=authoredOrderKey(e.scope);y.has(t)||(y.set(t,y.size),b.set(t,[...o,...e.chain.map(e=>({path:r,node:e}))]))}})),...(m?.get(r)??a(s.source,r,f)).map(a=>({...a.fileImport.location,run:()=>{let c=t(a,s.placement);if(c===void 0)return;let l=i(r,a.fileImport.pattern),u=(g.get(r)??[]).filter(e=>e.isContainer&&!e.implicit&&e.scope.length<=c.length&&e.scope.every((e,t)=>c[t]===e)).sort((e,t)=>e.scope.length-t.scope.length).map(e=>e.chain.at(-1));[...h.keys()].filter(e=>e!==r&&n(l,e)).sort().forEach((t,n)=>{e(h.get(t).placement,c)&&visit(t,[...o,...[...new Set(u)].map(e=>({path:r,node:e})),{path:r,node:a.fileImport,targetPath:t,matchIndex:n}])})}}))].sort((e,t)=>e.line-t.line||e.column-t.column).forEach(e=>e.run()))};u.map(r).forEach(e=>{h.get(e)?.placement.length===0&&visit(e,[])}),c.set(l,y),s.set(l,b)}export{authoredOrderKey,authoredOrderOf,authoredOriginsOf,recordAuthoredOrder,sameAuthoredStep};
|
|
2
2
|
//# sourceMappingURL=AuthoredOrder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthoredOrder.js","names":["orders","scope","application"],"sources":["../../../../../../Compiler/Files/AuthoredOrder.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 { DiscoveredImport, placementFrom } from '../Parsing/ImportDiscovery';\nimport { discoverImports, parseForAuthoring } from '../ScreenplayCompiler';\nimport { ApplicationSyntax, FeatureSyntax } from '../Syntax/Structure';\nimport { PlacedPlayDocument } from './PlayDocumentSource';\nimport { matchesPlayPattern, normalizePlayPath, resolvePlayPattern } from './PlayGlob';\nimport { samePlacement } from './PlayPlacement';\nimport { AuthoredDeclaration } from './AuthoredDeclaration';\n\n// Presentation metadata never enters syntax JSON, semantic bytes or identity. Merging and diagnostics\n// still use the original document order; only a consumer explicitly requesting authored order sees it.\nconst orders = new WeakMap<ApplicationSyntax, ReadonlyMap<string, number>>();\nexport const authoredOrderKey = (scope: readonly string[]): string => JSON.stringify(scope);\n\nexport function authoredOrderOf(application: ApplicationSyntax): ReadonlyMap<string, number> {\n return orders.get(application) ?? new Map();\n}\n\n// A board may narrow an application without changing the order of its remaining declarations.\nexport function copyAuthoredOrder(original: ApplicationSyntax, narrowed: ApplicationSyntax): ApplicationSyntax {\n const order = orders.get(original);\n if (order !== undefined) orders.set(narrowed, order);\n return narrowed;\n}\n\nfunction declarations(application: ApplicationSyntax): AuthoredDeclaration[] {\n const found: AuthoredDeclaration[] = [];\n const feature = (syntax: FeatureSyntax, outer: readonly string[]) => {\n const scope = [...outer, syntax.name];\n found.push({ scope, ...syntax.location, implicit: syntax.isPlacement, isContainer: true });\n syntax.features.forEach(child => feature(child, scope));\n syntax.slices.forEach(slice => found.push({ scope: [...scope, slice.name], ...slice.location, implicit: false, isContainer: false }));\n };\n application.modules.forEach(module => {\n found.push({ scope: [module.name], ...module.location, implicit: module.isPlacement, isContainer: true });\n module.features.forEach(child => feature(child, [module.name]));\n });\n return found;\n}\n\n// A root's explicit declarations, or those in an enclosing container's own named file, define container\n// order before globbed slice files that merely restate the same containers. Prefer the outer named\n// composite, then the shallower path; absent one, the text walk keeps the first explicit occurrence.\nfunction containerOwners(own: ReadonlyMap<string, readonly AuthoredDeclaration[]>, roots: ReadonlySet<string>): ReadonlyMap<string, string> {\n const owners = new Map<string, { path: string; priority: number; depth: number }>();\n for (const [path, declarations] of own) {\n const segments = path.split('/');\n const name = segments[segments.length - 1].slice(0, -5);\n for (const declaration of declarations.filter(declaration => declaration.isContainer && !declaration.implicit)) {\n const ancestor = declaration.scope.indexOf(name);\n if (!roots.has(path) && ancestor === -1) continue;\n const priority = roots.has(path) ? 0 : ancestor + 1;\n const key = authoredOrderKey(declaration.scope);\n const current = owners.get(key);\n if (current === undefined || priority < current.priority || (priority === current.priority && segments.length < current.depth)) {\n owners.set(key, { path, priority, depth: segments.length });\n }\n }\n }\n return new Map([...owners].map(([key, owner]) => [key, owner.path]));\n}\n\n// Walk text, not the merged tree: placement stubs must not claim the position of a declaration that is\n// written elsewhere. Expand an import only if it contributes the file's settled (deepest) placement.\nexport function recordAuthoredOrder(application: ApplicationSyntax, roots: readonly string[], documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, parsed?: ReadonlyMap<string, ApplicationSyntax>, imports?: ReadonlyMap<string, readonly DiscoveredImport[]>): void {\n const files = new Map(documents.map(document => [document.path, document]));\n const own = new Map(documents.filter(document => document.isPlacementResolved !== false).map(document => [document.path, declarations(parsed?.get(document.path) ?? parseForAuthoring(document.source, document.path, document.placement, false, undefined, languages).value)]));\n const owners = containerOwners(own, new Set(roots.map(normalizePlayPath)));\n const explicit = new Set([...own.values()].flat().filter(declaration => !declaration.implicit).map(declaration => authoredOrderKey(declaration.scope)));\n const order = new Map<string, number>();\n const visited = new Set<string>();\n const visit = (path: string) => {\n const document = files.get(path);\n if (document === undefined || document.isPlacementResolved === false || visited.has(path)) return;\n visited.add(path);\n const entries = [\n ...(own.get(path) ?? []).filter(declaration => {\n const key = authoredOrderKey(declaration.scope);\n return (!declaration.implicit || !explicit.has(key)) && (!declaration.isContainer || !owners.has(key) || owners.get(key) === path);\n })\n .map(declaration => ({ line: declaration.line, column: declaration.column, run: () => {\n const key = authoredOrderKey(declaration.scope);\n if (!order.has(key)) order.set(key, order.size);\n } })),\n ...(imports?.get(path) ?? discoverImports(document.source, path, languages)).map(imported => ({\n ...imported.fileImport.location,\n run: () => {\n const placement = placementFrom(imported, document.placement);\n if (placement === undefined) return;\n const pattern = resolvePlayPattern(path, imported.fileImport.pattern);\n [...files.keys()].filter(target => target !== path && matchesPlayPattern(pattern, target)).sort().forEach(target => {\n if (samePlacement(files.get(target)!.placement, placement)) visit(target);\n });\n },\n })),\n ];\n entries.sort((left, right) => left.line - right.line || left.column - right.column).forEach(entry => entry.run());\n };\n roots.map(normalizePlayPath).forEach(path => {\n const document = files.get(path);\n // A broad root glob can discover a file before the import that actually places it.\n if (document?.placement.length === 0) visit(path);\n });\n orders.set(application, order);\n}\n"],"mappings":"4HAaA,MAAMA,kBAAS,IAAI,QACN,iBAAoB,GAAqC,KAAK,UAAUC,CAAK,EAE1F,SAAgB,gBAAgB,EAA6D,CACzF,OAAOD,EAAO,IAAIE,CAAW,mBAAK,IAAI,GAC1C"}
|
|
1
|
+
{"version":3,"file":"AuthoredOrder.js","names":["origins","application","left","right","orders","scope","found","outer","syntax","chain","ancestors","child","slice","module","owners","path","declarations","own","segments","name","declaration","ancestor","roots","priority","key","current","owner","files","documents","document","parsed","parseForAuthoring","languages","normalizePlayPath","explicit","order","trace","visited","imports","discoverImports","imported","placement","placementFrom","pattern","resolvePlayPattern","index","target","matchesPlayPattern","samePlacement","entry"],"sources":["../../../../../../Compiler/Files/AuthoredOrder.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 { DiscoveredImport, placementFrom } from '../Parsing/ImportDiscovery';\nimport { discoverImports, parseForAuthoring } from '../ScreenplayCompiler';\nimport { ApplicationSyntax, FeatureSyntax } from '../Syntax/Structure';\nimport { PlacedPlayDocument } from './PlayDocumentSource';\nimport { matchesPlayPattern, normalizePlayPath, resolvePlayPattern } from './PlayGlob';\nimport { samePlacement } from './PlayPlacement';\nimport { AuthoredDeclaration } from './AuthoredDeclaration';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\n\n/** A physical declaration or one particular file reached by an import. Presentation only. */\nexport interface AuthoredOrderStep {\n readonly path: string;\n readonly node: SyntaxNode;\n readonly targetPath?: string;\n readonly matchIndex?: number;\n}\n\nconst origins = new WeakMap<ApplicationSyntax, ReadonlyMap<string, readonly AuthoredOrderStep[]>>();\nexport const authoredOriginsOf = (application: ApplicationSyntax): ReadonlyMap<string, readonly AuthoredOrderStep[]> => origins.get(application) ?? new Map();\nexport const sameAuthoredStep = (left: AuthoredOrderStep, right: AuthoredOrderStep): boolean => left.path === right.path && left.node.kind === right.node.kind &&\n left.node.location.line === right.node.location.line && left.node.location.column === right.node.location.column && left.targetPath === right.targetPath;\n\n// Presentation metadata never enters syntax JSON, semantic bytes or identity. Merging and diagnostics\n// still use the original document order; only a consumer explicitly requesting authored order sees it.\nconst orders = new WeakMap<ApplicationSyntax, ReadonlyMap<string, number>>();\nexport const authoredOrderKey = (scope: readonly string[]): string => JSON.stringify(scope);\n\nexport function authoredOrderOf(application: ApplicationSyntax): ReadonlyMap<string, number> {\n return orders.get(application) ?? new Map();\n}\n\n// A board may narrow an application without changing the order of its remaining declarations.\nexport function copyAuthoredOrder(original: ApplicationSyntax, narrowed: ApplicationSyntax): ApplicationSyntax {\n const order = orders.get(original);\n if (order !== undefined) orders.set(narrowed, order);\n return narrowed;\n}\n\nfunction declarations(application: ApplicationSyntax): (AuthoredDeclaration & { chain: readonly SyntaxNode[] })[] {\n const found: (AuthoredDeclaration & { chain: readonly SyntaxNode[] })[] = [];\n const feature = (syntax: FeatureSyntax, outer: readonly string[], ancestors: readonly SyntaxNode[]) => {\n const scope = [...outer, syntax.name];\n const chain = syntax.isPlacement ? ancestors : [...ancestors, syntax];\n found.push({ scope, ...syntax.location, implicit: syntax.isPlacement, isContainer: true, chain });\n syntax.features.forEach(child => feature(child, scope, chain));\n syntax.slices.forEach(slice => found.push({ scope: [...scope, slice.name], ...slice.location, implicit: false, isContainer: false, chain: [...chain, slice] }));\n };\n application.modules.forEach(module => {\n const chain = module.isPlacement ? [] : [module];\n found.push({ scope: [module.name], ...module.location, implicit: module.isPlacement, isContainer: true, chain });\n module.features.forEach(child => feature(child, [module.name], chain));\n });\n return found;\n}\n\n// A root's explicit declarations, or those in an enclosing container's own named file, define container\n// order before globbed slice files that merely restate the same containers. Prefer the outer named\n// composite, then the shallower path; absent one, the text walk keeps the first explicit occurrence.\nfunction containerOwners(own: ReadonlyMap<string, readonly AuthoredDeclaration[]>, roots: ReadonlySet<string>): ReadonlyMap<string, string> {\n const owners = new Map<string, { path: string; priority: number; depth: number }>();\n for (const [path, declarations] of own) {\n const segments = path.split('/');\n const name = segments[segments.length - 1].slice(0, -5);\n for (const declaration of declarations.filter(declaration => declaration.isContainer && !declaration.implicit)) {\n const ancestor = declaration.scope.indexOf(name);\n if (!roots.has(path) && ancestor === -1) continue;\n const priority = roots.has(path) ? 0 : ancestor + 1;\n const key = authoredOrderKey(declaration.scope);\n const current = owners.get(key);\n if (current === undefined || priority < current.priority || (priority === current.priority && segments.length < current.depth)) {\n owners.set(key, { path, priority, depth: segments.length });\n }\n }\n }\n return new Map([...owners].map(([key, owner]) => [key, owner.path]));\n}\n\n// Walk text, not the merged tree: placement stubs must not claim the position of a declaration that is\n// written elsewhere. Expand an import only if it contributes the file's settled (deepest) placement.\nexport function recordAuthoredOrder(application: ApplicationSyntax, roots: readonly string[], documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, parsed?: ReadonlyMap<string, ApplicationSyntax>, imports?: ReadonlyMap<string, readonly DiscoveredImport[]>): void {\n const files = new Map(documents.map(document => [document.path, document]));\n const own = new Map(documents.filter(document => document.isPlacementResolved !== false).map(document => [document.path, declarations(parsed?.get(document.path) ?? parseForAuthoring(document.source, document.path, document.placement, false, undefined, languages).value)]));\n const owners = containerOwners(own, new Set(roots.map(normalizePlayPath)));\n const explicit = new Set([...own.values()].flat().filter(declaration => !declaration.implicit).map(declaration => authoredOrderKey(declaration.scope)));\n const order = new Map<string, number>();\n const trace = new Map<string, readonly AuthoredOrderStep[]>();\n const visited = new Set<string>();\n const visit = (path: string, outer: readonly AuthoredOrderStep[]) => {\n const document = files.get(path);\n if (document === undefined || document.isPlacementResolved === false || visited.has(path)) return;\n visited.add(path);\n const entries = [\n ...(own.get(path) ?? []).filter(declaration => {\n const key = authoredOrderKey(declaration.scope);\n return (!declaration.implicit || !explicit.has(key)) && (!declaration.isContainer || !owners.has(key) || owners.get(key) === path);\n })\n .map(declaration => ({ line: declaration.line, column: declaration.column, run: () => {\n const key = authoredOrderKey(declaration.scope);\n if (!order.has(key)) {\n order.set(key, order.size);\n trace.set(key, [...outer, ...declaration.chain.map(node => ({ path, node }))]);\n }\n } })),\n ...(imports?.get(path) ?? discoverImports(document.source, path, languages)).map(imported => ({\n ...imported.fileImport.location,\n run: () => {\n const placement = placementFrom(imported, document.placement);\n if (placement === undefined) return;\n const pattern = resolvePlayPattern(path, imported.fileImport.pattern);\n const ancestors = (own.get(path) ?? []).filter(declaration => declaration.isContainer && !declaration.implicit &&\n declaration.scope.length <= placement.length && declaration.scope.every((name, index) => placement[index] === name))\n .sort((left, right) => left.scope.length - right.scope.length).map(declaration => declaration.chain.at(-1)!);\n [...files.keys()].filter(target => target !== path && matchesPlayPattern(pattern, target)).sort().forEach((target, matchIndex) => {\n if (samePlacement(files.get(target)!.placement, placement)) visit(target, [...outer, ...[...new Set(ancestors)].map(node => ({ path, node })), { path, node: imported.fileImport, targetPath: target, matchIndex }]);\n });\n },\n })),\n ];\n entries.sort((left, right) => left.line - right.line || left.column - right.column).forEach(entry => entry.run());\n };\n roots.map(normalizePlayPath).forEach(path => {\n const document = files.get(path);\n // A broad root glob can discover a file before the import that actually places it.\n if (document?.placement.length === 0) visit(path, []);\n });\n orders.set(application, order);\n origins.set(application, trace);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import"../ScreenplayCompiler.js";
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{matchesPlayPattern as e,normalizePlayPath as t,resolvePlayPattern as n}from"./PlayGlob.js";import{discoverImports as r}from"../ScreenplayCompiler.js";function selectOrderingRoot(i,a,o,s){let c=[...new Set(i.map(t))];if(c.length===1)return c[0];if(s??=new Map(a.map(e=>[e.path,r(e.source,e.path,o)])),(s.get(`application.play`)?.length??0)>0)return`application.play`;let l=/* @__PURE__ */ new Set;for(let[t,r]of s)for(let i of r){let r=n(t,i.fileImport.pattern);a.filter(n=>n.path!==t&&e(r,n.path)).forEach(e=>l.add(e.path))}let u=[...s].filter(([e,t])=>t.length>0&&!l.has(e)).map(([e])=>e);return u.length===1?u[0]:void 0}export{selectOrderingRoot};
|
|
2
|
+
//# sourceMappingURL=OrderingRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderingRoot.js","names":["normalized","roots","normalizePlayPath","documents","document","discoverImports","languages","imports","imported","path","entries","entry","pattern","resolvePlayPattern","matchesPlayPattern","candidates"],"sources":["../../../../../../Compiler/Files/OrderingRoot.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 { DiscoveredImport } from '../Parsing/ImportDiscovery';\nimport { discoverImports } from '../ScreenplayCompiler';\nimport { PlacedPlayDocument } from './PlayDocumentSource';\nimport { matchesPlayPattern, normalizePlayPath, resolvePlayPattern } from './PlayGlob';\n\n// Choosing presentation order never changes the roots used for resolving or merging documents.\nexport function selectOrderingRoot(roots: readonly string[], documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, imports?: ReadonlyMap<string, readonly DiscoveredImport[]>): string | undefined {\n const normalized = [...new Set(roots.map(normalizePlayPath))];\n if (normalized.length === 1) return normalized[0];\n imports ??= new Map(documents.map(document => [document.path, discoverImports(document.source, document.path, languages)]));\n if ((imports.get('application.play')?.length ?? 0) > 0) return 'application.play';\n const imported = new Set<string>();\n for (const [path, entries] of imports) {\n for (const entry of entries) {\n const pattern = resolvePlayPattern(path, entry.fileImport.pattern);\n documents.filter(document => document.path !== path && matchesPlayPattern(pattern, document.path)).forEach(document => imported.add(document.path));\n }\n }\n const candidates = [...imports].filter(([path, entries]) => entries.length > 0 && !imported.has(path)).map(([path]) => path);\n return candidates.length === 1 ? candidates[0] : undefined;\n}\n"],"mappings":"kNASA,SAAgB,mBAAmB,EAA0B,EAA0C,EAAiC,EAAgF,CACpN,IAAMA,EAAa,CAAC,GAAG,IAAI,IAAIC,EAAM,IAAIC,CAAiB,CAAC,CAAC,EAC5D,GAAIF,EAAW,SAAW,EAAG,OAAOA,EAAW,GAE/C,GADA,IAAY,IAAI,IAAIG,EAAU,IAAI,GAAY,CAACC,EAAS,KAAMC,EAAgBD,EAAS,OAAQA,EAAS,KAAME,CAAS,CAAC,CAAC,CAAC,GACrHC,EAAQ,IAAI,kBAAkB,CAAC,EAAE,QAAU,GAAK,EAAG,MAAO,mBAC/D,IAAMC,kBAAW,IAAI,IACrB,IAAK,GAAM,CAACC,EAAMC,KAAYH,EAC1B,IAAK,IAAMI,KAASD,EAAS,CACzB,IAAME,EAAUC,EAAmBJ,EAAME,EAAM,WAAW,OAAO,EACjER,EAAU,OAAO,GAAYC,EAAS,OAASK,GAAQK,EAAmBF,EAASR,EAAS,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAYI,EAAS,IAAIJ,EAAS,IAAI,CAAC,CACtJ,CAEJ,IAAMW,EAAa,CAAC,GAAGR,CAAO,CAAC,CAAC,QAAQ,CAACE,EAAMC,KAAaA,EAAQ,OAAS,GAAK,CAACF,EAAS,IAAIC,CAAI,CAAC,CAAC,CAAC,KAAK,CAACA,KAAUA,CAAI,EAC3H,OAAOM,EAAW,SAAW,EAAIA,EAAW,GAAK,IAAA,EACrD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{splitLines as e}from"../Parsing/SourceLineSplitter.js";import{effectiveStructuralInteractions as t}from"../Parsing/StructuralInteractionSites.js";import{expandSpecificationExamples as n,validateSpecificationExampleTypes as r}from"../Parsing/SpecificationCommandExamples.js";import{validateResponses as i}from"../Parsing/ResponseValidator.js";import{validateSpecificationCases as a}from"../Parsing/SpecificationCaseValidator.js";import{productionDestinationDiagnostics as o}from"../Diagnostics/ProductionDestinationDiagnostics.js";import{validateConstraintProperties as s}from"../Parsing/ConstraintPropertyValidator.js";import{validateDependencyDeclarations as c}from"../Dependencies/DeclaredDependencyTargets.js";import{LineReader as l}from"../Parsing/LineReader.js";import{ParserContext as u}from"../Parsing/ParserContext.js";import"./AuthoredOrder.js";import{DeclaredDependencies as
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{splitLines as e}from"../Parsing/SourceLineSplitter.js";import{effectiveStructuralInteractions as t}from"../Parsing/StructuralInteractionSites.js";import{expandSpecificationExamples as n,validateSpecificationExampleTypes as r}from"../Parsing/SpecificationCommandExamples.js";import{validateResponses as i}from"../Parsing/ResponseValidator.js";import{validateSpecificationCases as a}from"../Parsing/SpecificationCaseValidator.js";import{productionDestinationDiagnostics as o}from"../Diagnostics/ProductionDestinationDiagnostics.js";import{validateConstraintProperties as s}from"../Parsing/ConstraintPropertyValidator.js";import{validateDependencyDeclarations as c}from"../Dependencies/DeclaredDependencyTargets.js";import{LineReader as l}from"../Parsing/LineReader.js";import{ParserContext as u}from"../Parsing/ParserContext.js";import{normalizePlayPath as d}from"./PlayGlob.js";import{recordAuthoredOrder as f}from"./AuthoredOrder.js";import{DeclaredDependencies as p}from"../Dependencies/DeclaredDependencies.js";import{validatePublicEventUsage as m}from"../Parsing/PublicEventUsageValidator.js";import{validateInlineEvents as h}from"../Parsing/InlineEventValidator.js";import{validateOperations as g}from"../Parsing/OperationValidator.js";import{CommandStreamCandidates as _}from"../Parsing/CommandStreamCandidates.js";import{validateEventSources as v}from"../Parsing/EventSourceValidator.js";import{validateProjectionTargets as y}from"../Parsing/ProjectionTargetValidator.js";import{validateIdentifierCompliance as b}from"../Parsing/IdentifierComplianceValidator.js";import{validateEventSubjects as x}from"../Parsing/EventSubjectValidator.js";import{validateReadModelKeys as S}from"../Parsing/ReadModelKeyValidator.js";import{validateReactionRefusals as C}from"../Parsing/ReactionRefusalValidator.js";import{validateSpecificationRedelivery as w}from"../Parsing/SpecificationRedeliveryValidator.js";import{validateGuardedActions as T}from"../Parsing/GuardedActionValidator.js";import{validatePersonaCallers as E}from"../Parsing/PersonaCallerValidator.js";import{validatePurposes as D}from"../Parsing/PurposeValidator.js";import{timelineOrderDiagnostics as O}from"./TimelineOrder.js";import{discoverImports as k,parseForAuthoring as A}from"../ScreenplayCompiler.js";import{EventSourceReadConfidence as j}from"../Syntax/EventSourceReadConfidence.js";import{mergeDocuments as M}from"./PlayFolderMerge.js";import{inMemoryDocumentSource as N}from"./PlayDocumentSource.js";import{resolveImports as P}from"./PlayImports.js";import{selectOrderingRoot as F}from"./OrderingRoot.js";function assembleApplication(e,t,n,r){let i=[...e],{documents:a,diagnostics:o}=P(i,t,n),{result:s,syntax:c}=parsePlacedDocumentsWithSyntax(a,n),l=new Map(a.map(e=>[e.path,k(e.source,e.path,n)])),u=r===null?void 0:F(r===void 0?i:[r],a,n,l);u!==void 0&&f(s.value,[u],a,n,c,l);let d=u===void 0?[]:O(s.value),p=[...o,...s.diagnostics,...d];return{...s,documents:a,diagnostics:p,success:!p.some(e=>e.severity===`error`)}}function parsePlacedDocuments(e,t,n=!1){return parsePlacedDocumentsWithSyntax(e,t,n).result}function parsePlacedDocumentsWithSyntax(d,f,O=!1){let k=_.capturePlaced(d.filter(e=>e.isPlacementResolved!==!1).map(t=>({lines:e(t.source,!1,t.path),placement:t.placement})),f),N=d.map(e=>A(e.source,e.path,e.isPlacementResolved===!1?[]:e.placement,!1,k,f)),P=N.flatMap((e,t)=>(e.value.eventSources??[]).map(e=>({source:e,placementResolved:d[t].isPlacementResolved!==!1}))),F=d.every(e=>e.isPlacementResolved!==!1)&&N.every(e=>!j.hasUnknownExtent(e.diagnostics)),I=N.map((e,t)=>d[t].isPlacementResolved===!1?{...e,value:{...e.value,eventSources:[]}}:e),L=M(I),R=new u(new l([]),void 0,f);L.value.sourceOptions!==void 0&&(R.sourceOptions=L.value.sourceOptions),R.guardedInteractions.push(...I.flatMap(e=>e.guardedInteractions)),R.interactionBehaviors.push(...I.flatMap(e=>e.interactionBehaviors)),R.interactionUses.push(...t(L.value).filter(e=>`behavior`in e),...I.flatMap(e=>e.interactionUses).filter(e=>e.ancestors.some(e=>e.keyword===`screen`))),R.continuationValues.push(...I.flatMap(e=>e.continuationValues)),a(L.value,R),r(L.value,R,O);let z=n(L.value);v(L.value,R),g(L.value,R),m(L.value,R),h(L.value,R),s(L.value,R),i(z,R,I.flatMap(e=>e.inputUses)),y(L.value,R),b(z,R),x(L.value,R),S(L.value,R),C(L.value,R),w(L.value,R),T(L.value,R),E(L.value,R),D(L.value,R);let B=c(L.value,R);p.validate(B,R);for(let e of o(B))R.information(e.code,e.message,e.location);let V=L.diagnostics,H=new Set(V.map(diagnosticKey)),U=[...V,...R.diagnostics.filter(e=>!H.has(diagnosticKey(e)))];return{result:{...L,value:B,diagnostics:U,success:!U.some(e=>e.severity===`error`),physicalEventSources:P,sourceInventoryComplete:F,continuationValues:R.continuationValues},syntax:new Map(I.map((e,t)=>[d[t].path,e.value]))}}function diagnosticKey(e){return JSON.stringify([e.code,e.location.path,e.location.line,e.location.column])}function compileApplication(e,t,n,r){let i=new Map([...e].map(([e,t])=>[d(e),t]));return assembleApplication(t??[...i.keys()].sort(),N(i),n,r)}export{assembleApplication,compileApplication,parsePlacedDocuments};
|
|
2
2
|
//# sourceMappingURL=PlayApplicationAssembly.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayApplicationAssembly.js","names":["documents","languages","deferImportedExampleTypes","candidates","CommandStreamCandidates","document","splitLines","physical","parseForAuthoring","physicalEventSources","result","index","sourceInventoryComplete","EventSourceReadConfidence","parsed","merged","mergeDocuments","context","ParserContext","LineReader","effectiveStructuralInteractions","site","ancestor","validateSpecificationCases","validateSpecificationExampleTypes","effective","expandSpecificationExamples","validateEventSources","validateOperations","validatePublicEventUsage","validateInlineEvents","validateConstraintProperties","validateResponses","validateProjectionTargets","validateIdentifierCompliance","validateEventSubjects","validateReadModelKeys","validateReactionRefusals","validateSpecificationRedelivery","validateGuardedActions","validatePersonaCallers","validatePurposes","value","validateDependencyDeclarations","DeclaredDependencies","diagnostic","productionDestinationDiagnostics","existing","reported","all"],"sources":["../../../../../../Compiler/Files/PlayApplicationAssembly.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { validateSpecificationCases } from '../Parsing/SpecificationCaseValidator';\nimport { expandSpecificationExamples, validateSpecificationExampleTypes } from '../Parsing/SpecificationCommandExamples';\nimport { productionDestinationDiagnostics } from '../Diagnostics/ProductionDestinationDiagnostics';\nimport { validateConstraintProperties } from '../Parsing/ConstraintPropertyValidator';\nimport { validateDependencyDeclarations } from '../Dependencies/DeclaredDependencyTargets';\nimport { DeclaredDependencies } from '../Dependencies/DeclaredDependencies';\nimport { validateInlineEvents } from '../Parsing/InlineEventValidator';\nimport { LineReader } from '../Parsing/LineReader';\nimport { CommandStreamCandidates } from '../Parsing/CommandStreamCandidates';\nimport { validateEventSources } from '../Parsing/EventSourceValidator';\nimport { validateProjectionTargets } from '../Parsing/ProjectionTargetValidator';\nimport { validateIdentifierCompliance } from '../Parsing/IdentifierComplianceValidator';\nimport { validateEventSubjects } from '../Parsing/EventSubjectValidator';\nimport { validateReadModelKeys } from '../Parsing/ReadModelKeyValidator';\nimport { validateReactionRefusals } from '../Parsing/ReactionRefusalValidator';\nimport { validateSpecificationRedelivery } from '../Parsing/SpecificationRedeliveryValidator';\nimport { effectiveStructuralInteractions } from '../Parsing/StructuralInteractionSites';\nimport { validateGuardedActions } from '../Parsing/GuardedActionValidator';\nimport { validatePersonaCallers } from '../Parsing/PersonaCallerValidator';\nimport { validatePurposes } from '../Parsing/PurposeValidator';\nimport { splitLines } from '../Parsing/SourceLineSplitter';\nimport { ParserContext } from '../Parsing/ParserContext';\nimport { validateResponses } from '../Parsing/ResponseValidator';\nimport { validatePublicEventUsage } from '../Parsing/PublicEventUsageValidator';\nimport { validateOperations } from '../Parsing/OperationValidator';\nimport { CompilationResult, discoverImports, parseForAuthoring } from '../ScreenplayCompiler';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { EventSourceReadConfidence } from '../Syntax/EventSourceReadConfidence';\nimport { mergeDocuments } from './PlayFolderMerge';\nimport { inMemoryDocumentSource, PlacedPlayDocument, PlayDocumentSource } from './PlayDocumentSource';\nimport { normalizePlayPath } from './PlayGlob';\nimport { resolveImports } from './PlayImports';\nimport { recordAuthoredOrder } from './AuthoredOrder';\nimport { selectOrderingRoot } from './OrderingRoot';\nimport { timelineOrderDiagnostics } from './TimelineOrder';\n\n// One .play document of a folder: its path relative to the folder, and its text.\nexport interface PlayFileSource {\n readonly path: string;\n readonly source: string;\n}\n\n// One application compiled from documents: the documents that make it up, each with where its top level\n// belongs, and the merged syntax with every diagnostic - resolving, parsing and merging.\nexport interface ApplicationCompilation extends CompilationResult<ApplicationSyntax> {\n readonly documents: readonly PlacedPlayDocument[];\n}\n\n// Assembles one application from documents - following their imports from the roots, parsing each where it is\n// placed, and merging the lot. The port of the C# PlayApplicationAssembly.Compile.\nexport function assembleApplication(roots: Iterable<string>, source: PlayDocumentSource, languages?: ReadonlySet<string>, presentationRoot?: string | null): ApplicationCompilation {\n const rootPaths = [...roots];\n const { documents, diagnostics } = resolveImports(rootPaths, source, languages);\n const { result: merged, syntax } = parsePlacedDocumentsWithSyntax(documents, languages);\n // Resolution owns its import inventory; share one discovery between the presentation passes.\n const imports = new Map(documents.map(document => [document.path, discoverImports(document.source, document.path, languages)]));\n const orderingRoot = presentationRoot === null ? undefined : selectOrderingRoot(presentationRoot === undefined ? rootPaths : [presentationRoot], documents, languages, imports);\n if (orderingRoot !== undefined) recordAuthoredOrder(merged.value, [orderingRoot], documents, languages, syntax, imports);\n const timeline = orderingRoot === undefined ? [] : timelineOrderDiagnostics(merged.value);\n const all = [...diagnostics, ...merged.diagnostics, ...timeline];\n return { ...merged, documents, diagnostics: all, success: !all.some(diagnostic => diagnostic.severity === 'error') };\n}\n\n// Parses documents whose source identities and placements are already known (for example unsaved\n// editor buffers), then validates contracts against the merged declaration inventory. Editor callers may\n// defer example types whose imports are not in that inventory; resolved types are still checked.\nexport function parsePlacedDocuments(documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, deferImportedExampleTypes = false): CompilationResult<ApplicationSyntax> & {\n readonly physicalEventSources: readonly { source: EventSourceSyntax; placementResolved: boolean }[];\n readonly sourceInventoryComplete: boolean;\n readonly continuationValues: ReturnType<typeof parseForAuthoring>['continuationValues'];\n} {\n return parsePlacedDocumentsWithSyntax(documents, languages, deferImportedExampleTypes).result;\n}\n\nfunction parsePlacedDocumentsWithSyntax(documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, deferImportedExampleTypes = false) {\n const candidates = CommandStreamCandidates.capturePlaced(documents.filter(document => document.isPlacementResolved !== false).map(document => ({ lines: splitLines(document.source, false, document.path), placement: document.placement })), languages);\n const physical = documents.map(document => parseForAuthoring(document.source, document.path, document.isPlacementResolved === false ? [] : document.placement, false, candidates, languages));\n const physicalEventSources = physical.flatMap((result, index) => (result.value.eventSources ?? []).map(source => ({ source, placementResolved: documents[index].isPlacementResolved !== false })));\n const sourceInventoryComplete = documents.every(document => document.isPlacementResolved !== false) && physical.every(result => !EventSourceReadConfidence.hasUnknownExtent(result.diagnostics));\n const parsed = physical.map((result, index) => documents[index].isPlacementResolved === false ? { ...result, value: { ...result.value, eventSources: [] } } : result);\n const merged = mergeDocuments(parsed);\n const context = new ParserContext(new LineReader([]), undefined, languages);\n if (merged.value.sourceOptions !== undefined) context.sourceOptions = merged.value.sourceOptions;\n context.guardedInteractions.push(...parsed.flatMap(document => document.guardedInteractions));\n context.interactionBehaviors.push(...parsed.flatMap(document => document.interactionBehaviors));\n context.interactionUses.push(...effectiveStructuralInteractions(merged.value).filter(site => 'behavior' in site),\n ...parsed.flatMap(document => document.interactionUses).filter(site => site.ancestors.some(ancestor => ancestor.keyword === 'screen')));\n context.continuationValues.push(...parsed.flatMap(document => document.continuationValues));\n validateSpecificationCases(merged.value, context);\n validateSpecificationExampleTypes(merged.value, context, deferImportedExampleTypes);\n const effective = expandSpecificationExamples(merged.value);\n validateEventSources(merged.value, context);\n validateOperations(merged.value, context);\n validatePublicEventUsage(merged.value, context);\n validateInlineEvents(merged.value, context);\n validateConstraintProperties(merged.value, context);\n validateResponses(effective, context, parsed.flatMap(document => document.inputUses));\n validateProjectionTargets(merged.value, context);\n validateIdentifierCompliance(effective, context);\n validateEventSubjects(merged.value, context);\n validateReadModelKeys(merged.value, context);\n validateReactionRefusals(merged.value, context);\n validateSpecificationRedelivery(merged.value, context);\n validateGuardedActions(merged.value, context);\n validatePersonaCallers(merged.value, context);\n validatePurposes(merged.value, context);\n const value = validateDependencyDeclarations(merged.value, context);\n DeclaredDependencies.validate(value, context);\n for (const diagnostic of productionDestinationDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n const existing = merged.diagnostics;\n const reported = new Set(existing.map(diagnosticKey));\n const all = [...existing, ...context.diagnostics.filter(diagnostic => !reported.has(diagnosticKey(diagnostic)))];\n return {\n result: { ...merged, value, diagnostics: all, success: !all.some(diagnostic => diagnostic.severity === 'error'), physicalEventSources, sourceInventoryComplete, continuationValues: context.continuationValues },\n syntax: new Map(parsed.map((result, index) => [documents[index].path, result.value])),\n };\n}\n\nfunction diagnosticKey(diagnostic: Diagnostic): string {\n return JSON.stringify([diagnostic.code, diagnostic.location.path, diagnostic.location.line, diagnostic.location.column]);\n}\n\n// Compiles documents held in memory, keyed by portable path, as one application. Without roots every\n// document is a root, in ordinal order of its path - a folder compiled as one application, where a file an\n// import places in a module or feature is placed there. With roots, only those documents and what they import\n// make up the application - a single file compiled with its imports followed. The default sort compares\n// UTF-16 code units, which is the C# ordinal order.\nexport function compileApplication(documents: ReadonlyMap<string, string>, roots?: readonly string[], languages?: ReadonlySet<string>, presentationRoot?: string | null): ApplicationCompilation {\n const normalized = new Map([...documents].map(([path, source]) => [normalizePlayPath(path), source]));\n return assembleApplication(roots ?? [...normalized.keys()].sort(), inMemoryDocumentSource(normalized), languages, presentationRoot);\n}\n\n// Compiles the documents of a folder as one application - the counterpart of the C# CompileFolder. Every\n// document is a root, read in ordinal order of its relative path as the C# compiler reads them, so a merge\n// keeps the same first declaration in either language; one an import places in a module or feature is\n// placed there.\nexport function parseFolder(files: readonly PlayFileSource[], languages?: ReadonlySet<string>): ApplicationCompilation {\n return compileApplication(new Map(files.map(file => [file.path, file.source])), undefined, languages);\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlayApplicationAssembly.js","names":["rootPaths","roots","resolveImports","source","languages","merged","documents","imports","document","discoverImports","orderingRoot","presentationRoot","selectOrderingRoot","recordAuthoredOrder","syntax","timeline","timelineOrderDiagnostics","all","diagnostics","diagnostic","deferImportedExampleTypes","candidates","CommandStreamCandidates","splitLines","physical","parseForAuthoring","physicalEventSources","result","index","sourceInventoryComplete","EventSourceReadConfidence","parsed","mergeDocuments","context","ParserContext","LineReader","effectiveStructuralInteractions","site","ancestor","validateSpecificationCases","validateSpecificationExampleTypes","effective","expandSpecificationExamples","validateEventSources","validateOperations","validatePublicEventUsage","validateInlineEvents","validateConstraintProperties","validateResponses","validateProjectionTargets","validateIdentifierCompliance","validateEventSubjects","validateReadModelKeys","validateReactionRefusals","validateSpecificationRedelivery","validateGuardedActions","validatePersonaCallers","validatePurposes","value","validateDependencyDeclarations","DeclaredDependencies","productionDestinationDiagnostics","existing","reported","normalized","path","normalizePlayPath","inMemoryDocumentSource"],"sources":["../../../../../../Compiler/Files/PlayApplicationAssembly.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { validateSpecificationCases } from '../Parsing/SpecificationCaseValidator';\nimport { expandSpecificationExamples, validateSpecificationExampleTypes } from '../Parsing/SpecificationCommandExamples';\nimport { productionDestinationDiagnostics } from '../Diagnostics/ProductionDestinationDiagnostics';\nimport { validateConstraintProperties } from '../Parsing/ConstraintPropertyValidator';\nimport { validateDependencyDeclarations } from '../Dependencies/DeclaredDependencyTargets';\nimport { DeclaredDependencies } from '../Dependencies/DeclaredDependencies';\nimport { validateInlineEvents } from '../Parsing/InlineEventValidator';\nimport { LineReader } from '../Parsing/LineReader';\nimport { CommandStreamCandidates } from '../Parsing/CommandStreamCandidates';\nimport { validateEventSources } from '../Parsing/EventSourceValidator';\nimport { validateProjectionTargets } from '../Parsing/ProjectionTargetValidator';\nimport { validateIdentifierCompliance } from '../Parsing/IdentifierComplianceValidator';\nimport { validateEventSubjects } from '../Parsing/EventSubjectValidator';\nimport { validateReadModelKeys } from '../Parsing/ReadModelKeyValidator';\nimport { validateReactionRefusals } from '../Parsing/ReactionRefusalValidator';\nimport { validateSpecificationRedelivery } from '../Parsing/SpecificationRedeliveryValidator';\nimport { effectiveStructuralInteractions } from '../Parsing/StructuralInteractionSites';\nimport { validateGuardedActions } from '../Parsing/GuardedActionValidator';\nimport { validatePersonaCallers } from '../Parsing/PersonaCallerValidator';\nimport { validatePurposes } from '../Parsing/PurposeValidator';\nimport { splitLines } from '../Parsing/SourceLineSplitter';\nimport { ParserContext } from '../Parsing/ParserContext';\nimport { validateResponses } from '../Parsing/ResponseValidator';\nimport { validatePublicEventUsage } from '../Parsing/PublicEventUsageValidator';\nimport { validateOperations } from '../Parsing/OperationValidator';\nimport { CompilationResult, discoverImports, parseForAuthoring } from '../ScreenplayCompiler';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { EventSourceReadConfidence } from '../Syntax/EventSourceReadConfidence';\nimport { mergeDocuments } from './PlayFolderMerge';\nimport { inMemoryDocumentSource, PlacedPlayDocument, PlayDocumentSource } from './PlayDocumentSource';\nimport { normalizePlayPath } from './PlayGlob';\nimport { resolveImports } from './PlayImports';\nimport { recordAuthoredOrder } from './AuthoredOrder';\nimport { selectOrderingRoot } from './OrderingRoot';\nimport { timelineOrderDiagnostics } from './TimelineOrder';\n\n// One .play document of a folder: its path relative to the folder, and its text.\nexport interface PlayFileSource {\n readonly path: string;\n readonly source: string;\n}\n\n// One application compiled from documents: the documents that make it up, each with where its top level\n// belongs, and the merged syntax with every diagnostic - resolving, parsing and merging.\nexport interface ApplicationCompilation extends CompilationResult<ApplicationSyntax> {\n readonly documents: readonly PlacedPlayDocument[];\n}\n\n// Assembles one application from documents - following their imports from the roots, parsing each where it is\n// placed, and merging the lot. The port of the C# PlayApplicationAssembly.Compile.\nexport function assembleApplication(roots: Iterable<string>, source: PlayDocumentSource, languages?: ReadonlySet<string>, presentationRoot?: string | null): ApplicationCompilation {\n const rootPaths = [...roots];\n const { documents, diagnostics } = resolveImports(rootPaths, source, languages);\n const { result: merged, syntax } = parsePlacedDocumentsWithSyntax(documents, languages);\n // Resolution owns its import inventory; share one discovery between the presentation passes.\n const imports = new Map(documents.map(document => [document.path, discoverImports(document.source, document.path, languages)]));\n const orderingRoot = presentationRoot === null ? undefined : selectOrderingRoot(presentationRoot === undefined ? rootPaths : [presentationRoot], documents, languages, imports);\n if (orderingRoot !== undefined) recordAuthoredOrder(merged.value, [orderingRoot], documents, languages, syntax, imports);\n const timeline = orderingRoot === undefined ? [] : timelineOrderDiagnostics(merged.value);\n const all = [...diagnostics, ...merged.diagnostics, ...timeline];\n return { ...merged, documents, diagnostics: all, success: !all.some(diagnostic => diagnostic.severity === 'error') };\n}\n\n// Parses documents whose source identities and placements are already known (for example unsaved\n// editor buffers), then validates contracts against the merged declaration inventory. Editor callers may\n// defer example types whose imports are not in that inventory; resolved types are still checked.\nexport function parsePlacedDocuments(documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, deferImportedExampleTypes = false): CompilationResult<ApplicationSyntax> & {\n readonly physicalEventSources: readonly { source: EventSourceSyntax; placementResolved: boolean }[];\n readonly sourceInventoryComplete: boolean;\n readonly continuationValues: ReturnType<typeof parseForAuthoring>['continuationValues'];\n} {\n return parsePlacedDocumentsWithSyntax(documents, languages, deferImportedExampleTypes).result;\n}\n\nfunction parsePlacedDocumentsWithSyntax(documents: readonly PlacedPlayDocument[], languages?: ReadonlySet<string>, deferImportedExampleTypes = false) {\n const candidates = CommandStreamCandidates.capturePlaced(documents.filter(document => document.isPlacementResolved !== false).map(document => ({ lines: splitLines(document.source, false, document.path), placement: document.placement })), languages);\n const physical = documents.map(document => parseForAuthoring(document.source, document.path, document.isPlacementResolved === false ? [] : document.placement, false, candidates, languages));\n const physicalEventSources = physical.flatMap((result, index) => (result.value.eventSources ?? []).map(source => ({ source, placementResolved: documents[index].isPlacementResolved !== false })));\n const sourceInventoryComplete = documents.every(document => document.isPlacementResolved !== false) && physical.every(result => !EventSourceReadConfidence.hasUnknownExtent(result.diagnostics));\n const parsed = physical.map((result, index) => documents[index].isPlacementResolved === false ? { ...result, value: { ...result.value, eventSources: [] } } : result);\n const merged = mergeDocuments(parsed);\n const context = new ParserContext(new LineReader([]), undefined, languages);\n if (merged.value.sourceOptions !== undefined) context.sourceOptions = merged.value.sourceOptions;\n context.guardedInteractions.push(...parsed.flatMap(document => document.guardedInteractions));\n context.interactionBehaviors.push(...parsed.flatMap(document => document.interactionBehaviors));\n context.interactionUses.push(...effectiveStructuralInteractions(merged.value).filter(site => 'behavior' in site),\n ...parsed.flatMap(document => document.interactionUses).filter(site => site.ancestors.some(ancestor => ancestor.keyword === 'screen')));\n context.continuationValues.push(...parsed.flatMap(document => document.continuationValues));\n validateSpecificationCases(merged.value, context);\n validateSpecificationExampleTypes(merged.value, context, deferImportedExampleTypes);\n const effective = expandSpecificationExamples(merged.value);\n validateEventSources(merged.value, context);\n validateOperations(merged.value, context);\n validatePublicEventUsage(merged.value, context);\n validateInlineEvents(merged.value, context);\n validateConstraintProperties(merged.value, context);\n validateResponses(effective, context, parsed.flatMap(document => document.inputUses));\n validateProjectionTargets(merged.value, context);\n validateIdentifierCompliance(effective, context);\n validateEventSubjects(merged.value, context);\n validateReadModelKeys(merged.value, context);\n validateReactionRefusals(merged.value, context);\n validateSpecificationRedelivery(merged.value, context);\n validateGuardedActions(merged.value, context);\n validatePersonaCallers(merged.value, context);\n validatePurposes(merged.value, context);\n const value = validateDependencyDeclarations(merged.value, context);\n DeclaredDependencies.validate(value, context);\n for (const diagnostic of productionDestinationDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n const existing = merged.diagnostics;\n const reported = new Set(existing.map(diagnosticKey));\n const all = [...existing, ...context.diagnostics.filter(diagnostic => !reported.has(diagnosticKey(diagnostic)))];\n return {\n result: { ...merged, value, diagnostics: all, success: !all.some(diagnostic => diagnostic.severity === 'error'), physicalEventSources, sourceInventoryComplete, continuationValues: context.continuationValues },\n syntax: new Map(parsed.map((result, index) => [documents[index].path, result.value])),\n };\n}\n\nfunction diagnosticKey(diagnostic: Diagnostic): string {\n return JSON.stringify([diagnostic.code, diagnostic.location.path, diagnostic.location.line, diagnostic.location.column]);\n}\n\n// Compiles documents held in memory, keyed by portable path, as one application. Without roots every\n// document is a root, in ordinal order of its path - a folder compiled as one application, where a file an\n// import places in a module or feature is placed there. With roots, only those documents and what they import\n// make up the application - a single file compiled with its imports followed. The default sort compares\n// UTF-16 code units, which is the C# ordinal order.\nexport function compileApplication(documents: ReadonlyMap<string, string>, roots?: readonly string[], languages?: ReadonlySet<string>, presentationRoot?: string | null): ApplicationCompilation {\n const normalized = new Map([...documents].map(([path, source]) => [normalizePlayPath(path), source]));\n return assembleApplication(roots ?? [...normalized.keys()].sort(), inMemoryDocumentSource(normalized), languages, presentationRoot);\n}\n\n// Compiles the documents of a folder as one application - the counterpart of the C# CompileFolder. Every\n// document is a root, read in ordinal order of its relative path as the C# compiler reads them, so a merge\n// keeps the same first declaration in either language; one an import places in a module or feature is\n// placed there.\nexport function parseFolder(files: readonly PlayFileSource[], languages?: ReadonlySet<string>): ApplicationCompilation {\n return compileApplication(new Map(files.map(file => [file.path, file.source])), undefined, languages);\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";function inMemoryDocumentSource(e){return{filesBeneath:t=>[...e.keys()].filter(e=>t.length===0||e.startsWith(`${t}/`)),read:t=>{let n=e.get(t);if(n===void 0)throw Error(`There is no document '${t}'`);return n}}}export{inMemoryDocumentSource};
|
|
2
|
+
//# sourceMappingURL=PlayDocumentSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayDocumentSource.js","names":["documents","folder","path","source"],"sources":["../../../../../../Compiler/Files/PlayDocumentSource.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 { PlayPlacement } from './PlayPlacement';\n\n// Where the documents an import names come from - a folder on disk, or the documents of a workspace. Every\n// path is portable: '/' separated and relative to one root. A path may begin with '..' when an import climbs\n// above that root. The port of the C# IPlayDocumentSource.\nexport interface PlayDocumentSource {\n // Every .play file beneath a portable folder path, at any depth - the empty folder is the root.\n filesBeneath(folder: string): Iterable<string>;\n\n // The source text of a document.\n read(path: string): string;\n}\n\n// A document of an application together with where its top level belongs.\nexport interface PlacedPlayDocument {\n readonly path: string;\n readonly source: string;\n readonly placement: PlayPlacement;\n // False for conflicting/cyclic placement and every descendant of such an importer.\n readonly isPlacementResolved?: boolean;\n}\n\n// A document source over documents held in memory, keyed by portable path.\nexport function inMemoryDocumentSource(documents: ReadonlyMap<string, string>): PlayDocumentSource {\n return {\n filesBeneath: folder => [...documents.keys()].filter(path => folder.length === 0 || path.startsWith(`${folder}/`)),\n read: path => {\n const source = documents.get(path);\n if (source === undefined) {\n throw new Error(`There is no document '${path}'`);\n }\n return source;\n },\n };\n}\n"],"mappings":"qDA0BA,SAAgB,uBAAuB,EAA4D,CAC/F,MAAO,CACH,aAAc,GAAU,CAAC,GAAGA,EAAU,KAAK,CAAC,CAAC,CAAC,OAAO,GAAQC,EAAO,SAAW,GAAKC,EAAK,WAAW,GAAGD,EAAO,EAAE,CAAC,EACjH,KAAM,GAAQ,CACV,IAAME,EAASH,EAAU,IAAIE,CAAI,EACjC,GAAIC,IAAW,IAAA,GACX,MAAU,MAAM,yBAAyBD,EAAK,EAAE,EAEpD,OAAOC,CACX,CACJ,CACJ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";const hasWildcard=e=>e.includes(`*`)||e.includes(`?`);function normalizePlayPath(e){let t=[];for(let n of e.replaceAll(`\\`,`/`).split(`/`).filter(e=>e.length>0))n!==`.`&&(n===`..`&&t.length>0&&t[t.length-1]!==`..`?t.pop():t.push(n));return t.join(`/`)}function resolvePlayPattern(e,t){let n=e.lastIndexOf(`/`),r=n>=0?e.substring(0,n):``;return normalizePlayPath(t.startsWith(`/`)?t.replace(/^\/+/,``):r.length===0?t:`${r}/${t}`)}function staticFolderOf(e){let t=e.split(`/`).slice(0,-1),n=t.findIndex(hasWildcard);return(n<0?t:t.slice(0,n)).join(`/`)}function matchesPlayPattern(e,t){return t.toLowerCase().endsWith(`.play`)&&toRegularExpression(e).test(t)}function toRegularExpression(e){let t=`^`,n=e.split(`/`);return n.forEach((e,r)=>{let i=r===n.length-1;if(e===`**`)t+=i?`.*`:`(?:[^/]+/)*`;else{for(let n of e)t+=n===`*`?`[^/]*`:n===`?`?`[^/]`:n.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);i||(t+=`/`)}}),RegExp(`${t}$`,`u`)}export{hasWildcard,matchesPlayPattern,normalizePlayPath,resolvePlayPattern,staticFolderOf};
|
|
2
|
+
//# sourceMappingURL=PlayGlob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayGlob.js","names":["pattern","segments","segment","path","each","slash","importingPath","folder","resolvedPattern","wildcard","expression","last","index","character"],"sources":["../../../../../../Compiler/Files/PlayGlob.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\n// Matches the path or glob pattern of a file import against portable '/' separated paths - the port of the\n// C# PlayGlob, so a folder resolves the same way in an editor and in a build. '**' as a whole segment matches\n// any number of folders, including none; '*' matches any run of characters within one segment and '?' one\n// character. A pattern is relative to the folder of the file that imports, may climb with '..', and only ever\n// matches .play files.\n\n// Whether a pattern holds a wildcard, as opposed to naming one file.\nexport const hasWildcard = (pattern: string): boolean => pattern.includes('*') || pattern.includes('?');\n\n// Normalizes a portable path - separators to '/', '.' segments removed, '..' applied. Leading '..' segments\n// that climb above the root are kept.\nexport function normalizePlayPath(path: string): string {\n const segments: string[] = [];\n for (const segment of path.replaceAll('\\\\', '/').split('/').filter(each => each.length > 0)) {\n if (segment === '.') continue;\n if (segment === '..' && segments.length > 0 && segments[segments.length - 1] !== '..') {\n segments.pop();\n continue;\n }\n segments.push(segment);\n }\n return segments.join('/');\n}\n\n// Resolves a pattern written in a file against the folder that file is in, relative to the same root as the\n// importing path.\nexport function resolvePlayPattern(importingPath: string, pattern: string): string {\n const slash = importingPath.lastIndexOf('/');\n const folder = slash >= 0 ? importingPath.substring(0, slash) : '';\n const combined = pattern.startsWith('/') ? pattern.replace(/^\\/+/, '') : (folder.length === 0 ? pattern : `${folder}/${pattern}`);\n return normalizePlayPath(combined);\n}\n\n// The folder a resolved pattern can only match beneath - everything before its first wildcard segment.\nexport function staticFolderOf(resolvedPattern: string): string {\n const segments = resolvedPattern.split('/').slice(0, -1);\n const wildcard = segments.findIndex(hasWildcard);\n return (wildcard < 0 ? segments : segments.slice(0, wildcard)).join('/');\n}\n\n// Whether a normalized portable path is a .play file a resolved pattern names.\nexport function matchesPlayPattern(resolvedPattern: string, path: string): boolean {\n return path.toLowerCase().endsWith('.play') && toRegularExpression(resolvedPattern).test(path);\n}\n\nfunction toRegularExpression(pattern: string): RegExp {\n let expression = '^';\n const segments = pattern.split('/');\n segments.forEach((segment, index) => {\n const last = index === segments.length - 1;\n if (segment === '**') {\n expression += last ? '.*' : '(?:[^/]+/)*';\n return;\n }\n for (const character of segment) {\n expression += character === '*' ? '[^/]*' : character === '?' ? '[^/]' : character.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n if (!last) expression += '/';\n });\n return new RegExp(`${expression}$`, 'u');\n}\n"],"mappings":"qDAUA,MAAa,YAAe,GAA6BA,EAAQ,SAAS,GAAG,GAAKA,EAAQ,SAAS,GAAG,EAItG,SAAgB,kBAAkB,EAAsB,CACpD,IAAMC,EAAqB,CAAC,EAC5B,IAAK,IAAMC,KAAWC,EAAK,WAAW,KAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,GAAQC,EAAK,OAAS,CAAC,EAClFF,IAAY,MACZA,IAAY,MAAQD,EAAS,OAAS,GAAKA,EAASA,EAAS,OAAS,KAAO,KAC7EA,EAAS,IAAI,EAGjBA,EAAS,KAAKC,CAAO,GAEzB,OAAOD,EAAS,KAAK,GAAG,CAC5B,CAIA,SAAgB,mBAAmB,EAAuB,EAAyB,CAC/E,IAAMI,EAAQC,EAAc,YAAY,GAAG,EACrCC,EAASF,GAAS,EAAIC,EAAc,UAAU,EAAGD,CAAK,EAAI,GAEhE,OAAO,kBADUL,EAAQ,WAAW,GAAG,EAAIA,EAAQ,QAAQ,OAAQ,EAAE,EAAKO,EAAO,SAAW,EAAIP,EAAU,GAAGO,EAAO,GAAGP,GACtF,CACrC,CAGA,SAAgB,eAAe,EAAiC,CAC5D,IAAMC,EAAWO,EAAgB,MAAM,GAAG,CAAC,CAAC,MAAM,EAAG,EAAE,EACjDC,EAAWR,EAAS,UAAU,WAAW,EAC/C,OAAQQ,EAAW,EAAIR,EAAWA,EAAS,MAAM,EAAGQ,CAAQ,EAAA,CAAG,KAAK,GAAG,CAC3E,CAGA,SAAgB,mBAAmB,EAAyB,EAAuB,CAC/E,OAAON,EAAK,YAAY,CAAC,CAAC,SAAS,OAAO,GAAK,oBAAoBK,CAAe,CAAC,CAAC,KAAKL,CAAI,CACjG,CAEA,SAAS,oBAAoB,EAAyB,CAClD,IAAIO,EAAa,IACXT,EAAWD,EAAQ,MAAM,GAAG,EAYlC,OAXAC,EAAS,SAAS,EAAS,IAAU,CACjC,IAAMU,EAAOC,IAAUX,EAAS,OAAS,EACzC,GAAIC,IAAY,KACZ,GAAcS,EAAO,KAAO,kBAGhC,KAAK,IAAME,KAAaX,EACpB,GAAcW,IAAc,IAAM,QAAUA,IAAc,IAAM,OAASA,EAAU,QAAQ,sBAAuB,MAAM,EAEvHF,IAAM,GAAc,IAFmG,CAGhI,CAAC,EACU,OAAO,GAAGD,EAAW,GAAI,GAAG,CAC3C"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import"../Parsing/ImportDiscovery.js";import"../ScreenplayCompiler.js";
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{describePlacement as t,documentPlacement as n,isWithinOrSame as r,samePlacement as i}from"./PlayPlacement.js";import{placementFrom as a}from"../Parsing/ImportDiscovery.js";import{hasWildcard as o,matchesPlayPattern as s,normalizePlayPath as c,resolvePlayPattern as l,staticFolderOf as u}from"./PlayGlob.js";import{discoverImports as d}from"../ScreenplayCompiler.js";function resolveImports(e,t,n){let r=new Resolution(t,n);for(let t of new Set([...e].map(c)))r.addRoot(t);return r.settle(),{documents:r.documents(),diagnostics:r.diagnostics}}var Resolution=class{source;languages;diagnostics=[];#e=[];#t=/* @__PURE__ */ new Set;#n=/* @__PURE__ */ new Map;#r=/* @__PURE__ */ new Map;#i=/* @__PURE__ */ new Map;#a=/* @__PURE__ */ new Map;#o=[];#s=/* @__PURE__ */ new Map;#c=/* @__PURE__ */ new Set;constructor(e,t){this.source=e,this.languages=t}addRoot(e){this.#t.add(e),this.#u(e)}settle(){for(let e=this.#o.shift();e!==void 0;e=this.#o.shift())this.#f(e);this.#v();let e=[...this.#c];for(let t of e)for(let n of(this.#r.get(t)??[]).flatMap(e=>e.targets))this.#c.has(n)||(this.#c.add(n),e.push(n))}documents(){return this.#l().map(e=>({path:e,source:this.#n.get(e),placement:this.#h(e)??n,isPlacementResolved:!this.#c.has(e)}))}#l(){if(this.#t.size!==1)return[...this.#e];let e=/* @__PURE__ */ new Set,t=[];for(let n of this.#e){let r=[n];for(let n=r.pop();n!==void 0;n=r.pop())e.has(n)||(e.add(n),t.push(n),r.push(...(this.#r.get(n)??[]).flatMap(e=>e.targets).reverse()))}return t}#u(e){if(this.#n.has(e))return;this.#e.push(e);let t=this.source.read(e);this.#n.set(e,t),this.#r.set(e,d(t,e,this.languages).map(t=>({discovered:t,targets:this.#d(e,t)}))),this.#o.push(e)}#d(t,n){let{pattern:r,location:i}=n.fileImport,a=l(t,r),d=[...new Set([...this.source.filesBeneath(u(a))].map(c).filter(e=>e!==t&&s(a,e)))].sort();return d.length===0&&this.#y(o(r)?{severity:`warning`,code:e.FileImportMatchesNothing,message:`Import '${r}' matches no .play file`,location:i}:error(e.ImportedFileNotFound,`Imported file '${r}' does not exist`,i)),d}#f(t){let n=this.#h(t);this.#r.get(t).forEach(({discovered:r,targets:i},o)=>{let s=n===void 0?void 0:a(r,n);s!==void 0&&s.length>32&&(this.#y(error(e.ImportCycle,`Import '${r.fileImport.pattern}' places files deeper than 32 levels - the imports form a cycle`,r.fileImport.location)),this.#c.add(t),s=void 0);for(let e of i)this.#u(e),this.#p(e,t,o,s)})}#p(e,t,n,r){let a=this.#i.get(e)??/* @__PURE__ */ new Map;this.#i.set(e,a);let o=JSON.stringify([t,n]),s=a.get(o),c=r===void 0?a.delete(o):s===void 0||!i(s.placement,r);r!==void 0&&a.set(o,{importer:t,index:n,placement:r}),c&&this.#m(e)}#m(t){let n=this.#g(t),r=this.#a.get(t);if(!(r===void 0?n!==void 0:n===void 0||!i(r,n)))return;let a=(this.#s.get(t)??0)+1;if(this.#s.set(t,a),a>32){this.#c.add(t);for(let{discovered:{fileImport:n}}of this.#r.get(t))this.#y(error(e.ImportCycle,`Import '${n.pattern}' is part of imports that keep placing each other - the imports form a cycle`,n.location))}else n===void 0?this.#a.delete(t):this.#a.set(t,n),this.#o.push(t)}#h(e){return this.#a.get(e)??this.#g(e)}#g(e){return[...this.#t.has(e)?[n]:[],...this.#_(e).map(e=>e.placement)].reduce((e,t)=>e===void 0||r(t,e)?t:e,void 0)}#_(e){return[...this.#i.get(e)?.values()??[]].sort((e,t)=>e.importer===t.importer?e.index-t.index:e.importer<t.importer?-1:1)}#v(){for(let n of this.#e){let i=this.#h(n);if(i!==void 0){for(let{importer:a,index:o,placement:s}of this.#_(n))if(!r(i,s)){this.#c.add(n);let{fileImport:r}=this.#r.get(a)[o].discovered;this.#y(error(e.ConflictingImportPlacement,`'${n}' is imported into both ${t(i)} and ${t(s)} - a file belongs in one place`,r.location))}}}}#y(e){let t=keyOf(e);this.diagnostics.some(e=>keyOf(e)===t)||this.diagnostics.push(e)}};const keyOf=e=>JSON.stringify([e.severity,e.code,e.message,e.location]),error=(e,t,n)=>({severity:`error`,code:e,message:t,location:n});export{resolveImports};
|
|
2
|
+
//# sourceMappingURL=PlayImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayImports.js","names":["resolution","source","languages","root","roots","normalizePlayPath","#roots","#find","file","#pending","#propagate","#reportConflicts","unresolved","#unresolved","importer","target","#imports","imported","#orderedPaths","#sources","path","#placement","documentPlacement","#found","seen","ordered","pending","text","discoverImports","#targets","discovered","resolved","resolvePlayPattern","pattern","matches","staticFolderOf","matchesPlayPattern","#report","hasWildcard","DiagnosticCodes","location","placement","placementFrom","targets","#contribute","index","contributions","#contributions","key","current","changed","samePlacement","#recompute","#deepest","#placements","changes","#changes","fileImport","#ordered","contribution","deepest","isWithinOrSame","candidate","left","right","describePlacement","diagnostic","other"],"sources":["../../../../../../Compiler/Files/PlayImports.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { DiscoveredImport, placementFrom } from '../Parsing/ImportDiscovery';\nimport { discoverImports } from '../ScreenplayCompiler';\nimport { PlacedPlayDocument, PlayDocumentSource } from './PlayDocumentSource';\nimport { hasWildcard, matchesPlayPattern, normalizePlayPath, resolvePlayPattern, staticFolderOf } from './PlayGlob';\nimport { describePlacement, documentPlacement, isWithinOrSame, PlayPlacement, samePlacement } from './PlayPlacement';\n\n// How deep a placement may get, and how often one file's placement may change, before the imports behind it\n// are taken to be a cycle.\nexport const maximumImportDepth = 32;\n\n// The documents of an application, and the diagnostics settling them produced.\nexport interface ResolvedImports {\n readonly documents: readonly PlacedPlayDocument[];\n readonly diagnostics: readonly Diagnostic[];\n}\n\n// Settles which documents make up an application and where each one's top level belongs, by following the\n// file imports from a set of root documents - the port of the C# PlayImports.Resolve.\n//\n// A root document is a whole document. Every file an import matches joins the application once, however many\n// imports match it. When several imports place the same file, the deepest placement wins; two placements where\n// neither lies inside the other are a conflict, and placements that keep deepening are an import cycle. A file's\n// placement depends on the placements of the files importing it, so it is recomputed from every importer's\n// current placement until nothing changes - the order files are found in never decides where one belongs. The\n// documents keep discovery order for multiple roots; a single root follows authored imports depth-first.\nexport function resolveImports(roots: Iterable<string>, source: PlayDocumentSource, languages?: ReadonlySet<string>): ResolvedImports {\n const resolution = new Resolution(source, languages);\n for (const root of new Set([...roots].map(normalizePlayPath))) {\n resolution.addRoot(root);\n }\n resolution.settle();\n return { documents: resolution.documents(), diagnostics: resolution.diagnostics };\n}\n\ninterface FoundImport {\n readonly discovered: DiscoveredImport;\n readonly targets: readonly string[];\n}\n\n// What each import currently contributes to a file's placement, keyed by the importing file and the import.\ntype Contributions = Map<string, { readonly importer: string; readonly index: number; readonly placement: PlayPlacement }>;\n\nclass Resolution {\n readonly diagnostics: Diagnostic[] = [];\n readonly #found: string[] = [];\n readonly #roots = new Set<string>();\n readonly #sources = new Map<string, string>();\n readonly #imports = new Map<string, readonly FoundImport[]>();\n readonly #contributions = new Map<string, Contributions>();\n readonly #placements = new Map<string, PlayPlacement>();\n readonly #pending: string[] = [];\n readonly #changes = new Map<string, number>();\n readonly #unresolved = new Set<string>();\n\n constructor(private readonly source: PlayDocumentSource, private readonly languages?: ReadonlySet<string>) {}\n\n addRoot(root: string): void {\n this.#roots.add(root);\n this.#find(root);\n }\n\n // Placements only deepen, and none is allowed past the maximum depth, so this ends.\n settle(): void {\n for (let file = this.#pending.shift(); file !== undefined; file = this.#pending.shift()) {\n this.#propagate(file);\n }\n this.#reportConflicts();\n const unresolved = [...this.#unresolved];\n for (const importer of unresolved) {\n for (const target of (this.#imports.get(importer) ?? []).flatMap(imported => imported.targets)) {\n if (!this.#unresolved.has(target)) {\n this.#unresolved.add(target);\n unresolved.push(target);\n }\n }\n }\n }\n\n documents(): PlacedPlayDocument[] {\n return this.#orderedPaths().map(path => ({ path, source: this.#sources.get(path) as string, placement: this.#placement(path) ?? documentPlacement, isPlacementResolved: !this.#unresolved.has(path) }));\n }\n\n #orderedPaths(): string[] {\n // Folder compilation keeps discovery order for merge precedence and event ownership.\n // AuthoredOrder records presentation ranks independently, including explicit pins before globs.\n if (this.#roots.size !== 1) return [...this.#found];\n const seen = new Set<string>();\n const ordered: string[] = [];\n for (const root of this.#found) {\n const pending = [root];\n for (let path = pending.pop(); path !== undefined; path = pending.pop()) {\n if (seen.has(path)) continue;\n seen.add(path);\n ordered.push(path);\n pending.push(...(this.#imports.get(path) ?? []).flatMap(imported => imported.targets).reverse());\n }\n }\n return ordered;\n }\n\n #find(file: string): void {\n if (this.#sources.has(file)) return;\n this.#found.push(file);\n const text = this.source.read(file);\n this.#sources.set(file, text);\n this.#imports.set(file, discoverImports(text, file, this.languages).map(discovered => ({ discovered, targets: this.#targets(file, discovered) })));\n this.#pending.push(file);\n }\n\n #targets(file: string, discovered: DiscoveredImport): string[] {\n const { pattern, location } = discovered.fileImport;\n const resolved = resolvePlayPattern(file, pattern);\n // The default sort compares UTF-16 code units, which is the C# ordinal order.\n const matches = [...new Set([...this.source.filesBeneath(staticFolderOf(resolved))]\n .map(normalizePlayPath)\n .filter(path => path !== file && matchesPlayPattern(resolved, path)))].sort();\n if (matches.length === 0) {\n this.#report(hasWildcard(pattern)\n ? { severity: 'warning', code: DiagnosticCodes.FileImportMatchesNothing, message: `Import '${pattern}' matches no .play file`, location }\n : error(DiagnosticCodes.ImportedFileNotFound, `Imported file '${pattern}' does not exist`, location));\n }\n return matches;\n }\n\n #propagate(file: string): void {\n const placement = this.#placement(file);\n (this.#imports.get(file) as readonly FoundImport[]).forEach(({ discovered, targets }, index) => {\n let target = placement === undefined ? undefined : placementFrom(discovered, placement);\n if (target !== undefined && target.length > maximumImportDepth) {\n this.#report(error(DiagnosticCodes.ImportCycle,\n `Import '${discovered.fileImport.pattern}' places files deeper than ${maximumImportDepth} levels - the imports form a cycle`, discovered.fileImport.location));\n this.#unresolved.add(file);\n target = undefined;\n }\n for (const path of targets) {\n this.#find(path);\n this.#contribute(path, file, index, target);\n }\n });\n }\n\n #contribute(file: string, importer: string, index: number, placement: PlayPlacement | undefined): void {\n const contributions = this.#contributions.get(file) ?? new Map();\n this.#contributions.set(file, contributions);\n const key = JSON.stringify([importer, index]);\n const current = contributions.get(key);\n const changed = placement === undefined\n ? contributions.delete(key)\n : current === undefined || !samePlacement(current.placement, placement);\n if (placement !== undefined) {\n contributions.set(key, { importer, index, placement });\n }\n if (changed) {\n this.#recompute(file);\n }\n }\n\n #recompute(file: string): void {\n const placement = this.#deepest(file);\n const current = this.#placements.get(file);\n const changed = current === undefined ? placement !== undefined : placement === undefined || !samePlacement(current, placement);\n if (!changed) return;\n\n // A placement that keeps changing is held up by imports that feed back into themselves.\n const changes = (this.#changes.get(file) ?? 0) + 1;\n this.#changes.set(file, changes);\n if (changes > maximumImportDepth) {\n this.#unresolved.add(file);\n for (const { discovered: { fileImport } } of this.#imports.get(file) as readonly FoundImport[]) {\n this.#report(error(DiagnosticCodes.ImportCycle,\n `Import '${fileImport.pattern}' is part of imports that keep placing each other - the imports form a cycle`, fileImport.location));\n }\n return;\n }\n if (placement === undefined) {\n this.#placements.delete(file);\n } else {\n this.#placements.set(file, placement);\n }\n this.#pending.push(file);\n }\n\n #placement(file: string): PlayPlacement | undefined {\n return this.#placements.get(file) ?? this.#deepest(file);\n }\n\n #deepest(file: string): PlayPlacement | undefined {\n const candidates = [...(this.#roots.has(file) ? [documentPlacement] : []), ...this.#ordered(file).map(contribution => contribution.placement)];\n return candidates.reduce<PlayPlacement | undefined>(\n (deepest, candidate) => deepest === undefined || isWithinOrSame(candidate, deepest) ? candidate : deepest, undefined);\n }\n\n #ordered(file: string) {\n return [...(this.#contributions.get(file)?.values() ?? [])]\n .sort((left, right) => left.importer === right.importer ? left.index - right.index : left.importer < right.importer ? -1 : 1);\n }\n\n #reportConflicts(): void {\n for (const file of this.#found) {\n const placement = this.#placement(file);\n if (placement === undefined) continue;\n for (const { importer, index, placement: contribution } of this.#ordered(file)) {\n if (!isWithinOrSame(placement, contribution)) {\n this.#unresolved.add(file);\n const { fileImport } = (this.#imports.get(importer) as readonly FoundImport[])[index].discovered;\n this.#report(error(DiagnosticCodes.ConflictingImportPlacement,\n `'${file}' is imported into both ${describePlacement(placement)} and ${describePlacement(contribution)} - a file belongs in one place`, fileImport.location));\n }\n }\n }\n }\n\n // Reports a diagnostic once - a file whose placement changes runs its imports again.\n #report(diagnostic: Diagnostic): void {\n const key = keyOf(diagnostic);\n if (!this.diagnostics.some(other => keyOf(other) === key)) {\n this.diagnostics.push(diagnostic);\n }\n }\n}\n\nconst keyOf = (diagnostic: Diagnostic): string => JSON.stringify([diagnostic.severity, diagnostic.code, diagnostic.message, diagnostic.location]);\nconst error = (code: string, message: string, location: SourceLocation): Diagnostic => ({ severity: 'error', code, message, location });\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";const e=[],isDocumentPlacement=e=>e.length===0;function describePlacement(e){return e.length===0?`the application`:e.length===1?`module '${e[0]}'`:`feature '${e.join(`.`)}'`}export{describePlacement,e as documentPlacement,isDocumentPlacement};
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";const e=[],isDocumentPlacement=e=>e.length===0;function describePlacement(e){return e.length===0?`the application`:e.length===1?`module '${e[0]}'`:`feature '${e.join(`.`)}'`}const isWithinOrSame=(e,t)=>t.length<=e.length&&t.every((t,n)=>t===e[n]),samePlacement=(e,t)=>e.length===t.length&&isWithinOrSame(e,t);export{describePlacement,e as documentPlacement,isDocumentPlacement,isWithinOrSame,samePlacement};
|
|
2
2
|
//# sourceMappingURL=PlayPlacement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayPlacement.js","names":["documentPlacement","placement"],"sources":["../../../../../../Compiler/Files/PlayPlacement.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\n// Where the top level of a .play file belongs: the module name followed by the names of the nested features,\n// outermost first, and empty for the application itself - the port of the C# PlayPlacement. A file is placed\n// by the import that brings it in: written inside 'module Ordering' and 'feature Orders', it places the\n// imported file at Ordering.Orders, so what the file declares at its top level is the body of that feature.\nexport type PlayPlacement = readonly string[];\n\n// The placement of a whole document - its top level is the application's.\nexport const documentPlacement: PlayPlacement = [];\n\n// Whether a file is a whole document rather than placed in a module or feature.\nexport const isDocumentPlacement = (placement: PlayPlacement): boolean => placement.length === 0;\n\n// The placement as it reads in a diagnostic, such as module 'Ordering' or feature 'Ordering.Orders'.\nexport function describePlacement(placement: PlayPlacement): string {\n if (placement.length === 0) return 'the application';\n if (placement.length === 1) return `module '${placement[0]}'`;\n return `feature '${placement.join('.')}'`;\n}\n\n// Whether one placement lies inside another, or is the same - the other's scope is a prefix of this one.\nexport const isWithinOrSame = (placement: PlayPlacement, other: PlayPlacement): boolean =>\n other.length <= placement.length && other.every((name, index) => name === placement[index]);\n\nexport const samePlacement = (left: PlayPlacement, right: PlayPlacement): boolean =>\n left.length === right.length && isWithinOrSame(left, right);\n"],"mappings":"qDAUA,MAAaA,EAAmC,CAAC,EAGpC,oBAAuB,GAAsCC,EAAU,SAAW,EAG/F,SAAgB,kBAAkB,EAAkC,CAGhE,OAFIA,EAAU,SAAW,EAAU,kBAC/BA,EAAU,SAAW,EAAU,WAAWA,EAAU,GAAG,GACpD,YAAYA,EAAU,KAAK,GAAG,EAAE,EAC3C"}
|
|
1
|
+
{"version":3,"file":"PlayPlacement.js","names":["documentPlacement","placement","other","name","index","left","right"],"sources":["../../../../../../Compiler/Files/PlayPlacement.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\n// Where the top level of a .play file belongs: the module name followed by the names of the nested features,\n// outermost first, and empty for the application itself - the port of the C# PlayPlacement. A file is placed\n// by the import that brings it in: written inside 'module Ordering' and 'feature Orders', it places the\n// imported file at Ordering.Orders, so what the file declares at its top level is the body of that feature.\nexport type PlayPlacement = readonly string[];\n\n// The placement of a whole document - its top level is the application's.\nexport const documentPlacement: PlayPlacement = [];\n\n// Whether a file is a whole document rather than placed in a module or feature.\nexport const isDocumentPlacement = (placement: PlayPlacement): boolean => placement.length === 0;\n\n// The placement as it reads in a diagnostic, such as module 'Ordering' or feature 'Ordering.Orders'.\nexport function describePlacement(placement: PlayPlacement): string {\n if (placement.length === 0) return 'the application';\n if (placement.length === 1) return `module '${placement[0]}'`;\n return `feature '${placement.join('.')}'`;\n}\n\n// Whether one placement lies inside another, or is the same - the other's scope is a prefix of this one.\nexport const isWithinOrSame = (placement: PlayPlacement, other: PlayPlacement): boolean =>\n other.length <= placement.length && other.every((name, index) => name === placement[index]);\n\nexport const samePlacement = (left: PlayPlacement, right: PlayPlacement): boolean =>\n left.length === right.length && isWithinOrSame(left, right);\n"],"mappings":"qDAUA,MAAaA,EAAmC,CAAC,EAGpC,oBAAuB,GAAsCC,EAAU,SAAW,EAG/F,SAAgB,kBAAkB,EAAkC,CAGhE,OAFIA,EAAU,SAAW,EAAU,kBAC/BA,EAAU,SAAW,EAAU,WAAWA,EAAU,GAAG,GACpD,YAAYA,EAAU,KAAK,GAAG,EAAE,EAC3C,CAGA,MAAa,gBAAkB,EAA0B,IACrDC,EAAM,QAAUD,EAAU,QAAUC,EAAM,OAAO,EAAM,IAAUC,IAASF,EAAUG,EAAM,EAEjF,eAAiB,EAAqB,IAC/CC,EAAK,SAAWC,EAAM,QAAU,eAAeD,EAAMC,CAAK"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{eventDeclarations as t}from"../Syntax/EventDeclarations.js";import{authoredOrderKey as n,authoredOrderOf as r}from"./AuthoredOrder.js";import{buildingReadModelReferences as i,sliceReferences as a}from"../Dependencies/SliceReferences.js";import{stronglyConnectedGroups as o}from"../Dependencies/StronglyConnectedGroups.js";import{DependencyGraph as s}from"../Dependencies/DependencyGraph.js";import{ordinalIgnoreCaseKey as c}from"../Text/ordinalIgnoreCaseKey.js";function timelineOrderDiagnostics(
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{eventDeclarations as t}from"../Syntax/EventDeclarations.js";import{authoredOrderKey as n,authoredOrderOf as r}from"./AuthoredOrder.js";import{buildingReadModelReferences as i,sliceReferences as a}from"../Dependencies/SliceReferences.js";import{stronglyConnectedGroups as o}from"../Dependencies/StronglyConnectedGroups.js";import{DependencyGraph as s}from"../Dependencies/DependencyGraph.js";import{ordinalIgnoreCaseKey as c}from"../Text/ordinalIgnoreCaseKey.js";function timelineOrderDiagnostics(e){return timelineOrderFindings(e).map(e=>e.diagnostic)}function timelineOrderFindings(l,u=r(l)){let ordered=(e,t)=>e.map(e=>({syntax:e,rank:u.get(n([...t,e.name]))??2**53-1})).sort((e,t)=>e.rank-t.rank).map(e=>e.syntax),d=[],feature=(e,t)=>{let n=[...t,e.name];for(let t of ordered(e.slices,n))d.push({syntax:t,scope:[...n,t.name],identity:[...n.map(e=>`container:${e}`),`slice:${t.name}`],index:d.length});for(let t of ordered(e.features,n))feature(t,n)};for(let e of ordered(l.modules,[]))for(let t of ordered(e.features,[e.name]))feature(t,[e.name]);let f=new Map(d.map(e=>[e,/* @__PURE__ */ new Set([...t(e.syntax).map(e=>c(e.name)),...e.syntax.commands.flatMap(e=>e.produces.map(e=>c(e.event))),...e.syntax.reactions.flatMap(e=>e.triggers.flatMap(e=>e.produces.map(e=>c(e.event))))])])),p=/* @__PURE__ */ new Map;for(let e of d)for(let n of t(e.syntax)){let t=c(n.name);p.has(t)||p.set(t,e)}let m=/* @__PURE__ */ new Map;for(let e of d){let t=n(e.scope);m.has(t)||m.set(t,e)}let h=/* @__PURE__ */ new Map;for(let e of s.for(l,u).edges.filter(e=>e.kind===`decidesFrom`))for(let t of e.evidence){let r=n([...e.consumer.scope,t.name.toLowerCase()]);h.has(r)||h.set(r,m.get(n(e.producer.scope)))}let g=[];for(let e of d){let t=/* @__PURE__ */ new Set,r=a(e.syntax).references.filter(e=>e.timeline).map(e=>({event:e.name,location:e.location,readModel:e.targetKind===`ReadModel`}));for(let a of r){let r=c(a.event),o=`${a.readModel?`ReadModel`:`Event`}:${r}`;if(t.has(o))continue;t.add(o);let s=a.readModel?h.get(n([...e.scope,a.event.toLowerCase()])):p.get(r);if(s===void 0||s===e)continue;let l=0;for(;l<e.scope.length&&l<s.scope.length&&e.identity[l]===s.identity[l];)l++;if(l!==e.scope.length&&l!==s.scope.length){if(a.readModel){let t=e.identity.slice(0,l+1),n=new Set(d.filter(e=>t.every((t,n)=>e.identity[n]===t)).flatMap(e=>[...f.get(e)]));if(i(s.syntax,a.event).some(e=>e.timeline&&e.kind===`usesFactsFrom`&&e.targetKind===`Event`&&n.has(c(e.name))))continue}g.push({...a,consumer:e,producer:s,container:n(e.identity.slice(0,l)),left:e.identity[l],right:s.identity[l]})}}}let compare=(e,t)=>e.consumer.index-t.consumer.index||e.location.line-t.location.line||e.location.column-t.location.column,_=/* @__PURE__ */ new Set,v=[];for(let t of new Set(g.map(e=>e.container))){let r=g.filter(e=>e.container===t),i=/* @__PURE__ */ new Map;for(let e of r)i.has(e.left)||i.set(e.left,/* @__PURE__ */ new Set),i.has(e.right)||i.set(e.right,/* @__PURE__ */ new Set),i.get(e.left).add(e.right);for(let a of o(i).filter(e=>e.length>1)){let i=new Set(a),o=r.filter(e=>i.has(e.left)&&i.has(e.right));o.forEach(e=>_.add(e));let s=o.filter(e=>e.consumer.index<e.producer.index).sort(compare)[0];if(s===void 0)continue;let memberIndex=e=>Math.min(...o.flatMap(e=>[e.consumer,e.producer]).filter(n=>{let r=JSON.parse(t);return n.identity[r.length]===e}).map(e=>e.index));a.sort((e,t)=>memberIndex(e)-memberIndex(t)),v.push({edge:s,members:a,diagnostic:{severity:`information`,code:e.TimelineCycleGroup,message:`Timeline group ${a.map(e=>`${e.startsWith(`slice:`)?`slice`:t===n([])?`module`:`feature`} '${e.slice(e.indexOf(`:`)+1)}'`).join(`, `)} depend on each other's events or read models; reordering these members cannot make every dependency flow left to right.`,location:s.location}})}}for(let t of g){if(t.consumer.index>=t.producer.index||_.has(t))continue;let n=t.consumer.scope.slice(0,-1),r=t.producer.scope.length>t.consumer.scope.length&&n.every((e,n)=>t.producer.scope[n]===e),i=r?` The producer is in the consumer's own sub-feature; this cannot be fixed by reordering.`:` Consider drawing the producer before the consumer.`,a=t.readModel?`reads read model '${t.event}' built by`:`uses event '${t.event}' produced by`;v.push({edge:t,ownSubFeature:r,diagnostic:{severity:`information`,code:e.EventFromLaterSlice,message:`Slice '${t.consumer.syntax.name}' ${a} slice '${t.producer.syntax.name}' drawn after it.${i}`,location:t.location}})}return v.sort((e,t)=>compare(e.edge,t.edge)).map(({edge:e,diagnostic:t,members:r,ownSubFeature:i})=>({diagnostic:t,consumerScope:e.consumer.scope,producerScope:e.producer.scope,readModel:e.readModel,ownSubFeature:i===!0,key:n(r===void 0?[t.code,n(e.consumer.scope),...e.readModel?[`ReadModel`]:[],c(e.event)]:[t.code,e.container,...[...r].sort()])}))}export{timelineOrderDiagnostics,timelineOrderFindings};
|
|
2
2
|
//# sourceMappingURL=TimelineOrder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimelineOrder.js","names":["order","authoredOrderOf","application","items","authoredOrderKey","outer","syntax","left","right","item","slices","scope","slice","name","child","module","produced","eventDeclarations","ordinalIgnoreCaseKey","event","command","value","reaction","trigger","producers","byScope","key","readers","decision","DependencyGraph","edge","reference","edges","consumer","seen","references","sliceReferences","producer","common","side","facts","index","buildingReadModelReferences","suppressed","findings","container","local","graph","group","stronglyConnectedGroups","members","internal","first","member","DiagnosticCodes","parent","consequence","use","finding"],"sources":["../../../../../../Compiler/Files/TimelineOrder.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { buildingReadModelReferences, sliceReferences } from '../Dependencies/SliceReferences';\nimport { DependencyGraph } from '../Dependencies/DependencyGraph';\nimport { stronglyConnectedGroups } from '../Dependencies/StronglyConnectedGroups';\nimport { ApplicationSyntax, FeatureSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { authoredOrderKey, authoredOrderOf } from './AuthoredOrder';\nimport { ordinalIgnoreCaseKey } from '../Text/ordinalIgnoreCaseKey';\n\ninterface Slice {\n syntax: SliceSyntax;\n scope: readonly string[];\n identity: readonly string[];\n index: number;\n}\ninterface Reference { event: string; location: SourceLocation; readModel: boolean }\ninterface Edge extends Reference { consumer: Slice; producer: Slice; left: string; right: string; container: string }\n\n// This pass only observes syntax. Its ranks and graph never enter the persisted model.\nexport function timelineOrderDiagnostics(application: ApplicationSyntax): Diagnostic[] {\n const order = authoredOrderOf(application);\n const ordered = <T extends { name: string }>(items: readonly T[], outer: readonly string[]): T[] => items\n .map(syntax => ({ syntax, rank: order.get(authoredOrderKey([...outer, syntax.name])) ?? Number.MAX_SAFE_INTEGER }))\n .sort((left, right) => left.rank - right.rank).map(item => item.syntax);\n const slices: Slice[] = [];\n const feature = (syntax: FeatureSyntax, outer: readonly string[]) => {\n const scope = [...outer, syntax.name];\n for (const slice of ordered(syntax.slices, scope)) slices.push({ syntax: slice, scope: [...scope, slice.name], identity: [...scope.map(name => `container:${name}`), `slice:${slice.name}`], index: slices.length });\n for (const child of ordered(syntax.features, scope)) feature(child, scope);\n };\n for (const module of ordered(application.modules, [])) {\n for (const child of ordered(module.features, [module.name])) feature(child, [module.name]);\n }\n const produced = new Map(slices.map(slice => [slice, new Set([\n ...eventDeclarations(slice.syntax).map(event => ordinalIgnoreCaseKey(event.name)),\n ...slice.syntax.commands.flatMap(command => command.produces.map(value => ordinalIgnoreCaseKey(value.event))),\n ...slice.syntax.reactions.flatMap(reaction => reaction.triggers.flatMap(trigger => trigger.produces.map(value => ordinalIgnoreCaseKey(value.event)))),\n ])]));\n const producers = new Map<string, Slice>();\n for (const slice of slices) {\n for (const event of eventDeclarations(slice.syntax)) {\n const name = ordinalIgnoreCaseKey(event.name);\n if (!producers.has(name)) producers.set(name, slice);\n }\n }\n // Use decidesFrom resolution, including builder preference and declaration fallback.\n const byScope = new Map<string, Slice>();\n for (const slice of slices) {\n const key = authoredOrderKey(slice.scope);\n if (!byScope.has(key)) byScope.set(key, slice);\n }\n const readers = new Map<string, Slice>();\n for (const decision of DependencyGraph.for(application, order).edges.filter(edge => edge.kind === 'decidesFrom')) {\n for (const reference of decision.evidence) {\n const key = authoredOrderKey([...decision.consumer.scope, reference.name.toLowerCase()]);\n if (!readers.has(key)) readers.set(key, byScope.get(authoredOrderKey(decision.producer.scope))!);\n }\n }\n const edges: Edge[] = [];\n for (const consumer of slices) {\n const seen = new Set<string>();\n const references = sliceReferences(consumer.syntax).references.filter(reference => reference.timeline)\n .map(reference => ({ event: reference.name, location: reference.location, readModel: reference.targetKind === 'ReadModel' }));\n for (const reference of references) {\n const name = ordinalIgnoreCaseKey(reference.event);\n const key = `${reference.readModel ? 'ReadModel' : 'Event'}:${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n const producer = reference.readModel ? readers.get(authoredOrderKey([...consumer.scope, reference.event.toLowerCase()])) : producers.get(name);\n if (producer === undefined || producer === consumer) continue;\n let common = 0;\n while (common < consumer.scope.length && common < producer.scope.length && consumer.identity[common] === producer.identity[common]) common++;\n if (common === consumer.scope.length || common === producer.scope.length) continue;\n // At the lowest common container, the reader's whole child supplies feedback\n // only for builders of the read model being read.\n // Exclude this read before SCC grouping, not just backward-edge emission.\n if (reference.readModel) {\n const side = consumer.identity.slice(0, common + 1);\n const facts = new Set(slices.filter(slice => side.every((name, index) => slice.identity[index] === name)).flatMap(slice => [...produced.get(slice)!]));\n if (buildingReadModelReferences(producer.syntax, reference.event).some(value => value.timeline && value.kind === 'usesFactsFrom' && value.targetKind === 'Event' && facts.has(ordinalIgnoreCaseKey(value.name)))) continue;\n }\n edges.push({ ...reference, consumer, producer, container: authoredOrderKey(consumer.identity.slice(0, common)), left: consumer.identity[common], right: producer.identity[common] });\n }\n }\n const compare = (left: Edge, right: Edge) => left.consumer.index - right.consumer.index || left.location.line - right.location.line || left.location.column - right.location.column;\n const suppressed = new Set<Edge>();\n const findings: { edge: Edge; diagnostic: Diagnostic }[] = [];\n for (const container of new Set(edges.map(edge => edge.container))) {\n const local = edges.filter(edge => edge.container === container);\n const graph = new Map<string, Set<string>>();\n for (const edge of local) {\n if (!graph.has(edge.left)) graph.set(edge.left, new Set());\n if (!graph.has(edge.right)) graph.set(edge.right, new Set());\n graph.get(edge.left)!.add(edge.right);\n }\n for (const group of stronglyConnectedGroups(graph).filter(group => group.length > 1)) {\n const members = new Set(group);\n const internal = local.filter(edge => members.has(edge.left) && members.has(edge.right));\n internal.forEach(edge => suppressed.add(edge));\n const first = internal.filter(edge => edge.consumer.index < edge.producer.index).sort(compare)[0];\n if (first === undefined) continue;\n const memberIndex = (member: string) => Math.min(...internal.flatMap(edge => [edge.consumer, edge.producer]).filter(slice => {\n const scope = JSON.parse(container) as string[];\n return slice.identity[scope.length] === member;\n }).map(slice => slice.index));\n group.sort((left, right) => memberIndex(left) - memberIndex(right));\n findings.push({ edge: first, diagnostic: { severity: 'information', code: DiagnosticCodes.TimelineCycleGroup, message: `Timeline group ${group.map(member => `${member.startsWith('slice:') ? 'slice' : container === authoredOrderKey([]) ? 'module' : 'feature'} '${member.slice(member.indexOf(':') + 1)}'`).join(', ')} depend on each other's events or read models; reordering these members cannot make every dependency flow left to right.`, location: first.location } });\n }\n }\n for (const edge of edges) {\n if (edge.consumer.index >= edge.producer.index || suppressed.has(edge)) continue;\n const parent = edge.consumer.scope.slice(0, -1);\n const ownSubFeature = edge.producer.scope.length > edge.consumer.scope.length && parent.every((name, index) => edge.producer.scope[index] === name);\n const consequence = ownSubFeature ? ' The producer is in the consumer\\'s own sub-feature; this cannot be fixed by reordering.' : ' Consider drawing the producer before the consumer.';\n const use = edge.readModel ? `reads read model '${edge.event}' built by` : `uses event '${edge.event}' produced by`;\n findings.push({ edge, diagnostic: { severity: 'information', code: DiagnosticCodes.EventFromLaterSlice, message: `Slice '${edge.consumer.syntax.name}' ${use} slice '${edge.producer.syntax.name}' drawn after it.${consequence}`, location: edge.location } });\n }\n return findings.sort((left, right) => compare(left.edge, right.edge)).map(finding => finding.diagnostic);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimelineOrder.js","names":["application","finding","authoredOrderOf","items","order","authoredOrderKey","outer","syntax","left","right","item","slices","scope","slice","name","child","module","produced","eventDeclarations","ordinalIgnoreCaseKey","event","command","value","reaction","trigger","producers","byScope","key","readers","decision","DependencyGraph","edge","reference","edges","consumer","seen","references","sliceReferences","producer","common","side","facts","index","buildingReadModelReferences","suppressed","findings","container","local","graph","group","stronglyConnectedGroups","members","internal","first","member","DiagnosticCodes","parent","ownSubFeature","consequence","use","diagnostic"],"sources":["../../../../../../Compiler/Files/TimelineOrder.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 { Diagnostic } from '../Diagnostics/Diagnostic';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { buildingReadModelReferences, sliceReferences } from '../Dependencies/SliceReferences';\nimport { DependencyGraph } from '../Dependencies/DependencyGraph';\nimport { stronglyConnectedGroups } from '../Dependencies/StronglyConnectedGroups';\nimport { ApplicationSyntax, FeatureSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { authoredOrderKey, authoredOrderOf } from './AuthoredOrder';\nimport { ordinalIgnoreCaseKey } from '../Text/ordinalIgnoreCaseKey';\n\ninterface Slice {\n syntax: SliceSyntax;\n scope: readonly string[];\n identity: readonly string[];\n index: number;\n}\ninterface Reference { event: string; location: SourceLocation; readModel: boolean }\ninterface Edge extends Reference { consumer: Slice; producer: Slice; left: string; right: string; container: string }\n\n/** Structured presentation evidence for a repair; never serialized into the model. */\nexport interface TimelineFinding {\n readonly diagnostic: Diagnostic;\n readonly consumerScope: readonly string[];\n readonly producerScope: readonly string[];\n readonly readModel: boolean;\n readonly ownSubFeature: boolean;\n readonly key: string;\n}\n\n// This pass only observes syntax. Its ranks and graph never enter the persisted model.\nexport function timelineOrderDiagnostics(application: ApplicationSyntax): Diagnostic[] {\n return timelineOrderFindings(application).map(finding => finding.diagnostic);\n}\n\nexport function timelineOrderFindings(application: ApplicationSyntax, order: ReadonlyMap<string, number> = authoredOrderOf(application)): TimelineFinding[] {\n const ordered = <T extends { name: string }>(items: readonly T[], outer: readonly string[]): T[] => items\n .map(syntax => ({ syntax, rank: order.get(authoredOrderKey([...outer, syntax.name])) ?? Number.MAX_SAFE_INTEGER }))\n .sort((left, right) => left.rank - right.rank).map(item => item.syntax);\n const slices: Slice[] = [];\n const feature = (syntax: FeatureSyntax, outer: readonly string[]) => {\n const scope = [...outer, syntax.name];\n for (const slice of ordered(syntax.slices, scope)) slices.push({ syntax: slice, scope: [...scope, slice.name], identity: [...scope.map(name => `container:${name}`), `slice:${slice.name}`], index: slices.length });\n for (const child of ordered(syntax.features, scope)) feature(child, scope);\n };\n for (const module of ordered(application.modules, [])) {\n for (const child of ordered(module.features, [module.name])) feature(child, [module.name]);\n }\n const produced = new Map(slices.map(slice => [slice, new Set([\n ...eventDeclarations(slice.syntax).map(event => ordinalIgnoreCaseKey(event.name)),\n ...slice.syntax.commands.flatMap(command => command.produces.map(value => ordinalIgnoreCaseKey(value.event))),\n ...slice.syntax.reactions.flatMap(reaction => reaction.triggers.flatMap(trigger => trigger.produces.map(value => ordinalIgnoreCaseKey(value.event)))),\n ])]));\n const producers = new Map<string, Slice>();\n for (const slice of slices) {\n for (const event of eventDeclarations(slice.syntax)) {\n const name = ordinalIgnoreCaseKey(event.name);\n if (!producers.has(name)) producers.set(name, slice);\n }\n }\n // Use decidesFrom resolution, including builder preference and declaration fallback.\n const byScope = new Map<string, Slice>();\n for (const slice of slices) {\n const key = authoredOrderKey(slice.scope);\n if (!byScope.has(key)) byScope.set(key, slice);\n }\n const readers = new Map<string, Slice>();\n for (const decision of DependencyGraph.for(application, order).edges.filter(edge => edge.kind === 'decidesFrom')) {\n for (const reference of decision.evidence) {\n const key = authoredOrderKey([...decision.consumer.scope, reference.name.toLowerCase()]);\n if (!readers.has(key)) readers.set(key, byScope.get(authoredOrderKey(decision.producer.scope))!);\n }\n }\n const edges: Edge[] = [];\n for (const consumer of slices) {\n const seen = new Set<string>();\n const references = sliceReferences(consumer.syntax).references.filter(reference => reference.timeline)\n .map(reference => ({ event: reference.name, location: reference.location, readModel: reference.targetKind === 'ReadModel' }));\n for (const reference of references) {\n const name = ordinalIgnoreCaseKey(reference.event);\n const key = `${reference.readModel ? 'ReadModel' : 'Event'}:${name}`;\n if (seen.has(key)) continue;\n seen.add(key);\n const producer = reference.readModel ? readers.get(authoredOrderKey([...consumer.scope, reference.event.toLowerCase()])) : producers.get(name);\n if (producer === undefined || producer === consumer) continue;\n let common = 0;\n while (common < consumer.scope.length && common < producer.scope.length && consumer.identity[common] === producer.identity[common]) common++;\n if (common === consumer.scope.length || common === producer.scope.length) continue;\n // At the lowest common container, the reader's whole child supplies feedback\n // only for builders of the read model being read.\n // Exclude this read before SCC grouping, not just backward-edge emission.\n if (reference.readModel) {\n const side = consumer.identity.slice(0, common + 1);\n const facts = new Set(slices.filter(slice => side.every((name, index) => slice.identity[index] === name)).flatMap(slice => [...produced.get(slice)!]));\n if (buildingReadModelReferences(producer.syntax, reference.event).some(value => value.timeline && value.kind === 'usesFactsFrom' && value.targetKind === 'Event' && facts.has(ordinalIgnoreCaseKey(value.name)))) continue;\n }\n edges.push({ ...reference, consumer, producer, container: authoredOrderKey(consumer.identity.slice(0, common)), left: consumer.identity[common], right: producer.identity[common] });\n }\n }\n const compare = (left: Edge, right: Edge) => left.consumer.index - right.consumer.index || left.location.line - right.location.line || left.location.column - right.location.column;\n const suppressed = new Set<Edge>();\n const findings: { edge: Edge; diagnostic: Diagnostic; members?: readonly string[]; ownSubFeature?: boolean }[] = [];\n for (const container of new Set(edges.map(edge => edge.container))) {\n const local = edges.filter(edge => edge.container === container);\n const graph = new Map<string, Set<string>>();\n for (const edge of local) {\n if (!graph.has(edge.left)) graph.set(edge.left, new Set());\n if (!graph.has(edge.right)) graph.set(edge.right, new Set());\n graph.get(edge.left)!.add(edge.right);\n }\n for (const group of stronglyConnectedGroups(graph).filter(group => group.length > 1)) {\n const members = new Set(group);\n const internal = local.filter(edge => members.has(edge.left) && members.has(edge.right));\n internal.forEach(edge => suppressed.add(edge));\n const first = internal.filter(edge => edge.consumer.index < edge.producer.index).sort(compare)[0];\n if (first === undefined) continue;\n const memberIndex = (member: string) => Math.min(...internal.flatMap(edge => [edge.consumer, edge.producer]).filter(slice => {\n const scope = JSON.parse(container) as string[];\n return slice.identity[scope.length] === member;\n }).map(slice => slice.index));\n group.sort((left, right) => memberIndex(left) - memberIndex(right));\n findings.push({ edge: first, members: group, diagnostic: { severity: 'information', code: DiagnosticCodes.TimelineCycleGroup, message: `Timeline group ${group.map(member => `${member.startsWith('slice:') ? 'slice' : container === authoredOrderKey([]) ? 'module' : 'feature'} '${member.slice(member.indexOf(':') + 1)}'`).join(', ')} depend on each other's events or read models; reordering these members cannot make every dependency flow left to right.`, location: first.location } });\n }\n }\n for (const edge of edges) {\n if (edge.consumer.index >= edge.producer.index || suppressed.has(edge)) continue;\n const parent = edge.consumer.scope.slice(0, -1);\n const ownSubFeature = edge.producer.scope.length > edge.consumer.scope.length && parent.every((name, index) => edge.producer.scope[index] === name);\n const consequence = ownSubFeature ? ' The producer is in the consumer\\'s own sub-feature; this cannot be fixed by reordering.' : ' Consider drawing the producer before the consumer.';\n const use = edge.readModel ? `reads read model '${edge.event}' built by` : `uses event '${edge.event}' produced by`;\n findings.push({ edge, ownSubFeature, diagnostic: { severity: 'information', code: DiagnosticCodes.EventFromLaterSlice, message: `Slice '${edge.consumer.syntax.name}' ${use} slice '${edge.producer.syntax.name}' drawn after it.${consequence}`, location: edge.location } });\n }\n return findings.sort((left, right) => compare(left.edge, right.edge)).map(({ edge, diagnostic, members, ownSubFeature }) => ({\n diagnostic, consumerScope: edge.consumer.scope, producerScope: edge.producer.scope, readModel: edge.readModel, ownSubFeature: ownSubFeature === true,\n key: members === undefined ? authoredOrderKey([diagnostic.code, authoredOrderKey(edge.consumer.scope), ...(edge.readModel ? ['ReadModel'] : []), ordinalIgnoreCaseKey(edge.event)])\n : authoredOrderKey([diagnostic.code, edge.container, ...[...members].sort()]),\n }));\n}\n"],"mappings":"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"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import"./FileImportParser.js";import"./FeatureBody.js";import"./ModuleBody.js";
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{firstWord as e}from"./LineText.js";import{isDocumentPlacement as t}from"../Files/PlayPlacement.js";import{tryParseFileImport as n}from"./FileImportParser.js";import{parseFeature as r}from"./FeatureBody.js";import{parseModule as i}from"./ModuleBody.js";function placementFrom(e,n){let{scope:r}=e;return r.length===0?n:e.startsAtModule?t(n)?r:n.length===1&&n[0]===r[0]?[...n,...r.slice(1)]:void 0:t(n)?void 0:[...n,...r]}function discoverImports(t){let a=[];for(let o=t.reader.peekSignificant();o!==void 0;o=t.reader.peekSignificant()){t.reader.takeSignificant();let s=e(o.content),c=s===`import`?n(o):void 0;if(c!==void 0)a.push({scope:[],startsAtModule:!1,fileImport:c});else if(s===`module`){let e=i(t,o);a.push(...e.fileImports.map(t=>({scope:[e.name],startsAtModule:!0,fileImport:t}))),a.push(...e.features.flatMap(t=>importsIn(t,[e.name],!0)))}else s===`feature`?a.push(...importsIn(r(t,o),[],!1)):t.skipOpaqueBlock(o.indent)}return a}function importsIn(e,t,n){let r=[...t,e.name];return[...e.fileImports.map(e=>({scope:r,startsAtModule:n,fileImport:e})),...e.features.flatMap(e=>importsIn(e,r,n))]}export{discoverImports,placementFrom};
|
|
2
|
+
//# sourceMappingURL=ImportDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportDiscovery.js","names":["discovered","scope","document","isDocumentPlacement","found","line","context","keyword","firstWord","fileImport","tryParseFileImport","module","parseModule","each","feature","parseFeature","outer","nested","startsAtModule"],"sources":["../../../../../../Compiler/Parsing/ImportDiscovery.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 { isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { FeatureSyntax, FileImportSyntax } from '../Syntax/Structure';\nimport { parseFeature } from './FeatureBody';\nimport { tryParseFileImport } from './FileImportParser';\nimport { firstWord } from './LineText';\nimport { parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\n\n// A file import, together with the module and feature names around it in the document, outermost first, and\n// whether the outermost name is a 'module' written at the document's top level rather than a 'feature'. The\n// port of the C# DiscoveredFileImport.\nexport interface DiscoveredImport {\n readonly scope: readonly string[];\n readonly startsAtModule: boolean;\n readonly fileImport: FileImportSyntax;\n}\n\n// Where an import places what it imports, given where the document holding it is placed - undefined when the\n// import cannot place anything from there. A top level 'feature' only means something once the document is\n// placed in a module, so until then its imports place nothing - the document reports the misplaced feature\n// itself if it never is. A top level 'module' is the module's own declaration in a whole document, a\n// restatement that joins the placement in a document placed in that module, and nothing anywhere else.\nexport function placementFrom(discovered: DiscoveredImport, document: PlayPlacement): PlayPlacement | undefined {\n const { scope } = discovered;\n if (scope.length === 0) return document;\n if (!discovered.startsAtModule) return isDocumentPlacement(document) ? undefined : [...document, ...scope];\n if (isDocumentPlacement(document)) return scope;\n return document.length === 1 && document[0] === scope[0] ? [...document, ...scope.slice(1)] : undefined;\n}\n\n// Finds the files a document imports and where in it each import is written, without settling where the\n// document itself belongs - the port of the C# ScreenplayParser.DiscoverImports. Where a file belongs depends\n// on what imports it, and what it imports depends on where the imports are written in it, so this reads the\n// module and feature structure of any file, whether its top level is the application's or the body of a\n// module or feature it will later be placed in. The context's diagnostics are not the document's.\nexport function discoverImports(context: ParserContext): DiscoveredImport[] {\n const found: DiscoveredImport[] = [];\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n const fileImport = keyword === 'import' ? tryParseFileImport(line) : undefined;\n if (fileImport !== undefined) {\n found.push({ scope: [], startsAtModule: false, fileImport });\n } else if (keyword === 'module') {\n const module = parseModule(context, line);\n found.push(...module.fileImports.map(each => ({ scope: [module.name], startsAtModule: true, fileImport: each })));\n found.push(...module.features.flatMap(feature => importsIn(feature, [module.name], true)));\n } else if (keyword === 'feature') {\n found.push(...importsIn(parseFeature(context, line), [], false));\n } else {\n context.skipOpaqueBlock(line.indent);\n }\n }\n return found;\n}\n\nfunction importsIn(feature: FeatureSyntax, outer: readonly string[], startsAtModule: boolean): DiscoveredImport[] {\n const scope = [...outer, feature.name];\n return [\n ...feature.fileImports.map(fileImport => ({ scope, startsAtModule, fileImport })),\n ...feature.features.flatMap(nested => importsIn(nested, scope, startsAtModule)),\n ];\n}\n"],"mappings":"wTAyBA,SAAgB,cAAc,EAA8B,EAAoD,CAC5G,GAAM,CAAE,SAAUA,EAIlB,OAHIC,EAAM,SAAW,EAAUC,EAC1BF,EAAW,eACZG,EAAoBD,CAAQ,EAAUD,EACnCC,EAAS,SAAW,GAAKA,EAAS,KAAOD,EAAM,GAAK,CAAC,GAAGC,EAAU,GAAGD,EAAM,MAAM,CAAC,CAAC,EAAI,IAAA,GAFvDE,EAAoBD,CAAQ,EAAI,IAAA,GAAY,CAAC,GAAGA,EAAU,GAAGD,CAAK,CAG7G,CAOA,SAAgB,gBAAgB,EAA4C,CACxE,IAAMG,EAA4B,CAAC,EACnC,IAAK,IAAIC,EAAOC,EAAQ,OAAO,gBAAgB,EAAGD,IAAS,IAAA,GAAW,EAAOC,EAAQ,OAAO,gBAAgB,EAAG,CAC3GA,EAAQ,OAAO,gBAAgB,EAC/B,IAAMC,EAAUC,EAAUH,EAAK,OAAO,EAChCI,EAAaF,IAAY,SAAWG,EAAmBL,CAAI,EAAI,IAAA,GACrE,GAAII,IAAe,IAAA,GACfL,EAAM,KAAK,CAAE,MAAO,CAAC,EAAG,eAAgB,GAAO,YAAW,CAAC,OACxD,GAAIG,IAAY,SAAU,CAC7B,IAAMI,EAASC,EAAYN,EAASD,CAAI,EACxCD,EAAM,KAAK,GAAGO,EAAO,YAAY,IAAI,IAAS,CAAE,MAAO,CAACA,EAAO,IAAI,EAAG,eAAgB,GAAM,WAAYE,CAAK,EAAE,CAAC,EAChHT,EAAM,KAAK,GAAGO,EAAO,SAAS,QAAQ,GAAW,UAAUG,EAAS,CAACH,EAAO,IAAI,EAAG,EAAI,CAAC,CAAC,CAC7F,MAAWJ,IAAY,UACnBH,EAAM,KAAK,GAAG,UAAUW,EAAaT,EAASD,CAAI,EAAG,CAAC,EAAG,EAAK,CAAC,EAE/DC,EAAQ,gBAAgBD,EAAK,MAAM,CAE3C,CACA,OAAOD,CACX,CAEA,SAAS,UAAU,EAAwB,EAA0B,EAA6C,CAC9G,IAAMH,EAAQ,CAAC,GAAGe,EAAOF,EAAQ,IAAI,EACrC,MAAO,CACH,GAAGA,EAAQ,YAAY,IAAI,IAAe,CAAE,QAAO,iBAAgB,YAAW,EAAE,EAChF,GAAGA,EAAQ,SAAS,QAAQ,GAAU,UAAUG,EAAQhB,EAAOiB,CAAc,CAAC,CAClF,CACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../_virtual/_virtual/_rolldown/runtime.js";import{splitLines as e}from"./Parsing/SourceLineSplitter.js";import{validateIdentity as t}from"./Parsing/IdentityValidator.js";import{validateApplicationHandlers as n}from"./Parsing/CommandHandlerValidator.js";import{recordStructuralInteractions as r}from"./Parsing/StructuralInteractionSites.js";import{expandSpecificationExamples as i,validateSpecificationExampleTypes as a}from"./Parsing/SpecificationCommandExamples.js";import{validateResponses as o}from"./Parsing/ResponseValidator.js";import{validateSpecificationCases as s}from"./Parsing/SpecificationCaseValidator.js";import{productionDestinationDiagnostics as c}from"./Diagnostics/ProductionDestinationDiagnostics.js";import{validateConstraintProperties as l}from"./Parsing/ConstraintPropertyValidator.js";import{validateDependencyDeclarations as u}from"./Dependencies/DeclaredDependencyTargets.js";import{documentPlacement as d}from"./Files/PlayPlacement.js";import{interactionAncestry as f}from"./Parsing/InteractionAlternatives.js";import"./Parsing/SpecificationParser.js";import"./Parsing/SpecificationExampleParser.js";import"./Parsing/CaptureParser.js";import"./Parsing/ProjectionParser.js";import"./Parsing/ImportDiscovery.js";import{DeclaredDependencies as
|
|
1
|
+
import"../_virtual/_virtual/_rolldown/runtime.js";import{splitLines as e}from"./Parsing/SourceLineSplitter.js";import{validateIdentity as t}from"./Parsing/IdentityValidator.js";import{validateApplicationHandlers as n}from"./Parsing/CommandHandlerValidator.js";import{recordStructuralInteractions as r}from"./Parsing/StructuralInteractionSites.js";import{expandSpecificationExamples as i,validateSpecificationExampleTypes as a}from"./Parsing/SpecificationCommandExamples.js";import{validateResponses as o}from"./Parsing/ResponseValidator.js";import{validateSpecificationCases as s}from"./Parsing/SpecificationCaseValidator.js";import{productionDestinationDiagnostics as c}from"./Diagnostics/ProductionDestinationDiagnostics.js";import{validateConstraintProperties as l}from"./Parsing/ConstraintPropertyValidator.js";import{validateDependencyDeclarations as u}from"./Dependencies/DeclaredDependencyTargets.js";import{documentPlacement as d}from"./Files/PlayPlacement.js";import{interactionAncestry as f}from"./Parsing/InteractionAlternatives.js";import"./Parsing/SpecificationParser.js";import"./Parsing/SpecificationExampleParser.js";import"./Parsing/CaptureParser.js";import"./Parsing/ProjectionParser.js";import{discoverImports as p}from"./Parsing/ImportDiscovery.js";import{DeclaredDependencies as m}from"./Dependencies/DeclaredDependencies.js";import{validatePublicEventUsage as h}from"./Parsing/PublicEventUsageValidator.js";import{sourceContext as g}from"./Parsing/SourceOptionsParser.js";import{validateInlineEvents as _}from"./Parsing/InlineEventValidator.js";import{validateOperations as v}from"./Parsing/OperationValidator.js";import{parseApplication as y}from"./Parsing/ScreenplayParser.js";import{CommandStreamCandidates as b}from"./Parsing/CommandStreamCandidates.js";import{validateEventSources as x}from"./Parsing/EventSourceValidator.js";import{validateProjectionTargets as S}from"./Parsing/ProjectionTargetValidator.js";import{validateIdentifierCompliance as C}from"./Parsing/IdentifierComplianceValidator.js";import{validateEventSubjects as w}from"./Parsing/EventSubjectValidator.js";import{validateReadModelKeys as T}from"./Parsing/ReadModelKeyValidator.js";import{validateReactionRefusals as E}from"./Parsing/ReactionRefusalValidator.js";import{validateSpecificationRedelivery as D}from"./Parsing/SpecificationRedeliveryValidator.js";import{validateGuardedActions as O}from"./Parsing/GuardedActionValidator.js";import{validatePersonaCallers as k}from"./Parsing/PersonaCallerValidator.js";import{validatePurposes as A}from"./Parsing/PurposeValidator.js";import{timelineOrderDiagnostics as j}from"./Files/TimelineOrder.js";function parseForAuthoring(p,M,N=d,P=!0,F,I){let L=e(p,!1,M),R=g(L,M,I);R.scope=N,R.interactionAncestors=f(L),R.streamCandidates=F??b.capture([L],N,I);let z=y(R,L,N);if(r(z,R),P){n(z,R),t(z,R),A(z,R),_(z,R),l(z,R),v(z,R),h(z,R),s(z,R),a(z,R,!0);let e=i(z);o(e,R),x(z,R),S(z,R),C(e,R),w(z,R),T(z,R),E(z,R),D(z,R),O(z,R),k(z,R),z=u(z,R),m.validate(z,R);for(let e of c(z))R.information(e.code,e.message,e.location);for(let e of j(z))R.information(e.code,e.message,e.location)}return{value:z,diagnostics:R.diagnostics,triggerData:R.triggerData,inputUses:R.inputUses,continuationValues:R.continuationValues,guardedInteractions:R.guardedInteractions,interactionBehaviors:R.interactionBehaviors,interactionUses:R.interactionUses,success:!R.diagnostics.some(e=>e.severity===`error`)}}function discoverImports(t,n,r){let i=e(t,!1,n);return p(g(i,n,r))}export{discoverImports,parseForAuthoring};
|
|
2
2
|
//# sourceMappingURL=ScreenplayCompiler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenplayCompiler.js","names":["documentPlacement","lines","splitLines","source","path","context","sourceContext","languages","placement","interactionAncestry","streamCandidates","CommandStreamCandidates","value","parseApplication","recordStructuralInteractions","validateResponseContracts","validateApplicationHandlers","validateIdentity","validatePurposes","validateInlineEvents","validateConstraintProperties","validateOperations","validatePublicEventUsage","validateSpecificationCases","validateSpecificationExampleTypes","effective","expandSpecificationExamples","validateResponses","validateEventSources","validateProjectionTargets","validateIdentifierCompliance","validateEventSubjects","validateReadModelKeys","validateReactionRefusals","validateSpecificationRedelivery","validateGuardedActions","validatePersonaCallers","validateDependencyDeclarations","DeclaredDependencies","diagnostic","productionDestinationDiagnostics","timelineOrderDiagnostics"],"sources":["../../../../../Compiler/ScreenplayCompiler.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 { validateIdentity } from './Parsing/IdentityValidator';\nimport { validateApplicationHandlers } from './Parsing/CommandHandlerValidator';\nimport { recordStructuralInteractions } from './Parsing/StructuralInteractionSites';\nimport { Diagnostic } from './Diagnostics/Diagnostic';\nimport { validateSpecificationCases } from './Parsing/SpecificationCaseValidator';\nimport { expandSpecificationExamples, validateSpecificationExampleTypes } from './Parsing/SpecificationCommandExamples';\nimport { productionDestinationDiagnostics } from './Diagnostics/ProductionDestinationDiagnostics';\nimport { validateConstraintProperties } from './Parsing/ConstraintPropertyValidator';\nimport { validateDependencyDeclarations } from './Dependencies/DeclaredDependencyTargets';\nimport { DeclaredDependencies } from './Dependencies/DeclaredDependencies';\nimport { documentPlacement, PlayPlacement } from './Files/PlayPlacement';\nimport { DiscoveredImport, discoverImports as discoverImportsIn } from './Parsing/ImportDiscovery';\nimport { ContinuationValueUse } from './Parsing/ContinuationValueUse';\nimport { InputUse } from './Parsing/InputUses';\nimport { GuardedInteractionBinding, interactionAncestry } from './Parsing/InteractionAlternatives';\nimport { validateResponses } from './Parsing/ResponseValidator';\nimport { validatePublicEventUsage } from './Parsing/PublicEventUsageValidator';\nimport { sourceContext } from './Parsing/SourceOptionsParser';\nimport { validateInlineEvents } from './Parsing/InlineEventValidator';\nimport { validateOperations } from './Parsing/OperationValidator';\nimport { CommandStreamCandidates } from './Parsing/CommandStreamCandidates';\nimport { validateEventSources } from './Parsing/EventSourceValidator';\nimport { validateProjectionTargets } from './Parsing/ProjectionTargetValidator';\nimport { validateIdentifierCompliance } from './Parsing/IdentifierComplianceValidator';\nimport { validateEventSubjects } from './Parsing/EventSubjectValidator';\nimport { validateReadModelKeys } from './Parsing/ReadModelKeyValidator';\nimport { validateReactionRefusals } from './Parsing/ReactionRefusalValidator';\nimport { validateSpecificationRedelivery } from './Parsing/SpecificationRedeliveryValidator';\nimport { validateGuardedActions } from './Parsing/GuardedActionValidator';\nimport { validatePersonaCallers } from './Parsing/PersonaCallerValidator';\nimport { validatePurposes } from './Parsing/PurposeValidator';\nimport { parseApplication } from './Parsing/ScreenplayParser';\nimport { splitLines } from './Parsing/SourceLineSplitter';\nimport { PropertySyntax } from './Syntax/Declarations';\nimport { ApplicationSyntax } from './Syntax/Structure';\nimport { ApplicationSyntaxVisitor } from './Syntax/Visitors';\nimport { ProjectionSyntax } from './Syntax/Projections';\nimport { CaptureSyntax } from './Syntax/Captures';\nimport { SpecificationExampleSyntax, SpecificationSyntax } from './Syntax/Specifications';\nimport { SyntaxNode } from './Syntax/SyntaxNode';\nimport { ParserContext } from './Parsing/ParserContext';\nimport { parseProjection } from './Parsing/ProjectionParser';\nimport { parseCapture } from './Parsing/CaptureParser';\nimport { parseSpecification } from './Parsing/SpecificationParser';\nimport { parseExample } from './Parsing/SpecificationExampleParser';\nimport { firstWord } from './Parsing/LineText';\nimport { SourceLine, locationOf } from './Parsing/SourceLine';\nimport { DiagnosticCodes } from './Diagnostics/DiagnosticCodes';\nimport { timelineOrderDiagnostics } from './Files/TimelineOrder';\n\n// What compiling produced: the syntax tree, and the diagnostics found on the way. A tree is always\n// produced, so a document with errors still shows everything that could be read.\nexport interface CompilationResult<T> {\n readonly value: T;\n readonly diagnostics: readonly Diagnostic[];\n readonly success: boolean;\n}\n\n// Parses one .play document - the TypeScript counterpart of the C# ScreenplayCompiler.Parse. The path, when\n// given, is carried on every source location so a folder of documents can be merged and still point back\n// at the file each node came from. A placement says the document's top level belongs to the module or\n// feature an import placed it in: that module and feature are in the tree, marked as placements, holding what\n// the document declares at its top level.\nexport function parse(source: string, path?: string, placement: PlayPlacement = documentPlacement): CompilationResult<ApplicationSyntax> {\n const { value, diagnostics, success } = parseForAuthoring(source, path, placement);\n return { value, diagnostics, success };\n}\n\n// Additive authoring view: do not widen TypeRefSyntax or the cross-compiler SyntaxJson projection.\nexport function parseForAuthoring(source: string, path?: string, placement: PlayPlacement = documentPlacement, validateResponseContracts = true, streamCandidates?: CommandStreamCandidates, languages?: ReadonlySet<string>): CompilationResult<ApplicationSyntax> & { readonly triggerData: readonly PropertySyntax[]; readonly inputUses: readonly InputUse[]; readonly continuationValues: readonly ContinuationValueUse[]; readonly guardedInteractions: readonly GuardedInteractionBinding[]; readonly interactionBehaviors: ParserContext['interactionBehaviors']; readonly interactionUses: ParserContext['interactionUses'] } {\n const lines = splitLines(source, false, path);\n const context = sourceContext(lines, path, languages);\n context.scope = placement;\n context.interactionAncestors = interactionAncestry(lines);\n context.streamCandidates = streamCandidates ?? CommandStreamCandidates.capture([lines], placement, languages);\n let value = parseApplication(context, lines, placement);\n recordStructuralInteractions(value, context);\n // Folder assembly validates declaration-dependent contracts once against the merged inventory.\n if (validateResponseContracts) {\n validateApplicationHandlers(value, context);\n validateIdentity(value, context);\n validatePurposes(value, context);\n validateInlineEvents(value, context);\n validateConstraintProperties(value, context);\n validateOperations(value, context);\n validatePublicEventUsage(value, context);\n validateSpecificationCases(value, context);\n validateSpecificationExampleTypes(value, context, true);\n const effective = expandSpecificationExamples(value);\n validateResponses(effective, context);\n validateEventSources(value, context);\n validateProjectionTargets(value, context);\n validateIdentifierCompliance(effective, context);\n validateEventSubjects(value, context);\n validateReadModelKeys(value, context);\n validateReactionRefusals(value, context);\n validateSpecificationRedelivery(value, context);\n validateGuardedActions(value, context);\n validatePersonaCallers(value, context);\n value = validateDependencyDeclarations(value, context);\n DeclaredDependencies.validate(value, context);\n for (const diagnostic of productionDestinationDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n for (const diagnostic of timelineOrderDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n }\n return {\n value,\n diagnostics: context.diagnostics,\n triggerData: context.triggerData,\n inputUses: context.inputUses,\n continuationValues: context.continuationValues,\n guardedInteractions: context.guardedInteractions,\n interactionBehaviors: context.interactionBehaviors,\n interactionUses: context.interactionUses,\n success: !context.diagnostics.some(diagnostic => diagnostic.severity === 'error'),\n };\n}\n\n/** Checks public boundaries on programmatically authored or decoded assembled syntax. */\nexport function publicEventDiagnostics(application: ApplicationSyntax): readonly Diagnostic[] {\n const context = sourceContext([], application.location.path);\n validatePublicEventUsage(application, context);\n return context.diagnostics;\n}\n\n// Parses a document and hands its syntax tree to a visitor - the counterpart of the C#\n// ScreenplayCompiler.Compile<T>(source, visitor). The visitor runs even when there are errors, over\n// everything that could be read.\nexport function compile<T>(source: string, visitor: ApplicationSyntaxVisitor<T>, path?: string): CompilationResult<T> {\n const parsed = parse(source, path);\n return { value: visitor.visit(parsed.value), diagnostics: parsed.diagnostics, success: parsed.success };\n}\n\n// Finds the files a document imports and where in it each import is written - each import with the module\n// and feature names around it, outermost first. Diagnostics are not collected; parsing the document reports them.\nexport function discoverImports(source: string, path?: string, languages?: ReadonlySet<string>): DiscoveredImport[] {\n const lines = splitLines(source, false, path);\n return discoverImportsIn(sourceContext(lines, path, languages));\n}\n\n// Additive entry points preserve the caller's registry; none can select numeric mode externally.\nexport function parseWithLanguages(source: string, languages: ReadonlySet<string>, path?: string, placement: PlayPlacement = documentPlacement): CompilationResult<ApplicationSyntax> {\n const { value, diagnostics, success } = parseForAuthoring(source, path, placement, true, undefined, languages);\n return { value, diagnostics, success };\n}\n\nexport function parseProjectionSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly ProjectionSyntax[]> {\n return parseSourceFamily(source, 'projection', parseProjection, path, languages);\n}\n\nexport function parseCaptureSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly CaptureSyntax[]> {\n return parseSourceFamily(source, 'capture', parseCapture, path, languages);\n}\n\nexport function parseSpecificationSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly SpecificationSyntax[]> {\n return parseSourceFamily(source, 'specification', parseSpecification, path, languages);\n}\n\nfunction parseSourceFamily<T extends SyntaxNode>(source: string, keyword: string, read: (context: ParserContext, line: SourceLine) => T, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly T[]> {\n const context = sourceContext(splitLines(source, true, path), path, languages, true);\n const value: T[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n if (keyword === 'specification' && firstWord(line.content) === 'example') examples.push(parseExample(context, line));\n else if (line.content.startsWith(keyword)) value.push(read(context, line));\n else {\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Expected '${keyword}', got '${line.content}'`, locationOf(line));\n context.skipOpaqueBlock(line.indent);\n }\n }\n if (context.sourceOptions.numericMode === 'exact' && value.length === 0 && context.diagnostics.length === 0) {\n const code = keyword === 'projection' ? DiagnosticCodes.ProjectionDocumentWithoutProjection : keyword === 'capture' ? DiagnosticCodes.CaptureDocumentWithoutCapture : DiagnosticCodes.SpecificationDocumentWithoutSpecification;\n context.error(code, `Document must contain at least one ${keyword}`, context.start);\n }\n const roots = keyword === 'specification' && examples.length > 0 ? value.map(node => ({ ...node, examples })) : value;\n if (keyword === 'specification') {\n const application = parseApplication(sourceContext([], path, languages), [], documentPlacement);\n validateSpecificationCases({ ...application, examples }, context, roots as unknown as SpecificationSyntax[]);\n }\n return { value: roots, diagnostics: context.diagnostics, success: !context.diagnostics.some(diagnostic => diagnostic.severity === 'error') };\n}\n"],"mappings":"sjFAwEA,SAAgB,kBAAkB,EAAgB,EAAe,EAA2BA,EAAmB,EAA4B,GAAM,EAA4C,EAA0a,CACnmB,IAAMC,EAAQC,EAAWC,EAAQ,GAAOC,CAAI,EACtCC,EAAUC,EAAcL,EAAOG,EAAMG,CAAS,EACpD,EAAQ,MAAQC,EAChB,EAAQ,qBAAuBC,EAAoBR,CAAK,EACxD,EAAQ,iBAAmBS,GAAoBC,EAAwB,QAAQ,CAACV,CAAK,EAAGO,EAAWD,CAAS,EAC5G,IAAIK,EAAQC,EAAiBR,EAASJ,EAAOO,CAAS,EAGtD,GAFAM,EAA6BF,EAAOP,CAAO,EAEvCU,EAA2B,CAC3BC,EAA4BJ,EAAOP,CAAO,EAC1CY,EAAiBL,EAAOP,CAAO,EAC/Ba,EAAiBN,EAAOP,CAAO,EAC/Bc,EAAqBP,EAAOP,CAAO,EACnCe,EAA6BR,EAAOP,CAAO,EAC3CgB,EAAmBT,EAAOP,CAAO,EACjCiB,EAAyBV,EAAOP,CAAO,EACvCkB,EAA2BX,EAAOP,CAAO,EACzCmB,EAAkCZ,EAAOP,EAAS,EAAI,EACtD,IAAMoB,EAAYC,EAA4Bd,CAAK,EACnDe,EAAkBF,EAAWpB,CAAO,EACpCuB,EAAqBhB,EAAOP,CAAO,EACnCwB,EAA0BjB,EAAOP,CAAO,EACxCyB,EAA6BL,EAAWpB,CAAO,EAC/C0B,EAAsBnB,EAAOP,CAAO,EACpC2B,EAAsBpB,EAAOP,CAAO,EACpC4B,EAAyBrB,EAAOP,CAAO,EACvC6B,EAAgCtB,EAAOP,CAAO,EAC9C8B,EAAuBvB,EAAOP,CAAO,EACrC+B,EAAuBxB,EAAOP,CAAO,EACrC,EAAQgC,EAA+BzB,EAAOP,CAAO,EACrDiC,EAAqB,SAAS1B,EAAOP,CAAO,EAC5C,IAAK,IAAMkC,KAAcC,EAAiC5B,CAAK,EAAGP,EAAQ,YAAYkC,EAAW,KAAMA,EAAW,QAASA,EAAW,QAAQ,EAC9I,IAAK,IAAMA,KAAcE,EAAyB7B,CAAK,EAAGP,EAAQ,YAAYkC,EAAW,KAAMA,EAAW,QAASA,EAAW,QAAQ,CAC1I,CACA,MAAO,CACH,QACA,YAAalC,EAAQ,YACrB,YAAaA,EAAQ,YACrB,UAAWA,EAAQ,UACnB,mBAAoBA,EAAQ,mBAC5B,oBAAqBA,EAAQ,oBAC7B,qBAAsBA,EAAQ,qBAC9B,gBAAiBA,EAAQ,gBACzB,QAAS,CAACA,EAAQ,YAAY,KAAK,GAAckC,EAAW,WAAa,OAAO,CACpF,CACJ"}
|
|
1
|
+
{"version":3,"file":"ScreenplayCompiler.js","names":["discoverImportsIn","discoverImports$1","documentPlacement","lines","splitLines","source","path","context","sourceContext","languages","placement","interactionAncestry","streamCandidates","CommandStreamCandidates","value","parseApplication","recordStructuralInteractions","validateResponseContracts","validateApplicationHandlers","validateIdentity","validatePurposes","validateInlineEvents","validateConstraintProperties","validateOperations","validatePublicEventUsage","validateSpecificationCases","validateSpecificationExampleTypes","effective","expandSpecificationExamples","validateResponses","validateEventSources","validateProjectionTargets","validateIdentifierCompliance","validateEventSubjects","validateReadModelKeys","validateReactionRefusals","validateSpecificationRedelivery","validateGuardedActions","validatePersonaCallers","validateDependencyDeclarations","DeclaredDependencies","diagnostic","productionDestinationDiagnostics","timelineOrderDiagnostics"],"sources":["../../../../../Compiler/ScreenplayCompiler.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 { validateIdentity } from './Parsing/IdentityValidator';\nimport { validateApplicationHandlers } from './Parsing/CommandHandlerValidator';\nimport { recordStructuralInteractions } from './Parsing/StructuralInteractionSites';\nimport { Diagnostic } from './Diagnostics/Diagnostic';\nimport { validateSpecificationCases } from './Parsing/SpecificationCaseValidator';\nimport { expandSpecificationExamples, validateSpecificationExampleTypes } from './Parsing/SpecificationCommandExamples';\nimport { productionDestinationDiagnostics } from './Diagnostics/ProductionDestinationDiagnostics';\nimport { validateConstraintProperties } from './Parsing/ConstraintPropertyValidator';\nimport { validateDependencyDeclarations } from './Dependencies/DeclaredDependencyTargets';\nimport { DeclaredDependencies } from './Dependencies/DeclaredDependencies';\nimport { documentPlacement, PlayPlacement } from './Files/PlayPlacement';\nimport { DiscoveredImport, discoverImports as discoverImportsIn } from './Parsing/ImportDiscovery';\nimport { ContinuationValueUse } from './Parsing/ContinuationValueUse';\nimport { InputUse } from './Parsing/InputUses';\nimport { GuardedInteractionBinding, interactionAncestry } from './Parsing/InteractionAlternatives';\nimport { validateResponses } from './Parsing/ResponseValidator';\nimport { validatePublicEventUsage } from './Parsing/PublicEventUsageValidator';\nimport { sourceContext } from './Parsing/SourceOptionsParser';\nimport { validateInlineEvents } from './Parsing/InlineEventValidator';\nimport { validateOperations } from './Parsing/OperationValidator';\nimport { CommandStreamCandidates } from './Parsing/CommandStreamCandidates';\nimport { validateEventSources } from './Parsing/EventSourceValidator';\nimport { validateProjectionTargets } from './Parsing/ProjectionTargetValidator';\nimport { validateIdentifierCompliance } from './Parsing/IdentifierComplianceValidator';\nimport { validateEventSubjects } from './Parsing/EventSubjectValidator';\nimport { validateReadModelKeys } from './Parsing/ReadModelKeyValidator';\nimport { validateReactionRefusals } from './Parsing/ReactionRefusalValidator';\nimport { validateSpecificationRedelivery } from './Parsing/SpecificationRedeliveryValidator';\nimport { validateGuardedActions } from './Parsing/GuardedActionValidator';\nimport { validatePersonaCallers } from './Parsing/PersonaCallerValidator';\nimport { validatePurposes } from './Parsing/PurposeValidator';\nimport { parseApplication } from './Parsing/ScreenplayParser';\nimport { splitLines } from './Parsing/SourceLineSplitter';\nimport { PropertySyntax } from './Syntax/Declarations';\nimport { ApplicationSyntax } from './Syntax/Structure';\nimport { ApplicationSyntaxVisitor } from './Syntax/Visitors';\nimport { ProjectionSyntax } from './Syntax/Projections';\nimport { CaptureSyntax } from './Syntax/Captures';\nimport { SpecificationExampleSyntax, SpecificationSyntax } from './Syntax/Specifications';\nimport { SyntaxNode } from './Syntax/SyntaxNode';\nimport { ParserContext } from './Parsing/ParserContext';\nimport { parseProjection } from './Parsing/ProjectionParser';\nimport { parseCapture } from './Parsing/CaptureParser';\nimport { parseSpecification } from './Parsing/SpecificationParser';\nimport { parseExample } from './Parsing/SpecificationExampleParser';\nimport { firstWord } from './Parsing/LineText';\nimport { SourceLine, locationOf } from './Parsing/SourceLine';\nimport { DiagnosticCodes } from './Diagnostics/DiagnosticCodes';\nimport { timelineOrderDiagnostics } from './Files/TimelineOrder';\n\n// What compiling produced: the syntax tree, and the diagnostics found on the way. A tree is always\n// produced, so a document with errors still shows everything that could be read.\nexport interface CompilationResult<T> {\n readonly value: T;\n readonly diagnostics: readonly Diagnostic[];\n readonly success: boolean;\n}\n\n// Parses one .play document - the TypeScript counterpart of the C# ScreenplayCompiler.Parse. The path, when\n// given, is carried on every source location so a folder of documents can be merged and still point back\n// at the file each node came from. A placement says the document's top level belongs to the module or\n// feature an import placed it in: that module and feature are in the tree, marked as placements, holding what\n// the document declares at its top level.\nexport function parse(source: string, path?: string, placement: PlayPlacement = documentPlacement): CompilationResult<ApplicationSyntax> {\n const { value, diagnostics, success } = parseForAuthoring(source, path, placement);\n return { value, diagnostics, success };\n}\n\n// Additive authoring view: do not widen TypeRefSyntax or the cross-compiler SyntaxJson projection.\nexport function parseForAuthoring(source: string, path?: string, placement: PlayPlacement = documentPlacement, validateResponseContracts = true, streamCandidates?: CommandStreamCandidates, languages?: ReadonlySet<string>): CompilationResult<ApplicationSyntax> & { readonly triggerData: readonly PropertySyntax[]; readonly inputUses: readonly InputUse[]; readonly continuationValues: readonly ContinuationValueUse[]; readonly guardedInteractions: readonly GuardedInteractionBinding[]; readonly interactionBehaviors: ParserContext['interactionBehaviors']; readonly interactionUses: ParserContext['interactionUses'] } {\n const lines = splitLines(source, false, path);\n const context = sourceContext(lines, path, languages);\n context.scope = placement;\n context.interactionAncestors = interactionAncestry(lines);\n context.streamCandidates = streamCandidates ?? CommandStreamCandidates.capture([lines], placement, languages);\n let value = parseApplication(context, lines, placement);\n recordStructuralInteractions(value, context);\n // Folder assembly validates declaration-dependent contracts once against the merged inventory.\n if (validateResponseContracts) {\n validateApplicationHandlers(value, context);\n validateIdentity(value, context);\n validatePurposes(value, context);\n validateInlineEvents(value, context);\n validateConstraintProperties(value, context);\n validateOperations(value, context);\n validatePublicEventUsage(value, context);\n validateSpecificationCases(value, context);\n validateSpecificationExampleTypes(value, context, true);\n const effective = expandSpecificationExamples(value);\n validateResponses(effective, context);\n validateEventSources(value, context);\n validateProjectionTargets(value, context);\n validateIdentifierCompliance(effective, context);\n validateEventSubjects(value, context);\n validateReadModelKeys(value, context);\n validateReactionRefusals(value, context);\n validateSpecificationRedelivery(value, context);\n validateGuardedActions(value, context);\n validatePersonaCallers(value, context);\n value = validateDependencyDeclarations(value, context);\n DeclaredDependencies.validate(value, context);\n for (const diagnostic of productionDestinationDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n for (const diagnostic of timelineOrderDiagnostics(value)) context.information(diagnostic.code, diagnostic.message, diagnostic.location);\n }\n return {\n value,\n diagnostics: context.diagnostics,\n triggerData: context.triggerData,\n inputUses: context.inputUses,\n continuationValues: context.continuationValues,\n guardedInteractions: context.guardedInteractions,\n interactionBehaviors: context.interactionBehaviors,\n interactionUses: context.interactionUses,\n success: !context.diagnostics.some(diagnostic => diagnostic.severity === 'error'),\n };\n}\n\n/** Checks public boundaries on programmatically authored or decoded assembled syntax. */\nexport function publicEventDiagnostics(application: ApplicationSyntax): readonly Diagnostic[] {\n const context = sourceContext([], application.location.path);\n validatePublicEventUsage(application, context);\n return context.diagnostics;\n}\n\n// Parses a document and hands its syntax tree to a visitor - the counterpart of the C#\n// ScreenplayCompiler.Compile<T>(source, visitor). The visitor runs even when there are errors, over\n// everything that could be read.\nexport function compile<T>(source: string, visitor: ApplicationSyntaxVisitor<T>, path?: string): CompilationResult<T> {\n const parsed = parse(source, path);\n return { value: visitor.visit(parsed.value), diagnostics: parsed.diagnostics, success: parsed.success };\n}\n\n// Finds the files a document imports and where in it each import is written - each import with the module\n// and feature names around it, outermost first. Diagnostics are not collected; parsing the document reports them.\nexport function discoverImports(source: string, path?: string, languages?: ReadonlySet<string>): DiscoveredImport[] {\n const lines = splitLines(source, false, path);\n return discoverImportsIn(sourceContext(lines, path, languages));\n}\n\n// Additive entry points preserve the caller's registry; none can select numeric mode externally.\nexport function parseWithLanguages(source: string, languages: ReadonlySet<string>, path?: string, placement: PlayPlacement = documentPlacement): CompilationResult<ApplicationSyntax> {\n const { value, diagnostics, success } = parseForAuthoring(source, path, placement, true, undefined, languages);\n return { value, diagnostics, success };\n}\n\nexport function parseProjectionSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly ProjectionSyntax[]> {\n return parseSourceFamily(source, 'projection', parseProjection, path, languages);\n}\n\nexport function parseCaptureSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly CaptureSyntax[]> {\n return parseSourceFamily(source, 'capture', parseCapture, path, languages);\n}\n\nexport function parseSpecificationSource(source: string, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly SpecificationSyntax[]> {\n return parseSourceFamily(source, 'specification', parseSpecification, path, languages);\n}\n\nfunction parseSourceFamily<T extends SyntaxNode>(source: string, keyword: string, read: (context: ParserContext, line: SourceLine) => T, path?: string, languages?: ReadonlySet<string>): CompilationResult<readonly T[]> {\n const context = sourceContext(splitLines(source, true, path), path, languages, true);\n const value: T[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n if (keyword === 'specification' && firstWord(line.content) === 'example') examples.push(parseExample(context, line));\n else if (line.content.startsWith(keyword)) value.push(read(context, line));\n else {\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Expected '${keyword}', got '${line.content}'`, locationOf(line));\n context.skipOpaqueBlock(line.indent);\n }\n }\n if (context.sourceOptions.numericMode === 'exact' && value.length === 0 && context.diagnostics.length === 0) {\n const code = keyword === 'projection' ? DiagnosticCodes.ProjectionDocumentWithoutProjection : keyword === 'capture' ? DiagnosticCodes.CaptureDocumentWithoutCapture : DiagnosticCodes.SpecificationDocumentWithoutSpecification;\n context.error(code, `Document must contain at least one ${keyword}`, context.start);\n }\n const roots = keyword === 'specification' && examples.length > 0 ? value.map(node => ({ ...node, examples })) : value;\n if (keyword === 'specification') {\n const application = parseApplication(sourceContext([], path, languages), [], documentPlacement);\n validateSpecificationCases({ ...application, examples }, context, roots as unknown as SpecificationSyntax[]);\n }\n return { value: roots, diagnostics: context.diagnostics, success: !context.diagnostics.some(diagnostic => diagnostic.severity === 'error') };\n}\n"],"mappings":"glFAwEA,SAAgB,kBAAkB,EAAgB,EAAe,EAA2BE,EAAmB,EAA4B,GAAM,EAA4C,EAA0a,CACnmB,IAAMC,EAAQC,EAAWC,EAAQ,GAAOC,CAAI,EACtCC,EAAUC,EAAcL,EAAOG,EAAMG,CAAS,EACpD,EAAQ,MAAQC,EAChB,EAAQ,qBAAuBC,EAAoBR,CAAK,EACxD,EAAQ,iBAAmBS,GAAoBC,EAAwB,QAAQ,CAACV,CAAK,EAAGO,EAAWD,CAAS,EAC5G,IAAIK,EAAQC,EAAiBR,EAASJ,EAAOO,CAAS,EAGtD,GAFAM,EAA6BF,EAAOP,CAAO,EAEvCU,EAA2B,CAC3BC,EAA4BJ,EAAOP,CAAO,EAC1CY,EAAiBL,EAAOP,CAAO,EAC/Ba,EAAiBN,EAAOP,CAAO,EAC/Bc,EAAqBP,EAAOP,CAAO,EACnCe,EAA6BR,EAAOP,CAAO,EAC3CgB,EAAmBT,EAAOP,CAAO,EACjCiB,EAAyBV,EAAOP,CAAO,EACvCkB,EAA2BX,EAAOP,CAAO,EACzCmB,EAAkCZ,EAAOP,EAAS,EAAI,EACtD,IAAMoB,EAAYC,EAA4Bd,CAAK,EACnDe,EAAkBF,EAAWpB,CAAO,EACpCuB,EAAqBhB,EAAOP,CAAO,EACnCwB,EAA0BjB,EAAOP,CAAO,EACxCyB,EAA6BL,EAAWpB,CAAO,EAC/C0B,EAAsBnB,EAAOP,CAAO,EACpC2B,EAAsBpB,EAAOP,CAAO,EACpC4B,EAAyBrB,EAAOP,CAAO,EACvC6B,EAAgCtB,EAAOP,CAAO,EAC9C8B,EAAuBvB,EAAOP,CAAO,EACrC+B,EAAuBxB,EAAOP,CAAO,EACrC,EAAQgC,EAA+BzB,EAAOP,CAAO,EACrDiC,EAAqB,SAAS1B,EAAOP,CAAO,EAC5C,IAAK,IAAMkC,KAAcC,EAAiC5B,CAAK,EAAGP,EAAQ,YAAYkC,EAAW,KAAMA,EAAW,QAASA,EAAW,QAAQ,EAC9I,IAAK,IAAMA,KAAcE,EAAyB7B,CAAK,EAAGP,EAAQ,YAAYkC,EAAW,KAAMA,EAAW,QAASA,EAAW,QAAQ,CAC1I,CACA,MAAO,CACH,QACA,YAAalC,EAAQ,YACrB,YAAaA,EAAQ,YACrB,UAAWA,EAAQ,UACnB,mBAAoBA,EAAQ,mBAC5B,oBAAqBA,EAAQ,oBAC7B,qBAAsBA,EAAQ,qBAC9B,gBAAiBA,EAAQ,gBACzB,QAAS,CAACA,EAAQ,YAAY,KAAK,GAAckC,EAAW,WAAa,OAAO,CACpF,CACJ,CAmBA,SAAgB,gBAAgB,EAAgB,EAAe,EAAqD,CAChH,IAAMtC,EAAQC,EAAWC,EAAQ,GAAOC,CAAI,EAC5C,OAAON,EAAkBQ,EAAcL,EAAOG,EAAMG,CAAS,CAAC,CAClE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DiagnosticCodes as e}from"./Diagnostics/DiagnosticCodes.js";import"./Parsing/checkPortableMatchPattern.js";import{unescapeString as t}from"./Text/StringLiteral.js";import{pattern as n}from"./Text/patterns.js";import{sourceLocation as r}from"./Diagnostics/SourceLocation.js";import{eventDeclarations as i}from"./Syntax/EventDeclarations.js";import{operationDeclarations as a}from"./Syntax/Operations.js";import{AuthoringProductionResolver as o}from"./Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as s}from"./Syntax/DependencySources.js";import{ScreenplaySyntaxWalker as c}from"./Syntax/ScreenplaySyntaxWalker.js";import{isExactNumberToken as l,parseExactNumber as u}from"./Syntax/ExactNumber.js";import{diagnosticKeyword as d,diagnosticText as f}from"./Diagnostics/DiagnosticArgument.js";import{EventSourceCatalog as p}from"./Syntax/EventSourceCatalog.js";import{implicitDestination as m,requiresExplicitDestinations as h}from"./Syntax/ProductionDestinations.js";import{InvalidExactNumber as g,canonicalExactText as _,exactIsIntegral as v}from"./Syntax/ExactMathFacts.js";import{responseCommandResolver as y}from"./Parsing/ResponseCommandResolver.js";import{synthesizePersonaCaller as b}from"./Syntax/PersonaCallers.js";import"./Syntax/SpecificationCaseOrigin.js";import"./Parsing/SpecificationCommandExamples.js";import{DeclaredDependencyTargets as x}from"./Dependencies/DeclaredDependencyTargets.js";import{describePlacement as S,documentPlacement as C,isDocumentPlacement as w}from"./Files/PlayPlacement.js";import"./Syntax/InvalidSyntaxJson.js";import"./Syntax/SourceOptions.js";import{isSourceStreamName as
|
|
1
|
+
import{DiagnosticCodes as e}from"./Diagnostics/DiagnosticCodes.js";import"./Parsing/checkPortableMatchPattern.js";import{unescapeString as t}from"./Text/StringLiteral.js";import{pattern as n}from"./Text/patterns.js";import{sourceLocation as r}from"./Diagnostics/SourceLocation.js";import{eventDeclarations as i}from"./Syntax/EventDeclarations.js";import{operationDeclarations as a}from"./Syntax/Operations.js";import{AuthoringProductionResolver as o}from"./Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as s}from"./Syntax/DependencySources.js";import{ScreenplaySyntaxWalker as c}from"./Syntax/ScreenplaySyntaxWalker.js";import{isExactNumberToken as l,parseExactNumber as u}from"./Syntax/ExactNumber.js";import{diagnosticKeyword as d,diagnosticText as f}from"./Diagnostics/DiagnosticArgument.js";import{EventSourceCatalog as p}from"./Syntax/EventSourceCatalog.js";import{implicitDestination as m,requiresExplicitDestinations as h}from"./Syntax/ProductionDestinations.js";import{InvalidExactNumber as g,canonicalExactText as _,exactIsIntegral as v}from"./Syntax/ExactMathFacts.js";import{responseCommandResolver as y}from"./Parsing/ResponseCommandResolver.js";import{synthesizePersonaCaller as b}from"./Syntax/PersonaCallers.js";import"./Syntax/SpecificationCaseOrigin.js";import"./Parsing/SpecificationCommandExamples.js";import{DeclaredDependencyTargets as x}from"./Dependencies/DeclaredDependencyTargets.js";import{describePlacement as S,documentPlacement as C,isDocumentPlacement as w,isWithinOrSame as T,samePlacement as E}from"./Files/PlayPlacement.js";import"./Syntax/InvalidSyntaxJson.js";import"./Syntax/SourceOptions.js";import{isSourceStreamName as D,isSourceStreamTypeName as O,sourceStreamPattern as k}from"./Text/SourceStreamNames.js";import{sliceTypes as A}from"./Syntax/Structure.js";import{consumedEvents as j,eventsSourceKind as M,fromSetting as N,isEventsSource as P}from"./Syntax/CaptureEventsSource.js";import{eventBodyReservedWords as F}from"./Text/ReservedWords.js";import{hasWildcard as I,matchesPlayPattern as L,normalizePlayPath as R,resolvePlayPattern as z,staticFolderOf as B}from"./Files/PlayGlob.js";import"./Files/AuthoredOrder.js";import{dependencyKinds as V}from"./Dependencies/DependencyKind.js";import{InvalidDependencyQuery as H}from"./Dependencies/InvalidDependencyQuery.js";import{SliceReferenceCollector as U,buildingReadModelReferences as W,referenceClassifications as G,sliceReferences as K}from"./Dependencies/SliceReferences.js";import{stronglyConnectedGroups as q}from"./Dependencies/StronglyConnectedGroups.js";import{DependencyGraph as J}from"./Dependencies/DependencyGraph.js";import{streamIdFailureMessage as Y,tryFormatInteger as X,tryFormatText as Z,tryFormatUuidText as Q}from"./Syntax/StreamIdFormatter.js";import{discoverImports as $,parseForAuthoring as ee}from"./ScreenplayCompiler.js";import{EventSourceReadConfidence as te}from"./Syntax/EventSourceReadConfidence.js";import"./Syntax/SyntaxJson.js";import{mergeDocuments as ne}from"./Files/PlayFolderMerge.js";import{inMemoryDocumentSource as re}from"./Files/PlayDocumentSource.js";import{resolveImports as ie}from"./Files/PlayImports.js";import"./Files/OrderingRoot.js";import{assembleApplication as ae,compileApplication as oe,parsePlacedDocuments as se}from"./Files/PlayApplicationAssembly.js";import{applyQuickFixEdits as ce,isQuickFixDiagnostic as le,legacyOptionalTypeLength as ue,prepareQuickFixes as de}from"./Authoring/QuickFixes.js";import"./Completeness/ModelCompleteness.js";import"./Dependencies/index.js";import"./Syntax/index.js";export{o as AuthoringProductionResolver,x as DeclaredDependencyTargets,J as DependencyGraph,e as DiagnosticCodes,p as EventSourceCatalog,te as EventSourceReadConfidence,H as InvalidDependencyQuery,g as InvalidExactNumber,c as ScreenplaySyntaxWalker,U as SliceReferenceCollector,ce as applyQuickFixEdits,ae as assembleApplication,W as buildingReadModelReferences,_ as canonicalExactText,oe as compileApplication,j as consumedEvents,V as dependencyKinds,s as dependencySourcesOf,S as describePlacement,d as diagnosticKeyword,f as diagnosticText,$ as discoverImports,C as documentPlacement,F as eventBodyReservedWords,i as eventDeclarations,M as eventsSourceKind,v as exactIsIntegral,N as fromSetting,I as hasWildcard,m as implicitDestination,re as inMemoryDocumentSource,w as isDocumentPlacement,P as isEventsSource,l as isExactNumberToken,le as isQuickFixDiagnostic,D as isSourceStreamName,O as isSourceStreamTypeName,T as isWithinOrSame,ue as legacyOptionalTypeLength,L as matchesPlayPattern,ne as mergeDocuments,R as normalizePlayPath,a as operationDeclarations,u as parseExactNumber,ee as parseForAuthoring,se as parsePlacedDocuments,n as pattern,de as prepareQuickFixes,G as referenceClassifications,h as requiresExplicitDestinations,ie as resolveImports,z as resolvePlayPattern,y as responseCommandResolver,E as samePlacement,K as sliceReferences,A as sliceTypes,r as sourceLocation,k as sourceStreamPattern,B as staticFolderOf,Y as streamIdFailureMessage,q as stronglyConnectedGroups,b as synthesizePersonaCaller,X as tryFormatInteger,Z as tryFormatText,Q as tryFormatUuidText,t as unescapeString};
|
package/dist/code-actions.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { languages } from 'monaco-editor';
|
|
2
|
-
export declare function createCodeActionProvider(placement?: readonly string[]): languages.CodeActionProvider;
|
|
1
|
+
import type { editor, languages } from 'monaco-editor';
|
|
2
|
+
export declare function createCodeActionProvider(placement?: readonly string[], applicationModels?: () => ReadonlyMap<string, editor.ITextModel>): languages.CodeActionProvider;
|
|
3
3
|
//# sourceMappingURL=code-actions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-actions.d.ts","sourceRoot":"","sources":["../code-actions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"code-actions.d.ts","sourceRoot":"","sources":["../code-actions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAU,SAAS,EAAE,MAAM,eAAe,CAAC;AAe/D,wBAAgB,wBAAwB,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,iBAAiB,CAAC,EAAE,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,kBAAkB,CAsDtK"}
|
package/package.json
CHANGED