зеркало из https://github.com/aspnet/Razor.VSCode.git
Add Project system and completion system infrastructure and services.
- Also re-ordered some control flows to enable future scenarios. - Added a fake foreground thread on the server to re-use a lot of tooling code. - Did a ton of stuff in this commit, too much to put into a commit message. These bits are the basis for everything we'll be doing going forward. ;)
This commit is contained in:
Родитель
ac9875968c
Коммит
10d1797030
|
@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 15.0.26124.0
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2BBB2AB1-2AE4-4306-AA88-FD66A90AA101}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{9AD3190E-86E4-419B-9D57-C6FFEF3A01F6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
build\dependencies.props = build\dependencies.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.LanguageServer", "src\Microsoft.AspNetCore.Razor.LanguageServer\Microsoft.AspNetCore.Razor.LanguageServer.csproj", "{AF5FB0D8-BACD-45DE-B4A2-4CA172DCAEB6}"
|
||||
EndProject
|
||||
|
@ -17,6 +20,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonRpc", "modules\csharp-l
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protocol", "modules\csharp-language-server-protocol\src\Protocol\Protocol.csproj", "{AF14A869-234A-4874-8D97-9B28DDC89B6E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp-language-server-protocol", "csharp-language-server-protocol", "{27AB8254-F634-4D21-AFF1-E078CF3A2009}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed", "src\Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed\Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed.csproj", "{427A5FBB-09EF-49BA-9B00-F3A09892811F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Razor", "Razor", "{3C0D9AB8-562E-4736-A31D-839AF8C9D9FD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor.Workspaces", "modules\Razor\src\Microsoft.CodeAnalysis.Razor.Workspaces\Microsoft.CodeAnalysis.Razor.Workspaces.csproj", "{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Razor", "modules\Razor\src\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj", "{8CFC36F5-61B4-4F56-8311-750C2969B61D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Language", "modules\Razor\src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj", "{487B924C-B52C-44B0-A10C-9CCE95138F14}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -39,15 +54,37 @@ Global
|
|||
{AF14A869-234A-4874-8D97-9B28DDC89B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AF14A869-234A-4874-8D97-9B28DDC89B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AF14A869-234A-4874-8D97-9B28DDC89B6E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{427A5FBB-09EF-49BA-9B00-F3A09892811F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{427A5FBB-09EF-49BA-9B00-F3A09892811F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{427A5FBB-09EF-49BA-9B00-F3A09892811F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{427A5FBB-09EF-49BA-9B00-F3A09892811F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8CFC36F5-61B4-4F56-8311-750C2969B61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8CFC36F5-61B4-4F56-8311-750C2969B61D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8CFC36F5-61B4-4F56-8311-750C2969B61D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8CFC36F5-61B4-4F56-8311-750C2969B61D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{487B924C-B52C-44B0-A10C-9CCE95138F14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{487B924C-B52C-44B0-A10C-9CCE95138F14}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{487B924C-B52C-44B0-A10C-9CCE95138F14}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{487B924C-B52C-44B0-A10C-9CCE95138F14}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{AF5FB0D8-BACD-45DE-B4A2-4CA172DCAEB6} = {2BBB2AB1-2AE4-4306-AA88-FD66A90AA101}
|
||||
{6659F686-E560-416C-9390-17F89C668A8D} = {BEAA2EDB-B257-4B34-9FA3-2AD973914528}
|
||||
{C8CAF4AD-6AD1-4B8C-B1F3-15B0C5632CD9} = {BEAA2EDB-B257-4B34-9FA3-2AD973914528}
|
||||
{AF14A869-234A-4874-8D97-9B28DDC89B6E} = {BEAA2EDB-B257-4B34-9FA3-2AD973914528}
|
||||
{6659F686-E560-416C-9390-17F89C668A8D} = {27AB8254-F634-4D21-AFF1-E078CF3A2009}
|
||||
{C8CAF4AD-6AD1-4B8C-B1F3-15B0C5632CD9} = {27AB8254-F634-4D21-AFF1-E078CF3A2009}
|
||||
{AF14A869-234A-4874-8D97-9B28DDC89B6E} = {27AB8254-F634-4D21-AFF1-E078CF3A2009}
|
||||
{27AB8254-F634-4D21-AFF1-E078CF3A2009} = {BEAA2EDB-B257-4B34-9FA3-2AD973914528}
|
||||
{427A5FBB-09EF-49BA-9B00-F3A09892811F} = {2BBB2AB1-2AE4-4306-AA88-FD66A90AA101}
|
||||
{3C0D9AB8-562E-4736-A31D-839AF8C9D9FD} = {BEAA2EDB-B257-4B34-9FA3-2AD973914528}
|
||||
{A3E388BC-F625-4A6A-AD31-04E8B1DD0D91} = {3C0D9AB8-562E-4736-A31D-839AF8C9D9FD}
|
||||
{8CFC36F5-61B4-4F56-8311-750C2969B61D} = {3C0D9AB8-562E-4736-A31D-839AF8C9D9FD}
|
||||
{487B924C-B52C-44B0-A10C-9CCE95138F14} = {3C0D9AB8-562E-4736-A31D-839AF8C9D9FD}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {ED1782EB-ABE7-4615-80E2-442006DF2826}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview1-17090</InternalAspNetCoreSdkPackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"comments": {
|
||||
"blockComment": [ "<!--", "-->" ]
|
||||
},
|
||||
"brackets": [
|
||||
["<!--", "-->"],
|
||||
["<", ">"],
|
||||
["{", "}"],
|
||||
["(", ")"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
{ "open": "{", "close": "}"},
|
||||
{ "open": "[", "close": "]"},
|
||||
{ "open": "(", "close": ")" },
|
||||
{ "open": "'", "close": "'" },
|
||||
{ "open": "\"", "close": "\"" }
|
||||
],
|
||||
"surroundingPairs": [
|
||||
{ "open": "'", "close": "'" },
|
||||
{ "open": "\"", "close": "\"" },
|
||||
{ "open": "<", "close": ">" }
|
||||
]
|
||||
}
|
|
@ -11,9 +11,65 @@
|
|||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onLanguage:razor"
|
||||
"onLanguage:razorcore"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "extension.showRazorCSharpWindow",
|
||||
"title": "Show Razor CSharp"
|
||||
},
|
||||
{
|
||||
"command": "extension.showRazorHtmlWindow",
|
||||
"title": "Show Razor Html"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "extension.showRazorCSharpWindow",
|
||||
"when": "resourceLangId == razor"
|
||||
},
|
||||
{
|
||||
"command": "extension.showRazorHtmlWindow",
|
||||
"when": "resourceLangId == razor"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "razorcore",
|
||||
"extensions": [
|
||||
".razor"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"title": "Razor Configuration",
|
||||
"properties": {
|
||||
"razor.languageServer.path": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"default": null,
|
||||
"description": "Specifies the path to the Razor LanguageServer. This should be the absolute path to the language server dll."
|
||||
},
|
||||
"razor.languageServer.debug": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Specifies whether to wait for debug attach when launching the language server."
|
||||
},
|
||||
"razor.languageServer.trace": {
|
||||
"type": "string",
|
||||
"default": "Messages",
|
||||
"description": "Specifies whether to output all messages [Verbose], some messages [Messages] or not at all [Off]."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
|
@ -23,9 +79,12 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^2.6.1",
|
||||
"vscode": "^1.1.6",
|
||||
"tslint": "^5.8.0",
|
||||
"@types/node": "^7.0.43",
|
||||
"@types/mocha": "^2.2.42"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode": "^1.1.18",
|
||||
"vscode-languageclient": "^4.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 './CSharpProjectedDocument';
|
||||
import { CSharpProjectedDocumentContentProvider } from './CSharpProjectedDocumentContentProvider';
|
||||
|
||||
export class CSharpPreviewDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
||||
public static readonly scheme: string = CSharpProjectedDocument.scheme + "-preview";
|
||||
public static readonly previewUri: vscode.Uri = vscode.Uri.parse(CSharpPreviewDocumentContentProvider.scheme + "://razor/csharppreview");
|
||||
|
||||
private _onDidChange: vscode.EventEmitter<vscode.Uri>;
|
||||
private _csharpProjectionProvider: CSharpProjectedDocumentContentProvider;
|
||||
|
||||
constructor (csharpContentProvider: CSharpProjectedDocumentContentProvider ) {
|
||||
this._csharpProjectionProvider = csharpContentProvider;
|
||||
this._onDidChange = new vscode.EventEmitter<vscode.Uri>();
|
||||
}
|
||||
|
||||
public get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
public update() {
|
||||
let projectedDocument = this._csharpProjectionProvider.getActiveDocument();
|
||||
|
||||
if (!projectedDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChange.fire(CSharpPreviewDocumentContentProvider.previewUri);
|
||||
}
|
||||
|
||||
public async provideTextDocumentContent(): Promise<string> {
|
||||
let projectedDocument = await this._csharpProjectionProvider.getActiveDocument();
|
||||
|
||||
if (!projectedDocument) {
|
||||
vscode.window.showErrorMessage("For some reason the projected document isn't set.");
|
||||
return "";
|
||||
}
|
||||
|
||||
let projectedUriPath = projectedDocument.projectedUri.path;
|
||||
let document = vscode.workspace.textDocuments.find((doc) => {
|
||||
if (doc.uri.path.localeCompare(projectedUriPath, undefined, { sensitivity: 'base' }) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (document) {
|
||||
let content = document.getText();
|
||||
let htmlContent = `
|
||||
<body>
|
||||
<p>For host document: <strong>${projectedDocument.hostDocumentUri.path}</strong></p>
|
||||
<hr />
|
||||
<pre>${content}</pre>
|
||||
<hr />
|
||||
</body>`;
|
||||
|
||||
return htmlContent;
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public async showRazorCSharpWindow(): Promise<void> {
|
||||
let activeProjectedDocument = this._csharpProjectionProvider.getActiveDocument();
|
||||
|
||||
if (!activeProjectedDocument) {
|
||||
vscode.window.showErrorMessage("No active text editor.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await vscode.commands.executeCommand('vscode.previewHtml', CSharpPreviewDocumentContentProvider.previewUri, vscode.ViewColumn.Two, 'Razor CSharp Output');
|
||||
}
|
||||
catch (error) {
|
||||
vscode.window.showErrorMessage(error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 CSharpProjectedDocument {
|
||||
public static readonly scheme: string = "razor-csharp";
|
||||
|
||||
private _projectedUri : vscode.Uri;
|
||||
private _hostDocumentUri : vscode.Uri;
|
||||
|
||||
private constructor (projectedUri: vscode.Uri, hostDocumentUri: vscode.Uri) {
|
||||
this._projectedUri = projectedUri;
|
||||
this._hostDocumentUri = hostDocumentUri;
|
||||
}
|
||||
|
||||
public get projectedUri() : vscode.Uri { return this._projectedUri; }
|
||||
|
||||
public get hostDocumentUri() : vscode.Uri { return this._hostDocumentUri; }
|
||||
|
||||
public static create(hostDocumentUri: vscode.Uri): CSharpProjectedDocument {
|
||||
let extensionlessPath = hostDocumentUri.path.substring(0, hostDocumentUri.path.length - 6);
|
||||
let transformedPath = extensionlessPath + ".cs";
|
||||
let projectedUri = vscode.Uri.parse(this.scheme + "://" + transformedPath);
|
||||
|
||||
return new CSharpProjectedDocument(projectedUri, hostDocumentUri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 './CSharpProjectedDocument';
|
||||
|
||||
export class CSharpProjectedDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
||||
private _onDidChange: vscode.EventEmitter<vscode.Uri>;
|
||||
private _projectedDocuments: { [hostDocumentPath: string]: CSharpProjectedDocument };
|
||||
|
||||
constructor () {
|
||||
this._onDidChange = new vscode.EventEmitter<vscode.Uri>();
|
||||
this._projectedDocuments = {};
|
||||
}
|
||||
|
||||
public get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
public update(uri: vscode.Uri) {
|
||||
this.ensureProjectedDocument(uri).then((projectedDocument) => {
|
||||
this._onDidChange.fire(projectedDocument.projectedUri);
|
||||
},
|
||||
(reason) => {
|
||||
vscode.window.showErrorMessage("For some reason we failed to open the projected document: " + reason);
|
||||
});
|
||||
}
|
||||
|
||||
public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult<string> {
|
||||
let projectedDocument: CSharpProjectedDocument | undefined;
|
||||
for (let hostDocumentPath in this._projectedDocuments) {
|
||||
let document = this._projectedDocuments[hostDocumentPath];
|
||||
|
||||
if (document.projectedUri.path.localeCompare(uri.path, undefined, { sensitivity: 'base' }) === 0) {
|
||||
projectedDocument = document;
|
||||
}
|
||||
}
|
||||
|
||||
if (!projectedDocument) {
|
||||
vscode.window.showErrorMessage("For some reason the projected document isn't set.");
|
||||
return;
|
||||
}
|
||||
|
||||
let hostDocumentUriPath = projectedDocument.hostDocumentUri.path;
|
||||
let hostDocument = vscode.workspace.textDocuments.find((doc) => {
|
||||
if (doc.uri.path.localeCompare(hostDocumentUriPath, undefined, { sensitivity: 'base' }) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
var content = "// " + uri + "\r\n";
|
||||
|
||||
if (hostDocument) {
|
||||
content += "\r\n" + hostDocument.getText() + "\r\n";
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
private async ensureProjectedDocument(hostDocumentUri: vscode.Uri): Promise<CSharpProjectedDocument> {
|
||||
let projectedDocument = this._projectedDocuments[hostDocumentUri.path];
|
||||
|
||||
if (!projectedDocument) {
|
||||
projectedDocument = CSharpProjectedDocument.create(hostDocumentUri);
|
||||
this._projectedDocuments[hostDocumentUri.path] = projectedDocument;
|
||||
}
|
||||
|
||||
await vscode.workspace.openTextDocument(projectedDocument.projectedUri);
|
||||
return projectedDocument;
|
||||
}
|
||||
|
||||
public getDocument(hostDocumentUri: vscode.Uri): Promise<CSharpProjectedDocument> {
|
||||
return this.ensureProjectedDocument(hostDocumentUri);
|
||||
}
|
||||
|
||||
public async getActiveDocument(): Promise<CSharpProjectedDocument> {
|
||||
if (!vscode.window.activeTextEditor) {
|
||||
throw new Error("No active text document");
|
||||
}
|
||||
|
||||
let projectedDocument = await this.ensureProjectedDocument(vscode.window.activeTextEditor.document.uri);
|
||||
|
||||
return projectedDocument;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 './CSharpProjectedDocumentContentProvider';
|
||||
import { CSharpProjectedDocument } from './CSharpProjectedDocument';
|
||||
import { CSharpPreviewDocumentContentProvider } from './CSharpPreviewDocumentContentProvider';
|
||||
|
||||
export class RazorCSharpFeature {
|
||||
private _projectionProvider: CSharpProjectedDocumentContentProvider;
|
||||
private _previewProvider: CSharpPreviewDocumentContentProvider;
|
||||
|
||||
constructor() {
|
||||
|
||||
this._projectionProvider = new CSharpProjectedDocumentContentProvider();
|
||||
this._previewProvider = new CSharpPreviewDocumentContentProvider(this._projectionProvider);
|
||||
}
|
||||
|
||||
public get ProjectionProvider() : CSharpProjectedDocumentContentProvider {
|
||||
return this._projectionProvider;
|
||||
}
|
||||
|
||||
public get PreviewProvider() : CSharpPreviewDocumentContentProvider {
|
||||
return this._previewProvider;
|
||||
}
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
let activeProjectedDocument = await this._projectionProvider.getActiveDocument();
|
||||
|
||||
this.updateDocument(activeProjectedDocument.hostDocumentUri);
|
||||
}
|
||||
|
||||
public updateDocument(documentUri: vscode.Uri): void {
|
||||
this._projectionProvider.update(documentUri);
|
||||
this._previewProvider.update();
|
||||
}
|
||||
|
||||
public register(): vscode.Disposable {
|
||||
let registrations: vscode.Disposable[] = [];
|
||||
|
||||
registrations.push(vscode.workspace.registerTextDocumentContentProvider(CSharpProjectedDocument.scheme, this._projectionProvider));
|
||||
registrations.push(vscode.workspace.registerTextDocumentContentProvider(CSharpPreviewDocumentContentProvider.scheme, this._previewProvider));
|
||||
registrations.push(vscode.commands.registerCommand('extension.showRazorCSharpWindow', () => this._previewProvider.showRazorCSharpWindow()));
|
||||
|
||||
let disposable = vscode.Disposable.from(...registrations);
|
||||
return disposable;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { HtmlProjectedDocument } from './HtmlProjectedDocument';
|
||||
import { HtmlProjectedDocumentContentProvider } from './HtmlProjectedDocumentContentProvider';
|
||||
|
||||
export class HtmlPreviewDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
||||
public static readonly scheme: string = HtmlProjectedDocument.scheme + "-preview";
|
||||
public static readonly previewUri: vscode.Uri = vscode.Uri.parse(HtmlPreviewDocumentContentProvider.scheme + "://razor/Htmlpreview");
|
||||
|
||||
private _onDidChange: vscode.EventEmitter<vscode.Uri>;
|
||||
private _htmlProjectionProvider: HtmlProjectedDocumentContentProvider;
|
||||
|
||||
constructor (HtmlContentProvider: HtmlProjectedDocumentContentProvider ) {
|
||||
this._htmlProjectionProvider = HtmlContentProvider;
|
||||
this._onDidChange = new vscode.EventEmitter<vscode.Uri>();
|
||||
}
|
||||
|
||||
public get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
public update() {
|
||||
let projectedDocument = this._htmlProjectionProvider.getActiveDocument();
|
||||
|
||||
if (!projectedDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChange.fire(HtmlPreviewDocumentContentProvider.previewUri);
|
||||
}
|
||||
|
||||
public async provideTextDocumentContent(): Promise<string> {
|
||||
let projectedDocument = await this._htmlProjectionProvider.getActiveDocument();
|
||||
let projectedUriPath = projectedDocument.projectedUri.path;
|
||||
let document = vscode.workspace.textDocuments.find((doc) => {
|
||||
if (doc.uri.path.localeCompare(projectedUriPath, undefined, { sensitivity: 'base' }) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (document) {
|
||||
let content = document.getText();
|
||||
let htmlContent = `
|
||||
<body>
|
||||
<p>For host document: <strong>${projectedDocument.hostDocumentUri.path}</strong></p>
|
||||
<hr />
|
||||
<pre>
|
||||
${content}
|
||||
</pre>
|
||||
<hr />
|
||||
</body>`;
|
||||
|
||||
return htmlContent;
|
||||
}
|
||||
else {
|
||||
return "<body>No content...</body>";
|
||||
}
|
||||
}
|
||||
|
||||
public async showRazorHtmlWindow(): Promise<void> {
|
||||
let activeProjectedDocument = this._htmlProjectionProvider.getActiveDocument();
|
||||
|
||||
if (!activeProjectedDocument) {
|
||||
vscode.window.showErrorMessage("No active text editor.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await vscode.commands.executeCommand('vscode.previewHtml', HtmlPreviewDocumentContentProvider.previewUri, vscode.ViewColumn.Two, 'Razor Html Output');
|
||||
}
|
||||
catch (error) {
|
||||
vscode.window.showErrorMessage(error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 HtmlProjectedDocument {
|
||||
public static readonly scheme: string = "razor-html";
|
||||
|
||||
private _projectedUri : vscode.Uri;
|
||||
private _hostDocumentUri : vscode.Uri;
|
||||
|
||||
private constructor (projectedUri: vscode.Uri, hostDocumentUri: vscode.Uri) {
|
||||
this._projectedUri = projectedUri;
|
||||
this._hostDocumentUri = hostDocumentUri;
|
||||
}
|
||||
|
||||
public get projectedUri() : vscode.Uri { return this._projectedUri; }
|
||||
|
||||
public get hostDocumentUri() : vscode.Uri { return this._hostDocumentUri; }
|
||||
|
||||
public static create(hostDocumentUri: vscode.Uri): HtmlProjectedDocument {
|
||||
let extensionlessPath = hostDocumentUri.path.substring(0, hostDocumentUri.path.length - 6);
|
||||
let transformedPath = extensionlessPath + ".html";
|
||||
let projectedUri = vscode.Uri.parse(this.scheme + "://" + transformedPath);
|
||||
|
||||
return new HtmlProjectedDocument(projectedUri, hostDocumentUri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { HtmlProjectedDocument } from './HtmlProjectedDocument';
|
||||
|
||||
export class HtmlProjectedDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
||||
private _onDidChange: vscode.EventEmitter<vscode.Uri>;
|
||||
private _projectedDocuments: { [hostDocumentPath: string]: HtmlProjectedDocument };
|
||||
|
||||
constructor () {
|
||||
this._onDidChange = new vscode.EventEmitter<vscode.Uri>();
|
||||
this._projectedDocuments = {};
|
||||
}
|
||||
|
||||
public get onDidChange(): vscode.Event<vscode.Uri> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
public update(uri: vscode.Uri) {
|
||||
this.ensureProjectedDocument(uri).then((projectedDocument) => {
|
||||
this._onDidChange.fire(projectedDocument.projectedUri);
|
||||
},
|
||||
(reason) => {
|
||||
vscode.window.showErrorMessage("For some reason we failed to open the projected HTML document: " + reason);
|
||||
});
|
||||
}
|
||||
|
||||
public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult<string> {
|
||||
let projectedDocument: HtmlProjectedDocument | undefined;
|
||||
for (let hostDocumentPath in this._projectedDocuments) {
|
||||
let document = this._projectedDocuments[hostDocumentPath];
|
||||
|
||||
if (document.projectedUri.path.localeCompare(uri.path, undefined, { sensitivity: 'base' }) === 0) {
|
||||
projectedDocument = document;
|
||||
}
|
||||
}
|
||||
|
||||
if (!projectedDocument) {
|
||||
vscode.window.showErrorMessage("For some reason the projected html document isn't set.");
|
||||
return;
|
||||
}
|
||||
|
||||
let hostDocumentUriPath = projectedDocument.hostDocumentUri.path;
|
||||
let hostDocument = vscode.workspace.textDocuments.find((doc) => {
|
||||
if (doc.uri.path.localeCompare(hostDocumentUriPath, undefined, { sensitivity: 'base' }) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
let content = "";
|
||||
|
||||
if (hostDocument) {
|
||||
content = hostDocument.getText();
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
private async ensureProjectedDocument(hostDocumentUri: vscode.Uri): Promise<HtmlProjectedDocument> {
|
||||
let projectedDocument = this._projectedDocuments[hostDocumentUri.path];
|
||||
|
||||
if (!projectedDocument) {
|
||||
projectedDocument = HtmlProjectedDocument.create(hostDocumentUri);
|
||||
this._projectedDocuments[hostDocumentUri.path] = projectedDocument;
|
||||
}
|
||||
|
||||
await vscode.workspace.openTextDocument(projectedDocument.projectedUri);
|
||||
|
||||
return projectedDocument;
|
||||
}
|
||||
|
||||
public getDocument(hostDocumentUri: vscode.Uri): Promise<HtmlProjectedDocument> {
|
||||
return this.ensureProjectedDocument(hostDocumentUri);
|
||||
}
|
||||
|
||||
public async getActiveDocument(): Promise<HtmlProjectedDocument> {
|
||||
if (!vscode.window.activeTextEditor) {
|
||||
throw new Error("No active text document");
|
||||
}
|
||||
|
||||
let projectedDocument = await this.ensureProjectedDocument(vscode.window.activeTextEditor.document.uri);
|
||||
|
||||
return projectedDocument;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { HtmlProjectedDocumentContentProvider } from './HtmlProjectedDocumentContentProvider';
|
||||
import { HtmlPreviewDocumentContentProvider } from './HtmlPreviewDocumentContentProvider';
|
||||
import { HtmlProjectedDocument } from './HtmlProjectedDocument';
|
||||
|
||||
export class RazorHtmlFeature {
|
||||
private _projectionProvider: HtmlProjectedDocumentContentProvider;
|
||||
private _previewProvider: HtmlPreviewDocumentContentProvider;
|
||||
|
||||
constructor() {
|
||||
|
||||
this._projectionProvider = new HtmlProjectedDocumentContentProvider();
|
||||
this._previewProvider = new HtmlPreviewDocumentContentProvider(this._projectionProvider);
|
||||
}
|
||||
|
||||
public get ProjectionProvider() : HtmlProjectedDocumentContentProvider {
|
||||
return this._projectionProvider;
|
||||
}
|
||||
|
||||
public get PreviewProvider() : HtmlPreviewDocumentContentProvider {
|
||||
return this._previewProvider;
|
||||
}
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
let activeProjectedDocument = await this._projectionProvider.getActiveDocument();
|
||||
|
||||
this.updateDocument(activeProjectedDocument.hostDocumentUri);
|
||||
}
|
||||
|
||||
public updateDocument(documentUri: vscode.Uri): void {
|
||||
this._projectionProvider.update(documentUri);
|
||||
this._previewProvider.update();
|
||||
}
|
||||
|
||||
public register(): vscode.Disposable {
|
||||
let registrations: vscode.Disposable[] = [];
|
||||
|
||||
registrations.push(vscode.workspace.registerTextDocumentContentProvider(HtmlProjectedDocument.scheme, this._projectionProvider));
|
||||
registrations.push(vscode.workspace.registerTextDocumentContentProvider(HtmlPreviewDocumentContentProvider.scheme, this._previewProvider));
|
||||
registrations.push(vscode.commands.registerCommand('extension.showRazorHtmlWindow', () => this._previewProvider.showRazorHtmlWindow()));
|
||||
|
||||
let disposable = vscode.Disposable.from(...registrations);
|
||||
return disposable;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
export class AddProjectRequest {
|
||||
constructor (filePath: string, configurationName: string) {
|
||||
this.filePath = filePath;
|
||||
this.configurationName = configurationName;
|
||||
}
|
||||
|
||||
public readonly filePath: string;
|
||||
public readonly configurationName: string;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 {
|
||||
constructor (hostDocumentUri: vscode.Uri, projectedCSharpDocumentUri: vscode.Uri, position: vscode.Position) {
|
||||
this.hostDocumentUri = hostDocumentUri.path;
|
||||
this.projectedCSharpDocumentUri = projectedCSharpDocumentUri.path;
|
||||
this.hostDocumentPosition = position;
|
||||
}
|
||||
|
||||
public readonly hostDocumentUri: string;
|
||||
public readonly projectedCSharpDocumentUri: string;
|
||||
public readonly hostDocumentPosition: vscode.Position;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 LanguageQueryResponse {
|
||||
constructor (textDocumentUri: vscode.Uri, position: vscode.Position) {
|
||||
this.textDocumentUri = textDocumentUri.path;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public readonly textDocumentUri: string;
|
||||
public readonly position: vscode.Position;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { RazorCSharpFeature } from './CSharp/RazorCSharpFeature';
|
||||
import { RazorHtmlFeature } from './Html/RazorHtmlFeature';
|
||||
|
||||
export class RazorCompletionItemProvider implements vscode.CompletionItemProvider {
|
||||
private _csharpFeature: RazorCSharpFeature;
|
||||
private _htmlFeature: RazorHtmlFeature;
|
||||
|
||||
constructor(csharpFeature: RazorCSharpFeature, htmlFeature: RazorHtmlFeature) {
|
||||
this._csharpFeature = csharpFeature;
|
||||
this._htmlFeature = htmlFeature;
|
||||
}
|
||||
|
||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList> {
|
||||
let projectedDocument = await this._htmlFeature.ProjectionProvider.getDocument(document.uri);
|
||||
let completionList = await vscode.commands.executeCommand<vscode.CompletionList | vscode.CompletionItem[]>(
|
||||
"vscode.executeCompletionItemProvider",
|
||||
projectedDocument.projectedUri,
|
||||
position,
|
||||
context.triggerCharacter);
|
||||
|
||||
if (!completionList) {
|
||||
completionList = {
|
||||
isIncomplete: true,
|
||||
items: []
|
||||
};
|
||||
}
|
||||
|
||||
return completionList;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { LanguageClient } from 'vscode-languageclient/lib/main';
|
||||
// import { RazorLanguage } from './RazorLanguage';
|
||||
|
||||
// class RazorDocumentTracker implements vscode.Disposable {
|
||||
// private _client: LanguageClient;
|
||||
|
||||
// constructor(client: LanguageClient) {
|
||||
// this._client = client;
|
||||
|
||||
// }
|
||||
|
||||
// public dispose(): void {
|
||||
// }
|
||||
|
||||
// private async trackCurrentDocumentsAsync() {
|
||||
// for (let i = 0; i < vscode.workspace.textDocuments.length; i++) {
|
||||
// let document = vscode.workspace.textDocuments[i];
|
||||
|
||||
// if (this.isRazorDocument(document)) {
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private trackFutureDocuments() {
|
||||
// }
|
||||
|
||||
// private isRazorDocument(document: vscode.TextDocument): boolean {
|
||||
// if (document.languageId === RazorLanguage.id) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function trackRazorDocuments(client: LanguageClient): vscode.Disposable {
|
||||
// let documentTracker = new RazorDocumentTracker(client);
|
||||
|
||||
// return documentTracker;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// var projectUris = await vscode.workspace.findFiles("**/*.csproj");
|
||||
|
||||
// for (let i = 0; i < projectUris.length; i++) {
|
||||
// let request = new AddProjectRequest(projectUris[i].fsPath, "MVC-2.0");
|
||||
// await client.sendRequest<AddProjectRequest>("projects/addProject", request);
|
||||
// }
|
|
@ -0,0 +1,13 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 RazorLanguage {
|
||||
public static id: string = "razorcore";
|
||||
public static documentSelector: vscode.DocumentSelector = [ { pattern: '**/*.razor' } ];
|
||||
public static languageConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration('razor');
|
||||
public static serverConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration('razor.languageServer');
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/lib/main';
|
||||
import { RazorLanguage } from './RazorLanguage';
|
||||
import { RazorLanguageServerOptions } from './RazorLanguageServerOptions';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
export class RazorLanguageServerClient implements vscode.Disposable {
|
||||
private static Events =
|
||||
{
|
||||
ServerStart: "ServerStart",
|
||||
ServerStop: "ServerStop"
|
||||
};
|
||||
|
||||
private _clientOptions: LanguageClientOptions;
|
||||
private _serverOptions: ServerOptions;
|
||||
private _client: LanguageClient;
|
||||
private _startDisposable: vscode.Disposable | undefined;
|
||||
private _eventBus: EventEmitter;
|
||||
|
||||
constructor(options: RazorLanguageServerOptions) {
|
||||
this._clientOptions = {
|
||||
documentSelector: <any>RazorLanguage.documentSelector, // No idea why I need to cast here.
|
||||
outputChannel: options.outputChannel
|
||||
};
|
||||
|
||||
// TODO: Resolve dotnet path or self-host server executable
|
||||
let args = [options.serverDllPath, '-lsp'];
|
||||
|
||||
if (options.debug) {
|
||||
args[2] = "--debug";
|
||||
}
|
||||
|
||||
this._serverOptions = {
|
||||
run: { command: 'dotnet', args: args },
|
||||
debug: { command: 'dotnet', args: args }
|
||||
};
|
||||
|
||||
this._client = new LanguageClient('razorLanguageServer', 'Razor Language Server', this._serverOptions, this._clientOptions);
|
||||
this._eventBus = new EventEmitter();
|
||||
}
|
||||
|
||||
public onStart(listener: () => any): vscode.Disposable {
|
||||
this._eventBus.addListener(RazorLanguageServerClient.Events.ServerStart, listener);
|
||||
|
||||
let disposable = new vscode.Disposable(() => this._eventBus.removeListener(RazorLanguageServerClient.Events.ServerStart, listener));
|
||||
return disposable;
|
||||
}
|
||||
|
||||
public onStop(listener: () => any): vscode.Disposable {
|
||||
this._eventBus.addListener(RazorLanguageServerClient.Events.ServerStop, listener);
|
||||
|
||||
let disposable = new vscode.Disposable(() => this._eventBus.removeListener(RazorLanguageServerClient.Events.ServerStop, listener));
|
||||
return disposable;
|
||||
}
|
||||
|
||||
public async start(): Promise<void> {
|
||||
this._startDisposable = await this._client.start();
|
||||
await this._client.onReady();
|
||||
|
||||
this._eventBus.emit(RazorLanguageServerClient.Events.ServerStart);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._startDisposable) {
|
||||
this._startDisposable.dispose();
|
||||
}
|
||||
|
||||
this._eventBus.emit(RazorLanguageServerClient.Events.ServerStop);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { Trace } from 'vscode-jsonrpc';
|
||||
|
||||
export interface RazorLanguageServerOptions {
|
||||
serverDllPath: string;
|
||||
outputChannel?: vscode.OutputChannel;
|
||||
debug?: boolean;
|
||||
trace?: Trace;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { Trace } from 'vscode-jsonrpc';
|
||||
import { RazorLanguage } from './RazorLanguage';
|
||||
import { RazorLanguageServerOptions } from './RazorLanguageServerOptions';
|
||||
|
||||
export function resolveRazorLanguageServerOptions(): RazorLanguageServerOptions {
|
||||
let languageServerDllPath = RazorLanguage.serverConfig.get<string>("path");
|
||||
|
||||
if (!languageServerDllPath) {
|
||||
throw new Error("Razor VSCode extension does not currently support dynamic resolution of language server.");
|
||||
}
|
||||
|
||||
let debugLanguageServer = RazorLanguage.serverConfig.get<boolean>("debug");
|
||||
let outputChannel = vscode.window.createOutputChannel("Razor Language Server");
|
||||
let traceString = RazorLanguage.serverConfig.get<string>("trace");
|
||||
let trace: Trace;
|
||||
|
||||
if (traceString === "Off") {
|
||||
trace = Trace.Off;
|
||||
}
|
||||
else if (traceString === "Messages") {
|
||||
trace = Trace.Messages;
|
||||
}
|
||||
else if (traceString === "Verbose") {
|
||||
trace = Trace.Verbose;
|
||||
}
|
||||
else {
|
||||
console.log("Invalid trace settign for Razor language server. Defaulting to 'Off'");
|
||||
trace = Trace.Off;
|
||||
}
|
||||
|
||||
let options: RazorLanguageServerOptions = {
|
||||
serverDllPath: languageServerDllPath,
|
||||
debug: debugLanguageServer,
|
||||
outputChannel: outputChannel,
|
||||
trace: trace
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
|
@ -1,37 +1,47 @@
|
|||
'use strict';
|
||||
// The module 'vscode' contains the VS Code extensibility API
|
||||
// Import the module and reference it with the alias vscode in your code below
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* 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 { ExtensionContext } from 'vscode';
|
||||
import { RazorLanguage } from './RazorLanguage';
|
||||
import { resolveRazorLanguageServerOptions } from './RazorLanguageServerOptionsResolver';
|
||||
import { RazorLanguageServerClient } from './RazorLanguageServerClient';
|
||||
import { RazorCSharpFeature } from './CSharp/RazorCSharpFeature';
|
||||
import { RazorHtmlFeature } from './Html/RazorHtmlFeature';
|
||||
import { RazorCompletionItemProvider } from './RazorCompletionItemProvider';
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: ExtensionContext) {
|
||||
let languageServerOptions = resolveRazorLanguageServerOptions();
|
||||
let languageServerClient = new RazorLanguageServerClient(languageServerOptions);
|
||||
let csharpFeature = new RazorCSharpFeature();
|
||||
let htmlFeature = new RazorHtmlFeature();
|
||||
let localRegistrations: vscode.Disposable[] = [];
|
||||
|
||||
// Use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// This line of code will only be executed once when your extension is activated
|
||||
console.log('Congratulations, your extension "helloworld" is now active!');
|
||||
let onStartRegistration = languageServerClient.onStart(() => {
|
||||
localRegistrations.push(vscode.languages.registerCompletionItemProvider(RazorLanguage.id, new RazorCompletionItemProvider(csharpFeature, htmlFeature)));
|
||||
localRegistrations.push(csharpFeature.register());
|
||||
localRegistrations.push(htmlFeature.register());
|
||||
|
||||
// The command has been defined in the package.json file
|
||||
// Now provide the implementation of the command with registerCommand
|
||||
// The commandId parameter must match the command field in package.json
|
||||
let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
|
||||
// The code you place here will be executed every time your command is executed
|
||||
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return; // No open text editor
|
||||
}
|
||||
|
||||
let selection = editor.selection;
|
||||
let text = editor.document.getText(selection);
|
||||
|
||||
// Display a message box to the user
|
||||
vscode.window.showInformationMessage('Selected characters: ' + text.length);
|
||||
localRegistrations.push(vscode.workspace.onDidChangeTextDocument((args: vscode.TextDocumentChangeEvent) => {
|
||||
if (vscode.window.activeTextEditor && args.document === vscode.window.activeTextEditor.document) {
|
||||
csharpFeature.updateDocument(args.document.uri);
|
||||
htmlFeature.updateDocument(args.document.uri);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
let onStopRegistration = languageServerClient.onStop(() => {
|
||||
for (let i = 0; i < localRegistrations.length; i++) {
|
||||
localRegistrations[i].dispose();
|
||||
}
|
||||
localRegistrations.length = 0;
|
||||
});
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() {
|
||||
await languageServerClient.start();
|
||||
await csharpFeature.initialize();
|
||||
await htmlFeature.initialize();
|
||||
|
||||
context.subscriptions.push(languageServerClient, onStartRegistration, onStopRegistration);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 94a131414627d4eda52d1ffd6649277134f906a3
|
|
@ -1 +1 @@
|
|||
Subproject commit d3468c2380f9a2b364d658b68107238eaaf7ecf7
|
||||
Subproject commit a5cdb62fd5714e778b90241656d0786180b26c5c
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultDocumentSnapshotShim : DocumentSnapshotShim
|
||||
{
|
||||
private readonly DocumentSnapshot _snapshot;
|
||||
|
||||
public DefaultDocumentSnapshotShim(DocumentSnapshot snapshot)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
}
|
||||
|
||||
public override string FilePath => _snapshot.FilePath;
|
||||
|
||||
public override string TargetPath => _snapshot.TargetPath;
|
||||
|
||||
public override Task<RazorCodeDocument> GetGeneratedOutputAsync() => _snapshot.GetGeneratedOutputAsync();
|
||||
|
||||
public override IReadOnlyList<DocumentSnapshotShim> GetImports()
|
||||
{
|
||||
var imports = new List<DocumentSnapshotShim>();
|
||||
var innerImports = _snapshot.GetImports();
|
||||
|
||||
for (var i = 0; i < innerImports.Count; i++)
|
||||
{
|
||||
imports.Add(new DefaultDocumentSnapshotShim(innerImports[i]));
|
||||
}
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
public override Task<SourceText> GetTextAsync() => _snapshot.GetTextAsync();
|
||||
|
||||
public override Task<VersionStamp> GetTextVersionAsync() => _snapshot.GetTextVersionAsync();
|
||||
|
||||
public override bool TryGetGeneratedOutput(out RazorCodeDocument result) => _snapshot.TryGetGeneratedOutput(out result);
|
||||
|
||||
public override bool TryGetText(out SourceText result) => _snapshot.TryGetText(out result);
|
||||
|
||||
public override bool TryGetTextVersion(out VersionStamp result) => _snapshot.TryGetTextVersion(out result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultForegroundDispatcherShim : ForegroundDispatcherShim
|
||||
{
|
||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||
|
||||
public DefaultForegroundDispatcherShim(ForegroundDispatcher foregroundDispatcher)
|
||||
{
|
||||
if (foregroundDispatcher == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||
}
|
||||
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
}
|
||||
|
||||
public override bool IsForegroundThread => _foregroundDispatcher.IsForegroundThread;
|
||||
|
||||
public override TaskScheduler ForegroundScheduler => _foregroundDispatcher.ForegroundScheduler;
|
||||
|
||||
public override TaskScheduler BackgroundScheduler => _foregroundDispatcher.BackgroundScheduler;
|
||||
|
||||
public override void AssertForegroundThread([CallerMemberName] string caller = null) => _foregroundDispatcher.AssertForegroundThread(caller);
|
||||
|
||||
public override void AssertBackgroundThread([CallerMemberName] string caller = null) => _foregroundDispatcher.AssertBackgroundThread(caller);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultHostDocumentShim : HostDocumentShim
|
||||
{
|
||||
public DefaultHostDocumentShim(HostDocument hostDocument)
|
||||
{
|
||||
if (hostDocument == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(hostDocument));
|
||||
}
|
||||
|
||||
InnerHostDocument = hostDocument;
|
||||
}
|
||||
|
||||
public HostDocument InnerHostDocument { get; }
|
||||
|
||||
public override string FilePath => InnerHostDocument.FilePath;
|
||||
|
||||
public override string TargetPath => InnerHostDocument.TargetPath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultHostProjectShim : HostProjectShim
|
||||
{
|
||||
public DefaultHostProjectShim(HostProject hostProject)
|
||||
{
|
||||
if (hostProject == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(hostProject));
|
||||
}
|
||||
|
||||
InnerHostProject = hostProject;
|
||||
}
|
||||
|
||||
public HostProject InnerHostProject { get; }
|
||||
|
||||
public override RazorConfiguration Configuration => InnerHostProject.Configuration;
|
||||
|
||||
public override string FilePath => InnerHostProject.FilePath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultProjectSnapshotManagerShim : ProjectSnapshotManagerShim
|
||||
{
|
||||
public DefaultProjectSnapshotManagerShim(ProjectSnapshotManagerBase projectSnapshotManager)
|
||||
{
|
||||
if (projectSnapshotManager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectSnapshotManager));
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager = projectSnapshotManager;
|
||||
|
||||
InnerProjectSnapshotManager.Changed += OnInnerSnapshotManagerChanged;
|
||||
}
|
||||
|
||||
public ProjectSnapshotManagerBase InnerProjectSnapshotManager { get; }
|
||||
|
||||
public override IReadOnlyList<ProjectSnapshotShim> Projects
|
||||
{
|
||||
get
|
||||
{
|
||||
var projects = new List<ProjectSnapshotShim>();
|
||||
|
||||
for (var i = 0; i < InnerProjectSnapshotManager.Projects.Count; i++)
|
||||
{
|
||||
var projectShim = new DefaultProjectSnapshotShim(InnerProjectSnapshotManager.Projects[i]);
|
||||
projects.Add(projectShim);
|
||||
}
|
||||
|
||||
return projects;
|
||||
}
|
||||
}
|
||||
|
||||
public override Workspace Workspace => InnerProjectSnapshotManager.Workspace;
|
||||
|
||||
#pragma warning disable 67
|
||||
public override event EventHandler<ProjectChangeEventArgsShim> Changed;
|
||||
#pragma warning restore 67
|
||||
|
||||
public override void DocumentAdded(HostProjectShim hostProject, HostDocumentShim hostDocument, TextLoader textLoader)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
if (!(hostDocument is DefaultHostDocumentShim defaultHostDocument))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host document.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.DocumentAdded(defaultHostProject.InnerHostProject, defaultHostDocument.InnerHostDocument, textLoader);
|
||||
}
|
||||
|
||||
public override void DocumentChanged(string projectFilePath, string documentFilePath, TextLoader textLoader) => InnerProjectSnapshotManager.DocumentChanged(projectFilePath, documentFilePath, textLoader);
|
||||
|
||||
public override void DocumentChanged(string projectFilePath, string documentFilePath, SourceText sourceText) => InnerProjectSnapshotManager.DocumentChanged(projectFilePath, documentFilePath, sourceText);
|
||||
|
||||
public override void DocumentClosed(string projectFilePath, string documentFilePath, TextLoader textLoader) => InnerProjectSnapshotManager.DocumentClosed(projectFilePath, documentFilePath, textLoader);
|
||||
|
||||
public override void DocumentOpened(string projectFilePath, string documentFilePath, SourceText sourceText) => InnerProjectSnapshotManager.DocumentOpened(projectFilePath, documentFilePath, sourceText);
|
||||
|
||||
public override void DocumentRemoved(HostProjectShim hostProject, HostDocumentShim hostDocument)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
if (!(hostDocument is DefaultHostDocumentShim defaultHostDocument))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host document.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.DocumentRemoved(defaultHostProject.InnerHostProject, defaultHostDocument.InnerHostDocument);
|
||||
}
|
||||
|
||||
public override ProjectSnapshotShim GetLoadedProject(string filePath)
|
||||
{
|
||||
var loadedProject = InnerProjectSnapshotManager.GetLoadedProject(filePath);
|
||||
|
||||
return new DefaultProjectSnapshotShim(loadedProject);
|
||||
}
|
||||
|
||||
public override ProjectSnapshotShim GetOrCreateProject(string filePath)
|
||||
{
|
||||
var project = InnerProjectSnapshotManager.GetOrCreateProject(filePath);
|
||||
|
||||
return new DefaultProjectSnapshotShim(project);
|
||||
}
|
||||
|
||||
public override void HostProjectAdded(HostProjectShim hostProject)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.HostProjectAdded(defaultHostProject.InnerHostProject);
|
||||
}
|
||||
|
||||
public override void HostProjectChanged(HostProjectShim hostProject)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.HostProjectChanged(defaultHostProject.InnerHostProject);
|
||||
}
|
||||
|
||||
public override void HostProjectRemoved(HostProjectShim hostProject)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.HostProjectRemoved(defaultHostProject.InnerHostProject);
|
||||
}
|
||||
|
||||
public override bool IsDocumentOpen(string documentFilePath) => InnerProjectSnapshotManager.IsDocumentOpen(documentFilePath);
|
||||
|
||||
public override void ReportError(Exception exception) => InnerProjectSnapshotManager.ReportError(exception);
|
||||
|
||||
public override void ReportError(Exception exception, ProjectSnapshotShim project)
|
||||
{
|
||||
if (!(project is DefaultProjectSnapshotShim defaultProjectSnapshot))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of project snapshot.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.ReportError(exception, defaultProjectSnapshot.InnerProjectSnapshot);
|
||||
}
|
||||
|
||||
public override void ReportError(Exception exception, HostProjectShim hostProject)
|
||||
{
|
||||
if (!(hostProject is DefaultHostProjectShim defaultHostProject))
|
||||
{
|
||||
throw new ArgumentException("Cannot understand non-default implementations of host project.");
|
||||
}
|
||||
|
||||
InnerProjectSnapshotManager.ReportError(exception, defaultHostProject.InnerHostProject);
|
||||
}
|
||||
|
||||
public override void ReportError(Exception exception, Project workspaceProject) => InnerProjectSnapshotManager.ReportError(exception, workspaceProject);
|
||||
|
||||
public override void WorkspaceProjectAdded(Project workspaceProject) => InnerProjectSnapshotManager.WorkspaceProjectAdded(workspaceProject);
|
||||
|
||||
public override void WorkspaceProjectChanged(Project workspaceProject) => InnerProjectSnapshotManager.WorkspaceProjectChanged(workspaceProject);
|
||||
|
||||
public override void WorkspaceProjectRemoved(Project workspaceProject) => InnerProjectSnapshotManager.WorkspaceProjectRemoved(workspaceProject);
|
||||
|
||||
private void OnInnerSnapshotManagerChanged(object sender, ProjectChangeEventArgs args)
|
||||
{
|
||||
var shimArgs = new ProjectChangeEventArgsShim(args.ProjectFilePath, args.DocumentFilePath, (ProjectChangeKindShim)args.Kind);
|
||||
|
||||
Changed?.Invoke(this, shimArgs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultProjectSnapshotManagerShimAccessor : ProjectSnapshotManagerShimAccessor
|
||||
{
|
||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||
private readonly ErrorReporter _errorReporter;
|
||||
private ProjectSnapshotManagerShim _instance;
|
||||
|
||||
public DefaultProjectSnapshotManagerShimAccessor(
|
||||
ForegroundDispatcher foregroundDispatcher,
|
||||
ErrorReporter errorReporter)
|
||||
{
|
||||
if (foregroundDispatcher == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||
}
|
||||
|
||||
if (errorReporter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(errorReporter));
|
||||
}
|
||||
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
_errorReporter = errorReporter;
|
||||
}
|
||||
|
||||
public override ProjectSnapshotManagerShim Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
var workspace = new AdhocWorkspace();
|
||||
var projectSnapshotManager = new DefaultProjectSnapshotManager(
|
||||
_foregroundDispatcher,
|
||||
_errorReporter,
|
||||
Enumerable.Empty<ProjectSnapshotChangeTrigger>(),
|
||||
workspace);
|
||||
_instance = new DefaultProjectSnapshotManagerShim(projectSnapshotManager);
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultProjectSnapshotShim : ProjectSnapshotShim
|
||||
{
|
||||
public DefaultProjectSnapshotShim(ProjectSnapshot projectSnapshot)
|
||||
{
|
||||
if (projectSnapshot == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectSnapshot));
|
||||
}
|
||||
|
||||
InnerProjectSnapshot = projectSnapshot;
|
||||
}
|
||||
|
||||
public ProjectSnapshot InnerProjectSnapshot { get; }
|
||||
|
||||
public override HostProjectShim HostProject
|
||||
{
|
||||
get
|
||||
{
|
||||
if (InnerProjectSnapshot is DefaultProjectSnapshot defaultSnapshot)
|
||||
{
|
||||
new DefaultHostProjectShim(defaultSnapshot.HostProject);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override RazorConfiguration Configuration => InnerProjectSnapshot.Configuration;
|
||||
|
||||
public override IEnumerable<string> DocumentFilePaths => InnerProjectSnapshot.DocumentFilePaths;
|
||||
|
||||
public override string FilePath => InnerProjectSnapshot.FilePath;
|
||||
|
||||
public override bool IsInitialized => InnerProjectSnapshot.IsInitialized;
|
||||
|
||||
public override VersionStamp Version => InnerProjectSnapshot.Version;
|
||||
|
||||
public override Project WorkspaceProject => InnerProjectSnapshot.WorkspaceProject;
|
||||
|
||||
public override DocumentSnapshotShim GetDocument(string filePath)
|
||||
{
|
||||
var document = InnerProjectSnapshot.GetDocument(filePath);
|
||||
return new DefaultDocumentSnapshotShim(document);
|
||||
}
|
||||
|
||||
public override RazorProjectEngine GetProjectEngine() => InnerProjectSnapshot.GetProjectEngine();
|
||||
|
||||
public override Task<IReadOnlyList<TagHelperDescriptor>> GetTagHelpersAsync() => InnerProjectSnapshot.GetTagHelpersAsync();
|
||||
|
||||
public override bool TryGetTagHelpers(out IReadOnlyList<TagHelperDescriptor> result) => InnerProjectSnapshot.TryGetTagHelpers(out result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class DefaultRazorConfigurationResolver : RazorConfigurationResolver
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, RazorConfiguration> SupportedConfigurations = new Dictionary<string, RazorConfiguration>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[FallbackRazorConfiguration.MVC_1_0.ConfigurationName] = FallbackRazorConfiguration.MVC_1_0,
|
||||
[FallbackRazorConfiguration.MVC_1_1.ConfigurationName] = FallbackRazorConfiguration.MVC_1_1,
|
||||
[FallbackRazorConfiguration.MVC_2_0.ConfigurationName] = FallbackRazorConfiguration.MVC_2_0,
|
||||
[FallbackRazorConfiguration.MVC_2_1.ConfigurationName] = FallbackRazorConfiguration.MVC_2_1,
|
||||
};
|
||||
|
||||
public override bool TryResolve(string configurationName, out RazorConfiguration configuration)
|
||||
{
|
||||
if (configurationName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configurationName));
|
||||
}
|
||||
|
||||
if (SupportedConfigurations.TryGetValue(configurationName, out configuration))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class DocumentSnapshotShim
|
||||
{
|
||||
public abstract string FilePath { get; }
|
||||
|
||||
public abstract string TargetPath { get; }
|
||||
|
||||
public abstract IReadOnlyList<DocumentSnapshotShim> GetImports();
|
||||
|
||||
public abstract Task<SourceText> GetTextAsync();
|
||||
|
||||
public abstract Task<VersionStamp> GetTextVersionAsync();
|
||||
|
||||
public abstract Task<RazorCodeDocument> GetGeneratedOutputAsync();
|
||||
|
||||
public abstract bool TryGetText(out SourceText result);
|
||||
|
||||
public abstract bool TryGetTextVersion(out VersionStamp result);
|
||||
|
||||
public abstract bool TryGetGeneratedOutput(out RazorCodeDocument result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class ForegroundDispatcherShim
|
||||
{
|
||||
public abstract bool IsForegroundThread { get; }
|
||||
|
||||
public abstract TaskScheduler ForegroundScheduler { get; }
|
||||
|
||||
public abstract TaskScheduler BackgroundScheduler { get; }
|
||||
|
||||
public abstract void AssertForegroundThread([CallerMemberName] string caller = null);
|
||||
|
||||
public abstract void AssertBackgroundThread([CallerMemberName] string caller = null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class HostDocumentShim
|
||||
{
|
||||
public abstract string FilePath { get; }
|
||||
|
||||
public abstract string TargetPath { get; }
|
||||
|
||||
public static HostDocumentShim Create(string filePath, string targetPath)
|
||||
{
|
||||
var hostDocument = new HostDocument(filePath, targetPath);
|
||||
var hostDocumentShim = new DefaultHostDocumentShim(hostDocument);
|
||||
return hostDocumentShim;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class HostProjectShim
|
||||
{
|
||||
public abstract RazorConfiguration Configuration { get; }
|
||||
|
||||
public abstract string FilePath { get; }
|
||||
|
||||
public static HostProjectShim Create(string filePath, RazorConfiguration configuration)
|
||||
{
|
||||
if (filePath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
if (configuration == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configuration));
|
||||
}
|
||||
|
||||
var hostProject = new HostProject(filePath, configuration);
|
||||
return new DefaultHostProjectShim(hostProject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public static class IServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddRazorShims(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ForegroundDispatcher, VSCodeForegroundDispatcher>();
|
||||
services.AddSingleton<ForegroundDispatcherShim, DefaultForegroundDispatcherShim>();
|
||||
services.AddSingleton<ErrorReporter, DefaultErrorReporter>();
|
||||
services.AddSingleton<ProjectSnapshotManagerShimAccessor, DefaultProjectSnapshotManagerShimAccessor>();
|
||||
services.AddSingleton<RazorConfigurationResolver, DefaultRazorConfigurationResolver>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Description>Temporary assembly until the csharp language server is strong name signed.</Description>
|
||||
<EnableApiCheck>false</EnableApiCheck>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\modules\Razor\src\Microsoft.CodeAnalysis.Razor.Workspaces\Microsoft.CodeAnalysis.Razor.Workspaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public class ProjectChangeEventArgsShim : EventArgs
|
||||
{
|
||||
public ProjectChangeEventArgsShim(string projectFilePath, ProjectChangeKindShim kind)
|
||||
{
|
||||
if (projectFilePath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectFilePath));
|
||||
}
|
||||
|
||||
ProjectFilePath = projectFilePath;
|
||||
Kind = kind;
|
||||
}
|
||||
|
||||
public ProjectChangeEventArgsShim(string projectFilePath, string documentFilePath, ProjectChangeKindShim kind)
|
||||
{
|
||||
if (projectFilePath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectFilePath));
|
||||
}
|
||||
|
||||
ProjectFilePath = projectFilePath;
|
||||
DocumentFilePath = documentFilePath;
|
||||
Kind = kind;
|
||||
}
|
||||
|
||||
public string ProjectFilePath { get; }
|
||||
|
||||
public string DocumentFilePath { get; }
|
||||
|
||||
public ProjectChangeKindShim Kind { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public enum ProjectChangeKindShim
|
||||
{
|
||||
ProjectAdded,
|
||||
ProjectRemoved,
|
||||
ProjectChanged,
|
||||
DocumentAdded,
|
||||
DocumentRemoved,
|
||||
|
||||
// This could be a state change (opened/closed) or a content change.
|
||||
DocumentChanged,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class ProjectSnapshotManagerShim
|
||||
{
|
||||
public abstract event EventHandler<ProjectChangeEventArgsShim> Changed;
|
||||
|
||||
public abstract IReadOnlyList<ProjectSnapshotShim> Projects { get; }
|
||||
|
||||
public abstract bool IsDocumentOpen(string documentFilePath);
|
||||
|
||||
public abstract ProjectSnapshotShim GetLoadedProject(string filePath);
|
||||
|
||||
public abstract ProjectSnapshotShim GetOrCreateProject(string filePath);
|
||||
|
||||
|
||||
public abstract Workspace Workspace { get; }
|
||||
|
||||
public abstract void DocumentAdded(HostProjectShim hostProject, HostDocumentShim hostDocument, TextLoader textLoader);
|
||||
|
||||
public abstract void DocumentOpened(string projectFilePath, string documentFilePath, SourceText sourceText);
|
||||
|
||||
public abstract void DocumentClosed(string projectFilePath, string documentFilePath, TextLoader textLoader);
|
||||
|
||||
public abstract void DocumentChanged(string projectFilePath, string documentFilePath, TextLoader textLoader);
|
||||
|
||||
public abstract void DocumentChanged(string projectFilePath, string documentFilePath, SourceText sourceText);
|
||||
|
||||
public abstract void DocumentRemoved(HostProjectShim hostProject, HostDocumentShim hostDocument);
|
||||
|
||||
public abstract void HostProjectAdded(HostProjectShim hostProject);
|
||||
|
||||
public abstract void HostProjectChanged(HostProjectShim hostProject);
|
||||
|
||||
public abstract void HostProjectRemoved(HostProjectShim hostProject);
|
||||
|
||||
public abstract void WorkspaceProjectAdded(Project workspaceProject);
|
||||
|
||||
public abstract void WorkspaceProjectChanged(Project workspaceProject);
|
||||
|
||||
public abstract void WorkspaceProjectRemoved(Project workspaceProject);
|
||||
|
||||
public abstract void ReportError(Exception exception);
|
||||
|
||||
public abstract void ReportError(Exception exception, ProjectSnapshotShim project);
|
||||
|
||||
public abstract void ReportError(Exception exception, HostProjectShim hostProject);
|
||||
|
||||
public abstract void ReportError(Exception exception, Project workspaceProject);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class ProjectSnapshotManagerShimAccessor
|
||||
{
|
||||
public abstract ProjectSnapshotManagerShim Instance { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
|
||||
public abstract class ProjectSnapshotShim
|
||||
{
|
||||
public abstract HostProjectShim HostProject { get; }
|
||||
|
||||
public abstract RazorConfiguration Configuration { get; }
|
||||
|
||||
public abstract IEnumerable<string> DocumentFilePaths { get; }
|
||||
|
||||
public abstract string FilePath { get; }
|
||||
|
||||
public abstract bool IsInitialized { get; }
|
||||
|
||||
public abstract VersionStamp Version { get; }
|
||||
|
||||
public abstract Project WorkspaceProject { get; }
|
||||
|
||||
public abstract RazorProjectEngine GetProjectEngine();
|
||||
|
||||
public abstract DocumentSnapshotShim GetDocument(string filePath);
|
||||
|
||||
public abstract Task<IReadOnlyList<TagHelperDescriptor>> GetTagHelpersAsync();
|
||||
|
||||
public abstract bool TryGetTagHelpers(out IReadOnlyList<TagHelperDescriptor> result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
public abstract class RazorConfigurationResolver
|
||||
{
|
||||
public abstract bool TryResolve(string configurationName, out RazorConfiguration configuration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed
|
||||
{
|
||||
internal class VSCodeForegroundDispatcher : ForegroundDispatcher
|
||||
{
|
||||
public override bool IsForegroundThread => Thread.CurrentThread.ManagedThreadId == ForegroundTaskScheduler.Instance.ForegroundThreadId;
|
||||
|
||||
public override TaskScheduler ForegroundScheduler { get; } = ForegroundTaskScheduler.Instance;
|
||||
|
||||
public override TaskScheduler BackgroundScheduler { get; } = TaskScheduler.Default;
|
||||
|
||||
internal class ForegroundTaskScheduler : TaskScheduler
|
||||
{
|
||||
public static ForegroundTaskScheduler Instance = new ForegroundTaskScheduler();
|
||||
|
||||
private readonly Thread _thread;
|
||||
private readonly BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
|
||||
|
||||
private ForegroundTaskScheduler()
|
||||
{
|
||||
_thread = new Thread(ThreadStart)
|
||||
{
|
||||
IsBackground = true,
|
||||
};
|
||||
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
public int ForegroundThreadId => _thread.ManagedThreadId;
|
||||
|
||||
public override int MaximumConcurrencyLevel => 1;
|
||||
|
||||
protected override void QueueTask(Task task) => _tasks.Add(task);
|
||||
|
||||
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) => TryExecuteTask(task);
|
||||
|
||||
protected override IEnumerable<Task> GetScheduledTasks() => _tasks.ToArray();
|
||||
|
||||
private void ThreadStart()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var task = _tasks.Take();
|
||||
TryExecuteTask(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using OmniSharp.Extensions.JsonRpc;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
[Parallel, Method("razor/languageDocumentQuery")]
|
||||
public interface IRazorLanguageQueryHandler : IJsonRpcRequestHandler<RazorLanguageQueryParams, RazorLanguageQueryResponse>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public abstract class LanguageServerHandlerBase
|
||||
{
|
||||
private readonly ILanguageServer _router;
|
||||
private static string LastLogType = string.Empty;
|
||||
|
||||
public LanguageServerHandlerBase(ILanguageServer router)
|
||||
{
|
||||
if (router == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(router));
|
||||
}
|
||||
|
||||
_router = router;
|
||||
}
|
||||
|
||||
protected void LogToClient(string message)
|
||||
{
|
||||
var messageBuilder = new StringBuilder();
|
||||
var typeName = GetType().Name;
|
||||
|
||||
lock (LastLogType)
|
||||
{
|
||||
if (LastLogType != typeName)
|
||||
{
|
||||
LastLogType = typeName;
|
||||
|
||||
messageBuilder
|
||||
.AppendLine()
|
||||
.AppendLine(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
messageBuilder
|
||||
.Append(" ")
|
||||
.Append(DateTime.Now.ToString("HH:mm:ss"))
|
||||
.Append("\t\t")
|
||||
.Append(message);
|
||||
|
||||
_router.Window.LogMessage(new LogMessageParams()
|
||||
{
|
||||
Type = MessageType.Log,
|
||||
Message = messageBuilder.ToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\modules\csharp-language-server-protocol\src\Server\Server.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed\Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
using System;
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.Projects;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OmniSharp.Extensions.LanguageServer.Server;
|
||||
|
||||
|
@ -15,6 +20,19 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
|
|||
|
||||
public static async Task MainAsync(string[] args)
|
||||
{
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (args[i].IndexOf("debug", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
while (!Debugger.IsAttached)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer.From(options =>
|
||||
options
|
||||
.WithInput(Console.OpenStandardInput())
|
||||
|
@ -22,7 +40,11 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
|
|||
.WithLoggerFactory(new LoggerFactory())
|
||||
.AddDefaultLoggingProvider()
|
||||
.WithMinimumLogLevel(LogLevel.Trace)
|
||||
.WithHandler<TextDocumentHandler>());
|
||||
.WithHandler<RazorDocumentSynchronizationHandler>()
|
||||
.WithHandler<RazorCompletionHandler>()
|
||||
.WithHandler<RazorLanguageService>()
|
||||
.WithHandler<RazorProjectService>()
|
||||
.WithServices(services => services.AddRazorShims()));
|
||||
|
||||
await server.WaitForExit;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using OmniSharp.Extensions.JsonRpc;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.Projects
|
||||
{
|
||||
[Parallel, Method("projects/addDocument")]
|
||||
public interface IRazorAddDocumentHandler : IJsonRpcNotificationHandler<RazorAddDocumentParams>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using OmniSharp.Extensions.JsonRpc;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.Projects
|
||||
{
|
||||
[Parallel, Method("projects/addProject")]
|
||||
public interface IRazorAddProjectHandler : IJsonRpcNotificationHandler<RazorAddProjectParams>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using MediatR;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.Projects
|
||||
{
|
||||
public class RazorAddDocumentParams : IRequest
|
||||
{
|
||||
public TextDocumentItem TextDocument { get; set; }
|
||||
|
||||
public string ProjectFilePath { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using MediatR;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.Projects
|
||||
{
|
||||
public class RazorAddProjectParams : IRequest
|
||||
{
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public string ConfigurationName { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer.Projects
|
||||
{
|
||||
internal class RazorProjectService : LanguageServerHandlerBase, IRazorAddProjectHandler, IRazorAddDocumentHandler
|
||||
{
|
||||
private readonly ProjectSnapshotManagerShimAccessor _projectSnapshotManagerAccessor;
|
||||
private readonly RazorConfigurationResolver _configurationResolver;
|
||||
private readonly ForegroundDispatcherShim _foregroundDispatcher;
|
||||
|
||||
public RazorProjectService(
|
||||
ProjectSnapshotManagerShimAccessor projectSnapshotManagerAccessor,
|
||||
RazorConfigurationResolver configurationResolver,
|
||||
ForegroundDispatcherShim foregroundDispatcher,
|
||||
ILanguageServer router) : base(router)
|
||||
{
|
||||
if (projectSnapshotManagerAccessor == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectSnapshotManagerAccessor));
|
||||
}
|
||||
|
||||
if (configurationResolver == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configurationResolver));
|
||||
}
|
||||
|
||||
if (foregroundDispatcher == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||
}
|
||||
|
||||
_projectSnapshotManagerAccessor = projectSnapshotManagerAccessor;
|
||||
_configurationResolver = configurationResolver;
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
}
|
||||
|
||||
public async Task<Unit> Handle(RazorAddProjectParams notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if (notification == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(notification));
|
||||
}
|
||||
|
||||
if (!_configurationResolver.TryResolve(notification.ConfigurationName, out var razorConfiguration))
|
||||
{
|
||||
LogToClient($"Could not resolve Razor configuration '{notification.ConfigurationName}'. Falling back to default.");
|
||||
razorConfiguration = RazorConfiguration.Default;
|
||||
}
|
||||
|
||||
await AddProjectOnForegroundAsync(notification, razorConfiguration);
|
||||
|
||||
return Unit.Value;
|
||||
}
|
||||
|
||||
public async Task<Unit> Handle(RazorAddDocumentParams notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if (notification == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(notification));
|
||||
}
|
||||
|
||||
await AddDocumentOnForegroundAsync(notification.ProjectFilePath, notification.TextDocument);
|
||||
|
||||
return Unit.Value;
|
||||
}
|
||||
|
||||
private Task AddDocumentOnForegroundAsync(string projectFilePath, TextDocumentItem textDocument)
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
var projectSnapshot = _projectSnapshotManagerAccessor.Instance.GetLoadedProject(projectFilePath);
|
||||
if (projectSnapshot == null)
|
||||
{
|
||||
// No active project to track the document. Treat this as a misc Razor file.
|
||||
return;
|
||||
}
|
||||
|
||||
var hostDocument = HostDocumentShim.Create(textDocument.Uri.AbsolutePath, textDocument.Uri.AbsolutePath);
|
||||
var sourceText = SourceText.From(textDocument.Text);
|
||||
var textAndVersion = TextAndVersion.Create(sourceText, VersionStamp.Default);
|
||||
var textLoader = TextLoader.From(textAndVersion);
|
||||
_projectSnapshotManagerAccessor.Instance.DocumentAdded(projectSnapshot.HostProject, hostDocument, textLoader);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
|
||||
}
|
||||
|
||||
private Task AddProjectOnForegroundAsync(RazorAddProjectParams notification, RazorConfiguration razorConfiguration)
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
var hostProject = HostProjectShim.Create(notification.FilePath, razorConfiguration);
|
||||
_projectSnapshotManagerAccessor.Instance.HostProjectAdded(hostProject);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public class RazorCompletionHandler : LanguageServerHandlerBase, ICompletionHandler
|
||||
{
|
||||
private CompletionCapability _capability;
|
||||
|
||||
public RazorCompletionHandler(ILanguageServer router) : base(router)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetCapability(CompletionCapability capability)
|
||||
{
|
||||
LogToClient("Setting capability");
|
||||
|
||||
_capability = capability;
|
||||
}
|
||||
|
||||
public Task<CompletionList> Handle(CompletionParams request, CancellationToken cancellationToken)
|
||||
{
|
||||
LogToClient("Handling completion request.");
|
||||
|
||||
var completionItems = new List<CompletionItem>()
|
||||
{
|
||||
new CompletionItem()
|
||||
{
|
||||
Label = "taylor",
|
||||
InsertText = "taylor",
|
||||
Detail = "The taylor directive.",
|
||||
Documentation = "The taylor directive which is awesome.",
|
||||
FilterText = "taylor",
|
||||
SortText = "Taylor",
|
||||
Kind = CompletionItemKind.Text
|
||||
}
|
||||
};
|
||||
|
||||
var completionList = new CompletionList(completionItems, isIncomplete: true);
|
||||
|
||||
return Task.FromResult(completionList);
|
||||
}
|
||||
|
||||
public CompletionRegistrationOptions GetRegistrationOptions()
|
||||
{
|
||||
return new CompletionRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = RazorDocument.Selector,
|
||||
ResolveProvider = true,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public static class RazorDocument
|
||||
{
|
||||
public static DocumentSelector Selector { get; } = new DocumentSelector(
|
||||
new DocumentFilter()
|
||||
{
|
||||
Pattern = "**/*.razor"
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public class RazorDocumentSynchronizationHandler : LanguageServerHandlerBase, ITextDocumentSyncHandler
|
||||
{
|
||||
private SynchronizationCapability _capability;
|
||||
private readonly ProjectSnapshotManagerShimAccessor _projectSnapshotManagerAccessor;
|
||||
|
||||
public RazorDocumentSynchronizationHandler(
|
||||
ILanguageServer router,
|
||||
ProjectSnapshotManagerShimAccessor projectSnapshotManagerAccessor) : base(router)
|
||||
{
|
||||
if (router == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(router));
|
||||
}
|
||||
|
||||
if (projectSnapshotManagerAccessor == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectSnapshotManagerAccessor));
|
||||
}
|
||||
|
||||
_projectSnapshotManagerAccessor = projectSnapshotManagerAccessor;
|
||||
}
|
||||
|
||||
public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Incremental;
|
||||
|
||||
public void SetCapability(SynchronizationCapability capability)
|
||||
{
|
||||
LogToClient("Setting Capability");
|
||||
|
||||
_capability = capability;
|
||||
}
|
||||
|
||||
public Task<Unit> Handle(DidChangeTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
LogToClient("Changed Document");
|
||||
|
||||
return Unit.Task;
|
||||
}
|
||||
|
||||
public Task<Unit> Handle(DidOpenTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
LogToClient("Opened Document");
|
||||
|
||||
return Unit.Task;
|
||||
}
|
||||
|
||||
public Task<Unit> Handle(DidCloseTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
LogToClient("Closed Document");
|
||||
|
||||
return Unit.Task;
|
||||
}
|
||||
|
||||
public Task<Unit> Handle(DidSaveTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
LogToClient("Saved Document");
|
||||
|
||||
return Unit.Task;
|
||||
}
|
||||
|
||||
public TextDocumentAttributes GetTextDocumentAttributes(Uri uri)
|
||||
{
|
||||
LogToClient("Asked for attributes");
|
||||
|
||||
return new TextDocumentAttributes(uri, "razor");
|
||||
}
|
||||
|
||||
TextDocumentChangeRegistrationOptions IRegistration<TextDocumentChangeRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentChangeRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = RazorDocument.Selector,
|
||||
SyncKind = Change
|
||||
};
|
||||
}
|
||||
|
||||
TextDocumentRegistrationOptions IRegistration<TextDocumentRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = RazorDocument.Selector,
|
||||
};
|
||||
}
|
||||
|
||||
TextDocumentSaveRegistrationOptions IRegistration<TextDocumentSaveRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentSaveRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = RazorDocument.Selector,
|
||||
IncludeText = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using MediatR;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public class RazorLanguageQueryParams : IRequest<RazorLanguageQueryResponse>
|
||||
{
|
||||
public Uri HostDocumentUri { get; set; }
|
||||
|
||||
public Uri ProjectedCSharpDocumentUri { get; set; }
|
||||
|
||||
// TODO: Not implemented on client.
|
||||
public Uri ProjectedHtmlDocumentUri { get; set; }
|
||||
|
||||
public Position HostDocumentPosition { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public class RazorLanguageQueryResponse
|
||||
{
|
||||
public Uri TextDocumentUri { get; set; }
|
||||
|
||||
public Position Position { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
internal class RazorLanguageService : IRazorLanguageQueryHandler
|
||||
{
|
||||
public Task<RazorLanguageQueryResponse> Handle(RazorLanguageQueryParams request, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = new RazorLanguageQueryResponse()
|
||||
{
|
||||
Position = request.HostDocumentPosition,
|
||||
TextDocumentUri = request.ProjectedCSharpDocumentUri,
|
||||
};
|
||||
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.LanguageServer
|
||||
{
|
||||
public class TextDocumentHandler : ITextDocumentSyncHandler
|
||||
{
|
||||
private readonly ILanguageServer _router;
|
||||
|
||||
private readonly DocumentSelector _documentSelector = new DocumentSelector(
|
||||
new DocumentFilter()
|
||||
{
|
||||
Pattern = "**/*.cshtml"
|
||||
}
|
||||
);
|
||||
|
||||
private SynchronizationCapability _capability;
|
||||
|
||||
public TextDocumentHandler(ILanguageServer router)
|
||||
{
|
||||
_router = router;
|
||||
}
|
||||
|
||||
public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Full;
|
||||
|
||||
public Task Handle(DidChangeTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
_router.Window.LogMessage(new LogMessageParams()
|
||||
{
|
||||
Type = MessageType.Log,
|
||||
Message = "Hello World!!!!"
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
TextDocumentChangeRegistrationOptions IRegistration<TextDocumentChangeRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentChangeRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = _documentSelector,
|
||||
SyncKind = Change
|
||||
};
|
||||
}
|
||||
|
||||
public void SetCapability(SynchronizationCapability capability)
|
||||
{
|
||||
_capability = capability;
|
||||
}
|
||||
|
||||
public async Task Handle(DidOpenTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
await Task.Yield();
|
||||
_router.Window.LogMessage(new LogMessageParams()
|
||||
{
|
||||
Type = MessageType.Log,
|
||||
Message = "Hello World!!!!"
|
||||
});
|
||||
}
|
||||
|
||||
TextDocumentRegistrationOptions IRegistration<TextDocumentRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = _documentSelector,
|
||||
};
|
||||
}
|
||||
|
||||
public Task Handle(DidCloseTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Handle(DidSaveTextDocumentParams notification, CancellationToken token)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
TextDocumentSaveRegistrationOptions IRegistration<TextDocumentSaveRegistrationOptions>.GetRegistrationOptions()
|
||||
{
|
||||
return new TextDocumentSaveRegistrationOptions()
|
||||
{
|
||||
DocumentSelector = _documentSelector,
|
||||
IncludeText = true
|
||||
};
|
||||
}
|
||||
|
||||
public TextDocumentAttributes GetTextDocumentAttributes(Uri uri)
|
||||
{
|
||||
return new TextDocumentAttributes(uri, "razor");
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче