Extension을 개발하면서 가장 힘든건 아이디어를 생각하는게 제일 힘듭니다. 뭘 구현해야할지 정하는게 제일 난감한데, 문득 유니티의 팁들을 전부 제공하는 Diagnostic을 제공하는게 어떨까 싶었습니다. Diagnostic이란건 이런기능을 말합니다.
딱봐도 뭔가 개발할게 확 늘어나고 보기도 좋아보이고 사람들이 쓰기 좋을거같아서 기분이 좋았습니다. 머릿속으로 대충 어떻게 구현할지랑 다 생각하고 구조도 다 대략적으로 생각해놓고, Roslyn을 typescript에서 못쓰니까 간단한 cs parser도 만들생각이였습니다. 간만에 할게 늘어나서 두근두근하는 마음으로 집에와서 바로 일단 샘플부터 구현해봤는데..
????? 위에있는게 내가 구현한건데 밑에있는건 누구지??
https://github.com/microsoft/Microsoft.Unity.Analyzers/blob/main/doc/UNT0001.md
마소가 이미 다 만들어놨다.. 갑자기 할게 사라져서 너무 허무한느낌…
할건 날아갔지만 대충 내가 생각한 구조라도 여기에 대충 메모.. (VSCode Extension API도 공유할겸)
우선 VSCode에서 지정된 텍스트에 밑줄을 긋는 API는 아래의 방법을 이용하면 됩니다.
function validateText(document: vscode.TextDocument): vscode.Diagnostic[] {
const diagnostics: vscode.Diagnostic[] = [];
const text = document.getText();
// 텍스트 검사 로직을 이곳에 추가
// 예: text에서 특정 패턴을 찾아 경고를 생성하는 로직
const regex = /console\.log\(/g;
let match;
while (match = regex.exec(text)) {
const startPos = document.positionAt(match.index);
const endPos = document.positionAt(match.index + match[0].length);
const range = new vscode.Range(startPos, endPos);
const diagnostic = new vscode.Diagnostic(range, "Avoid using console.log()", vscode.DiagnosticSeverity.Warning);
diagnostics.push(diagnostic);
}
return diagnostics;
}
DiagnosticSeverity는 4종류있는데 Hint, Warning, Error, Information 이렇게 있습니다. diagnosticCollect에 activateEditor.document를 처음에 activate할때 넣어줘야하고, 이후에는 vscode.workspace.onDidChangeTextDocument같은 이벤트에 등록해서 넣어주면됩니다. 왜 처음에 activate할때 넣냐면 VSCode키고 아무것도 안하고있으면 동작하지않기때문에 좀 어색해서..
QuickFix같은 기능은 CodeActionProvider를 사용하면 됩니다.
class MyCodeActionProvider implements vscode.CodeActionProvider {
provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeAction[]> {
const diagnostic = context.diagnostics[0]; // Assume there's only one diagnostic
const quickFix = new vscode.CodeAction('Replace with a better solution', vscode.CodeActionKind.QuickFix);
quickFix.edit = new vscode.WorkspaceEdit();
quickFix.edit.replace(document.uri, diagnostic.range, 'Better solution');
return [quickFix];
}
}
대충 이런식으로 구현하면 되고 등록은
context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
{ scheme: 'file', language: 'csharp' },
new MyCodeActionProvider()
)
);
를 activate에서 호출하면 됩니다. csharp 대상으로 구현할거니 language는 csharp입니다. 자세한 API설명은 더 필요없을거같고.. 제가 생각한 구조는 우선 document change는 추후에 cs parser를 구현한다고 가정했을때 매번 텍스트가 바뀔때마다 로드하는게 너무 무거울거라고 생각해서 대충 10초 인터벌주기로 diagnostics를 갱신하는 방법을 생각했습니다.
cs simple parser는 그냥 간단하게 regex를 좀 정리해두고 읽은 cs파일 데이터를 라인별로 읽어서 라인별로 생각해둔 regex를 매칭할때마다 bracket {}
기호를 기반으로 적당히 클래스와 메소드구분만 할수있게 구현한뒤
Update, FixedUpdate, LateUpdate 내부에서 사용하는 GetComponent같은거에 경고를 띄우고 그런걸 대략적으로 생각했었습니다.
Empty Update같은건 메소드 구분한 내부 데이터를 Trim해서 string.IsNullEmpty같은거나 CodeActionProvider 내부에서 여러가지 팁을 쓰려면 어떻게 구조를 짜야 확장하기 편할지도 생각하고 그랬었는데 아쉽네요.
그래도 유니티 안티패턴같은게 정리되어있는 MS문서를 발견했으니 나중에 모아서 번역해서 정리해두려고합니다. Snippets 기능을 추가했었는데 영어설명만 지원하고있는데 아예 다국어를 여러가지 (영,한,일,독,중 정도) 지원할까 생각드네요.