Skip to content

Commit e0fdd0c

Browse files
author
iscai-msft
committed
switch to one rule
1 parent 678aba7 commit e0fdd0c

File tree

9 files changed

+288
-541
lines changed

9 files changed

+288
-541
lines changed

packages/typespec-client-generator-core/src/linter.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
import { defineLinter } from "@typespec/compiler";
2+
import { noReservedWordsRule } from "./rules/no-reserved-words.rule.js";
23
import { noUnnamedTypesRule } from "./rules/no-unnamed-types.rule.js";
34
import { propertyNameConflictRule } from "./rules/property-name-conflict.rule.js";
45
import { requireClientSuffixRule } from "./rules/require-client-suffix.rule.js";
5-
import { csharpReservedWordsRule } from "./rules/reserved-words/csharp.rule.js";
6-
import { javaReservedWordsRule } from "./rules/reserved-words/java.rule.js";
7-
import { javascriptReservedWordsRule } from "./rules/reserved-words/javascript.rule.js";
8-
import { pythonReservedWordsRule } from "./rules/reserved-words/python.rule.js";
96

107
const rules = [
118
requireClientSuffixRule,
129
propertyNameConflictRule,
1310
noUnnamedTypesRule,
14-
csharpReservedWordsRule,
15-
pythonReservedWordsRule,
16-
javaReservedWordsRule,
17-
javascriptReservedWordsRule,
11+
noReservedWordsRule,
1812
];
1913

20-
const csharpRules = [propertyNameConflictRule, csharpReservedWordsRule];
21-
const pythonRules = [pythonReservedWordsRule];
22-
const javaRules = [javaReservedWordsRule];
23-
const javascriptRules = [javascriptReservedWordsRule];
14+
const csharpRules = [propertyNameConflictRule, noReservedWordsRule];
15+
const pythonRules = [noReservedWordsRule];
16+
const javaRules = [noReservedWordsRule];
17+
const javascriptRules = [noReservedWordsRule];
2418

2519
function createRuleSet(langRules: typeof rules) {
2620
return {
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import {
2+
createRule,
3+
Enum,
4+
EnumMember,
5+
Model,
6+
ModelProperty,
7+
Operation,
8+
paramMessage,
9+
Union,
10+
UnionVariant,
11+
} from "@typespec/compiler";
12+
import { createTCGCContext } from "../context.js";
13+
import { getLibraryName } from "../public-utils.js";
14+
import {
15+
csharpReservedWords,
16+
javaReservedWords,
17+
javascriptReservedWords,
18+
LanguageReservedWords,
19+
pythonReservedWords,
20+
} from "./reserved-words.js";
21+
22+
interface LanguageConfig {
23+
/** Scope string passed to `getLibraryName` to resolve `@clientName` overrides. */
24+
scope: string;
25+
/** Human-readable name for diagnostic messages. */
26+
displayName: string;
27+
/** Context-specific reserved word sets. */
28+
words: LanguageReservedWords;
29+
}
30+
31+
const languages: readonly LanguageConfig[] = [
32+
{ scope: "python", displayName: "Python", words: pythonReservedWords },
33+
{ scope: "csharp", displayName: "C#", words: csharpReservedWords },
34+
{ scope: "java", displayName: "Java", words: javaReservedWords },
35+
{ scope: "javascript", displayName: "JavaScript", words: javascriptReservedWords },
36+
];
37+
38+
export const noReservedWordsRule = createRule({
39+
name: "no-reserved-words",
40+
description:
41+
"Warns when identifiers conflict with reserved words in target languages (Python, C#, Java, JavaScript).",
42+
severity: "warning",
43+
url: "https://azure.github.io/typespec-azure/docs/libraries/typespec-client-generator-core/rules/no-reserved-words",
44+
messages: {
45+
default: paramMessage`'${"name"}' cannot be used as a ${"context"} name since it is a reserved word in ${"language"}. Consider using the @clientName decorator to rename it for ${"language"} code generation.`,
46+
},
47+
create(context) {
48+
const tcgcContext = createTCGCContext(
49+
context.program,
50+
"@azure-tools/typespec-client-generator-core",
51+
{
52+
mutateNamespace: false,
53+
},
54+
);
55+
56+
function check(
57+
target: Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant,
58+
getWordSet: (words: LanguageReservedWords) => ReadonlySet<string>,
59+
contextName: string,
60+
) {
61+
if (typeof target.name !== "string") return;
62+
for (const lang of languages) {
63+
const effectiveName = getLibraryName(tcgcContext, target, lang.scope);
64+
if (getWordSet(lang.words).has(effectiveName)) {
65+
context.reportDiagnostic({
66+
format: { name: effectiveName, language: lang.displayName, context: contextName },
67+
target,
68+
});
69+
}
70+
}
71+
}
72+
73+
const parameterModels = new WeakSet<Model>();
74+
75+
return {
76+
model: (node: Model) => check(node, (w) => w.model, "model"),
77+
modelProperty: (node: ModelProperty) => {
78+
if (node.model && parameterModels.has(node.model)) {
79+
check(node, (w) => w.parameter, "parameter");
80+
} else {
81+
check(node, (w) => w.property, "property");
82+
}
83+
},
84+
operation: (node: Operation) => {
85+
check(node, (w) => w.operation, "operation");
86+
parameterModels.add(node.parameters);
87+
},
88+
enum: (node: Enum) => {
89+
check(node, (w) => w.enumType, "enum");
90+
for (const member of node.members.values()) {
91+
check(member, (w) => w.enumMember, "enum member");
92+
}
93+
},
94+
union: (node: Union) => check(node, (w) => w.enumType, "union"),
95+
unionVariant: (node: UnionVariant) => check(node, (w) => w.enumMember, "union variant"),
96+
};
97+
},
98+
});

packages/typespec-client-generator-core/src/rules/reserved-words/words.ts renamed to packages/typespec-client-generator-core/src/rules/reserved-words.ts

File renamed without changes.

packages/typespec-client-generator-core/src/rules/reserved-words/create-reserved-word-rule.ts

Lines changed: 0 additions & 91 deletions
This file was deleted.

packages/typespec-client-generator-core/src/rules/reserved-words/csharp.rule.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/typespec-client-generator-core/src/rules/reserved-words/java.rule.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/typespec-client-generator-core/src/rules/reserved-words/javascript.rule.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

packages/typespec-client-generator-core/src/rules/reserved-words/python.rule.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)