实验页新建、删除类
- "+ 新建类":输入类名,可以带文件夹(SQLHelpers/SQLBLL),文件夹成为命名空间的一段, 模板和 VS 2012 的类模板一样;检查重名、非法名字 - 自己建的类可以删除(窗体、Program.cs、项目资源类不能用这个删) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
13c3e4c3ec
commit
42e258ddcd
3 files changed
+104
-2
No files matched your search
@@ -3,7 +3,7 @@ import { expect, test } from 'bun:test'
|
||||
import { generateDesigner, parseDesigner } from './document'
|
||||
import { addControl } from './edit'
|
||||
import { controlDef } from './catalog'
|
||||
import { assignmentTemplate, formNameTaken, newFormFiles, nextFormName, projectNamespace, startupForm } from './templates'
|
||||
import { assignmentTemplate, classPathError, formNameTaken, newClassFile, newFormFiles, nextFormName, projectNamespace, startupForm } from './templates'
|
||||
|
||||
const files = [
|
||||
{ path: 'Program.cs', content: 'namespace 登录\n{\n static class Program\n {\n static void Main()\n {\n Application.Run(new Login());\n }\n }\n}\n' },
|
||||
@@ -66,3 +66,17 @@ test('作业起点"空白工程":Program.cs 启动空的 Form1', async () => {
|
||||
expect(program).toContain('Application.Run(new Form1())')
|
||||
expect(files.find((f) => f.path === 'Form1.Designer.cs')!.content).not.toContain('com_port')
|
||||
})
|
||||
|
||||
test('新建类:可以带文件夹,文件夹也是命名空间的一段;名字不能重复', () => {
|
||||
const files = [{ path: 'Program.cs', content: 'namespace 智慧校园\n{\n static class Program { }\n}\n' }, { path: 'AppSet.cs', content: 'class AppSet { }' }]
|
||||
expect(newClassFile('智慧校园', 'SQLHelpers/SQLHelper')).toEqual({
|
||||
path: 'SQLHelpers/SQLHelper.cs',
|
||||
content: 'using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace 智慧校园.SQLHelpers\n{\n class SQLHelper\n {\n }\n}\n',
|
||||
})
|
||||
expect(newClassFile('智慧校园', 'RecordClass.cs').path).toBe('RecordClass.cs')
|
||||
expect(classPathError(files, 'SQLHelpers/SQLBLL')).toBeNull()
|
||||
expect(classPathError(files, 'AppSet')).toBe('已经有 AppSet.cs 了')
|
||||
expect(classPathError(files, 'Other/AppSet')).toBe('已经有名为“AppSet”的类或窗体')
|
||||
expect(classPathError(files, '1abc')).toContain('不能以数字开头')
|
||||
expect(classPathError(files, 'Properties/X')).toContain('平台管理')
|
||||
})
|
||||
@@ -22,6 +22,42 @@ export function formNameTaken(files: SourceFile[], name: string): boolean {
|
||||
return files.some((f) => f.path === `${name}.cs` || f.path === `${name}.Designer.cs` || new RegExp(`(?<![\\p{L}\\p{N}_])class\\s+${name}(?![\\p{L}\\p{N}_])`, 'u').test(f.content))
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建类时输入的名字有什么问题(没有问题返回 null)。可以带文件夹,如 SQLHelpers/SQLHelper:
|
||||
* 和 VS 一样,文件放进文件夹,文件夹也是命名空间的一段。
|
||||
*/
|
||||
export function classPathError(files: SourceFile[], input: string): string | null {
|
||||
const path = input.trim().replace(/\\/g, '/').replace(/\.cs$/i, '')
|
||||
if (!path) return '请输入类名'
|
||||
const parts = path.split('/')
|
||||
if (parts.some((p) => !/^[\p{L}_][\p{L}\p{N}_]*$/u.test(p))) return '类名和文件夹名只能用字母、汉字、数字、下划线,且不能以数字开头'
|
||||
if (parts[0] === 'Properties') return 'Properties 文件夹由平台管理,请换一个文件夹'
|
||||
if (files.some((f) => f.path.toLowerCase() === `${path}.cs`.toLowerCase())) return `已经有 ${path}.cs 了`
|
||||
if (formNameTaken(files, parts.at(-1)!)) return `已经有名为“${parts.at(-1)}”的类或窗体`
|
||||
return null
|
||||
}
|
||||
|
||||
/** 新建类(VS 的"添加 → 类"):和 VS 2012 的模板一样 */
|
||||
export function newClassFile(namespace: string, input: string): SourceFile {
|
||||
const path = input.trim().replace(/\\/g, '/').replace(/\.cs$/i, '')
|
||||
const parts = path.split('/')
|
||||
const name = parts.pop()!
|
||||
const content = `using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ${[namespace, ...parts].join('.')}
|
||||
{
|
||||
class ${name}
|
||||
{
|
||||
}
|
||||
}
|
||||
`
|
||||
return { path: `${path}.cs`, content }
|
||||
}
|
||||
|
||||
/** Program.cs 里 Application.Run(new X()) 启动的窗体类名 */
|
||||
export function startupForm(files: SourceFile[]): string | undefined {
|
||||
const program = files.find((f) => f.path === 'Program.cs')
|
||||
|
||||
Reference in new issue
Block a user