-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
alejandro
committed
Jan 6, 2023
1 parent
602eb53
commit 58e5cc9
Showing
17 changed files
with
842 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace NavigateToHandlerPubSub | ||
{ | ||
[Command(PackageIds.ShowHandlersCommand)] | ||
internal sealed class MyToolWindowCommand : BaseCommand<MyToolWindowCommand> | ||
{ | ||
protected override async Task ExecuteAsync(OleMenuCmdEventArgs e) | ||
{ | ||
await MyToolWindow.ShowAsync(); | ||
|
||
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); | ||
ThreadHelper.JoinableTaskFactory.RunAsync(async () => | ||
{ | ||
ToolWindowMessenger messenger = await Package.GetServiceAsync<ToolWindowMessenger, ToolWindowMessenger>(); | ||
messenger.Send("Refresh Handlers Files"); | ||
}).FireAndForget(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
using Microsoft.Build.Framework.XamlTypes; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.FindSymbols; | ||
using Microsoft.CodeAnalysis.Text; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace NavigateToHandlerPubSub.Logic | ||
{ | ||
public class FindHandler | ||
{ | ||
public async Task<List<IdentifiedHandler>> FindHandlersAsync(Microsoft.CodeAnalysis.Solution solution, Document workingDocument, int linePosition, string projectName) | ||
{ | ||
var syntaxRoot = await workingDocument.GetSyntaxRootAsync(); | ||
var syntaxNode = syntaxRoot?.FindNode(new TextSpan(linePosition, 0), true, true); | ||
|
||
// Get type information | ||
|
||
var semanticModel = await workingDocument.GetSemanticModelAsync(); | ||
await VS.StatusBar.ShowProgressAsync("Get document model", 2, 3); | ||
|
||
var symbol = GetTypeInfo(semanticModel, syntaxNode); | ||
|
||
var handlers = await GetEventHandlerReferencesAsync(symbol, solution, projectName); | ||
await VS.StatusBar.ShowProgressAsync("Getting references", 3, 3); | ||
|
||
return handlers; | ||
} | ||
|
||
private ITypeSymbol GetTypeInfo(SemanticModel semanticModel, SyntaxNode syntaxNode) | ||
{ | ||
if (syntaxNode is VariableDeclaratorSyntax variableDeclarator) | ||
{ | ||
return semanticModel.GetTypeInfo(((VariableDeclarationSyntax)variableDeclarator.Parent).Type).Type; | ||
} | ||
if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax) | ||
{ | ||
return semanticModel.GetDeclaredSymbol(typeDeclarationSyntax); | ||
} | ||
if (syntaxNode is IdentifierNameSyntax identifierName) | ||
{ | ||
var accessSymbol = semanticModel.GetSymbolInfo(identifierName.Parent); | ||
IMethodSymbol methodSymbol = (IMethodSymbol)accessSymbol.Symbol; | ||
if (methodSymbol == null) return null; | ||
|
||
var returnType = (INamedTypeSymbol)methodSymbol.ReceiverType; | ||
return returnType; | ||
} | ||
|
||
return semanticModel.GetTypeInfo(syntaxNode).Type; | ||
} | ||
|
||
private async Task<List<IdentifiedHandler>> GetEventHandlerReferencesAsync(ITypeSymbol symbol, Microsoft.CodeAnalysis.Solution solution, string projectName) | ||
{ | ||
if (symbol == null) | ||
return default; | ||
|
||
List<IdentifiedHandler> handlers = new(); | ||
|
||
IEnumerable<ReferencedSymbol> references = default; | ||
ImmutableArray<ITypeSymbol> arguments = default; | ||
|
||
if (symbol is INamedTypeSymbol named) | ||
{ | ||
arguments = named.TypeArguments; | ||
|
||
if (arguments.Any()) | ||
{ | ||
symbol = arguments.First(); | ||
} | ||
} | ||
references = await SymbolFinder.FindReferencesAsync(symbol, solution); | ||
|
||
foreach (var reference in references) | ||
{ | ||
var locations = string.IsNullOrWhiteSpace(projectName) ? | ||
reference.Locations | ||
: reference.Locations.Where(l => l.Document.Project.AssemblyName == projectName); | ||
|
||
foreach (var location in locations) | ||
{ | ||
var tree = await location.Document.GetSyntaxTreeAsync(); | ||
var root = await tree.GetRootAsync(); | ||
var allMethods = root.DescendantNodes().OfType<MethodDeclarationSyntax>(); | ||
var publicMethods = default(IEnumerable<MethodDeclarationSyntax>); | ||
publicMethods = allMethods.Where(publicMethod => | ||
publicMethod.Modifiers.Any(modifier => modifier.Text.Equals("public")) && | ||
publicMethod.ToFullString().Contains("HandleAsync") && | ||
publicMethod.ParameterList.Parameters.Any(parameter => parameter.ToFullString().Contains(symbol.Name))); | ||
|
||
if (!publicMethods.Any()) | ||
continue; | ||
|
||
if (arguments != default && arguments.Count() > 1) | ||
{ | ||
var argumentName = arguments.Last().ToString(); | ||
var argumentParsed = argumentName.Split('.'); | ||
|
||
if (argumentParsed.Count() > 1) | ||
argumentName = argumentParsed.Last(); | ||
publicMethods = publicMethods.Where(publicMethod => publicMethod.ReturnType.ToFullString().Contains(argumentName)); | ||
|
||
if (!publicMethods.Any()) | ||
continue; | ||
} | ||
|
||
if (!handlers.Any(x => x.SourceFile == location.Document.FilePath)) | ||
handlers.Add(new IdentifiedHandler | ||
{ | ||
FileName = location.Document.Name, | ||
SourceFile = location.Document.FilePath, | ||
LineNumber = publicMethods.First().SpanStart | ||
}); | ||
} | ||
} | ||
|
||
return handlers; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using System.ComponentModel; | ||
|
||
namespace NavigateToHandlerPubSub.Logic | ||
{ | ||
public class IdentifiedHandler : INotifyPropertyChanged | ||
{ | ||
private string fileName; | ||
public string FileName | ||
{ | ||
get | ||
{ | ||
return fileName; | ||
} | ||
set | ||
{ | ||
if (fileName != value) | ||
{ | ||
fileName = value; | ||
OnPropertyChanged("FileName"); | ||
} | ||
} | ||
} | ||
private string sourceFile; | ||
public string SourceFile | ||
{ | ||
get | ||
{ | ||
return sourceFile; | ||
} | ||
set | ||
{ | ||
if (sourceFile != value) | ||
{ | ||
sourceFile = value; | ||
OnPropertyChanged("SourceFile"); | ||
} | ||
} | ||
} | ||
|
||
private int lineNumber; | ||
public int LineNumber | ||
{ | ||
get | ||
{ | ||
return lineNumber; | ||
} | ||
set | ||
{ | ||
if (lineNumber != value) | ||
{ | ||
lineNumber = value; | ||
OnPropertyChanged("LineNumber"); | ||
} | ||
} | ||
} | ||
|
||
public event PropertyChangedEventHandler PropertyChanged; | ||
private void OnPropertyChanged(String info) | ||
{ | ||
PropertyChangedEventHandler handler = PropertyChanged; | ||
if (handler != null) | ||
{ | ||
handler(this, new PropertyChangedEventArgs(info)); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | ||
<LangVersion>latest</LangVersion> | ||
</PropertyGroup> | ||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<ProjectGuid>{0A887131-CD6F-4B38-9305-A00ED936AB29}</ProjectGuid> | ||
<OutputType>Library</OutputType> | ||
<AppDesignerFolder>Properties</AppDesignerFolder> | ||
<RootNamespace>NavigateToHandlerPubSub</RootNamespace> | ||
<AssemblyName>NavigateToHandlerPubSub</AssemblyName> | ||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> | ||
<GeneratePkgDefFile>true</GeneratePkgDefFile> | ||
<UseCodebase>true</UseCodebase> | ||
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer> | ||
<IncludeDebugSymbolsInVSIXContainer>true</IncludeDebugSymbolsInVSIXContainer> | ||
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment> | ||
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory> | ||
<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory> | ||
<StartAction>Program</StartAction> | ||
<StartProgram Condition="'$(DevEnvDir)' != ''">$(DevEnvDir)devenv.exe</StartProgram> | ||
<StartArguments>/rootsuffix Exp</StartArguments> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<DebugSymbols>true</DebugSymbols> | ||
<DebugType>full</DebugType> | ||
<Optimize>false</Optimize> | ||
<OutputPath>bin\Debug\</OutputPath> | ||
<DefineConstants>DEBUG;TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<DebugType>pdbonly</DebugType> | ||
<Optimize>true</Optimize> | ||
<OutputPath>bin\Release\</OutputPath> | ||
<DefineConstants>TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="Logic\FindHandler.cs" /> | ||
<Compile Include="Logic\IdentifiedHandler.cs" /> | ||
<Compile Include="Properties\AssemblyInfo.cs" /> | ||
<Compile Include="Commands\MyToolWindowCommand.cs" /> | ||
<Compile Include="NavigateToHandlerPubSubPackage.cs" /> | ||
<Compile Include="source.extension.cs"> | ||
<AutoGen>True</AutoGen> | ||
<DesignTime>True</DesignTime> | ||
<DependentUpon>source.extension.vsixmanifest</DependentUpon> | ||
</Compile> | ||
<Compile Include="ToolWindowMessenger.cs" /> | ||
<Compile Include="ToolWindows\SelectionContextItem.cs" /> | ||
<Compile Include="VSCommandTable.cs"> | ||
<AutoGen>True</AutoGen> | ||
<DesignTime>True</DesignTime> | ||
<DependentUpon>VSCommandTable.vsct</DependentUpon> | ||
</Compile> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="source.extension.vsixmanifest"> | ||
<SubType>Designer</SubType> | ||
<Generator>VsixManifestGenerator</Generator> | ||
<LastGenOutput>source.extension.cs</LastGenOutput> | ||
</None> | ||
<Content Include="Resources\Icon.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
<IncludeInVSIX>true</IncludeInVSIX> | ||
</Content> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<VSCTCompile Include="VSCommandTable.vsct"> | ||
<ResourceName>Menus.ctmenu</ResourceName> | ||
<Generator>VsctGenerator</Generator> | ||
<LastGenOutput>VSCommandTable.cs</LastGenOutput> | ||
</VSCTCompile> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="ToolWindows\MyToolWindow.cs" /> | ||
<Page Include="ToolWindows\MyToolWindowControl.xaml"> | ||
<SubType>Designer</SubType> | ||
<Generator>MSBuild:Compile</Generator> | ||
</Page> | ||
<Compile Include="ToolWindows\MyToolWindowControl.xaml.cs"> | ||
<DependentUpon>MyToolWindowControl.xaml</DependentUpon> | ||
</Compile> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Reference Include="System" /> | ||
<Reference Include="System.Design" /> | ||
<Reference Include="System.Xaml" /> | ||
<Reference Include="PresentationCore" /> | ||
<Reference Include="PresentationFramework" /> | ||
<Reference Include="WindowsBase" /> | ||
<Reference Include="System.ComponentModel.Composition" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Community.VisualStudio.VSCT" Version="16.0.29.6" PrivateAssets="all" /> | ||
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.486" ExcludeAssets="Runtime"> | ||
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"> | ||
<Version>4.4.0</Version> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.VisualStudio.Imaging"> | ||
<Version>17.0.31723.112</Version> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.VisualStudio.LanguageServices"> | ||
<Version>4.4.0</Version> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.VisualStudio.SDK"> | ||
<Version>17.4.33103.184</Version> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0"> | ||
<Version>17.0.31723.112</Version> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.4.2119"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" /> | ||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||
Other similar extension points exist, see Microsoft.Common.targets. | ||
<Target Name="BeforeBuild"> | ||
</Target> | ||
<Target Name="AfterBuild"> | ||
</Target> | ||
--> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.4.33205.214 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NavigateToHandlerPubSub", "NavigateToHandlerPubSub.csproj", "{0A887131-CD6F-4B38-9305-A00ED936AB29}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Debug|arm64 = Debug|arm64 | ||
Debug|x86 = Debug|x86 | ||
Release|Any CPU = Release|Any CPU | ||
Release|arm64 = Release|arm64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|arm64.ActiveCfg = Debug|arm64 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|arm64.Build.0 = Debug|arm64 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|x86.ActiveCfg = Debug|x86 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Debug|x86.Build.0 = Debug|x86 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|arm64.ActiveCfg = Release|arm64 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|arm64.Build.0 = Release|arm64 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|x86.ActiveCfg = Release|x86 | ||
{0A887131-CD6F-4B38-9305-A00ED936AB29}.Release|x86.Build.0 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {6CF82DC8-FBF6-4430-9622-5E02D7C8B399} | ||
EndGlobalSection | ||
EndGlobal |
Oops, something went wrong.