@fazelstudio/floe 1.0.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/LICENSE +21 -0
- package/dist/src/cli/check.d.ts +14 -0
- package/dist/src/cli/check.d.ts.map +1 -0
- package/dist/src/cli/check.js +88 -0
- package/dist/src/cli/check.js.map +1 -0
- package/dist/src/cli/format.d.ts +9 -0
- package/dist/src/cli/format.d.ts.map +1 -0
- package/dist/src/cli/format.js +114 -0
- package/dist/src/cli/format.js.map +1 -0
- package/dist/src/cli/main.d.ts +19 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +207 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/render.d.ts +7 -0
- package/dist/src/cli/render.d.ts.map +1 -0
- package/dist/src/cli/render.js +90 -0
- package/dist/src/cli/render.js.map +1 -0
- package/dist/src/diagnostics.d.ts +32 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +4 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/index.d.ts +40 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +64 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/language/completion.d.ts +6 -0
- package/dist/src/language/completion.d.ts.map +1 -0
- package/dist/src/language/completion.js +363 -0
- package/dist/src/language/completion.js.map +1 -0
- package/dist/src/language/definitions.d.ts +9 -0
- package/dist/src/language/definitions.d.ts.map +1 -0
- package/dist/src/language/definitions.js +70 -0
- package/dist/src/language/definitions.js.map +1 -0
- package/dist/src/language/diagnosticsService.d.ts +14 -0
- package/dist/src/language/diagnosticsService.d.ts.map +1 -0
- package/dist/src/language/diagnosticsService.js +37 -0
- package/dist/src/language/diagnosticsService.js.map +1 -0
- package/dist/src/language/folding.d.ts +8 -0
- package/dist/src/language/folding.d.ts.map +1 -0
- package/dist/src/language/folding.js +58 -0
- package/dist/src/language/folding.js.map +1 -0
- package/dist/src/language/formatting.d.ts +5 -0
- package/dist/src/language/formatting.d.ts.map +1 -0
- package/dist/src/language/formatting.js +274 -0
- package/dist/src/language/formatting.js.map +1 -0
- package/dist/src/language/highlighting.d.ts +9 -0
- package/dist/src/language/highlighting.d.ts.map +1 -0
- package/dist/src/language/highlighting.js +74 -0
- package/dist/src/language/highlighting.js.map +1 -0
- package/dist/src/language/hover.d.ts +6 -0
- package/dist/src/language/hover.d.ts.map +1 -0
- package/dist/src/language/hover.js +197 -0
- package/dist/src/language/hover.js.map +1 -0
- package/dist/src/language/indentation.d.ts +15 -0
- package/dist/src/language/indentation.d.ts.map +1 -0
- package/dist/src/language/indentation.js +97 -0
- package/dist/src/language/indentation.js.map +1 -0
- package/dist/src/language/index.d.ts +54 -0
- package/dist/src/language/index.d.ts.map +1 -0
- package/dist/src/language/index.js +85 -0
- package/dist/src/language/index.js.map +1 -0
- package/dist/src/language/references.d.ts +12 -0
- package/dist/src/language/references.d.ts.map +1 -0
- package/dist/src/language/references.js +35 -0
- package/dist/src/language/references.js.map +1 -0
- package/dist/src/language/rename.d.ts +18 -0
- package/dist/src/language/rename.d.ts.map +1 -0
- package/dist/src/language/rename.js +53 -0
- package/dist/src/language/rename.js.map +1 -0
- package/dist/src/language/semanticModel.d.ts +21 -0
- package/dist/src/language/semanticModel.d.ts.map +1 -0
- package/dist/src/language/semanticModel.js +43 -0
- package/dist/src/language/semanticModel.js.map +1 -0
- package/dist/src/language/symbols.d.ts +9 -0
- package/dist/src/language/symbols.d.ts.map +1 -0
- package/dist/src/language/symbols.js +160 -0
- package/dist/src/language/symbols.js.map +1 -0
- package/dist/src/language/types.d.ts +49 -0
- package/dist/src/language/types.d.ts.map +1 -0
- package/dist/src/language/types.js +2 -0
- package/dist/src/language/types.js.map +1 -0
- package/dist/src/language/utils.d.ts +24 -0
- package/dist/src/language/utils.d.ts.map +1 -0
- package/dist/src/language/utils.js +154 -0
- package/dist/src/language/utils.js.map +1 -0
- package/dist/src/layout/dagre.d.ts +13 -0
- package/dist/src/layout/dagre.d.ts.map +1 -0
- package/dist/src/layout/dagre.js +229 -0
- package/dist/src/layout/dagre.js.map +1 -0
- package/dist/src/layout/index.d.ts +15 -0
- package/dist/src/layout/index.d.ts.map +1 -0
- package/dist/src/layout/index.js +22 -0
- package/dist/src/layout/index.js.map +1 -0
- package/dist/src/layout/simple.d.ts +20 -0
- package/dist/src/layout/simple.d.ts.map +1 -0
- package/dist/src/layout/simple.js +674 -0
- package/dist/src/layout/simple.js.map +1 -0
- package/dist/src/layout/types.d.ts +65 -0
- package/dist/src/layout/types.d.ts.map +1 -0
- package/dist/src/layout/types.js +2 -0
- package/dist/src/layout/types.js.map +1 -0
- package/dist/src/lexer.d.ts +25 -0
- package/dist/src/lexer.d.ts.map +1 -0
- package/dist/src/lexer.js +280 -0
- package/dist/src/lexer.js.map +1 -0
- package/dist/src/lsp/documents.d.ts +24 -0
- package/dist/src/lsp/documents.d.ts.map +1 -0
- package/dist/src/lsp/documents.js +97 -0
- package/dist/src/lsp/documents.js.map +1 -0
- package/dist/src/lsp/server.d.ts +70 -0
- package/dist/src/lsp/server.d.ts.map +1 -0
- package/dist/src/lsp/server.js +623 -0
- package/dist/src/lsp/server.js.map +1 -0
- package/dist/src/lsp/utils.d.ts +47 -0
- package/dist/src/lsp/utils.d.ts.map +1 -0
- package/dist/src/lsp/utils.js +142 -0
- package/dist/src/lsp/utils.js.map +1 -0
- package/dist/src/parser.d.ts +106 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/parser.js +1018 -0
- package/dist/src/parser.js.map +1 -0
- package/dist/src/pipeline.d.ts +51 -0
- package/dist/src/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline.js +65 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/range.d.ts +24 -0
- package/dist/src/range.d.ts.map +1 -0
- package/dist/src/range.js +20 -0
- package/dist/src/range.js.map +1 -0
- package/dist/src/render/index.d.ts +3 -0
- package/dist/src/render/index.d.ts.map +1 -0
- package/dist/src/render/index.js +3 -0
- package/dist/src/render/index.js.map +1 -0
- package/dist/src/render/shapes.d.ts +20 -0
- package/dist/src/render/shapes.d.ts.map +1 -0
- package/dist/src/render/shapes.js +110 -0
- package/dist/src/render/shapes.js.map +1 -0
- package/dist/src/render/svg.d.ts +19 -0
- package/dist/src/render/svg.d.ts.map +1 -0
- package/dist/src/render/svg.js +227 -0
- package/dist/src/render/svg.js.map +1 -0
- package/dist/src/security/url.d.ts +7 -0
- package/dist/src/security/url.d.ts.map +1 -0
- package/dist/src/security/url.js +27 -0
- package/dist/src/security/url.js.map +1 -0
- package/dist/src/types.d.ts +111 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +16 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/validator.d.ts +47 -0
- package/dist/src/validator.d.ts.map +1 -0
- package/dist/src/validator.js +235 -0
- package/dist/src/validator.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,wBAAgB,IAAI,CAClB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GACX,UAAU,CAEZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAgDA,MAAM,UAAU,IAAI,CAClB,QAAkB,EAClB,IAAoB,EACpB,OAAe,EACf,KAAY;IAEZ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floe — Diagram DSL public API (v1.0 stable)
|
|
3
|
+
*
|
|
4
|
+
* Core language does not depend on CodeMirror, React, Vue, DOM, SVG, Canvas, Dagre, ELK, or LSP.
|
|
5
|
+
* This entry point re-exports pure language primitives.
|
|
6
|
+
* Language services are editor-independent (see src/language/).
|
|
7
|
+
*
|
|
8
|
+
* Stability: exports listed under "Stable Public API" in docs/api.md are semver-stable.
|
|
9
|
+
* Exports marked @internal are deprecated and may be hidden in 2.0 — prefer stable wrappers.
|
|
10
|
+
*/
|
|
11
|
+
export type { Position, Range } from "./range.js";
|
|
12
|
+
export { rangeToString } from "./range.js";
|
|
13
|
+
export type { Diagnostic, DiagnosticCode, Severity } from "./diagnostics.js";
|
|
14
|
+
export type { Direction, FloeDiagram, FloeNode, FloeEdge, FloeGroup, FloeAnnotation, FloeLink, EdgeKind, ParseResult, } from "./types.js";
|
|
15
|
+
export { DEFAULT_DIRECTION, DIRECTIONS, IDENTIFIER_RE, isValidIdentifier, } from "./types.js";
|
|
16
|
+
export { Lexer, tokenize, type Token, type TokenType } from "./lexer.js";
|
|
17
|
+
export { Parser, parse as parseRaw, parseRaw as parseRawFloe } from "./parser.js";
|
|
18
|
+
export { validate, type ValidationInput, type ValidationResult } from "./validator.js";
|
|
19
|
+
import type { ParseResult } from "./types.js";
|
|
20
|
+
/**
|
|
21
|
+
* @stable
|
|
22
|
+
* Parse Floe source with full pipeline:
|
|
23
|
+
* 1. lexical analysis
|
|
24
|
+
* 2. grammar-based parsing (with source ranges, error recovery)
|
|
25
|
+
* 3. semantic validation (separate phase)
|
|
26
|
+
*
|
|
27
|
+
* Never throws on malformed input — returns diagnostics instead.
|
|
28
|
+
* This is the recommended entry point (stable).
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseFloe(source: string): ParseResult;
|
|
31
|
+
/**
|
|
32
|
+
* Alias: `parse` is the validated entry as well for ergonomics.
|
|
33
|
+
* For raw (without validation) use `parseRaw` / `parseRawFloe`.
|
|
34
|
+
*/
|
|
35
|
+
export declare const parse: typeof parseFloe;
|
|
36
|
+
export declare function isValid(source: string): boolean;
|
|
37
|
+
export { getHighlightTokens, getHighlightingInfo, getCompletions, getDiagnostics, getDiagnosticsWithSource, lint, getHover, getSymbols, getFlatSymbols, getDefinition, getDefinitionForWord, getReferences, getReferencesForWord, rename, renameWord, applyEdits, format, isFormatted, getIndentForLine, getIndentationInfo, getIndentationColumn, DEFAULT_INDENT, getFoldingRanges, getFoldingInfo, buildSemanticModel, getSemanticModel, } from "./language/index.js";
|
|
38
|
+
export type { CompletionItem, HoverInfo, SymbolKind, SymbolInformation, Location, TextEdit, FoldingRange, HighlightToken, FormattingOptions, SemanticModel, } from "./language/index.js";
|
|
39
|
+
export { FloeLanguageService, floeLanguageService } from "./language/index.js";
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG7E,YAAY,EACV,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAgBrD;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,kBAAY,CAAC;AAG/B,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG/C;AAMD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floe — Diagram DSL public API (v1.0 stable)
|
|
3
|
+
*
|
|
4
|
+
* Core language does not depend on CodeMirror, React, Vue, DOM, SVG, Canvas, Dagre, ELK, or LSP.
|
|
5
|
+
* This entry point re-exports pure language primitives.
|
|
6
|
+
* Language services are editor-independent (see src/language/).
|
|
7
|
+
*
|
|
8
|
+
* Stability: exports listed under "Stable Public API" in docs/api.md are semver-stable.
|
|
9
|
+
* Exports marked @internal are deprecated and may be hidden in 2.0 — prefer stable wrappers.
|
|
10
|
+
*/
|
|
11
|
+
export { rangeToString } from "./range.js"; // utility, stable
|
|
12
|
+
export { DEFAULT_DIRECTION, DIRECTIONS, IDENTIFIER_RE, isValidIdentifier, } from "./types.js";
|
|
13
|
+
// ── Stable: high-level parse API ──
|
|
14
|
+
// parseFloe is the recommended entry; parse is alias; parseRaw is raw without validation (stable).
|
|
15
|
+
// Parser class and Lexer are low-level and considered @internal/low-level (still exported for tooling compat).
|
|
16
|
+
export { Lexer, tokenize } from "./lexer.js"; // @internal low-level
|
|
17
|
+
export { Parser, parse as parseRaw, parseRaw as parseRawFloe } from "./parser.js"; // @internal low-level: prefer parseRaw() function
|
|
18
|
+
export { validate } from "./validator.js"; // @internal: validation is internal phase, use parseFloe()
|
|
19
|
+
import { Parser } from "./parser.js";
|
|
20
|
+
import { validate } from "./validator.js";
|
|
21
|
+
/**
|
|
22
|
+
* @stable
|
|
23
|
+
* Parse Floe source with full pipeline:
|
|
24
|
+
* 1. lexical analysis
|
|
25
|
+
* 2. grammar-based parsing (with source ranges, error recovery)
|
|
26
|
+
* 3. semantic validation (separate phase)
|
|
27
|
+
*
|
|
28
|
+
* Never throws on malformed input — returns diagnostics instead.
|
|
29
|
+
* This is the recommended entry point (stable).
|
|
30
|
+
*/
|
|
31
|
+
export function parseFloe(source) {
|
|
32
|
+
const raw = new Parser(source).parse();
|
|
33
|
+
const validated = validate({
|
|
34
|
+
diagram: raw.diagram,
|
|
35
|
+
diagnostics: raw.diagnostics,
|
|
36
|
+
explicitNodes: raw.explicitNodes,
|
|
37
|
+
edges: raw.edges,
|
|
38
|
+
directionDeclarations: raw.directionDeclarations,
|
|
39
|
+
groups: raw.groups,
|
|
40
|
+
annotations: raw.annotations,
|
|
41
|
+
links: raw.links,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
diagram: validated.diagram,
|
|
45
|
+
diagnostics: validated.diagnostics,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Alias: `parse` is the validated entry as well for ergonomics.
|
|
50
|
+
* For raw (without validation) use `parseRaw` / `parseRawFloe`.
|
|
51
|
+
*/
|
|
52
|
+
export const parse = parseFloe;
|
|
53
|
+
// Convenience: check if source is valid (no error diagnostics)
|
|
54
|
+
export function isValid(source) {
|
|
55
|
+
const { diagnostics } = parseFloe(source);
|
|
56
|
+
return diagnostics.every((d) => d.severity !== "error");
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Language Tooling — editor-independent language services (stable)
|
|
60
|
+
// Re-export explicit stable surface instead of wildcard to avoid leaking internals.
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
export { getHighlightTokens, getHighlightingInfo, getCompletions, getDiagnostics, getDiagnosticsWithSource, lint, getHover, getSymbols, getFlatSymbols, getDefinition, getDefinitionForWord, getReferences, getReferencesForWord, rename, renameWord, applyEdits, format, isFormatted, getIndentForLine, getIndentationInfo, getIndentationColumn, DEFAULT_INDENT, getFoldingRanges, getFoldingInfo, buildSemanticModel, getSemanticModel, } from "./language/index.js";
|
|
63
|
+
export { FloeLanguageService, floeLanguageService } from "./language/index.js";
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC,CAAC,kBAAkB;AAgB9D,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,qCAAqC;AACrC,mGAAmG;AACnG,+GAA+G;AAC/G,OAAO,EAAE,KAAK,EAAE,QAAQ,EAA8B,MAAM,YAAY,CAAC,CAAC,sBAAsB;AAEhG,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC,CAAC,kDAAkD;AAErI,OAAO,EAAE,QAAQ,EAA+C,MAAM,gBAAgB,CAAC,CAAC,2DAA2D;AAEnJ,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,QAAQ,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,qBAAqB,EAAE,GAAG,CAAC,qBAAqB;QAChD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC;IACH,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;KACnC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC;AAE/B,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,8EAA8E;AAC9E,mEAAmE;AACnE,oFAAoF;AACpF,8EAA8E;AAC9E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/language/completion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkDjD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAwS/E"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { tokenize } from "../lexer.js";
|
|
2
|
+
import { getTokenBeforeOffset, getTokenAtOffset, positionAt } from "./utils.js";
|
|
3
|
+
import { Parser } from "../parser.js";
|
|
4
|
+
import { validate } from "../validator.js";
|
|
5
|
+
function parseFloe(source) {
|
|
6
|
+
const raw = new Parser(source).parse();
|
|
7
|
+
const validated = validate({
|
|
8
|
+
diagram: raw.diagram,
|
|
9
|
+
diagnostics: raw.diagnostics,
|
|
10
|
+
explicitNodes: raw.explicitNodes,
|
|
11
|
+
edges: raw.edges,
|
|
12
|
+
directionDeclarations: raw.directionDeclarations,
|
|
13
|
+
groups: raw.groups,
|
|
14
|
+
annotations: raw.annotations,
|
|
15
|
+
links: raw.links,
|
|
16
|
+
});
|
|
17
|
+
return { diagram: validated.diagram, diagnostics: validated.diagnostics };
|
|
18
|
+
}
|
|
19
|
+
const DIRECTIONS = ["TB", "BT", "LR", "RL"];
|
|
20
|
+
const KNOWN_TYPES = [
|
|
21
|
+
"person",
|
|
22
|
+
"service",
|
|
23
|
+
"database",
|
|
24
|
+
"client",
|
|
25
|
+
"subsystem",
|
|
26
|
+
"external",
|
|
27
|
+
"system",
|
|
28
|
+
"container",
|
|
29
|
+
"component",
|
|
30
|
+
"queue",
|
|
31
|
+
"store",
|
|
32
|
+
"gateway",
|
|
33
|
+
];
|
|
34
|
+
const TOP_LEVEL_KEYWORDS = ["direction", "group", "meta", "note", "link"];
|
|
35
|
+
function prefixFilter(items, prefix) {
|
|
36
|
+
if (!prefix)
|
|
37
|
+
return items;
|
|
38
|
+
const lower = prefix.toLowerCase();
|
|
39
|
+
return items.filter((i) => i.label.toLowerCase().startsWith(lower));
|
|
40
|
+
}
|
|
41
|
+
function getPrefixAtOffset(source, offset) {
|
|
42
|
+
let start = offset;
|
|
43
|
+
while (start > 0 && /[A-Za-z0-9_-]/.test(source[start - 1]))
|
|
44
|
+
start--;
|
|
45
|
+
return source.slice(start, offset);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Context-aware completion — operates on semantic model, not random.
|
|
49
|
+
*/
|
|
50
|
+
export function getCompletions(source, offset) {
|
|
51
|
+
const tokens = tokenize(source);
|
|
52
|
+
const before = getTokenBeforeOffset(tokens, offset);
|
|
53
|
+
const at = getTokenAtOffset(tokens, offset);
|
|
54
|
+
const pos = positionAt(source, offset);
|
|
55
|
+
const textBefore = source.slice(0, offset);
|
|
56
|
+
const prefix = getPrefixAtOffset(source, offset);
|
|
57
|
+
// If inside string or comment, no completions (avoid invalid syntax)
|
|
58
|
+
if (at && (at.type === "STRING" || at.type === "COMMENT")) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
// Helper to detect context requiring completion
|
|
62
|
+
const trimmedBefore = textBefore.trimEnd();
|
|
63
|
+
const lines = source.slice(0, offset).split(/\r?\n/);
|
|
64
|
+
const currentLinePrefix = lines[lines.length - 1] ?? "";
|
|
65
|
+
const trimmedLine = currentLinePrefix.trimStart();
|
|
66
|
+
// 1) After "direction" keyword => suggest directions
|
|
67
|
+
// Detect if last keyword before offset is "direction" and no direction value yet consumed
|
|
68
|
+
// Check tokens: look backward for nearest DIRECTION_KW not followed by IDENT before offset
|
|
69
|
+
{
|
|
70
|
+
// Find last DIRECTION_KW before offset
|
|
71
|
+
let lastDirIdx = -1;
|
|
72
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
73
|
+
const t = tokens[i];
|
|
74
|
+
if (t.type === "DIRECTION_KW" && t.range.end.offset <= offset)
|
|
75
|
+
lastDirIdx = i;
|
|
76
|
+
}
|
|
77
|
+
if (lastDirIdx !== -1) {
|
|
78
|
+
const dirTok = tokens[lastDirIdx];
|
|
79
|
+
// Check tokens after direction until offset: if there is no IDENT after it (direction value) then suggest
|
|
80
|
+
let hasValue = false;
|
|
81
|
+
let valueToken;
|
|
82
|
+
for (let i = lastDirIdx + 1; i < tokens.length; i++) {
|
|
83
|
+
const t = tokens[i];
|
|
84
|
+
if (t.range.start.offset >= offset)
|
|
85
|
+
break;
|
|
86
|
+
if (t.type === "NEWLINE" || t.type === "COMMENT")
|
|
87
|
+
break;
|
|
88
|
+
if (t.type === "IDENT" || t.type === "UNKNOWN") {
|
|
89
|
+
hasValue = true;
|
|
90
|
+
valueToken = t;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!hasValue) {
|
|
95
|
+
const items = DIRECTIONS.map((d) => ({
|
|
96
|
+
label: d,
|
|
97
|
+
kind: "value",
|
|
98
|
+
detail: "direction",
|
|
99
|
+
}));
|
|
100
|
+
// When cursor is directly after keyword (offset at token end), prefix is empty for value completion
|
|
101
|
+
// Don't use keyword prefix; check if we are inside a partial value token at cursor
|
|
102
|
+
let valuePrefix = "";
|
|
103
|
+
if (at && at.type === "IDENT" && at.range.start.offset > dirTok.range.end.offset) {
|
|
104
|
+
valuePrefix = source.slice(at.range.start.offset, offset);
|
|
105
|
+
}
|
|
106
|
+
else if (at && at.type === "UNKNOWN" && at.range.start.offset > dirTok.range.end.offset) {
|
|
107
|
+
valuePrefix = source.slice(at.range.start.offset, offset);
|
|
108
|
+
}
|
|
109
|
+
return prefixFilter(items, valuePrefix);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// hasValue true: user may be editing the existing direction value token (partial)
|
|
113
|
+
// Handle cursor inside or right after valueToken (at may be undefined when at token end)
|
|
114
|
+
if (valueToken) {
|
|
115
|
+
const idx = tokens.indexOf(valueToken);
|
|
116
|
+
const prevIsDir = idx > 0 && tokens[idx - 1]?.type === "DIRECTION_KW";
|
|
117
|
+
if (prevIsDir && offset >= valueToken.range.start.offset && offset <= valueToken.range.end.offset + 1) {
|
|
118
|
+
const valuePrefix = source.slice(valueToken.range.start.offset, offset);
|
|
119
|
+
const items = DIRECTIONS.map((d) => ({
|
|
120
|
+
label: d,
|
|
121
|
+
kind: "value",
|
|
122
|
+
detail: "direction",
|
|
123
|
+
}));
|
|
124
|
+
return prefixFilter(items, valuePrefix);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Fallback for at being IDENT (when offset inside token)
|
|
128
|
+
if (at && at.type === "IDENT") {
|
|
129
|
+
// check previous token is DIRECTION_KW or this token is the value token
|
|
130
|
+
const isValueToken = valueToken && at.range.start.offset === valueToken.range.start.offset;
|
|
131
|
+
const prevIsDir = (() => {
|
|
132
|
+
const idx = tokens.indexOf(at);
|
|
133
|
+
return idx > 0 && tokens[idx - 1]?.type === "DIRECTION_KW";
|
|
134
|
+
})();
|
|
135
|
+
if (isValueToken || prevIsDir) {
|
|
136
|
+
const items = DIRECTIONS.map((d) => ({
|
|
137
|
+
label: d,
|
|
138
|
+
kind: "value",
|
|
139
|
+
detail: "direction",
|
|
140
|
+
}));
|
|
141
|
+
// Use value token prefix, not keyword prefix
|
|
142
|
+
const valuePrefix = source.slice(at.range.start.offset, offset);
|
|
143
|
+
return prefixFilter(items, valuePrefix);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (at && at.type === "UNKNOWN" && valueToken && at.range.start.offset === valueToken.range.start.offset) {
|
|
147
|
+
const items = DIRECTIONS.map((d) => ({
|
|
148
|
+
label: d,
|
|
149
|
+
kind: "value",
|
|
150
|
+
detail: "direction",
|
|
151
|
+
}));
|
|
152
|
+
const valuePrefix = source.slice(at.range.start.offset, offset);
|
|
153
|
+
return prefixFilter(items, valuePrefix);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Also if currentLinePrefix trimmed is exactly "direction" or "direction " etc, or prefix is part of "direction" keyword? handle typo? but not needed
|
|
158
|
+
// Direct textual check: if trimmedBefore endsWith "direction" (keyword not yet completed + space)
|
|
159
|
+
if (trimmedBefore.endsWith("direction") && !trimmedBefore.endsWith("direction ")) {
|
|
160
|
+
// cursor right after keyword without space — also suggest directions after space? but we suggest directions
|
|
161
|
+
// Provide directions anyway
|
|
162
|
+
// Actually spec example: After "direction\n" suggest TB etc — means after keyword on next line? Wait example:
|
|
163
|
+
// After:
|
|
164
|
+
// direction
|
|
165
|
+
// suggest TB etc -> means line is "direction" with no value, next line maybe? Or same line start?
|
|
166
|
+
// Interpret as after typing "direction" and awaiting value
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// 2) Inside brackets [ _ ] — suggest known node types
|
|
170
|
+
// Detect if previous non-whitespace char before offset is "[" or inside bracket context
|
|
171
|
+
{
|
|
172
|
+
// Find last LBRACKET before offset not closed before offset
|
|
173
|
+
// Simple: look backward for LBRACKET, check if not followed by RBRACKET before offset
|
|
174
|
+
let lastLbIdx = -1;
|
|
175
|
+
let lastRbIdx = -1;
|
|
176
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
177
|
+
const t = tokens[i];
|
|
178
|
+
if (t.range.end.offset > offset)
|
|
179
|
+
break;
|
|
180
|
+
if (t.type === "LBRACKET")
|
|
181
|
+
lastLbIdx = i;
|
|
182
|
+
if (t.type === "RBRACKET")
|
|
183
|
+
lastRbIdx = i;
|
|
184
|
+
}
|
|
185
|
+
if (lastLbIdx !== -1 && lastLbIdx > lastRbIdx) {
|
|
186
|
+
// Inside brackets
|
|
187
|
+
const items = KNOWN_TYPES.map((t) => ({
|
|
188
|
+
label: t,
|
|
189
|
+
kind: "type",
|
|
190
|
+
detail: "node type",
|
|
191
|
+
}));
|
|
192
|
+
return prefixFilter(items, prefix);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// 3) After edge operator -> or -- => suggest node ids (existing nodes)
|
|
196
|
+
{
|
|
197
|
+
// Find last ARROW/DASHDASH before offset that is on same line and no target yet
|
|
198
|
+
let lastOpIdx = -1;
|
|
199
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
200
|
+
const t = tokens[i];
|
|
201
|
+
if (t.range.end.offset <= offset && (t.type === "ARROW" || t.type === "DASHDASH")) {
|
|
202
|
+
lastOpIdx = i;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
if (t.type === "NEWLINE" && t.range.start.offset < offset) {
|
|
206
|
+
// crossed line, but maybe edge is multiline? Floe is single line per statement, so break
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (lastOpIdx !== -1) {
|
|
211
|
+
const opTok = tokens[lastOpIdx];
|
|
212
|
+
// Check if there is already a target IDENT after op before offset and before newline
|
|
213
|
+
let hasTarget = false;
|
|
214
|
+
for (let i = lastOpIdx + 1; i < tokens.length; i++) {
|
|
215
|
+
const t = tokens[i];
|
|
216
|
+
if (t.range.start.offset >= offset)
|
|
217
|
+
break;
|
|
218
|
+
if (t.type === "NEWLINE" || t.type === "COMMENT" || t.type === "RBRACE")
|
|
219
|
+
break;
|
|
220
|
+
if (t.type === "IDENT") {
|
|
221
|
+
// Could be target but if prefix exists we still want to suggest? If at is IDENT (partial target) we should suggest filtered node ids
|
|
222
|
+
hasTarget = true;
|
|
223
|
+
// But if we are currently typing target (at is IDENT), we should still suggest
|
|
224
|
+
if (at && at.type === "IDENT" && at.range.start.offset > opTok.range.end.offset) {
|
|
225
|
+
hasTarget = false; // still completing target
|
|
226
|
+
}
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (!hasTarget) {
|
|
231
|
+
// Suggest existing node ids + group ids
|
|
232
|
+
try {
|
|
233
|
+
const { diagram } = parseFloe(source);
|
|
234
|
+
const ids = diagram.nodes.map((n) => n.id);
|
|
235
|
+
// also groups
|
|
236
|
+
const collectGroups = (gs) => {
|
|
237
|
+
const out = [];
|
|
238
|
+
for (const g of gs) {
|
|
239
|
+
out.push(g.id);
|
|
240
|
+
out.push(...collectGroups(g.groups));
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
};
|
|
244
|
+
const groupIds = collectGroups(diagram.groups);
|
|
245
|
+
const allIds = Array.from(new Set([...ids, ...groupIds]));
|
|
246
|
+
const items = allIds.map((id) => ({
|
|
247
|
+
label: id,
|
|
248
|
+
kind: "variable",
|
|
249
|
+
detail: "node",
|
|
250
|
+
}));
|
|
251
|
+
if (items.length === 0) {
|
|
252
|
+
// Fallback suggest placeholder?
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
return prefixFilter(items, prefix);
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return [];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// 4) At line start or after newline => suggest top-level keywords + existing ids for edge sources?
|
|
264
|
+
// Check if current line prefix after trimStart is empty or is partial keyword
|
|
265
|
+
{
|
|
266
|
+
const lineTrim = trimmedLine;
|
|
267
|
+
// If line is empty or starts with partial identifier that could be keyword
|
|
268
|
+
if (lineTrim === "" || /^[A-Za-z]*$/.test(prefix) && lineTrim.length <= prefix.length + 10) {
|
|
269
|
+
// Determine if we are at start of statement (beginning of line)
|
|
270
|
+
// Suggest keywords
|
|
271
|
+
const keywordItems = TOP_LEVEL_KEYWORDS.map((k) => ({
|
|
272
|
+
label: k,
|
|
273
|
+
kind: "keyword",
|
|
274
|
+
detail: "keyword",
|
|
275
|
+
}));
|
|
276
|
+
// Also suggest existing node ids as potential edge sources? Might be useful
|
|
277
|
+
// But to avoid random, we only suggest keywords at line start; user can type edge from existing node by typing its id
|
|
278
|
+
// For now, suggest keywords filtered by prefix, plus maybe direction values if after direction? already handled
|
|
279
|
+
// Include node types? No
|
|
280
|
+
// For broader completions, include existing ids as well when prefix matches?
|
|
281
|
+
// Let's include node ids when prefix is not empty and not a keyword prefix?
|
|
282
|
+
// Better: if prefix empty, suggest keywords; if prefix matches keyword start, filter keywords; else also suggest node ids
|
|
283
|
+
const filteredKeywords = prefixFilter(keywordItems, prefix);
|
|
284
|
+
if (filteredKeywords.length > 0) {
|
|
285
|
+
// Also consider suggesting node ids if requested? But keep deterministic
|
|
286
|
+
// Include node ids as secondary if keyword filter yields many? Keep just keywords for top-level start
|
|
287
|
+
return filteredKeywords;
|
|
288
|
+
}
|
|
289
|
+
// If no keyword matches, fallback to suggest node ids (useful for edge source completion at line start)
|
|
290
|
+
if (prefix.length > 0) {
|
|
291
|
+
try {
|
|
292
|
+
const { diagram } = parseFloe(source);
|
|
293
|
+
const ids = Array.from(new Set(diagram.nodes.map((n) => n.id)));
|
|
294
|
+
const idItems = ids.map((id) => ({
|
|
295
|
+
label: id,
|
|
296
|
+
kind: "variable",
|
|
297
|
+
detail: "node id",
|
|
298
|
+
}));
|
|
299
|
+
const filteredIds = prefixFilter(idItems, prefix);
|
|
300
|
+
if (filteredIds.length > 0)
|
|
301
|
+
return filteredIds;
|
|
302
|
+
}
|
|
303
|
+
catch { }
|
|
304
|
+
}
|
|
305
|
+
return filteredKeywords;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// 5) After "group" keyword — expecting group id? Could suggest?
|
|
309
|
+
{
|
|
310
|
+
if (before && before.type === "GROUP_KW") {
|
|
311
|
+
return []; // expecting new identifier, no suggestion
|
|
312
|
+
}
|
|
313
|
+
if (trimmedBefore.endsWith("group") || trimmedBefore.match(/\bgroup\s+$/)) {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// 6) After "meta", "note", "link" etc — suggest identifiers
|
|
318
|
+
{
|
|
319
|
+
if (before && before.type === "META_KW") {
|
|
320
|
+
// meta key — suggest? no
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
if (before && before.type === "NOTE_KW") {
|
|
324
|
+
// note [target] — suggest existing ids
|
|
325
|
+
try {
|
|
326
|
+
const { diagram } = parseFloe(source);
|
|
327
|
+
const ids = Array.from(new Set([...diagram.nodes.map((n) => n.id), ...collectGroupIds(diagram.groups)]));
|
|
328
|
+
const items = ids.map((id) => ({
|
|
329
|
+
label: id,
|
|
330
|
+
kind: "variable",
|
|
331
|
+
detail: "note target",
|
|
332
|
+
}));
|
|
333
|
+
// Also suggest string? But not needed
|
|
334
|
+
if (items.length > 0)
|
|
335
|
+
return prefixFilter(items, prefix);
|
|
336
|
+
}
|
|
337
|
+
catch { }
|
|
338
|
+
}
|
|
339
|
+
if (before && before.type === "LINK_KW") {
|
|
340
|
+
try {
|
|
341
|
+
const { diagram } = parseFloe(source);
|
|
342
|
+
const ids = Array.from(new Set([...diagram.nodes.map((n) => n.id), ...collectGroupIds(diagram.groups)]));
|
|
343
|
+
const items = ids.map((id) => ({
|
|
344
|
+
label: id,
|
|
345
|
+
kind: "variable",
|
|
346
|
+
detail: "link target",
|
|
347
|
+
}));
|
|
348
|
+
return prefixFilter(items, prefix);
|
|
349
|
+
}
|
|
350
|
+
catch { }
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return [];
|
|
354
|
+
}
|
|
355
|
+
function collectGroupIds(groups) {
|
|
356
|
+
const out = [];
|
|
357
|
+
for (const g of groups) {
|
|
358
|
+
out.push(g.id);
|
|
359
|
+
out.push(...collectGroupIds(g.groups));
|
|
360
|
+
}
|
|
361
|
+
return out;
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/language/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Location } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Definitions — a node declaration should be identifiable.
|
|
4
|
+
* Given offset, find definition location of symbol at that offset.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getDefinition(source: string, offset: number): Location | null;
|
|
7
|
+
/** For testing: get definition for a given word directly */
|
|
8
|
+
export declare function getDefinitionForWord(source: string, word: string): Location | null;
|
|
9
|
+
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/language/definitions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmB3C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4B7E;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAOlF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { tokenize } from "../lexer.js";
|
|
2
|
+
import { getTokenAtOffset } from "./utils.js";
|
|
3
|
+
import { Parser } from "../parser.js";
|
|
4
|
+
import { validate } from "../validator.js";
|
|
5
|
+
function parseFloe(source) {
|
|
6
|
+
const raw = new Parser(source).parse();
|
|
7
|
+
const validated = validate({
|
|
8
|
+
diagram: raw.diagram,
|
|
9
|
+
diagnostics: raw.diagnostics,
|
|
10
|
+
explicitNodes: raw.explicitNodes,
|
|
11
|
+
edges: raw.edges,
|
|
12
|
+
directionDeclarations: raw.directionDeclarations,
|
|
13
|
+
groups: raw.groups,
|
|
14
|
+
annotations: raw.annotations,
|
|
15
|
+
links: raw.links,
|
|
16
|
+
});
|
|
17
|
+
return { diagram: validated.diagram, diagnostics: validated.diagnostics };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Definitions — a node declaration should be identifiable.
|
|
21
|
+
* Given offset, find definition location of symbol at that offset.
|
|
22
|
+
*/
|
|
23
|
+
export function getDefinition(source, offset) {
|
|
24
|
+
const tokens = tokenize(source);
|
|
25
|
+
const tok = getTokenAtOffset(tokens, offset);
|
|
26
|
+
if (!tok || tok.type !== "IDENT")
|
|
27
|
+
return null;
|
|
28
|
+
const id = tok.lexeme;
|
|
29
|
+
const { diagram } = parseFloe(source);
|
|
30
|
+
// Search explicit nodes first
|
|
31
|
+
const node = diagram.nodes.find((n) => n.id === id);
|
|
32
|
+
if (node) {
|
|
33
|
+
return { range: node.range };
|
|
34
|
+
}
|
|
35
|
+
// Search groups
|
|
36
|
+
const grp = findGroup(diagram.groups, id);
|
|
37
|
+
if (grp) {
|
|
38
|
+
return { range: grp.range };
|
|
39
|
+
}
|
|
40
|
+
// If not found as node/group but appears as edge source/target implicit, definition could be first occurrence?
|
|
41
|
+
// Fallback: find first token with same lexeme
|
|
42
|
+
for (const t of tokens) {
|
|
43
|
+
if (t.type === "IDENT" && t.lexeme === id) {
|
|
44
|
+
return { range: t.range };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/** For testing: get definition for a given word directly */
|
|
50
|
+
export function getDefinitionForWord(source, word) {
|
|
51
|
+
const { diagram } = parseFloe(source);
|
|
52
|
+
const node = diagram.nodes.find((n) => n.id === word);
|
|
53
|
+
if (node)
|
|
54
|
+
return { range: node.range };
|
|
55
|
+
const grp = findGroup(diagram.groups, word);
|
|
56
|
+
if (grp)
|
|
57
|
+
return { range: grp.range };
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
function findGroup(groups, id) {
|
|
61
|
+
for (const g of groups) {
|
|
62
|
+
if (g.id === id)
|
|
63
|
+
return g;
|
|
64
|
+
const child = findGroup(g.groups, id);
|
|
65
|
+
if (child)
|
|
66
|
+
return child;
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../../src/language/definitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Diagnostic } from "../diagnostics.js";
|
|
2
|
+
/**
|
|
3
|
+
* Diagnostics API — useful while document is incomplete.
|
|
4
|
+
* Should produce recoverable diagnostic rather than crashing.
|
|
5
|
+
* Example: "User ->" should produce E009/E006 not throw.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDiagnostics(source: string): Diagnostic[];
|
|
8
|
+
export declare function getDiagnosticsWithSource(source: string): {
|
|
9
|
+
diagnostics: Diagnostic[];
|
|
10
|
+
hasErrors: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** For LSP/CodeMirror lint integration — returns diagnostics sorted */
|
|
13
|
+
export declare function lint(source: string): Diagnostic[];
|
|
14
|
+
//# sourceMappingURL=diagnosticsService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnosticsService.d.ts","sourceRoot":"","sources":["../../../src/language/diagnosticsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAmBpD;;;;GAIG;AAEH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAG3D;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAM1G;AAED,uEAAuE;AACvE,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAEjD"}
|