Resurrect Blazor VSIX (#6779)

* Remove Blazor.LanguageServices

The text-view-listener was the only thing here and it's not needed
anymore now that these features are build into our main VS payload.

We won't have any more code to put in this project because it's this
VSIX is pretty temporary.

* Remove reference to ProjectSystem

We don't need this reference, and it's got some breaking changes between
15 and 16 - rahter then mess with nuget sources for vs16 packages, I'm
just going to drop the dependency

* Remove unused cruft
* Target net472
* Add Blazor VSIX to build
* Add Extension to .sln
* Use AsyncPackage
* Update and streamline references
* Update manifest for 16.0
* Pack Templates before building VSIX
* Fix version of templates
This commit is contained in:
Ryan Nowak 2019-01-24 14:26:12 -08:00 committed by Nate McMaster
parent 8ce02ef68e
commit f0fc598511
15 changed files with 99 additions and 387 deletions

View File

@ -37,14 +37,9 @@
<!-- These projects are always excluded, even when -projects is specified on command line. -->
<ItemGroup>
<!--
Excluding the Blazor VSIX because MSBuild.exe currently always fails with "error NETSDK1050: The version of Microsoft.NET.Sdk used by this project is insufficient".
This VSIX is going to move into aspnet/AspNetCore-Tooling soon
-->
<ProjectToExclude Include="$(RepositoryRoot)src\Components\Blazor\BlazorExtension\src\Microsoft.VisualStudio.BlazorExtension.csproj" />
<!-- These projects use 'legacy' csproj, which is not supported by dotnet-msbuild. -->
<ProjectToExclude Include="
$(RepositoryRoot)src\Components\Blazor\BlazorExtension\src\Microsoft.VisualStudio.BlazorExtension.csproj;
$(RepositoryRoot)src\Servers\HttpSys\samples\TestClient\TestClient.csproj;
$(RepositoryRoot)src\Middleware\WebSockets\samples\TestServer\TestServer.csproj;
"

View File

@ -125,7 +125,6 @@
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR" ProjectPath="$(RepositoryRoot)src\SignalR\server\SignalR\src\Microsoft.AspNetCore.SignalR.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.Specification.Tests" ProjectPath="$(RepositoryRoot)src\SignalR\server\Specification.Tests\src\Microsoft.AspNetCore.SignalR.Specification.Tests.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" ProjectPath="$(RepositoryRoot)src\SignalR\server\StackExchangeRedis\src\Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj" />
<ProjectReferenceProvider Include="Microsoft.VisualStudio.LanguageServices.Blazor" ProjectPath="$(RepositoryRoot)src\Components\Blazor\BlazorLanguageServices\src\Microsoft.VisualStudio.LanguageServices.Blazor.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor" ProjectPath="$(RepositoryRoot)src\Components\Blazor\Blazor\src\Microsoft.AspNetCore.Blazor.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Build" ProjectPath="$(RepositoryRoot)src\Components\Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Blazor.Server" ProjectPath="$(RepositoryRoot)src\Components\Blazor\Server\src\Microsoft.AspNetCore.Blazor.Server.csproj" />

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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.VisualStudio.Shell.Interop;
@ -33,12 +33,12 @@ namespace Microsoft.VisualStudio.BlazorExtension
public void Listen()
{
AddBuildServiceNamedPipeServer();
_ = AddBuildServiceNamedPipeServerAsync();
}
private void AddBuildServiceNamedPipeServer()
private Task AddBuildServiceNamedPipeServerAsync()
{
Task.Factory.StartNew(async () =>
return Task.Factory.StartNew(async () =>
{
try
{
@ -69,7 +69,7 @@ namespace Microsoft.VisualStudio.BlazorExtension
// As soon as we receive a connection, spin up another background
// listener to wait for the next connection
await serverPipe.WaitForConnectionAsync();
AddBuildServiceNamedPipeServer();
_ = AddBuildServiceNamedPipeServerAsync();
await HandleRequestAsync(serverPipe, isServerElevated);
}

View File

@ -1,10 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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 System.Threading.Tasks;
using Microsoft.VisualStudio.ProjectSystem.Properties;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
@ -74,14 +73,16 @@ namespace Microsoft.VisualStudio.BlazorExtension
public int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (IsBlazorProject(pHierProj))
{
// This method runs both for manually-invoked builds and for builds triggered automatically
// by PerformNewBuildAsync(). In the case where it's a manually-invoked build, make sure
// there's an in-progress BuildInfo so that if there are further builds requests while the
// build is still in progress we can join them onto this existing build.
var ctx = (IVsBrowseObjectContext)pCfgProj;
var projectPath = ctx.UnconfiguredProject.FullPath;
var projectPath = GetProjectPath(pHierProj);
lock (mostRecentBuildInfosLock)
{
var hasBuildInProgress =
@ -99,11 +100,12 @@ namespace Microsoft.VisualStudio.BlazorExtension
public int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel)
{
ThreadHelper.ThrowIfNotOnUIThread();
if (IsBlazorProject(pHierProj))
{
var buildResult = fSuccess == 1;
var ctx = (IVsBrowseObjectContext)pCfgProj;
var projectPath = ctx.UnconfiguredProject.FullPath;
var projectPath = GetProjectPath(pHierProj);
// Mark pending build info as completed
BuildInfo foundInfo = null;
@ -160,6 +162,13 @@ namespace Microsoft.VisualStudio.BlazorExtension
private static bool IsBlazorProject(IVsHierarchy pHierProj)
=> pHierProj.IsCapabilityMatch(BlazorProjectCapability);
private static string GetProjectPath(IVsHierarchy pHierProj)
{
ThreadHelper.ThrowIfNotOnUIThread();
ErrorHandler.ThrowOnFailure(((IVsProject)pHierProj).GetMkDocument((uint)VSConstants.VSITEMID.Root, out var projectPath), VSConstants.E_NOTIMPL);
return projectPath;
}
class BuildInfo
{
public DateTime StartTime { get; }

View File

@ -1,40 +1,44 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.BlazorExtension
{
// We mainly have a package so we can have an "About" dialog entry.
[PackageRegistration(UseManagedResourcesOnly = true)]
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[AboutDialogInfo(PackageGuidString, "ASP.NET Core Blazor Language Services", "#110", "112")]
[Guid(BlazorPackage.PackageGuidString)]
[ProvideAutoLoad(UIContextGuids80.SolutionExists)]
public sealed class BlazorPackage : Package
[ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
public sealed class BlazorPackage : AsyncPackage
{
public const string PackageGuidString = "d9fe04bc-57a7-4107-915e-3a5c2f9e19fb";
protected override void Initialize()
protected async override Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
base.Initialize();
RegisterAutoRebuildService();
}
await base.InitializeAsync(cancellationToken, progress);
private void RegisterAutoRebuildService()
{
ThreadHelper.ThrowIfNotOnUIThread();
await JoinableTaskFactory.SwitchToMainThreadAsync();
// Create build watcher. No need to unadvise, as this only happens once anyway.
var solution = (IVsSolution)GetGlobalService(typeof(IVsSolution));
var buildManager = (IVsSolutionBuildManager)GetService(typeof(SVsSolutionBuildManager));
var buildWatcher = new BuildEventsWatcher(solution, buildManager);
var hr = buildManager.AdviseUpdateSolutionEvents(buildWatcher, out var cookie);
Marshal.ThrowExceptionForHR(hr);
var solution = (IVsSolution)await GetServiceAsync(typeof(IVsSolution));
var buildManager = (IVsSolutionBuildManager)await GetServiceAsync(typeof(SVsSolutionBuildManager));
new AutoRebuildService(buildWatcher).Listen();
// According to the docs, this can happen if VS shuts down while our package is loading.
if (solution == null || buildManager == null)
{
var buildWatcher = new BuildEventsWatcher(solution, buildManager);
var hr = buildManager.AdviseUpdateSolutionEvents(buildWatcher, out var cookie);
Marshal.ThrowExceptionForHR(hr);
new AutoRebuildService(buildWatcher).Listen();
}
}
}
}

View File

@ -8,10 +8,15 @@
<ImportDirectoryBuildTargets>true</ImportDirectoryBuildTargets>
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<!-- Other projects should not reference this assembly. It is only mean to be used in Visual Studio. -->
<!-- Other projects should not reference this assembly. It is only meaning to be used in Visual Studio. -->
<IsProjectReferenceProvider>false</IsProjectReferenceProvider>
<IsShippingPackage>false</IsShippingPackage>
<IsPackable>false</IsPackable>
<EnableSourceLink>false</EnableSourceLink>
<GenerateSourceLinkFile>false</GenerateSourceLinkFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!--
Since the VSSDK doeesn't support SDK-based projects, we have to use the long/verbose version.
@ -20,26 +25,23 @@
BEGIN INTERESTING STUFF
-->
<PropertyGroup>
<!-- VSIXes are always signed. This is the same key that ASP.NET uses for OSS signing -->
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\..\eng\AspNetCore.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<!--
Following VS convention of using the VS release # as a convention for the vsix version.
VS needs this build number to be parsable by System.Version, so it can't have any letters.
VS needs this build number to be parsable by System.Version, so it can't have any letters or a - which
is used by our build system.
-->
<VsixVersion>15.7</VsixVersion>
<VsixVersion Condition="'$(BuildNumber)'!='' AND '$(BuildNumber)'!='t000'">$(VsixVersion).$(BuildNumber)</VsixVersion>
<VsixVersion Condition="'$(BuildNumber)'=='' AND '$(CI)'!='true'">$(VsixVersion).999999</VsixVersion>
<VsixVersion Condition="'$(BuildNumber)'=='' AND '$(CI)'=='true'">$(VsixVersion).ERROR-MISSING_BUILD_NUMBER</VsixVersion>
<VsixVersionPrefix>16.0</VsixVersionPrefix>
<VsixVersionSuffix Condition="'$(BuildNumberSuffix)'=='t000'">424242.424242</VsixVersionSuffix>
<VsixVersionSuffix Condition="'$(VsixVersionSuffix)'==''">$(BuildNumberSuffix.Replace('-', '.'))</VsixVersionSuffix>
<VsixVersion>$(VsixVersionPrefix).$(VsixVersionSuffix)</VsixVersion>
</PropertyGroup>
<!--
Used by the .vsixmanifest to insert the the VSIX version based on $(VsixVersion)
-->
<Target Name="GetBuildVersion" Outputs="$(VsixVersion)" />
<PropertyGroup>
<!-- Use the same experimental hive as Roslyn and Razor. This makes it easy to mix private builds. -->
<StartAction>Program</StartAction>
@ -71,7 +73,7 @@
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>
</PropertyGroup>
<Target Name="PreCreateVsixContainer" BeforeTargets="CreateVsixContainer">
<Target Name="PreCreateVsixContainer" BeforeTargets="GetVsixSourceItems">
<ItemGroup>
<VSIXSourceItem Include="$(ArtifactsShippingPackagesDir)Microsoft.AspNetCore.Blazor.Templates.*.nupkg">
<VSIXSubPath>ProjectTemplates\</VSIXSubPath>
@ -89,25 +91,7 @@
<Target Name="CopySymbolsToOutput" AfterTargets="Build" Condition="'$(SymbolsPublishDir)' != ''">
<Copy SourceFiles="$(OutDir)$(AssemblyName).pdb" DestinationFolder="$(SymbolsPublishDir)" />
</Target>
<!--
We should be really careful about what goes into the VSIX and what doesn't. Since we're using
P2P references and packages, there are some things we need to exclude.
We want everything that *we* don't own to be excluded, those dependencies need to be satisfied
by other VS components (Razor, Roslyn).
Ideally we could use an allow-list here, but I don't know how to do that.
-->
<ItemDefinitionGroup>
<SuppressFromVsix>
<Visible>false</Visible>
</SuppressFromVsix>
</ItemDefinitionGroup>
<ItemGroup>
<SuppressFromVsix Include="Microsoft.AspNetCore.Razor.Language.dll" />
<SuppressFromVsix Include="Microsoft.CodeAnalysis.Razor.dll" />
<SuppressFromVsix Include="Microsoft.CodeAnalysis.Razor.Workspaces.dll" />
</ItemGroup>
<ItemGroup>
<!--
Let's continue our parade of gross workarounds.
@ -124,27 +108,13 @@
<ProjectReference Include="..\..\Templates\src\Microsoft.AspNetCore.Blazor.Templates.csproj">
<Project>{edd21533-c6e6-4f85-be4f-10e06756e24c}</Project>
<Name>Microsoft.AspNetCore.Blazor.Templates</Name>
<Targets>Pack</Targets>
<Private>False</Private>
<IncludeOutputGroupsInVSIX>
</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>
</IncludeOutputGroupsInVSIXLocalOnly>
</ProjectReference>
<ProjectReference Include="..\..\BlazorLanguageServices\src\Microsoft.VisualStudio.LanguageServices.Blazor.csproj">
<Project>{b9f7f502-6dd2-4e77-8fd1-cbd76f695b26}</Project>
<Name>Microsoft.VisualStudio.LanguageServices.Blazor</Name>
<Private>False</Private>
<IncludeOutputGroupsInVSIX>
</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>
</IncludeOutputGroupsInVSIXLocalOnly>
</ProjectReference>
<Content Include="..\..\BlazorLanguageServices\src\bin\$(Configuration)\net461\Microsoft.VisualStudio.LanguageServices.Blazor.dll">
<Link>Microsoft.VisualStudio.LanguageServices.Blazor.dll</Link>
<IncludeInVSIX>true</IncludeInVSIX>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible>
</Content>
</ItemGroup>
<!--
We need to generate the assembly attributes for our assembly using the version from the build, so
@ -189,7 +159,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.VisualStudio.BlazorExtension</RootNamespace>
<AssemblyName>Microsoft.VisualStudio.BlazorExtension</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<GeneratePkgDefFile>true</GeneratePkgDefFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -208,25 +178,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.CoreUtility" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.Imaging" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.OLE.Interop" Version="7.10.6071" />
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem" Version="15.3.224" />
<PackageReference Include="Microsoft.VisualStudio.SDK.EmbedInteropTypes" Version="15.0.16" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="7.10.6072" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.10.0" Version="10.0.30320" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.11.0" Version="11.0.61031" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.12.0" Version="12.0.30110" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.8.0" Version="8.0.50728" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.9.0" Version="9.0.30730" />
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop" Version="7.10.6071" />
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop.8.0" Version="8.0.50728" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="15.6.46" />
<PackageReference Include="Microsoft.VisualStudio.Utilities" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="15.3.15" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="15.5.100" />
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="15.7.27703" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="15.9.3032" />
<PackageReference Include="StreamJsonRpc" Version="1.5.43" />
</ItemGroup>
<ItemGroup>
<Compile Include="AboutDialogInfoAttribute.cs" />
@ -234,7 +188,6 @@
<Compile Include="AutoRebuild\BuildEventsWatcher.cs" />
<Compile Include="AutoRebuild\StreamProtocolExtensions.cs" />
<Compile Include="BlazorPackage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="CodeSnippets\Blazor\para.snippet">
@ -306,4 +259,8 @@
<_GeneratedVSIXAssemblyInfoInputsCacheFile>$(IntermediateOutputPath)$(MSBuildProjectName).VSIXAssemblyInfo.cache.txt</_GeneratedVSIXAssemblyInfoInputsCacheFile>
<_GeneratedVSIXAssemblyInfoFile>$(IntermediateOutputPath)$(MSBuildProjectName).VSIXAssemblyInfo.cs</_GeneratedVSIXAssemblyInfoFile>
</PropertyGroup>
<!-- This needs to be here because the build will try to call it -->
<Target Name="Pack">
</Target>
</Project>

View File

@ -1,17 +0,0 @@
// 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.VisualStudio.Shell;
// Add binding redirects for each assembly we ship in VS. This is required so that these assemblies show
// up in the Load context, which means that we can use ServiceHub and other nice things.
//
// The versions here need to match what the build is producing. If you change the version numbers
// for the referenced assemblies, this needs to change as well.
[assembly: ProvideBindingRedirection(
AssemblyName = "Microsoft.VisualStudio.LanguageServices.Blazor",
GenerateCodeBase = true,
PublicKeyToken = "",
OldVersionLowerBound = "0.0.0.0",
OldVersionUpperBound = "0.8.0.0",
NewVersion = "0.8.0.0")]

View File

@ -1,2 +1,2 @@
[$RootKey$\TemplateEngine\Templates\Blazor\0.2.0]
[$RootKey$\TemplateEngine\Templates\Blazor\0.8.0]
"InstalledPath"="$PackageFolder$\ProjectTemplates"

View File

@ -12,19 +12,17 @@
<PreviewImage>Content\WebConfiguration.png</PreviewImage>
</Metadata>
<Installation AllUsers="true">
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[15.0.27617, 16.0)" />
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[16.0,)" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.6.1,)" />
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.7.2,)" />
</Dependencies>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="File" Path="Microsoft.VisualStudio.LanguageServices.Blazor.dll" />
<Asset Type="Microsoft.VisualStudio.Assembly" d:Source="File" Path="Microsoft.VisualStudio.LanguageServices.Blazor.dll" />
<Asset Type="Microsoft.VisualStudio.VsPackage" Path="Templates.pkgdef" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="File" Path="Templates.pkgdef" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="File" Path="CodeSnippets.pkgdef" />
</Assets>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.Web" Version="[15.7.27520.0,16.0)" DisplayName="ASP.NET and web development tools" />
<Prerequisite Id="Microsoft.VisualStudio.Component.Web" Version="[16.0,)" DisplayName="ASP.NET and web development tools" />
</Prerequisites>
</PackageManifest>

View File

@ -1,20 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<!-- This assembly ships in the Razor VSIX, not in a NuGet package. -->
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Razor.Workspaces" Version="2.1.0" />
<PackageReference Include="Microsoft.VisualStudio.CoreUtility" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.Editor.Razor" Version="2.1.0" />
<PackageReference Include="Microsoft.VisualStudio.LanguageServices" Version="2.8.0" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop" Version="7.10.6071" />
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop.8.0" Version="8.0.50728" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="15.6.46" />
</ItemGroup>
</Project>

View File

@ -1,213 +0,0 @@
// 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 System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.VisualStudio.Editor.Razor;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Blazor
{
[ContentType(RazorLanguage.ContentType)]
[TextViewRole(PredefinedTextViewRoles.Editable)]
[Export(typeof(IWpfTextViewConnectionListener))]
internal class BlazorOpenDocumentTracker : IWpfTextViewConnectionListener
{
private readonly RazorEditorFactoryService _editorFactory;
private readonly Workspace _workspace;
private readonly HashSet<IWpfTextView> _openViews;
private Type _codeGeneratorType;
private Type _projectSnapshotManagerType;
[ImportingConstructor]
public BlazorOpenDocumentTracker(
RazorEditorFactoryService editorFactory,
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
{
if (editorFactory == null)
{
throw new ArgumentNullException(nameof(editorFactory));
}
if (workspace == null)
{
throw new ArgumentNullException(nameof(workspace));
}
_editorFactory = editorFactory;
_workspace = workspace;
_openViews = new HashSet<IWpfTextView>();
_workspace.WorkspaceChanged += Workspace_WorkspaceChanged;
}
public Workspace Workspace => _workspace;
public void SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{
if (textView == null)
{
throw new ArgumentException(nameof(textView));
}
if (subjectBuffers == null)
{
throw new ArgumentNullException(nameof(subjectBuffers));
}
_openViews.Add(textView);
}
public void SubjectBuffersDisconnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{
if (textView == null)
{
throw new ArgumentException(nameof(textView));
}
if (subjectBuffers == null)
{
throw new ArgumentNullException(nameof(subjectBuffers));
}
_openViews.Remove(textView);
}
// We're watching the Roslyn workspace for changes specifically because we want
// to know when the language service has processed a file change.
//
// It might be more elegant to use a file watcher rather than sniffing workspace events
// but there would be a delay between the file watcher and Roslyn processing the update.
private void Workspace_WorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
{
switch (e.Kind)
{
case WorkspaceChangeKind.DocumentAdded:
case WorkspaceChangeKind.DocumentChanged:
case WorkspaceChangeKind.DocumentInfoChanged:
case WorkspaceChangeKind.DocumentReloaded:
case WorkspaceChangeKind.DocumentRemoved:
var document = e.NewSolution.GetDocument(e.DocumentId);
if (document == null || document.FilePath == null)
{
break;
}
if (!document.FilePath.EndsWith(".g.i.cs"))
{
break;
}
OnDeclarationsChanged(e.NewSolution.GetProject(e.ProjectId));
break;
}
}
private void OnDeclarationsChanged(Project project)
{
// In 15.8 the Razor Language Services provides the actual Tag Helper discovery logic.
// We can interface with that if we're running in a 15.8 build.
if (_projectSnapshotManagerType == null && _codeGeneratorType == null)
{
try
{
var assembly = typeof(Microsoft.CodeAnalysis.Razor.IProjectEngineFactory).Assembly;
_projectSnapshotManagerType = assembly.GetType("Microsoft.CodeAnalysis.Razor.ProjectSystem.ProjectSnapshotManager");
}
catch (Exception)
{
// If the above fails, try the 15.7 logic.
}
}
if (_projectSnapshotManagerType != null)
{
try
{
var languageServices = _workspace.Services.GetLanguageServices(RazorLanguage.Name);
var manager = languageServices
.GetType()
.GetMethod(nameof(HostLanguageServices.GetService))
.MakeGenericMethod(_projectSnapshotManagerType)
.Invoke(languageServices, null);
manager.GetType().GetMethod("WorkspaceProjectChanged").Invoke(manager, new object[] { project, });
return;
}
catch (Exception)
{
// If the above fails, try the 15.7 logic.
}
}
// This is a design-time Razor file change.Go poke all of the open
// Razor documents and tell them to update.
var buffers = _openViews
.SelectMany(v => v.BufferGraph.GetTextBuffers(b => b.ContentType.IsOfType("RazorCSharp")))
.Distinct()
.ToArray();
if (_codeGeneratorType == null)
{
try
{
var assembly = Assembly.Load("Microsoft.VisualStudio.Web.Editors.Razor.4_0, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
_codeGeneratorType = assembly.GetType("Microsoft.VisualStudio.Web.Editors.Razor.RazorCodeGenerator");
}
catch (Exception)
{
// If this fails, just unsubscribe. We won't be able to do our work, so just don't waste time.
_workspace.WorkspaceChanged -= Workspace_WorkspaceChanged;
}
}
foreach (var buffer in buffers)
{
try
{
var tryGetFromBuffer = _codeGeneratorType.GetMethod("TryGetFromBuffer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var args = new object[] { buffer, null };
if (!(bool)tryGetFromBuffer.Invoke(null, args) || args[1] == null)
{
continue;
}
var field = _codeGeneratorType.GetField("_tagHelperDescriptorResolver", BindingFlags.Instance | BindingFlags.NonPublic);
var resolver = field.GetValue(args[1]);
if (resolver == null)
{
continue;
}
var reset = resolver.GetType().GetMethod("ResetTagHelperDescriptors", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (reset == null)
{
continue;
}
reset.Invoke(resolver, Array.Empty<object>());
}
catch (Exception)
{
// If this fails, just unsubscribe. We won't be able to do our work, so just don't waste time.
_workspace.WorkspaceChanged -= Workspace_WorkspaceChanged;
}
}
}
}
}

View File

@ -59,12 +59,12 @@
"datatype": "choice",
"choices": [
{
"choice": "netcoreapp2.1",
"description": "Target netcoreapp2.1"
"choice": "netcoreapp3.0",
"description": "Target netcoreapp3.0"
}
],
"replaces": "netcoreapp2.1",
"defaultValue": "netcoreapp2.1"
"replaces": "netcoreapp3.0",
"defaultValue": "netcoreapp3.0"
},
"HostIdentifier": {
"type": "bind",

View File

@ -32,12 +32,12 @@
"datatype": "choice",
"choices": [
{
"choice": "netcoreapp2.1",
"description": "Target netcoreapp2.1"
"choice": "netcoreapp3.0",
"description": "Target netcoreapp3.0"
}
],
"replaces": "netcoreapp2.1",
"defaultValue": "netcoreapp2.1"
"replaces": "netcoreapp3.0",
"defaultValue": "netcoreapp3.0"
},
"HostIdentifier": {
"type": "bind",

View File

@ -32,12 +32,12 @@
"datatype": "choice",
"choices": [
{
"choice": "netcoreapp2.1",
"description": "Target netcoreapp2.1"
"choice": "netcoreapp3.0",
"description": "Target netcoreapp3.0"
}
],
"replaces": "netcoreapp2.1",
"defaultValue": "netcoreapp2.1"
"replaces": "netcoreapp3.0",
"defaultValue": "netcoreapp3.0"
},
"HostIdentifier": {
"type": "bind",

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
# Visual Studio Version 16
VisualStudioVersion = 16.0.28509.92
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{E059A46B-56E3-41E2-83F4-B5D180056F3B}"
EndProject
@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.Tests", "Blazor\Blazor\test\Microsoft.AspNetCore.Blazor.Tests.csproj", "{958AD6D2-174B-4B5B-BEFC-FA64B5159334}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.LanguageServices.Blazor", "Blazor\BlazorLanguageServices\src\Microsoft.VisualStudio.LanguageServices.Blazor.csproj", "{27CF854D-E98B-4853-946B-2D4EA28B8FC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.Build", "Blazor\Build\src\Microsoft.AspNetCore.Blazor.Build.csproj", "{E8AD67A4-77D3-4B85-AE19-4711388B62B1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.Build.Tests", "Blazor\Build\test\Microsoft.AspNetCore.Blazor.Build.Tests.csproj", "{E38FDBB0-08C1-444E-A449-69C8A59D721B}"
@ -213,6 +211,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Ne
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.JsonPatch", "..\Features\JsonPatch\src\Microsoft.AspNetCore.JsonPatch.csproj", "{DC47C40A-FC38-44E4-94A4-ADE794E76309}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.BlazorExtension", "blazor\BlazorExtension\src\Microsoft.VisualStudio.BlazorExtension.csproj", "{9088E4E4-B855-457F-AE9E-D86709A5E1F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -271,18 +271,6 @@ Global
{958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x64.Build.0 = Release|Any CPU
{958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x86.ActiveCfg = Release|Any CPU
{958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x86.Build.0 = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|x64.ActiveCfg = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|x64.Build.0 = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|x86.ActiveCfg = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Debug|x86.Build.0 = Debug|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|Any CPU.Build.0 = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|x64.ActiveCfg = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|x64.Build.0 = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|x86.ActiveCfg = Release|Any CPU
{27CF854D-E98B-4853-946B-2D4EA28B8FC5}.Release|x86.Build.0 = Release|Any CPU
{E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -1351,6 +1339,18 @@ Global
{DC47C40A-FC38-44E4-94A4-ADE794E76309}.Release|x64.Build.0 = Release|Any CPU
{DC47C40A-FC38-44E4-94A4-ADE794E76309}.Release|x86.ActiveCfg = Release|Any CPU
{DC47C40A-FC38-44E4-94A4-ADE794E76309}.Release|x86.Build.0 = Release|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|x64.Build.0 = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Debug|x86.Build.0 = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|Any CPU.Build.0 = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x64.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x64.Build.0 = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x86.ActiveCfg = Debug|Any CPU
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1360,7 +1360,6 @@ Global
{F000C49D-3857-42A4-918D-DA4C08691FE2} = {E059A46B-56E3-41E2-83F4-B5D180056F3B}
{641922CD-E6F5-41E7-A085-EE07C2A7328D} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
{958AD6D2-174B-4B5B-BEFC-FA64B5159334} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
{27CF854D-E98B-4853-946B-2D4EA28B8FC5} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
{E8AD67A4-77D3-4B85-AE19-4711388B62B1} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
{E38FDBB0-08C1-444E-A449-69C8A59D721B} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
{A6C8050D-7C18-4585-ADCF-833AC1765847} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
@ -1452,6 +1451,7 @@ Global
{3FAF725B-A628-4531-9F61-499660CD4347} = {2FC10057-7A0A-4E34-8302-879925BC0102}
{04262990-929C-42BF-85A9-21C25FA95617} = {2FC10057-7A0A-4E34-8302-879925BC0102}
{DC47C40A-FC38-44E4-94A4-ADE794E76309} = {2FC10057-7A0A-4E34-8302-879925BC0102}
{9088E4E4-B855-457F-AE9E-D86709A5E1F4} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CC3C47E1-AD1A-4619-9CD3-E08A0148E5CE}