Skip to content

Duplicate Code: Namespace-Wrapping Boilerplate Repeated Across All Three Generator Modules #280

Description

@github-actions

Analysis of commit 710bd94

Assignee: @copilot

Summary

All three generator modules (FieldsGenerator, DUCasesGenerator, LensesGenerator) repeat identical 2–4 line blocks that look up the configured namespace from config and wrap a nested module in a SynModuleOrNamespace. If the key name, default value, or isRecursive flag ever needs to change, all three sites must be updated consistently.

Duplication Details

Pattern: Namespace lookup + SynModuleOrNamespace.CreateNamespace wrapping

  • Severity: Medium
  • Occurrences: 3 (one per generator)
  • Locations:
    • src/Myriad.Plugins/DUCasesGenerator.fs (lines 120–124)
    • src/Myriad.Plugins/FieldsGenerator.fs (lines 138–142)
    • src/Myriad.Plugins/LensesGenerator.fs (lines 192–195)

DUCasesGenerator (lines 120–124):

let info = SynComponentInfo.Create recordId
let mdl = SynModuleDecl.CreateNestedModule(info, declarations)
let dusNamespace = GeneratorConfig.getOrDefault "namespace" "UnknownNamespace" config
SynModuleOrNamespace.CreateNamespace(Ident.CreateLong dusNamespace, isRecursive = true, decls = [mdl])

FieldsGenerator (lines 138–142):

let info = SynComponentInfo.Create recordId
let mdl = SynModuleDecl.CreateNestedModule(info, decls)
let fieldsNamespace = GeneratorConfig.getOrDefault "namespace" "UnknownNamespace" config
SynModuleOrNamespace.CreateNamespace(Ident.CreateLong fieldsNamespace, isRecursive = true, decls = [mdl])

LensesGenerator (lines 192–195):

let typeNamespace = GeneratorConfig.getOrDefault "namespace" "UnknownNamespace" config
// ...
SynModuleOrNamespace.CreateNamespace(Ident.CreateLong typeNamespace, isRecursive = true, decls = [synModule])

Impact Analysis

  • Maintainability: Three sites to update if the config key "namespace", default "UnknownNamespace", or isRecursive semantics change.
  • Bug Risk: A fix or change applied to one generator but not the others creates inconsistent behaviour across generator outputs.
  • Code Bloat: Minor but represents avoidable copy-paste between modules that already share GeneratorHelpers and GeneratorConfig.

Refactoring Recommendations

  1. Add a helper to GeneratorHelpers or GeneratorConfig

    • Add a small helper such as:
      /// Wraps `decls` in a recursively-open namespace read from the "namespace" config key.
      let wrapInNamespace (config: (string * obj) seq) (decls: SynModuleDecl list) : SynModuleOrNamespace =
          let ns = GeneratorConfig.getOrDefault "namespace" "UnknownNamespace" config
          SynModuleOrNamespace.CreateNamespace(Ident.CreateLong ns, isRecursive = true, decls = decls)
    • Estimated effort: 30 minutes
    • Benefits: Single point of change for the namespace config key and default; consistent behaviour across all generators.
  2. Update all three call sites

    • Replace the repeated 2–4 line blocks with a single call to the new helper.

Implementation Checklist

  • Review duplication findings
  • Add wrapInNamespace (or equivalent) helper to GeneratorHelpers.fs or GeneratorConfig.fs
  • Update DUCasesGenerator.fs to use the helper
  • Update FieldsGenerator.fs to use the helper
  • Update LensesGenerator.fs to use the helper
  • Run existing tests to verify no functionality broken

Analysis Metadata

  • Analyzed Files: 3 (DUCasesGenerator.fs, FieldsGenerator.fs, LensesGenerator.fs)
  • Detection Method: Semantic code analysis
  • Commit: 710bd94
  • Analysis Date: 2026-03-22

Generated by Duplicate Code Detector

To install this workflow, run gh aw add githubnext/agentics/workflows/duplicate-code-detector.md@ee49512da7887942965ac0a0e48357106313c9dd. View source at https://github.com/githubnext/agentics/tree/ee49512da7887942965ac0a0e48357106313c9dd/workflows/duplicate-code-detector.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions