From fa3102ee04bda4cccad2f211df0332a1ddf9f9ee Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:08:23 +1100 Subject: [PATCH 01/10] Remove cohosting setting and hardcode the value to true --- package.json | 8 -------- package.nls.cs.json | 3 +-- package.nls.de.json | 3 +-- package.nls.es.json | 3 +-- package.nls.fr.json | 3 +-- package.nls.it.json | 3 +-- package.nls.ja.json | 3 +-- package.nls.json | 1 - package.nls.ko.json | 3 +-- package.nls.pl.json | 3 +-- package.nls.pt-br.json | 3 +-- package.nls.ru.json | 3 +-- package.nls.tr.json | 3 +-- package.nls.zh-cn.json | 3 +-- package.nls.zh-tw.json | 3 +-- src/lsptoolshost/options/configurationMiddleware.ts | 9 +++++++++ src/razor/src/razorLanguageServerOptionsResolver.ts | 2 +- src/shared/options.ts | 2 +- 18 files changed, 24 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index 8571bd56ab..c6444461e1 100644 --- a/package.json +++ b/package.json @@ -1542,14 +1542,6 @@ "type": "boolean", "default": true, "description": "%configuration.razor.languageServer.suppressLspErrorToasts%" - }, - "razor.languageServer.cohostingEnabled": { - "type": "boolean", - "default": true, - "description": "%configuration.razor.languageServer.cohostingEnabled%", - "tags": [ - "experimental" - ] } } }, diff --git a/package.nls.cs.json b/package.nls.cs.json index f2092add5f..1c5bdc57be 100644 --- a/package.nls.cs.json +++ b/package.nls.cs.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Určuje, jestli má server OmniSharp používat nastavení editoru VS Code pro formátování kódu C# (použití tabulátorů, velikost odsazení).", "configuration.omnisharp.useModernNet.description": "Použijte build serveru OmniSharp pro .NET 6. Tato verze _nepodporuje_ projekty .NET Framework, které nejsou ve stylu sady SDK, včetně Unity. U projektů Framework, .NET Core a .NET 5+, které jsou ve stylu sady SDK, byste měli zaznamenat výrazné zlepšení výkonu.", "configuration.omnisharp.useModernNet.title": "Použít build serveru OmniSharp pro .NET 6", - "configuration.razor.languageServer.cohostingEnabled": "Povolte společné hostování Razor.", "configuration.razor.languageServer.debug": "Určuje, jestli se má při spouštění jazykového serveru čekat na připojení ladění.", "configuration.razor.languageServer.directory": "Přepíše cestu k adresáři jazykového serveru Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Potlačí zobrazování informačních zpráv o chybách, pokud na serveru dojde k chybě, ze které se dá zotavit.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Při nastavení této možnosti se text, který cílová aplikace zapisuje do stdout a stderr (např. Console.WriteLine), uloží do zadaného souboru. Tato možnost se bude ignorovat, pokud je konzola nastavená na jinou hodnotu než internalConsole. Příklad: ${workspaceFolder}/out.txt", "generateOptionsSchema.type.markdownDescription": "Typ kódu, který se má ladit. Může to být buď coreclr pro ladění .NET Core, nebo cclr pro Desktop .NET Framework. clr funguje pouze v systému Windows, protože Desktop Framework je určen pouze pro Windows.", "viewsWelcome.debug.contents": "[Generování prostředků jazyka C# pro sestavení a ladění](command:dotnet.generateAssets)\r\n\r\nDalší informace o souboru launch.json najdete v tématu [Konfigurace souboru launch.json pro ladění v jazyce C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.de.json b/package.nls.de.json index d4f7dc3c30..ce0bca804e 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Gibt an, ob OmniSharp VS Code-Editoreinstellungen für C#-Codeformatierung verwenden soll (Verwendung von Registerkarten, Einzugsgröße).", "configuration.omnisharp.useModernNet.description": "Verwenden Sie den OmniSharp-Build für .NET 6. Diese Version unterstützt _keine_ .NET Framework-Projekte, die nicht im SDK-Stil vorliegen, einschließlich Unity. Framework-Projekte im SDK-Stil, .NET Core- und .NET 5+-Projekte sollten erhebliche Leistungsverbesserungen aufweisen.", "configuration.omnisharp.useModernNet.title": ".NET 6-Build von OmniSharp verwenden", - "configuration.razor.languageServer.cohostingEnabled": "Razor-Cohosting aktivieren.", "configuration.razor.languageServer.debug": "Gibt an, ob beim Starten des Sprachservers auf die Debuganfügung gewartet werden soll.", "configuration.razor.languageServer.directory": "Überschreibt den Pfad zum Razor-Sprachserver-Verzeichnis.", "configuration.razor.languageServer.suppressLspErrorToasts": "Unterdrückt, dass Fehler-Popups angezeigt werden, wenn auf dem Server ein wiederherstellbarer Fehler auftritt.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Bei Festlegung wird Text, den die Zielanwendung in \"stdout\" und \"stderr\" (z. B. Console.WriteLine) schreibt, in der angegebenen Datei gespeichert. Diese Option wird ignoriert, wenn die Konsole auf einen anderen Wert als internalConsole festgelegt ist. Beispiel: \"${workspaceFolder}/out.txt\"", "generateOptionsSchema.type.markdownDescription": "Geben Sie den Typ des zu debuggenden Codes ein. Dies kann `coreclr` für das .NET Core-Debugging oder `clr` für Desktop .NET Framework sein. `clr` funktioniert nur für Windows, da das Desktopframework nur Windows ist.", "viewsWelcome.debug.contents": "[C#-Objekte für Build und Debuggen generieren](command:dotnet.generateAssets)\r\n\r\nWeitere Informationen zu launch.json finden Sie unter [Konfigurieren von launch.json für das C#-Debuggen](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.es.json b/package.nls.es.json index b17ac4e85e..ad3083122b 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Especifica si OmniSharp debe usar la configuración VS Code del editor para el formato de código de C# (uso de tabulaciones, tamaño de sangría).", "configuration.omnisharp.useModernNet.description": "Use la compilación de OmniSharp para .NET 6. Esta versión no admite proyectos de .NET Framework que no sean de tipo SDK, incluido Unity. Los proyectos framework de estilo SDK, .NET Core y .NET 5+ deben ver mejoras significativas en el rendimiento.", "configuration.omnisharp.useModernNet.title": "Usar la compilación de .NET 6 de OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Habilite el cohospedaje de Razor.", "configuration.razor.languageServer.debug": "Especifica si se debe esperar a que se adjunte la depuración al iniciar el servidor de lenguaje.", "configuration.razor.languageServer.directory": "Invalida la ruta de acceso al directorio del servidor de lenguaje Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Suprime la visualización de notificaciones del sistema de error si el servidor encuentra un error recuperable.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Cuando se establece, el texto que la aplicación de destino escribe en stdout y stderr (por ejemplo, Console.WriteLine) se guardará en el archivo especificado. Esta opción se omite si la consola se establece en un valor distinto de internalConsole. Por ejemplo, \"${workspaceFolder}/out.txt\"", "generateOptionsSchema.type.markdownDescription": "Escriba el tipo de código que se va a depurar. Puede ser \"coreclr\" para la depuración de .NET Core o \"clr\" para desktop .NET Framework. \"clr\" solo funciona en Windows, ya que el marco de trabajo de escritorio es solo de Windows.", "viewsWelcome.debug.contents": "[Generar recursos de C# para compilación y depuración](command:dotnet.generateAssets)\r\n\r\nPara obtener más información sobre launch.json, consulte [Configuración de launch.json para la depuración de C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.fr.json b/package.nls.fr.json index 34d3cb2890..21a402c19d 100644 --- a/package.nls.fr.json +++ b/package.nls.fr.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Spécifie si OmniSharp doit utiliser VS Code paramètres de l’éditeur pour la mise en forme du code C# (utilisation d’onglets, taille de retrait).", "configuration.omnisharp.useModernNet.description": "Utilisez la version OmniSharp pour .NET 6. Cette version _ne prend pas_ en charge les projets .NET Framework non de style SDK, y compris Unity. Les projets framework de style SDK, .NET Core et .NET 5+ doivent voir des améliorations significatives des performances.", "configuration.omnisharp.useModernNet.title": "Utiliser la version .NET 6 d'OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Activez la cohébergement Razor.", "configuration.razor.languageServer.debug": "Spécifie s’il faut attendre l’attachement du débogage au lancement du serveur de langage.", "configuration.razor.languageServer.directory": "Remplace le chemin d’accès au répertoire du serveur de langage Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Supprime l’affichage des notifications toast d’erreur si le serveur a rencontré une erreur récupérable.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Lorsqu’il est défini, le texte écrit par l’application cible dans stdout et stderr (par exemple, Console.WriteLine) est enregistré dans le fichier spécifié. Cette option est ignorée si la console a une valeur autre que internalConsole. Exemple : « ${workspaceFolder}/out.txt »", "generateOptionsSchema.type.markdownDescription": "Type de code à déboguer. Peut être soit « coreclr » pour le débogage .NET Core, soit « clr » pour Desktop .NET Framework. `clr` ne fonctionne que sous Windows car le framework Desktop est uniquement Windows.", "viewsWelcome.debug.contents": "[Générer des ressources C# pour la génération et le débogage](command:dotnet.generateAssets)\r\n\r\nPour en savoir plus sur launch.json, consultez [Configuration de launch.json pour le débogage C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.it.json b/package.nls.it.json index 18384ae5b5..9a7b2caf75 100644 --- a/package.nls.it.json +++ b/package.nls.it.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Specifica se OmniSharp deve usare le impostazioni dell'editor VS Code per la formattazione del codice C# (uso di tabulazioni, dimensioni rientro).", "configuration.omnisharp.useModernNet.description": "Usare la build OmniSharp per .NET 6. Questa versione _non_ supporta i progetti .NET Framework non di tipo SDK, tra cui Unity. I progetti Framework, .NET Core e .NET 5+ di tipo SDK devono vedere miglioramenti significativi delle prestazioni.", "configuration.omnisharp.useModernNet.title": "Usare la build .NET 6 di OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Abilita il cohosting di Razor.", "configuration.razor.languageServer.debug": "Specifica se attendere il collegamento di debug all'avvio del server di linguaggio.", "configuration.razor.languageServer.directory": "Esegue l'override del percorso della directory del server di linguaggio Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Impedisce la visualizzazione degli avvisi popup di errore se il server rileva un errore reversibile.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Quando questa opzione è impostata, il testo che l'applicazione di destinazione scrive in stdout e stderr, ad esempio Console.WriteLine, verrà salvato nel file specificato. Questa opzione viene ignorata se la console è impostata su un valore diverso da internalConsole. Ad esempio '${workspaceFolder}/out.txt'.", "generateOptionsSchema.type.markdownDescription": "Digitare il tipo di codice di cui eseguire il debug. Può essere `coreclr` per il debug di .NET Core o `clr` per .NET Framework desktop. `clr` funziona solo su Windows poiché il framework desktop è solo per Windows.", "viewsWelcome.debug.contents": "[Genera risorse C# per compilazione e debug](command:dotnet.generateAssets)\r\n\r\nPer altre informazioni su launch.json, vedere [Configurazione di launch.json per il debug di C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.ja.json b/package.nls.ja.json index 8d52f65742..d08b325d89 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "OmniSharp で C# コードの書式設定 (タブ、インデント サイズの使用) に VS Code エディター設定を使用するかどうかを指定します。", "configuration.omnisharp.useModernNet.description": ".NET 6 用の OmniSharp ビルドを使用します。このバージョンは、Unity を含む SDK スタイルではない .NET Framework プロジェクトを _サポートしていません_。SDK スタイルの Framework、.NET Core、および .NET 5+ のプロジェクトでは、パフォーマンスが大幅に向上します。", "configuration.omnisharp.useModernNet.title": "OmniSharp の .NET 6 ビルドを使用する", - "configuration.razor.languageServer.cohostingEnabled": "Razor の共同ホストを有効にします。", "configuration.razor.languageServer.debug": "言語サーバーの起動時にデバッグ アタッチを待機するかどうかを指定します。", "configuration.razor.languageServer.directory": "Razor Language Server ディレクトリへのパスをオーバーライドします。", "configuration.razor.languageServer.suppressLspErrorToasts": "サーバーで回復可能なエラーが発生した場合に、エラー トーストが表示されないようにします。", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "設定すると、ターゲット アプリケーションが StdOut および stderr (例: Console.WriteLine) に書き込むテキストが指定したファイルに保存されます。コンソールが internalConsole 以外に設定されている場合、このオプションは無視されます。例: '${workspaceFolder}/out.txt'", "generateOptionsSchema.type.markdownDescription": "デバッグするコードの種類を入力します。.NET Core デバッグの場合は `coreclr`、デスクトップ .NET Framework の場合は `clr` のいずれかを指定できます。デスクトップ フレームワークは Windows 専用であるため、`clr` は Windows でのみ動作します。", "viewsWelcome.debug.contents": "[ビルドおよびデバッグ用の C# 資産の生成](command:dotnet.generateAssets)\r\n\r\nlaunch.json の詳細については、[C# デバッグ用の launch.json の構成](https://aka.ms/VSCode-CS-LaunchJson). を参照してください。" -} \ No newline at end of file +} diff --git a/package.nls.json b/package.nls.json index aec726d744..23f7f2ffa1 100644 --- a/package.nls.json +++ b/package.nls.json @@ -134,7 +134,6 @@ "configuration.razor.languageServer.debug": "Specifies whether to wait for debug attach when launching the language server.", "configuration.razor.server.trace": "Specifies the logging level to use for the Razor server.", "configuration.razor.languageServer.suppressLspErrorToasts": "Suppresses error toasts from showing up if the server encounters a recoverable error.", - "configuration.razor.languageServer.cohostingEnabled": "Enable Razor cohosting.", "debuggers.coreclr.configurationSnippets.label.console-local": ".NET: Launch Executable file (Console)", "debuggers.coreclr.configurationSnippets.label.web-local": ".NET: Launch Executable file (Web)", "debuggers.coreclr.configurationSnippets.label.attach-local": ".NET: Attach to a .NET process", diff --git a/package.nls.ko.json b/package.nls.ko.json index abea8a8406..535c23cbcd 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "OmniSharp에서 C# 코드 서식 지정(탭 사용, 들여쓰기 크기)에 VS Code 편집기 설정을 사용해야 하는지 여부를 지정합니다.", "configuration.omnisharp.useModernNet.description": ".NET 6에 OmniSharp 빌드를 사용합니다. 이 버전은 Unity를 포함하여 SDK 스타일이 아닌 .NET Framework 프로젝트를 지원하지 _않습니다_. SDK 스타일 Framework, .NET Core, .NET 5 이상 프로젝트에서는 성능이 크게 향상됩니다.", "configuration.omnisharp.useModernNet.title": "OmniSharp의 .NET 6 빌드 사용", - "configuration.razor.languageServer.cohostingEnabled": "Razor 공동 호스트를 사용하도록 설정합니다.", "configuration.razor.languageServer.debug": "언어 서버를 시작할 때 디버그 연결을 기다릴지 여부를 지정합니다.", "configuration.razor.languageServer.directory": "Razor 언어 서버 디렉터리의 경로를 재정의합니다.", "configuration.razor.languageServer.suppressLspErrorToasts": "서버에서 복구 가능한 오류가 발생하는 경우 오류 알림이 표시되지 않도록 합니다.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "설정하면 대상 애플리케이션이 stdout 및 stderr(예: Console.WriteLine)에 쓰는 텍스트가 지정된 파일에 저장됩니다. 콘솔이 internalConsole 이외의 것으로 설정된 경우 이 옵션은 무시됩니다(예: '${workspaceFolder}/out.txt')", "generateOptionsSchema.type.markdownDescription": "디버깅할 코드 형식입니다. .NET Core 디버깅의 경우 `coreclr`, 데스크톱 .NET Framework의 경우 `clr`일 수 있습니다. 데스크톱 프레임워크는 Windows 전용이므로 `clr`은 Windows에서만 작동합니다.", "viewsWelcome.debug.contents": "[빌드와 디버그를 위한 C# 자산 생성](command:dotnet.generateAssets)\r\n\r\nlaunch.json에 관해 자세히 알아보려면 [C# 디버깅을 위한 launch.json 구성](https://aka.ms/VSCode-CS-LaunchJson)을 참조하세요." -} \ No newline at end of file +} diff --git a/package.nls.pl.json b/package.nls.pl.json index d06f0e4ba1..95fbd85390 100644 --- a/package.nls.pl.json +++ b/package.nls.pl.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Określa, czy element OmniSharp powinien używać ustawień edytora VS Code dla formatowania kodu języka C# (używać kart, rozmiaru wcięć).", "configuration.omnisharp.useModernNet.description": "Użyj kompilacji OmniSharp dla platformy .NET 6. Ta wersja _nie_ obsługuje projektów .NET Framework innych niż SDK, w tym aparat Unity. Projekty platformy w stylu zestawu SDK, platformy .NET Core i platformy .NET 5+ powinny widzieć znaczącą poprawę wydajności.", "configuration.omnisharp.useModernNet.title": "Użyj kompilacji .NET 6 elementu OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Włącz współhosting Razor.", "configuration.razor.languageServer.debug": "Określa, czy czekać na dołączenie debugowania podczas uruchamiania serwera języka.", "configuration.razor.languageServer.directory": "Przesłania ścieżkę do katalogu serwera języka Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Pomija wyświetlanie wyskakujących powiadomień o błędach, jeśli serwer napotka błąd do odzyskania.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Po ustawieniu tekst, który aplikacja docelowa zapisuje w stdout i stderr (np. Console.WriteLine), zostanie zapisany w określonym pliku. Ta opcja jest ignorowana, jeśli konsola jest ustawiona na wartość inną niż internalConsole, np. \"${workspaceFolder}/out.txt\"", "generateOptionsSchema.type.markdownDescription": "Wpisz typ kodu do debugowania. Może to być „coreclr” na potrzeby debugowania platformy .NET Core lub „clr” dla platformy klasycznej .NET Framework. Element „clr” działa tylko w systemie Windows, ponieważ platforma klasyczna działa tylko w systemie Windows.", "viewsWelcome.debug.contents": "[Generuj zasoby języka C# na potrzeby kompilacji i debugowania](polecenie:dotnet.generateAssets)\r\n\r\nAby dowiedzieć się więcej o uruchamianiu pliku launch.json, zobacz [Konfigurowanie pliku launch.json na potrzeby debugowania w języku C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.pt-br.json b/package.nls.pt-br.json index e11deab2f5..57802268ba 100644 --- a/package.nls.pt-br.json +++ b/package.nls.pt-br.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Especifica se o OmniSharp deve usar as configurações do editor VS Code para formatar o código C# (uso de tabulações, tamanho do recuo).", "configuration.omnisharp.useModernNet.description": "Use a compilação OmniSharp para .NET 6. Esta versão _não_ suporta projetos que não sejam do estilo SDK .NET Framework, incluindo Unity. Projetos do Framework no estilo SDK, .NET Core e .NET 5+ devem ver melhorias significativas de desempenho.", "configuration.omnisharp.useModernNet.title": "Usar a compilação do .NET 6 da OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Habilite a co-hospedagem do Razor.", "configuration.razor.languageServer.debug": "Especifica se é preciso aguardar o anexo de depuração ao iniciar o servidor de linguagem.", "configuration.razor.languageServer.directory": "Substitui o caminho para o diretório do Servidor de Linguagem Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Suprime a exibição de notificações do erro se o servidor encontrar um erro recuperável.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Quando definido, o texto que o aplicativo de destino grava em stdout e stderr (ex: Console.WriteLine) será salvo no arquivo especificado. Essa opção será ignorada se o console for definido como algo diferente de internalConsole. Por exemplo. '${workspaceFolder}/out.txt'", "generateOptionsSchema.type.markdownDescription": "Tipo de código a ser depurado. Pode ser \"coreclr\" para a depuração do .NET Core ou \"clr\" para o .NET Framework para desktop. O \"clr\" só funciona no Windows, pois o Desktop Framework é exclusivo do Windows.", "viewsWelcome.debug.contents": "[Gerar ativos C# para Build e Depuração](command:dotnet.generateAssets)\r\n\r\nPara saber mais sobre launch.json, consulte [Como configurar launch.json para depuração C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.ru.json b/package.nls.ru.json index 5284539014..586560dbb6 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "Указывает, следует ли OmniSharp использовать параметры редактора VS Code для форматирования кода C# (использование вкладок, размер отступа).", "configuration.omnisharp.useModernNet.description": "Используйте сборку OmniSharp для .NET 6. Эта версия _не_ поддерживает проекты .NET Framework не в стиле SDK, в том числе Unity. Проекты .NET Core, .NET 5+ и платформы .NET Framework в стиле SDK должны значительно повысить производительность.", "configuration.omnisharp.useModernNet.title": "Использовать сборку .NET 6 для OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "Включите совместное размещение Razor.", "configuration.razor.languageServer.debug": "Указывает, следует ли ожидать подключения отладки при запуске языкового сервера.", "configuration.razor.languageServer.directory": "Переопределяет путь к каталогу языкового сервера Razor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Подавляет появление всплывающих сообщений об ошибках, если сервер обнаруживает устранимую ошибку.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Если этот параметр настроен, текст, который целевое приложение записывает в stdout и stderr (например, Console.WriteLine), будет сохранен в указанном файле. Этот параметр игнорируется, если для консоли настроено значение, отличное от internalConsole. Например, \"${workspaceFolder}/out.txt\"", "generateOptionsSchema.type.markdownDescription": "Введите тип кода для отладки. Может быть либо \"coreclr\" для отладки .NET Core, либо \"clr\" для классической .NET Framework. \"clr\" работает только в Windows, так как классическая платформа предназначена только для Windows.", "viewsWelcome.debug.contents": "[Создание ресурсов C# для сборки и отладки](command:dotnet.generateAssets)\r\n\r\nДополнительные сведения о launch.json см. в разделе [Настройка launch.json для отладки C#](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.tr.json b/package.nls.tr.json index 66fcb40e7c..5848e5416c 100644 --- a/package.nls.tr.json +++ b/package.nls.tr.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "OmniSharp'ın C# kod biçimlendirmesi için VS Code düzenleyici ayarlarını kullanıp kullanmayacağını belirtir (sekme kullanımı, girinti boyutu).", "configuration.omnisharp.useModernNet.description": ".NET 6 için OmniSharp derlemesini kullanın. Bu sürüm Unity dahil SDK stili olmayan .NET Framework projelerini desteklemiyor. SDK stili Framework, .NET Core ve .NET 5+ projeleri önemli performans iyileştirmeleri görüyor olmalıdır.", "configuration.omnisharp.useModernNet.title": "OmniSharp'ın .NET 6 derlemesi kullanın", - "configuration.razor.languageServer.cohostingEnabled": "Razor ile birlikte barındırmayı etkinleştirin.", "configuration.razor.languageServer.debug": "Dil sunucusunu başlatırken hata ayıklama eklemesinin beklenip beklenmeyeceğini belirtir.", "configuration.razor.languageServer.directory": "Razor Dil Sunucusu dizininin yolunu geçersiz kılıyor.", "configuration.razor.languageServer.suppressLspErrorToasts": "Sunucu kurtarılabilir bir hatayla karşılaştığında hata bildirimlerinin görünmesini engeller.", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "Ayarlandığında hedef uygulamanın stdout ve stderr'a (ör. Console.WriteLine) yazdığı metin belirtilen dosyaya kaydedilir. Konsol, internalConsole dışında bir değere ayarlanmışsa bu seçenek yoksayılır. Ör. '${workspaceFolder}/out.txt'", "generateOptionsSchema.type.markdownDescription": "Hata ayıklamak için kodun türünü yazın. NET Core hata ayıklama için `coreclr` veya Masaüstü .NET Framework için `clr` olabilir. Masaüstü çerçevesi yalnızca Windows'a özel olduğundan `clr` yalnızca Windows'ta çalışır.", "viewsWelcome.debug.contents": "[Derleme ve Hata Ayıklama için C# Varlıkları Oluşturma](command:dotnet.generateAssets)\r\n\r\nlaunch.json hakkında daha fazla bilgi edinmek için bkz. [C# hata ayıklaması için launch.json yapılandırma](https://aka.ms/VSCode-CS-LaunchJson)." -} \ No newline at end of file +} diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 750c60632f..8d6eb2cb16 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "指定 OmniSharp 是否应使用 VS Code 编辑器设置进行 C# 代码格式化(使用制表符、缩进大小)。", "configuration.omnisharp.useModernNet.description": "使用 .NET 6 版本的 OmniSharp。此版本不支持非 SDK 风格的 .NET Framework 项目,包括 Unity。SDK 样式的框架、.NET Core 和 .NET 5+ 项目应该会获得显著的性能提升。", "configuration.omnisharp.useModernNet.title": "使用 .NET 6 版本的 OmniSharp", - "configuration.razor.languageServer.cohostingEnabled": "启用 Razor 共同托管。", "configuration.razor.languageServer.debug": "指定在启动语言服务器时是否等待调试附加。", "configuration.razor.languageServer.directory": "重写 Razor 语言服务器目录的路径。", "configuration.razor.languageServer.suppressLspErrorToasts": "当服务器遇到可恢复错误时,禁止显示错误 toast。", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "设置后,目标应用程序写入 stdout 和 stderr (例如 Console.WriteLine) 的文本将保存到指定的文件。如果控制台设置为 internalConsole 以外的其他内容,则忽略此选项。例如 \"${workspaceFolder}/out.txt\"", "generateOptionsSchema.type.markdownDescription": "键入要调试的代码类型。可以是用于 .NET Core 调试的“coreclr”,也可以是用于桌面 .NET Framework 的“clr”。由于桌面框架仅适用于 Windows,因此“clr”仅适用于 Windows。", "viewsWelcome.debug.contents": "[为版本和调试生成 C# 资产](command:dotnet.generateAssets)\r\n\r\n若要了解有关 launch.json 的详细信息,请参阅 [为 C# 调试配置 launch.json](https://aka.ms/VSCode-CS-LaunchJson)。" -} \ No newline at end of file +} diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 273a3913db..1a707fdcbf 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -125,7 +125,6 @@ "configuration.omnisharp.useEditorFormattingSettings": "指定 OmniSharp 是否應該針對 C# 程式碼格式設定 (使用 Tab、縮排大小) 使用 VS Code 編輯器設定。", "configuration.omnisharp.useModernNet.description": "使用適用於 .NET 6 的 OmniSharp 組建。此版本不支援非 SDK 樣式的 .NET Framework 專案,包括 Unity。SDK 樣式的 Framework、.NET Core 和 .NET 5+ 專案應該會大幅提升效能。", "configuration.omnisharp.useModernNet.title": "使用 OmniSharp 的 .NET 6 版本", - "configuration.razor.languageServer.cohostingEnabled": "啟用 Razor 共同託管。", "configuration.razor.languageServer.debug": "指定啟動語言伺服器時,是否要等候偵錯附加。", "configuration.razor.languageServer.directory": "覆寫 Razor 語言伺服器目錄的路徑。", "configuration.razor.languageServer.suppressLspErrorToasts": "如果伺服器發生可復原的錯誤,隱藏不顯示錯誤快顯通知。", @@ -261,4 +260,4 @@ "generateOptionsSchema.targetOutputLogPath.description": "設定時,目標應用程式寫入 stdout 和 stderr 的文字 (例如: Console.WriteLine) 將會儲存到指定的檔案。如果主控台設定為 internalConsole 以外的項目,則會略過此選項。例如 '${workspaceFolder}/out.txt'", "generateOptionsSchema.type.markdownDescription": "輸入要進行偵錯的程式碼類型。可以是 `coreclr` 表示 .NET Core 偵錯,或 `clr` 表示桌面 .NET Framework。`clr` 僅在 Windows 上運作,因為桌面 Framework 僅限 Windows。", "viewsWelcome.debug.contents": "[為組建和偵錯產生 C# 資產](command:dotnet.generateAssets)\r\n\r\n若要深入了解 launch.json,請參閱[為 C# 偵錯設定 launch.json](https://aka.ms/VSCode-CS-LaunchJson)(英文)。" -} \ No newline at end of file +} diff --git a/src/lsptoolshost/options/configurationMiddleware.ts b/src/lsptoolshost/options/configurationMiddleware.ts index 352ec81515..8ce2070569 100644 --- a/src/lsptoolshost/options/configurationMiddleware.ts +++ b/src/lsptoolshost/options/configurationMiddleware.ts @@ -22,6 +22,15 @@ export function readConfigurations(params: ConfigurationParams): (string | null) continue; } + // HACK: https://github.com/dotnet/razor/issues/12491 + // In order to allow us to remove the cohosting setting, without a dual Roslyn and Razor + // insertion, we're just going to hardcode it to true, until we have removed and inserted + // the code in those repos that check it + if (section === 'razor.language_server.cohosting_enabled') { + result.push('true'); + continue; + } + // Server use a different name compare to the name defined in client, so do the remapping. const clientSideName = convertServerOptionNameToClientConfigurationName(section); if (clientSideName == null) { diff --git a/src/razor/src/razorLanguageServerOptionsResolver.ts b/src/razor/src/razorLanguageServerOptionsResolver.ts index 33d54bf6fb..d6b2adb5b3 100644 --- a/src/razor/src/razorLanguageServerOptionsResolver.ts +++ b/src/razor/src/razorLanguageServerOptionsResolver.ts @@ -24,7 +24,7 @@ export function resolveRazorLanguageServerOptions( !getCSharpDevKit() && vscodeApi.workspace.getConfiguration().get('dotnet.server.useOmnisharp'); const suppressErrorToasts = serverConfig.get('suppressLspErrorToasts'); - const cohostingEnabled = serverConfig.get('cohostingEnabled'); + const cohostingEnabled = true; return { serverPath: languageServerExecutablePath, diff --git a/src/shared/options.ts b/src/shared/options.ts index d9643a654a..86877625dc 100644 --- a/src/shared/options.ts +++ b/src/shared/options.ts @@ -432,7 +432,7 @@ class RazorOptionsImpl implements RazorOptions { return readOption('razor.languageServer.directory', ''); } public get cohostingEnabled() { - return readOption('razor.languageServer.cohostingEnabled', false); + return true; } } From c63da243f03065fa8da4351d18cf96d2171319ac Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:13:38 +1100 Subject: [PATCH 02/10] Remove checks for cohosting --- .../projectContext/projectContextService.ts | 11 ++------- .../projectContext/projectContextStatus.ts | 8 +++---- src/lsptoolshost/razor/razorEndpoints.ts | 15 ++++-------- .../server/roslynLanguageServer.ts | 24 +++++++------------ .../src/dynamicFile/dynamicFileInfoHandler.ts | 15 ------------ src/razor/src/extension.ts | 11 +-------- 6 files changed, 20 insertions(+), 64 deletions(-) diff --git a/src/lsptoolshost/projectContext/projectContextService.ts b/src/lsptoolshost/projectContext/projectContextService.ts index 621e67da15..6a1d3167c4 100644 --- a/src/lsptoolshost/projectContext/projectContextService.ts +++ b/src/lsptoolshost/projectContext/projectContextService.ts @@ -53,15 +53,8 @@ export class ProjectContextService { public async refresh() { const textEditor = vscode.window.activeTextEditor; const languageId = textEditor?.document?.languageId; - if (languageId !== 'csharp') { - if (languageId !== 'aspnetcorerazor') { - return; - } - - // We only support Razor when cohosting is enabled. - if (!razorOptions.cohostingEnabled) { - return; - } + if (languageId !== 'csharp' && languageId !== 'aspnetcorerazor') { + return; } // If we have an open request, cancel it. diff --git a/src/lsptoolshost/projectContext/projectContextStatus.ts b/src/lsptoolshost/projectContext/projectContextStatus.ts index bcdac68f0d..8239281ab8 100644 --- a/src/lsptoolshost/projectContext/projectContextStatus.ts +++ b/src/lsptoolshost/projectContext/projectContextStatus.ts @@ -12,10 +12,10 @@ import { combineDocumentSelectors } from '../../shared/utils/combineDocumentSele export class ProjectContextStatus { static createStatusItem(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) { - // We only support Razor when cohosting is enabled. - const documentSelector = razorOptions.cohostingEnabled - ? combineDocumentSelectors(languageServerOptions.documentSelector, RazorLanguage.documentSelector) - : combineDocumentSelectors(languageServerOptions.documentSelector); + const documentSelector = combineDocumentSelectors( + languageServerOptions.documentSelector, + RazorLanguage.documentSelector + ); const projectContextService = languageServer._projectContextService; const item = vscode.languages.createLanguageStatusItem('csharp.projectContextStatus', documentSelector); diff --git a/src/lsptoolshost/razor/razorEndpoints.ts b/src/lsptoolshost/razor/razorEndpoints.ts index ecd5a76646..f66a0abe62 100644 --- a/src/lsptoolshost/razor/razorEndpoints.ts +++ b/src/lsptoolshost/razor/razorEndpoints.ts @@ -66,16 +66,11 @@ export function registerRazorEndpoints( razorLogger.log(params.message, params.type) ); - if (razorOptions.cohostingEnabled) { - vscode.commands.executeCommand('setContext', 'razor.mode', 'cohosting'); - registerCohostingEndpoints(); - - context.subscriptions.push(BlazorDebugConfigurationProvider.register(razorLogger, vscode)); - context.subscriptions.push(ShowGeneratedDocumentCommand.register(roslynLanguageServer)); - } else { - vscode.commands.executeCommand('setContext', 'razor.mode', 'lsp'); - registerNonCohostingEndpoints(); - } + vscode.commands.executeCommand('setContext', 'razor.mode', 'cohosting'); + registerCohostingEndpoints(); + + context.subscriptions.push(BlazorDebugConfigurationProvider.register(razorLogger, vscode)); + context.subscriptions.push(ShowGeneratedDocumentCommand.register(roslynLanguageServer)); return; diff --git a/src/lsptoolshost/server/roslynLanguageServer.ts b/src/lsptoolshost/server/roslynLanguageServer.ts index 6ddc1ccadc..c733b98dbc 100644 --- a/src/lsptoolshost/server/roslynLanguageServer.ts +++ b/src/lsptoolshost/server/roslynLanguageServer.ts @@ -656,17 +656,11 @@ export class RoslynLanguageServer { razorComponentPath = path.dirname(extPath); }); - // If cohosting is enabled we get the source generator from the razor component path - const razorSourceGeneratorPath = razorOptions.cohostingEnabled ? razorComponentPath : razorPath; - - args.push( - '--razorSourceGenerator', - path.join(razorSourceGeneratorPath, 'Microsoft.CodeAnalysis.Razor.Compiler.dll') - ); + args.push('--razorSourceGenerator', path.join(razorComponentPath, 'Microsoft.CodeAnalysis.Razor.Compiler.dll')); args.push( '--razorDesignTimePath', - path.join(razorSourceGeneratorPath, 'Targets', 'Microsoft.NET.Sdk.Razor.DesignTime.targets') + path.join(razorComponentPath, 'Targets', 'Microsoft.NET.Sdk.Razor.DesignTime.targets') ); // Get the brokered service pipe name from C# Dev Kit (if installed). @@ -707,14 +701,12 @@ export class RoslynLanguageServer { await vscode.commands.executeCommand('setContext', 'dotnet.server.activationContext', 'Roslyn'); _wasActivatedWithCSharpDevkit = false; - if (razorOptions.cohostingEnabled) { - // Razor has code in Microsoft.CSharp.DesignTime.targets to handle non-Razor-SDK projects, but that doesn't get imported outside - // of DevKit so we polyfill with a mini-version that Razor provides for that scenario. - args.push( - '--csharpDesignTimePath', - path.join(razorComponentPath, 'Targets', 'Microsoft.CSharpExtension.DesignTime.targets') - ); - } + // Razor has code in Microsoft.CSharp.DesignTime.targets to handle non-Razor-SDK projects, but that doesn't get imported outside + // of DevKit so we polyfill with a mini-version that Razor provides for that scenario. + args.push( + '--csharpDesignTimePath', + path.join(razorComponentPath, 'Targets', 'Microsoft.CSharpExtension.DesignTime.targets') + ); } for (const extensionPath of additionalExtensionPaths) { diff --git a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts index 2457e78704..f6b67e8874 100644 --- a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts +++ b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts @@ -40,21 +40,6 @@ export class DynamicFileInfoHandler { await this.removeDynamicFileInfo(request); } ); - - if (!razorOptions.cohostingEnabled) { - this.documentManager.onChange(async (e) => { - // Ignore any updates without text changes. This is important for perf since sending an update to roslyn does - // a round trip for producing nothing new and causes a lot of churn in solution updates. - if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen && e.changes.length > 0) { - const uriString = UriConverter.serialize(e.document.uri); - const identifier = TextDocumentIdentifier.create(uriString); - await vscode.commands.executeCommand( - DynamicFileInfoHandler.dynamicFileUpdatedCommand, - new RazorDynamicFileChangedParams(identifier) - ); - } - }); - } } // Given Razor document URIs, returns associated generated doc URIs diff --git a/src/razor/src/extension.ts b/src/razor/src/extension.ts index a2555ac0b7..ead3dc9041 100644 --- a/src/razor/src/extension.ts +++ b/src/razor/src/extension.ts @@ -78,16 +78,7 @@ export async function activate( logger ); - if (razorOptions.cohostingEnabled) { - // TODO: We still need a document manager for Html, so need to do _some_ of the below, just not sure what yet, - // and it needs to be able to take a roslynLanguageServerClient instead of a razorLanguageServerClient I guess. - - logger.logTrace( - 'Razor cohosting is enabled, skipping language server activation. No rzls process will be created.' - ); - - return; - } + return; const hostExecutableResolver = new DotnetRuntimeExtensionResolver( platformInfo, From 5e24bad95d9b102a31e072acb26451b46d7d7733 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:23:58 +1100 Subject: [PATCH 03/10] Remove unused things --- .../projectContext/projectContextService.ts | 1 - .../projectContext/projectContextStatus.ts | 2 +- src/lsptoolshost/razor/razorEndpoints.ts | 35 ------------------- .../server/roslynLanguageServer.ts | 7 +--- .../src/dynamicFile/dynamicFileInfoHandler.ts | 4 --- src/razor/src/razorLanguageServerOptions.ts | 1 - .../src/razorLanguageServerOptionsResolver.ts | 2 -- src/shared/options.ts | 4 --- 8 files changed, 2 insertions(+), 54 deletions(-) diff --git a/src/lsptoolshost/projectContext/projectContextService.ts b/src/lsptoolshost/projectContext/projectContextService.ts index 6a1d3167c4..e22f2550e0 100644 --- a/src/lsptoolshost/projectContext/projectContextService.ts +++ b/src/lsptoolshost/projectContext/projectContextService.ts @@ -9,7 +9,6 @@ import { VSGetProjectContextsRequest, VSProjectContext, VSProjectContextList } f import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; import { UriConverter } from '../utils/uriConverter'; import { LanguageServerEvents, ServerState } from '../server/languageServerEvents'; -import { razorOptions } from '../../shared/options'; export interface ProjectContextChangeEvent { languageId: string; diff --git a/src/lsptoolshost/projectContext/projectContextStatus.ts b/src/lsptoolshost/projectContext/projectContextStatus.ts index 8239281ab8..4188f3169f 100644 --- a/src/lsptoolshost/projectContext/projectContextStatus.ts +++ b/src/lsptoolshost/projectContext/projectContextStatus.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; import { RoslynLanguageServer } from '../server/roslynLanguageServer'; -import { languageServerOptions, razorOptions } from '../../shared/options'; +import { languageServerOptions } from '../../shared/options'; import { RazorLanguage } from '../../razor/src/razorLanguage'; import { ServerState } from '../server/languageServerEvents'; import { combineDocumentSelectors } from '../../shared/utils/combineDocumentSelectors'; diff --git a/src/lsptoolshost/razor/razorEndpoints.ts b/src/lsptoolshost/razor/razorEndpoints.ts index f66a0abe62..58a4824d1c 100644 --- a/src/lsptoolshost/razor/razorEndpoints.ts +++ b/src/lsptoolshost/razor/razorEndpoints.ts @@ -35,19 +35,10 @@ import { UriConverter } from '../utils/uriConverter'; import { PlatformInformation } from '../../shared/platform'; import { HtmlDocumentManager } from './htmlDocumentManager'; import { DocumentColorHandler } from '../../razor/src/documentColor/documentColorHandler'; -import { razorOptions } from '../../shared/options'; import { ColorPresentationHandler } from '../../razor/src/colorPresentation/colorPresentationHandler'; import { convertRangeToSerializable } from '../../razor/src/rpc/serializableRange'; import { FoldingRangeHandler } from '../../razor/src/folding/foldingRangeHandler'; import { CompletionHandler } from '../../razor/src/completion/completionHandler'; -import { DynamicFileInfoHandler } from '../../razor/src/dynamicFile/dynamicFileInfoHandler'; -import { ProvideDynamicFileParams } from '../../razor/src/dynamicFile/provideDynamicFileParams'; -import { ProvideDynamicFileResponse } from '../../razor/src/dynamicFile/provideDynamicFileResponse'; -import { RazorMapSpansParams } from '../../razor/src/mapping/razorMapSpansParams'; -import { RazorMapSpansResponse } from '../../razor/src/mapping/razorMapSpansResponse'; -import { MappingHandler } from '../../razor/src/mapping/mappingHandler'; -import { RazorMapTextChangesParams } from '../../razor/src/mapping/razorMapTextChangesParams'; -import { RazorMapTextChangesResponse } from '../../razor/src/mapping/razorMapTextChangesResponse'; import { FormattingHandler } from '../../razor/src/formatting/formattingHandler'; import { ReportIssueCommand } from '../../razor/src/diagnostics/reportIssueCommand'; import { HtmlDocument } from './htmlDocument'; @@ -207,32 +198,6 @@ export function registerRazorEndpoints( }); } - function registerNonCohostingEndpoints() { - registerMethodHandler( - 'razor/provideDynamicFileInfo', - async (params) => - vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, params) - ); - - registerMethodHandler( - 'razor/removeDynamicFileInfo', - async (params) => - vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, params) - ); - registerMethodHandler('razor/mapSpans', async (params) => { - return await vscode.commands.executeCommand(MappingHandler.MapSpansCommand, params); - }); - registerMethodHandler( - 'razor/mapTextChanges', - async (params) => { - return await vscode.commands.executeCommand( - MappingHandler.MapChangesCommand, - params - ); - } - ); - } - // Helper method that registers a request handler, and logs errors to the Razor logger. function registerCohostHandler( type: RequestType, diff --git a/src/lsptoolshost/server/roslynLanguageServer.ts b/src/lsptoolshost/server/roslynLanguageServer.ts index c733b98dbc..4d9848829e 100644 --- a/src/lsptoolshost/server/roslynLanguageServer.ts +++ b/src/lsptoolshost/server/roslynLanguageServer.ts @@ -52,7 +52,7 @@ import { DotnetInfo } from '../../shared/utils/dotnetInfo'; import { RoslynLanguageServerEvents, ServerState } from './languageServerEvents'; import { registerShowToastNotification } from '../handlers/showToastNotification'; import { registerOnAutoInsert } from '../autoInsert/onAutoInsert'; -import { commonOptions, languageServerOptions, omnisharpOptions, razorOptions } from '../../shared/options'; +import { commonOptions, languageServerOptions, omnisharpOptions } from '../../shared/options'; import { NamedPipeInformation } from './roslynProtocol'; import { IDisposable } from '../../disposable'; import { BuildDiagnosticsService } from '../diagnostics/buildDiagnosticsService'; @@ -645,11 +645,6 @@ export class RoslynLanguageServer { args.push('--logLevel', logLevel); } - const razorPath = - razorOptions.razorServerPath === '' - ? path.join(context.extension.extensionPath, '.razor') - : razorOptions.razorServerPath; - let razorComponentPath = ''; getComponentPaths('razorExtension', languageServerOptions, channel).forEach((extPath) => { additionalExtensionPaths.push(extPath); diff --git a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts index f6b67e8874..fc34e9a9e4 100644 --- a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts +++ b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts @@ -11,12 +11,8 @@ import { ProvideDynamicFileParams } from './provideDynamicFileParams'; import { ProvideDynamicFileResponse } from './provideDynamicFileResponse'; import { RemoveDynamicFileParams } from './removeDynamicFileParams'; import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { RazorDynamicFileChangedParams } from './dynamicFileUpdatedParams'; -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; import { razorTextChange } from './razorTextChange'; import { razorTextSpan } from './razorTextSpan'; -import { razorOptions } from '../../../shared/options'; // Handles Razor generated doc communication between the Roslyn workspace and Razor. // didChange behavior for Razor generated docs is handled in the RazorDocumentManager. diff --git a/src/razor/src/razorLanguageServerOptions.ts b/src/razor/src/razorLanguageServerOptions.ts index 9e9568dbe7..356bc32ad8 100644 --- a/src/razor/src/razorLanguageServerOptions.ts +++ b/src/razor/src/razorLanguageServerOptions.ts @@ -11,5 +11,4 @@ export interface RazorLanguageServerOptions { debug?: boolean; usingOmniSharp: boolean; suppressErrorToasts: boolean; - cohostingEnabled: boolean; } diff --git a/src/razor/src/razorLanguageServerOptionsResolver.ts b/src/razor/src/razorLanguageServerOptionsResolver.ts index d6b2adb5b3..8ea7ade13a 100644 --- a/src/razor/src/razorLanguageServerOptionsResolver.ts +++ b/src/razor/src/razorLanguageServerOptionsResolver.ts @@ -24,7 +24,6 @@ export function resolveRazorLanguageServerOptions( !getCSharpDevKit() && vscodeApi.workspace.getConfiguration().get('dotnet.server.useOmnisharp'); const suppressErrorToasts = serverConfig.get('suppressLspErrorToasts'); - const cohostingEnabled = true; return { serverPath: languageServerExecutablePath, @@ -32,7 +31,6 @@ export function resolveRazorLanguageServerOptions( outputChannel: logger.outputChannel, usingOmniSharp, suppressErrorToasts, - cohostingEnabled, } as RazorLanguageServerOptions; } diff --git a/src/shared/options.ts b/src/shared/options.ts index 86877625dc..7d3526acb2 100644 --- a/src/shared/options.ts +++ b/src/shared/options.ts @@ -88,7 +88,6 @@ export interface RazorOptions { readonly razorDevMode: boolean; readonly razorPluginPath: string; readonly razorServerPath: string; - readonly cohostingEnabled: boolean; } class CommonOptionsImpl implements CommonOptions { @@ -431,9 +430,6 @@ class RazorOptionsImpl implements RazorOptions { public get razorServerPath() { return readOption('razor.languageServer.directory', ''); } - public get cohostingEnabled() { - return true; - } } export const commonOptions: CommonOptions = new CommonOptionsImpl(); From a43ff877539a3e0177381b2e852b3463fb53ce5c Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:35:42 +1100 Subject: [PATCH 04/10] Remove old Razor extension class and leave Omnisharp --- src/activateOmniSharp.ts | 15 +- src/activateRoslyn.ts | 21 --- src/razor/razor.ts | 67 ------- src/razor/razorOmnisharp.ts | 36 ++++ src/razor/src/extension.ts | 366 ------------------------------------ 5 files changed, 38 insertions(+), 467 deletions(-) delete mode 100644 src/razor/razor.ts create mode 100644 src/razor/razorOmnisharp.ts delete mode 100644 src/razor/src/extension.ts diff --git a/src/activateOmniSharp.ts b/src/activateOmniSharp.ts index 05659a943b..5358fcaab1 100644 --- a/src/activateOmniSharp.ts +++ b/src/activateOmniSharp.ts @@ -12,8 +12,7 @@ import TelemetryReporter from '@vscode/extension-telemetry'; import { activateOmniSharpLanguageServer } from './omnisharp/omnisharpLanguageServer'; import { EventStream } from './eventStream'; import { razorOptions } from './shared/options'; -import { activateRazorExtension } from './razor/razor'; -import { RazorLogger } from './razor/src/razorLogger'; +import { activateRazorOmniSharpExtension } from './razor/razorOmnisharp'; export function activateOmniSharp( context: vscode.ExtensionContext, @@ -40,19 +39,9 @@ export function activateOmniSharp( reporter ); - const razorLogger = new RazorLogger(); let omnisharpRazorPromise: Promise | undefined = undefined; if (!razorOptions.razorDevMode) { - omnisharpRazorPromise = activateRazorExtension( - context, - context.extension.extensionPath, - eventStream, - reporter, - undefined, - platformInfo, - /* useOmnisharpServer */ true, - razorLogger - ); + omnisharpRazorPromise = activateRazorOmniSharpExtension(context, context.extension.extensionPath, eventStream); } const coreClrDebugPromise = getCoreClrDebugPromise(omnisharpLangServicePromise); diff --git a/src/activateRoslyn.ts b/src/activateRoslyn.ts index 65a26b7971..45342fb7f0 100644 --- a/src/activateRoslyn.ts +++ b/src/activateRoslyn.ts @@ -5,7 +5,6 @@ import * as vscode from 'vscode'; import { CSharpExtensionExports } from './csharpExtensionExports'; -import { activateRazorExtension } from './razor/razor'; import { PlatformInformation } from './shared/platform'; import { Observable } from 'rxjs'; import { EventStream } from './eventStream'; @@ -42,25 +41,6 @@ export function activateRoslyn( const razorLogger = new RazorLogger(); - // Activate Razor. Needs to be activated before Roslyn so commands are registered in the correct order. - // Otherwise, if Roslyn starts up first, they could execute commands that don't yet exist on Razor's end. - // - // Flow: - // Razor starts up and registers dynamic file info commands -> - // Roslyn starts up and registers Razor-specific didOpen/didClose/didChange commands and sends request to Razor - // for dynamic file info once project system is ready -> - // Razor sends didOpen commands to Roslyn for generated docs and responds to request with dynamic file info - const razorLanguageServerStartedPromise = activateRazorExtension( - context, - context.extension.extensionPath, - eventStream, - reporter, - csharpDevkitExtension, - platformInfo, - /* useOmnisharpServer */ false, - razorLogger - ); - // Setup a listener for project initialization complete before we start the server. const projectInitializationCompletePromise = new Promise((resolve, _) => { roslynLanguageServerEvents.onServerStateChange(async (e) => { @@ -90,7 +70,6 @@ export function activateRoslyn( isLimitedActivation: false, initializationFinished: async () => { await coreClrDebugPromise; - await razorLanguageServerStartedPromise; await roslynLanguageServerStartedPromise; await projectInitializationCompletePromise; }, diff --git a/src/razor/razor.ts b/src/razor/razor.ts deleted file mode 100644 index 0fe92db802..0000000000 --- a/src/razor/razor.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as fs from 'fs'; -import * as RazorOmniSharp from 'microsoft.aspnetcore.razor.vscode'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import * as Razor from '../../src/razor/src/extension'; -import { EventStream } from '../eventStream'; -import TelemetryReporter from '@vscode/extension-telemetry'; -import { PlatformInformation } from '../shared/platform'; -import { showWarningMessage } from '../shared/observers/utils/showMessage'; -import { RazorLogger } from './src/razorLogger'; - -export async function activateRazorExtension( - context: vscode.ExtensionContext, - extensionPath: string, - eventStream: EventStream, - vscodeTelemetryReporter: TelemetryReporter, - csharpDevkitExtension: vscode.Extension | undefined, - platformInfo: PlatformInformation, - useOmnisharpServer: boolean, - logger: RazorLogger -) { - const razorConfig = vscode.workspace.getConfiguration('razor'); - const configuredLanguageServerDir = razorConfig.get('languageServer.directory', ''); - const languageServerDir = - configuredLanguageServerDir.length > 0 - ? configuredLanguageServerDir - : useOmnisharpServer - ? path.join(extensionPath, '.razoromnisharp') - : path.join(extensionPath, '.razor'); - - if (fs.existsSync(languageServerDir)) { - if (useOmnisharpServer) { - await RazorOmniSharp.activate( - vscode, - context, - languageServerDir, - eventStream, - /* enableProposedApis: */ false - ); - } else { - await Razor.activate( - vscode, - context, - languageServerDir, - eventStream, - vscodeTelemetryReporter, - csharpDevkitExtension, - platformInfo, - logger, - /* enableProposedApis: */ false - ); - } - } else { - showWarningMessage( - vscode, - vscode.l10n.t( - "Cannot load Razor language server because the directory was not found: '{0}'", - languageServerDir - ) - ); - } -} diff --git a/src/razor/razorOmnisharp.ts b/src/razor/razorOmnisharp.ts new file mode 100644 index 0000000000..21a341e865 --- /dev/null +++ b/src/razor/razorOmnisharp.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs'; +import * as RazorOmniSharp from 'microsoft.aspnetcore.razor.vscode'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { EventStream } from '../eventStream'; +import { showWarningMessage } from '../shared/observers/utils/showMessage'; + +export async function activateRazorOmniSharpExtension( + context: vscode.ExtensionContext, + extensionPath: string, + eventStream: EventStream +) { + const razorConfig = vscode.workspace.getConfiguration('razor'); + const configuredLanguageServerDir = razorConfig.get('languageServer.directory', ''); + const languageServerDir = + configuredLanguageServerDir.length > 0 + ? configuredLanguageServerDir + : path.join(extensionPath, '.razoromnisharp'); + + if (fs.existsSync(languageServerDir)) { + await RazorOmniSharp.activate(vscode, context, languageServerDir, eventStream, /* enableProposedApis: */ false); + } else { + showWarningMessage( + vscode, + vscode.l10n.t( + "Cannot load Razor OmniSharp language server because the directory was not found: '{0}'", + languageServerDir + ) + ); + } +} diff --git a/src/razor/src/extension.ts b/src/razor/src/extension.ts deleted file mode 100644 index ead3dc9041..0000000000 --- a/src/razor/src/extension.ts +++ /dev/null @@ -1,366 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as vscodeapi from 'vscode'; -import { ExtensionContext } from 'vscode'; -import { CodeActionsHandler } from './codeActions/codeActionsHandler'; -import { CompletionHandler } from './completion/completionHandler'; -import { RazorCodeActionRunner } from './codeActions/razorCodeActionRunner'; -import { RazorCodeLensProvider } from './codeLens/razorCodeLensProvider'; -import { ColorPresentationHandler } from './colorPresentation/colorPresentationHandler'; -import { RazorCSharpFeature } from './csharp/razorCSharpFeature'; -import { RazorDefinitionProvider } from './definition/razorDefinitionProvider'; -import { ReportIssueCommand } from './diagnostics/reportIssueCommand'; -import { RazorDocumentManager } from './document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from './document/razorDocumentSynchronizer'; -import { DocumentColorHandler } from './documentColor/documentColorHandler'; -import { RazorDocumentHighlightProvider } from './documentHighlight/razorDocumentHighlightProvider'; -import { reportTelemetryForDocuments } from './documentTelemetryListener'; -import { DynamicFileInfoHandler } from './dynamicFile/dynamicFileInfoHandler'; -import { FoldingRangeHandler } from './folding/foldingRangeHandler'; -import { FormattingHandler } from './formatting/formattingHandler'; -import { HostEventStream } from './hostEventStream'; -import { RazorHoverProvider } from './hover/razorHoverProvider'; -import { RazorHtmlFeature } from './html/razorHtmlFeature'; -import { IEventEmitterFactory } from './IEventEmitterFactory'; -import { RazorImplementationProvider } from './implementation/razorImplementationProvider'; -import { ProposedApisFeature } from './proposedApisFeature'; -import { RazorLanguage } from './razorLanguage'; -import { RazorLanguageConfiguration } from './razorLanguageConfiguration'; -import { RazorLanguageServerClient } from './razorLanguageServerClient'; -import { RazorLanguageServiceClient } from './razorLanguageServiceClient'; -import { RazorLogger } from './razorLogger'; -import { RazorReferenceProvider } from './reference/razorReferenceProvider'; -import { RazorRenameProvider } from './rename/razorRenameProvider'; -import { SemanticTokensRangeHandler } from './semantic/semanticTokensRangeHandler'; -import { RazorSignatureHelpProvider } from './signatureHelp/razorSignatureHelpProvider'; -import { TelemetryReporter as RazorTelemetryReporter } from './telemetryReporter'; -import { RazorDiagnosticHandler } from './diagnostics/razorDiagnosticHandler'; -import { RazorSimplifyMethodHandler } from './simplify/razorSimplifyMethodHandler'; -import TelemetryReporter from '@vscode/extension-telemetry'; -import { CSharpDevKitExports } from '../../csharpDevKitExports'; -import { DotnetRuntimeExtensionResolver } from '../../lsptoolshost/dotnetRuntime/dotnetRuntimeExtensionResolver'; -import { PlatformInformation } from '../../shared/platform'; -import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; -import { resolveRazorLanguageServerOptions } from './razorLanguageServerOptionsResolver'; -import { RazorFormatNewFileHandler } from './formatNewFile/razorFormatNewFileHandler'; -import { InlayHintHandler } from './inlayHint/inlayHintHandler'; -import { InlayHintResolveHandler } from './inlayHint/inlayHintResolveHandler'; -import { getComponentPaths } from '../../lsptoolshost/extensions/builtInComponents'; -import { BlazorDebugConfigurationProvider } from './blazorDebug/blazorDebugConfigurationProvider'; -import { MappingHandler } from './mapping/mappingHandler'; - -// We specifically need to take a reference to a particular instance of the vscode namespace, -// otherwise providers attempt to operate on the null extension. -export async function activate( - vscodeType: typeof vscodeapi, - context: ExtensionContext, - languageServerDir: string, - eventStream: HostEventStream, - vscodeTelemetryReporter: TelemetryReporter, - csharpDevkitExtension: vscode.Extension | undefined, - platformInfo: PlatformInformation, - logger: RazorLogger, - enableProposedApis = false -) { - const razorTelemetryReporter = new RazorTelemetryReporter(eventStream); - const eventEmitterFactory: IEventEmitterFactory = { - create: () => new vscode.EventEmitter(), - }; - - try { - const razorOptions: RazorLanguageServerOptions = resolveRazorLanguageServerOptions( - vscodeType, - languageServerDir, - logger - ); - - return; - - const hostExecutableResolver = new DotnetRuntimeExtensionResolver( - platformInfo, - () => razorOptions.serverPath, - logger.outputChannel, - context.extensionPath - ); - - const dotnetInfo = await hostExecutableResolver.getHostExecutableInfo(); - - let telemetryExtensionDllPath = ''; - // Set up DevKit environment for telemetry - if (csharpDevkitExtension) { - await setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension, logger); - - if (vscode.env.isTelemetryEnabled) { - const razorComponentPaths = getComponentPaths('razorDevKit', undefined, logger.outputChannel); - if (razorComponentPaths.length !== 1) { - logger.logError('Failed to find Razor DevKit telemetry extension path.', undefined); - } else { - telemetryExtensionDllPath = razorComponentPaths[0]; - } - } - } - - const languageServerClient = new RazorLanguageServerClient( - vscodeType, - languageServerDir, - razorTelemetryReporter, - vscodeTelemetryReporter, - telemetryExtensionDllPath, - dotnetInfo.env, - dotnetInfo.path, - logger - ); - - const documentManager = new RazorDocumentManager( - languageServerClient, - logger, - razorTelemetryReporter, - platformInfo - ); - - const languageServiceClient = new RazorLanguageServiceClient(languageServerClient, documentManager); - - const documentSynchronizer = new RazorDocumentSynchronizer(documentManager, logger); - reportTelemetryForDocuments(documentManager, razorTelemetryReporter); - const languageConfiguration = new RazorLanguageConfiguration(); - const csharpFeature = new RazorCSharpFeature(documentManager, eventEmitterFactory, logger); - const htmlFeature = new RazorHtmlFeature(documentManager, languageServiceClient, eventEmitterFactory, logger); - const localRegistrations: vscode.Disposable[] = []; - const reportIssueCommand = new ReportIssueCommand(vscodeType, documentManager, undefined, undefined, logger); - const razorCodeActionRunner = new RazorCodeActionRunner(languageServerClient, logger); - const codeActionsHandler = new CodeActionsHandler( - documentManager, - documentSynchronizer, - languageServerClient, - logger - ); - const completionHandler = new CompletionHandler( - documentManager, - documentSynchronizer, - languageServerClient, - csharpFeature.projectionProvider, - logger - ); - - // Our dynamic file handler needs to be registered regardless of whether the Razor language server starts - // since the Roslyn implementation expects the dynamic file commands to always be registered. - const dynamicFileInfoProvider = new DynamicFileInfoHandler(documentManager, logger); - dynamicFileInfoProvider.register(); - - languageServerClient.onStart(async () => { - const semanticTokenHandler = new SemanticTokensRangeHandler( - documentManager, - documentSynchronizer, - languageServerClient, - logger - ); - const colorPresentationHandler = new ColorPresentationHandler( - documentManager, - languageServerClient, - logger - ); - const documentColorHandler = new DocumentColorHandler( - documentManager, - documentSynchronizer, - languageServerClient, - logger - ); - const foldingRangeHandler = new FoldingRangeHandler(languageServerClient, documentManager, logger); - const inlayHintHandler = new InlayHintHandler( - languageServerClient, - documentManager, - documentSynchronizer, - logger - ); - const inlayHintResolveHandler = new InlayHintResolveHandler(languageServerClient, documentManager, logger); - const formattingHandler = new FormattingHandler( - documentManager, - documentSynchronizer, - languageServerClient, - logger - ); - const signatureHelpProvider = new RazorSignatureHelpProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const definitionProvider = new RazorDefinitionProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const implementationProvider = new RazorImplementationProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const hoverProvider = new RazorHoverProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const codeLensProvider = new RazorCodeLensProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const renameProvider = new RazorRenameProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const referenceProvider = new RazorReferenceProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const documentHighlightProvider = new RazorDocumentHighlightProvider( - documentSynchronizer, - documentManager, - languageServiceClient, - logger - ); - const razorDiagnosticHandler = new RazorDiagnosticHandler( - documentSynchronizer, - languageServerClient, - languageServiceClient, - documentManager, - logger - ); - const razorSimplifyMethodHandler = new RazorSimplifyMethodHandler( - documentSynchronizer, - languageServerClient, - languageServiceClient, - documentManager, - logger - ); - const razorFormatNewFileHandler = new RazorFormatNewFileHandler( - documentSynchronizer, - languageServerClient, - languageServiceClient, - documentManager, - logger - ); - - const mappingHandler = new MappingHandler(languageServiceClient); - - localRegistrations.push( - languageConfiguration.register(), - vscodeType.languages.registerSignatureHelpProvider(RazorLanguage.id, signatureHelpProvider, '(', ','), - vscodeType.languages.registerDefinitionProvider(RazorLanguage.id, definitionProvider), - vscodeType.languages.registerImplementationProvider(RazorLanguage.id, implementationProvider), - vscodeType.languages.registerHoverProvider(RazorLanguage.documentSelector, hoverProvider), - vscodeType.languages.registerReferenceProvider(RazorLanguage.id, referenceProvider), - vscodeType.languages.registerCodeLensProvider(RazorLanguage.id, codeLensProvider), - vscodeType.languages.registerRenameProvider(RazorLanguage.id, renameProvider), - vscodeType.languages.registerDocumentHighlightProvider(RazorLanguage.id, documentHighlightProvider), - documentManager.register(), - csharpFeature.register(), - htmlFeature.register(), - documentSynchronizer.register(), - reportIssueCommand.register(), - razorCodeActionRunner.register() - ); - - if (enableProposedApis) { - const proposedApisFeature = new ProposedApisFeature(); - - await proposedApisFeature.register(vscodeType); - } - - await Promise.all([ - colorPresentationHandler.register(), - documentColorHandler.register(), - foldingRangeHandler.register(), - inlayHintHandler.register(), - inlayHintResolveHandler.register(), - formattingHandler.register(), - semanticTokenHandler.register(), - razorDiagnosticHandler.register(), - codeActionsHandler.register(), - completionHandler.register(), - razorSimplifyMethodHandler.register(), - razorFormatNewFileHandler.register(), - mappingHandler.register(), - ]); - }); - - const onStopRegistration = languageServerClient.onStop(() => { - localRegistrations.forEach((r) => r.dispose()); - localRegistrations.length = 0; - }); - - context.subscriptions.push(BlazorDebugConfigurationProvider.register(logger, vscodeType)); - - languageServerClient.onStarted(async () => { - await documentManager.initialize(); - }); - - await startLanguageServer(vscodeType, languageServerClient, logger, context); - - context.subscriptions.push(languageServerClient, onStopRegistration, logger); - } catch (error) { - logger.logError('Failed when activating Razor VSCode.', error as Error); - razorTelemetryReporter.reportErrorOnActivation(error as Error); - } -} - -async function startLanguageServer( - vscodeType: typeof vscodeapi, - languageServerClient: RazorLanguageServerClient, - logger: RazorLogger, - context: vscode.ExtensionContext -) { - const razorFiles = await vscodeType.workspace.findFiles(RazorLanguage.globbingPattern); - if (razorFiles.length === 0) { - // No Razor files in workspace, language server should stay off until one is added or opened. - logger.logAlways('No Razor files detected in workspace, delaying language server start.'); - - const watcher = vscodeType.workspace.createFileSystemWatcher(RazorLanguage.globbingPattern); - const delayedLanguageServerStart = async () => { - razorFileCreatedRegistration.dispose(); - razorFileOpenedRegistration.dispose(); - await languageServerClient.start(); - }; - const razorFileCreatedRegistration = watcher.onDidCreate(async () => delayedLanguageServerStart()); - const razorFileOpenedRegistration = vscodeType.workspace.onDidOpenTextDocument(async (event) => { - if (event.languageId === RazorLanguage.id) { - await delayedLanguageServerStart(); - } - }); - context.subscriptions.push(razorFileCreatedRegistration, razorFileOpenedRegistration); - } else { - await languageServerClient.start(); - } -} - -async function setupDevKitEnvironment( - env: NodeJS.ProcessEnv, - csharpDevkitExtension: vscode.Extension, - logger: RazorLogger -): Promise { - try { - const exports = await csharpDevkitExtension.activate(); - - // setupTelemetryEnvironmentAsync was a later addition to devkit (not in preview 1) - // so it may not exist in whatever version of devkit the user has installed - if (!exports.setupTelemetryEnvironmentAsync) { - return; - } - - await exports.setupTelemetryEnvironmentAsync(env); - } catch (error) { - logger.logError('Failed to setup DevKit environment for telemetry.', error as Error); - } -} From 55e214a97911a6152e0d2bea6b98d1a2d51fbc23 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:55:48 +1100 Subject: [PATCH 05/10] Remove things that need .razor or .razorDevKit folders --- package.json | 4 ---- package.nls.cs.json | 1 - package.nls.de.json | 1 - package.nls.es.json | 1 - package.nls.fr.json | 1 - package.nls.it.json | 1 - package.nls.ja.json | 1 - package.nls.json | 1 - package.nls.ko.json | 1 - package.nls.pl.json | 1 - package.nls.pt-br.json | 1 - package.nls.ru.json | 1 - package.nls.tr.json | 1 - package.nls.zh-cn.json | 1 - package.nls.zh-tw.json | 1 - .../extensions/builtInComponents.ts | 5 ----- tasks/offlinePackagingTasks.ts | 21 +------------------ tasks/projectPaths.ts | 2 -- 18 files changed, 1 insertion(+), 45 deletions(-) diff --git a/package.json b/package.json index c6444461e1..47f6c96b61 100644 --- a/package.json +++ b/package.json @@ -1447,10 +1447,6 @@ "razorExtension": { "description": "%configuration.dotnet.server.componentPaths.razorExtension%", "type": "string" - }, - "razorDevKit": { - "description": "%configuration.dotnet.server.componentPaths.razorDevKit%", - "type": "string" } }, "default": {} diff --git a/package.nls.cs.json b/package.nls.cs.json index 1c5bdc57be..590c7fb7aa 100644 --- a/package.nls.cs.json +++ b/package.nls.cs.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Umožňuje využívat prostředí „programů založených na souborech“ (dotnet run app.cs) ve verzi Preview.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Zobrazit informace o poznámkách při zobrazení symbolu.", "configuration.dotnet.server.componentPaths": "Umožňuje přepsat cestu ke složce pro integrované komponenty jazykového serveru (například přepsat cestu .roslynDevKit v adresáři rozšíření tak, aby používala místně sestavené komponenty).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Přepíše cestu ke složce pro komponentu Razor Dev Kit jazykového serveru", "configuration.dotnet.server.componentPaths.razorExtension": "Přepíše cestu ke složce pro komponentu rozšíření Razor jazykového serveru", "configuration.dotnet.server.componentPaths.roslynCopilot": "Přepíše cestu ke složce pro komponentu .roslynCopilot jazykového serveru.", "configuration.dotnet.server.componentPaths.roslynDevKit": "Přepíše cestu ke složce pro komponentu .roslynDevKit jazykového serveru.", diff --git a/package.nls.de.json b/package.nls.de.json index ce0bca804e..1d067940a8 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Aktiviert die Vorschau für die Erfahrung „dateibasierte Programme“ (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Beschreibungsinformationen beim Anzeigen des Symbols anzeigen.", "configuration.dotnet.server.componentPaths": "Ermöglicht das Überschreiben des Ordnerpfads für eingebaute Komponenten des Sprachservers (z. B. Überschreiben des Pfads .roslynDevKit im Erweiterungsverzeichnis, um lokal erstellte Komponenten zu verwenden)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Überschreibt den Ordnerpfad für die Razor-Dev-Kit-Komponente des Sprachservers", "configuration.dotnet.server.componentPaths.razorExtension": "Überschreibt den Ordnerpfad für die Razor-Erweiterungskomponente des Sprachservers", "configuration.dotnet.server.componentPaths.roslynCopilot": "Überschreibt den Ordnerpfad für die .roslynCopilot-Komponente des Sprachservers", "configuration.dotnet.server.componentPaths.roslynDevKit": "Überschreibt den Ordnerpfad für die Komponente .roslynDevKit des Sprachservers", diff --git a/package.nls.es.json b/package.nls.es.json index ad3083122b..850edc0045 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Habilita la experiencia de vista previa de \"programas basados en archivos\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostrar información de comentarios cuando se muestra el símbolo.", "configuration.dotnet.server.componentPaths": "Permite invalidar la ruta de acceso de carpeta para los componentes integrados del servidor de lenguaje (por ejemplo, invalidar la ruta de acceso .roslynDevKit en el directorio de extensión para usar componentes compilados localmente).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Invalida la ruta de acceso de la carpeta para el componente Razor Dev Kit del servidor de lenguaje", "configuration.dotnet.server.componentPaths.razorExtension": "Invalida la ruta de acceso de la carpeta para el componente de extensión Razor del servidor de lenguaje", "configuration.dotnet.server.componentPaths.roslynCopilot": "Invalida la ruta de acceso de la carpeta para el componente .roslynCopilot del servidor de lenguaje", "configuration.dotnet.server.componentPaths.roslynDevKit": "Invalida la ruta de acceso de la carpeta para el componente .roslynDevKit del servidor de lenguaje.", diff --git a/package.nls.fr.json b/package.nls.fr.json index 21a402c19d..8e1488151c 100644 --- a/package.nls.fr.json +++ b/package.nls.fr.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Active l’expérience de prévisualisation des « programmes basés sur des fichiers » (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Afficher les informations sur les remarques lors de l’affichage du symbole.", "configuration.dotnet.server.componentPaths": "Permet de remplacer le chemin d’accès au dossier des composants intégrés du serveur de langage (par exemple, remplacer le chemin d’accès .roslynDevKit dans le répertoire d’extension pour utiliser les composants générés localement).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Remplace le chemin d’accès du dossier pour le composant du Kit de développement Razor du serveur de langage", "configuration.dotnet.server.componentPaths.razorExtension": "Remplace le chemin d’accès du dossier pour le composant d’extension Razor du serveur de langage", "configuration.dotnet.server.componentPaths.roslynCopilot": "Remplace le chemin d’accès du dossier pour le composant .roslynCopilot du serveur de langage", "configuration.dotnet.server.componentPaths.roslynDevKit": "Remplace le chemin d’accès au dossier du composant .roslynDevKit du serveur de langage", diff --git a/package.nls.it.json b/package.nls.it.json index 9a7b2caf75..a58c8ba84b 100644 --- a/package.nls.it.json +++ b/package.nls.it.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Abilita l'esperienza di anteprima di \"programmi basati su file\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostra le informazioni sulle note quando viene visualizzato il simbolo.", "configuration.dotnet.server.componentPaths": "Consente di eseguire l'override del percorso della cartella per i componenti predefiniti del server di linguaggio (ad esempio, eseguire l'override del percorso .roslynDevKit nella directory delle estensioni per usare componenti compilati in locale)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Esegue l'override del percorso della cartella per il componente Razor Dev Kit del server di linguaggio", "configuration.dotnet.server.componentPaths.razorExtension": "Esegue l'override del percorso della cartella per il componente di estensione Razor del server di linguaggio", "configuration.dotnet.server.componentPaths.roslynCopilot": "Esegue l'override del percorso della cartella per il componente roslynCopilot del server di linguaggio", "configuration.dotnet.server.componentPaths.roslynDevKit": "Esegue l'override del percorso della cartella per il componente .roslynDevKit del server di linguaggio", diff --git a/package.nls.ja.json b/package.nls.ja.json index d08b325d89..2d3cff2348 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "プレビューの \"ファイル ベースのプログラム\" (dotnet run app.cs) エクスペリエンスを有効にします。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "シンボルを表示するときに注釈情報を表示します。", "configuration.dotnet.server.componentPaths": "言語サーバーの組み込みコンポーネントのフォルダー パスをオーバーライドできます (たとえば、ローカルにビルドされたコンポーネントを使用するように拡張ディレクトリの .roslynDevKit パスをオーバーライドする)", - "configuration.dotnet.server.componentPaths.razorDevKit": "言語サーバーの Razor Dev Kit コンポーネントのフォルダー パスを上書きします", "configuration.dotnet.server.componentPaths.razorExtension": "言語サーバーの Razor 拡張機能コンポーネントのフォルダー パスを上書きします", "configuration.dotnet.server.componentPaths.roslynCopilot": "言語サーバーの .roslynCopilot コンポーネントのフォルダー パスをオーバーライドします", "configuration.dotnet.server.componentPaths.roslynDevKit": "言語サーバーの .roslynDevKit コンポーネントのフォルダー パスをオーバーライドします", diff --git a/package.nls.json b/package.nls.json index 23f7f2ffa1..4db2b51c16 100644 --- a/package.nls.json +++ b/package.nls.json @@ -33,7 +33,6 @@ "configuration.dotnet.server.componentPaths.xamlTools": "Overrides the folder path for the .xamlTools component of the language server", "configuration.dotnet.server.componentPaths.roslynCopilot": "Overrides the folder path for the .roslynCopilot component of the language server", "configuration.dotnet.server.componentPaths.razorExtension": "Overrides the folder path for the Razor extension component of the language server", - "configuration.dotnet.server.componentPaths.razorDevKit": "Overrides the folder path for the Razor Dev Kit component of the language server", "configuration.dotnet.server.startTimeout": "Specifies a timeout (in ms) for the client to successfully start and connect to the language server.", "configuration.dotnet.server.waitForDebugger": "Passes the --debug flag when launching the server to allow a debugger to be attached. (Previously `omnisharp.waitForDebugger`)", "configuration.dotnet.server.extensionPaths": "Override for path to language server --extension arguments", diff --git a/package.nls.ko.json b/package.nls.ko.json index 535c23cbcd..4a36e57a7b 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "미리 보기 \"파일 기반 프로그램\"(dotnet run app.cs) 환경을 활성화합니다.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "기호를 표시할 때 설명 정보를 표시합니다.", "configuration.dotnet.server.componentPaths": "언어 서버의 기본 제공 구성 요소에 대한 폴더 경로를 재정의할 수 있습니다(예: 로컬로 빌드된 구성 요소를 사용하도록 확장 디렉터리의 .roslynDevKit 경로 재정의).", - "configuration.dotnet.server.componentPaths.razorDevKit": "언어 서버의 Razor Dev Kit 구성 요소에 대한 폴더 경로를 재정의합니다.", "configuration.dotnet.server.componentPaths.razorExtension": "언어 서버의 Razor 확장 구성 요소에 대한 폴더 경로를 재정의합니다.", "configuration.dotnet.server.componentPaths.roslynCopilot": "언어 서버의 .roslynCopilot 구성 요소에 대한 폴더 경로를 덮어씁니다.", "configuration.dotnet.server.componentPaths.roslynDevKit": "언어 서버의 .roslynDevKit 구성 요소에 대한 폴더 경로를 재정의합니다.", diff --git a/package.nls.pl.json b/package.nls.pl.json index 95fbd85390..6fc5e2c285 100644 --- a/package.nls.pl.json +++ b/package.nls.pl.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Włącza podgląd środowiska „programy oparte na plikach” (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Pokaż informacje o uwagach podczas wyświetlania symbolu.", "configuration.dotnet.server.componentPaths": "Umożliwia zastąpienie ścieżki folderu dla wbudowanych składników serwera języka (na przykład przesłonięcie ścieżki roslynDevKit w katalogu rozszerzenia w celu użycia składników skompilowanych lokalnie)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Zastępuje ścieżkę folderu składnika Razor Dev Kit serwera języka", "configuration.dotnet.server.componentPaths.razorExtension": "Zastępuje ścieżkę folderu składnika rozszerzenia Razor serwera języka", "configuration.dotnet.server.componentPaths.roslynCopilot": "Przesłania ścieżkę folderu dla składnika .roslynCopilot serwera językowego", "configuration.dotnet.server.componentPaths.roslynDevKit": "Przesłania ścieżkę folderu dla składnika roslynDevKit serwera językowego", diff --git a/package.nls.pt-br.json b/package.nls.pt-br.json index 57802268ba..be7aa6e9ab 100644 --- a/package.nls.pt-br.json +++ b/package.nls.pt-br.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Habilita a experiência de prévia \"programas baseados em arquivo\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Mostrar informações de comentários ao exibir o símbolo.", "configuration.dotnet.server.componentPaths": "Permite substituir o caminho da pasta para componentes internos do servidor de linguagem (por exemplo, substituir o caminho .roslynDevKit no diretório de extensão para usar componentes compilados localmente)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Substitui o caminho da pasta para o componente do Kit de Desenvolvimento do Razor do servidor de linguagem", "configuration.dotnet.server.componentPaths.razorExtension": "Substitui o caminho da pasta para o componente de extensão Razor do servidor de linguagem", "configuration.dotnet.server.componentPaths.roslynCopilot": "Substitui o caminho da pasta para o componente .roslynCopilot do servidor de idiomas", "configuration.dotnet.server.componentPaths.roslynDevKit": "Substitui o caminho da pasta para o componente .roslynDevKit do servidor de linguagem", diff --git a/package.nls.ru.json b/package.nls.ru.json index 586560dbb6..a99535a9d4 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "Включает предварительный просмотр \"программ на основе файлов\" (dotnet run app.cs).", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Показывать примечания при отображении символа.", "configuration.dotnet.server.componentPaths": "Позволяет переопределить путь к папке для встроенных компонентов языкового сервера (например, переопределить путь .roslynDevKit в каталоге расширения для использования локально созданных компонентов).", - "configuration.dotnet.server.componentPaths.razorDevKit": "Переопределяет путь к папке для компонента Razor Dev Kit языкового сервера", "configuration.dotnet.server.componentPaths.razorExtension": "Переопределяет путь к папке для компонента расширения Razor языкового сервера", "configuration.dotnet.server.componentPaths.roslynCopilot": "Переопределяет путь к папке для компонента .roslynCopilot языкового сервера", "configuration.dotnet.server.componentPaths.roslynDevKit": "Переопределяет путь к папке для компонента .roslynDevKit языкового сервера.", diff --git a/package.nls.tr.json b/package.nls.tr.json index 5848e5416c..d3225a2ab1 100644 --- a/package.nls.tr.json +++ b/package.nls.tr.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "\"Dosya tabanlı programlar\" (dotnet run app.cs) önizleme deneyimini etkinleştirir.", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "Simge görüntülendiğinde açıklama bilgilerini göster.", "configuration.dotnet.server.componentPaths": "Dil sunucusundaki yerleşik bileşenlerin klasör yolunu geçersiz kılmaya olanak tanır (örneğin, yerel olarak oluşturulan bileşenleri kullanmak için uzantı dizinindeki .roslynDevKit yolunu geçersiz kılın)", - "configuration.dotnet.server.componentPaths.razorDevKit": "Dil sunucusundaki Razor Geliştirme Paketi bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.razorExtension": "Dil sunucusundaki Razor uzantısı bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.roslynCopilot": "Dil sunucusunun .roslynCopilot bileşeninin klasör yolunu geçersiz kılar", "configuration.dotnet.server.componentPaths.roslynDevKit": "Dil sunucusundaki .roslynDevKit bileşeninin klasör yolunu geçersiz kılar", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 8d6eb2cb16..3e38f06726 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "启用预览“基于文件的程序”(dotnet run app.cs)体验。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "显示符号时显示备注信息。", "configuration.dotnet.server.componentPaths": "允许替代语言服务器内置组件的文件夹路径(例如,替代扩展目录中的 .roslynDevKit 路径以使用本地生成的组件)", - "configuration.dotnet.server.componentPaths.razorDevKit": "替代语言服务器的 Razor 开发工具包组件的文件夹路径", "configuration.dotnet.server.componentPaths.razorExtension": "替代语言服务器的 Razor 扩展组件的文件夹路径", "configuration.dotnet.server.componentPaths.roslynCopilot": "替代语言服务器的 .roslynCopilot 组件的文件夹路径", "configuration.dotnet.server.componentPaths.roslynDevKit": "替代语言服务器的 .roslynDevKit 组件的文件夹路径", diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 1a707fdcbf..1c4009df47 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -65,7 +65,6 @@ "configuration.dotnet.projects.enableFileBasedPrograms": "啟用「檔案型程式」 (dotnet run app.cs) 的預覽體驗。", "configuration.dotnet.quickInfo.showRemarksInQuickInfo": "顯示符號時顯示備註資訊。", "configuration.dotnet.server.componentPaths": "允許覆寫語言伺服器內建元件的資料夾路徑 (例如,覆寫延伸模組目錄中的 .roslynDevKit 路徑,以使用本機建置的元件)", - "configuration.dotnet.server.componentPaths.razorDevKit": "覆寫語言伺服器 Razor 開發套件元件的資料夾路徑", "configuration.dotnet.server.componentPaths.razorExtension": "覆寫語言伺服器 Razor 延伸模組元件的資料夾路徑", "configuration.dotnet.server.componentPaths.roslynCopilot": "覆寫語言伺服器 .roslynCopilot 元件的資料夾路徑", "configuration.dotnet.server.componentPaths.roslynDevKit": "覆寫語言伺服器 .roslynDevKit 元件的資料夾路徑", diff --git a/src/lsptoolshost/extensions/builtInComponents.ts b/src/lsptoolshost/extensions/builtInComponents.ts index 4f67c80e28..017512a10c 100644 --- a/src/lsptoolshost/extensions/builtInComponents.ts +++ b/src/lsptoolshost/extensions/builtInComponents.ts @@ -29,11 +29,6 @@ export const componentInfo: { [key: string]: ComponentInfo } = { 'Microsoft.VisualStudio.DesignTools.CodeAnalysis.Diagnostics.dll', ], }, - razorDevKit: { - defaultFolderName: '.razorDevKit', - optionName: 'razorDevKit', - componentDllPaths: ['Microsoft.VisualStudio.DevKit.Razor.dll'], - }, razorExtension: { defaultFolderName: '.razorExtension', optionName: 'razorExtension', diff --git a/tasks/offlinePackagingTasks.ts b/tasks/offlinePackagingTasks.ts index af16c0e1a0..aa8b829230 100644 --- a/tasks/offlinePackagingTasks.ts +++ b/tasks/offlinePackagingTasks.ts @@ -24,8 +24,6 @@ import { rootPath, devKitDependenciesDirectory, xamlToolsDirectory, - razorLanguageServerDirectory, - razorDevKitDirectory, razorExtensionDirectory, } from '../tasks/projectPaths'; import { getPackageJSON } from '../tasks/packageJson'; @@ -86,18 +84,6 @@ export const allNugetPackages: { [key: string]: NugetPackageInfo } = { getPackageContentPath: (_platformInfo) => 'content', vsixOutputPath: xamlToolsDirectory, }, - razor: { - getPackageName: (platformInfo) => `rzls.${platformInfo?.rid ?? 'neutral'}`, - packageJsonName: 'razor', - getPackageContentPath: (platformInfo) => path.join('content', 'LanguageServer', platformInfo?.rid ?? 'neutral'), - vsixOutputPath: razorLanguageServerDirectory, - }, - razorDevKit: { - getPackageName: (_platformInfo) => 'Microsoft.VisualStudio.DevKit.Razor', - packageJsonName: 'razor', - getPackageContentPath: (_platformInfo) => 'content', - vsixOutputPath: razorDevKitDirectory, - }, razorExtension: { getPackageName: (_platformInfo) => 'Microsoft.VisualStudioCode.RazorExtension', packageJsonName: 'razor', @@ -182,11 +168,6 @@ gulp.task( 'updateRazorVersion', // Run the fetch of all packages, and then also installDependencies after gulp.series(async () => { - await updateNugetPackageVersion(allNugetPackages.razor); - - // Also pull in the Razor DevKit dependencies nuget package. - await acquireNugetPackage(allNugetPackages.razorDevKit, undefined, getPackageJSON(), true); - // Pull in the .razorExtension code that gets loaded in the roslyn language server await acquireNugetPackage(allNugetPackages.razorExtension, undefined, getPackageJSON(), true); }, 'installDependencies') @@ -378,7 +359,7 @@ async function doPackageOffline(vsixPlatform: VSIXPlatformInfo | undefined) { } async function cleanAsync() { - const directoriesToDelete = ['install.*', '.omnisharp*', '.debugger', '.razor']; + const directoriesToDelete = ['install.*', '.omnisharp*', '.debugger', '.razorExtension']; for (const key in allNugetPackages) { directoriesToDelete.push(allNugetPackages[key].vsixOutputPath); } diff --git a/tasks/projectPaths.ts b/tasks/projectPaths.ts index 3acaf2702d..bc45ebc36c 100644 --- a/tasks/projectPaths.ts +++ b/tasks/projectPaths.ts @@ -18,8 +18,6 @@ export const nugetTempPath = path.join(rootPath, 'out', '.nuget'); export const languageServerDirectory = path.join(rootPath, '.roslyn'); export const devKitDependenciesDirectory = path.join(rootPath, componentInfo.roslynDevKit.defaultFolderName); export const xamlToolsDirectory = path.join(rootPath, componentInfo.xamlTools.defaultFolderName); -export const razorLanguageServerDirectory = path.join(rootPath, '.razor'); -export const razorDevKitDirectory = path.join(rootPath, componentInfo.razorDevKit.defaultFolderName); export const razorExtensionDirectory = path.join(rootPath, componentInfo.razorExtension.defaultFolderName); export const codeExtensionPath = commandLineOptions.codeExtensionPath || rootPath; From f215d2c5ae814a196004445d8695145e5b075f0f Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 19 Nov 2025 21:56:03 +1100 Subject: [PATCH 06/10] Remove razor.mode --- src/lsptoolshost/razor/razorEndpoints.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lsptoolshost/razor/razorEndpoints.ts b/src/lsptoolshost/razor/razorEndpoints.ts index 58a4824d1c..2428bd775e 100644 --- a/src/lsptoolshost/razor/razorEndpoints.ts +++ b/src/lsptoolshost/razor/razorEndpoints.ts @@ -57,7 +57,6 @@ export function registerRazorEndpoints( razorLogger.log(params.message, params.type) ); - vscode.commands.executeCommand('setContext', 'razor.mode', 'cohosting'); registerCohostingEndpoints(); context.subscriptions.push(BlazorDebugConfigurationProvider.register(razorLogger, vscode)); From 6946296e08ba7d2bdbf114f00a54c13de426eab8 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 20 Nov 2025 20:03:12 +1100 Subject: [PATCH 07/10] Remove old Razor files --- l10n/bundle.l10n.json | 30 +- src/lsptoolshost/activate.ts | 2 - src/lsptoolshost/razor/htmlDocumentManager.ts | 3 +- src/lsptoolshost/razor/razorCommands.ts | 140 ------- src/lsptoolshost/razor/razorEndpoints.ts | 8 +- .../server/roslynLanguageServer.ts | 42 -- src/lsptoolshost/utils/uriConverter.ts | 15 +- src/razor/src/IEventEmitterFactory.ts | 10 - src/razor/src/IRazorProject.ts | 13 - src/razor/src/IRazorProjectChangeEvent.ts | 12 - src/razor/src/IRazorProjectConfiguration.ts | 19 - .../src/codeActions/codeActionsHandler.ts | 132 ------- src/razor/src/codeActions/razorCodeAction.ts | 14 - .../codeActions/razorCodeActionDataParams.ts | 8 - .../razorCodeActionResolutionParams.ts | 9 - .../src/codeActions/razorCodeActionRunner.ts | 50 --- .../serializableCodeActionParams.ts | 14 - .../serializableDelegatedCodeActionParams.ts | 13 - ...erializableRazorResolveCodeActionParams.ts | 15 - src/razor/src/codeLens/razorCodeLens.ts | 17 - .../src/codeLens/razorCodeLensProvider.ts | 158 -------- .../colorPresentationHandler.ts | 54 +-- src/razor/src/completion/completionHandler.ts | 353 +---------------- ...bleDelegatedCompletionItemResolveParams.ts | 15 - .../serializableDelegatedCompletionParams.ts | 21 - src/razor/src/csharp/csharpPreviewPanel.ts | 152 -------- .../src/csharp/csharpProjectedDocument.ts | 243 ------------ .../csharpProjectedDocumentContentProvider.ts | 79 ---- src/razor/src/csharp/razorCSharpFeature.ts | 49 --- .../src/definition/razorDefinitionProvider.ts | 59 --- .../src/diagnostics/razorDiagnosticHandler.ts | 86 ----- .../src/diagnostics/reportIssueCommand.ts | 13 +- .../src/diagnostics/reportIssueCreator.ts | 111 +----- src/razor/src/document/IRazorDocument.ts | 15 - .../src/document/IRazorDocumentChangeEvent.ts | 14 - .../src/document/IRazorDocumentManager.ts | 17 - src/razor/src/document/razorDocument.ts | 32 -- .../src/document/razorDocumentChangeKind.ts | 13 - .../src/document/razorDocumentFactory.ts | 44 --- .../src/document/razorDocumentManager.ts | 358 ------------------ .../src/document/razorDocumentSynchronizer.ts | 266 ------------- .../src/documentColor/documentColorHandler.ts | 67 +--- .../serializableDocumentColorParams.ts | 11 - .../razorDocumentHighlightProvider.ts | 60 --- src/razor/src/documentTelemetryListener.ts | 21 - .../src/dynamicFile/dynamicFileInfoHandler.ts | 116 ------ .../dynamicFile/dynamicFileUpdatedParams.ts | 10 - .../dynamicFile/provideDynamicFileParams.ts | 11 - .../dynamicFile/provideDynamicFileResponse.ts | 23 -- src/razor/src/dynamicFile/razorTextChange.ts | 10 - src/razor/src/dynamicFile/razorTextSpan.ts | 8 - .../dynamicFile/removeDynamicFileParams.ts | 11 - src/razor/src/folding/foldingRangeHandler.ts | 75 +--- .../folding/serializableFoldingRangeParams.ts | 12 - .../serializableFoldingRangeResponse.ts | 10 - .../razorFormatNewFileHandler.ts | 52 --- .../serializableFormatNewFileParams.ts | 12 - src/razor/src/formatting/formattingHandler.ts | 111 +----- .../serializableFormattingParams.ts | 13 - .../serializableOnTypeFormattingParams.ts | 16 - src/razor/src/hostEventStream.ts | 65 ---- src/razor/src/hover/razorHoverProvider.ts | 80 ---- src/razor/src/html/htmlPreviewPanel.ts | 153 -------- src/razor/src/html/htmlProjectedDocument.ts | 63 --- .../htmlProjectedDocumentContentProvider.ts | 75 ---- .../src/html/htmlTagCompletionProvider.ts | 182 --------- src/razor/src/html/razorHtmlFeature.ts | 57 --- .../razorImplementationProvider.ts | 57 --- src/razor/src/inlayHint/inlayHintHandler.ts | 80 ---- .../src/inlayHint/inlayHintResolveHandler.ts | 52 --- .../inlayHint/serializableInlayHintParams.ts | 12 - .../serializableInlayHintResolveParams.ts | 12 - src/razor/src/mapping/mappingHandler.ts | 32 -- src/razor/src/mapping/mappingHelpers.ts | 167 -------- src/razor/src/mapping/razorMapSpansParams.ts | 11 - .../src/mapping/razorMapSpansResponse.ts | 19 - .../src/mapping/razorMapTextChangesParams.ts | 14 - .../mapping/razorMapTextChangesResponse.ts | 15 - .../mapping/razorMapToDocumentEditsParams.ts | 16 - .../razorMapToDocumentEditsResponse.ts | 10 - .../src/projection/IProjectedDocument.ts | 14 - src/razor/src/projection/projectionResult.ts | 14 - src/razor/src/proposedApisFeature.ts | 14 - .../src/razorCSharpLanguageMiddleware.ts | 139 ------- src/razor/src/razorConventions.ts | 31 -- src/razor/src/razorLanguageClient.ts | 38 -- src/razor/src/razorLanguageFeatureBase.ts | 74 ---- src/razor/src/razorLanguageServerClient.ts | 321 ---------------- src/razor/src/razorLanguageServerOptions.ts | 14 - .../src/razorLanguageServerOptionsResolver.ts | 78 ---- src/razor/src/razorLanguageServiceClient.ts | 127 ------- src/razor/src/razorLogger.ts | 8 - src/razor/src/razorProjectChangeKind.ts | 10 - .../src/reference/razorReferenceProvider.ts | 60 --- src/razor/src/rename/razorRenameProvider.ts | 77 ---- .../src/rename/serializableRenameDocument.ts | 14 - src/razor/src/rpc/languageKind.ts | 10 - src/razor/src/rpc/languageQueryRequest.ts | 14 - src/razor/src/rpc/languageQueryResponse.ts | 14 - .../rpc/razorMapToDocumentRangesRequest.ts | 20 - .../rpc/razorMapToDocumentRangesResponse.ts | 13 - .../src/rpc/serializableCreateDocument.ts | 13 - .../src/rpc/serializableDeleteDocument.ts | 13 - .../src/rpc/serializableTextDocumentEdit.ts | 15 - .../src/rpc/serializableWorkspaceEdit.ts | 61 --- src/razor/src/rpc/serverTextChange.ts | 11 - src/razor/src/rpc/serverTextSpan.ts | 9 - src/razor/src/rpc/updateBufferRequest.ts | 18 - .../semantic/provideSemanticTokensResponse.ts | 9 - src/razor/src/semantic/semanticTokens.ts | 8 - .../semantic/semanticTokensRangeHandler.ts | 154 -------- .../serializableSemanticTokensParams.ts | 14 - .../razorSignatureHelpProvider.ts | 25 -- .../simplify/razorSimplifyMethodHandler.ts | 71 ---- ...rializableDelegatedSimplifyMethodParams.ts | 13 - .../serializableSimplifyMethodParams.ts | 11 - ...lizableTextDocumentIdentifierAndVersion.ts | 11 - src/razor/src/telemetryReporter.ts | 79 ---- src/shared/options.ts | 4 - 119 files changed, 35 insertions(+), 6147 deletions(-) delete mode 100644 src/lsptoolshost/razor/razorCommands.ts delete mode 100644 src/razor/src/IEventEmitterFactory.ts delete mode 100644 src/razor/src/IRazorProject.ts delete mode 100644 src/razor/src/IRazorProjectChangeEvent.ts delete mode 100644 src/razor/src/IRazorProjectConfiguration.ts delete mode 100644 src/razor/src/codeActions/codeActionsHandler.ts delete mode 100644 src/razor/src/codeActions/razorCodeAction.ts delete mode 100644 src/razor/src/codeActions/razorCodeActionDataParams.ts delete mode 100644 src/razor/src/codeActions/razorCodeActionResolutionParams.ts delete mode 100644 src/razor/src/codeActions/razorCodeActionRunner.ts delete mode 100644 src/razor/src/codeActions/serializableCodeActionParams.ts delete mode 100644 src/razor/src/codeActions/serializableDelegatedCodeActionParams.ts delete mode 100644 src/razor/src/codeActions/serializableRazorResolveCodeActionParams.ts delete mode 100644 src/razor/src/codeLens/razorCodeLens.ts delete mode 100644 src/razor/src/codeLens/razorCodeLensProvider.ts delete mode 100644 src/razor/src/completion/serializableDelegatedCompletionItemResolveParams.ts delete mode 100644 src/razor/src/completion/serializableDelegatedCompletionParams.ts delete mode 100644 src/razor/src/csharp/csharpPreviewPanel.ts delete mode 100644 src/razor/src/csharp/csharpProjectedDocument.ts delete mode 100644 src/razor/src/csharp/csharpProjectedDocumentContentProvider.ts delete mode 100644 src/razor/src/csharp/razorCSharpFeature.ts delete mode 100644 src/razor/src/definition/razorDefinitionProvider.ts delete mode 100644 src/razor/src/diagnostics/razorDiagnosticHandler.ts delete mode 100644 src/razor/src/document/IRazorDocument.ts delete mode 100644 src/razor/src/document/IRazorDocumentChangeEvent.ts delete mode 100644 src/razor/src/document/IRazorDocumentManager.ts delete mode 100644 src/razor/src/document/razorDocument.ts delete mode 100644 src/razor/src/document/razorDocumentChangeKind.ts delete mode 100644 src/razor/src/document/razorDocumentFactory.ts delete mode 100644 src/razor/src/document/razorDocumentManager.ts delete mode 100644 src/razor/src/document/razorDocumentSynchronizer.ts delete mode 100644 src/razor/src/documentColor/serializableDocumentColorParams.ts delete mode 100644 src/razor/src/documentHighlight/razorDocumentHighlightProvider.ts delete mode 100644 src/razor/src/documentTelemetryListener.ts delete mode 100644 src/razor/src/dynamicFile/dynamicFileInfoHandler.ts delete mode 100644 src/razor/src/dynamicFile/dynamicFileUpdatedParams.ts delete mode 100644 src/razor/src/dynamicFile/provideDynamicFileParams.ts delete mode 100644 src/razor/src/dynamicFile/provideDynamicFileResponse.ts delete mode 100644 src/razor/src/dynamicFile/razorTextChange.ts delete mode 100644 src/razor/src/dynamicFile/razorTextSpan.ts delete mode 100644 src/razor/src/dynamicFile/removeDynamicFileParams.ts delete mode 100644 src/razor/src/folding/serializableFoldingRangeParams.ts delete mode 100644 src/razor/src/folding/serializableFoldingRangeResponse.ts delete mode 100644 src/razor/src/formatNewFile/razorFormatNewFileHandler.ts delete mode 100644 src/razor/src/formatNewFile/serializableFormatNewFileParams.ts delete mode 100644 src/razor/src/formatting/serializableFormattingParams.ts delete mode 100644 src/razor/src/formatting/serializableOnTypeFormattingParams.ts delete mode 100644 src/razor/src/hostEventStream.ts delete mode 100644 src/razor/src/hover/razorHoverProvider.ts delete mode 100644 src/razor/src/html/htmlPreviewPanel.ts delete mode 100644 src/razor/src/html/htmlProjectedDocument.ts delete mode 100644 src/razor/src/html/htmlProjectedDocumentContentProvider.ts delete mode 100644 src/razor/src/html/htmlTagCompletionProvider.ts delete mode 100644 src/razor/src/html/razorHtmlFeature.ts delete mode 100644 src/razor/src/implementation/razorImplementationProvider.ts delete mode 100644 src/razor/src/inlayHint/inlayHintHandler.ts delete mode 100644 src/razor/src/inlayHint/inlayHintResolveHandler.ts delete mode 100644 src/razor/src/inlayHint/serializableInlayHintParams.ts delete mode 100644 src/razor/src/inlayHint/serializableInlayHintResolveParams.ts delete mode 100644 src/razor/src/mapping/mappingHandler.ts delete mode 100644 src/razor/src/mapping/mappingHelpers.ts delete mode 100644 src/razor/src/mapping/razorMapSpansParams.ts delete mode 100644 src/razor/src/mapping/razorMapSpansResponse.ts delete mode 100644 src/razor/src/mapping/razorMapTextChangesParams.ts delete mode 100644 src/razor/src/mapping/razorMapTextChangesResponse.ts delete mode 100644 src/razor/src/mapping/razorMapToDocumentEditsParams.ts delete mode 100644 src/razor/src/mapping/razorMapToDocumentEditsResponse.ts delete mode 100644 src/razor/src/projection/IProjectedDocument.ts delete mode 100644 src/razor/src/projection/projectionResult.ts delete mode 100644 src/razor/src/proposedApisFeature.ts delete mode 100644 src/razor/src/razorCSharpLanguageMiddleware.ts delete mode 100644 src/razor/src/razorConventions.ts delete mode 100644 src/razor/src/razorLanguageClient.ts delete mode 100644 src/razor/src/razorLanguageFeatureBase.ts delete mode 100644 src/razor/src/razorLanguageServerClient.ts delete mode 100644 src/razor/src/razorLanguageServerOptions.ts delete mode 100644 src/razor/src/razorLanguageServerOptionsResolver.ts delete mode 100644 src/razor/src/razorLanguageServiceClient.ts delete mode 100644 src/razor/src/razorProjectChangeKind.ts delete mode 100644 src/razor/src/reference/razorReferenceProvider.ts delete mode 100644 src/razor/src/rename/razorRenameProvider.ts delete mode 100644 src/razor/src/rename/serializableRenameDocument.ts delete mode 100644 src/razor/src/rpc/languageKind.ts delete mode 100644 src/razor/src/rpc/languageQueryRequest.ts delete mode 100644 src/razor/src/rpc/languageQueryResponse.ts delete mode 100644 src/razor/src/rpc/razorMapToDocumentRangesRequest.ts delete mode 100644 src/razor/src/rpc/razorMapToDocumentRangesResponse.ts delete mode 100644 src/razor/src/rpc/serializableCreateDocument.ts delete mode 100644 src/razor/src/rpc/serializableDeleteDocument.ts delete mode 100644 src/razor/src/rpc/serializableTextDocumentEdit.ts delete mode 100644 src/razor/src/rpc/serializableWorkspaceEdit.ts delete mode 100644 src/razor/src/rpc/serverTextChange.ts delete mode 100644 src/razor/src/rpc/serverTextSpan.ts delete mode 100644 src/razor/src/rpc/updateBufferRequest.ts delete mode 100644 src/razor/src/semantic/provideSemanticTokensResponse.ts delete mode 100644 src/razor/src/semantic/semanticTokens.ts delete mode 100644 src/razor/src/semantic/semanticTokensRangeHandler.ts delete mode 100644 src/razor/src/semantic/serializableSemanticTokensParams.ts delete mode 100644 src/razor/src/signatureHelp/razorSignatureHelpProvider.ts delete mode 100644 src/razor/src/simplify/razorSimplifyMethodHandler.ts delete mode 100644 src/razor/src/simplify/serializableDelegatedSimplifyMethodParams.ts delete mode 100644 src/razor/src/simplify/serializableSimplifyMethodParams.ts delete mode 100644 src/razor/src/simplify/serializableTextDocumentIdentifierAndVersion.ts delete mode 100644 src/razor/src/telemetryReporter.ts diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 2e1b7a2b14..0177b4b991 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -67,26 +67,9 @@ "Replace existing build and debug assets?": "Replace existing build and debug assets?", "Could not locate .NET Core project in '{0}'. Assets were not generated.": "Could not locate .NET Core project in '{0}'. Assets were not generated.", "Unable to generate assets to build and debug. {0}.": "Unable to generate assets to build and debug. {0}.", - "Cannot load Razor language server because the directory was not found: '{0}'": "Cannot load Razor language server because the directory was not found: '{0}'", + "Cannot load Razor OmniSharp language server because the directory was not found: '{0}'": "Cannot load Razor OmniSharp language server because the directory was not found: '{0}'", "Razor Log": "Razor Log", "Could not find '{0}' in or above '{1}'.": "Could not find '{0}' in or above '{1}'.", - "Could not find Razor Language Server executable '{0}' within directory": "Could not find Razor Language Server executable '{0}' within directory", - "Server failed to start after retrying 5 times.": "Server failed to start after retrying 5 times.", - "Razor Language Server failed to start unexpectedly, please check the 'Razor Log' and report an issue.": "Razor Language Server failed to start unexpectedly, please check the 'Razor Log' and report an issue.", - "Tried to send requests while server is not started.": "Tried to send requests while server is not started.", - "Tried to bind on request logic while server is not started.": "Tried to bind on request logic while server is not started.", - "Tried to bind on notification logic while server is not started.": "Tried to bind on notification logic while server is not started.", - "Cannot stop Razor Language Server as it is already stopped.": "Cannot stop Razor Language Server as it is already stopped.", - "Razor Language Server failed to stop correctly, please check the 'Razor Log' and report an issue.": "Razor Language Server failed to stop correctly, please check the 'Razor Log' and report an issue.", - "Razor HTML Preview": "Razor HTML Preview", - "Unexpected error when attaching to HTML preview window.": "Unexpected error when attaching to HTML preview window.", - "Razor HTML copied to clipboard": "Razor HTML copied to clipboard", - "Report a Razor issue": "Report a Razor issue", - "Host document file path": "Host document file path", - "Virtual document file path": "Virtual document file path", - "Copy Html": "Copy Html", - "Token cancellation requested: {0}": "Token cancellation requested: {0}", - "Synchronization timed out": "Synchronization timed out", "Report Razor Issue": "Report Razor Issue", "Unexpected error when attaching to report Razor issue window.": "Unexpected error when attaching to report Razor issue window.", "You must first start the data collection before copying.": "You must first start the data collection before copying.", @@ -104,6 +87,7 @@ "Privacy Alert! The contents copied to your clipboard may contain personal data. Prior to posting to GitHub, please remove any personal data which should not be publicly viewable.": "Privacy Alert! The contents copied to your clipboard may contain personal data. Prior to posting to GitHub, please remove any personal data which should not be publicly viewable.", "Copy issue content again": "Copy issue content again", "Cannot start collecting Razor logs when {0} is set to {1}. Please open the output window, choose the \"Razor Log\", and use the gear icon to ensure the log level is set to \"Debug\" or \"Trace\".": "Cannot start collecting Razor logs when {0} is set to {1}. Please open the output window, choose the \"Razor Log\", and use the gear icon to ensure the log level is set to \"Debug\" or \"Trace\".", + "Report a Razor issue": "Report a Razor issue", "Non Razor file as active document": "Non Razor file as active document", "Could not determine CSharp content": "Could not determine CSharp content", "Could not determine Html content": "Could not determine Html content", @@ -128,20 +112,10 @@ "Razor.VSCode version": "Razor.VSCode version", "VSCode version": "VSCode version", "Extensions": "Extensions", - "Projected CSharp as seen by extension": "Projected CSharp as seen by extension", - "Unable to resolve VSCode's version of CSharp": "Unable to resolve VSCode's version of CSharp", - "Projected Html as seen by extension": "Projected Html as seen by extension", - "Unable to resolve VSCode's version of Html": "Unable to resolve VSCode's version of Html", "Unable to find Razor extension version.": "Unable to find Razor extension version.", "Extension": "Extension", "Author": "Author", "Version": "Version", - "Razor C# Preview": "Razor C# Preview", - "Unexpected error when attaching to C# preview window.": "Unexpected error when attaching to C# preview window.", - "Razor C# copied to clipboard": "Razor C# copied to clipboard", - "Copy C#": "Copy C#", - "1 reference": "1 reference", - "{0} references": "{0} references", "Run and Debug: auto-detection found {0} for a launch browser": "Run and Debug: auto-detection found {0} for a launch browser", "There was an unexpected error while launching your debugging session. Check the console for helpful logs and visit the debugging docs for more info.": "There was an unexpected error while launching your debugging session. Check the console for helpful logs and visit the debugging docs for more info.", "View Debug Docs": "View Debug Docs", diff --git a/src/lsptoolshost/activate.ts b/src/lsptoolshost/activate.ts index bc8d0e04d7..4a8c24135f 100644 --- a/src/lsptoolshost/activate.ts +++ b/src/lsptoolshost/activate.ts @@ -16,7 +16,6 @@ import { registerUnitTestingCommands } from './testing/unitTesting'; import { registerLanguageServerOptionChanges } from './options/optionChanges'; import { Observable } from 'rxjs'; import { RoslynLanguageServerEvents } from './server/languageServerEvents'; -import { registerRazorCommands } from './razor/razorCommands'; import { registerCodeActionFixAllCommands } from './diagnostics/fixAllCodeAction'; import { commonOptions, languageServerOptions } from '../shared/options'; import { registerNestedCodeActionCommands } from './diagnostics/nestedCodeAction'; @@ -85,7 +84,6 @@ export async function activateRoslynLanguageServer( registerNestedCodeActionCommands(context, languageServer, _channel); registerCodeActionFixAllCommands(context, languageServer, _channel); - registerRazorCommands(context, languageServer); registerRazorEndpoints(context, languageServer, razorLogger, platformInfo); registerUnitTestingCommands(context, languageServer); diff --git a/src/lsptoolshost/razor/htmlDocumentManager.ts b/src/lsptoolshost/razor/htmlDocumentManager.ts index f2fe885f98..f7980119a4 100644 --- a/src/lsptoolshost/razor/htmlDocumentManager.ts +++ b/src/lsptoolshost/razor/htmlDocumentManager.ts @@ -7,13 +7,14 @@ import * as vscode from 'vscode'; import { RazorLogger } from '../../razor/src/razorLogger'; import { PlatformInformation } from '../../shared/platform'; import { getUriPath } from '../../razor/src/uriPaths'; -import { virtualHtmlSuffix } from '../../razor/src/razorConventions'; import { HtmlDocumentContentProvider } from './htmlDocumentContentProvider'; import { HtmlDocument } from './htmlDocument'; import { RoslynLanguageServer } from '../server/roslynLanguageServer'; import { RequestType, TextDocumentIdentifier } from 'vscode-languageserver-protocol'; import { UriConverter } from '../utils/uriConverter'; +const virtualHtmlSuffix = '__virtual.html'; + export class HtmlDocumentManager { private readonly htmlDocuments: { [hostDocumentPath: string]: HtmlDocument } = {}; private readonly contentProvider: HtmlDocumentContentProvider; diff --git a/src/lsptoolshost/razor/razorCommands.ts b/src/lsptoolshost/razor/razorCommands.ts deleted file mode 100644 index fd398bbaeb..0000000000 --- a/src/lsptoolshost/razor/razorCommands.ts +++ /dev/null @@ -1,140 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { RoslynLanguageServer } from '../server/roslynLanguageServer'; -import * as vscode from 'vscode'; -import { - DidChangeTextDocumentNotification, - DidCloseTextDocumentNotification, - DidCloseTextDocumentParams, - DidChangeTextDocumentParams, - DocumentDiagnosticParams, - RequestType, - DocumentDiagnosticRequest, - DocumentDiagnosticReport, - CancellationToken, - CodeAction, - CodeActionParams, - CodeActionRequest, - CodeActionResolveRequest, - CompletionParams, - CompletionRequest, - CompletionResolveRequest, - CompletionItem, - InlayHint, - InlayHintResolveRequest, - InlayHintParams, - InlayHintRequest, -} from 'vscode-languageclient'; -import SerializableSimplifyMethodParams from '../../razor/src/simplify/serializableSimplifyMethodParams'; -import { TextEdit } from 'vscode-html-languageservice'; -import { SerializableFormatNewFileParams } from '../../razor/src/formatNewFile/serializableFormatNewFileParams'; - -// These are commands that are invoked by the Razor extension, and are used to send LSP requests to the Roslyn LSP server -export const roslynDidChangeCommand = 'roslyn.changeRazorCSharp'; -export const roslynDidCloseCommand = 'roslyn.closeRazorCSharp'; -export const roslynPullDiagnosticCommand = 'roslyn.pullDiagnosticRazorCSharp'; -export const provideCodeActionsCommand = 'roslyn.provideCodeActions'; -export const resolveCodeActionCommand = 'roslyn.resolveCodeAction'; -export const provideCompletionsCommand = 'roslyn.provideCompletions'; -export const resolveCompletionsCommand = 'roslyn.resolveCompletion'; -export const roslynSimplifyMethodCommand = 'roslyn.simplifyMethod'; -export const roslynFormatNewFileCommand = 'roslyn.formatNewFile'; -export const razorInitializeCommand = 'razor.initialize'; -export const provideInlayHintsCommand = 'roslyn.provideInlayHints'; -export const resolveInlayHintCommand = 'roslyn.resolveInlayHint'; - -export function registerRazorCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) { - // Razor will call into us (via command) for generated file didChange/didClose notifications. We'll then forward these - // notifications along to Roslyn. didOpen notifications are handled separately via the vscode.openTextDocument method. - context.subscriptions.push( - vscode.commands.registerCommand(roslynDidChangeCommand, async (notification: DidChangeTextDocumentParams) => { - await languageServer.sendNotification(DidChangeTextDocumentNotification.method, notification); - }) - ); - context.subscriptions.push( - vscode.commands.registerCommand(roslynDidCloseCommand, async (notification: DidCloseTextDocumentParams) => { - await languageServer.sendNotification(DidCloseTextDocumentNotification.method, notification); - }) - ); - context.subscriptions.push( - vscode.commands.registerCommand(roslynPullDiagnosticCommand, async (request: DocumentDiagnosticParams) => { - const diagnosticRequestType = new RequestType( - DocumentDiagnosticRequest.method - ); - return await languageServer.sendRequest(diagnosticRequestType, request, CancellationToken.None); - }) - ); - context.subscriptions.push( - vscode.commands.registerCommand( - roslynSimplifyMethodCommand, - async (request: SerializableSimplifyMethodParams) => { - const simplifyMethodRequestType = new RequestType( - 'roslyn/simplifyMethod' - ); - return await languageServer.sendRequest(simplifyMethodRequestType, request, CancellationToken.None); - } - ) - ); - - const formatNewFileRequestType = new RequestType( - 'roslyn/formatNewFile' - ); - context.subscriptions.push( - vscode.commands.registerCommand( - roslynFormatNewFileCommand, - async (request: SerializableFormatNewFileParams) => { - return await languageServer.sendRequest(formatNewFileRequestType, request, CancellationToken.None); - } - ) - ); - - // The VS Code API for code actions (and the vscode.CodeAction type) doesn't support everything that LSP supports, - // namely the data property, which Razor needs to identify which code actions are on their allow list, so we need - // to expose a command for them to directly invoke our code actions LSP endpoints, rather than use built-in commands. - context.subscriptions.push( - vscode.commands.registerCommand(provideCodeActionsCommand, async (request: CodeActionParams) => { - return await languageServer.sendRequest(CodeActionRequest.type, request, CancellationToken.None); - }) - ); - context.subscriptions.push( - vscode.commands.registerCommand(resolveCodeActionCommand, async (request: CodeAction) => { - return await languageServer.sendRequest(CodeActionResolveRequest.type, request, CancellationToken.None); - }) - ); - - context.subscriptions.push( - vscode.commands.registerCommand(provideInlayHintsCommand, async (request: InlayHintParams) => { - return await languageServer.sendRequest(InlayHintRequest.type, request, CancellationToken.None); - }) - ); - - context.subscriptions.push( - vscode.commands.registerCommand(resolveInlayHintCommand, async (request: InlayHint) => { - return await languageServer.sendRequest(InlayHintResolveRequest.type, request, CancellationToken.None); - }) - ); - - context.subscriptions.push( - vscode.commands.registerCommand(provideCompletionsCommand, async (request: CompletionParams) => { - return await languageServer.sendRequest(CompletionRequest.type, request, CancellationToken.None); - }) - ); - context.subscriptions.push( - vscode.commands.registerCommand(resolveCompletionsCommand, async (request: CompletionItem) => { - return await languageServer.sendRequest(CompletionResolveRequest.type, request, CancellationToken.None); - }) - ); - - // Roslyn is responsible for producing a json file containing information for Razor, that comes from the compilation for - // a project. We want to defer this work until necessary, so this command is called by the Razor document manager to tell - // us when they need us to initialize the Razor things. - context.subscriptions.push( - vscode.commands.registerCommand(razorInitializeCommand, async (pipeName) => { - // params object must match https://github.com/dotnet/roslyn/blob/325ec8d93f9a28701fdcacffb175d2b01c3ac682/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/RazorInitializeHandler.cs#L37 - await languageServer.sendNotification('razor/initialize', { pipeName: pipeName }); - }) - ); -} diff --git a/src/lsptoolshost/razor/razorEndpoints.ts b/src/lsptoolshost/razor/razorEndpoints.ts index 2428bd775e..af846ee8cf 100644 --- a/src/lsptoolshost/razor/razorEndpoints.ts +++ b/src/lsptoolshost/razor/razorEndpoints.ts @@ -69,13 +69,7 @@ export function registerRazorEndpoints( // function registerCohostingEndpoints() { const documentManager = new HtmlDocumentManager(platformInfo, roslynLanguageServer, razorLogger); - const reportIssueCommand = new ReportIssueCommand( - vscode, - undefined, - documentManager, - roslynLanguageServer, - razorLogger - ); + const reportIssueCommand = new ReportIssueCommand(vscode, documentManager, roslynLanguageServer, razorLogger); context.subscriptions.push(documentManager.register()); context.subscriptions.push(reportIssueCommand.register()); diff --git a/src/lsptoolshost/server/roslynLanguageServer.ts b/src/lsptoolshost/server/roslynLanguageServer.ts index 4d9848829e..98109be50d 100644 --- a/src/lsptoolshost/server/roslynLanguageServer.ts +++ b/src/lsptoolshost/server/roslynLanguageServer.ts @@ -31,7 +31,6 @@ import { } from 'vscode-languageclient/node'; import { PlatformInformation } from '../../shared/platform'; import { readConfigurations } from '../options/configurationMiddleware'; -import { DynamicFileInfoHandler } from '../../razor/src/dynamicFile/dynamicFileInfoHandler'; import * as RoslynProtocol from './roslynProtocol'; import { CSharpDevKitExports } from '../../csharpDevKitExports'; import { SolutionSnapshotId } from '../solutionSnapshot/ISolutionSnapshotProvider'; @@ -59,8 +58,6 @@ import { BuildDiagnosticsService } from '../diagnostics/buildDiagnosticsService' import { getComponentPaths } from '../extensions/builtInComponents'; import { OnAutoInsertFeature } from '../autoInsert/onAutoInsertFeature'; import { ProjectContextService } from '../projectContext/projectContextService'; -import { ProvideDynamicFileResponse } from '../../razor/src/dynamicFile/provideDynamicFileResponse'; -import { ProvideDynamicFileParams } from '../../razor/src/dynamicFile/provideDynamicFileParams'; import { ActionOption, CommandOption, @@ -68,7 +65,6 @@ import { showInformationMessage, } from '../../shared/observers/utils/showMessage'; import { TelemetryEventNames } from '../../shared/telemetryEventNames'; -import { RazorDynamicFileChangedParams } from '../../razor/src/dynamicFile/dynamicFileUpdatedParams'; import { getProfilingEnvVars } from '../profiling/profiling'; import { isString } from '../utils/isString'; import { getServerPath } from '../activate'; @@ -79,10 +75,6 @@ import { UriConverter } from '../utils/uriConverter'; let _wasActivatedWithCSharpDevkit: boolean | undefined; export class RoslynLanguageServer { - // These are notifications we will get from the LSP server and will forward to the Razor extension. - private static readonly provideRazorDynamicFileInfoMethodName: string = 'razor/provideDynamicFileInfo'; - private static readonly removeRazorDynamicFileInfoMethodName: string = 'razor/removeDynamicFileInfo'; - /** * The encoding to use when writing to and from the stream. */ @@ -144,9 +136,6 @@ export class RoslynLanguageServer { this._projectContextService = new ProjectContextService(this, this._languageServerEvents); - // Register Razor dynamic file info handling - this.registerDynamicFileInfo(); - this.registerDebuggerAttach(); registerShowToastNotification(this._languageClient); @@ -832,37 +821,6 @@ export class RoslynLanguageServer { }; } - private ProvideDyanmicFileInfoType: RequestType = - new RequestType(RoslynLanguageServer.provideRazorDynamicFileInfoMethodName); - - private registerDynamicFileInfo() { - // When the Roslyn language server sends a request for Razor dynamic file info, we forward that request along to Razor via - // a command. - this._languageClient.onRequest( - this.ProvideDyanmicFileInfoType, - async (request) => - vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, request) - ); - this._languageClient.onNotification( - RoslynLanguageServer.removeRazorDynamicFileInfoMethodName, - async (notification) => - vscode.commands.executeCommand(DynamicFileInfoHandler.removeDynamicFileInfoCommand, notification) - ); - vscode.commands.registerCommand( - DynamicFileInfoHandler.dynamicFileUpdatedCommand, - async (notification: RazorDynamicFileChangedParams) => { - if (this.isRunning()) { - await this.sendNotification( - 'razor/dynamicFileInfoChanged', - notification - ); - } else { - this._channel.warn('Tried to send razor/dynamicFileInfoChanged while server is not running'); - } - } - ); - } - // eslint-disable-next-line @typescript-eslint/promise-function-async private WaitForAttachCompleteAsync(attachRequestId: string): Promise { return new Promise((resolve) => { diff --git a/src/lsptoolshost/utils/uriConverter.ts b/src/lsptoolshost/utils/uriConverter.ts index 24d19ff79a..7de2acccc2 100644 --- a/src/lsptoolshost/utils/uriConverter.ts +++ b/src/lsptoolshost/utils/uriConverter.ts @@ -4,23 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { CSharpProjectedDocumentContentProvider } from '../../razor/src/csharp/csharpProjectedDocumentContentProvider'; export class UriConverter { public static serialize(uri: vscode.Uri): string { - if (uri.scheme === CSharpProjectedDocumentContentProvider.scheme) { - // VSCode specifically handles file schemes different than others: - // https://github.com/microsoft/vscode-uri/blob/b54811339bd748982d0e2697fa857a3fecc72522/src/uri.ts#L606 - // Since it's desirable that URIs follow the same scheme across different OSs regardless of - // path separator, cause generation to happen as if it was a file scheme and then replace - // with the actual scheme. This behavior follows the expectations in RazorDynamicFileInfoProvider.cs - const fileSchemUri = uri.with({ scheme: 'file' }); - const uriString = fileSchemUri.toString(true); - return uri.scheme + uriString.slice('file'.length); - } else { - // Fix issue in System.Uri where file:///c%3A/file.txt is not a valid Windows path - return uri.toString(true); - } + return uri.toString(true); } public static deserialize(value: string): vscode.Uri { diff --git a/src/razor/src/IEventEmitterFactory.ts b/src/razor/src/IEventEmitterFactory.ts deleted file mode 100644 index 14a20a4f22..0000000000 --- a/src/razor/src/IEventEmitterFactory.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { EventEmitter } from './vscodeAdapter'; - -export interface IEventEmitterFactory { - create: () => EventEmitter; -} diff --git a/src/razor/src/IRazorProject.ts b/src/razor/src/IRazorProject.ts deleted file mode 100644 index 15b1b490d7..0000000000 --- a/src/razor/src/IRazorProject.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { IRazorProjectConfiguration } from './IRazorProjectConfiguration'; - -export interface IRazorProject { - readonly uri: vscode.Uri; - readonly path: string; - readonly configuration?: IRazorProjectConfiguration; -} diff --git a/src/razor/src/IRazorProjectChangeEvent.ts b/src/razor/src/IRazorProjectChangeEvent.ts deleted file mode 100644 index 9e3a9fe968..0000000000 --- a/src/razor/src/IRazorProjectChangeEvent.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IRazorProject } from './IRazorProject'; -import { RazorProjectChangeKind } from './razorProjectChangeKind'; - -export interface IRazorProjectChangeEvent { - readonly project: IRazorProject; - readonly kind: RazorProjectChangeKind; -} diff --git a/src/razor/src/IRazorProjectConfiguration.ts b/src/razor/src/IRazorProjectConfiguration.ts deleted file mode 100644 index 2d0589e7c2..0000000000 --- a/src/razor/src/IRazorProjectConfiguration.ts +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export interface IRazorProjectConfiguration { - readonly path: string; - readonly uri: vscode.Uri; - readonly projectPath: string; - readonly projectUri: vscode.Uri; - readonly configuration: any; - readonly rootNamespace: string; - readonly projectWorkspaceState: any; - readonly lastUpdated: Date; - readonly documents: any; - readonly serializationFormat: string; -} diff --git a/src/razor/src/codeActions/codeActionsHandler.ts b/src/razor/src/codeActions/codeActionsHandler.ts deleted file mode 100644 index d7f8ac1481..0000000000 --- a/src/razor/src/codeActions/codeActionsHandler.ts +++ /dev/null @@ -1,132 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { CodeAction, RequestType, TextDocumentIdentifier } from 'vscode-languageserver-protocol'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { SerializableDelegatedCodeActionParams } from './serializableDelegatedCodeActionParams'; -import { LanguageKind } from '../rpc/languageKind'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { SerializableRazorResolveCodeActionParams } from './serializableRazorResolveCodeActionParams'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { provideCodeActionsCommand, resolveCodeActionCommand } from '../../../lsptoolshost/razor/razorCommands'; - -export class CodeActionsHandler { - private static readonly provideCodeActionsEndpoint = 'razor/provideCodeActions'; - private static readonly resolveCodeActionsEndpoint = 'razor/resolveCodeActions'; - private codeActionRequestType: RequestType = - new RequestType(CodeActionsHandler.provideCodeActionsEndpoint); - private codeActionResolveRequestType: RequestType = - new RequestType(CodeActionsHandler.resolveCodeActionsEndpoint); - private emptyCodeActionResponse: CodeAction[] = []; - private emptyCodeAction: CodeAction = {}; - - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly serverClient: RazorLanguageServerClient, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams( - this.codeActionRequestType, - async (request: SerializableDelegatedCodeActionParams, token: vscode.CancellationToken) => - this.provideCodeActions(request, token) - ); - - await this.serverClient.onRequestWithParams( - this.codeActionResolveRequestType, - async (request: SerializableRazorResolveCodeActionParams, token: vscode.CancellationToken) => - this.resolveCodeAction(request, token) - ); - } - - private async provideCodeActions( - delegatedCodeActionParams: SerializableDelegatedCodeActionParams, - token: vscode.CancellationToken - ) { - try { - const codeActionParams = delegatedCodeActionParams.codeActionParams; - const razorDocumentUri = vscode.Uri.parse(codeActionParams.textDocument.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return this.emptyCodeActionResponse; - } - - // We only support C# delegated code actions (for now??) - if (delegatedCodeActionParams.languageKind !== LanguageKind.CSharp) { - return this.emptyCodeActionResponse; - } - - if (!this.documentManager.roslynActivated) { - // Unlike most other handlers, code actions works by directly sending an LSP request to Roslyn, so if Roslyn isn't - // activated we need to catch that here. - return this.emptyCodeActionResponse; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - delegatedCodeActionParams.hostDocumentVersion, - token - ); - if (!synchronized) { - return this.emptyCodeActionResponse; - } - - // Point this request to the virtual C# document, and call Roslyn - const virtualCSharpUri = UriConverter.serialize(razorDocument.csharpDocument.uri); - codeActionParams.textDocument = TextDocumentIdentifier.create(virtualCSharpUri); - - return await vscode.commands.executeCommand(provideCodeActionsCommand, codeActionParams); - } catch (error) { - this.logger.logWarning(`${CodeActionsHandler.provideCodeActionsEndpoint} failed with ${error}`); - } - - return this.emptyCodeActionResponse; - } - - private async resolveCodeAction( - resolveCodeActionParams: SerializableRazorResolveCodeActionParams, - token: vscode.CancellationToken - ) { - try { - const codeAction = resolveCodeActionParams.codeAction; - const razorDocumentUri = vscode.Uri.parse(resolveCodeActionParams.identifier.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return this.emptyCodeAction; - } - - // We only support C# delegated code actions (for now??) - if (resolveCodeActionParams.languageKind !== LanguageKind.CSharp) { - return this.emptyCodeAction; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocument.uri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - resolveCodeActionParams.hostDocumentVersion, - token - ); - if (!synchronized) { - return this.emptyCodeAction; - } - - // Call Roslyn. Since this code action came from Roslyn, we don't even have to point it - // to the virtual C# document. - return await vscode.commands.executeCommand(resolveCodeActionCommand, codeAction); - } catch (error) { - this.logger.logWarning(`${CodeActionsHandler.resolveCodeActionsEndpoint} failed with ${error}`); - } - - return this.emptyCodeAction; - } -} diff --git a/src/razor/src/codeActions/razorCodeAction.ts b/src/razor/src/codeActions/razorCodeAction.ts deleted file mode 100644 index 1497468a1f..0000000000 --- a/src/razor/src/codeActions/razorCodeAction.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableWorkspaceEdit } from '../rpc/serializableWorkspaceEdit'; -import { RazorCodeActionDataParams } from './razorCodeActionDataParams'; -import { RazorCodeActionResolutionParams } from './razorCodeActionResolutionParams'; - -export interface RazorCodeAction { - title: string; - edit: SerializableWorkspaceEdit; - data: RazorCodeActionResolutionParams | RazorCodeActionDataParams; -} diff --git a/src/razor/src/codeActions/razorCodeActionDataParams.ts b/src/razor/src/codeActions/razorCodeActionDataParams.ts deleted file mode 100644 index 9cc69a6ee5..0000000000 --- a/src/razor/src/codeActions/razorCodeActionDataParams.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface RazorCodeActionDataParams { - CustomTags: string[]; -} diff --git a/src/razor/src/codeActions/razorCodeActionResolutionParams.ts b/src/razor/src/codeActions/razorCodeActionResolutionParams.ts deleted file mode 100644 index 329039498b..0000000000 --- a/src/razor/src/codeActions/razorCodeActionResolutionParams.ts +++ /dev/null @@ -1,9 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface RazorCodeActionResolutionParams { - action: string; - data: object; -} diff --git a/src/razor/src/codeActions/razorCodeActionRunner.ts b/src/razor/src/codeActions/razorCodeActionRunner.ts deleted file mode 100644 index 8c3975e67c..0000000000 --- a/src/razor/src/codeActions/razorCodeActionRunner.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { convertWorkspaceEditFromSerializable } from '../rpc/serializableWorkspaceEdit'; -import { RazorCodeAction } from './razorCodeAction'; -import { RazorCodeActionResolutionParams } from './razorCodeActionResolutionParams'; - -export class RazorCodeActionRunner { - private static readonly codeActionResolveEndpoint = 'textDocument/codeActionResolve'; - private static readonly razorCodeActionRunnerCommand = 'razor/runCodeAction'; - - constructor(private readonly serverClient: RazorLanguageServerClient, private readonly logger: RazorLogger) {} - - public register(): vscode.Disposable { - return vscode.commands.registerCommand( - RazorCodeActionRunner.razorCodeActionRunnerCommand, - async (request: RazorCodeActionResolutionParams) => this.runCodeAction(request), - this - ); - } - - private async runCodeAction(request: RazorCodeActionResolutionParams): Promise { - const response: RazorCodeAction = await this.serverClient.sendRequest( - RazorCodeActionRunner.codeActionResolveEndpoint, - { data: request, title: request.action } - ); - - let changesWorkspaceEdit: vscode.WorkspaceEdit; - let documentChangesWorkspaceEdit: vscode.WorkspaceEdit; - - try { - changesWorkspaceEdit = convertWorkspaceEditFromSerializable({ changes: response.edit.changes }); - documentChangesWorkspaceEdit = convertWorkspaceEditFromSerializable({ - documentChanges: response.edit.documentChanges, - }); - } catch (error) { - this.logger.logError(`Unexpected error deserializing code action for ${request.action}`, error as Error); - return Promise.resolve(false); - } - - return vscode.workspace - .applyEdit(documentChangesWorkspaceEdit) - .then(() => vscode.workspace.applyEdit(changesWorkspaceEdit)); - } -} diff --git a/src/razor/src/codeActions/serializableCodeActionParams.ts b/src/razor/src/codeActions/serializableCodeActionParams.ts deleted file mode 100644 index 3735ccc94e..0000000000 --- a/src/razor/src/codeActions/serializableCodeActionParams.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CodeActionContext } from 'vscode-languageserver-protocol'; -import { SerializableRange } from '../rpc/serializableRange'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableCodeActionParams { - textDocument: SerializableTextDocumentIdentifier; - range: SerializableRange; - context: CodeActionContext; -} diff --git a/src/razor/src/codeActions/serializableDelegatedCodeActionParams.ts b/src/razor/src/codeActions/serializableDelegatedCodeActionParams.ts deleted file mode 100644 index 9235d45bef..0000000000 --- a/src/razor/src/codeActions/serializableDelegatedCodeActionParams.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { LanguageKind } from '../rpc/languageKind'; -import { SerializableCodeActionParams } from './serializableCodeActionParams'; - -export interface SerializableDelegatedCodeActionParams { - hostDocumentVersion: number; - codeActionParams: SerializableCodeActionParams; - languageKind: LanguageKind; -} diff --git a/src/razor/src/codeActions/serializableRazorResolveCodeActionParams.ts b/src/razor/src/codeActions/serializableRazorResolveCodeActionParams.ts deleted file mode 100644 index d449fdab22..0000000000 --- a/src/razor/src/codeActions/serializableRazorResolveCodeActionParams.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { LanguageKind } from '../rpc/languageKind'; -import { CodeAction } from 'vscode-languageserver-protocol'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableRazorResolveCodeActionParams { - hostDocumentVersion: number; - identifier: SerializableTextDocumentIdentifier; - languageKind: LanguageKind; - codeAction: CodeAction; -} diff --git a/src/razor/src/codeLens/razorCodeLens.ts b/src/razor/src/codeLens/razorCodeLens.ts deleted file mode 100644 index 3883957d76..0000000000 --- a/src/razor/src/codeLens/razorCodeLens.ts +++ /dev/null @@ -1,17 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export class RazorCodeLens extends vscode.CodeLens { - constructor( - range: vscode.Range, - public uri: vscode.Uri, - public document: vscode.TextDocument, - command?: vscode.Command - ) { - super(range, command); - } -} diff --git a/src/razor/src/codeLens/razorCodeLensProvider.ts b/src/razor/src/codeLens/razorCodeLensProvider.ts deleted file mode 100644 index e6b143eeb8..0000000000 --- a/src/razor/src/codeLens/razorCodeLensProvider.ts +++ /dev/null @@ -1,158 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLogger } from '../razorLogger'; -import { LanguageKind } from '../rpc/languageKind'; -import { RazorCodeLens } from './razorCodeLens'; -import { MappingHelpers } from '../mapping/mappingHelpers'; - -export class RazorCodeLensProvider extends RazorLanguageFeatureBase implements vscode.CodeLensProvider { - public onDidChangeCodeLenses: vscode.Event; - - constructor( - documentSynchronizer: RazorDocumentSynchronizer, - documentManager: RazorDocumentManager, - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger - ) { - super(documentSynchronizer, documentManager, serviceClient, logger); - - const onCodeLensChangedEmitter = new vscode.EventEmitter(); - this.onDidChangeCodeLenses = onCodeLensChangedEmitter.event; - - documentManager.onChange(async (event) => { - if (event.kind !== RazorDocumentChangeKind.added) { - return; - } - - // Sometimes when a file already open in the editor is renamed, provideCodeLens would return empty - // because the background C# document is not ready yet. So, when that happens we should manually invoke - // a code lens refresh after waiting for a little while. - const openDocumentUris = vscode.workspace.textDocuments - .filter((doc) => !doc.isClosed) - .map((doc) => doc.uri); - if (openDocumentUris.includes(event.document.uri)) { - await new Promise((r) => setTimeout(r, 5000)); - onCodeLensChangedEmitter.fire(); - } - }); - documentManager.onRazorInitialized(() => onCodeLensChangedEmitter.fire()); - } - - public async provideCodeLenses(document: vscode.TextDocument, _: vscode.CancellationToken) { - try { - // If a Razor file is open in VS Code at start up, we can be called before Razor is initialized. - // We don't want to answer those calls, but we'll be refreshed when everything is ready. - if (!this.documentManager.razorDocumentGenerationInitialized) { - return; - } - - const razorDocument = await this.documentManager.getDocument(document.uri); - if (!razorDocument) { - return; - } - - const csharpDocument = razorDocument.csharpDocument; - - // Get all the code lenses that applies to our projected C# document. - const codeLenses = (await vscode.commands.executeCommand( - 'vscode.executeCodeLensProvider', - csharpDocument.uri - )) as vscode.CodeLens[]; - if (!codeLenses) { - return; - } - - // Re-map the CodeLens locations to the original Razor document. - const remappedCodeLenses = new Array(); - for (const codeLens of codeLenses) { - const result = await this.serviceClient.mapToDocumentRanges( - LanguageKind.CSharp, - [codeLens.range], - razorDocument.uri - ); - if (result && result.ranges.length > 0) { - const newCodeLens = new RazorCodeLens( - result.ranges[0], - razorDocument.uri, - document, - codeLens.command - ); - remappedCodeLenses.push(newCodeLens); - } else { - // This means this CodeLens was for non-user code. We can safely ignore those. - } - } - - return remappedCodeLenses; - } catch (error) { - this.logger.logWarning(`provideCodeLens failed with ${error}`); - return []; - } - } - - public async resolveCodeLens(codeLens: vscode.CodeLens, token: vscode.CancellationToken) { - if (codeLens instanceof RazorCodeLens) { - return this.resolveRazorCodeLens(codeLens, token); - } - } - - private async resolveRazorCodeLens( - codeLens: RazorCodeLens, - token: vscode.CancellationToken - ): Promise { - // Initialize with default values. - codeLens.command = { - title: '', - command: '', - arguments: [], - }; - - try { - const razorDocument = await this.documentManager.getDocument(codeLens.uri); - if (!razorDocument) { - return codeLens; - } - - // Make sure this CodeLens is for a valid location in the projected C# document. - const projection = await this.getProjection(codeLens.document, codeLens.range.start, token); - if (!projection || projection.languageKind !== LanguageKind.CSharp) { - return codeLens; - } - - const references = (await vscode.commands.executeCommand( - 'vscode.executeReferenceProvider', - projection.uri, - projection.position - )) as vscode.Location[]; - - const remappedReferences = await MappingHelpers.remapGeneratedFileLocations( - references, - this.serviceClient, - this.logger, - token - ); - - // We now have a list of references to show in the CodeLens. - const count = remappedReferences.length; - codeLens.command = { - title: count === 1 ? vscode.l10n.t('1 reference') : vscode.l10n.t('{0} references', count), - command: 'editor.action.showReferences', - arguments: [razorDocument.uri, codeLens.range.start, remappedReferences], - }; - - return codeLens; - } catch (error) { - this.logger.logWarning(`resolveCodeLens failed with ${error}`); - return codeLens; - } - } -} diff --git a/src/razor/src/colorPresentation/colorPresentationHandler.ts b/src/razor/src/colorPresentation/colorPresentationHandler.ts index 8161700aa6..dbe21cd5f6 100644 --- a/src/razor/src/colorPresentation/colorPresentationHandler.ts +++ b/src/razor/src/colorPresentation/colorPresentationHandler.ts @@ -4,65 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { RequestType } from 'vscode-jsonrpc'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; import { convertTextEditToSerializable, SerializableTextEdit } from '../rpc/serializableTextEdit'; import { ColorPresentationContext } from './colorPresentationContext'; import { SerializableColorPresentation } from './serializableColorPresentation'; import { SerializableColorPresentationParams } from './serializableColorPresentationParams'; export class ColorPresentationHandler { - private static readonly provideHtmlColorPresentation = 'razor/provideHtmlColorPresentation'; - private colorPresentationRequestType: RequestType< - SerializableColorPresentationParams, - SerializableColorPresentation[], - any - > = new RequestType(ColorPresentationHandler.provideHtmlColorPresentation); - private emptyColorInformationResponse: SerializableColorPresentation[] = []; - - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly serverClient: RazorLanguageServerClient, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams< - SerializableColorPresentationParams, - SerializableColorPresentation[], - any - >( - this.colorPresentationRequestType, - async (request: SerializableColorPresentationParams, token: vscode.CancellationToken) => - this.provideHtmlColorPresentation(request, token) - ); - } - - private async provideHtmlColorPresentation( - colorPresentationParams: SerializableColorPresentationParams, - _: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse(`${colorPresentationParams.textDocument.uri}`, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - this.logger.logWarning( - `Could not find Razor document ${razorDocumentUri}; returning empty color information.` - ); - return this.emptyColorInformationResponse; - } - - const virtualHtmlUri = razorDocument.htmlDocument.uri; - - return await ColorPresentationHandler.doColorPresentationRequest(virtualHtmlUri, colorPresentationParams); - } catch (error) { - this.logger.logWarning(`${ColorPresentationHandler.provideHtmlColorPresentation} failed with ${error}`); - } - - return this.emptyColorInformationResponse; - } + constructor() {} public static async doColorPresentationRequest( virtualHtmlUri: vscode.Uri, diff --git a/src/razor/src/completion/completionHandler.ts b/src/razor/src/completion/completionHandler.ts index 4be190186f..0c029d04d3 100644 --- a/src/razor/src/completion/completionHandler.ts +++ b/src/razor/src/completion/completionHandler.ts @@ -7,368 +7,17 @@ import * as vscode from 'vscode'; import { CompletionItem, CompletionList, - CompletionParams, - CompletionTriggerKind, InsertReplaceEdit, InsertTextFormat, InsertTextMode, MarkupContent, Position, Range, - RequestType, TextEdit, } from 'vscode-languageserver-protocol'; -import { provideCompletionsCommand, resolveCompletionsCommand } from '../../../lsptoolshost/razor/razorCommands'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { SerializableDelegatedCompletionParams } from './serializableDelegatedCompletionParams'; -import { SerializableDelegatedCompletionItemResolveParams } from './serializableDelegatedCompletionItemResolveParams'; -import { LanguageKind } from '../rpc/languageKind'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { SerializableTextEdit } from '../rpc/serializableTextEdit'; -import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { IProjectedDocument } from '../projection/IProjectedDocument'; -import { CSharpProjectedDocumentContentProvider } from '../csharp/csharpProjectedDocumentContentProvider'; export class CompletionHandler { - private static readonly completionEndpoint = 'razor/completion'; - private static readonly completionResolveEndpoint = 'razor/completionItem/resolve'; - private completionRequestType: RequestType = - new RequestType(CompletionHandler.completionEndpoint); - private completionResolveRequestType: RequestType< - SerializableDelegatedCompletionItemResolveParams, - CompletionItem, - any - > = new RequestType(CompletionHandler.completionResolveEndpoint); - private static readonly emptyCompletionList: CompletionList = { - items: new Array(0), - }; - private static readonly emptyCompletionItem: CompletionItem = {}; - - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly serverClient: RazorLanguageServerClient, - private readonly projectedCSharpProvider: CSharpProjectedDocumentContentProvider, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams( - this.completionRequestType, - async (request: SerializableDelegatedCompletionParams, token: vscode.CancellationToken) => - this.provideCompletions(request, token) - ); - - await this.serverClient.onRequestWithParams< - SerializableDelegatedCompletionItemResolveParams, - CompletionItem, - any - >( - this.completionResolveRequestType, - async (request: SerializableDelegatedCompletionItemResolveParams, token: vscode.CancellationToken) => - this.provideResolvedCompletionItem(request, token) - ); - } - - private async provideCompletions( - delegatedCompletionParams: SerializableDelegatedCompletionParams, - token: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse( - delegatedCompletionParams.identifier.textDocumentIdentifier.uri, - true - ); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return CompletionHandler.emptyCompletionList; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - - let virtualDocument: any; - if (delegatedCompletionParams.projectedKind === LanguageKind.Html) { - virtualDocument = razorDocument.htmlDocument; - } else if (delegatedCompletionParams.projectedKind === LanguageKind.CSharp) { - virtualDocument = razorDocument.csharpDocument; - } else { - this.logger.logWarning(`Unknown language kind value ${delegatedCompletionParams.projectedKind}`); - return CompletionHandler.emptyCompletionList; - } - - if (!virtualDocument) { - this.logger.logWarning(`Null or undefined virtual document: ${virtualDocument}`); - return CompletionHandler.emptyCompletionList; - } - - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - virtualDocument, - delegatedCompletionParams.identifier.version, - token - ); - if (!synchronized) { - return CompletionHandler.emptyCompletionList; - } - - // "@" is not a valid trigger character for C# / HTML and therefore we need to translate - // it into a non-trigger invocation. - const modifiedTriggerCharacter = - delegatedCompletionParams.context.triggerCharacter === '@' - ? undefined - : delegatedCompletionParams.context.triggerCharacter; - const triggerKind = - delegatedCompletionParams.context.triggerCharacter === '@' - ? CompletionTriggerKind.Invoked - : delegatedCompletionParams.context.triggerKind; - - // Roslyn/C# completion - if (delegatedCompletionParams.projectedKind === LanguageKind.CSharp) { - return this.provideCSharpCompletions( - triggerKind, - modifiedTriggerCharacter, - virtualDocument as CSharpProjectedDocument, - delegatedCompletionParams.projectedPosition, - delegatedCompletionParams.provisionalTextEdit - ); - } - - // HTML completion - provided via vscode command - return CompletionHandler.provideVscodeCompletions( - virtualDocument.uri, - delegatedCompletionParams.projectedPosition, - modifiedTriggerCharacter - ); - } catch (error) { - this.logger.logWarning(`${CompletionHandler.completionEndpoint} failed with ${error}`); - } - - return CompletionHandler.emptyCompletionList; - } - - private async provideResolvedCompletionItem( - delegatedCompletionItemResolveParams: SerializableDelegatedCompletionItemResolveParams, - _cancellationToken: vscode.CancellationToken - ) { - // TODO: Snippet support - const razorDocumentUri = vscode.Uri.parse( - delegatedCompletionItemResolveParams.identifier.textDocumentIdentifier.uri, - true - ); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - const virtualCsharpDocument = razorDocument.csharpDocument as CSharpProjectedDocument; - const provisionalDotPosition = virtualCsharpDocument.getProvisionalDotPosition(); - try { - if ( - delegatedCompletionItemResolveParams.originatingKind != LanguageKind.CSharp || - delegatedCompletionItemResolveParams.completionItem.data.TextDocument == null - ) { - return delegatedCompletionItemResolveParams.completionItem; - } else { - // will add a provisional dot to the C# document if a C# provisional completion triggered - // this resolve completion request - if (virtualCsharpDocument.ensureResolveProvisionalDot()) { - if (provisionalDotPosition !== undefined) { - await this.ensureProvisionalDotUpdatedInCSharpDocument( - virtualCsharpDocument.uri, - provisionalDotPosition - ); - } - } - const newItem = await vscode.commands.executeCommand( - resolveCompletionsCommand, - delegatedCompletionItemResolveParams.completionItem - ); - - if (!newItem) { - return delegatedCompletionItemResolveParams.completionItem; - } - - return newItem; - } - } catch (error) { - this.logger.logWarning(`${CompletionHandler.completionResolveEndpoint} failed with ${error}`); - } finally { - // remove the provisional dot after the resolve has completed and if it was added - if (virtualCsharpDocument.removeResolveProvisionalDot()) { - const removeDot = true; - if (provisionalDotPosition !== undefined) { - await this.ensureProvisionalDotUpdatedInCSharpDocument( - virtualCsharpDocument.uri, - provisionalDotPosition, - removeDot - ); - } - } - } - - return CompletionHandler.emptyCompletionItem; - } - - private async provideCSharpCompletions( - triggerKind: CompletionTriggerKind, - triggerCharacter: string | undefined, - virtualDocument: CSharpProjectedDocument, - projectedPosition: Position, - provisionalTextEdit?: SerializableTextEdit - ) { - // Convert projected position to absolute index for provisional dot - const absoluteIndex = CompletionHandler.getIndexOfPosition(virtualDocument, projectedPosition); - try { - // currently, we are temporarily adding a '.' to the C# document to ensure correct completions are provided - // for each roslyn.resolveCompletion request and we remember the location from the last provisional completion request. - // Therefore we need to remove the resolve provisional dot position - // at the start of every completion request in case a '.' gets added when it shouldn't be. - virtualDocument.clearResolveCompletionRequestVariables(); - if (provisionalTextEdit) { - // provisional C# completion - // add '.' to projected C# document to ensure correct completions are provided - // This is because when a user types '.' after an object, it is initially in - // html document and not generated C# document. - if (absoluteIndex === -1) { - return CompletionHandler.emptyCompletionList; - } - virtualDocument.addProvisionalDotAt(absoluteIndex); - // projected Position is passed in to the virtual doc so that it can be used during the resolve request - virtualDocument.setProvisionalDotPosition(projectedPosition); - await this.ensureProvisionalDotUpdatedInCSharpDocument(virtualDocument.uri, projectedPosition); - } - - const virtualDocumentUri = UriConverter.serialize(virtualDocument.uri); - const params: CompletionParams = { - context: { - triggerKind: triggerKind, - triggerCharacter: triggerCharacter, - }, - textDocument: { - uri: virtualDocumentUri, - }, - position: projectedPosition, - }; - - const csharpCompletions = await vscode.commands.executeCommand( - provideCompletionsCommand, - params - ); - if (!csharpCompletions) { - return CompletionHandler.emptyCompletionList; - } - CompletionHandler.adjustCSharpCompletionList(csharpCompletions, triggerCharacter); - return csharpCompletions; - } catch (error) { - this.logger.logWarning(`${CompletionHandler.completionEndpoint} failed with ${error}`); - } finally { - if (provisionalTextEdit && virtualDocument.removeProvisionalDot()) { - const removeDot = true; - await this.ensureProvisionalDotUpdatedInCSharpDocument( - virtualDocument.uri, - projectedPosition, - removeDot - ); - } - } - - return CompletionHandler.emptyCompletionList; - } - - private async ensureProvisionalDotUpdatedInCSharpDocument( - virtualDocumentUri: vscode.Uri, - projectedPosition: Position, - removeDot = false // if true then we ensure the provisional dot is removed instead of being added - ) { - // notifies the C# document content provider that the document content has changed - this.projectedCSharpProvider.ensureDocumentContent(virtualDocumentUri); - await this.waitForDocumentChange(virtualDocumentUri, projectedPosition, removeDot); - } - - // make sure the provisional dot is added or deleted in the virtual document for provisional completion - private async waitForDocumentChange( - uri: vscode.Uri, - projectedPosition: Position, - removeDot: boolean - ): Promise { - return new Promise((resolve) => { - const disposable = vscode.workspace.onDidChangeTextDocument((event) => { - const matchingText = removeDot ? '' : '.'; - if (event.document.uri.toString() === uri.toString()) { - // Check if the change is at the expected index - const changeAtIndex = event.contentChanges.some( - (change) => - change.range.start.character <= projectedPosition.character && - change.range.start.line === projectedPosition.line && - change.range.end.character + 1 >= projectedPosition.character && - change.range.end.line === projectedPosition.line && - change.text === matchingText - ); - if (changeAtIndex) { - // Resolve the promise and dispose of the event listener - resolve(); - disposable.dispose(); - } - } - }); - }); - } - - // Adjust Roslyn completion command results to make it more palatable to VSCode - private static adjustCSharpCompletionList(completionList: CompletionList, triggerCharacter: string | undefined) { - const data = completionList.itemDefaults?.data; - for (const completionItem of completionList.items) { - // textEdit is deprecated in favor of .range. Clear out its value to avoid any unexpected behavior. - completionItem.textEdit = undefined; - - if (triggerCharacter === '@' && completionItem.commitCharacters) { - // We remove `{`, '(', and '*' from the commit characters to prevent auto-completing the first - // completion item with a curly brace when a user intended to type `@{}` or `@()`. - completionItem.commitCharacters = completionItem.commitCharacters.filter( - (commitChar) => commitChar !== '{' && commitChar !== '(' && commitChar !== '*' - ); - } - - // for intellicode items, manually set the insertText to avoid including stars in the commit - if (completionItem.label.toString().includes('\u2605')) { - if (completionItem.textEditText) { - completionItem.insertText = completionItem.textEditText; - } - } - - // copy default item data to each item or else completion item resolve will fail later - if (!completionItem.data) { - completionItem.data = data; - } - } - } - - // Convert (line, character) Position to absolute index number - private static getIndexOfPosition(document: IProjectedDocument, position: Position): number { - const content: string = document.getContent(); - let lineNumber = 0; - let index = 0; - while (lineNumber < position.line && index < content.length) { - const ch = content[index]; - if (ch === '\r') { - lineNumber++; - if (index + 1 < content.length && content[index + 1] === '\n') { - index++; - } - } else if (ch === '\n') { - lineNumber++; - } - - index++; - } - - if (lineNumber !== position.line) { - return -1; - } - - const positionIndex = index + position.character - 1; - - return positionIndex; - } + constructor() {} // Provide completions using standard vscode executeCompletionItemProvider command // Used in HTML context diff --git a/src/razor/src/completion/serializableDelegatedCompletionItemResolveParams.ts b/src/razor/src/completion/serializableDelegatedCompletionItemResolveParams.ts deleted file mode 100644 index 6a4e5dcdda..0000000000 --- a/src/razor/src/completion/serializableDelegatedCompletionItemResolveParams.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CompletionItem } from 'vscode-languageserver-protocol'; -import { LanguageKind } from '../rpc/languageKind'; -import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion'; - -export interface SerializableDelegatedCompletionItemResolveParams { - // TODO: test OptionalVersionedTextDocumentIdentifier from vscode-languageclient - identifier: SerializableTextDocumentIdentifierAndVersion; - completionItem: CompletionItem; - originatingKind: LanguageKind; -} diff --git a/src/razor/src/completion/serializableDelegatedCompletionParams.ts b/src/razor/src/completion/serializableDelegatedCompletionParams.ts deleted file mode 100644 index e36d03be90..0000000000 --- a/src/razor/src/completion/serializableDelegatedCompletionParams.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CompletionContext } from 'vscode-languageserver-protocol'; -import { LanguageKind } from '../rpc/languageKind'; -import { SerializablePosition } from '../rpc/serializablePosition'; -import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion'; -import { SerializableTextEdit } from '../rpc/serializableTextEdit'; - -// TODO: cleanup parameter types -export interface SerializableDelegatedCompletionParams { - identifier: SerializableTextDocumentIdentifierAndVersion; - projectedPosition: SerializablePosition; - projectedKind: LanguageKind; - context: CompletionContext; - provisionalTextEdit?: SerializableTextEdit; - shouldIncludeSnippets: boolean; - // Do I need correlation ID? -} diff --git a/src/razor/src/csharp/csharpPreviewPanel.ts b/src/razor/src/csharp/csharpPreviewPanel.ts deleted file mode 100644 index 104ea8d370..0000000000 --- a/src/razor/src/csharp/csharpPreviewPanel.ts +++ /dev/null @@ -1,152 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { IRazorDocumentChangeEvent } from '../document/IRazorDocumentChangeEvent'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { getUriPath } from '../uriPaths'; -import { showErrorMessage, showInformationMessage } from '../../../shared/observers/utils/showMessage'; - -export class CSharpPreviewPanel { - public static readonly viewType = 'razorCSharpPreview'; - - private panel: vscode.WebviewPanel | undefined; - private csharpContent: string | undefined; - - constructor(private readonly documentManager: RazorDocumentManager) { - documentManager.onChange(async (event) => this.documentChanged(event)); - } - - public async show() { - if (this.panel) { - this.panel.reveal(vscode.ViewColumn.Two); - } else { - this.panel = vscode.window.createWebviewPanel( - CSharpPreviewPanel.viewType, - vscode.l10n.t('Razor C# Preview'), - vscode.ViewColumn.Two, - { - enableScripts: true, - // Disallow any remote sources - localResourceRoots: [], - } - ); - this.attachToCurrentPanel(); - } - - await this.update(); - } - - public async revive(panel: vscode.WebviewPanel) { - this.panel = panel; - this.attachToCurrentPanel(); - await this.update(); - } - - private async documentChanged(event: IRazorDocumentChangeEvent) { - if (!this.panel) { - return; - } - - if ( - event.kind === RazorDocumentChangeKind.csharpChanged || - event.kind === RazorDocumentChangeKind.opened || - event.kind === RazorDocumentChangeKind.closed - ) { - await this.update(); - } - } - - private attachToCurrentPanel() { - if (!this.panel) { - showErrorMessage(vscode, vscode.l10n.t('Unexpected error when attaching to C# preview window.')); - return; - } - - this.panel.webview.onDidReceiveMessage(async (message) => { - switch (message.command) { - case 'copy': - if (!this.csharpContent) { - return; - } - - await vscode.env.clipboard.writeText(this.csharpContent); - showInformationMessage(vscode, vscode.l10n.t('Razor C# copied to clipboard')); - return; - } - }); - this.panel.onDidDispose(() => (this.panel = undefined)); - } - - private async update() { - if (!this.panel) { - return; - } - const document = await this.documentManager.getActiveDocument(); - let hostDocumentFilePath = ''; - let virtualDocumentFilePath = ''; - - if (document) { - // The document is guaranteed to be a Razor document - this.csharpContent = document.csharpDocument.getContent(); - hostDocumentFilePath = getUriPath(document.uri); - virtualDocumentFilePath = getUriPath(document.csharpDocument.uri); - } else { - this.csharpContent = undefined; - } - - let content = this.csharpContent ? this.csharpContent : ''; - content = content.replace(/ - - - - - - ${title} - - - - - -

${hostDocumentPathLabel}: ${hostDocumentFilePath}

-

${virtualDocumentPathLabel}: ${virtualDocumentFilePath}

-
-
${content}
- -`; - } -} diff --git a/src/razor/src/csharp/csharpProjectedDocument.ts b/src/razor/src/csharp/csharpProjectedDocument.ts deleted file mode 100644 index 4b326694ef..0000000000 --- a/src/razor/src/csharp/csharpProjectedDocument.ts +++ /dev/null @@ -1,243 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IProjectedDocument } from '../projection/IProjectedDocument'; -import { ServerTextChange } from '../rpc/serverTextChange'; -import { getUriPath } from '../uriPaths'; -import { Position } from 'vscode-languageserver-protocol'; -import * as vscode from '../vscodeAdapter'; - -export class CSharpProjectedDocument implements IProjectedDocument { - public readonly path: string; - - private content = ''; - private preProvisionalContent: string | undefined; - private preResolveProvisionalContent: string | undefined; - private provisionalEditAt: number | undefined; - private resolveProvisionalEditAt: number | undefined; - private ProvisionalDotPosition: Position | undefined; - private hostDocumentVersion: number | null = null; - private updates: CSharpDocumentUpdate[] | null = null; - private _checksum: string = ''; - private _checksumAlgorithm: number = 1; // Default to Sha1 - private _encodingCodePage: number | null = null; - - public constructor(public readonly uri: vscode.Uri) { - this.path = getUriPath(uri); - } - - public get hostDocumentSyncVersion(): number | null { - return this.hostDocumentVersion; - } - - public get length(): number { - return this.content.length; - } - - public clear() { - this.setContent(''); - } - - public get checksum(): string { - return this._checksum; - } - - public get checksumAlgorithm(): number { - return this._checksumAlgorithm; - } - - public get encodingCodePage(): number | null { - return this._encodingCodePage; - } - - public update( - hostDocumentIsOpen: boolean, - edits: ServerTextChange[], - hostDocumentVersion: number, - checksum: string, - checksumAlgorithm: number, - encodingCodePage: number | null - ) { - if (hostDocumentIsOpen) { - this.removeProvisionalDot(); - - // Apply any stored edits if needed - if (this.updates) { - for (const update of this.updates) { - this.updateContent(update.changes); - } - - this.updates = null; - } - - this.updateContent(edits); - this._checksum = checksum; - this._checksumAlgorithm = checksumAlgorithm; - this._encodingCodePage = encodingCodePage; - } else { - const update = new CSharpDocumentUpdate(edits, checksum, checksumAlgorithm, encodingCodePage); - - if (this.updates) { - this.updates = this.updates.concat(update); - } else { - this.updates = [update]; - } - } - - this.hostDocumentVersion = hostDocumentVersion; - } - - public applyEdits(): ApplyEditsResponse { - const updates = this.updates; - this.updates = null; - - const originalChecksum = this._checksum; - const originalChecksumAlgorithm = this._checksumAlgorithm; - const originalEncodingCodePage = this._encodingCodePage; - - if (updates) { - for (const update of updates) { - this.updateContent(update.changes); - this._checksum = update.checksum; - this._checksumAlgorithm = update.checksumAlgorithm; - this._encodingCodePage = update.encodingCodePage; - } - } - - return { - edits: updates, - originalChecksum: originalChecksum, - originalChecksumAlgorithm: originalChecksumAlgorithm, - originalEncodingCodePage: originalEncodingCodePage, - }; - } - - public getContent() { - return this.content; - } - - // A provisional dot represents a '.' that's inserted into the projected document but will be - // removed prior to any edits that get applied. In Razor's case a provisional dot is used to - // show completions after an expression for a dot that's usually interpreted as Html. - public addProvisionalDotAt(index: number) { - if (this.provisionalEditAt === index) { - // Edits already applied. - return; - } - //reset the state for provisional completion and resolve completion - this.removeProvisionalDot(); - this.resolveProvisionalEditAt = undefined; - this.ProvisionalDotPosition = undefined; - - const newContent = this.getEditedContent('.', index, index, this.content); - this.preProvisionalContent = this.content; - this.provisionalEditAt = index; - this.setContent(newContent); - } - - public removeProvisionalDot() { - if (this.provisionalEditAt && this.preProvisionalContent) { - // Undo provisional edit if one was applied. - this.setContent(this.preProvisionalContent); - this.resolveProvisionalEditAt = this.provisionalEditAt; - this.provisionalEditAt = undefined; - this.preProvisionalContent = undefined; - return true; - } - - return false; - } - - // add resolve provisional dot if a provisional completion request was made - // A resolve provisional dot is the same as a provisional dot, but it remembers the - // last provisional dot inserted location and is used for the roslyn.resolveCompletion API - public ensureResolveProvisionalDot() { - //remove the last resolve provisional dot it it exists - this.removeResolveProvisionalDot(); - - if (this.resolveProvisionalEditAt) { - const newContent = this.getEditedContent( - '.', - this.resolveProvisionalEditAt, - this.resolveProvisionalEditAt, - this.content - ); - this.preResolveProvisionalContent = this.content; - this.setContent(newContent); - return true; - } - return false; - } - - public removeResolveProvisionalDot() { - if (this.resolveProvisionalEditAt && this.preResolveProvisionalContent) { - // Undo provisional edit if one was applied. - this.setContent(this.preResolveProvisionalContent); - this.provisionalEditAt = undefined; - this.preResolveProvisionalContent = undefined; - return true; - } - - return false; - } - - public setProvisionalDotPosition(position: Position) { - this.ProvisionalDotPosition = position; - } - - public getProvisionalDotPosition() { - return this.ProvisionalDotPosition; - } - - // since multiple roslyn.resolveCompletion requests can be made for each completion, - // we need to clear the resolveProvisionalEditIndex (currently when a new completion request is made, - // this works if resolve requests are always preceded by a completion request) - public clearResolveCompletionRequestVariables() { - this.resolveProvisionalEditAt = undefined; - this.ProvisionalDotPosition = undefined; - } - - private getEditedContent(newText: string, start: number, end: number, content: string) { - const before = content.substring(0, start); - const after = content.substring(end); - content = `${before}${newText}${after}`; - - return content; - } - - private setContent(content: string) { - this.content = content; - } - - private updateContent(edits: ServerTextChange[]) { - if (edits.length === 0) { - return; - } - - let content = this.content; - for (const edit of edits.reverse()) { - // TODO: Use a better data structure to represent the content, string concatenation is slow. - content = this.getEditedContent(edit.newText, edit.span.start, edit.span.start + edit.span.length, content); - } - - this.setContent(content); - } -} - -export class CSharpDocumentUpdate { - constructor( - public readonly changes: ServerTextChange[], - public readonly checksum: string, - public readonly checksumAlgorithm: number, - public readonly encodingCodePage: number | null - ) {} -} - -export interface ApplyEditsResponse { - edits: CSharpDocumentUpdate[] | null; - originalChecksum: string; - originalChecksumAlgorithm: number; - originalEncodingCodePage: number | null; -} diff --git a/src/razor/src/csharp/csharpProjectedDocumentContentProvider.ts b/src/razor/src/csharp/csharpProjectedDocumentContentProvider.ts deleted file mode 100644 index 0f8ee15e7b..0000000000 --- a/src/razor/src/csharp/csharpProjectedDocumentContentProvider.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IRazorDocumentChangeEvent } from '../document/IRazorDocumentChangeEvent'; -import { IRazorDocumentManager } from '../document/IRazorDocumentManager'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { IEventEmitterFactory } from '../IEventEmitterFactory'; -import { RazorLogger } from '../razorLogger'; -import { getUriPath } from '../uriPaths'; -import * as vscode from '../vscodeAdapter'; - -export class CSharpProjectedDocumentContentProvider implements vscode.TextDocumentContentProvider { - public static readonly scheme = 'virtualCSharp-razor'; - - private readonly onDidChangeEmitter: vscode.EventEmitter; - - constructor( - private readonly documentManager: IRazorDocumentManager, - eventEmitterFactory: IEventEmitterFactory, - private readonly logger: RazorLogger - ) { - documentManager.onChange((event: IRazorDocumentChangeEvent) => this.documentChanged(event)); - this.onDidChangeEmitter = eventEmitterFactory.create(); - } - - public get onDidChange() { - return this.onDidChangeEmitter.event; - } - - public provideTextDocumentContent(uri: vscode.Uri) { - const razorDocument = this.findRazorDocument(uri); - if (!razorDocument) { - // Document was removed from the document manager, meaning there's no more content for this - // file. Report an empty document. - - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Could not find document '${getUriPath( - uri - )}' when updating the C# buffer. This typically happens when a document is removed.` - ); - } - return ''; - } - - const content = `${razorDocument.csharpDocument.getContent()} -// ${razorDocument.csharpDocument.hostDocumentSyncVersion}`; - - return content; - } - - public ensureDocumentContent(uri: vscode.Uri) { - this.onDidChangeEmitter.fire(uri); - } - - private documentChanged(event: IRazorDocumentChangeEvent) { - if ( - event.kind === RazorDocumentChangeKind.csharpChanged || - event.kind === RazorDocumentChangeKind.opened || - event.kind === RazorDocumentChangeKind.removed - ) { - // We also notify changes on document removal in order to tell VSCode that there's no more - // C# content for the file. - - this.onDidChangeEmitter.fire(event.document.csharpDocument.uri); - } - } - - private findRazorDocument(uri: vscode.Uri) { - const projectedPath = getUriPath(uri); - - return this.documentManager.documents.find( - (razorDocument) => - razorDocument.csharpDocument.path.localeCompare(projectedPath, undefined, { sensitivity: 'base' }) === 0 - ); - } -} diff --git a/src/razor/src/csharp/razorCSharpFeature.ts b/src/razor/src/csharp/razorCSharpFeature.ts deleted file mode 100644 index b47425a9ad..0000000000 --- a/src/razor/src/csharp/razorCSharpFeature.ts +++ /dev/null @@ -1,49 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { IEventEmitterFactory } from '../IEventEmitterFactory'; -import { RazorLogger } from '../razorLogger'; -import { CSharpPreviewPanel } from './csharpPreviewPanel'; -import { CSharpProjectedDocumentContentProvider } from './csharpProjectedDocumentContentProvider'; - -export class RazorCSharpFeature { - public readonly projectionProvider: CSharpProjectedDocumentContentProvider; - private readonly csharpPreviewPanel: CSharpPreviewPanel; - - constructor(documentManager: RazorDocumentManager, eventEmitterFactory: IEventEmitterFactory, logger: RazorLogger) { - this.projectionProvider = new CSharpProjectedDocumentContentProvider( - documentManager, - eventEmitterFactory, - logger - ); - this.csharpPreviewPanel = new CSharpPreviewPanel(documentManager); - } - - public register() { - const registrations = [ - vscode.workspace.registerTextDocumentContentProvider( - CSharpProjectedDocumentContentProvider.scheme, - this.projectionProvider - ), - vscode.commands.registerCommand('extension.showRazorCSharpWindow', async () => - this.csharpPreviewPanel.show() - ), - ]; - - if (vscode.window.registerWebviewPanelSerializer) { - registrations.push( - vscode.window.registerWebviewPanelSerializer(CSharpPreviewPanel.viewType, { - deserializeWebviewPanel: async (panel: vscode.WebviewPanel) => { - await this.csharpPreviewPanel.revive(panel); - }, - }) - ); - } - - return vscode.Disposable.from(...registrations); - } -} diff --git a/src/razor/src/definition/razorDefinitionProvider.ts b/src/razor/src/definition/razorDefinitionProvider.ts deleted file mode 100644 index 653a378365..0000000000 --- a/src/razor/src/definition/razorDefinitionProvider.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { getRazorDocumentUri, isRazorCSharpFile, isRazorHtmlFile } from '../razorConventions'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { LanguageKind } from '../rpc/languageKind'; -import { MappingHelpers } from '../mapping/mappingHelpers'; - -export class RazorDefinitionProvider extends RazorLanguageFeatureBase implements vscode.DefinitionProvider { - public async provideDefinition( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection || projection.languageKind === LanguageKind.Razor) { - return; - } - - const definitions = (await vscode.commands.executeCommand( - 'vscode.executeDefinitionProvider', - projection.uri, - projection.position - )) as vscode.Location[]; - - const result = new Array(); - for (const definition of definitions) { - if (projection.languageKind === LanguageKind.Html && isRazorHtmlFile(definition.uri)) { - // Because the line pragmas for html are generated referencing the projected document - // we need to remap their file locations to reference the top level Razor document. - const razorFile = getRazorDocumentUri(definition.uri); - result.push(new vscode.Location(razorFile, definition.range)); - } else if (isRazorCSharpFile(definition.uri)) { - const remappedLocation = await MappingHelpers.remapGeneratedFileLocation( - definition, - this.serviceClient, - this.logger, - token - ); - if (remappedLocation === undefined) { - continue; - } - - result.push(remappedLocation); - } else { - // This means it is one of the following, - // 1. A .cs file - // 2. A .html/.js file - // In both of these cases, we don't need to remap. So accept it as is and move on. - result.push(definition); - } - } - - return result; - } -} diff --git a/src/razor/src/diagnostics/razorDiagnosticHandler.ts b/src/razor/src/diagnostics/razorDiagnosticHandler.ts deleted file mode 100644 index ab3759873d..0000000000 --- a/src/razor/src/diagnostics/razorDiagnosticHandler.ts +++ /dev/null @@ -1,86 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { DocumentDiagnosticParams, DocumentDiagnosticReport, RequestType } from 'vscode-languageserver-protocol'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLogger } from '../razorLogger'; -import { roslynPullDiagnosticCommand } from '../../../lsptoolshost/razor/razorCommands'; -import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion'; - -export class RazorDiagnosticHandler extends RazorLanguageFeatureBase { - private static readonly razorPullDiagnosticsCommand = 'razor/csharpPullDiagnostics'; - private diagnosticRequestType: RequestType = - new RequestType(RazorDiagnosticHandler.razorPullDiagnosticsCommand); - - constructor( - protected readonly documentSynchronizer: RazorDocumentSynchronizer, - protected readonly serverClient: RazorLanguageServerClient, - protected readonly serviceClient: RazorLanguageServiceClient, - protected readonly documentManager: RazorDocumentManager, - protected readonly logger: RazorLogger - ) { - super(documentSynchronizer, documentManager, serviceClient, logger); - } - - public async register() { - await this.serverClient.onRequestWithParams< - DelegatedDiagnosticParams, - DocumentDiagnosticReport | undefined, - any - >(this.diagnosticRequestType, async (request: DelegatedDiagnosticParams, token: vscode.CancellationToken) => - this.getDiagnostic(request, token) - ); - } - - private async getDiagnostic( - request: DelegatedDiagnosticParams, - token: vscode.CancellationToken - ): Promise { - if (!this.documentManager.roslynActivated) { - return undefined; - } - - const razorDocumentUri = vscode.Uri.parse(request.identifier.textDocumentIdentifier.uri, true); - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - request.identifier.version, - token - ); - - if (!synchronized) { - return undefined; - } - - const virtualCSharpUri = razorDocument.csharpDocument.uri; - - const roslynRequest: DocumentDiagnosticParams = { - textDocument: { - uri: UriConverter.serialize(virtualCSharpUri), - }, - }; - - const response: DocumentDiagnosticReport = await vscode.commands.executeCommand( - roslynPullDiagnosticCommand, - roslynRequest - ); - - return response; - } -} - -interface DelegatedDiagnosticParams { - identifier: SerializableTextDocumentIdentifierAndVersion; - correlationId: string; -} diff --git a/src/razor/src/diagnostics/reportIssueCommand.ts b/src/razor/src/diagnostics/reportIssueCommand.ts index 1a8a0c61a7..11b96ce9dd 100644 --- a/src/razor/src/diagnostics/reportIssueCommand.ts +++ b/src/razor/src/diagnostics/reportIssueCommand.ts @@ -5,7 +5,6 @@ import { HtmlDocumentManager } from '../../../lsptoolshost/razor/htmlDocumentManager'; import { RoslynLanguageServer } from '../../../lsptoolshost/server/roslynLanguageServer'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; import { RazorLogger } from '../razorLogger'; import { api } from '../vscodeAdapter'; import * as vscode from '../vscodeAdapter'; @@ -20,18 +19,12 @@ export class ReportIssueCommand { constructor( private readonly vscodeApi: api, - documentManager: RazorDocumentManager | undefined, - cohostingDocumentManager: HtmlDocumentManager | undefined, - roslynLanguageServer: RoslynLanguageServer | undefined, + cohostingDocumentManager: HtmlDocumentManager, + roslynLanguageServer: RoslynLanguageServer, logger: RazorLogger ) { this.dataCollectorFactory = new ReportIssueDataCollectorFactory(logger); - this.issueCreator = new ReportIssueCreator( - this.vscodeApi, - documentManager, - cohostingDocumentManager, - roslynLanguageServer - ); + this.issueCreator = new ReportIssueCreator(this.vscodeApi, cohostingDocumentManager, roslynLanguageServer); this.issuePanel = new ReportIssuePanel(this.dataCollectorFactory, this.issueCreator, logger); } diff --git a/src/razor/src/diagnostics/reportIssueCreator.ts b/src/razor/src/diagnostics/reportIssueCreator.ts index 5a217c1e66..861acf4292 100644 --- a/src/razor/src/diagnostics/reportIssueCreator.ts +++ b/src/razor/src/diagnostics/reportIssueCreator.ts @@ -7,8 +7,6 @@ import * as cp from 'child_process'; import * as os from 'os'; import * as vscodeAdapter from '../vscodeAdapter'; import * as vscode from 'vscode'; -import { IRazorDocument } from '../document/IRazorDocument'; -import { IRazorDocumentManager } from '../document/IRazorDocumentManager'; import { razorExtensionId } from '../razorExtensionId'; import { IReportIssueDataCollectionResult } from './IReportIssueDataCollectionResult'; import { HtmlDocumentManager } from '../../../lsptoolshost/razor/htmlDocumentManager'; @@ -19,9 +17,8 @@ import { RoslynLanguageServer } from '../../../lsptoolshost/server/roslynLanguag export class ReportIssueCreator { constructor( private readonly vscodeApi: vscodeAdapter.api, - private readonly documentManager?: IRazorDocumentManager, - private readonly cohostingDocumentManager?: HtmlDocumentManager, - private readonly roslynLanguageServer?: RoslynLanguageServer + private readonly cohostingDocumentManager: HtmlDocumentManager, + private readonly roslynLanguageServer: RoslynLanguageServer ) {} public async create(collectionResult: IReportIssueDataCollectionResult) { @@ -36,25 +33,19 @@ export class ReportIssueCreator { if (collectionResult.document) { razorContent = await this.getRazor(collectionResult.document); - if (this.documentManager) { - const razorDocument = await this.documentManager.getDocument(collectionResult.document.uri); - csharpContent = await this.getProjectedCSharp(razorDocument); - htmlContent = await this.getProjectedHtml(razorDocument); - } else if (this.cohostingDocumentManager) { - try { - csharpContent = await ShowGeneratedDocumentCommand.getGeneratedDocumentContent( - collectionResult.document.uri, - GeneratedDocumentKind.CSharp, - this.roslynLanguageServer! - ); - } catch (e: any) { - csharpContent = vscode.l10n.t('Could not determine CSharp content: {0}', e.toString()); - } - - const htmlDocument = await this.cohostingDocumentManager.getDocument(collectionResult.document.uri); - if (htmlDocument) { - htmlContent = htmlDocument.getContent(); - } + try { + csharpContent = await ShowGeneratedDocumentCommand.getGeneratedDocumentContent( + collectionResult.document.uri, + GeneratedDocumentKind.CSharp, + this.roslynLanguageServer! + ); + } catch (e: any) { + csharpContent = vscode.l10n.t('Could not determine CSharp content: {0}', e.toString()); + } + + const htmlDocument = await this.cohostingDocumentManager.getDocument(collectionResult.document.uri); + if (htmlDocument) { + htmlContent = htmlDocument.getContent(); } } @@ -192,8 +183,7 @@ ${extensionTable} `; } - // Protected for testing - protected sanitize(content: string) { + private sanitize(content: string) { const user = process.env.USERNAME === undefined ? process.env.USER : process.env.USERNAME; if (user === undefined) { @@ -206,72 +196,13 @@ ${extensionTable} return sanitizedContent; } - // Protected for testing - protected async getRazor(document: vscodeAdapter.TextDocument) { + private async getRazor(document: vscodeAdapter.TextDocument) { const content = document.getText(); return content; } - // Protected for testing - protected async getProjectedCSharp(razorDocument: IRazorDocument) { - const projectedCSharpHeaderFooter = vscode.l10n.t('Projected CSharp as seen by extension'); - - let csharpContent = `////////////////////// ${projectedCSharpHeaderFooter} /////////////////////// -${razorDocument.csharpDocument.getContent()} - - -////////////////////// ${projectedCSharpHeaderFooter} ///////////////////////`; - - const errorSuffix = vscode.l10n.t("Unable to resolve VSCode's version of CSharp"); - try { - const csharpTextDocument = await this.vscodeApi.workspace.openTextDocument( - razorDocument.csharpDocument.uri - ); - if (csharpTextDocument) { - csharpContent = `${csharpContent} -${csharpTextDocument.getText()}`; - } else { - csharpContent = `${csharpContent} -${errorSuffix}`; - } - } catch (_) { - csharpContent = `${csharpContent} -${errorSuffix}`; - } - - return csharpContent; - } - - // Protected for testing - protected async getProjectedHtml(razorDocument: IRazorDocument) { - const projectedHTmlHeaderFooter = vscode.l10n.t('Projected Html as seen by extension'); - let htmlContent = `////////////////////// ${projectedHTmlHeaderFooter} /////////////////////// -${razorDocument.htmlDocument.getContent()} - - -////////////////////// ${projectedHTmlHeaderFooter} ///////////////////////`; - - const errorSuffix = vscode.l10n.t("Unable to resolve VSCode's version of Html"); - try { - const htmlTextDocument = await this.vscodeApi.workspace.openTextDocument(razorDocument.htmlDocument.uri); - if (htmlTextDocument) { - htmlContent = `${htmlContent} -${htmlTextDocument.getText()}`; - } else { - htmlContent = `${htmlContent} -${errorSuffix}`; - } - } catch (_) { - htmlContent = `${htmlContent} -${errorSuffix}`; - } - - return htmlContent; - } - - // Protected for testing - protected getExtensionVersion(): string { + private getExtensionVersion(): string { const extension = this.vscodeApi.extensions.getExtension(razorExtensionId); if (!extension) { return vscode.l10n.t('Unable to find Razor extension version.'); @@ -279,8 +210,7 @@ ${errorSuffix}`; return extension.packageJSON.version; } - // Protected for testing - protected getInstalledExtensions() { + private getInstalledExtensions() { const extensions: Array> = this.vscodeApi.extensions.all.filter( (extension) => extension.packageJSON.isBuiltin === false ); @@ -290,8 +220,7 @@ ${errorSuffix}`; ); } - // Protected for testing - protected generateExtensionTable() { + private generateExtensionTable() { const extensions = this.getInstalledExtensions(); if (extensions.length <= 0) { return 'none'; diff --git a/src/razor/src/document/IRazorDocument.ts b/src/razor/src/document/IRazorDocument.ts deleted file mode 100644 index 6fcd07a265..0000000000 --- a/src/razor/src/document/IRazorDocument.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { IProjectedDocument } from '../projection/IProjectedDocument'; - -export interface IRazorDocument { - readonly path: string; - readonly uri: vscode.Uri; - readonly csharpDocument: IProjectedDocument; - readonly htmlDocument: IProjectedDocument; - readonly isOpen: boolean; -} diff --git a/src/razor/src/document/IRazorDocumentChangeEvent.ts b/src/razor/src/document/IRazorDocumentChangeEvent.ts deleted file mode 100644 index 83ed53cbf7..0000000000 --- a/src/razor/src/document/IRazorDocumentChangeEvent.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServerTextChange } from '../rpc/serverTextChange'; -import { IRazorDocument } from './IRazorDocument'; -import { RazorDocumentChangeKind } from './razorDocumentChangeKind'; - -export interface IRazorDocumentChangeEvent { - readonly document: IRazorDocument; - readonly kind: RazorDocumentChangeKind; - readonly changes: ServerTextChange[]; -} diff --git a/src/razor/src/document/IRazorDocumentManager.ts b/src/razor/src/document/IRazorDocumentManager.ts deleted file mode 100644 index 4bdc673483..0000000000 --- a/src/razor/src/document/IRazorDocumentManager.ts +++ /dev/null @@ -1,17 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from '../vscodeAdapter'; -import { IRazorDocument } from './IRazorDocument'; -import { IRazorDocumentChangeEvent } from './IRazorDocumentChangeEvent'; - -export interface IRazorDocumentManager { - readonly onChange: vscode.Event; - readonly documents: IRazorDocument[]; - getDocument(uri: vscode.Uri): Promise; - getActiveDocument(): Promise; - initialize(): Promise; - register(): vscode.Disposable; -} diff --git a/src/razor/src/document/razorDocument.ts b/src/razor/src/document/razorDocument.ts deleted file mode 100644 index 1c42dce6a6..0000000000 --- a/src/razor/src/document/razorDocument.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { HtmlProjectedDocument } from '../html/htmlProjectedDocument'; -import { getUriPath } from '../uriPaths'; -import { IRazorDocument } from './IRazorDocument'; - -export class RazorDocument implements IRazorDocument { - public readonly path: string; - - constructor( - readonly uri: vscode.Uri, - readonly csharpDocument: CSharpProjectedDocument, - readonly htmlDocument: HtmlProjectedDocument - ) { - this.path = getUriPath(uri); - } - - public get isOpen(): boolean { - for (const textDocument of vscode.workspace.textDocuments) { - if (textDocument.uri.fsPath == this.uri.fsPath) { - return true; - } - } - - return false; - } -} diff --git a/src/razor/src/document/razorDocumentChangeKind.ts b/src/razor/src/document/razorDocumentChangeKind.ts deleted file mode 100644 index 3905ed2b02..0000000000 --- a/src/razor/src/document/razorDocumentChangeKind.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export enum RazorDocumentChangeKind { - added, - removed, - opened, - closed, - csharpChanged, - htmlChanged, -} diff --git a/src/razor/src/document/razorDocumentFactory.ts b/src/razor/src/document/razorDocumentFactory.ts deleted file mode 100644 index 1b3f2c5db7..0000000000 --- a/src/razor/src/document/razorDocumentFactory.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { CSharpProjectedDocumentContentProvider } from '../csharp/csharpProjectedDocumentContentProvider'; -import { HtmlProjectedDocument } from '../html/htmlProjectedDocument'; -import { HtmlProjectedDocumentContentProvider } from '../html/htmlProjectedDocumentContentProvider'; -import { virtualCSharpSuffix, virtualHtmlSuffix } from '../razorConventions'; -import { getUriPath } from '../uriPaths'; -import { IRazorDocument } from './IRazorDocument'; -import { RazorDocument } from './razorDocument'; - -export function createDocument(uri: vscode.Uri): IRazorDocument { - const csharpDocument = createProjectedCSharpDocument(uri); - const htmlDocument = createProjectedHtmlDocument(uri); - const document = new RazorDocument(uri, csharpDocument, htmlDocument); - - return document; -} - -function createProjectedHtmlDocument(hostDocumentUri: vscode.Uri) { - // Index.cshtml => Index.cshtml__virtual.html - const path = getUriPath(hostDocumentUri); - const projectedPath = `${path}${virtualHtmlSuffix}`; - let uri = vscode.Uri.file(projectedPath); - uri = uri.with({ scheme: HtmlProjectedDocumentContentProvider.scheme }); - const projectedDocument = new HtmlProjectedDocument(uri); - - return projectedDocument; -} - -function createProjectedCSharpDocument(hostDocumentUri: vscode.Uri) { - // Index.cshtml => Index.cshtml__virtual.cs - const path = getUriPath(hostDocumentUri); - const projectedPath = `${path}${virtualCSharpSuffix}`; - let uri = vscode.Uri.file(projectedPath); - uri = uri.with({ scheme: CSharpProjectedDocumentContentProvider.scheme }); - const projectedDocument = new CSharpProjectedDocument(uri); - - return projectedDocument; -} diff --git a/src/razor/src/document/razorDocumentManager.ts b/src/razor/src/document/razorDocumentManager.ts deleted file mode 100644 index 83639218a0..0000000000 --- a/src/razor/src/document/razorDocumentManager.ts +++ /dev/null @@ -1,358 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { HtmlProjectedDocument } from '../html/htmlProjectedDocument'; -import { RazorLanguage } from '../razorLanguage'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { TelemetryReporter } from '../telemetryReporter'; -import { UpdateBufferRequest } from '../rpc/updateBufferRequest'; -import { getUriPath } from '../uriPaths'; -import { IRazorDocument } from './IRazorDocument'; -import { IRazorDocumentChangeEvent } from './IRazorDocumentChangeEvent'; -import { IRazorDocumentManager } from './IRazorDocumentManager'; -import { RazorDocumentChangeKind } from './razorDocumentChangeKind'; -import { createDocument } from './razorDocumentFactory'; -import { razorInitializeCommand } from '../../../lsptoolshost/razor/razorCommands'; -import { PlatformInformation } from '../../../shared/platform'; -import { randomUUID } from 'crypto'; -import { ServerTextChange } from '../rpc/serverTextChange'; - -export class RazorDocumentManager implements IRazorDocumentManager { - public roslynActivated = false; - - private readonly razorDocuments: { [hostDocumentPath: string]: IRazorDocument } = {}; - private readonly openRazorDocuments = new Set(); - private readonly onChangeEmitter = new vscode.EventEmitter(); - private readonly onRazorInitializedEmitter = new vscode.EventEmitter(); - - public razorDocumentGenerationInitialized = false; - - constructor( - private readonly serverClient: RazorLanguageServerClient | undefined, - private readonly logger: RazorLogger, - private readonly telemetryReporter: TelemetryReporter, - private readonly platformInfo: PlatformInformation - ) {} - - public get onChange() { - return this.onChangeEmitter.event; - } - - public get onRazorInitialized() { - return this.onRazorInitializedEmitter.event; - } - - public get documents() { - return Object.values(this.razorDocuments); - } - - public async getDocument(uri: vscode.Uri): Promise { - const document = this._getDocument(uri); - return document; - } - - public async getDocumentForCSharpUri(csharpUri: vscode.Uri): Promise { - const csharpPath = csharpUri.fsPath ?? csharpUri.path; - - return this.documents.find((document) => { - if (this.platformInfo.isLinux()) { - return document.csharpDocument.path === csharpPath; - } - - return document.csharpDocument.path.localeCompare(csharpPath, undefined, { sensitivity: 'base' }) === 0; - }); - } - - public async getActiveDocument(): Promise { - if (!vscode.window.activeTextEditor) { - return null; - } - - if (vscode.window.activeTextEditor.document.languageId !== RazorLanguage.id) { - return null; - } - - const activeDocument = await this.getDocument(vscode.window.activeTextEditor.document.uri); - return activeDocument; - } - - // Returns true if a textDocument/didOpen notification has been sent - // to the C# workspace for a given document and if the document is - // currently open. - public isRazorDocumentOpenInCSharpWorkspace(razorUri: vscode.Uri) { - const path = getUriPath(razorUri); - return this.openRazorDocuments.has(path); - } - - // Indicates that a given document has been opened in the C# workspace. - public didOpenRazorCSharpDocument(razorUri: vscode.Uri) { - const path = getUriPath(razorUri); - this.openRazorDocuments.add(path); - } - - // Indicates that a given document has been closed in the C# workspace. - public didCloseRazorCSharpDocument(razorUri: vscode.Uri) { - const path = getUriPath(razorUri); - this.openRazorDocuments.delete(path); - } - - public async initialize() { - // Track current documents - const documentUris = await vscode.workspace.findFiles(RazorLanguage.globbingPattern); - - for (const uri of documentUris) { - this.addDocument(uri); - } - - for (const textDocument of vscode.workspace.textDocuments) { - if (textDocument.languageId !== RazorLanguage.id) { - continue; - } - - if (textDocument.isClosed) { - continue; - } - - await this.openDocument(textDocument.uri); - } - } - - public register() { - // Track future documents - const watcher = vscode.workspace.createFileSystemWatcher(RazorLanguage.globbingPattern); - const didCreateRegistration = watcher.onDidCreate(async (uri: vscode.Uri) => this.addDocument(uri)); - const didOpenRegistration = vscode.workspace.onDidOpenTextDocument(async (document) => { - if (document.languageId !== RazorLanguage.id) { - return; - } - - await this.openDocument(document.uri); - }); - const didCloseRegistration = vscode.workspace.onDidCloseTextDocument((document) => { - if (document.languageId !== RazorLanguage.id) { - return; - } - - this.closeDocument(document.uri); - }); - - if (this.serverClient !== undefined) { - this.serverClient.onNotification('razor/updateCSharpBuffer', async (updateBufferRequest) => - this.updateCSharpBuffer(updateBufferRequest) - ); - - this.serverClient.onNotification('razor/updateHtmlBuffer', async (updateBufferRequest) => - this.updateHtmlBuffer(updateBufferRequest) - ); - } - - return vscode.Disposable.from(watcher, didCreateRegistration, didOpenRegistration, didCloseRegistration); - } - - private _getDocument(uri: vscode.Uri): IRazorDocument { - const path = getUriPath(uri); - let document = this.findDocument(path); - - // This might happen in the case that a file is opened outside the workspace - if (!document) { - this.logger.logInfo( - `File '${path}' didn't exist in the Razor document list. This is likely because it's from outside the workspace.` - ); - document = this.addDocument(uri); - } - - return document!; - } - - private async openDocument(uri: vscode.Uri) { - await this.ensureRazorInitialized(); - - const document = this._getDocument(uri); - - this.notifyDocumentChange(document, RazorDocumentChangeKind.opened, []); - } - - public async ensureRazorInitialized() { - if (this.serverClient === undefined) { - return; - } - - // Kick off the generation of all Razor documents so that components are - // discovered correctly. We need to do this even if a Razor file isn't - // open yet to handle the scenario where the user opens a C# file before - // a Razor file. - if (this.roslynActivated && !this.razorDocumentGenerationInitialized) { - this.razorDocumentGenerationInitialized = true; - const pipeName = randomUUID(); - - await vscode.commands.executeCommand(razorInitializeCommand, pipeName); - await this.serverClient.connectNamedPipe(pipeName); - - this.onRazorInitializedEmitter.fire(); - } - } - - private closeDocument(uri: vscode.Uri) { - const document = this._getDocument(uri); - - // Documents that are files should be removed if they are outside the workspace folder - if (uri.scheme === 'file') { - // Files outside of the workspace will return undefined from getWorkspaceFolder - const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri); - if (!workspaceFolder) { - this.removeDocument(uri); - } - } - - this.notifyDocumentChange(document, RazorDocumentChangeKind.closed, []); - } - - private addDocument(uri: vscode.Uri): IRazorDocument { - const path = getUriPath(uri); - let document = this.findDocument(path); - if (document) { - this.logger.logInfo(`Skipping document creation for '${path}' because it already exists.`); - return document; - } - - document = createDocument(uri); - this.razorDocuments[document.path] = document; - - this.notifyDocumentChange(document, RazorDocumentChangeKind.added, []); - - return document; - } - - private removeDocument(uri: vscode.Uri) { - const document = this._getDocument(uri); - delete this.razorDocuments[document.path]; - - this.notifyDocumentChange(document, RazorDocumentChangeKind.removed, []); - } - - private findDocument(path: string) { - // This method ultimately gets called from VS Code, using file system paths, or from DevKit, which - // can use paths as specified in the sln file. When these don't agree, on case-insensitive operating - // systems, we have to be careful to match things up correctly. - - if (this.platformInfo.isLinux()) { - return this.razorDocuments[path]; - } - - return Object.values(this.razorDocuments).find( - (document) => document.path.localeCompare(path, undefined, { sensitivity: 'base' }) === 0 - ); - } - - private async updateCSharpBuffer(updateBufferRequest: UpdateBufferRequest) { - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Updating the C# document for Razor file '${updateBufferRequest.hostDocumentFilePath}' ` + - `(${updateBufferRequest.hostDocumentVersion})` - ); - } - - const hostDocumentUri = vscode.Uri.file(updateBufferRequest.hostDocumentFilePath); - const document = this._getDocument(hostDocumentUri); - const projectedDocument = document.csharpDocument; - - if ( - updateBufferRequest.previousWasEmpty || - !projectedDocument.hostDocumentSyncVersion || - projectedDocument.hostDocumentSyncVersion <= updateBufferRequest.hostDocumentVersion - ) { - // We allow re-setting of the updated content from the same doc sync version in the case - // of project or file import changes. - const csharpProjectedDocument = projectedDocument as CSharpProjectedDocument; - - // If the language server is telling us that the previous document was empty, then we should clear - // ours out. Hopefully ours would have been empty too, but there are cases where things get out of - // sync - if (updateBufferRequest.previousWasEmpty && projectedDocument.length !== 0) { - this.telemetryReporter.reportBuffersOutOfSync(); - csharpProjectedDocument.clear(); - } - - csharpProjectedDocument.update( - document.isOpen, - updateBufferRequest.changes, - updateBufferRequest.hostDocumentVersion, - updateBufferRequest.checksum, - updateBufferRequest.checksumAlgorithm, - updateBufferRequest.encodingCodePage - ); - - this.notifyDocumentChange(document, RazorDocumentChangeKind.csharpChanged, updateBufferRequest.changes); - } else { - this.logger.logWarning( - 'Failed to update the C# document buffer. This is unexpected and may result in incorrect C# interactions.' - ); - } - } - - private async updateHtmlBuffer(updateBufferRequest: UpdateBufferRequest) { - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Updating the HTML document for Razor file '${updateBufferRequest.hostDocumentFilePath}' ` + - `(${updateBufferRequest.hostDocumentVersion})` - ); - } - - const hostDocumentUri = vscode.Uri.file(updateBufferRequest.hostDocumentFilePath); - const document = this._getDocument(hostDocumentUri); - const projectedDocument = document.htmlDocument; - - if ( - updateBufferRequest.previousWasEmpty || - !projectedDocument.hostDocumentSyncVersion || - projectedDocument.hostDocumentSyncVersion <= updateBufferRequest.hostDocumentVersion - ) { - // We allow re-setting of the updated content from the same doc sync version in the case - // of project or file import changes. - - // Make sure the document is open, because updating will cause a didChange event to fire. - await vscode.workspace.openTextDocument(document.htmlDocument.uri); - - const htmlProjectedDocument = projectedDocument as HtmlProjectedDocument; - - // If the language server is telling us that the previous document was empty, then we should clear - // ours out. Hopefully ours would have been empty too, but there are cases where things get out of - // sync - if (updateBufferRequest.previousWasEmpty && projectedDocument.length !== 0) { - this.telemetryReporter.reportBuffersOutOfSync(); - htmlProjectedDocument.clear(); - } - - htmlProjectedDocument.update(updateBufferRequest.changes, updateBufferRequest.hostDocumentVersion); - - this.notifyDocumentChange(document, RazorDocumentChangeKind.htmlChanged, updateBufferRequest.changes); - } else { - this.logger.logWarning( - 'Failed to update the HTML document buffer. This is unexpected and may result in incorrect HTML interactions.' - ); - } - } - - private notifyDocumentChange(document: IRazorDocument, kind: RazorDocumentChangeKind, changes: ServerTextChange[]) { - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Notifying document '${getUriPath(document.uri)}' changed '${RazorDocumentChangeKind[kind]}' with '${ - changes.length - }' changes.` - ); - } - - const args: IRazorDocumentChangeEvent = { - document, - kind, - changes, - }; - - this.onChangeEmitter.fire(args); - } -} diff --git a/src/razor/src/document/razorDocumentSynchronizer.ts b/src/razor/src/document/razorDocumentSynchronizer.ts deleted file mode 100644 index 34d6eaa600..0000000000 --- a/src/razor/src/document/razorDocumentSynchronizer.ts +++ /dev/null @@ -1,266 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { CSharpProjectedDocumentContentProvider } from '../csharp/csharpProjectedDocumentContentProvider'; -import { HtmlProjectedDocumentContentProvider } from '../html/htmlProjectedDocumentContentProvider'; -import { IProjectedDocument } from '../projection/IProjectedDocument'; -import { RazorLogger } from '../razorLogger'; -import { getUriPath } from '../uriPaths'; -import { IRazorDocumentChangeEvent } from './IRazorDocumentChangeEvent'; -import { RazorDocumentChangeKind } from './razorDocumentChangeKind'; -import { RazorDocumentManager } from './razorDocumentManager'; - -export class RazorDocumentSynchronizer { - private readonly synchronizations: { [uri: string]: SynchronizationContext[] } = {}; - private synchronizationIdentifier = 0; - - constructor(private readonly documentManager: RazorDocumentManager, private readonly logger: RazorLogger) {} - - public register() { - const documentManagerRegistration = this.documentManager.onChange((event) => this.documentChanged(event)); - const textDocumentChangeRegistration = vscode.workspace.onDidChangeTextDocument((event) => - this.textDocumentChanged(event) - ); - - return vscode.Disposable.from(documentManagerRegistration, textDocumentChangeRegistration); - } - - public async trySynchronizeProjectedDocument( - hostDocument: vscode.TextDocument, - projectedDocument: IProjectedDocument, - expectedHostDocumentVersion: number, - token: vscode.CancellationToken - ) { - const logId = ++this.synchronizationIdentifier; - - const documentKey = getUriPath(projectedDocument.uri); - if (this.logger.traceEnabled) { - const ehdv = expectedHostDocumentVersion; - this.logger.logTrace( - `${logId} - Synchronizing '${documentKey}': - Currently at ${projectedDocument.hostDocumentSyncVersion}, synchronizing to version '${ehdv}'.'` - ); - } - - const context: SynchronizationContext = this.createSynchronizationContext( - documentKey, - projectedDocument, - expectedHostDocumentVersion, - hostDocument, - token - ); - - try { - if (projectedDocument.hostDocumentSyncVersion !== expectedHostDocumentVersion) { - if (this.logger.traceEnabled) { - this.logger.logTrace( - `${logId} - Projected document not in sync with host document, waiting for update... - Current host document sync version: ${projectedDocument.hostDocumentSyncVersion}` - ); - } - await context.onProjectedDocumentSynchronized; - } - - if (this.logger.traceEnabled) { - this.logger.logTrace(`${logId} - Projected document in sync with host document`); - } - - // Projected document is the one we expect. - - const projectedTextDocument = await vscode.workspace.openTextDocument(projectedDocument.uri); - const projectedTextDocumentVersion = this.getProjectedTextDocumentVersion(projectedTextDocument); - if (projectedDocument.hostDocumentSyncVersion !== projectedTextDocumentVersion) { - if (this.logger.traceEnabled) { - this.logger.logTrace( - `${logId} - Projected text document not in sync with data type, waiting for update... - Current projected text document sync version: ${projectedTextDocumentVersion}` - ); - } - await context.onProjectedTextDocumentSynchronized; - } - - if (this.logger.traceEnabled) { - this.logger.logTrace(`${logId} - Projected text document in sync with data type`); - } - - // Projected text document is the one we expect - } catch (cancellationReason) { - this.removeSynchronization(context); - - if (this.logger.traceEnabled) { - this.logger.logTrace(`${logId} - Synchronization failed: ${cancellationReason}`); - } - - return false; - } - - this.removeSynchronization(context); - - if (this.logger.traceEnabled) { - this.logger.logTrace(`${logId} - Synchronization successful!`); - } - - return true; - } - - private removeSynchronization(context: SynchronizationContext) { - context.dispose(); - - const documentKey = getUriPath(context.projectedDocument.uri); - const synchronizations = this.synchronizations[documentKey]; - - if (synchronizations.length === 1) { - delete this.synchronizations[documentKey]; - return; - } - - this.synchronizations[documentKey] = synchronizations.filter((item) => item !== context); - } - - private createSynchronizationContext( - documentKey: string, - projectedDocument: IProjectedDocument, - toHostDocumentVersion: number, - hostDocument: vscode.TextDocument, - token: vscode.CancellationToken - ) { - const rejectionsForCancel: Array<(reason: string) => void> = []; - let projectedDocumentSynchronized: () => void = Function; - const onProjectedDocumentSynchronized = new Promise((resolve, reject) => { - projectedDocumentSynchronized = resolve; - rejectionsForCancel.push(reject); - }); - let projectedTextDocumentSynchronized: () => void = Function; - const onProjectedTextDocumentSynchronized = new Promise((resolve, reject) => { - projectedTextDocumentSynchronized = resolve; - rejectionsForCancel.push(reject); - }); - - token.onCancellationRequested((reason) => { - context.cancel(vscode.l10n.t('Token cancellation requested: {0}', reason)); - }); - const timeoutId = setTimeout(() => { - context.cancel(vscode.l10n.t('Synchronization timed out')); - }, 2000); - const context: SynchronizationContext = { - projectedDocument, - logIdentifier: this.synchronizationIdentifier, - timeoutId, - toHostDocumentVersion, - cancel: (reason) => { - for (const reject of rejectionsForCancel) { - reject(reason); - } - }, - dispose: () => { - rejectionsForCancel.length = 0; - clearTimeout(context.timeoutId); - }, - projectedDocumentSynchronized, - onProjectedDocumentSynchronized, - projectedTextDocumentSynchronized, - onProjectedTextDocumentSynchronized, - }; - - let synchronizations = this.synchronizations[documentKey]; - if (!synchronizations) { - synchronizations = []; - this.synchronizations[documentKey] = synchronizations; - } - - synchronizations.push(context); - - return context; - } - - private textDocumentChanged(event: vscode.TextDocumentChangeEvent) { - if ( - event.document.uri.scheme !== CSharpProjectedDocumentContentProvider.scheme && - event.document.uri.scheme !== HtmlProjectedDocumentContentProvider.scheme - ) { - return; - } - - const projectedTextDocumentVersion = this.getProjectedTextDocumentVersion(event.document); - if (projectedTextDocumentVersion === null) { - return; - } - - const documentKey = getUriPath(event.document.uri); - const synchronizationContexts = this.synchronizations[documentKey]; - - if (!synchronizationContexts) { - return; - } - - for (const context of synchronizationContexts) { - if (context.projectedDocument.hostDocumentSyncVersion === projectedTextDocumentVersion) { - if (this.logger.traceEnabled) { - const li = context.logIdentifier; - const ptdv = projectedTextDocumentVersion; - this.logger.logTrace(`${li} - Projected text document synchronized to ${ptdv}.`); - } - context.projectedTextDocumentSynchronized(); - } - } - } - - private documentChanged(event: IRazorDocumentChangeEvent) { - let projectedDocument: IProjectedDocument; - if (event.kind === RazorDocumentChangeKind.csharpChanged) { - projectedDocument = event.document.csharpDocument; - } else if (event.kind === RazorDocumentChangeKind.htmlChanged) { - projectedDocument = event.document.htmlDocument; - } else { - return; - } - - const hostDocumentSyncVersion = projectedDocument.hostDocumentSyncVersion; - if (hostDocumentSyncVersion === null) { - return; - } - - const documentKey = getUriPath(projectedDocument.uri); - const synchronizationContexts = this.synchronizations[documentKey]; - if (!synchronizationContexts) { - return; - } - - for (const context of synchronizationContexts) { - if (context.toHostDocumentVersion === projectedDocument.hostDocumentSyncVersion) { - context.projectedDocumentSynchronized(); - } - } - } - - private getProjectedTextDocumentVersion(textDocument: vscode.TextDocument) { - // Logic defined in this method is heavily dependent on the functionality in the projected - // document content providers to append versions to the end of text documents. - - if (textDocument.lineCount <= 0) { - return null; - } - - const lastLine = textDocument.lineAt(textDocument.lineCount - 1); - const versionString = lastLine.text.substring(3 /* //_ */); - const textDocumentProjectedVersion = parseInt(versionString, 10); - - return textDocumentProjectedVersion; - } -} - -interface SynchronizationContext { - readonly projectedDocument: IProjectedDocument; - readonly logIdentifier: number; - readonly toHostDocumentVersion: number; - readonly timeoutId: NodeJS.Timeout; - readonly projectedDocumentSynchronized: () => void; - readonly onProjectedDocumentSynchronized: Promise; - readonly projectedTextDocumentSynchronized: () => void; - readonly onProjectedTextDocumentSynchronized: Promise; - readonly cancel: (reason: string) => void; - readonly dispose: () => void; -} diff --git a/src/razor/src/documentColor/documentColorHandler.ts b/src/razor/src/documentColor/documentColorHandler.ts index 0c7398b840..9a451ea98f 100644 --- a/src/razor/src/documentColor/documentColorHandler.ts +++ b/src/razor/src/documentColor/documentColorHandler.ts @@ -4,76 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { RequestType } from 'vscode-jsonrpc'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; import { convertRangeToSerializable } from '../rpc/serializableRange'; import { SerializableColorInformation } from './serializableColorInformation'; -import { SerializableDocumentColorParams } from './serializableDocumentColorParams'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; export class DocumentColorHandler { - private static readonly provideHtmlDocumentColorEndpoint = 'razor/provideHtmlDocumentColor'; - private documentColorRequestType: RequestType< - SerializableDocumentColorParams, - SerializableColorInformation[], - any - > = new RequestType(DocumentColorHandler.provideHtmlDocumentColorEndpoint); - private emptyColorInformationResponse: SerializableColorInformation[] = []; - - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly serverClient: RazorLanguageServerClient, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams< - SerializableDocumentColorParams, - SerializableColorInformation[], - any - >( - this.documentColorRequestType, - async (request: SerializableDocumentColorParams, token: vscode.CancellationToken) => - this.provideHtmlDocumentColors(request, token) - ); - } - - private async provideHtmlDocumentColors( - documentColorParams: SerializableDocumentColorParams, - cancellationToken: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse(documentColorParams.textDocument.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - this.logger.logWarning( - `Could not find Razor document ${razorDocumentUri}; returning empty color information.` - ); - return this.emptyColorInformationResponse; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.htmlDocument, - documentColorParams._razor_hostDocumentVersion, - cancellationToken - ); - if (!synchronized) { - return this.emptyColorInformationResponse; - } - - const virtualHtmlUri = razorDocument.htmlDocument.uri; - return await DocumentColorHandler.doDocumentColorRequest(virtualHtmlUri); - } catch (error) { - this.logger.logWarning(`${DocumentColorHandler.provideHtmlDocumentColorEndpoint} failed with ${error}`); - } - - return this.emptyColorInformationResponse; - } + constructor() {} public static async doDocumentColorRequest(virtualHtmlUri: vscode.Uri) { const colorInformation = await vscode.commands.executeCommand( diff --git a/src/razor/src/documentColor/serializableDocumentColorParams.ts b/src/razor/src/documentColor/serializableDocumentColorParams.ts deleted file mode 100644 index 7e4de54b81..0000000000 --- a/src/razor/src/documentColor/serializableDocumentColorParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableDocumentColorParams { - textDocument: SerializableTextDocumentIdentifier; - _razor_hostDocumentVersion: number; -} diff --git a/src/razor/src/documentHighlight/razorDocumentHighlightProvider.ts b/src/razor/src/documentHighlight/razorDocumentHighlightProvider.ts deleted file mode 100644 index 8507979f81..0000000000 --- a/src/razor/src/documentHighlight/razorDocumentHighlightProvider.ts +++ /dev/null @@ -1,60 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { LanguageKind } from '../rpc/languageKind'; - -export class RazorDocumentHighlightProvider - extends RazorLanguageFeatureBase - implements vscode.DocumentHighlightProvider -{ - public async provideDocumentHighlights( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection || projection.languageKind === LanguageKind.Razor) { - return; - } - - const highlights = await vscode.commands.executeCommand( - 'vscode.executeDocumentHighlights', - projection.uri, - projection.position - ); - - if (!highlights || highlights.length === 0) { - return; - } - - const remappedHighlights = new Array(); - - // Re-map the projected document ranges to host document ranges - for (const highlight of highlights) { - const remappedResponse = await this.serviceClient.mapToDocumentRanges( - projection.languageKind, - [highlight.range], - document.uri - ); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // Couldn't remap the projected highlight location. - continue; - } - - if (projection.hostDocumentVersion !== remappedResponse.hostDocumentVersion) { - // This highlight result is for a different version of the text document, bail. - continue; - } - - const remappedHighlight = new vscode.DocumentHighlight(remappedResponse.ranges[0], highlight.kind); - remappedHighlights.push(remappedHighlight); - } - - return remappedHighlights; - } -} diff --git a/src/razor/src/documentTelemetryListener.ts b/src/razor/src/documentTelemetryListener.ts deleted file mode 100644 index 3d5db977d7..0000000000 --- a/src/razor/src/documentTelemetryListener.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { RazorDocumentChangeKind } from './document/razorDocumentChangeKind'; -import { RazorDocumentManager } from './document/razorDocumentManager'; -import { TelemetryReporter } from './telemetryReporter'; - -export function reportTelemetryForDocuments( - documentManager: RazorDocumentManager, - telemetryReporter: TelemetryReporter -) { - documentManager.onChange((event) => { - switch (event.kind) { - case RazorDocumentChangeKind.added: - telemetryReporter.reportWorkspaceContainsRazor(); - break; - } - }); -} diff --git a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts deleted file mode 100644 index fc34e9a9e4..0000000000 --- a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts +++ /dev/null @@ -1,116 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLogger } from '../razorLogger'; -import { ProvideDynamicFileParams } from './provideDynamicFileParams'; -import { ProvideDynamicFileResponse } from './provideDynamicFileResponse'; -import { RemoveDynamicFileParams } from './removeDynamicFileParams'; -import { CSharpProjectedDocument } from '../csharp/csharpProjectedDocument'; -import { razorTextChange } from './razorTextChange'; -import { razorTextSpan } from './razorTextSpan'; - -// Handles Razor generated doc communication between the Roslyn workspace and Razor. -// didChange behavior for Razor generated docs is handled in the RazorDocumentManager. -export class DynamicFileInfoHandler { - public static readonly provideDynamicFileInfoCommand = 'razor.provideDynamicFileInfo'; - public static readonly removeDynamicFileInfoCommand = 'razor.removeDynamicFileInfo'; - public static readonly dynamicFileUpdatedCommand = 'razor.dynamicFileUpdated'; - - constructor(private readonly documentManager: RazorDocumentManager, private readonly logger: RazorLogger) {} - - public register() { - vscode.commands.registerCommand( - DynamicFileInfoHandler.provideDynamicFileInfoCommand, - async (request: ProvideDynamicFileParams) => { - return this.provideDynamicFileInfo(request); - } - ); - vscode.commands.registerCommand( - DynamicFileInfoHandler.removeDynamicFileInfoCommand, - async (request: RemoveDynamicFileParams) => { - await this.removeDynamicFileInfo(request); - } - ); - } - - // Given Razor document URIs, returns associated generated doc URIs - private async provideDynamicFileInfo( - request: ProvideDynamicFileParams - ): Promise { - this.documentManager.roslynActivated = true; - const vscodeUri = vscode.Uri.parse(request.razorDocument.uri, true); - - // Normally we start receiving dynamic info after Razor is initialized, but if the user had a .razor file open - // when they started VS Code, the order is the other way around. This no-ops if Razor is already initialized. - await this.documentManager.ensureRazorInitialized(); - - const razorDocument = await this.documentManager.getDocument(vscodeUri); - try { - if (razorDocument === undefined) { - this.logger.logWarning( - `Could not find Razor document ${vscodeUri.fsPath}; adding null as a placeholder in URI array.` - ); - - return null; - } - - const csharpDocument = razorDocument.csharpDocument as CSharpProjectedDocument; - if (request.fullText) { - // The server asked for a full replace so the newtext is the important - // thing here, the span doesn't matter. - const change = new razorTextChange(razorDocument.csharpDocument.getContent(), new razorTextSpan(0, 0)); - - return new ProvideDynamicFileResponse( - request.razorDocument, - [change], - csharpDocument.checksum, - csharpDocument.checksumAlgorithm, - csharpDocument.encodingCodePage - ); - } - - const virtualCsharpUri = UriConverter.serialize(razorDocument.csharpDocument.uri); - - if (this.documentManager.isRazorDocumentOpenInCSharpWorkspace(vscodeUri)) { - // Open documents have didOpen/didChange to update the csharp buffer. Razor - // does not send edits and instead lets vscode handle them. - return null; - } else { - // Closed documents provide edits since the last time they were requested since - // there is no open buffer in vscode corresponding to the csharp content. - const response = csharpDocument.applyEdits(); - const updates = response.edits?.flatMap((e) => - e.changes.map((c) => new razorTextChange(c.newText, new razorTextSpan(c.span.start, c.span.length))) - ); - - return new ProvideDynamicFileResponse( - { uri: virtualCsharpUri }, - updates ?? [], - response.originalChecksum, - response.originalChecksumAlgorithm, - response.originalEncodingCodePage - ); - } - } catch (error) { - this.logger.logWarning(`${DynamicFileInfoHandler.provideDynamicFileInfoCommand} failed with ${error}`); - } - - return null; - } - - private async removeDynamicFileInfo(request: RemoveDynamicFileParams) { - try { - const vscodeUri = UriConverter.deserialize(request.csharpDocument.uri); - if (this.documentManager.isRazorDocumentOpenInCSharpWorkspace(vscodeUri)) { - this.documentManager.didCloseRazorCSharpDocument(vscodeUri); - } - } catch (error) { - this.logger.logWarning(`${DynamicFileInfoHandler.removeDynamicFileInfoCommand} failed with ${error}`); - } - } -} diff --git a/src/razor/src/dynamicFile/dynamicFileUpdatedParams.ts b/src/razor/src/dynamicFile/dynamicFileUpdatedParams.ts deleted file mode 100644 index 3a5f4c3972..0000000000 --- a/src/razor/src/dynamicFile/dynamicFileUpdatedParams.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -export class RazorDynamicFileChangedParams { - constructor(public readonly razorDocument: TextDocumentIdentifier) {} -} diff --git a/src/razor/src/dynamicFile/provideDynamicFileParams.ts b/src/razor/src/dynamicFile/provideDynamicFileParams.ts deleted file mode 100644 index 1993f45e54..0000000000 --- a/src/razor/src/dynamicFile/provideDynamicFileParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -// matches https://github.com/dotnet/roslyn/blob/9e91ca6590450e66e0041ee3135bbf044ac0687a/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/RazorDynamicFileInfoProvider.cs#L22 -export class ProvideDynamicFileParams { - constructor(public readonly razorDocument: TextDocumentIdentifier, public readonly fullText: boolean) {} -} diff --git a/src/razor/src/dynamicFile/provideDynamicFileResponse.ts b/src/razor/src/dynamicFile/provideDynamicFileResponse.ts deleted file mode 100644 index 5be2be149e..0000000000 --- a/src/razor/src/dynamicFile/provideDynamicFileResponse.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; -import { ServerTextChange } from '../rpc/serverTextChange'; -import { razorTextChange } from './razorTextChange'; - -// matches https://github.com/dotnet/roslyn/blob/9e91ca6590450e66e0041ee3135bbf044ac0687a/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/RazorDynamicFileInfoProvider.cs#L28 -export class ProvideDynamicFileResponse { - constructor( - public readonly csharpDocument: TextDocumentIdentifier | null, - public readonly edits: razorTextChange[], - public readonly checksum: string, - public readonly checksumAlgorithm: number, - public readonly encodingCodePage: number | null - ) {} -} - -export class DynamicFileUpdate { - constructor(public readonly edits: ServerTextChange[]) {} -} diff --git a/src/razor/src/dynamicFile/razorTextChange.ts b/src/razor/src/dynamicFile/razorTextChange.ts deleted file mode 100644 index 491f3c4ab6..0000000000 --- a/src/razor/src/dynamicFile/razorTextChange.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { razorTextSpan } from './razorTextSpan'; - -export class razorTextChange { - constructor(public readonly newText: string | null, public readonly span: razorTextSpan) {} -} diff --git a/src/razor/src/dynamicFile/razorTextSpan.ts b/src/razor/src/dynamicFile/razorTextSpan.ts deleted file mode 100644 index 1e299b5296..0000000000 --- a/src/razor/src/dynamicFile/razorTextSpan.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export class razorTextSpan { - constructor(public readonly start: number, public readonly length: number) {} -} diff --git a/src/razor/src/dynamicFile/removeDynamicFileParams.ts b/src/razor/src/dynamicFile/removeDynamicFileParams.ts deleted file mode 100644 index 6b1c1cd10b..0000000000 --- a/src/razor/src/dynamicFile/removeDynamicFileParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -// matches https://github.com/dotnet/roslyn/blob/9e91ca6590450e66e0041ee3135bbf044ac0687a/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/RazorDynamicFileInfoProvider.cs#L28 -export class RemoveDynamicFileParams { - constructor(public readonly csharpDocument: TextDocumentIdentifier) {} -} diff --git a/src/razor/src/folding/foldingRangeHandler.ts b/src/razor/src/folding/foldingRangeHandler.ts index 2dd1f30177..ccd98af65a 100644 --- a/src/razor/src/folding/foldingRangeHandler.ts +++ b/src/razor/src/folding/foldingRangeHandler.ts @@ -4,82 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { FoldingRange, FoldingRangeKind, RequestType } from 'vscode-languageserver-protocol'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; +import { FoldingRange, FoldingRangeKind } from 'vscode-languageserver-protocol'; import { RazorLogger } from '../razorLogger'; -import { SerializableFoldingRangeParams } from './serializableFoldingRangeParams'; -import { SerializableFoldingRangeResponse } from './serializableFoldingRangeResponse'; export class FoldingRangeHandler { - private static readonly provideFoldingRange = 'razor/foldingRange'; - private foldingRangeRequestType: RequestType< - SerializableFoldingRangeParams, - SerializableFoldingRangeResponse, - any - > = new RequestType(FoldingRangeHandler.provideFoldingRange); - private emptyFoldingRangeReponse: SerializableFoldingRangeResponse = new SerializableFoldingRangeResponse( - new Array(), - new Array() - ); - - constructor( - private readonly serverClient: RazorLanguageServerClient, - private readonly documentManager: RazorDocumentManager, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams< - SerializableFoldingRangeParams, - SerializableFoldingRangeResponse, - any - >(this.foldingRangeRequestType, async (request, token) => this.provideFoldingRanges(request, token)); - } - - private async provideFoldingRanges( - foldingRangeParams: SerializableFoldingRangeParams, - _: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse(foldingRangeParams.textDocument.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return this.emptyFoldingRangeReponse; - } - - const virtualHtmlUri = razorDocument.htmlDocument.uri; - const virtualCSharpUri = razorDocument.csharpDocument.uri; - - const htmlFoldingRanges = await vscode.commands.executeCommand( - 'vscode.executeFoldingRangeProvider', - virtualHtmlUri - ); - const csharpFoldingRanges = await vscode.commands.executeCommand( - 'vscode.executeFoldingRangeProvider', - virtualCSharpUri - ); - - const convertedHtmlFoldingRanges = - htmlFoldingRanges === undefined - ? new Array() - : FoldingRangeHandler.convertFoldingRanges(htmlFoldingRanges, this.logger); - const convertedCSharpFoldingRanges = - csharpFoldingRanges === undefined - ? new Array() - : FoldingRangeHandler.convertFoldingRanges(csharpFoldingRanges, this.logger); - - const response = new SerializableFoldingRangeResponse( - convertedHtmlFoldingRanges, - convertedCSharpFoldingRanges - ); - return response; - } catch (error) { - this.logger.logWarning(`${FoldingRangeHandler.provideFoldingRange} failed with ${error}`); - } - - return this.emptyFoldingRangeReponse; - } + constructor() {} public static convertFoldingRanges(foldingRanges: vscode.FoldingRange[], logger: RazorLogger) { const convertedFoldingRanges = new Array(); diff --git a/src/razor/src/folding/serializableFoldingRangeParams.ts b/src/razor/src/folding/serializableFoldingRangeParams.ts deleted file mode 100644 index cf5ed1f7b5..0000000000 --- a/src/razor/src/folding/serializableFoldingRangeParams.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { integer } from 'vscode-languageserver-types'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableFoldingRangeParams { - hostDocumentVersion: integer; - textDocument: SerializableTextDocumentIdentifier; -} diff --git a/src/razor/src/folding/serializableFoldingRangeResponse.ts b/src/razor/src/folding/serializableFoldingRangeResponse.ts deleted file mode 100644 index c04f5a3242..0000000000 --- a/src/razor/src/folding/serializableFoldingRangeResponse.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { FoldingRange } from 'vscode-languageserver-protocol'; - -export class SerializableFoldingRangeResponse { - constructor(public htmlRanges: FoldingRange[], public csharpRanges: FoldingRange[]) {} -} diff --git a/src/razor/src/formatNewFile/razorFormatNewFileHandler.ts b/src/razor/src/formatNewFile/razorFormatNewFileHandler.ts deleted file mode 100644 index cbe335cb75..0000000000 --- a/src/razor/src/formatNewFile/razorFormatNewFileHandler.ts +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RequestType } from 'vscode-jsonrpc'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLogger } from '../razorLogger'; -import { SerializableFormatNewFileParams } from './serializableFormatNewFileParams'; -import { roslynFormatNewFileCommand } from '../../../lsptoolshost/razor/razorCommands'; - -export class RazorFormatNewFileHandler extends RazorLanguageFeatureBase { - private static readonly razorFormatNewFileCommand = 'razor/formatNewFile'; - private formatNewFileRequestType: RequestType = - new RequestType(RazorFormatNewFileHandler.razorFormatNewFileCommand); - - constructor( - documentSynchronizer: RazorDocumentSynchronizer, - protected readonly serverClient: RazorLanguageServerClient, - protected readonly serviceClient: RazorLanguageServiceClient, - protected readonly documentManager: RazorDocumentManager, - protected readonly logger: RazorLogger - ) { - super(documentSynchronizer, documentManager, serviceClient, logger); - } - - public async register() { - await this.serverClient.onRequestWithParams( - this.formatNewFileRequestType, - async (request: SerializableFormatNewFileParams, token: vscode.CancellationToken) => - this.getFormatNewFile(request, token) - ); - } - - private async getFormatNewFile( - request: SerializableFormatNewFileParams, - _: vscode.CancellationToken - ): Promise { - if (!this.documentManager.roslynActivated) { - return undefined; - } - - const response: string | undefined = await vscode.commands.executeCommand(roslynFormatNewFileCommand, request); - - return response; - } -} diff --git a/src/razor/src/formatNewFile/serializableFormatNewFileParams.ts b/src/razor/src/formatNewFile/serializableFormatNewFileParams.ts deleted file mode 100644 index 26227a24f2..0000000000 --- a/src/razor/src/formatNewFile/serializableFormatNewFileParams.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableFormatNewFileParams { - project: SerializableTextDocumentIdentifier; - document: SerializableTextDocumentIdentifier; - contents: string; -} diff --git a/src/razor/src/formatting/formattingHandler.ts b/src/razor/src/formatting/formattingHandler.ts index a7db772d2e..15fcc05be6 100644 --- a/src/razor/src/formatting/formattingHandler.ts +++ b/src/razor/src/formatting/formattingHandler.ts @@ -4,84 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { RequestType } from 'vscode-jsonrpc'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; import { convertTextEditToSerializable, SerializableTextEdit } from '../rpc/serializableTextEdit'; -import { SerializableFormattingParams } from './serializableFormattingParams'; import { SerializableFormattingResponse } from './serializableFormattingResponse'; -import { SerializableOnTypeFormattingParams } from './serializableOnTypeFormattingParams'; import { SerializablePosition } from '../rpc/serializablePosition'; export class FormattingHandler { - private static readonly provideFormattingEndpoint = 'razor/htmlFormatting'; - private static readonly provideOnTypeFormattingEndpoint = 'razor/htmlOnTypeFormatting'; - private formattingRequestType: RequestType = - new RequestType(FormattingHandler.provideFormattingEndpoint); - private onTypeFormattingRequestType: RequestType< - SerializableOnTypeFormattingParams, - SerializableFormattingResponse, - any - > = new RequestType(FormattingHandler.provideOnTypeFormattingEndpoint); private static emptyFormattingResponse = new SerializableFormattingResponse(); - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly serverClient: RazorLanguageServerClient, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams( - this.formattingRequestType, - async (request, token) => this.provideFormatting(request, token) - ); - await this.serverClient.onRequestWithParams< - SerializableOnTypeFormattingParams, - SerializableFormattingResponse, - any - >(this.onTypeFormattingRequestType, async (request, token) => this.provideOnTypeFormatting(request, token)); - } - - private async provideFormatting( - formattingParams: SerializableFormattingParams, - cancellationToken: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse(formattingParams.textDocument.uri); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return FormattingHandler.emptyFormattingResponse; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.htmlDocument, - formattingParams.hostDocumentVersion, - cancellationToken - ); - if (!synchronized) { - return FormattingHandler.emptyFormattingResponse; - } - - const virtualHtmlUri = razorDocument.htmlDocument.uri; - const htmlDocContent = razorDocument.htmlDocument.getContent(); - - return await FormattingHandler.getHtmlFormattingResult( - virtualHtmlUri, - htmlDocContent, - formattingParams.options - ); - } catch (error) { - this.logger.logWarning(`${FormattingHandler.provideFormattingEndpoint} failed with ${error}`); - } - - return FormattingHandler.emptyFormattingResponse; - } + constructor() {} public static async getHtmlFormattingResult( virtualHtmlUri: vscode.Uri, @@ -138,45 +68,6 @@ export class FormattingHandler { return new SerializableFormattingResponse(serializableTextEdits); } - private async provideOnTypeFormatting( - formattingParams: SerializableOnTypeFormattingParams, - cancellationToken: vscode.CancellationToken - ) { - try { - const razorDocumentUri = vscode.Uri.parse(formattingParams.textDocument.uri); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return FormattingHandler.emptyFormattingResponse; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - formattingParams.hostDocumentVersion, - cancellationToken - ); - if (!synchronized) { - return FormattingHandler.emptyFormattingResponse; - } - - const virtualHtmlUri = razorDocument.htmlDocument.uri; - const htmlDocContent = razorDocument.htmlDocument.getContent(); - - return await FormattingHandler.getHtmlOnTypeFormattingResult( - virtualHtmlUri, - htmlDocContent, - formattingParams.position, - formattingParams.ch, - formattingParams.options - ); - } catch (error) { - this.logger.logWarning(`${FormattingHandler.provideFormattingEndpoint} failed with ${error}`); - } - - return FormattingHandler.emptyFormattingResponse; - } - private static sanitizeTextEdits(htmlDocText: string, textEdits: vscode.TextEdit[]) { const zeroBasedLineCount = FormattingHandler.countLines(htmlDocText); const serializableTextEdits = Array(); diff --git a/src/razor/src/formatting/serializableFormattingParams.ts b/src/razor/src/formatting/serializableFormattingParams.ts deleted file mode 100644 index c178fb77f6..0000000000 --- a/src/razor/src/formatting/serializableFormattingParams.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableFormattingParams { - hostDocumentVersion: number; - textDocument: SerializableTextDocumentIdentifier; - options: vscode.FormattingOptions; -} diff --git a/src/razor/src/formatting/serializableOnTypeFormattingParams.ts b/src/razor/src/formatting/serializableOnTypeFormattingParams.ts deleted file mode 100644 index 0ab0a295b6..0000000000 --- a/src/razor/src/formatting/serializableOnTypeFormattingParams.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { SerializablePosition } from '../rpc/serializablePosition'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableOnTypeFormattingParams { - hostDocumentVersion: number; - textDocument: SerializableTextDocumentIdentifier; - ch: string; - position: SerializablePosition; - options: vscode.FormattingOptions; -} diff --git a/src/razor/src/hostEventStream.ts b/src/razor/src/hostEventStream.ts deleted file mode 100644 index 88cbf7f63c..0000000000 --- a/src/razor/src/hostEventStream.ts +++ /dev/null @@ -1,65 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Bits in this file are contracts defined in https://github.com/omnisharp/omnisharp-vscode - -export interface HostEventStream { - post(event: BaseEvent): void; -} - -export function createTelemetryEvent( - eventName: string, - properties?: { [key: string]: string }, - measures?: { [key: string]: number } -): TelemetryEvent { - return { - type: EventType.TelemetryEvent, - eventName, - properties, - measures, - }; -} - -export function createTelemetryErrorEvent( - eventName: string, - properties?: { [key: string]: string }, - measures?: { [key: string]: number }, - errorProps?: string[] -): TelemetryErrorEvent { - return { - type: EventType.TelemetryErrorEvent, - eventName, - properties, - measures, - errorProps, - }; -} - -interface TelemetryEvent extends BaseEvent { - type: EventType.TelemetryEvent; - - eventName: string; - properties?: { [key: string]: string }; - measures?: { [key: string]: number }; -} - -interface TelemetryErrorEvent extends BaseEvent { - type: EventType.TelemetryErrorEvent; - - eventName: string; - properties?: { [key: string]: string }; - measures?: { [key: string]: number }; - errorProps?: string[]; -} - -interface BaseEvent { - type: any; -} - -// This is a sub-copied portion of OmniSharp's EventType class. -enum EventType { - TelemetryEvent = 1, - TelemetryErrorEvent = 78, -} diff --git a/src/razor/src/hover/razorHoverProvider.ts b/src/razor/src/hover/razorHoverProvider.ts deleted file mode 100644 index fa6f1aa972..0000000000 --- a/src/razor/src/hover/razorHoverProvider.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; - -export class RazorHoverProvider extends RazorLanguageFeatureBase implements vscode.HoverProvider { - public async provideHover( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection) { - return; - } - - const results = await vscode.commands.executeCommand( - 'vscode.executeHoverProvider', - projection.uri, - projection.position - ); - - if (!results || results.length === 0) { - return; - } - - // At the vscode.HoverProvider layer we can only return a single hover result. Because of this limitation we need to - // be smart about combining multiple hovers content or only take a single hover result. For now we'll only take one - // of them and then based on user feedback we can change this approach in the future. - const applicableHover = results.filter((item) => item.range)[0]; - if (!applicableHover) { - // No hovers available with a range. - return; - } - - // Re-map the projected hover range to the host document range - const remappedResponse = await this.serviceClient.mapToDocumentRanges( - projection.languageKind, - [applicableHover.range!], - document.uri - ); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // Couldn't remap the projected hover location, there's no hover information available. - return; - } - - if (projection.hostDocumentVersion !== remappedResponse.hostDocumentVersion) { - // This hover result is for a different version of the text document, bail. - return; - } - - const rewrittenContent = new Array(); - for (const content of applicableHover.contents) { - // For some reason VSCode doesn't respect the hover contents as-is. Because of this we need to look at each permutation - // of "content" (MarkdownString | string | { language: string; value: string }) and re-compute it as a MarkdownString or - // string. - - if (typeof content === 'string') { - const markdownString = new vscode.MarkdownString(content); - rewrittenContent.push(markdownString); - } else if ((content as { language: string; value: string }).language) { - const contentObject = content as { language: string; value: string }; - const markdownString = new vscode.MarkdownString(); - markdownString.appendCodeblock(contentObject.value, contentObject.language); - rewrittenContent.push(markdownString); - } else { - const contentValue = (content as vscode.MarkdownString).value; - const markdownString = new vscode.MarkdownString(contentValue); - rewrittenContent.push(markdownString); - } - } - - const hover = new vscode.Hover(rewrittenContent, remappedResponse.ranges[0]); - return hover; - } -} diff --git a/src/razor/src/html/htmlPreviewPanel.ts b/src/razor/src/html/htmlPreviewPanel.ts deleted file mode 100644 index ba2c8045b6..0000000000 --- a/src/razor/src/html/htmlPreviewPanel.ts +++ /dev/null @@ -1,153 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { IRazorDocumentChangeEvent } from '../document/IRazorDocumentChangeEvent'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { getUriPath } from '../uriPaths'; -import { showErrorMessage, showInformationMessage } from '../../../shared/observers/utils/showMessage'; - -export class HtmlPreviewPanel { - public static readonly viewType = 'razorHtmlPreview'; - - private panel: vscode.WebviewPanel | undefined; - private htmlContent: string | undefined; - - constructor(private readonly documentManager: RazorDocumentManager) { - documentManager.onChange(async (event) => this.documentChanged(event)); - } - - public async show() { - if (this.panel) { - this.panel.reveal(vscode.ViewColumn.Two); - } else { - this.panel = vscode.window.createWebviewPanel( - HtmlPreviewPanel.viewType, - vscode.l10n.t('Razor HTML Preview'), - vscode.ViewColumn.Two, - { - enableScripts: true, - // Dissallow any remote sources - localResourceRoots: [], - } - ); - this.attachToCurrentPanel(); - } - - await this.update(); - } - - public async revive(panel: vscode.WebviewPanel) { - this.panel = panel; - this.attachToCurrentPanel(); - await this.update(); - } - - private async documentChanged(event: IRazorDocumentChangeEvent) { - if (!this.panel) { - return; - } - - if ( - event.kind === RazorDocumentChangeKind.htmlChanged || - event.kind === RazorDocumentChangeKind.opened || - event.kind === RazorDocumentChangeKind.closed - ) { - await this.update(); - } - } - - private attachToCurrentPanel() { - if (!this.panel) { - showErrorMessage(vscode, vscode.l10n.t('Unexpected error when attaching to HTML preview window.')); - return; - } - - this.panel.webview.onDidReceiveMessage(async (message) => { - switch (message.command) { - case 'copy': - if (!this.htmlContent) { - return; - } - - await vscode.env.clipboard.writeText(this.htmlContent); - showInformationMessage(vscode, vscode.l10n.t('Razor HTML copied to clipboard')); - return; - } - }); - this.panel.onDidDispose(() => (this.panel = undefined)); - } - - private async update() { - if (!this.panel) { - return; - } - const document = await this.documentManager.getActiveDocument(); - let hostDocumentFilePath = ''; - let virtualDocumentFilePath = ''; - - if (document) { - // The document is guaranteed to be a Razor document - this.htmlContent = document.htmlDocument.getContent(); - hostDocumentFilePath = getUriPath(document.uri); - virtualDocumentFilePath = getUriPath(document.htmlDocument.uri); - } else { - this.htmlContent = undefined; - } - - let content = this.htmlContent ? this.htmlContent : ''; - content = content.replace(/ - - - - - - ${title} - - - - - -

${hostDocumentPathLabel}: ${hostDocumentFilePath}

-

${virtualDocumentPathLabel}: ${virtualDocumentFilePath}

-

-
-
${content}
- -`; - } -} diff --git a/src/razor/src/html/htmlProjectedDocument.ts b/src/razor/src/html/htmlProjectedDocument.ts deleted file mode 100644 index 1ec11bc5d7..0000000000 --- a/src/razor/src/html/htmlProjectedDocument.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { IProjectedDocument } from '../projection/IProjectedDocument'; -import { ServerTextChange } from '../rpc/serverTextChange'; -import { getUriPath } from '../uriPaths'; - -export class HtmlProjectedDocument implements IProjectedDocument { - public readonly path: string; - private content = ''; - private hostDocumentVersion: number | null = null; - - public constructor(public readonly uri: vscode.Uri) { - this.path = getUriPath(uri); - } - - public get hostDocumentSyncVersion(): number | null { - return this.hostDocumentVersion; - } - - public get length(): number { - return this.content.length; - } - - public clear() { - this.setContent(''); - } - - public update(edits: ServerTextChange[], hostDocumentVersion: number) { - this.hostDocumentVersion = hostDocumentVersion; - - if (edits.length === 0) { - return; - } - - let content = this.content; - for (const edit of edits.reverse()) { - // TODO: Use a better data structure to represent the content, string concatenation is slow. - content = this.getEditedContent(edit.newText, edit.span.start, edit.span.start + edit.span.length, content); - } - - this.setContent(content); - } - - public getContent() { - return this.content; - } - - private getEditedContent(newText: string, start: number, end: number, content: string) { - const before = content.substr(0, start); - const after = content.substr(end); - content = `${before}${newText}${after}`; - - return content; - } - - private setContent(content: string) { - this.content = content; - } -} diff --git a/src/razor/src/html/htmlProjectedDocumentContentProvider.ts b/src/razor/src/html/htmlProjectedDocumentContentProvider.ts deleted file mode 100644 index 20b7eba4c4..0000000000 --- a/src/razor/src/html/htmlProjectedDocumentContentProvider.ts +++ /dev/null @@ -1,75 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IRazorDocumentChangeEvent } from '../document/IRazorDocumentChangeEvent'; -import { IRazorDocumentManager } from '../document/IRazorDocumentManager'; -import { RazorDocumentChangeKind } from '../document/razorDocumentChangeKind'; -import { IEventEmitterFactory } from '../IEventEmitterFactory'; -import { RazorLogger } from '../razorLogger'; -import { getUriPath } from '../uriPaths'; -import * as vscode from '../vscodeAdapter'; - -export class HtmlProjectedDocumentContentProvider implements vscode.TextDocumentContentProvider { - public static readonly scheme = 'razor-html'; - - private readonly onDidChangeEmitter: vscode.EventEmitter; - - constructor( - private readonly documentManager: IRazorDocumentManager, - eventEmitterFactory: IEventEmitterFactory, - private readonly logger: RazorLogger - ) { - documentManager.onChange((event: IRazorDocumentChangeEvent) => this.documentChanged(event)); - this.onDidChangeEmitter = eventEmitterFactory.create(); - } - - public get onDidChange() { - return this.onDidChangeEmitter.event; - } - - public provideTextDocumentContent(uri: vscode.Uri) { - const razorDocument = this.findRazorDocument(uri); - if (!razorDocument) { - // Document was removed from the document manager, meaning there's no more content for this - // file. Report an empty document. - - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Could not find document '${getUriPath( - uri - )}' when updating the HTML buffer. This typically happens when a document is removed.` - ); - } - return ''; - } - - const content = `${razorDocument.htmlDocument.getContent()} -// ${razorDocument.htmlDocument.hostDocumentSyncVersion}`; - - return content; - } - - private documentChanged(event: IRazorDocumentChangeEvent) { - if ( - event.kind === RazorDocumentChangeKind.htmlChanged || - event.kind === RazorDocumentChangeKind.opened || - event.kind === RazorDocumentChangeKind.removed - ) { - // We also notify changes on document removal in order to tell VSCode that there's no more - // HTML content for the file. - - this.onDidChangeEmitter.fire(event.document.htmlDocument.uri); - } - } - - private findRazorDocument(uri: vscode.Uri) { - const projectedPath = getUriPath(uri); - - return this.documentManager.documents.find( - (razorDocument) => - razorDocument.htmlDocument.path.localeCompare(projectedPath, undefined, { sensitivity: 'base' }) === 0 - ); - } -} diff --git a/src/razor/src/html/htmlTagCompletionProvider.ts b/src/razor/src/html/htmlTagCompletionProvider.ts deleted file mode 100644 index 6ea3f61043..0000000000 --- a/src/razor/src/html/htmlTagCompletionProvider.ts +++ /dev/null @@ -1,182 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { - getLanguageService as getHtmlLanguageService, - LanguageService as HtmlLanguageService, -} from 'vscode-html-languageservice'; -import { TextDocument as ServiceTextDocument } from 'vscode-languageserver-textdocument'; -import { IRazorDocumentManager } from '../document/IRazorDocumentManager'; -import { RazorLanguage } from '../razorLanguage'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { LanguageKind } from '../rpc/languageKind'; - -export class HtmlTagCompletionProvider { - private timeout: NodeJS.Timeout | undefined = void 0; - private enabled = false; - private htmlLanguageService: HtmlLanguageService | undefined; - - constructor( - private readonly documentManager: IRazorDocumentManager, - private readonly serviceClient: RazorLanguageServiceClient - ) {} - - public register() { - this.htmlLanguageService = getHtmlLanguageService(); - - const onChangeRegistration = vscode.workspace.onDidChangeTextDocument(async (args) => - this.onDidChangeTextDocument(args.document, args.contentChanges) - ); - - const onActiveTextEditorChange = vscode.window.onDidChangeActiveTextEditor(() => this.checkIfEnabled()); - - this.checkIfEnabled(); - - return vscode.Disposable.from(onChangeRegistration, onActiveTextEditorChange); - } - - private checkIfEnabled() { - this.enabled = false; - - const editor = vscode.window.activeTextEditor; - if (!editor) { - return; - } - - const document = editor.document; - if (document.languageId !== RazorLanguage.id) { - return; - } - - if (!vscode.workspace.getConfiguration(void 0, document.uri).get('html.autoClosingTags')) { - return; - } - - this.enabled = true; - } - - private async onDidChangeTextDocument( - document: vscode.TextDocument, - changes: ReadonlyArray - ) { - if (!this.enabled) { - return; - } - - if (changes.length === 0) { - return; - } - - if (!vscode.window.activeTextEditor || vscode.window.activeTextEditor.document !== document) { - // Don't trigger for virtual documents - return; - } - - // At this point we're guarunteed to be looking at the correct document. - if (this.timeout !== undefined) { - clearTimeout(this.timeout); - } - - const lastChange = changes[changes.length - 1]; - if (lastChange.rangeLength > 0) { - // Don't auto-complete self-closing tags when replacing. - return; - } - - const lastCharacter = lastChange.text[lastChange.text.length - 1]; - if (lastCharacter !== '>') { - // We only want to operate on open tags - return; - } - - const rangeStart = lastChange.range.start; - - if (rangeStart.character < 2) { - // Only operate when we're working with a semi-usable tag such as '' where O is some sort of identifier. - return; - } - - const changeOffset = document.offsetAt(lastChange.range.start); - let documentContent = document.getText(); - const potentialSelfClosingCharacter = documentContent.charAt(changeOffset - 1); - if (potentialSelfClosingCharacter === '/' || potentialSelfClosingCharacter === '>') { - // Tag was already closed or is incomplete no need to auto-complete. - return; - } - - if (this.atMarkupTransition(documentContent, changeOffset)) { - // We're at a tag, no need to check if we're operating in a non-HTML area - // (we want to auto-complete ). - } else { - // Check language kind - const languageResponse = await this.serviceClient.languageQuery(lastChange.range.start, document.uri); - if (languageResponse.kind !== LanguageKind.Html) { - // This prevents auto-completion of things like C# generics - return; - } - } - - const version = document.version; - - // We set a timeout to allow for multi-changes or quick document switches (opening a document then - // instantly swapping to another) to flow through the system. Basically, if content that would trigger - // an auto-close occurs we allow a small amount of time for other edits to invalidate the current - // auto-close task. - this.timeout = setTimeout(async () => { - if (!this.enabled) { - return; - } - - const activeEditor = vscode.window.activeTextEditor; - if (!activeEditor) { - return; - } - const activeDocument = activeEditor.document; - if (document !== activeDocument || activeDocument.version !== version) { - // User has already moved on or the current document was already edited. - return; - } - - const position = new vscode.Position(rangeStart.line, rangeStart.character + lastChange.text.length); - if (!this.htmlLanguageService) { - return; - } - - const razorDoc = await this.documentManager.getActiveDocument(); - if (razorDoc) { - // The document is guaranteed to be a Razor document - documentContent = razorDoc.htmlDocument.getContent(); - } - - const serviceTextDocument = ServiceTextDocument.create( - document.uri.fsPath, - document.languageId, - document.version, - documentContent - ); - const htmlDocument = this.htmlLanguageService.parseHTMLDocument(serviceTextDocument); - const tagCompletion = this.htmlLanguageService.doTagComplete(serviceTextDocument, position, htmlDocument); - - if (!tagCompletion) { - return; - } - - const selections = activeEditor.selections; - if (selections.length && selections.some((s) => s.active.isEqual(position))) { - await activeEditor.insertSnippet( - new vscode.SnippetString(tagCompletion), - selections.map((s) => s.active) - ); - } else { - await activeEditor.insertSnippet(new vscode.SnippetString(tagCompletion), position); - } - }, 75); - } - - private atMarkupTransition(documentContent: string, changeOffset: number): boolean { - return documentContent.substring(changeOffset - ' this.htmlPreviewPanel.show()), - this.htmlTagCompletionProvider.register(), - ]; - - if (vscode.window.registerWebviewPanelSerializer) { - registrations.push( - vscode.window.registerWebviewPanelSerializer(HtmlPreviewPanel.viewType, { - deserializeWebviewPanel: async (panel: vscode.WebviewPanel) => { - await this.htmlPreviewPanel.revive(panel); - }, - }) - ); - } - - return vscode.Disposable.from(...registrations); - } -} diff --git a/src/razor/src/implementation/razorImplementationProvider.ts b/src/razor/src/implementation/razorImplementationProvider.ts deleted file mode 100644 index 075c97fa13..0000000000 --- a/src/razor/src/implementation/razorImplementationProvider.ts +++ /dev/null @@ -1,57 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { LanguageKind } from '../rpc/languageKind'; -import { MappingHelpers } from '../mapping/mappingHelpers'; -import { isRazorCSharpFile } from '../razorConventions'; - -export class RazorImplementationProvider extends RazorLanguageFeatureBase implements vscode.ImplementationProvider { - public async provideImplementation( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if ( - !projection || - projection.languageKind === LanguageKind.Html || - projection.languageKind === LanguageKind.Razor - ) { - // We don't think that javascript implementations are supported by VSCodes HTML support. - // Since we shim through to them we'll do nothing until we get an ask. - return; - } - - const implementations = (await vscode.commands.executeCommand( - 'vscode.executeImplementationProvider', - projection.uri, - projection.position - )) as vscode.Location[]; - - const result = new Array(); - for (const implementation of implementations) { - if (isRazorCSharpFile(implementation.uri)) { - const remappedLocation = await MappingHelpers.remapGeneratedFileLocation( - implementation, - this.serviceClient, - this.logger, - token - ); - if (remappedLocation === undefined) { - continue; - } - - result.push(remappedLocation); - } else { - // This means it is a .cs file, so we don't need to remap. - result.push(implementation); - } - } - - return result; - } -} diff --git a/src/razor/src/inlayHint/inlayHintHandler.ts b/src/razor/src/inlayHint/inlayHintHandler.ts deleted file mode 100644 index f40acc8448..0000000000 --- a/src/razor/src/inlayHint/inlayHintHandler.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { InlayHint, InlayHintParams, RequestType, TextDocumentIdentifier } from 'vscode-languageserver-protocol'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { SerializableInlayHintParams } from './serializableInlayHintParams'; -import { provideInlayHintsCommand } from '../../../lsptoolshost/razor/razorCommands'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; - -export class InlayHintHandler { - private static readonly provideInlayHint = 'razor/inlayHint'; - private InlayHintRequestType: RequestType = new RequestType( - InlayHintHandler.provideInlayHint - ); - private emptyInlayHintResponse = new Array(); - - constructor( - private readonly serverClient: RazorLanguageServerClient, - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams( - this.InlayHintRequestType, - async (request, token) => this.provideInlayHints(request, token) - ); - } - - private async provideInlayHints(inlayHintParams: SerializableInlayHintParams, token: vscode.CancellationToken) { - try { - const razorDocumentUri = vscode.Uri.parse(inlayHintParams.identifier.textDocumentIdentifier.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return this.emptyInlayHintResponse; - } - - if (!this.documentManager.roslynActivated) { - // Unlike most other handlers, inlay hints works by directly sending an LSP request to Roslyn, so if Roslyn isn't - // activated we need to catch that here. - return this.emptyInlayHintResponse; - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - inlayHintParams.identifier.version, - token - ); - if (!synchronized) { - return this.emptyInlayHintResponse; - } - - const virtualCSharpUri = UriConverter.serialize(razorDocument.csharpDocument.uri); - - const roslynInlayHintParams = { - textDocument: TextDocumentIdentifier.create(virtualCSharpUri), - range: inlayHintParams.projectedRange, - }; - const csharpInlayHints = await vscode.commands.executeCommand( - provideInlayHintsCommand, - roslynInlayHintParams - ); - - return csharpInlayHints; - } catch (error) { - this.logger.logWarning(`${InlayHintHandler.provideInlayHint} failed with ${error}`); - } - - return this.emptyInlayHintResponse; - } -} diff --git a/src/razor/src/inlayHint/inlayHintResolveHandler.ts b/src/razor/src/inlayHint/inlayHintResolveHandler.ts deleted file mode 100644 index 2bba65b8c7..0000000000 --- a/src/razor/src/inlayHint/inlayHintResolveHandler.ts +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { InlayHint, RequestType } from 'vscode-languageserver-protocol'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorLogger } from '../razorLogger'; -import { SerializableInlayHintResolveParams } from './serializableInlayHintResolveParams'; -import { resolveInlayHintCommand } from '../../../lsptoolshost/razor/razorCommands'; - -export class InlayHintResolveHandler { - private static readonly resolveInlayHint = 'razor/inlayHintResolve'; - private InlayHintResolveRequestType: RequestType = - new RequestType(InlayHintResolveHandler.resolveInlayHint); - - constructor( - private readonly serverClient: RazorLanguageServerClient, - private readonly documentManager: RazorDocumentManager, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams( - this.InlayHintResolveRequestType, - async (request, token) => this.resolveInlayHint(request, token) - ); - } - - private async resolveInlayHint(InlayHintParams: SerializableInlayHintResolveParams, _: vscode.CancellationToken) { - try { - const razorDocumentUri = vscode.Uri.parse(InlayHintParams.identifier.textDocumentIdentifier.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - return null; - } - - const response = await vscode.commands.executeCommand( - resolveInlayHintCommand, - InlayHintParams.inlayHint - ); - - return response; - } catch (error) { - this.logger.logWarning(`${InlayHintResolveHandler.resolveInlayHint} failed with ${error}`); - } - - return null; - } -} diff --git a/src/razor/src/inlayHint/serializableInlayHintParams.ts b/src/razor/src/inlayHint/serializableInlayHintParams.ts deleted file mode 100644 index c1ac3fca5e..0000000000 --- a/src/razor/src/inlayHint/serializableInlayHintParams.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Range } from 'vscode-languageserver-protocol'; -import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion'; - -export interface SerializableInlayHintParams { - identifier: SerializableTextDocumentIdentifierAndVersion; - projectedRange: Range; -} diff --git a/src/razor/src/inlayHint/serializableInlayHintResolveParams.ts b/src/razor/src/inlayHint/serializableInlayHintResolveParams.ts deleted file mode 100644 index abf28476d7..0000000000 --- a/src/razor/src/inlayHint/serializableInlayHintResolveParams.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { InlayHint } from 'vscode-languageserver-protocol'; -import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion'; - -export interface SerializableInlayHintResolveParams { - identifier: SerializableTextDocumentIdentifierAndVersion; - inlayHint: InlayHint; -} diff --git a/src/razor/src/mapping/mappingHandler.ts b/src/razor/src/mapping/mappingHandler.ts deleted file mode 100644 index 97ecf4e3bf..0000000000 --- a/src/razor/src/mapping/mappingHandler.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorMapSpansParams } from './razorMapSpansParams'; -import { RazorMapTextChangesParams } from './razorMapTextChangesParams'; - -export class MappingHandler { - public static readonly MapSpansCommand = 'razor.mapSpansCommand'; - public static readonly MapChangesCommand = 'razor.mapChangesCommand'; - - constructor(private readonly languageServiceClient: RazorLanguageServiceClient) {} - - public async register(): Promise { - return vscode.Disposable.from( - ...[ - vscode.commands.registerCommand(MappingHandler.MapSpansCommand, async (params: RazorMapSpansParams) => { - return this.languageServiceClient.mapSpans(params); - }), - vscode.commands.registerCommand( - MappingHandler.MapChangesCommand, - async (params: RazorMapTextChangesParams) => { - return this.languageServiceClient.mapTextChanges(params); - } - ), - ] - ); - } -} diff --git a/src/razor/src/mapping/mappingHelpers.ts b/src/razor/src/mapping/mappingHelpers.ts deleted file mode 100644 index 0ac805b66b..0000000000 --- a/src/razor/src/mapping/mappingHelpers.ts +++ /dev/null @@ -1,167 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { LanguageKind } from '../rpc/languageKind'; -import { isRazorCSharpFile, getRazorDocumentUri } from '../razorConventions'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLogger } from '../razorLogger'; - -export class MappingHelpers { - public static readonly language = 'Razor'; - - public static async remapGeneratedFileWorkspaceEdit( - workspaceEdit: vscode.WorkspaceEdit, - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger, - token: vscode.CancellationToken - ) { - const map = new Map(); - - // The returned edits will be for the projected C# documents. We now need to re-map that to the original document. - for (const entry of workspaceEdit.entries()) { - const uri = entry[0]; - const edits = entry[1]; - - if (!isRazorCSharpFile(uri)) { - // This edit happens outside of a Razor document. Let the edit go through as is. - map.set(uri, edits); - continue; - } - - // We're now working with a Razor CSharp document. - const documentUri = getRazorDocumentUri(uri); - - // Re-map each edit to its position in the original Razor document. - for (const edit of edits) { - const remappedEdit = await MappingHelpers.remapGeneratedFileTextEdit( - documentUri, - edit, - serviceClient, - logger, - token - ); - - if (remappedEdit) { - this.addElementToDictionary(map, documentUri, remappedEdit); - } - } - } - - const result = this.mapToTextEdit(map); - return result; - } - - /** - * Try to map a textedit from a generated document onto the razor file - * @param uri The document uri, expected to be the generated document - * @param textEdit The edit to map from a generated document - * @returns A mapped edit, or undefined if the edit couldn't be mapped (or is in a razor file) - */ - public static async remapGeneratedFileTextEdit( - uri: vscode.Uri, - textEdit: vscode.TextEdit, - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger, - _: vscode.CancellationToken - ): Promise { - const remappedResponse = await serviceClient.mapToDocumentRanges(LanguageKind.CSharp, [textEdit.range], uri); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // This is kind of wrong. Workspace edits commonly consist of a bunch of different edits which - // don't make sense individually. If we try to introspect on them individually there won't be - // enough context to do anything intelligent. But we also need to know if the edit can just - // be handled by mapToDocumentRange (something went wrong here), so we ignore the edit. - logger.logWarning(`Unable to remap file ${uri.path} at ${textEdit.range}.`); - return undefined; - } else { - const remappedEdit = new vscode.TextEdit(remappedResponse.ranges[0], textEdit.newText); - - logger.logTrace( - `Re-mapping text ${textEdit.newText} at ${textEdit.range} in ${uri.path} to ${remappedResponse.ranges[0]} in ${uri.path}` - ); - - return remappedEdit; - } - } - - public static async remapGeneratedFileLocation( - location: vscode.Location, - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger, - _: vscode.CancellationToken - ) { - if (!isRazorCSharpFile(location.uri)) { - // This location exists outside of a Razor document. Leave it unchanged. - return location; - } - - // We're now working with a Razor CSharp document. - const documentUri = getRazorDocumentUri(location.uri); - const remappedResponse = await serviceClient.mapToDocumentRanges( - LanguageKind.CSharp, - [location.range], - documentUri - ); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // Something went wrong when re-mapping to the original document. Ignore this location. - logger.logWarning(`Unable to remap file ${location.uri.path} at ${location.range}.`); - return; - } - - logger.logTrace( - `Re-mapping location ${location.range} in ${location.uri.path} to ${remappedResponse.ranges[0]} in ${documentUri.path}` - ); - - const newLocation = new vscode.Location(documentUri, remappedResponse.ranges[0]); - return newLocation; - } - - public static async remapGeneratedFileLocations( - locations: vscode.Location[], - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger, - token: vscode.CancellationToken - ) { - const result: vscode.Location[] = []; - for (const location of locations) { - const remappedLocation = await this.remapGeneratedFileLocation(location, serviceClient, logger, token); - if (remappedLocation !== undefined) { - result.push(remappedLocation); - } - } - - return result; - } - - private static mapToTextEdit(map: Map): vscode.WorkspaceEdit { - const result = new vscode.WorkspaceEdit(); - map.forEach((value, key) => { - result.set(key, value); - }); - - return result; - } - - private static addElementToDictionary( - map: Map, - uri: vscode.Uri, - edit: vscode.TextEdit - ) { - let mapArray: vscode.TextEdit[] | undefined; - - if (map.has(uri)) { - mapArray = map.get(uri); - if (mapArray) { - mapArray.push(edit); - } - } else { - const editArray = new Array(); - editArray.push(edit); - map.set(uri, editArray); - } - } -} diff --git a/src/razor/src/mapping/razorMapSpansParams.ts b/src/razor/src/mapping/razorMapSpansParams.ts deleted file mode 100644 index 01e85702b3..0000000000 --- a/src/razor/src/mapping/razorMapSpansParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Range, TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -// Matches https://github.com/dotnet/razor/blob/main/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansParams.cs -export class RazorMapSpansParams { - constructor(public readonly csharpDocument: TextDocumentIdentifier, public readonly ranges: Range[]) {} -} diff --git a/src/razor/src/mapping/razorMapSpansResponse.ts b/src/razor/src/mapping/razorMapSpansResponse.ts deleted file mode 100644 index c407db89ea..0000000000 --- a/src/razor/src/mapping/razorMapSpansResponse.ts +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-types'; -import { razorTextSpan } from '../dynamicFile/razorTextSpan'; -import { SerializableRange } from '../rpc/serializableRange'; - -// matches https://github.com/dotnet/razor/blob/main/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansResponse.cs -export class RazorMapSpansResponse { - static empty: RazorMapSpansResponse = new RazorMapSpansResponse([], [], { uri: '' }); - - constructor( - public readonly ranges: SerializableRange[], - public readonly spans: razorTextSpan[], - public readonly razorDocument: TextDocumentIdentifier - ) {} -} diff --git a/src/razor/src/mapping/razorMapTextChangesParams.ts b/src/razor/src/mapping/razorMapTextChangesParams.ts deleted file mode 100644 index d0e5f6c185..0000000000 --- a/src/razor/src/mapping/razorMapTextChangesParams.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { TextDocumentIdentifier } from 'vscode-languageserver-types'; -import { razorTextChange } from '../dynamicFile/razorTextChange'; - -// Matches https://github.com/dotnet/razor/blob/401f6f8632a7e0320bc12804fa7e9659b3b3aeab/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesParams.cs -export class RazorMapTextChangesParams { - constructor( - public readonly csharpDocument: TextDocumentIdentifier, - public readonly textChanges: razorTextChange[] - ) {} -} diff --git a/src/razor/src/mapping/razorMapTextChangesResponse.ts b/src/razor/src/mapping/razorMapTextChangesResponse.ts deleted file mode 100644 index 09ff343c40..0000000000 --- a/src/razor/src/mapping/razorMapTextChangesResponse.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { TextDocumentIdentifier } from 'vscode-languageserver-types'; -import { razorTextChange } from '../dynamicFile/razorTextChange'; - -// Matches https://github.com/dotnet/razor/blob/401f6f8632a7e0320bc12804fa7e9659b3b3aeab/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapTextChangesResponse.cs -export class RazorMapTextChangesResponse { - static empty: RazorMapTextChangesResponse | PromiseLike; - constructor( - public readonly razorDocument: TextDocumentIdentifier, - public readonly textChanges: razorTextChange[] - ) {} -} diff --git a/src/razor/src/mapping/razorMapToDocumentEditsParams.ts b/src/razor/src/mapping/razorMapToDocumentEditsParams.ts deleted file mode 100644 index 39da2a08ce..0000000000 --- a/src/razor/src/mapping/razorMapToDocumentEditsParams.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { Uri } from 'vscode'; -import { razorTextChange } from '../dynamicFile/razorTextChange'; -import { LanguageKind } from '../rpc/languageKind'; - -// Matches https://github.com/dotnet/razor/blob/401f6f8632a7e0320bc12804fa7e9659b3b3aeab/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/DocumentMapping/RazorMapToDocumentEditsParams.cs -export class RazorMapToDocumentEditsParams { - constructor( - public readonly kind: LanguageKind, - public readonly razorDocumentUri: Uri, - public readonly textChanges: razorTextChange[] - ) {} -} diff --git a/src/razor/src/mapping/razorMapToDocumentEditsResponse.ts b/src/razor/src/mapping/razorMapToDocumentEditsResponse.ts deleted file mode 100644 index 48007cf40f..0000000000 --- a/src/razor/src/mapping/razorMapToDocumentEditsResponse.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { razorTextChange } from '../dynamicFile/razorTextChange'; - -// Matches https://github.com/dotnet/razor/blob/401f6f8632a7e0320bc12804fa7e9659b3b3aeab/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/DocumentMapping/RazorMapToDocumentEditsResponse.cs -export class RazorMapToDocumentEditsResponse { - constructor(public readonly textChanges: razorTextChange[], public readonly hostDocumentVersion: number) {} -} diff --git a/src/razor/src/projection/IProjectedDocument.ts b/src/razor/src/projection/IProjectedDocument.ts deleted file mode 100644 index f16ce62483..0000000000 --- a/src/razor/src/projection/IProjectedDocument.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export interface IProjectedDocument { - readonly path: string; - readonly uri: vscode.Uri; - readonly hostDocumentSyncVersion: number | null; - readonly length: number; - getContent(): string; -} diff --git a/src/razor/src/projection/projectionResult.ts b/src/razor/src/projection/projectionResult.ts deleted file mode 100644 index 55f65d7b3e..0000000000 --- a/src/razor/src/projection/projectionResult.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { LanguageKind } from '../rpc/languageKind'; - -export interface ProjectionResult { - uri: vscode.Uri; - position: vscode.Position; - languageKind: LanguageKind; - hostDocumentVersion: number; -} diff --git a/src/razor/src/proposedApisFeature.ts b/src/razor/src/proposedApisFeature.ts deleted file mode 100644 index 819c1fe0da..0000000000 --- a/src/razor/src/proposedApisFeature.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscodeapi from 'vscode'; - -export class ProposedApisFeature { - public async register(vscodeType: typeof vscodeapi) { - if (vscodeType.env.appName.endsWith('Insiders')) { - return; - } - } -} diff --git a/src/razor/src/razorCSharpLanguageMiddleware.ts b/src/razor/src/razorCSharpLanguageMiddleware.ts deleted file mode 100644 index ac026f920d..0000000000 --- a/src/razor/src/razorCSharpLanguageMiddleware.ts +++ /dev/null @@ -1,139 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { getRazorDocumentUri, isRazorCSharpFile } from './razorConventions'; -import { RazorLanguageServiceClient } from './razorLanguageServiceClient'; -import { RazorLogger } from './razorLogger'; -import { LanguageKind } from './rpc/languageKind'; - -// This interface should exactly match the `LanguageMiddleware` interface defined in Omnisharp. -// https://github.com/OmniSharp/omnisharp-vscode/blob/master/src/omnisharp/LanguageMiddlewareFeature.ts#L9-L16 -interface LanguageMiddleware { - language: string; - - remapWorkspaceEdit?( - workspaceEdit: vscode.WorkspaceEdit, - token: vscode.CancellationToken - ): vscode.ProviderResult; - - remapLocations?( - locations: vscode.Location[], - token: vscode.CancellationToken - ): vscode.ProviderResult; -} - -export class RazorCSharpLanguageMiddleware implements LanguageMiddleware { - public readonly language = 'Razor'; - - constructor(private readonly serviceClient: RazorLanguageServiceClient, private readonly logger: RazorLogger) {} - - public async remapWorkspaceEdit(workspaceEdit: vscode.WorkspaceEdit, _: vscode.CancellationToken) { - const map = new Map(); - - // The returned edits will be for the projected C# documents. We now need to re-map that to the original document. - for (const entry of workspaceEdit.entries()) { - const uri = entry[0]; - const edits = entry[1]; - - if (!isRazorCSharpFile(uri)) { - // This edit happens outside of a Razor document. Let the edit go through as is. - map.set(uri, edits); - continue; - } - - // We're now working with a Razor CSharp document. - const documentUri = getRazorDocumentUri(uri); - - // Re-map each edit to its position in the original Razor document. - for (const edit of edits) { - const remappedResponse = await this.serviceClient.mapToDocumentRanges( - LanguageKind.CSharp, - [edit.range], - documentUri - ); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // This is kind of wrong. Workspace edits commonly consist of a bunch of different edits which - // don't make sense individually. If we try to introspect on them individually there won't be - // enough context to do anything intelligent. But we also need to know if the edit can just - // be handled by mapToDocumentRange (something went wrong here), so we ignore the edit. - this.logger.logWarning(`Unable to remap file ${uri.path} at ${edit.range}.`); - continue; - } else { - const remappedEdit = new vscode.TextEdit(remappedResponse.ranges[0], edit.newText); - - this.logger.logTrace( - `Re-mapping text ${edit.newText} at ${edit.range} in ${uri.path} to ${remappedResponse.ranges[0]} in ${documentUri.path}` - ); - - this.addElementToDictionary(map, documentUri, remappedEdit); - } - } - } - - const result = this.mapToTextEdit(map); - return result; - } - - public async remapLocations(locations: vscode.Location[], _: vscode.CancellationToken) { - const result: vscode.Location[] = []; - - for (const location of locations) { - if (!isRazorCSharpFile(location.uri)) { - // This location exists outside of a Razor document. Leave it unchanged. - result.push(location); - continue; - } - - // We're now working with a Razor CSharp document. - const documentUri = getRazorDocumentUri(location.uri); - const remappedResponse = await this.serviceClient.mapToDocumentRanges( - LanguageKind.CSharp, - [location.range], - documentUri - ); - - if (!remappedResponse || !remappedResponse.ranges || !remappedResponse.ranges[0]) { - // Something went wrong when re-mapping to the original document. Ignore this location. - this.logger.logWarning(`Unable to remap file ${location.uri.path} at ${location.range}.`); - continue; - } - - const newLocation = new vscode.Location(documentUri, remappedResponse.ranges[0]); - result.push(newLocation); - - this.logger.logTrace( - `Re-mapping location ${location.range} in ${location.uri.path} to ${remappedResponse.ranges[0]} in ${documentUri.path}` - ); - } - - return result; - } - - private mapToTextEdit(map: Map): vscode.WorkspaceEdit { - const result = new vscode.WorkspaceEdit(); - map.forEach((value, key) => { - result.set(key, value); - }); - - return result; - } - - private addElementToDictionary(map: Map, uri: vscode.Uri, edit: vscode.TextEdit) { - let mapArray: vscode.TextEdit[] | undefined; - - if (map.has(uri)) { - mapArray = map.get(uri); - if (mapArray) { - mapArray.push(edit); - } - } else { - const editArray = new Array(); - editArray.push(edit); - map.set(uri, editArray); - } - } -} diff --git a/src/razor/src/razorConventions.ts b/src/razor/src/razorConventions.ts deleted file mode 100644 index 12bae6266f..0000000000 --- a/src/razor/src/razorConventions.ts +++ /dev/null @@ -1,31 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { getUriPath } from './uriPaths'; - -export const virtualHtmlSuffix = '__virtual.html'; -export const virtualCSharpSuffix = '__virtual.cs'; -export const backgroundVirtualCSharpSuffix = `__bg${virtualCSharpSuffix}`; - -export function isRazorCSharpFile(uri: vscode.Uri) { - const path = getUriPath(uri); - return path.endsWith(virtualCSharpSuffix); -} - -export function isRazorHtmlFile(uri: vscode.Uri) { - const path = getUriPath(uri); - return path.endsWith(virtualHtmlSuffix); -} - -export function getRazorDocumentUri(uri: vscode.Uri) { - const path = getUriPath(uri); - let originalDocumentPath = path.replace(backgroundVirtualCSharpSuffix, ''); - originalDocumentPath = originalDocumentPath.replace(virtualCSharpSuffix, ''); - originalDocumentPath = originalDocumentPath.replace(virtualHtmlSuffix, ''); - - const documentUri = vscode.Uri.file(originalDocumentPath); - return documentUri; -} diff --git a/src/razor/src/razorLanguageClient.ts b/src/razor/src/razorLanguageClient.ts deleted file mode 100644 index 73573aaa68..0000000000 --- a/src/razor/src/razorLanguageClient.ts +++ /dev/null @@ -1,38 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken, LanguageClientOptions, MessageSignature } from 'vscode-languageclient'; -import { LanguageClient, ServerOptions } from 'vscode-languageclient/node'; -import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; - -export class RazorLanguageClient extends LanguageClient { - razorOptions: RazorLanguageServerOptions; - - constructor( - id: string, - name: string, - serverOptions: ServerOptions, - clientOptions: LanguageClientOptions, - razorOptions: RazorLanguageServerOptions, - forceDebug?: boolean - ) { - super(id, name, serverOptions, clientOptions, forceDebug); - this.razorOptions = razorOptions; - } - - override handleFailedRequest( - type: MessageSignature, - token: CancellationToken | undefined, - error: any, - defaultValue: T, - showNotification?: boolean - ) { - if (this.razorOptions.suppressErrorToasts) { - return super.handleFailedRequest(type, token, error, defaultValue, false); - } - - return super.handleFailedRequest(type, token, error, defaultValue, showNotification); - } -} diff --git a/src/razor/src/razorLanguageFeatureBase.ts b/src/razor/src/razorLanguageFeatureBase.ts deleted file mode 100644 index 82d1e97b26..0000000000 --- a/src/razor/src/razorLanguageFeatureBase.ts +++ /dev/null @@ -1,74 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorDocumentManager } from './document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from './document/razorDocumentSynchronizer'; -import { ProjectionResult } from './projection/projectionResult'; -import { RazorLanguageServiceClient } from './razorLanguageServiceClient'; -import { RazorLogger } from './razorLogger'; -import { LanguageKind } from './rpc/languageKind'; -import { getUriPath } from './uriPaths'; - -export class RazorLanguageFeatureBase { - constructor( - protected readonly documentSynchronizer: RazorDocumentSynchronizer, - protected readonly documentManager: RazorDocumentManager, - protected readonly serviceClient: RazorLanguageServiceClient, - protected readonly logger: RazorLogger - ) {} - - protected async getProjection( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const languageResponse = await this.serviceClient.languageQuery(position, document.uri); - - switch (languageResponse.kind) { - case LanguageKind.CSharp: - case LanguageKind.Html: { - const razorDocument = await this.documentManager.getDocument(document.uri); - const projectedDocument = - languageResponse.kind === LanguageKind.CSharp - ? razorDocument.csharpDocument - : razorDocument.htmlDocument; - - if (languageResponse.hostDocumentVersion === undefined) { - // There should always be a document version attached to an open document. - // Log it and move on as if it was synchronized. - if (this.logger.traceEnabled) { - this.logger.logTrace( - `Could not find a document version associated with the document '${getUriPath( - document.uri - )}'.` - ); - } - } else { - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - document, - projectedDocument, - languageResponse.hostDocumentVersion, - token - ); - if (!synchronized) { - // Could not synchronize - return null; - } - } - - const projectedUri = projectedDocument.uri; - return { - uri: projectedUri, - position: languageResponse.position, - languageKind: languageResponse.kind, - hostDocumentVersion: projectedDocument.hostDocumentSyncVersion, - } as ProjectionResult; - } - default: - return null; - } - } -} diff --git a/src/razor/src/razorLanguageServerClient.ts b/src/razor/src/razorLanguageServerClient.ts deleted file mode 100644 index 2eb74d5918..0000000000 --- a/src/razor/src/razorLanguageServerClient.ts +++ /dev/null @@ -1,321 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as cp from 'child_process'; -import { EventEmitter } from 'events'; -import * as vscode from 'vscode'; -import { GenericNotificationHandler, RequestHandler, RequestType } from 'vscode-jsonrpc'; -import { InitializeResult } from 'vscode-languageserver-protocol'; -import { LanguageClientOptions, State } from 'vscode-languageclient'; -import { ServerOptions } from 'vscode-languageclient/node'; -import { RazorLanguage } from './razorLanguage'; -import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; -import { resolveRazorLanguageServerOptions } from './razorLanguageServerOptionsResolver'; -import { RazorLogger } from './razorLogger'; -import { TelemetryReporter as RazorTelemetryReporter } from './telemetryReporter'; -import TelemetryReporter from '@vscode/extension-telemetry'; -import { randomUUID } from 'crypto'; -import { showErrorMessage } from '../../shared/observers/utils/showMessage'; -import { RazorLanguageClient } from './razorLanguageClient'; -import { provideDiagnostics, provideWorkspaceDiagnostics } from '../../lsptoolshost/diagnostics/diagnosticMiddleware'; - -const events = { - ServerStop: 'ServerStop', -}; - -export class RazorLanguageServerClient implements vscode.Disposable { - private clientOptions!: LanguageClientOptions; - private serverOptions!: ServerOptions; - private client!: RazorLanguageClient; - private onStartListeners: Array<() => Promise> = []; - private onStartedListeners: Array<() => Promise> = []; - private eventBus: EventEmitter; - private isStarted: boolean; - private startHandle: Promise | undefined; - private stopHandle: Promise | undefined; - - constructor( - private readonly vscodeType: typeof vscode, - private readonly languageServerDir: string, - private readonly razorTelemetryReporter: RazorTelemetryReporter, - private readonly vscodeTelemetryReporter: TelemetryReporter, - private readonly telemetryExtensionDllPath: string, - private readonly env: NodeJS.ProcessEnv, - private readonly dotnetExecutablePath: string, - private readonly logger: RazorLogger - ) { - this.isStarted = false; - - this.setupLanguageServer(); - - this.eventBus = new EventEmitter(); - } - - public get initializeResult(): InitializeResult | undefined { - return this.client.initializeResult; - } - - public onStarted(listener: () => Promise) { - this.onStartedListeners.push(listener); - } - - public onStart(listener: () => Promise) { - this.onStartListeners.push(listener); - } - - public onStop(listener: () => any) { - this.eventBus.addListener(events.ServerStop, listener); - - const disposable = new vscode.Disposable(() => this.eventBus.removeListener(events.ServerStop, listener)); - return disposable; - } - - public async start() { - if (this.startHandle) { - return this.startHandle; - } - - let resolve: () => void = Function; - let reject: (reason: any) => void = Function; - // tslint:disable-next-line: promise-must-complete - this.startHandle = new Promise((resolver, rejecter) => { - resolve = resolver; - reject = rejecter; - }); - - // Workaround https://github.com/Microsoft/vscode-languageserver-node/issues/472 by tying into state - // change events to detect when restarts are occuring and then properly reject the Language Server - // start listeners. - let restartCount = 0; - const didChangeStateDisposable = this.client.onDidChangeState( - (stateChangeEvent: { newState: any; oldState: any }) => { - if (stateChangeEvent.oldState === State.Starting && stateChangeEvent.newState === State.Stopped) { - restartCount++; - - if (restartCount === 5) { - // Timeout, the built-in LanguageClient retries a hardcoded 5 times before giving up. We tie into that - // and then given up on starting the language server if we can't start by then. - reject(vscode.l10n.t('Server failed to start after retrying 5 times.')); - } - } else if (stateChangeEvent.newState === State.Running) { - restartCount = 0; - } - } - ); - - try { - this.logger.logInfo('Starting Razor Language Server...'); - await this.client.start(); - this.logger.logInfo('Server started, waiting for client to be ready...'); - this.isStarted = true; - - // Server is ready, hook up so logging changes can be reported - this.logger.languageServerClient = this; - - for (const listener of this.onStartListeners) { - await listener(); - } - - // Succesfully started, notify listeners. - resolve(); - - this.logger.logInfo('Server ready!'); - - for (const listener of this.onStartedListeners) { - await listener(); - } - - // We don't want to track restart management after the server has been initially started, - // the language client will handle that. - didChangeStateDisposable.dispose(); - } catch (error) { - showErrorMessage( - vscode, - vscode.l10n.t( - "Razor Language Server failed to start unexpectedly, please check the 'Razor Log' and report an issue." - ) - ); - - this.razorTelemetryReporter.reportErrorOnServerStart(error as Error); - reject(error); - } - - return this.startHandle; - } - - public async sendRequest(method: string, param: any) { - if (!this.isStarted) { - throw new Error(vscode.l10n.t('Tried to send requests while server is not started.')); - } - - return this.client.sendRequest(method, param); - } - - public async sendNotification(method: string, param: any) { - if (!this.isStarted) { - throw new Error(vscode.l10n.t('Tried to send requests while server is not started.')); - } - - return this.client.sendNotification(method, param); - } - - public async onRequestWithParams(method: RequestType, handler: RequestHandler) { - if (!this.isStarted) { - throw new Error(vscode.l10n.t('Tried to bind on request logic while server is not started.')); - } - - this.client.onRequest(method, handler); - } - - public onNotification(method: string, handler: GenericNotificationHandler) { - if (!this.isStarted) { - throw new Error(vscode.l10n.t('Tried to bind on notification logic while server is not started.')); - } - - this.client.onNotification(method, handler); - } - - public dispose() { - this.logger.logInfo('Disposing Razor Language Server.'); - - this.isStarted = false; - this.startHandle = undefined; - this.eventBus.emit(events.ServerStop); - } - - public async stop() { - let resolve: () => void = Function; - let reject: (reason: any) => void = Function; - // tslint:disable-next-line: promise-must-complete - this.stopHandle = new Promise((resolver, rejecter) => { - resolve = resolver; - reject = rejecter; - }); - - if (!this.startHandle) { - reject(new Error(vscode.l10n.t('Cannot stop Razor Language Server as it is already stopped.'))); - } - - this.logger.logInfo('Stopping Razor Language Server.'); - - try { - if (this.client) { - await this.client.stop(); - } - - this.dispose(); - - resolve(); - } catch (error) { - showErrorMessage( - vscode, - vscode.l10n.t( - "Razor Language Server failed to stop correctly, please check the 'Razor Log' and report an issue." - ) - ); - - reject(error); - } - - return this.stopHandle; - } - - public async connectNamedPipe(pipeName: string): Promise { - await this.start(); - - // Params must match https://github.com/dotnet/razor/blob/92005deac54f3e9d1a4d1d8f04389379cccfa354/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/RazorNamedPipeConnectParams.cs#L9 - await this.sendNotification('razor/namedPipeConnect', { pipeName: pipeName }); - } - - private setupLanguageServer() { - const options: RazorLanguageServerOptions = resolveRazorLanguageServerOptions( - this.vscodeType, - this.languageServerDir, - this.logger - ); - this.clientOptions = { - outputChannel: options.outputChannel, - documentSelector: [{ language: RazorLanguage.id, pattern: RazorLanguage.globbingPattern }], - middleware: { - provideDiagnostics, - provideWorkspaceDiagnostics, - }, - }; - - const args: string[] = []; - - this.logger.logInfo(`Razor language server path: ${options.serverPath}`); - - args.push('--logLevel'); - args.push(this.logger.logLevelForRZLS.toString()); - this.razorTelemetryReporter.reportTraceLevel(this.logger.logLevel); - - if (options.debug) { - this.razorTelemetryReporter.reportDebugLanguageServer(); - - this.logger.logInfo('Debug flag set for Razor Language Server.'); - args.push('--debug'); - } - - // TODO: When all of this code is on GitHub, should we just pass `--omnisharp` as a flag to rzls, and let it decide? - if (!options.usingOmniSharp) { - args.push('--DelegateToCSharpOnDiagnosticPublish'); - args.push('true'); - args.push('--UpdateBuffersForClosedDocuments'); - args.push('true'); - args.push('--SingleServerCompletionSupport'); - args.push('true'); - - if (this.telemetryExtensionDllPath.length > 0) { - args.push('--telemetryLevel', this.vscodeTelemetryReporter.telemetryLevel); - args.push('--sessionId', getSessionId()); - args.push('--telemetryExtensionPath', this.telemetryExtensionDllPath); - } - } - - let childProcess: () => Promise; - const cpOptions: cp.SpawnOptionsWithoutStdio = { - detached: true, - windowsHide: true, - env: this.env, - }; - - if (options.serverPath.endsWith('.dll')) { - // If we were given a path to a dll, launch that via dotnet. - const argsWithPath = [options.serverPath].concat(args); - this.logger.logInfo(`Server arguments ${argsWithPath.join(' ')}`); - - childProcess = async () => cp.spawn(this.dotnetExecutablePath, argsWithPath, cpOptions); - } else { - // Otherwise assume we were given a path to an executable. - this.logger.logInfo(`Server arguments ${args.join(' ')}`); - - childProcess = async () => cp.spawn(options.serverPath, args, cpOptions); - } - - this.serverOptions = childProcess; - - this.client = new RazorLanguageClient( - 'razorLanguageServer', - 'Razor Language Server', - this.serverOptions, - this.clientOptions, - options - ); - } -} - -// VS code will have a default session id when running under tests. Since we may still -// report telemetry, we need to give a unique session id instead of the default value. -function getSessionId(): string { - const sessionId = vscode.env.sessionId; - - // 'somevalue.sessionid' is the test session id provided by vs code - if (sessionId.toLowerCase() === 'somevalue.sessionid') { - return randomUUID(); - } - - return sessionId; -} diff --git a/src/razor/src/razorLanguageServerOptions.ts b/src/razor/src/razorLanguageServerOptions.ts deleted file mode 100644 index 356bc32ad8..0000000000 --- a/src/razor/src/razorLanguageServerOptions.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export interface RazorLanguageServerOptions { - serverPath: string; - outputChannel?: vscode.LogOutputChannel; - debug?: boolean; - usingOmniSharp: boolean; - suppressErrorToasts: boolean; -} diff --git a/src/razor/src/razorLanguageServerOptionsResolver.ts b/src/razor/src/razorLanguageServerOptionsResolver.ts deleted file mode 100644 index 8ea7ade13a..0000000000 --- a/src/razor/src/razorLanguageServerOptionsResolver.ts +++ /dev/null @@ -1,78 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import * as vscodeAdapter from './vscodeAdapter'; -import * as vscode from 'vscode'; -import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; -import { RazorLogger } from './razorLogger'; -import { getCSharpDevKit } from '../../utils/getCSharpDevKit'; - -export function resolveRazorLanguageServerOptions( - vscodeApi: vscodeAdapter.api, - languageServerDir: string, - logger: RazorLogger -) { - const languageServerExecutablePath = findLanguageServerExecutable(languageServerDir); - const serverConfig = vscodeApi.workspace.getConfiguration('razor.languageServer'); - const debugLanguageServer = serverConfig.get('debug'); - const usingOmniSharp = - !getCSharpDevKit() && vscodeApi.workspace.getConfiguration().get('dotnet.server.useOmnisharp'); - - const suppressErrorToasts = serverConfig.get('suppressLspErrorToasts'); - - return { - serverPath: languageServerExecutablePath, - debug: debugLanguageServer, - outputChannel: logger.outputChannel, - usingOmniSharp, - suppressErrorToasts, - } as RazorLanguageServerOptions; -} - -function findLanguageServerExecutable(withinDir: string) { - // On Windows we use the executable, which is "rzls.exe". - // On macOS we use the dll, which is "rzls.dll". - // On everything else we use the executable, which is "rzls". - - const fileName = 'rzls'; - let extension = ''; - - if (isWindows()) { - extension = '.exe'; - } - - if (isMacOS()) { - // Use the DLL on MacOS to work around signing issue tracked by https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1767519/ - extension = '.dll'; - } - - let pathWithExtension = `${fileName}${extension}`; - let fullPath = path.join(withinDir, pathWithExtension); - - if (!fs.existsSync(fullPath)) { - // We might be running a platform neutral vsix which has no executable, instead we run the dll directly. - pathWithExtension = `${fileName}.dll`; - fullPath = path.join(withinDir, pathWithExtension); - } - - if (!fs.existsSync(fullPath)) { - throw new Error( - vscode.l10n.t("Could not find Razor Language Server executable '{0}' within directory", fullPath) - ); - } - - return fullPath; -} - -function isWindows() { - return !!os.platform().match(/^win/); -} - -function isMacOS() { - return os.platform() === 'darwin'; -} diff --git a/src/razor/src/razorLanguageServiceClient.ts b/src/razor/src/razorLanguageServiceClient.ts deleted file mode 100644 index 0fb000df48..0000000000 --- a/src/razor/src/razorLanguageServiceClient.ts +++ /dev/null @@ -1,127 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageServerClient } from './razorLanguageServerClient'; -import { LanguageKind } from './rpc/languageKind'; -import { LanguageQueryRequest } from './rpc/languageQueryRequest'; -import { LanguageQueryResponse } from './rpc/languageQueryResponse'; -import { RazorMapToDocumentRangesRequest } from './rpc/razorMapToDocumentRangesRequest'; -import { RazorMapToDocumentRangesResponse } from './rpc/razorMapToDocumentRangesResponse'; -import { convertRangeFromSerializable, convertRangeToSerializable } from './rpc/serializableRange'; -import { RazorMapSpansParams } from './mapping/razorMapSpansParams'; -import { RazorMapSpansResponse } from './mapping/razorMapSpansResponse'; -import { UriConverter } from '../../lsptoolshost/utils/uriConverter'; -import { RazorDocumentManager } from './document/razorDocumentManager'; -import { RazorMapTextChangesParams } from './mapping/razorMapTextChangesParams'; -import { RazorMapTextChangesResponse } from './mapping/razorMapTextChangesResponse'; -import { RazorMapToDocumentEditsParams } from './mapping/razorMapToDocumentEditsParams'; -import { RazorMapToDocumentEditsResponse } from './mapping/razorMapToDocumentEditsResponse'; - -export class RazorLanguageServiceClient { - constructor( - private readonly serverClient: RazorLanguageServerClient, - private readonly documentManager: RazorDocumentManager - ) {} - - private static readonly MapToDocumentRangesEndpoint = 'razor/mapToDocumentRanges'; - - public async languageQuery(position: vscode.Position, uri: vscode.Uri) { - await this.ensureStarted(); - - const request = new LanguageQueryRequest(position, uri); - const response = await this.serverClient.sendRequest('razor/languageQuery', request); - response.position = new vscode.Position(response.position.line, response.position.character); - return response; - } - - public async mapToDocumentRanges(languageKind: LanguageKind, ranges: vscode.Range[], uri: vscode.Uri) { - await this.ensureStarted(); - - const serializableRanges = []; - for (const range of ranges) { - const serializableRange = convertRangeToSerializable(range); - serializableRanges.push(serializableRange); - } - - const request = new RazorMapToDocumentRangesRequest(languageKind, serializableRanges, uri); - const response = await this.serverClient.sendRequest( - RazorLanguageServiceClient.MapToDocumentRangesEndpoint, - request - ); - const responseRanges = []; - for (const range of response.ranges) { - if (range.start.line >= 0) { - const remappedRange = convertRangeFromSerializable(response.ranges[0]); - responseRanges.push(remappedRange); - } - } - - response.ranges = responseRanges; - return response; - } - - public async mapSpans(params: RazorMapSpansParams): Promise { - const csharpUri = UriConverter.deserialize(params.csharpDocument.uri); - const document = await this.documentManager.getDocumentForCSharpUri(csharpUri); - - if (!document) { - return RazorMapSpansResponse.empty; - } - - const request = new RazorMapToDocumentRangesRequest(LanguageKind.CSharp, params.ranges, document.uri); - const result = await this.serverClient.sendRequest( - RazorLanguageServiceClient.MapToDocumentRangesEndpoint, - request - ); - - if (!result) { - return RazorMapSpansResponse.empty; - } - - return new RazorMapSpansResponse( - result.ranges.map((r) => { - return { - start: { line: r.start.line, character: r.start.character }, - end: { line: r.end.line, character: r.end.character }, - }; - }), - result.spans, - { - uri: UriConverter.serialize(document.uri), - } - ); - } - - async mapTextChanges(params: RazorMapTextChangesParams): Promise { - const csharpUri = UriConverter.deserialize(params.csharpDocument.uri); - const document = await this.documentManager.getDocumentForCSharpUri(csharpUri); - if (!document) { - return RazorMapTextChangesResponse.empty; - } - - const request = new RazorMapToDocumentEditsParams(LanguageKind.CSharp, document.uri, params.textChanges); - const response = await this.serverClient.sendRequest( - 'razor/mapToDocumentEdits', - request - ); - - if (!response) { - return RazorMapTextChangesResponse.empty; - } - - return new RazorMapTextChangesResponse( - { - uri: UriConverter.serialize(document.uri), - }, - response.textChanges - ); - } - - private async ensureStarted() { - // If the server is already started this will instantly return. - await this.serverClient.start(); - } -} diff --git a/src/razor/src/razorLogger.ts b/src/razor/src/razorLogger.ts index a91d849e29..6542866196 100644 --- a/src/razor/src/razorLogger.ts +++ b/src/razor/src/razorLogger.ts @@ -7,7 +7,6 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vscodeAdapter from './vscodeAdapter'; import * as vscode from 'vscode'; -import { RazorLanguageServerClient } from './razorLanguageServerClient'; import { MessageType } from 'vscode-languageserver-protocol'; export class RazorLogger implements vscodeAdapter.Disposable { @@ -16,7 +15,6 @@ export class RazorLogger implements vscodeAdapter.Disposable { public debugEnabled!: boolean; public infoEnabled!: boolean; public readonly outputChannel: vscode.LogOutputChannel; - public languageServerClient: RazorLanguageServerClient | undefined; private readonly onLogEmitter: vscodeAdapter.EventEmitter; @@ -130,12 +128,6 @@ export class RazorLogger implements vscodeAdapter.Disposable { private async updateLogLevelAsync() { this.processTraceLevel(); - - if (this.languageServerClient) { - await this.languageServerClient.sendNotification('razor/updateLogLevel', { - logLevel: this.logLevelForRZLS, - }); - } } private logErrorInternal(message: string, error: Error) { diff --git a/src/razor/src/razorProjectChangeKind.ts b/src/razor/src/razorProjectChangeKind.ts deleted file mode 100644 index fe03e26165..0000000000 --- a/src/razor/src/razorProjectChangeKind.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export enum RazorProjectChangeKind { - added, - removed, - changed, -} diff --git a/src/razor/src/reference/razorReferenceProvider.ts b/src/razor/src/reference/razorReferenceProvider.ts deleted file mode 100644 index d363f77c31..0000000000 --- a/src/razor/src/reference/razorReferenceProvider.ts +++ /dev/null @@ -1,60 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { getRazorDocumentUri, isRazorCSharpFile, isRazorHtmlFile } from '../razorConventions'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { LanguageKind } from '../rpc/languageKind'; -import { MappingHelpers } from '../mapping/mappingHelpers'; - -export class RazorReferenceProvider extends RazorLanguageFeatureBase implements vscode.ReferenceProvider { - public async provideReferences( - document: vscode.TextDocument, - position: vscode.Position, - context: vscode.ReferenceContext, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection || projection.languageKind === LanguageKind.Razor) { - return; - } - - const references = (await vscode.commands.executeCommand( - 'vscode.executeReferenceProvider', - projection.uri, - projection.position - )) as vscode.Location[]; - - const result = new Array(); - for (const reference of references) { - if (projection.languageKind === LanguageKind.Html && isRazorHtmlFile(reference.uri)) { - // Because the line pragmas for html are generated referencing the projected document - // we need to remap their file locations to reference the top level Razor document. - const razorFile = getRazorDocumentUri(reference.uri); - result.push(new vscode.Location(razorFile, reference.range)); - } else if (isRazorCSharpFile(reference.uri)) { - const remappedLocation = await MappingHelpers.remapGeneratedFileLocation( - reference, - this.serviceClient, - this.logger, - token - ); - if (remappedLocation === undefined) { - continue; - } - - result.push(remappedLocation); - } else { - // This means it is one of the following, - // 1. A .cs file - // 2. A .html/.js file - // In both of these cases, we don't need to remap. So accept it as is and move on. - result.push(reference); - } - } - - return result; - } -} diff --git a/src/razor/src/rename/razorRenameProvider.ts b/src/razor/src/rename/razorRenameProvider.ts deleted file mode 100644 index 5c827b8ef1..0000000000 --- a/src/razor/src/rename/razorRenameProvider.ts +++ /dev/null @@ -1,77 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLogger } from '../razorLogger'; -import { LanguageKind } from '../rpc/languageKind'; -import { MappingHelpers } from '../mapping/mappingHelpers'; - -export class RazorRenameProvider extends RazorLanguageFeatureBase implements vscode.RenameProvider { - constructor( - documentSynchronizer: RazorDocumentSynchronizer, - documentManager: RazorDocumentManager, - serviceClient: RazorLanguageServiceClient, - logger: RazorLogger - ) { - super(documentSynchronizer, documentManager, serviceClient, logger); - } - - public async prepareRename( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection || projection.languageKind !== LanguageKind.CSharp) { - // We only support C# renames for now. Reject the rename request. - // Originally we rejected here. However due to how the language - // server client currently works, if we reject here it prevents - // other servers from being able to return a response instead. - // Null is the only return that allows us to handle renaming - // from the Razor language server. - return null; // Promise.reject(l10n.t('Cannot rename this symbol.')); - } - - const range = document.getWordRangeAtPosition(position); - return range; - } - - public async provideRenameEdits( - document: vscode.TextDocument, - position: vscode.Position, - newName: string, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (!projection) { - return; - } - - if (projection.languageKind !== LanguageKind.CSharp) { - // We only support C# renames for now. - return; - } - - const response = await vscode.commands.executeCommand( - 'vscode.executeDocumentRenameProvider', - projection.uri, - projection.position, - newName - ); - - // Re-map the rename location to the original Razor document - const remappedResponse = await MappingHelpers.remapGeneratedFileWorkspaceEdit( - response, - this.serviceClient, - this.logger, - token - ); - return remappedResponse; - } -} diff --git a/src/razor/src/rename/serializableRenameDocument.ts b/src/razor/src/rename/serializableRenameDocument.ts deleted file mode 100644 index 0fc4e42c4b..0000000000 --- a/src/razor/src/rename/serializableRenameDocument.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface SerializableRenameDocument { - kind: 'rename'; - oldUri: string; - newUri: string; - options: { - overwrite: boolean; - ignoreIfExists: boolean; - }; -} diff --git a/src/razor/src/rpc/languageKind.ts b/src/razor/src/rpc/languageKind.ts deleted file mode 100644 index b5179cb467..0000000000 --- a/src/razor/src/rpc/languageKind.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export enum LanguageKind { - CSharp = 1, - Html = 2, - Razor = 3, -} diff --git a/src/razor/src/rpc/languageQueryRequest.ts b/src/razor/src/rpc/languageQueryRequest.ts deleted file mode 100644 index 9e810b0034..0000000000 --- a/src/razor/src/rpc/languageQueryRequest.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export class LanguageQueryRequest { - public readonly uri: string; - - constructor(public readonly position: vscode.Position, uri: vscode.Uri) { - this.uri = uri.toString(); - } -} diff --git a/src/razor/src/rpc/languageQueryResponse.ts b/src/razor/src/rpc/languageQueryResponse.ts deleted file mode 100644 index 8116b36c9b..0000000000 --- a/src/razor/src/rpc/languageQueryResponse.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { LanguageKind } from './languageKind'; - -export interface LanguageQueryResponse { - kind: LanguageKind; - position: vscode.Position; - positionIndex: number; - hostDocumentVersion: number | undefined; -} diff --git a/src/razor/src/rpc/razorMapToDocumentRangesRequest.ts b/src/razor/src/rpc/razorMapToDocumentRangesRequest.ts deleted file mode 100644 index 6d373824b4..0000000000 --- a/src/razor/src/rpc/razorMapToDocumentRangesRequest.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { LanguageKind } from './languageKind'; -import { SerializableRange } from './serializableRange'; - -export class RazorMapToDocumentRangesRequest { - public readonly razorDocumentUri: string; - - constructor( - public readonly kind: LanguageKind, - public readonly projectedRanges: SerializableRange[], - razorDocumentUri: vscode.Uri - ) { - this.razorDocumentUri = razorDocumentUri.toString(); - } -} diff --git a/src/razor/src/rpc/razorMapToDocumentRangesResponse.ts b/src/razor/src/rpc/razorMapToDocumentRangesResponse.ts deleted file mode 100644 index 37ad9e5d73..0000000000 --- a/src/razor/src/rpc/razorMapToDocumentRangesResponse.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { razorTextSpan } from '../dynamicFile/razorTextSpan'; - -export interface RazorMapToDocumentRangesResponse { - ranges: vscode.Range[]; - hostDocumentVersion: number; - spans: razorTextSpan[]; -} diff --git a/src/razor/src/rpc/serializableCreateDocument.ts b/src/razor/src/rpc/serializableCreateDocument.ts deleted file mode 100644 index 323ed20443..0000000000 --- a/src/razor/src/rpc/serializableCreateDocument.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface SerializableCreateDocument { - kind: 'create'; - uri: string; - options: { - overwrite: boolean; - ignoreIfExists: boolean; - }; -} diff --git a/src/razor/src/rpc/serializableDeleteDocument.ts b/src/razor/src/rpc/serializableDeleteDocument.ts deleted file mode 100644 index 03384c345b..0000000000 --- a/src/razor/src/rpc/serializableDeleteDocument.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface SerializableDeleteDocument { - kind: 'delete'; - uri: string; - options: { - recursive: boolean; - ignoreIfNotExists: boolean; - }; -} diff --git a/src/razor/src/rpc/serializableTextDocumentEdit.ts b/src/razor/src/rpc/serializableTextDocumentEdit.ts deleted file mode 100644 index 50aaacda5a..0000000000 --- a/src/razor/src/rpc/serializableTextDocumentEdit.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableTextEdit } from './serializableTextEdit'; - -export interface SerializableTextDocumentEdit { - kind: undefined; - textDocument: { - uri: string; - version: number; - }; - edits: Array; -} diff --git a/src/razor/src/rpc/serializableWorkspaceEdit.ts b/src/razor/src/rpc/serializableWorkspaceEdit.ts deleted file mode 100644 index 1800bf844b..0000000000 --- a/src/razor/src/rpc/serializableWorkspaceEdit.ts +++ /dev/null @@ -1,61 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { SerializableRenameDocument } from '../rename/serializableRenameDocument'; -import { SerializableCreateDocument } from './serializableCreateDocument'; -import { SerializableDeleteDocument } from './serializableDeleteDocument'; -import { SerializableTextDocumentEdit } from './serializableTextDocumentEdit'; -import { convertTextEditFromSerializable, SerializableTextEdit } from './serializableTextEdit'; - -type SerializableDocumentChange = - | SerializableCreateDocument - | SerializableRenameDocument - | SerializableDeleteDocument - | SerializableTextDocumentEdit; - -export interface SerializableWorkspaceEdit { - changes?: { [key: string]: Array }; - documentChanges?: Array; -} - -export function convertWorkspaceEditFromSerializable(data: SerializableWorkspaceEdit): vscode.WorkspaceEdit { - const workspaceEdit = new vscode.WorkspaceEdit(); - - if (Array.isArray(data.documentChanges)) { - for (const documentChange of data.documentChanges) { - if (documentChange.kind === 'create') { - const createDocumentChange = documentChange as SerializableCreateDocument; - workspaceEdit.createFile(vscode.Uri.parse(createDocumentChange.uri), createDocumentChange.options); - } else if (documentChange.kind === 'rename') { - const renameDocumentChange = documentChange as SerializableRenameDocument; - workspaceEdit.renameFile( - vscode.Uri.parse(renameDocumentChange.oldUri), - vscode.Uri.parse(renameDocumentChange.newUri), - renameDocumentChange.options - ); - } else if (documentChange.kind === 'delete') { - const deleteDocumentChange = documentChange as SerializableDeleteDocument; - workspaceEdit.deleteFile(vscode.Uri.parse(deleteDocumentChange.uri), deleteDocumentChange.options); - } else { - const editDocumentChange = documentChange as SerializableTextDocumentEdit; - const changes = editDocumentChange.edits.map(convertTextEditFromSerializable); - workspaceEdit.set(vscode.Uri.parse(editDocumentChange.textDocument.uri), changes); - } - } - } - - if (data.changes !== undefined) { - for (const uri in data.changes) { - if (!Object.prototype.hasOwnProperty.call(data.changes, uri)) { - continue; - } - const changes = data.changes[uri].map(convertTextEditFromSerializable); - workspaceEdit.set(vscode.Uri.parse(uri), changes); - } - } - - return workspaceEdit; -} diff --git a/src/razor/src/rpc/serverTextChange.ts b/src/razor/src/rpc/serverTextChange.ts deleted file mode 100644 index aac1f4d3e1..0000000000 --- a/src/razor/src/rpc/serverTextChange.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServerTextSpan } from './serverTextSpan'; - -export interface ServerTextChange { - readonly newText: string; - readonly span: ServerTextSpan; -} diff --git a/src/razor/src/rpc/serverTextSpan.ts b/src/razor/src/rpc/serverTextSpan.ts deleted file mode 100644 index 3819ecd391..0000000000 --- a/src/razor/src/rpc/serverTextSpan.ts +++ /dev/null @@ -1,9 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface ServerTextSpan { - readonly start: number; - readonly length: number; -} diff --git a/src/razor/src/rpc/updateBufferRequest.ts b/src/razor/src/rpc/updateBufferRequest.ts deleted file mode 100644 index 2bf3ad74ec..0000000000 --- a/src/razor/src/rpc/updateBufferRequest.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServerTextChange } from './serverTextChange'; - -export class UpdateBufferRequest { - constructor( - public readonly hostDocumentVersion: number, - public readonly hostDocumentFilePath: string, - public readonly changes: ServerTextChange[], - public readonly previousWasEmpty: boolean, - public readonly checksum: string, - public readonly checksumAlgorithm: number, - public readonly encodingCodePage: number | null - ) {} -} diff --git a/src/razor/src/semantic/provideSemanticTokensResponse.ts b/src/razor/src/semantic/provideSemanticTokensResponse.ts deleted file mode 100644 index 98488f0549..0000000000 --- a/src/razor/src/semantic/provideSemanticTokensResponse.ts +++ /dev/null @@ -1,9 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export class ProvideSemanticTokensResponse { - // tslint:disable-next-line: variable-name - constructor(public tokens: number[], public hostDocumentSyncVersion: number) {} -} diff --git a/src/razor/src/semantic/semanticTokens.ts b/src/razor/src/semantic/semanticTokens.ts deleted file mode 100644 index f02c145844..0000000000 --- a/src/razor/src/semantic/semanticTokens.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface SemanticTokens { - data: number[]; -} diff --git a/src/razor/src/semantic/semanticTokensRangeHandler.ts b/src/razor/src/semantic/semanticTokensRangeHandler.ts deleted file mode 100644 index f5f251293e..0000000000 --- a/src/razor/src/semantic/semanticTokensRangeHandler.ts +++ /dev/null @@ -1,154 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RequestType } from 'vscode-jsonrpc'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { ProvideSemanticTokensResponse } from './provideSemanticTokensResponse'; -import { SerializableSemanticTokensParams } from './serializableSemanticTokensParams'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLogger } from '../razorLogger'; -import { SerializableRange } from '../rpc/serializableRange'; - -export class SemanticTokensRangeHandler { - private static readonly getSemanticTokensRangeEndpoint = 'razor/provideSemanticTokensRanges'; - private semanticTokensRequestType: RequestType< - SerializableSemanticTokensParams, - ProvideSemanticTokensResponse, - any - > = new RequestType(SemanticTokensRangeHandler.getSemanticTokensRangeEndpoint); - private emptyTokensResponse: number[] = new Array(); - - constructor( - private readonly documentManager: RazorDocumentManager, - private readonly documentSynchronizer: RazorDocumentSynchronizer, - private readonly serverClient: RazorLanguageServerClient, - private readonly logger: RazorLogger - ) {} - - public async register() { - await this.serverClient.onRequestWithParams< - SerializableSemanticTokensParams, - ProvideSemanticTokensResponse, - any - >( - this.semanticTokensRequestType, - async (request: SerializableSemanticTokensParams, token: vscode.CancellationToken) => - this.getSemanticTokens(request, token) - ); - } - - private async getSemanticTokens( - semanticTokensParams: SerializableSemanticTokensParams, - cancellationToken: vscode.CancellationToken - ): Promise { - try { - const razorDocumentUri = vscode.Uri.parse(semanticTokensParams.textDocument.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - if (razorDocument === undefined) { - this.logger.logWarning( - `Could not find Razor document ${razorDocumentUri}; returning semantic tokens information.` - ); - - return new ProvideSemanticTokensResponse( - this.emptyTokensResponse, - semanticTokensParams.requiredHostDocumentVersion - ); - } - - const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri); - const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument( - textDocument, - razorDocument.csharpDocument, - semanticTokensParams.requiredHostDocumentVersion, - cancellationToken - ); - - if (!synchronized) { - return new ProvideSemanticTokensResponse( - this.emptyTokensResponse, - semanticTokensParams.requiredHostDocumentVersion - ); - } - - if (semanticTokensParams.requiredHostDocumentVersion == 1) { - // HACK: Workaround for https://github.com/dotnet/razor/issues/9197 to stop errors from being thrown. - // Sometimes we get asked for semantic tokens on v1, and we have sent a v1 to Roslyn, but its the wrong v1. - // To prevent Roslyn throwing, lets validate the range we're asking about with the generated document they - // would have seen. - const endLine = semanticTokensParams.ranges[0].end.line; - const lineCount = this.countLines(razorDocument.csharpDocument.getContent()); - - if (lineCount < endLine) { - return new ProvideSemanticTokensResponse(this.emptyTokensResponse, -1); - } - } - - // We get multiple ranges in semanticTokensParams.ranges, and we just want to compute one range which encompasses it all - const reducedRange = this.reduceRanges(semanticTokensParams.ranges); - - const tokens = await vscode.commands.executeCommand( - 'vscode.provideDocumentRangeSemanticTokens', - razorDocument.csharpDocument.uri, - reducedRange - ); - - return new ProvideSemanticTokensResponse( - Array.from(tokens.data), - semanticTokensParams.requiredHostDocumentVersion - ); - } catch (error) { - this.logger.logWarning(`${SemanticTokensRangeHandler.getSemanticTokensRangeEndpoint} failed with ${error}`); - } - - return new ProvideSemanticTokensResponse( - this.emptyTokensResponse, - semanticTokensParams.requiredHostDocumentVersion - ); - } - - private reduceRanges(ranges: SerializableRange[]) { - if (!ranges || ranges.length === 0) { - return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }; - } - - // Start with the first range's bounds - let minStart = ranges[0].start; - let maxEnd = ranges[0].end; - - for (const range of ranges) { - const s = range.start; - const e = range.end; - - // Update minStart if this range starts earlier - if (s.line < minStart.line || (s.line === minStart.line && s.character < minStart.character)) { - minStart = s; - } - - // Update maxEnd if this range ends later - if (e.line > maxEnd.line || (e.line === maxEnd.line && e.character > maxEnd.character)) { - maxEnd = e; - } - } - - // Return new SerializableRange composed from the computed bounds - return { - start: { line: minStart.line, character: minStart.character }, - end: { line: maxEnd.line, character: maxEnd.character }, - }; - } - - private countLines(text: string) { - let lineCount = 0; - for (const i of text) { - if (i === '\n') { - lineCount++; - } - } - - return lineCount; - } -} diff --git a/src/razor/src/semantic/serializableSemanticTokensParams.ts b/src/razor/src/semantic/serializableSemanticTokensParams.ts deleted file mode 100644 index 044027b5c4..0000000000 --- a/src/razor/src/semantic/serializableSemanticTokensParams.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableRange } from '../rpc/serializableRange'; -import { SerializableTextDocumentIdentifier } from '../rpc/serializableTextDocumentIdentifier'; - -export interface SerializableSemanticTokensParams { - correlationId: string; - textDocument: SerializableTextDocumentIdentifier; - ranges: SerializableRange[]; - requiredHostDocumentVersion: number; -} diff --git a/src/razor/src/signatureHelp/razorSignatureHelpProvider.ts b/src/razor/src/signatureHelp/razorSignatureHelpProvider.ts deleted file mode 100644 index 34ceed7cee..0000000000 --- a/src/razor/src/signatureHelp/razorSignatureHelpProvider.ts +++ /dev/null @@ -1,25 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; - -export class RazorSignatureHelpProvider extends RazorLanguageFeatureBase implements vscode.SignatureHelpProvider { - public async provideSignatureHelp( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ) { - const projection = await this.getProjection(document, position, token); - if (projection) { - const result = await vscode.commands.executeCommand( - 'vscode.executeSignatureHelpProvider', - projection.uri, - projection.position - ); - return result; - } - } -} diff --git a/src/razor/src/simplify/razorSimplifyMethodHandler.ts b/src/razor/src/simplify/razorSimplifyMethodHandler.ts deleted file mode 100644 index 77bbe9ad2e..0000000000 --- a/src/razor/src/simplify/razorSimplifyMethodHandler.ts +++ /dev/null @@ -1,71 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { RequestType, TextDocumentIdentifier } from 'vscode-languageserver-protocol'; -import { RazorLanguageServerClient } from '../razorLanguageServerClient'; -import { RazorDocumentManager } from '../document/razorDocumentManager'; -import { UriConverter } from '../../../lsptoolshost/utils/uriConverter'; -import { RazorLanguageServiceClient } from '../razorLanguageServiceClient'; -import { RazorLanguageFeatureBase } from '../razorLanguageFeatureBase'; -import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer'; -import { RazorLogger } from '../razorLogger'; -import { SerializableDelegatedSimplifyMethodParams } from './serializableDelegatedSimplifyMethodParams'; -import SerializableSimplifyMethodParams from './serializableSimplifyMethodParams'; -import { TextEdit } from 'vscode-html-languageservice'; -import { roslynSimplifyMethodCommand } from '../../../lsptoolshost/razor/razorCommands'; - -export class RazorSimplifyMethodHandler extends RazorLanguageFeatureBase { - private static readonly razorSimplifyMethodCommand = 'razor/simplifyMethod'; - private simplifyMethodRequestType: RequestType = - new RequestType(RazorSimplifyMethodHandler.razorSimplifyMethodCommand); - - constructor( - documentSynchronizer: RazorDocumentSynchronizer, - protected readonly serverClient: RazorLanguageServerClient, - protected readonly serviceClient: RazorLanguageServiceClient, - protected readonly documentManager: RazorDocumentManager, - protected readonly logger: RazorLogger - ) { - super(documentSynchronizer, documentManager, serviceClient, logger); - } - - public async register() { - await this.serverClient.onRequestWithParams< - SerializableDelegatedSimplifyMethodParams, - TextEdit[] | undefined, - any - >( - this.simplifyMethodRequestType, - async (request: SerializableDelegatedSimplifyMethodParams, token: vscode.CancellationToken) => - this.getSimplifiedMethod(request, token) - ); - } - - private async getSimplifiedMethod( - request: SerializableDelegatedSimplifyMethodParams, - _: vscode.CancellationToken - ): Promise { - if (!this.documentManager.roslynActivated) { - return undefined; - } - - let identifier = request.identifier.textDocumentIdentifier; - if (request.requiresVirtualDocument) { - const razorDocumentUri = vscode.Uri.parse(request.identifier.textDocumentIdentifier.uri, true); - const razorDocument = await this.documentManager.getDocument(razorDocumentUri); - const virtualCSharpUri = razorDocument.csharpDocument.uri; - identifier = TextDocumentIdentifier.create(UriConverter.serialize(virtualCSharpUri)); - } - - const params = new SerializableSimplifyMethodParams(identifier, request.textEdit); - const response: TextEdit[] | undefined = await vscode.commands.executeCommand( - roslynSimplifyMethodCommand, - params - ); - - return response; - } -} diff --git a/src/razor/src/simplify/serializableDelegatedSimplifyMethodParams.ts b/src/razor/src/simplify/serializableDelegatedSimplifyMethodParams.ts deleted file mode 100644 index 54388545c6..0000000000 --- a/src/razor/src/simplify/serializableDelegatedSimplifyMethodParams.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { SerializableTextDocumentIdentifierAndVersion } from './serializableTextDocumentIdentifierAndVersion'; -import { TextEdit } from 'vscode-html-languageservice'; - -export interface SerializableDelegatedSimplifyMethodParams { - identifier: SerializableTextDocumentIdentifierAndVersion; - requiresVirtualDocument: boolean; - textEdit: TextEdit; -} diff --git a/src/razor/src/simplify/serializableSimplifyMethodParams.ts b/src/razor/src/simplify/serializableSimplifyMethodParams.ts deleted file mode 100644 index 8ce1c50860..0000000000 --- a/src/razor/src/simplify/serializableSimplifyMethodParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextEdit } from 'vscode-html-languageservice'; -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -export default class SerializableSimplifyMethodParams { - constructor(public readonly textDocument: TextDocumentIdentifier, public readonly textEdit: TextEdit) {} -} diff --git a/src/razor/src/simplify/serializableTextDocumentIdentifierAndVersion.ts b/src/razor/src/simplify/serializableTextDocumentIdentifierAndVersion.ts deleted file mode 100644 index 68ee99c49b..0000000000 --- a/src/razor/src/simplify/serializableTextDocumentIdentifierAndVersion.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; - -export interface SerializableTextDocumentIdentifierAndVersion { - textDocumentIdentifier: TextDocumentIdentifier; - version: number; -} diff --git a/src/razor/src/telemetryReporter.ts b/src/razor/src/telemetryReporter.ts deleted file mode 100644 index 58bb8cd797..0000000000 --- a/src/razor/src/telemetryReporter.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createTelemetryErrorEvent, createTelemetryEvent, HostEventStream } from './hostEventStream'; -import * as vscode from 'vscode'; - -export class TelemetryReporter { - private readonly razorExtensionActivated = createTelemetryEvent('VSCode.Razor.RazorExtensionActivated'); - private readonly debugLanguageServerEvent = createTelemetryEvent('VSCode.Razor.DebugLanguageServer'); - private readonly workspaceContainsRazorEvent = createTelemetryEvent('VSCode.Razor.WorkspaceContainsRazor'); - private readonly buffersOutOfSyncEvent = createTelemetryEvent('VSCode.Razor.BuffersOutOfSync'); - private reportedWorkspaceContainsRazor = false; - - constructor(private readonly eventStream: HostEventStream) { - // If this telemetry reporter is created it means the rest of the Razor extension world was created. - this.eventStream.post(this.razorExtensionActivated); - } - - public reportTraceLevel(trace: vscode.LogLevel) { - const traceLevelEvent = createTelemetryEvent('VSCode.Razor.TraceLevel', { - trace: vscode.LogLevel[trace], - }); - this.eventStream.post(traceLevelEvent); - } - - public reportBuffersOutOfSync() { - this.eventStream.post(this.buffersOutOfSyncEvent); - } - - public reportErrorOnServerStart(error: unknown) { - let realError; - if (error instanceof Error) { - realError = error; - } else { - realError = Error(String(error)); - } - - this.reportError('VSCode.Razor.ErrorOnServerStart', realError); - } - - public reportErrorOnActivation(error: unknown) { - let realError; - if (error instanceof Error) { - realError = error; - } else { - realError = Error(String(error)); - } - - this.reportError('VSCode.Razor.ErrorOnActivation', realError); - } - - public reportDebugLanguageServer() { - this.eventStream.post(this.debugLanguageServerEvent); - } - - public reportWorkspaceContainsRazor() { - if (this.reportedWorkspaceContainsRazor) { - return; - } - - this.reportedWorkspaceContainsRazor = true; - this.eventStream.post(this.workspaceContainsRazorEvent); - } - - private reportError(eventName: string, error: Error) { - const errorOnActivationEvent = createTelemetryErrorEvent( - eventName, - { - error: JSON.stringify(error), - }, - /*measures*/ undefined, - /*errorProps*/ ['error'] - ); - - this.eventStream.post(errorOnActivationEvent); - } -} diff --git a/src/shared/options.ts b/src/shared/options.ts index 7d3526acb2..15bc6c074b 100644 --- a/src/shared/options.ts +++ b/src/shared/options.ts @@ -87,7 +87,6 @@ export interface LanguageServerOptions { export interface RazorOptions { readonly razorDevMode: boolean; readonly razorPluginPath: string; - readonly razorServerPath: string; } class CommonOptionsImpl implements CommonOptions { @@ -427,9 +426,6 @@ class RazorOptionsImpl implements RazorOptions { public get razorPluginPath() { return readOption('razor.plugin.path', ''); } - public get razorServerPath() { - return readOption('razor.languageServer.directory', ''); - } } export const commonOptions: CommonOptions = new CommonOptionsImpl(); From 3dda4fbf16a3862b533b549c06de12365608eb8a Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 20 Nov 2025 20:45:43 +1100 Subject: [PATCH 08/10] Remove non-cohost tests --- .vscode/launch.json | 36 ------------------------------------ package.json | 1 - tasks/testTasks.ts | 18 +----------------- 3 files changed, 1 insertion(+), 54 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 375f156e8c..d9b513857a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -97,33 +97,6 @@ "preLaunchTask": "packageDev", "internalConsoleOptions": "openOnSessionStart" }, - { - "name": "[Razor] Run Current File Integration Test", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - // Launch VSCode using a specific profile to ensure that user settings are not used. - // This profile must be imported into vscode before running this launch configuration. - // The profile can be found under /test/csharp-test-profile. - "--profile", - "csharp-test-profile", - "${workspaceRoot}/test/razor/razorIntegrationTests/testAssets/RazorApp/.vscode/devkit_RazorApp.code-workspace", - "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/razor/razorIntegrationTests", - "--log", - "ms-dotnettools.csharp:trace" - ], - "env": { - "CODE_EXTENSIONS_PATH": "${workspaceRoot}", - "TEST_FILE_FILTER": "${file}" - }, - "sourceMaps": true, - "outFiles": ["${workspaceRoot}/dist/*.js", "${workspaceRoot}/out/test/**/*.js"], - "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"], - "preLaunchTask": "packageDev", - "internalConsoleOptions": "openOnSessionStart" - }, { "name": "[Razor Cohost] Run Current File Integration Test", "type": "extensionHost", @@ -248,15 +221,6 @@ "args": ["generateOptionsSchema"], "cwd": "${workspaceFolder}" }, - { - "type": "node", - "request": "launch", - "name": "Razor integration tests", - "preLaunchTask": "build", - "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", - "args": ["test:integration:razor"], - "cwd": "${workspaceFolder}" - }, { "type": "node", "request": "launch", diff --git a/package.json b/package.json index 47f6c96b61..022558581a 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "compile:razorTextMate": "npx js-yaml src/razor/syntaxes/aspnetcorerazor.tmLanguage.yml > src/razor/syntaxes/aspnetcorerazor.tmLanguage.json", "test:unit": "npm run compileDev && gulp test:unit", "test:integration:csharp": "npm run packageDev && gulp test:integration:csharp", - "test:integration:razor": "npm run packageDev && gulp test:integration:razor", "test:integration:razor:cohost": "npm run packageDev && gulp test:integration:razor:cohost", "test:integration:devkit": "npm run packageDev && gulp test:integration:devkit", "test:integration:untrusted": "npm run packageDev && gulp test:integration:untrusted", diff --git a/tasks/testTasks.ts b/tasks/testTasks.ts index d6c099c094..39c1d9941e 100644 --- a/tasks/testTasks.ts +++ b/tasks/testTasks.ts @@ -84,17 +84,6 @@ function createIntegrationTestSubTasks() { ); for (const projectName of razorIntegrationTestProjects) { - gulp.task(`test:integration:razor:${projectName}`, async () => - // Run DevKit tests because razor doesn't gracefully handle roslyn restarting - // in tests. DevKit prevents that behavior by handling project restore without - // requiring it. - runDevKitIntegrationTests( - projectName, - path.join('razor', 'razorIntegrationTests'), - `Razor Test Integration ${projectName}` - ) - ); - gulp.task(`test:integration:razor:cohost:${projectName}`, async () => // Register each test again, but as a regular test, which will run with cohosting on runIntegrationTest( @@ -105,11 +94,6 @@ function createIntegrationTestSubTasks() { ); } - gulp.task( - 'test:integration:razor', - gulp.series(razorIntegrationTestProjects.map((projectName) => `test:integration:razor:${projectName}`)) - ); - gulp.task( 'test:integration:razor:cohost', gulp.series(razorIntegrationTestProjects.map((projectName) => `test:integration:razor:cohost:${projectName}`)) @@ -120,7 +104,7 @@ function createIntegrationTestSubTasks() { gulp.series( 'test:integration:csharp', 'test:integration:devkit', - 'test:integration:razor', + 'test:integration:razor:cohost', 'test:integration:untrusted' ) ); From ebe29c69f1a72cfa14200421c5fce8ff454b63df Mon Sep 17 00:00:00 2001 From: David Wengier Date: Thu, 20 Nov 2025 21:31:28 +1100 Subject: [PATCH 09/10] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea716b39f6..214bc833f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876) # 2.103.x +* Remove non-cohosting editor code (PR: [#8810](https://github.com/dotnet/vscode-csharp/pull/8810)) # 2.102.x * Update Roslyn to 5.3.0-2.25568.9 (PR: [#8799](https://github.com/dotnet/vscode-csharp/pull/8799)) From 4a606753c3773812b43ad1c59096529fb864780b Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 21 Nov 2025 07:50:23 +1100 Subject: [PATCH 10/10] Update VSIX baseline expectation --- test/lsptoolshost/artifactTests/vsix.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lsptoolshost/artifactTests/vsix.test.ts b/test/lsptoolshost/artifactTests/vsix.test.ts index 9ae9b66275..6491ee692c 100644 --- a/test/lsptoolshost/artifactTests/vsix.test.ts +++ b/test/lsptoolshost/artifactTests/vsix.test.ts @@ -18,7 +18,7 @@ describe('Vscode VSIX', () => { vsixFiles.forEach((element) => { // We're packaging the platform specific Roslyn server with ready to run in the vsix, so the size should be roughly ~50MB // We also publish the Razor server, which is roughly ~75MB - const sizeInMB = 240; + const sizeInMB = 200; const maximumVsixSizeInBytes = sizeInMB * 1024 * 1024; describe(`Given ${element}`, () => {