-
Notifications
You must be signed in to change notification settings - Fork 3
Allow configuring custom declarationPattens #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import { ModuleMatcherService } from "./moduleMatcherService"; | |
| import { DefinitionEntryService } from "./definitionEntryService"; | ||
| import { SectionParser } from "./sectionParser"; | ||
| import { DiagramCodeLensService } from "./diagramCodeLensService"; | ||
| import { ConfigurationManager } from "../utils/config"; | ||
|
|
||
| /** | ||
| * A Parser implementation that uses ModuleConfiguration configurations | ||
|
|
@@ -53,10 +54,17 @@ export class ModuleParser implements Parser { | |
| definitionEntries: [], | ||
| }; | ||
| } | ||
|
|
||
| // Get alternative declaration patterns from configuration | ||
| const alternativePatterns = ConfigurationManager.getInstance().get( | ||
| "alternativeDeclarationPatterns" | ||
| ); | ||
|
Comment on lines
+58
to
+61
|
||
|
|
||
| // Identify which modules are present | ||
| const matchedModules = this.moduleMatcherService.identifyConfiguredModules( | ||
| useDeclarations, | ||
| availableConfigs | ||
| availableConfigs, | ||
| alternativePatterns | ||
| ); | ||
| if (matchedModules.length === 0) { | ||
| return { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| /** | ||
| * Test suite for ModuleMatcherService | ||
| */ | ||
|
|
||
| import { ModuleMatcherService } from "../../../src/parser/moduleMatcherService"; | ||
| import { ModuleConfiguration } from "../../../src/types/configurationRegistry"; | ||
|
|
||
| describe("ModuleMatcherService", () => { | ||
| const mockConfigs: ModuleConfiguration[] = [ | ||
| { | ||
| displayName: "Ash.Resource", | ||
| declarationPattern: "Ash.Resource", | ||
| dslSections: [], | ||
| }, | ||
| { | ||
| displayName: "Ash.Domain", | ||
| declarationPattern: "Ash.Domain", | ||
| dslSections: [], | ||
| }, | ||
| { | ||
| displayName: "AshGraphql", | ||
| declarationPattern: "AshGraphql.Resource", | ||
| dslSections: [], | ||
| }, | ||
| ]; | ||
|
|
||
| describe("identifyConfiguredModules", () => { | ||
| it("should match standard Ash.Resource declaration", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Resource"]; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Resource"); | ||
| }); | ||
|
|
||
| it("should match standard Ash.Domain declaration", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Domain"]; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Domain"); | ||
| }); | ||
|
|
||
| it("should match multiple standard declarations", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = [ | ||
| "use Ash.Resource", | ||
| "use Ash.Domain", | ||
| "use AshGraphql.Resource", | ||
| ]; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(3); | ||
| expect(result.map(r => r.declarationPattern)).toEqual([ | ||
| "Ash.Resource", | ||
| "Ash.Domain", | ||
| "AshGraphql.Resource", | ||
| ]); | ||
| }); | ||
|
|
||
| it("should not match when no declarations present", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use SomeOtherModule"]; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(0); | ||
| }); | ||
|
|
||
| it("should match alternative declaration pattern App.Resource to Ash.Resource", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use App.Resource"]; | ||
| const alternativePatterns = { | ||
| "App.Resource": "Ash.Resource", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Resource"); | ||
| expect(result[0].displayName).toBe("Ash.Resource"); | ||
| }); | ||
|
|
||
| it("should match alternative declaration pattern App.Domain to Ash.Domain", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use App.Domain"]; | ||
| const alternativePatterns = { | ||
| "App.Domain": "Ash.Domain", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Domain"); | ||
| expect(result[0].displayName).toBe("Ash.Domain"); | ||
| }); | ||
|
|
||
| it("should match multiple alternative patterns", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use App.Resource", "use App.Domain"]; | ||
| const alternativePatterns = { | ||
| "App.Resource": "Ash.Resource", | ||
| "App.Domain": "Ash.Domain", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(2); | ||
| expect(result.map(r => r.declarationPattern)).toEqual([ | ||
| "Ash.Resource", | ||
| "Ash.Domain", | ||
| ]); | ||
| }); | ||
|
|
||
| it("should match both standard and alternative patterns in same file", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Resource", "use App.Domain"]; | ||
| const alternativePatterns = { | ||
| "App.Domain": "Ash.Domain", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(2); | ||
| expect(result.map(r => r.declarationPattern)).toEqual([ | ||
| "Ash.Resource", | ||
| "Ash.Domain", | ||
| ]); | ||
| }); | ||
|
|
||
| it("should not add duplicate matches when both standard and alternative patterns match", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Resource", "use App.Resource"]; | ||
| const alternativePatterns = { | ||
| "App.Resource": "Ash.Resource", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| // Should only have one match even though both declarations matched | ||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Resource"); | ||
| }); | ||
|
|
||
| it("should work with empty alternative patterns object", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Resource"]; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| {} | ||
| ); | ||
|
|
||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Resource"); | ||
| }); | ||
|
|
||
| it("should ignore alternative patterns that don't match any use declaration", () => { | ||
| const service = new ModuleMatcherService(); | ||
| const useDeclarations = ["use Ash.Resource"]; | ||
| const alternativePatterns = { | ||
| "CustomMacro.Resource": "Ash.Resource", | ||
| }; | ||
| const result = service.identifyConfiguredModules( | ||
| useDeclarations, | ||
| mockConfigs, | ||
| alternativePatterns | ||
| ); | ||
|
|
||
| // Should still match the standard Ash.Resource | ||
| expect(result).toHaveLength(1); | ||
| expect(result[0].declarationPattern).toBe("Ash.Resource"); | ||
| }); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object.entries(alternativePatterns)is executed inside the nested loops, so it’s recomputed (and reallocated) for every(useDeclaration, config)pair. Precompute the entries once outside the loops, or invert to aMap<standardPattern, altPatterns[]>/Setto avoid O(UCA) scanning and repeated allocations during parsing.