Skip to content

fix: resolve a model reference in a model target by model ID - #231

Open
sergej-koscejev wants to merge 1 commit into
mainfrom
claude/strange-moser-a1e813
Open

sergej-koscejev wants to merge 1 commit into
mainfrom
claude/strange-moser-a1e813

Conversation

@sergej-koscejev

Copy link
Copy Markdown
Member

Summary

A Model Target that is a serialized Model Reference now resolves by model ID. Before, mops compared the exact printed reference text, so a reference with an out-of-date name in parentheses (for example after a model rename) failed with "model not found", while the same reference worked as a search scope.

 matchingModels(target)
-  keep models where name.value == target
-                 or printed reference == target
+  if target has a model ID with a type designator (r:, f:, path:, java:, …; optional moduleId/ prefix)
+    resolve the reference by model ID in the repository   // missing → MODEL_NOT_FOUND, no name fallback
+  else
+    keep models where name.value == target                 // more than one → AMBIGUOUS_TARGET, as before

Text without a type designator is a model name and never reaches MPS's createModelReference, which would read it as a name-based model ID. mops does not support name-based model IDs.

The check lives in one helper, parseModelReferenceOrNull (modelReferenceSpelling.kt). NavigationTargetResolver.resolveModelReference (search scopes, list, Ant test selection) now uses it too, in place of its own "the resolved ID must equal the parsed ID" guard, which existed only to reject name-based IDs.

Sibling paths

All go through ModelNodeResolver.findNode / findModelUnique, so all are changed:

  • get node, render node, find usages (MODEL_TARGET NODE_ID forms)
  • check model (help text now says a reference resolves by model ID; docs/reference/check.md regenerated)
  • edit-batch destination models and {"model": …, "nodeId": …} targets (EditBatchExecutor)
  • Code Mode mops.lookup.model / requireModel (MopsLookupExtensions)

Left for later: the inline-reference {"target": {"model": …, "node": …}} form in EditBatchExecutor.resolveReferenceTargetOrFail joins the model text and node ID into a Node Reference string and passes it to MPS, so a model name there is still parsed as a name-based model ID. It does not go through MODEL_TARGET resolution.

Evidence

New tests, all on the json fixture unless noted:

  • GetNodeSemanticsTest

    • resolves a model reference with an out-of-date name by its model ID — r:fd752404-…(com.specificlanguages.json.oldname) finds com.specificlanguages.json.structure
    • fails on a model reference to a missing model without falling back to its name — unknown ID, existing name in parentheses → MODEL_NOT_FOUND
    • fails instead of guessing when model target is ambiguous — extended: with two same-named models the bare name still fails AMBIGUOUS_TARGET, and a reference picks one of them by ID
    • bare model names are covered by the existing tests (exports node json and others)
  • ModelCheckSemanticsTest: a model reference with an out-of-date name checks the model it identifies (sandbox fixture)

  • CodeModeLookupTest: mops.lookup.model resolves a stale reference and returns null for a missing one

  • Before: with the old text-comparing matchingModels, GetNodeSemanticsTest → 21 tests completed, 1 failed: resolves a model reference with an out-of-date name by its model ID() throws MpsRequestException (model not found).

    After: GetNodeSemanticsTest (21), ModelCheckSemanticsTest (10), CodeModeLookupTest (1), ScopeResolutionTest (13), MpsListSemanticsTest (34), FindNodeByIdSemanticsTest (7), RenderNodeSemanticsTest (5), RootEditSemanticsTest (7), ModelEditSemanticsTest (9): all pass. Full ./gradlew build passes; detektMain is clean.

Merge Danger

Blast Radius: small

A target that matched before only because its exact text equaled the printed reference still matches. Two behaviors change: a reference with a stale name now resolves, and a model whose name contains a type-designator colon can no longer be addressed by name (MPS model names do not contain colons).

A model target that parses as a model reference with a type designator now
resolves by model ID, so a reference with an out-of-date name still finds its
model and a reference to a missing model never falls back to a name lookup.
Other targets are model names, as before. The navigation resolver used by
search scopes shares the same parser.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant