Code dump of Visual Studio language services

This commit is contained in:
Ryan Nowak 2017-01-08 19:48:15 -08:00
parent 2c55a03667
commit 3351192dc5
16 changed files with 405 additions and 1 deletions

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26020.0
VisualStudioVersion = 15.0.26014.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
EndProject
@ -30,6 +30,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CodeAnalysis.Razo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CodeAnalysis.Remote.Razor", "src\Microsoft.CodeAnalysis.Remote.Razor\Microsoft.CodeAnalysis.Remote.Razor.csproj", "{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tooling", "tooling", "{C0CC1E1F-1559-44DE-93A8-63259CEA2AAB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.LanguageServices.Razor", "tooling\Microsoft.VisualStudio.LanguageServices.Razor\Microsoft.VisualStudio.LanguageServices.Razor.csproj", "{53489966-7486-434F-AA76-6FBC488E3D29}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -148,6 +152,18 @@ Global
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Release|x64.Build.0 = Release|x64
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Release|x86.ActiveCfg = Release|x86
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4}.Release|x86.Build.0 = Release|x86
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|x64.ActiveCfg = Debug|x64
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|x64.Build.0 = Debug|x64
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|x86.ActiveCfg = Debug|x86
{53489966-7486-434F-AA76-6FBC488E3D29}.Debug|x86.Build.0 = Debug|x86
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|Any CPU.Build.0 = Release|Any CPU
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|x64.ActiveCfg = Release|x64
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|x64.Build.0 = Release|x64
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|x86.ActiveCfg = Release|x86
{53489966-7486-434F-AA76-6FBC488E3D29}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -162,5 +178,6 @@ Global
{277AB67E-9C8D-4799-A18C-C628E70A8664} = {92463391-81BE-462B-AC3C-78C6C760741F}
{0F265874-C592-448B-BC4F-3430AB03E0DC} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{4EAD959D-73B2-4FB2-B46F-16CEB1EF49D4} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
{53489966-7486-434F-AA76-6FBC488E3D29} = {C0CC1E1F-1559-44DE-93A8-63259CEA2AAB}
EndGlobalSection
EndGlobal

View File

@ -5,4 +5,5 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Evolution.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

View File

@ -0,0 +1,7 @@
// 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;
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

View File

@ -0,0 +1,146 @@
// 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.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using static Microsoft.VisualStudio.LanguageServices.Razor.ReflectionNames;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
[Export(typeof(IRazorEngineAssemblyResolver))]
internal class DefaultRazorEngineAssemblyResolver : IRazorEngineAssemblyResolver
{
public async Task<IEnumerable<RazorEngineAssembly>> GetRazorEngineAssembliesAsync(Project project)
{
var compilation = await project.GetCompilationAsync().ConfigureAwait(false);
var assemblies = GetRazorCustomizationAssemblies(compilation);
if (assemblies.Count == 0)
{
Console.WriteLine();
}
return assemblies;
}
private static List<RazorEngineAssembly> GetRazorCustomizationAssemblies(Compilation compilation)
{
// The goal here is to find the set of assemblies + paths that have some kind of
// Razor extensibility.
//
// We do that by making a compilation and then looking through the set of assembly names
// (AssemblyIdentity) and references to dlls on disk (PortableExecutableReference) to find
// uses of RazorEngineCustomizationAttribute and RazorEngineDependencyAttribute.
//
// We're limited to supporting files on disk because we will need to shadow copy them
// and manually load them.
//
// Also note that we're not doing anything here to explicitly uniquify this list, since
// we're limiting the set of candidates to the set of assemblies used for compilation, which
// has already been processed by Roslyn.
var results = new List<RazorEngineAssembly>();
// The RazorEngineDependencyAttribute also allows specifying an assembly name to go along
// with a piece of extensibility. We'll collect these on the first pass through the assemblies
// and then look those up by name.
var unresolvedIdentities = new List<AssemblyIdentity>();
foreach (var reference in compilation.References)
{
var peReference = reference as PortableExecutableReference;
if (peReference == null || peReference.FilePath == null)
{
// No path, can't load it.
continue;
}
var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
if (assemblySymbol == null)
{
// It's unlikely, but possible that a reference might be a module instead of an assembly.
// We can't load that, so just skip it.
continue;
}
var identity = assemblySymbol.Identity;
if (identity.Name == RazorAssemblyName)
{
// This is the main Razor assembly.
results.Add(new RazorEngineAssembly(identity, peReference.FilePath));
}
// Now we're looking for the Razor exensibility attributes.
var attributes = assemblySymbol.GetAttributes();
for (var i = 0; i < attributes.Length; i++)
{
var attribute = attributes[i];
var name = attribute.AttributeClass.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
if (string.Equals(
CustomizationAttribute,
name,
StringComparison.Ordinal))
{
results.Add(new RazorEngineAssembly(identity, peReference.FilePath));
}
if (string.Equals(
DependencyAttribute,
name,
StringComparison.Ordinal))
{
// This attribute refers to a separate assembly for which we will need to resolve a path.
//
// Ignore parsing failures here.
AssemblyIdentity dependency;
if (AssemblyIdentity.TryParseDisplayName((string)attribute.ConstructorArguments[0].Value, out dependency))
{
unresolvedIdentities.Add(dependency);
}
}
}
}
// Now we need to do another pass to resolve all the unresolved names.
if (unresolvedIdentities.Count > 0)
{
//while (identities.MoveNext() && references.MoveNext())
//{
// var peReference = references.Current as PortableExecutableReference;
// if (peReference == null || peReference.FilePath == null)
// {
// // No path, can't load it.
// continue;
// }
// var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(peReference) as IAssemblySymbol;
// if (assemblySymbol == null)
// {
// // It's unlikely, but possible that a reference might be a module instead of an assembly.
// // We can't load that, so just skip it.
// continue;
// }
// for (var i = 0; i < unresolvedIdentities.Count; i++)
// {
// // Note: argument ordering here is significant. We expect that the attribute will often refer to a
// // partial name and omit details like the version and public-key, therefore the value from the
// // attribute must be the first argument.
// if (AssemblyIdentityComparer.Default.ReferenceMatchesDefinition(
// unresolvedIdentities[i],
// identities.Current))
// {
// results.Add(new RazorEngineAssembly(identities.Current, peReference.FilePath));
// break;
// }
// }
//}
}
return results;
}
}
}

View File

@ -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.Collections.Generic;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
[Export(typeof(IRazorEngineDirectiveResolver))]
internal class DefaultRazorEngineDirectiveResolver : IRazorEngineDirectiveResolver
{
public async Task<IEnumerable<DirectiveDescriptor>> GetRazorEngineDirectivesAsync(Workspace workspace, Project project, CancellationToken cancellationToken = default(CancellationToken))
{
var client = await RazorLanguageServiceClientFactory.CreateAsync(workspace, cancellationToken);
using (var session = await client.CreateSessionAsync(project.Solution))
{
var directives = await session.InvokeAsync<IEnumerable<DirectiveDescriptor>>("GetDirectivesAsync", new object[] { project.Id.Id, "Foo" }).ConfigureAwait(false);
return directives;
}
}
}
}

View File

@ -0,0 +1,25 @@
// 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.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
[Export(typeof(IRazorEngineDocumentGenerator))]
internal class DefaultRazorEngineDocumentGenerator : IRazorEngineDocumentGenerator
{
public async Task<RazorEngineDocument> GenerateDocumentAsync(Workspace workspace, Project project, string filename, string text, CancellationToken cancellationToken = default(CancellationToken))
{
var client = await RazorLanguageServiceClientFactory.CreateAsync(workspace, cancellationToken);
using (var session = await client.CreateSessionAsync(project.Solution))
{
var document = await session.InvokeAsync<RazorEngineDocument>("GenerateDocumentAsync", new object[] { project.Id.Id, "Foo", filename, text }).ConfigureAwait(false);
return document;
}
}
}
}

View File

@ -0,0 +1,30 @@
// 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.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
using Microsoft.CodeAnalysis;
using System.Composition;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
[Export(typeof(IRazorEngineTagHelperResolver))]
internal class DefaultRazorEngineTagHelperResolver : IRazorEngineTagHelperResolver
{
public async Task<IEnumerable<TagHelperDescriptor>> GetRazorEngineTagHelpersAsync(Workspace workspace, Project project)
{
var client = await RazorLanguageServiceClientFactory.CreateAsync(workspace, CancellationToken.None);
using (var session = await client.CreateSessionAsync(project.Solution))
{
var results = await session.InvokeAsync<IEnumerable<TagHelperDescriptor>>("GetTagHelpersAsync", new object[] { project.Id.Id, "Foo" }).ConfigureAwait(false);
return results;
}
}
}
}

View File

@ -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 System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal interface IRazorEngineAssemblyResolver
{
Task<IEnumerable<RazorEngineAssembly>> GetRazorEngineAssembliesAsync(Project project);
}
}

View File

@ -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 System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal interface IRazorEngineDirectiveResolver
{
Task<IEnumerable<DirectiveDescriptor>> GetRazorEngineDirectivesAsync(Workspace workspace, Project project, CancellationToken cancellationToken = default(CancellationToken));
}
}

View File

@ -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 System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal interface IRazorEngineDocumentGenerator
{
Task<RazorEngineDocument> GenerateDocumentAsync(Workspace workspace, Project project, string filename, string text, CancellationToken cancellationToken = default(CancellationToken));
}
}

View File

@ -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.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
using Microsoft.CodeAnalysis;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal interface IRazorEngineTagHelperResolver
{
Task<IEnumerable<TagHelperDescriptor>> GetRazorEngineTagHelpersAsync(Workspace workspace, Project project);
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>net46</TargetFrameworks>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<RootNamespace>Microsoft.VisualStudio.LanguageServices.Razor</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<PropertyGroup>
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="2.0.0-rc3-*" />
<PackageReference Include="Microsoft.VisualStudio.LanguageServices.Razor.RemoteClient" Version="2.0.0-rc3-*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.CodeAnalysis.Razor.Workspaces\Microsoft.CodeAnalysis.Razor.Workspaces.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Evolution\Microsoft.AspNetCore.Razor.Evolution.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,7 @@
// 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;
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

View File

@ -0,0 +1,31 @@
// 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;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal struct RazorEngineAssembly
{
public RazorEngineAssembly(AssemblyIdentity identity, string filePath)
{
if (identity == null)
{
throw new ArgumentNullException(nameof(identity));
}
if (filePath == null)
{
throw new ArgumentNullException(nameof(filePath));
}
Identity = identity;
FilePath = filePath;
}
public string FilePath { get; }
public AssemblyIdentity Identity { get; }
}
}

View File

@ -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.VisualStudio.LanguageServices.Razor
{
internal class RazorEngineDocument
{
public string Text { get; set; }
}
}

View File

@ -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.
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
internal static class ReflectionNames
{
public static readonly string RazorAssemblyName = "Microsoft.AspNetCore.Razor.Evolution";
public static readonly string CustomizationAttribute = RazorAssemblyName + ".RazorEngineCustomizationAttribute";
public static readonly string DependencyAttribute = RazorAssemblyName + ".RazorEngineDependencyAttribute";
}
}