Skip to content

Commit

Permalink
Fix for Roslyn Syntax Tree Isolation (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwhitfield authored Oct 5, 2023
1 parent 7520d86 commit 1c00070
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/Unitverse.Core/Helpers/ISemanticModelLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Unitverse.Core.Helpers
{
using Microsoft.CodeAnalysis;

public interface ISemanticModelLoader
{
public SemanticModel GetSemanticModel(SyntaxNode node);
}
}
11 changes: 5 additions & 6 deletions src/Unitverse.Core/Helpers/InvocationExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
{
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand Down Expand Up @@ -67,8 +66,8 @@ public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax no
{
if (_targetFields.Contains(fieldTarget))
{
var symbolInfo = _semanticModel.GetSymbolInfo(node);
if (symbolInfo.Symbol is IPropertySymbol propertySymbol)
var symbolInfo = _semanticModel.GetSymbolInfoSafe(node);
if (symbolInfo?.Symbol is IPropertySymbol propertySymbol)
{
if (!(node.Parent is AssignmentExpressionSyntax assignment) || node != assignment.Left)
{
Expand All @@ -90,8 +89,8 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
{
if (_targetFields.Contains(fieldTarget))
{
var symbolInfo = _semanticModel.GetSymbolInfo(node);
if (symbolInfo.Symbol is IMethodSymbol methodSymbol)
var symbolInfo = _semanticModel.GetSymbolInfoSafe(node);
if (symbolInfo?.Symbol is IMethodSymbol methodSymbol)
{
// if ReducedFrom is non-null, this is actually an extension method call
if (methodSymbol.ReducedFrom is null)
Expand Down Expand Up @@ -147,7 +146,7 @@ private bool GetFieldTarget(ExpressionSyntax expressionSyntax, out string fieldT

private MethodDeclarationSyntax? GetInvokedMethodDeclaration(ExpressionSyntax invocationExpression)
{
var symbol = _semanticModel.GetSymbolInfo(invocationExpression).Symbol;
var symbol = _semanticModel.GetSymbolInfoSafe(invocationExpression)?.Symbol;

if (symbol == null
|| symbol.Kind != SymbolKind.Method
Expand Down
34 changes: 34 additions & 0 deletions src/Unitverse.Core/Helpers/SemanticModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,39 @@ public static class SemanticModelExtensions

return symbol.ContainingType;
}

public static SymbolInfo? GetSymbolInfoSafe(this SemanticModel semanticModel, SyntaxNode node)
{
if (semanticModel.SyntaxTree == node.SyntaxTree)
{
return semanticModel.GetSymbolInfo(node);
}

var loader = SemanticModelLoaderProvider.ModelLoader;
if (loader != null)
{
var model = loader.GetSemanticModel(node);
return model.GetSymbolInfo(node);
}

return null;
}

public static ISymbol? GetDeclaredSymbolSafe(this SemanticModel semanticModel, SyntaxNode node)
{
if (semanticModel.SyntaxTree == node.SyntaxTree)
{
return semanticModel.GetDeclaredSymbol(node);
}

var loader = SemanticModelLoaderProvider.ModelLoader;
if (loader != null)
{
var model = loader.GetSemanticModel(node);
return model.GetDeclaredSymbol(node);
}

return null;
}
}
}
7 changes: 7 additions & 0 deletions src/Unitverse.Core/Helpers/SemanticModelLoaderProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Unitverse.Core.Helpers
{
public static class SemanticModelLoaderProvider
{
public static ISemanticModelLoader? ModelLoader { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/Unitverse/Helper/TargetFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private static async Task<string> FindTargetByTypeAsync(ISymbol symbol, ProjectI

if (firstType != null && !firstType.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))
{
symbol = semanticModel.GetDeclaredSymbol(firstType);
symbol = semanticModel.GetDeclaredSymbolSafe(firstType);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Unitverse/IUnitTestGeneratorPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.Threading;
using NuGet.VisualStudio;
using Unitverse.Core.Helpers;
using Unitverse.Core.Options;
using Unitverse.Core.Options.Editing;

public interface IUnitTestGeneratorPackage : IServiceProvider, IConfigurationWriter
public interface IUnitTestGeneratorPackage : IServiceProvider, IConfigurationWriter, ISemanticModelLoader
{
JoinableTaskFactory JoinableTaskFactory { get; }

Expand Down
12 changes: 9 additions & 3 deletions src/Unitverse/UnitTestGeneratorPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Media.Animation;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices;
Expand All @@ -16,6 +14,7 @@
using NuGet.VisualStudio;
using Unitverse.Commands;
using Unitverse.Core;
using Unitverse.Core.Helpers;
using Unitverse.Core.Options;
using Unitverse.Editor;
using Unitverse.Options;
Expand Down Expand Up @@ -148,6 +147,13 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
await GenerateTestForSymbolCommand.InitializeAsync(this).ConfigureAwait(true);
await GoToUnitTestsForSymbolCommand.InitializeAsync(this).ConfigureAwait(true);
await CreateTestProjectCommand.InitializeAsync(this).ConfigureAwait(true);

SemanticModelLoaderProvider.ModelLoader = this;
}

public SemanticModel GetSemanticModel(SyntaxNode node)
{
return JoinableTaskFactory.Run(() => Workspace.CurrentSolution.GetDocument(node.SyntaxTree).GetSemanticModelAsync());
}
}
}

0 comments on commit 1c00070

Please sign in to comment.