feat(model): a workspace copy rooted at a library's packages is the library - #301
Merged
Merged
Conversation
…ibrary The language server treated a copy of a bundled library file as the user's document (derived ids, a minting action on every declaration) where the RDF mapping recognised the same bytes as the library. The roots-based recognition moves from internal/core/export to internal/core/identity (LibraryRoot, Catalog.DocumentRootedAt, LibraryVersion) and the workspace applies it: a qualifying document displaces the bundled file from the index, carries its tier and the copy's digest, keeps normative identity and offers no mint action; editing a root so it no longer qualifies, or closing a version whose on-disk text is the user's, restores the bundled file. Closing a file opened under a bundled file's own name now restores that file too; before, nothing was put back and later documents were checked against a library missing it. With the whole library present the standard-library expression gate reports nine dimension defects in the published SI.sysml and USCustomaryUnits.sysml, pinned as an exact set and recorded in docs/project/omg-issues.md; the library bytes are unchanged. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
An edit judged in a stand-in's own document was validated over an index that still held the bundled file the stand-in displaces: siblingIndexLocked only removed the bundled file for other stand-ins, and the edit engine then added the edited copy beside it, so the package and its members were declared twice and valid edits were rejected or resolved against the wrong declaration. edit.Model gains an Indexed hook, called after each document the edit adds to its index. The workspace supplies standInOverLocked, which applies the live stand-in rule to that index from the edited roots: a copy that is still a version of a bundled file displaces it and carries its tier; a copy that stopped qualifying gets the bundled file back. Tests: renaming a datatype inside a standing copy is accepted and the reference beside it follows; the validator's index holds exactly the edited copy while it qualifies and the bundled file once a root is renamed or its library keywords are dropped. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ame leaves it indexed A stand-in for a bundled library file removed that file's index key without checking whether a workspace document held the name, so opening a version beside a buffer opened under the bundled path dropped the buffer from name resolution and diagnostics, and closing the version did not bring it back. The workspace and the edit validator's index now leave a document holding the bundled name where it is; the version stands beside it, and the bundled file comes back only once neither is open. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…rts naming it Removing the last version of a bundled file re-expands wildcard imports while the file is still absent, and re-adding it does not expand them again, so a package importing it lost the names until the next edit. The restore, in the workspace and in the index an edit is judged in, now expands imports once the file is back. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…dex holds An edit with several operations is judged in one index, re-fed each rewrite in turn. The rule that displaces a bundled library file for a version of it, and restores the file when the version moves off the library's roots, read what the workspace's documents stand in for; an earlier rewrite in the same edit may already have moved the index's own. The index now carries its own stand-ins from the workspace's and moves them with each rewrite, so a copy that an intermediate rewrite rooted at the library's package and a later one moved off again is judged with the bundled file back in place. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…text, not their names An unchanged version of a bundled file standing in under a workspace name changed LibraryIdentity, so the runtime dropped every library-backed shape it could have carried across a re-analysis. The identity now digests each library document's tier and text digest only. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md
…fecycle A workspace over NewWorkspaceWithIndex skipped displaceLocked, restoreLocked, libraryVersionLocked and the edit validator's stand-in tracking whenever it had no frozen library base, so a document opened under a marked library file's name removed that file for good when closed, and a copy rooted at its package was never recognised as a version. The workspace now snapshots every marked library file (root, language, mark) at construction, restores from that snapshot, and judges versions against a catalog of a library-only index built once on demand; IdentityOf reads a displaced file from the same index. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library files An edit's temporary index overlays the frozen base and then re-indexes only what the base does not hold, so documents a caller added to its overlay, marked or not, survive ApplyEdit's validation. The library catalog records every library document's top-level packages apart from its normative elements, so a file MarkLibrary marks at the generic tier, which has no normative language, is still matched and restored as a version. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ary is what the index shows A document is a version of a library file only in that file's language: text of a .kerml file under a .sysml name was parsed as SysML, so it stays the user's file and the bundled file stays. The library-alone catalog reuses the frozen base only when it holds exactly the library files the index shows, so a file an overlay shadows under a base name is recognised by its own roots. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…entity digests the language The edit validator's temporary index overlays the frozen base, so a document the caller's overlay replaced under the base's name was taken from the base: an edit beside it resolved OldTanks where the workspace shows Tanks. The base is now trusted for a name only when it holds the document as the workspace's index shows it (root, language, library record). LibraryIdentity digested each library document's tier and text only; the generic tier states no language and AddDocumentWithKind allows any, so the same bytes parsed as KerML and as SysML agreed on an identity. The language now joins the digest; the document's name still does not. Co-Authored-By: jason.han <hanhuijun@gmail.com>
… neither file Catalog.roots kept whichever file's top-level package was catalogued last, so a copy rooted at a package two marked library files share displaced one of them arbitrarily. RootNamed and DocumentRootedAt now find no document for such a name; the copy is the user's file and both library files stay. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…shows LibraryCatalog shares a frozen base's catalog only with an overlay that holds the base's library documents as the base does; one that shadows, removes or adds a library document gets a catalog of what it shows, so LibraryVersion recognises a copy of the shown package and not one of the shadowed. Workspace.LibraryDocument classifies a name before consulting its cache. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Open may take a bundled name between LibraryDocument's read and write locks; the name is classified again before the bundled file is loaded so a name the workspace now holds answers nil. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…hat file LibraryVersion reads the library its index holds apart from the judged document: over a base, the base's file of that name stands where the copy does, so a copy of a library file indexed under the file's name is its version whether or not its bytes are the file's. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…ked files baseHoldsLibrary reused the frozen base whenever its marked files matched the library, so an unmarked base file the overlay removed — one annotating a library element — still reached a displaced library file's identity. Any unmarked base file now sends libraryAlone to build the index from the library files. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md # internal/core/model/edit.go # internal/core/model/workspace.go
…ce does Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…s languages Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…library-version Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/core/model/edit.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
The language server treated a workspace copy of a bundled library file as the user's document — derived ids, a minting code action on every declaration — where
sysml -convertrecognised the same bytes as the library. The workspace now applies the one recognition, so a copy rooted at a library's packages is the library in the editor as it is on the CLI.internal/core/exporttointernal/core/identity(LibraryRoot,Catalog.DocumentRootedAt,Catalog.NamesEveryRoot,LibraryVersion);export/library_names.godelegates to it and RDF behaviour is unchanged. A document qualifies when every root is a top-level package of one bundled library file that either states that package's normative id or is declared as the library declares it (library/standardkeywords). Nested library elements, a foreign root id, or roots from different bundled files do not qualify.model/library_version.go,workspace.go): a qualifying document displaces the bundled file from the overlay index, is marked with the bundled tier and its own digest, and its declarations are what the library's names resolve to.IdentityOfanswers normative identity for it (and, viaresolverOver(w.libBase), still for a displaced bundled file). Editing a root so it stops qualifying, closing a version whose on-disk text is the user's, or removing it restores the bundled file; several copies may coexist, and the sibling index used byApplyEditmirrors the arrangement.Closeremoved the document and put nothing back, so every later document was checked against a library missing it.TestExprTypeCheckNoStdlibFalsePositivespassed on develop only because of this: with the whole library present, the checker reports nine dimension defects in the publishedSI.sysmlandUSCustomaryUnits.sysml(e.g.'Sv/s' : DoseEquivalentUnit,J*s*eV*s : TotalAngularMomentumUnit,229835/900 [K]). Each is verified against theISQdefinitions and recorded indocs/project/omg-issues.md("Defects in the vendored quantity libraries"); the gate pins them as an exact set — an extra finding fails as a false positive, a missing one as a regression — andTestExprTypeCheckStdlibFindingsNeedTheLibraryproves the library survives the close. Library bytes are untouched.internal/interop/reposync/diff.gowas inspected and needs no change: it does not consume the workspace-vs-library classification.Specification basis
No specification clause moves; this is editor/CLI consistency over the project's own normative-identity rules (
docs/reference/rdf-mapping.md, now naming the shared recognition for both surfaces). The nine library findings rest on SysML v2.0 §9.8.9.1 (dimension of a bound value) and, for229835/900 [K], KerML 1.0 §8.2.5.8.1–8.2.5.8.2 (the bracket construction is a primary expression), the same reading already adjudicated for the geometry example.How it was verified
internal/core/model/library_version_test.go(qualifying copy stands in, normative identity, no library-package or duplicate-name diagnostics, multiple copies, root rename / keyword drop / foreign id stop qualification, normative explicit id qualifies without keywords, close follows on-disk text, delete releases, nested-only / mixed / cross-file roots do not qualify,ApplyEditthrough a standing copy, the exact-bundled-name case);identity/pilot_library_xmi_test.gocoversDocumentRootedAt;internal/lsp/identity_test.goandhover_test.goexpect(normative, KerML)hover and no mint action on a qualifying copy, and mint on a non-qualifying user file.go build ./...,go vet ./...,gofmt -l .(empty),go test -count=1 ./...,make lint— all green.OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 go test -count=1 ./internal/core/model -run 'TestTrainingExamples|TestPilotCorpora'and./internal/core/export -run TestCorpusRoundTrip— green, no ratchet movement.python3 scripts/changelog.py check,scripts/check-doc-ids.py,scripts/check-doc-links.py,make docs-counts— green (test counts regenerated).Checklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelog