diff --git a/packages/typespec-azure-resource-manager/src/rules/arm-resource-name-pattern.ts b/packages/typespec-azure-resource-manager/src/rules/arm-resource-name-pattern.ts index 9160adc0d8..062cdabced 100644 --- a/packages/typespec-azure-resource-manager/src/rules/arm-resource-name-pattern.ts +++ b/packages/typespec-azure-resource-manager/src/rules/arm-resource-name-pattern.ts @@ -1,7 +1,46 @@ -import { Program, createRule, getPattern } from "@typespec/compiler"; +import { + DiagnosticTarget, + Program, + SourceLocation, + createRule, + defineCodeFix, + getPattern, + getSourceLocation, +} from "@typespec/compiler"; +import { isWhiteSpace } from "../../../../core/packages/compiler/src/core/charcode.js"; import { getArmResources } from "../resource.js"; +// TODO: Replace this with a reusable implementation from the compiler package when implemented. +// Issue: https://github.com/microsoft/typespec/issues/3044 +function createPatternCodeFix(diagnosticTarget: DiagnosticTarget) { + return defineCodeFix({ + id: "add-pattern-decorator", + label: "Add `@pattern` decorator to the resource name property with the default ARM pattern.", + fix: (context) => { + const location = getSourceLocation(diagnosticTarget); + const { lineStart, indent } = findLineStartAndIndent(location); + const updatedLocation = { ...location, pos: lineStart }; + return context.prependText(updatedLocation, `${indent}@pattern(/^[a-zA-Z0-9-]+$/)\n`); + }, + }); +} + +function findLineStartAndIndent(location: SourceLocation): { lineStart: number; indent: string } { + const text = location.file.text; + let pos = location.pos; + let indent = 0; + while (pos > 0 && text[pos - 1] !== "\n") { + if (isWhiteSpace(text.charCodeAt(pos - 1))) { + indent++; + } else { + indent = 0; + } + pos--; + } + return { lineStart: pos, indent: location.file.text.slice(pos, pos + indent) }; +} + /** * Verify that a delete operation only */ @@ -25,6 +64,7 @@ export const armResourceNamePatternRule = createRule({ if (pattern === undefined) { context.reportDiagnostic({ target: nameProperty, + codefixes: [createPatternCodeFix(nameProperty)], }); } }