Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/renameSuggestions/common/namingConvention.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
export enum NamingConvention {
7
/** example: camelCase */
8
CamelCase = 'camelCase',
9
10
/** example: PascalCase */
11
PascalCase = 'PascalCase',
12
13
/** example: snake_case */
14
SnakeCase = 'snake_case',
15
16
/** example: SCREAMING_SNAKE_CASE */
17
ScreamingSnakeCase = 'SCREAMING_SNAKE_CASE',
18
19
/** example: Capital_snake_case */
20
CapitalSnakeCase = 'Capital_snake_case',
21
22
/** example: kebab-case */
23
KebabCase = 'kebab-case',
24
25
/** example: Capitalized */
26
Capitalized = 'Capitalized',
27
28
/** example: ALLCAPS */
29
Uppercase = 'Uppercase',
30
31
/**
32
* example: lowercase
33
*
34
* @remark could also be camel case, snake case, kebab case, e.g., `foo`
35
*/
36
LowerCase = 'lowercase',
37
38
Unknown = 'Unknown',
39
}
40
41
// Regular expressions for each naming convention
42
43
export function guessNamingConvention(ident: string): NamingConvention {
44
45
// lowercase
46
if (/^[a-z][a-z0-9]*$/.test(ident)) {
47
return NamingConvention.LowerCase;
48
}
49
50
// camelCase
51
if (/^[a-z][a-zA-Z0-9]*$/.test(ident)) {
52
return NamingConvention.CamelCase;
53
}
54
55
// snake_case
56
if (/^[a-z]+(_[a-z0-9]+)*$/.test(ident)) {
57
return NamingConvention.SnakeCase;
58
}
59
60
// kebab-case
61
if (/^[a-z]+(-[a-z0-9]+)*$/.test(ident)) {
62
return NamingConvention.KebabCase;
63
}
64
65
// Capitalized
66
if (/^[A-Z][a-z0-9]*$/.test(ident)) {
67
return NamingConvention.Capitalized;
68
}
69
70
// SCREAMING_SNAKE_CASE
71
if (/^[A-Z0-9]+(_[A-Z0-9]+)+$/.test(ident)) {
72
return NamingConvention.ScreamingSnakeCase;
73
}
74
75
// UPPERCASE
76
if (/^[A-Z]+$/.test(ident)) {
77
return NamingConvention.Uppercase;
78
}
79
80
// PascalCase
81
if (/^[A-Z][a-zA-Z0-9]*$/.test(ident)) {
82
return NamingConvention.PascalCase;
83
}
84
85
// Capital_snake_case
86
if (/^[A-Z][a-z0-9]*(_[a-z0-9]+)*$/.test(ident)) {
87
return NamingConvention.CapitalSnakeCase;
88
}
89
90
return NamingConvention.Unknown;
91
}
92
93
function chunksToCamelCase(chunks: string[]): string {
94
return chunks.map((chunk, i) => {
95
if (i === 0) {
96
return chunk.toLowerCase();
97
}
98
99
return chunk.charAt(0).toUpperCase() + chunk.substring(1).toLowerCase();
100
}).join('');
101
}
102
103
function chunksToPascalCase(chunks: string[]): string {
104
return chunks.map(chunk => chunk.charAt(0).toUpperCase() + chunk.substring(1).toLowerCase()).join('');
105
}
106
107
function chunksToSnakeCase(chunks: string[]): string {
108
return chunks.map(chunk => chunk.toLowerCase()).join('_');
109
}
110
111
function chunksToKebabCase(chunks: string[]): string {
112
return chunks.map(chunk => chunk.toLowerCase()).join('-');
113
}
114
115
export function enforceNamingConvention(givenIdent: string, targetConvention: NamingConvention): string {
116
117
const namingConvention = guessNamingConvention(givenIdent);
118
119
if (namingConvention === targetConvention) {
120
return givenIdent;
121
} else {
122
const chunks = chunkUpIdentByConvention(givenIdent, namingConvention);
123
switch (targetConvention) {
124
case NamingConvention.CamelCase:
125
return chunksToCamelCase(chunks);
126
case NamingConvention.PascalCase:
127
return chunksToPascalCase(chunks);
128
case NamingConvention.SnakeCase:
129
return chunksToSnakeCase(chunks);
130
case NamingConvention.ScreamingSnakeCase:
131
return chunksToSnakeCase(chunks).toUpperCase();
132
case NamingConvention.CapitalSnakeCase:
133
return chunksToSnakeCase(chunks).charAt(0).toUpperCase() + chunksToSnakeCase(chunks).substring(1);
134
case NamingConvention.KebabCase:
135
return chunksToKebabCase(chunks);
136
case NamingConvention.Capitalized:
137
return chunksToCamelCase(chunks).charAt(0).toUpperCase() + chunksToCamelCase(chunks).substring(1);
138
case NamingConvention.Uppercase:
139
return givenIdent.toUpperCase();
140
case NamingConvention.LowerCase:
141
return givenIdent.toLowerCase();
142
case NamingConvention.Unknown:
143
return givenIdent;
144
}
145
}
146
}
147
148
export function chunkUpIdentByConvention(ident: string, identConvention: NamingConvention): string[] {
149
switch (identConvention) {
150
case NamingConvention.CamelCase:
151
case NamingConvention.PascalCase:
152
return ident.split(/(?=[A-Z])/);
153
case NamingConvention.SnakeCase:
154
case NamingConvention.ScreamingSnakeCase:
155
case NamingConvention.CapitalSnakeCase:
156
case NamingConvention.KebabCase:
157
return ident.split(/[-_]/).map(chunk => chunk.toLowerCase());
158
case NamingConvention.Capitalized:
159
case NamingConvention.Uppercase:
160
case NamingConvention.LowerCase:
161
case NamingConvention.Unknown:
162
return [ident];
163
}
164
}
165
166