Skip to content

Add localization extraction functionality with Roslyn and Resx adapters#15

Merged
linckez merged 2 commits intomainfrom
feature/extractor-architecture-overhaul
Apr 8, 2026
Merged

Add localization extraction functionality with Roslyn and Resx adapters#15
linckez merged 2 commits intomainfrom
feature/extractor-architecture-overhaul

Conversation

@linckez
Copy link
Copy Markdown
Owner

@linckez linckez commented Apr 8, 2026

blazor-loc 10.2.0

Features

  • Cross-reference statusinspect now shows whether each translation key is fully wired up (Resolved), potentially unused (Review), or missing source text (Missing)
  • Usage vs Source — the inspect table now clearly separates where translations are used from where they're defined
  • .resx locale coverage — new summary showing per-locale completeness at a glance
  • --show-resx-locales / --show-extracted-calls — new flags for detailed drill-down

Fixes

  • Unused translation definitions are no longer hidden — they honestly show as needing review

Internal

  • Hexagonal architecture — Domain, Ports, Application, and Adapter layers with strict dependency direction
  • Replaced the BuilderSymbolTable with IOperation-based scanning.

- Implemented ScannedCallSite and ScannedArgument records to capture call site details.
- Created SourceDocument to manage syntax trees and original file paths.
- Developed LocaleDiscovery for discovering available locales from translations.
- Introduced ProjectScanResult and ProjectScanner for orchestrating project scans.
- Established TranslationPipeline for merging scanner outputs and handling conflicts.
- Defined domain models including DefinitionKind, MergedTranslation, and TranslationSourceText.
- Added IScannerOutput interface and ScanDiagnostic for scanner diagnostics.
- Created unit tests for extension method parameter name validation.
- Added sample resource files for localization testing.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades blazor-loc to 10.2.0 and reworks the Extractor into a hexagonal architecture (Domain/Ports/Application/Adapters), adding richer “inspect” cross-referencing (Resolved/Review/Missing), .resx locale coverage reporting, and new drill-down flags (--show-resx-locales, --show-extracted-calls). It also replaces the previous scanner implementation with an IOperation-based Roslyn adapter and introduces a .resx adapter feeding a unified merge pipeline.

Changes:

  • Introduce Application-layer ProjectScanner + TranslationPipeline consuming IScannerOutput from Roslyn and Resx adapters.
  • Add new inspect JSON/table semantics: cross-reference status, usage vs source separation, .resx locale coverage, and optional detailed outputs.
  • Update sample app + tests/verified outputs to exercise new .resx and indexer/reference scenarios.

Reviewed changes

Copilot reviewed 133 out of 134 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/SampleBlazorApp/SharedResource.cs Adds shared localizer marker type (currently invalid C# declaration).
tests/SampleBlazorApp/Resources/SharedResource.resx Adds shared resource .resx entries used across components.
tests/SampleBlazorApp/Resources/SharedResource.da.resx Adds Danish translations for shared resources.
tests/SampleBlazorApp/Resources/Components/Pages/Home.resx Adds new RESX keys for reference-type test matrix scenarios.
tests/SampleBlazorApp/Resources/Components/Pages/Home.es-MX.resx Adds es-MX translations for the new RESX keys.
tests/SampleBlazorApp/Resources/Components/Pages/Home.da.resx Adds Danish translations for the new RESX keys.
tests/SampleBlazorApp/Program.cs Comments an alternative AddLocalization(ResourcesPath=...) setup line for reference.
tests/SampleBlazorApp/Components/Pages/Home.razor Adds “Reference Type Test Matrix” UI demonstrating indexer/runtime keys + SharedResource.
tests/SampleBlazorApp/Components/_Imports.razor Injects IStringLocalizer<SharedResource> for shared resource lookups.
tests/BlazorLocalization.Extractor.Tests/SampleAppFixture.cs Updates fixture to use new Application.ProjectScanner and new domain types.
tests/BlazorLocalization.Extractor.Tests/SampleAppExportTests.I18NextJson_PerLocale_EsMx.verified.txt Updates verified i18next per-locale output for es-MX.
tests/BlazorLocalization.Extractor.Tests/SampleAppExportTests.I18NextJson_PerLocale_Da.verified.txt Updates verified i18next per-locale output for da.
tests/BlazorLocalization.Extractor.Tests/SampleAppExportTests.I18NextJson_FullOutput.verified.txt Updates verified full output to new entry shapes/ordering and new sample keys.
tests/BlazorLocalization.Extractor.Tests/SampleAppExportTests.cs Migrates exporters/tests to new Adapters.Export and MergedTranslation model.
tests/BlazorLocalization.Extractor.Tests/ProjectDiscoveryTests.cs Updates tests to new CLI adapter namespace for project discovery.
tests/BlazorLocalization.Extractor.Tests/ModuleInit.cs Adds test namespace and keeps Verify diff runner disabled.
tests/BlazorLocalization.Extractor.Tests/MergeTests.cs Updates merge tests to run through TranslationPipeline using definitions/references model.
tests/BlazorLocalization.Extractor.Tests/InspectRequestTests.cs Updates request validation expectations and new inspect flags.
tests/BlazorLocalization.Extractor.Tests/ExtractRequestTests.cs Updates output target modeling + validation semantics (stdout multi-locale now valid).
tests/BlazorLocalization.Extractor.Tests/ExtensionsContractTests.cs Adds reflection-based guard tests for parameter-name string constants contract.
tests/BlazorLocalization.Extractor.Tests/ExporterTests.GenericJson.verified.txt Updates verified generic JSON shape from sources to definitions/references.
tests/BlazorLocalization.Extractor.Tests/ExporterTests.cs Updates exporter tests to new MergedTranslation + definition/reference sites.
tests/BlazorLocalization.Extractor.Tests/DomainHelperTests.cs Moves locale discovery tests to Application layer + adds SourceFilePath tests.
tests/BlazorLocalization.Extractor.Tests/CliSmokeTests.cs Updates CLI smoke tests for renamed JSON properties and stdout multi-locale behavior.
src/BlazorLocalization.Extractor/Scanning/Sources/SourceOrigin.cs Removes legacy scanning source-origin model (replaced by Roslyn adapter types).
src/BlazorLocalization.Extractor/Scanning/Sources/SourceDocument.cs Removes legacy SourceDocument (replaced by Adapters.Roslyn.SourceDocument).
src/BlazorLocalization.Extractor/Scanning/Sources/LineMap.cs Removes legacy line mapping (replaced by Adapters.Roslyn.LineMap).
src/BlazorLocalization.Extractor/Scanning/Scanner.cs Removes legacy scanner orchestrator (replaced by Roslyn adapter + pipeline).
src/BlazorLocalization.Extractor/Scanning/ResxImporter.cs Removes legacy .resx importer (replaced by Resx adapter).
src/BlazorLocalization.Extractor/Scanning/Providers/RazorGeneratedSourceProvider.cs Removes legacy Razor provider (replaced by Adapters.Roslyn.RazorSourceProvider).
src/BlazorLocalization.Extractor/Scanning/Providers/ISourceProvider.cs Removes legacy source provider abstraction.
src/BlazorLocalization.Extractor/Scanning/Providers/CSharpFileSourceProvider.cs Removes legacy C# provider (replaced by Adapters.Roslyn.CSharpFileProvider).
src/BlazorLocalization.Extractor/Scanning/ProjectScanner.cs Removes legacy project scanner (replaced by Application.ProjectScanner).
src/BlazorLocalization.Extractor/Scanning/ProjectDiscovery.cs Moves project discovery into CLI adapter.
src/BlazorLocalization.Extractor/Scanning/Extractors/EnumAttributeExtractor.cs Removes legacy enum attribute extraction (replaced by Roslyn adapter interpreter).
src/BlazorLocalization.Extractor/Program.cs Updates CLI wiring to new Adapters.Cli commands and refreshed help text.
src/BlazorLocalization.Extractor/Ports/ScanDiagnostic.cs Adds scanner diagnostics port type + diagnostic level.
src/BlazorLocalization.Extractor/Ports/IScannerOutput.cs Adds port interface for scanner adapters (definitions/references/diagnostics).
src/BlazorLocalization.Extractor/Exporters/PoExporter.cs Removes legacy PO exporter (replaced by Adapters.Export.PoExporter).
src/BlazorLocalization.Extractor/Exporters/ITranslationExporter.cs Removes legacy exporter interface (replaced by Adapters.Export.ITranslationExporter).
src/BlazorLocalization.Extractor/Exporters/I18NextJsonExporter.cs Removes legacy i18next exporter (replaced by Adapters.Export.I18NextJsonExporter).
src/BlazorLocalization.Extractor/Exporters/GenericJsonExporter.cs Removes legacy generic JSON exporter (replaced by Adapters.Export.GenericJsonExporter).
src/BlazorLocalization.Extractor/Exporters/ExporterFactory.cs Removes legacy exporter factory (replaced by Adapters.Export.ExporterFactory).
src/BlazorLocalization.Extractor/Domain/TranslationStatus.cs Adds cross-reference status enum used by inspect.
src/BlazorLocalization.Extractor/Domain/TranslationSourceText.cs Moves TranslationSourceText into Domain namespace (from Domain.Entries).
src/BlazorLocalization.Extractor/Domain/TranslationReference.cs Adds reference model representing key usages in code.
src/BlazorLocalization.Extractor/Domain/TranslationForm.cs Adds form classifier helper for display/JSON (“Simple/Plural/Select/…”).
src/BlazorLocalization.Extractor/Domain/TranslationDefinition.cs Adds definition model representing source-text definitions (+ inline translations).
src/BlazorLocalization.Extractor/Domain/SourceFilePath.cs Adds immutable file-path wrapper with relative/absolute display behavior.
src/BlazorLocalization.Extractor/Domain/Sites.cs Adds DefinitionSite/ReferenceSite domain records.
src/BlazorLocalization.Extractor/Domain/ScanResult.cs Removes legacy scan result model.
src/BlazorLocalization.Extractor/Domain/Requests/InspectRequest.cs Removes legacy domain request for inspect (moved to CLI adapter request).
src/BlazorLocalization.Extractor/Domain/Requests/ExtractRequest.cs Removes legacy domain request/output target (moved to CLI adapter request).
src/BlazorLocalization.Extractor/Domain/PoLimitation.cs Removes legacy PO limitation logic (moved to export adapter).
src/BlazorLocalization.Extractor/Domain/PathStyle.cs Simplifies PathStyle and removes Description attributes (affects wizard/help UX).
src/BlazorLocalization.Extractor/Domain/MergedTranslation.cs Introduces merged per-key model + merge result/conflicts/invalid entries.
src/BlazorLocalization.Extractor/Domain/ExportFormat.cs Reorders/rewrites export format enum and removes Description attributes.
src/BlazorLocalization.Extractor/Domain/Entries/TranslationEntry.cs Removes legacy raw entry model.
src/BlazorLocalization.Extractor/Domain/Entries/SourceReference.cs Removes legacy source reference model.
src/BlazorLocalization.Extractor/Domain/Entries/MergedTranslationEntry.cs Removes legacy merge implementation (replaced by TranslationPipeline).
src/BlazorLocalization.Extractor/Domain/Entries/LocaleDiscovery.cs Moves locale discovery to Application layer.
src/BlazorLocalization.Extractor/Domain/DefinitionKind.cs Adds definition kind discriminator for inspect/source labeling.
src/BlazorLocalization.Extractor/Domain/ConflictStrategy.cs Keeps conflict strategy but adjusts formatting/attributes.
src/BlazorLocalization.Extractor/Domain/Calls/SourceLocation.cs Removes legacy extracted-call location model.
src/BlazorLocalization.Extractor/Domain/Calls/ResolvedArgument.cs Removes legacy resolved-argument model.
src/BlazorLocalization.Extractor/Domain/Calls/OverloadResolutionStatus.cs Removes legacy overload-resolution model.
src/BlazorLocalization.Extractor/Domain/Calls/ObjectCreation.cs Removes legacy nested object creation representation.
src/BlazorLocalization.Extractor/Domain/Calls/ExtractedCall.cs Removes legacy extracted-call model (inspect now uses ScannedCallSite).
src/BlazorLocalization.Extractor/Domain/Calls/ChainedMethodCall.cs Removes legacy fluent chain model.
src/BlazorLocalization.Extractor/Domain/Calls/CallKind.cs Removes legacy call-kind enum.
src/BlazorLocalization.Extractor/Cli/Rendering/PoLimitationRenderer.cs Removes legacy CLI renderer (replaced by adapters/cli).
src/BlazorLocalization.Extractor/Cli/Rendering/JsonRenderer.cs Removes legacy JSON renderer (replaced by adapters/cli).
src/BlazorLocalization.Extractor/Cli/Rendering/ExtractedCallRenderer.cs Removes legacy extracted-calls renderer (replaced by adapters/cli).
src/BlazorLocalization.Extractor/Cli/Rendering/ConflictRenderer.cs Removes legacy conflict renderer (replaced by adapters/cli).
src/BlazorLocalization.Extractor/Cli/InteractiveWizard.cs Moves interactive wizard to CLI adapter.
src/BlazorLocalization.Extractor/Cli/Commands/SharedSettings.cs Moves CLI settings to CLI adapter.
src/BlazorLocalization.Extractor/Cli/Commands/InspectSettings.cs Moves inspect settings to CLI adapter.
src/BlazorLocalization.Extractor/Cli/Commands/InspectCommand.cs Moves inspect command to CLI adapter.
src/BlazorLocalization.Extractor/Cli/Commands/ExtractSettings.cs Moves extract settings to CLI adapter.
src/BlazorLocalization.Extractor/BlazorLocalization.Extractor.csproj Bumps version to 10.2.0, updates Spectre.Console packages, adds InternalsVisibleTo and NoWarns.
src/BlazorLocalization.Extractor/Application/TranslationPipeline.cs Adds scanner-agnostic merge pipeline (definitions + references → merged translations).
src/BlazorLocalization.Extractor/Application/ProjectScanResult.cs Adds per-project scan result carrying merge output + raw scanner outputs.
src/BlazorLocalization.Extractor/Application/ProjectScanner.cs Adds composition root scanning Roslyn+Resx adapters and running pipeline.
src/BlazorLocalization.Extractor/Application/LocaleDiscovery.cs Moves locale discovery and per-locale entry rewriting into Application layer.
src/BlazorLocalization.Extractor/Adapters/Roslyn/SourceDocument.cs Adds Roslyn adapter source document + line mapping support.
src/BlazorLocalization.Extractor/Adapters/Roslyn/ScanTargets.cs Adds Roslyn scan target resolution via metadata names.
src/BlazorLocalization.Extractor/Adapters/Roslyn/ScannedCallSite.cs Adds adapter-internal raw call-site model used by inspect detail output.
src/BlazorLocalization.Extractor/Adapters/Roslyn/RoslynScannerOutput.cs Implements IScannerOutput for Roslyn, including preserved raw calls.
src/BlazorLocalization.Extractor/Adapters/Roslyn/RoslynScanner.cs Implements IOperation-based scanning and domain interpretation.
src/BlazorLocalization.Extractor/Adapters/Roslyn/RazorSourceProvider.cs Adds Razor-to-C# compilation and #line mapping for correct source lines.
src/BlazorLocalization.Extractor/Adapters/Roslyn/OperationValue.cs Adds structured argument-value extraction from IOperation trees.
src/BlazorLocalization.Extractor/Adapters/Roslyn/LocalizerOperationWalker.cs Adds operation walker detecting localizer indexer + method usage + definition factories.
src/BlazorLocalization.Extractor/Adapters/Roslyn/LineMap.cs Adds Razor-generated line-to-original line mapping.
src/BlazorLocalization.Extractor/Adapters/Roslyn/FluentChainWalker.cs Adds fluent builder chain extraction by walking IOperation parents.
src/BlazorLocalization.Extractor/Adapters/Roslyn/ExtensionsContract.cs Centralizes Extensions API contract (metadata names, method names, parameter names).
src/BlazorLocalization.Extractor/Adapters/Roslyn/EnumAttributeInterpreter.cs Adds enum [Translation] attribute interpretation into definitions (doc currently mismatched).
src/BlazorLocalization.Extractor/Adapters/Roslyn/CSharpFileProvider.cs Adds C# file enumeration for Roslyn scanning.
src/BlazorLocalization.Extractor/Adapters/Roslyn/CallSiteBuilder.cs Builds structured call sites from walker hits (contains unused isExtension).
src/BlazorLocalization.Extractor/Adapters/Resx/ResxScannerOutput.cs Implements IScannerOutput for .resx scanning (definitions only).
src/BlazorLocalization.Extractor/Adapters/Resx/ResxScanner.cs Orchestrates .resx scanning and converts entries into domain definitions.
src/BlazorLocalization.Extractor/Adapters/Resx/ResxFileParser.cs Provides .resx enumeration/grouping/parsing utilities.
src/BlazorLocalization.Extractor/Adapters/Export/PoLimitation.cs Reintroduces PO limitation detection in export adapter.
src/BlazorLocalization.Extractor/Adapters/Export/PoExporter.cs Reintroduces PO exporter using new merged model and path style.
src/BlazorLocalization.Extractor/Adapters/Export/ITranslationExporter.cs Defines new exporter interface taking MergedTranslation + PathStyle.
src/BlazorLocalization.Extractor/Adapters/Export/I18NextJsonExporter.cs Reintroduces i18next exporter using new merged model.
src/BlazorLocalization.Extractor/Adapters/Export/GenericJsonExporter.cs Reintroduces generic JSON exporter including definitions/references.
src/BlazorLocalization.Extractor/Adapters/Export/ExporterFactory.cs Reintroduces exporter factory mapping ExportFormat to exporters/extensions.
src/BlazorLocalization.Extractor/Adapters/Cli/Rendering/SourceFileMarkup.cs Adds OSC8 link markup for file paths (URI construction is not Windows-safe).
src/BlazorLocalization.Extractor/Adapters/Cli/Rendering/PoLimitationRenderer.cs Adds CLI rendering for PO limitations.
src/BlazorLocalization.Extractor/Adapters/Cli/Rendering/JsonRenderer.cs Adds new inspect/extract JSON output structure (currently hardcodes relative paths in parts).
src/BlazorLocalization.Extractor/Adapters/Cli/Rendering/ExtractedCallRenderer.cs Adds opt-in CLI rendering for raw extracted calls.
src/BlazorLocalization.Extractor/Adapters/Cli/Rendering/ConflictRenderer.cs Adds CLI rendering for conflicts using clickable file links.
src/BlazorLocalization.Extractor/Adapters/Cli/ProjectDiscovery.cs Moves project discovery into CLI adapter.
src/BlazorLocalization.Extractor/Adapters/Cli/InteractiveWizard.cs Updates wizard flow to new inspect/extract semantics and options.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/SharedSettings.cs Adds shared CLI settings in new namespace.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/InspectSettings.cs Adds inspect settings incl. new show flags.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/InspectRequest.cs Adds request/validation model for inspect.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/InspectCommand.cs Implements new inspect command flow + optional detail sections.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/ExtractSettings.cs Adds extract settings in new namespace.
src/BlazorLocalization.Extractor/Adapters/Cli/Commands/ExtractRequest.cs Adds request/validation model for extract + output-target classification.
README.md Updates top-level docs to emphasize inspect + extract.
docs/Extractor.md Expands CLI docs: inspect vs extract, options, and JSON piping.
BlazorLocalization.sln Adds SampleBlazorApp project to the solution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/SampleBlazorApp/SharedResource.cs
Comment thread src/BlazorLocalization.Extractor/Domain/PathStyle.cs
Comment thread src/BlazorLocalization.Extractor/Domain/ExportFormat.cs
Comment thread src/BlazorLocalization.Extractor/Adapters/Roslyn/CallSiteBuilder.cs Outdated
@linckez linckez merged commit 7ad3ef7 into main Apr 8, 2026
1 check passed
@linckez linckez deleted the feature/extractor-architecture-overhaul branch April 8, 2026 20:21
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.

2 participants