samchon / samchon/compiler-knowledge-graph
[Bulk index][C#] Wrap scip-dotnet and Roslyn Workspaces for solution snapshots
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
Outcome
Replace scip-dotnet repair/post-processing with a resident Roslyn semantic
service. Open the real solution once through MSBuildWorkspace, capture one
immutable Solution, walk syntax/semantic/IOperation data once, and export
changed project/document shards. Keep scip-dotnet only as an optional
navigation fallback.
Current master baseline
Current master registers scip-dotnet, but the strict grounding rules claim
zero edge families. Stock scip-dotnet omits enclosing attribution, kinds,
diagnostics and role information required by the graph. Its relationships
flatten transitive ancestry, and its identities have known namespace, generic
arity, project/assembly and declaration-order problems.
The PR #147 Serilog cold cell took 20.498 s, versus 25.085 s with
generic csharp-ls. The small speed difference does not compensate for the
semantic omissions, and no resident edit/no-op measurement exists.
Why Roslyn is the final route
The official
Roslyn workspace model
already represents the solution, projects, documents, parse/compilation
options, project references, syntax trees, semantic models and compilations.
Workspace.CurrentSolution is updated on changes; each captured Solution is
immutable and safe to analyze in isolation.
Roslyn also exposes the exact semantic operations the graph needs:
invocations, object creation, field/property/event references, assignments,
conversions, patterns and attributes through IOperation and symbols.
Running scip-dotnet and then a Roslyn sidecar would open/resolve the solution
twice. The Roslyn service can emit everything scip-dotnet can, with stronger
identity and incremental behavior, so it should be the preferred provider.
Service architecture
Build a pinned .NET sidecar/service:
- register the matching MSBuild instance before opening;
- open
.sln,.slnx, or explicitly selected projects in one
MSBuildWorkspace; - await workspace diagnostics and capture one immutable
Solution; - topologically process each configured project/target framework;
- for each source document, walk declarations and operations once and write a
document shard; - write project relationship/generated-source shards; and
- atomically commit only if
CurrentSolutionand build inputs still match.
Subscribe to WorkspaceChanged and debounce changes. Never keep mutable
compiler handles in the serialized graph. On refresh, capture the new solution
and use solution/project/document changes to bound re-export.
Source generators are part of the semantic universe. Include generated
documents and generator diagnostics with explicit origin; generator, SDK,
props/targets or analyzer changes may invalidate a whole project.
Fact extraction
- declarations and containment from
ISymbolplus every
DeclaringSyntaxReference; - namespace/project exports and using/alias imports;
- calls from
IInvocationOperation.TargetMethod, including reduced extension
methods and constructed generic methods; - construction from
IObjectCreationOperationand relevant implicit object
creation; - read/write accesses from field/property/event/local/parameter operations and
assignment/ref context; - type references and conversions from operation/type info;
- direct base type, direct interfaces, implementations and overridden members;
- attributes and their constructor/type plus annotated target;
- compiler/analyzer/generator diagnostics; and
- framework
testsonly through a named xUnit/NUnit/MSTest enricher.
Interface/virtual calls are not automatically executed-target edges.
TargetMethod is the selected declaration; publish candidate implementations
as unresolved candidates unless sealed/final/internal-world analysis proves a
single runtime target.
Identity
For source-declared public/member symbols use:
assembly identity + target framework + DocumentationCommentId + symbol kind.
Documentation IDs encode full namespace, generic arity and overload parameter
types and are independent of declaration order. Add explicit handling for:
- partial declarations: one symbol ID, all declaration spans;
- partial methods: link definition and implementation parts;
- records and synthesized members;
- reduced extension methods: canonicalize to the original definition while
preserving call evidence; - constructed generics: retain original definition plus type arguments as call
evidence rather than duplicate declaration nodes; - locals/parameters/local functions: file + containing stable member +
structural lexical identity; and - anonymous functions/types: generation-scoped structural identity with an
explicitidentity-unstablecoverage record if position invariance cannot be
proven.
Do not adopt scip-dotnet's package ".", truncated namespace, dropped arity or
+N overload key. Exact regression fixtures cover same suffix namespaces,
Foo/Foo<T>, same namespace/type across two projects, partial types and
overload insertion/reordering.
Build universe
Include solution/project graph, assembly identity, target framework and runtime
identifier, configuration/platform, SDK/global.json, language version,
nullable/unsafe/defines, parse and compilation options, project/metadata
references, NuGet lock/config, Directory.Build/Packages props/targets,
analyzers/source generators and generated document digests.
Multi-targeting projects produce separate target universes. Do not merge facts
from net8.0 and net10.0 merely because the source path matches.
Incremental and lifecycle behavior
- no-op: reuse the immutable solution/generation or validated disk shards;
- document body edit: use the new solution and re-export changed/affected
documents; - public/API/project-reference change: re-export the changed project and
dependent-project closure; - props/targets/SDK/restore change: reopen affected projects/solution;
- generator/analyzer change: invalidate generated and consuming shards;
- delete/rename: explicit shard deletion; and
- workspace diagnostics, cancel, crash or solution movement: retain the prior
committed graph.
Do not call dotnet restore on every refresh. Preparation may restore when
assets are absent or stale, under an explicit policy, then record exactly what
was used.
Implementation map
- Implement the #63 shard/coverage contract.
- Add a versioned .NET service under a dedicated sidecar directory with an
exact protocol handshake. - Add a Roslyn provider ahead of scip-dotnet in
GRAPH_PROVIDERSonly after
its solution-selection gate passes. - Add fake protocol/lifecycle tests and a real multi-project/multi-target
fixture. - Keep scip-dotnet as an explicitly limited fallback; do not attempt to merge
its ordinal identities with Roslyn identities. - Measure native solution load, export, merge, no-op and edit phases
independently.
Acceptance
- Exact fixtures cover
.sln/.slnx, multiple projects, target frameworks,
project references, partial types/methods, records, generics, overloads,
constructors, extension methods, attributes, nullable context, source
generators and tests. - Namespace suffix, generic arity, assembly and overload-order collisions
are impossible. - Direct inheritance/override edges are not replaced by a transitive
closure. - All 15 fact families have explicit coverage/unresolved rows.
- No-op, document/API edit, create/delete/rename, project/TFM/config/restore,
generator change, diagnostic, cancel, crash and retry are atomic. - The strict route opens/resolves the solution once and issues no
per-symbol LSP requests. - Cold time is compared with native
MSBuildWorkspacesolution load;
resident no-op target is below 250 ms and body edit target below 2 s on
the pinned fixture. - Windows, Linux and macOS SDK/MSBuild selection and fallback are tested.
- Focused tests, C# experiment,
pnpm build,pnpm test, and
pnpm coveragepass.
Primary references
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the #63 shard/coverage contract and the GRAPH_PROVIDERS solution-selection path, then review the dedicated sidecar directory and the required protocol and lifecycle behavior. Done means the Roslyn route satisfies the listed fixture, incremental, atomicity, platform, performance, and coverage acceptance criteria; validate with focused tests, pnpm build, pnpm test, and pnpm coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, typescript
- Domain
- compilers, devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100