c# - ver - show references visual studio 2017 community
Encontrar todas las referencias a un método con Roslyn. (2)
Estoy buscando escanear un grupo de archivos .cs para ver cuáles llaman a la propiedad Value
de un Nullable<T>
(encontrar todas las referencias). Por ejemplo, esto coincidiría con:
class Program
{
static void Main()
{
int? nullable = 123;
int value = nullable.Value;
}
}
Me enteré de Roslyn y miré algunas de las muestras, pero muchas de ellas están desactualizadas y la API es enorme. ¿Cómo voy a hacer esto?
Estoy atascado después de analizar el árbol de sintaxis. Esto es lo que tengo hasta ahora:
public static void Analyze(string sourceCode)
{
var tree = CSharpSyntaxTree.ParseText(sourceCode);
tree./* ??? What goes here? */
}
Un diario de problemas, y eventuales soluciones, conseguí que Roslyn trabajara con VS2017:
El motivo de los proyectos VS2017 vacíos se hace visible cuando el evento MSBuildWorkspace WorkspaceFailed está conectado.
La primera ronda de fallos fue:
MSB0001: Error interno de MSBuild: La información de tipo para Microsoft.Build.Utilities.ToolLocationHelper estaba presente en el caché de la lista blanca como Microsoft.Build.Utilities.ToolLocationHelper, Microsoft.Build.Utilities.Core, Version = 15.1.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a pero no se pudo cargar el tipo. inesperadamente nulo])
Esto se solucionó instalando los paquetes NuGet Microsoft.Build.Locator 1.1.2 y Microsoft.Build.Utilities.Core 15.9.20
La segunda ronda de fallos fue:
Msbuild falló al procesar el archivo ''C: / Users ... vbproj'' con el mensaje: C: / Archivos de programa (x86) / Microsoft Visual Studio / 2017 / Enterprise / MSBuild / 15.0 / Bin / Microsoft.Common.CurrentVersion.targets: (1491, 5): La tarea "Microsoft.Build.Tasks.AssignProjectConfiguration" no se pudo cargar desde el ensamblado Microsoft.Build.Tasks.Core, versión = 15.1.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a. No se pudo cargar el archivo o el ensamblaje ''Microsoft.Build.Tasks.Core, Version = 15.1.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a'' o una de sus dependencias. El sistema no puede encontrar el archivo especificado. Confirme que la declaración es correcta, que el ensamblaje y todas sus dependencias están disponibles y que la tarea contiene una clase pública que implementa Microsoft.Build.Framework.ITask.])
Esto se solucionó agregando NuGet Microsoft.Build.Tasks.Core 15.9.20
La tercera ronda de fallas fue: === Msbuild falló al procesar el archivo ''C: / Users ... vbproj'' con el mensaje: C: / Archivos de programa (x86) / Microsoft Visual Studio / 2017 / Enterprise / MSBuild / 15.0 / Bin / Microsoft.Common.CurrentVersion.targets: (1657, 5): La tarea "GetReferenceNearestTargetFrameworkTask" no se pudo crear una instancia desde el ensamblaje "C: / Archivos de programa (x86) / Microsoft Visual Studio / 2017 / Enterprise / Common7 / IDE / CommonExtensions / Microsoft / NuGet / NuGet.Build.Tasks.dll ". Verifique que el conjunto de tareas se haya creado utilizando la misma versión del conjunto Microsoft.Build.Framework que el instalado en su computadora y que a su aplicación host no le falte un redireccionamiento de enlaces para Microsoft.Build.Framework. No se puede convertir el objeto de tipo ''NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask'' para escribir ''Microsoft.Build.Framework.ITask''.])
Tenga en cuenta que Microsoft.Build.Framework.dll del proyecto = 15.1.0.0 pero el mensaje menciona "MSBuild / 15.0 / Bin"
Añadiendo a app.config - lo arreglamos! cf ingrese la descripción del enlace aquí ahora puedo cargar proyectos desde soluciones VS2017
<!-- vvv Roslyn manual fixup https://github.com/Microsoft/msbuild/issues/2369 -->
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Utilities.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Tasks.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.1.0.0" newVersion="15.1.0.0" />
</dependentAssembly>
<!-- ^^^ Roslyn manual fixup https://github.com/Microsoft/msbuild/issues/2369 -->
Probablemente estés buscando la clase de SymbolFinder
y específicamente el método FindAllReferences
.
Parece que estás teniendo problemas para familiarizarte con Roslyn. Tengo una serie de publicaciones en el blog para ayudar a las personas a conocer a Roslyn llamada Learn Roslyn Now .
Como @SLaks menciona, necesitará acceso al modelo semántico que cubro en la Parte 7: Introducción al modelo semántico
Aquí hay una muestra que muestra cómo se puede usar la API. Si puede, usaría MSBuildWorkspace
y cargaría el proyecto desde el disco en lugar de crearlo en un AdHocWorkspace
como este.
var mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var ws = new AdhocWorkspace();
//Create new solution
var solId = SolutionId.CreateNewId();
var solutionInfo = SolutionInfo.Create(solId, VersionStamp.Create());
//Create new project
var project = ws.AddProject("Sample", "C#");
project = project.AddMetadataReference(mscorlib);
//Add project to workspace
ws.TryApplyChanges(project.Solution);
string text = @"
class C
{
void M()
{
M();
M();
}
}";
var sourceText = SourceText.From(text);
//Create new document
var doc = ws.AddDocument(project.Id, "NewDoc", sourceText);
//Get the semantic model
var model = doc.GetSemanticModelAsync().Result;
//Get the syntax node for the first invocation to M()
var methodInvocation = doc.GetSyntaxRootAsync().Result.DescendantNodes().OfType<InvocationExpressionSyntax>().First();
var methodSymbol = model.GetSymbolInfo(methodInvocation).Symbol;
//Finds all references to M()
var referencesToM = SymbolFinder.FindReferencesAsync(methodSymbol, doc.Project.Solution).Result;