Skip to content

Commit c704a6c

Browse files
committed
Refactor resxgen
1 parent cbbb7c1 commit c704a6c

File tree

5 files changed

+407
-11
lines changed

5 files changed

+407
-11
lines changed

package-lock.json

+178-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
},
211211
"dependencies": {
212212
"@vscode/webview-ui-toolkit": "^1.2.2",
213-
"resx": "^2.0.4"
213+
"resx": "^2.0.4",
214+
"xmlbuilder2": "^3.1.1"
214215
}
215-
}
216+
}

src/resxProvider.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { printChannelOutput } from './extension';
66
import { newResourceInput } from './addNewResource';
77
import { AppConstants } from './utilities/constants';
88
import { generateAndUpdateDesignerFile } from './utilities/generateCode';
9+
import { jsonToResx } from './utilities/json2resx';
910

1011
export class ResxProvider implements vscode.CustomTextEditorProvider {
1112

@@ -134,7 +135,7 @@ export class ResxProvider implements vscode.CustomTextEditorProvider {
134135
}
135136

136137
// Update the RESX file
137-
const resxContent = await resx.js2resx(parsedJson);
138+
const resxContent = await jsonToResx(parsedJson);
138139
edit.replace(
139140
document.uri,
140141
new vscode.Range(0, 0, document.lineCount, 0),

src/utilities/designerGenerator.ts

+67-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,62 @@
11
import * as path from 'path';
2+
import * as fs from 'fs';
3+
4+
export function generateDesignerCode(resxPath: string, resources: { [key: string]: { value: string; comment?: string } }, accessLevel: 'public' | 'internal' = 'public'): string {
5+
const existingSummaries = new Map<string, string>();
6+
7+
// Try to read existing designer file
8+
const designerPath = resxPath.replace('.resx', '.Designer.cs');
9+
let existingNamespace: string | undefined;
10+
11+
if (fs.existsSync(designerPath)) {
12+
const existingCode = fs.readFileSync(designerPath, 'utf8');
13+
const lines = existingCode.split('\n');
14+
let currentSummary = '';
15+
let inResourceProperty = false;
16+
let currentProperty = '';
17+
18+
// Extract namespace if it exists
19+
const namespaceMatch = existingCode.match(/namespace\s+([^\s{]+)\s*{/);
20+
if (namespaceMatch) {
21+
existingNamespace = namespaceMatch[1];
22+
}
23+
24+
for (let i = 0; i < lines.length; i++) {
25+
const line = lines[i].trim();
26+
27+
// Check if we're entering a property definition
28+
if (line.includes('static string')) {
29+
inResourceProperty = true;
30+
const match = line.match(/static string (\w+)/);
31+
if (match) {
32+
currentProperty = match[1];
33+
// Only use the summary if we collected one and we're in a property
34+
if (currentSummary && inResourceProperty) {
35+
existingSummaries.set(currentProperty, currentSummary);
36+
}
37+
}
38+
}
39+
// If we hit a closing brace, we're no longer in a property
40+
else if (line === '}') {
41+
inResourceProperty = false;
42+
}
43+
// Capture summary comments only when not already collecting one
44+
else if (line.startsWith('/// <summary>') && !currentSummary) {
45+
currentSummary = '';
46+
// Collect all summary lines until we see the end
47+
while (i < lines.length && !lines[i].trim().endsWith('</summary>')) {
48+
currentSummary += lines[i] + '\n';
49+
i++;
50+
}
51+
currentSummary += lines[i] + '\n'; // Add the </summary> line
52+
}
53+
// Reset summary if we're not in a property and hit another line
54+
else if (!inResourceProperty) {
55+
currentSummary = '';
56+
}
57+
}
58+
}
259

3-
export function generateDesignerCode(resxPath: string, resources: { [key: string]: { value: string; comment?: string } }, accessLevel: 'public' | 'internal' = 'public', existingNamespace?: string): string {
460
const fileName = path.basename(resxPath, '.resx');
561
// Use existing namespace if available, otherwise compute from filename
662
const namespaceName = existingNamespace || (fileName.includes('.') ? fileName.split('.')[0] : 'Resources');
@@ -72,14 +128,18 @@ namespace ${namespaceName} {
72128

73129
// Generate a property for each resource
74130
for (const [key, resource] of Object.entries(resources)) {
75-
// Always add a summary - either the comment or a default message
76-
code += ` /// <summary>\n`;
77-
if (resource.comment) {
78-
code += ` /// ${resource.comment}\n`;
131+
// Use existing summary if available, otherwise generate a new one
132+
if (existingSummaries.has(key)) {
133+
code += existingSummaries.get(key);
79134
} else {
80-
code += ` /// Looks up a localized string similar to ${resource.value}\n`;
135+
code += ` /// <summary>\n`;
136+
if (resource.comment) {
137+
code += ` /// ${resource.comment}\n`;
138+
} else {
139+
code += ` /// Looks up a localized string similar to ${resource.value}.\n`;
140+
}
141+
code += ` /// </summary>\n`;
81142
}
82-
code += ` /// </summary>\n`;
83143
code += ` ${accessLevel} static string ${key} {
84144
get {
85145
return ResourceManager.GetString("${key}", resourceCulture);

0 commit comments

Comments
 (0)