public async Task Visit(DataStructure dataStructure) { var project = dataStructure.Project; if (project == null) { return; } var projectPath = dataStructure.ProjectDirectory; var POEntries = dataStructure.LocalizerEntries; var solution = project.Solution; var documents = project.Documents.Where(d => d.SupportsSyntaxTree); var LocalizerMethods = new List <LocalizationMethod>() { new LocalizationMethod("IStringLocalizer", "get_Item", false), new LocalizationMethod("StringLocalizerExtensions", "GetString", false), new LocalizationMethod("IHtmlLocalizer", "get_Item", false), new LocalizationMethod("IHtmlLocalizer", "GetString", false), new LocalizationMethod("ValidationAttribute", "set_ErrorMessage", false), new LocalizationMethod("DisplayAttribute", "set_Name", false), new LocalizationMethod("DisplayAttribute", "set_Prompt", false) }; var combinedMethodSymbols = Array.Empty <IMethodSymbol>().AsEnumerable(); foreach (var localizerMethod in LocalizerMethods) { // find DeclarationSymbols var TypeDeclarationSymbols = await SymbolFinder.FindDeclarationsAsync(project, localizerMethod.TypeName, ignoreCase : false); var TypeDeclarationSymbol = TypeDeclarationSymbols.OfType <INamedTypeSymbol>().FirstOrDefault(s => s.IsGenericType.Equals(localizerMethod.IsGenericType)); // find MethodSymbols var methodSymbols = TypeDeclarationSymbol?.GetMembers(localizerMethod.MethodName).OfType <IMethodSymbol>(); // combine MethodSymbols combinedMethodSymbols = combinedMethodSymbols.Union(methodSymbols); } foreach (var methodSymbol in combinedMethodSymbols) { //find method referenced location var methodReferencedLocations = (await SymbolFinder.FindReferencesAsync(methodSymbol, solution)).Where(r => r.Locations.Any()); foreach (var referencedSymbol in methodReferencedLocations) { foreach (var location in referencedSymbol.Locations) { var textSpan = location.Location.SourceSpan; var document = location.Document; var rootSyntaxNode = await document.GetSyntaxRootAsync(); var syntaxTree = await document.GetSyntaxTreeAsync(); var node = rootSyntaxNode.FindNode(textSpan); var parent = node.Parent; var lineNumber = node.GetLocation().GetLineSpan().StartLinePosition.Line; var sourceFile = Path.IsPathRooted(syntaxTree.FilePath) ? Path.GetRelativePath(projectPath, syntaxTree.FilePath) : syntaxTree.FilePath; var sourceFileLine = lineNumber + 1; var code = syntaxTree.GetText().Lines[lineNumber].ToString().Trim(); // mapping *.cshtml.g.cs to *.cshtml if (sourceFile.EndsWith(".cshtml.g.cs") && rootSyntaxNode.GetLeadingTrivia().FirstOrDefault(t => t.IsKind(SyntaxKind.PragmaChecksumDirectiveTrivia)).GetStructure() is PragmaChecksumDirectiveTriviaSyntax pragmaChecksumDirectiveTriviaSyntax) { var razorSourceFile = pragmaChecksumDirectiveTriviaSyntax.File.ValueText; if (string.IsNullOrEmpty(razorSourceFile) && rootSyntaxNode is CompilationUnitSyntax compilationUnitSyntax) { var attributeList = compilationUnitSyntax.AttributeLists .Select(list => list.Attributes.FirstOrDefault(a => a.ToString().Contains("Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute"))) .FirstOrDefault(a => a != null && a.ArgumentList.Arguments.Count == 3); if (attributeList?.ArgumentList.Arguments[2].Expression is LiteralExpressionSyntax literalExpressionSyntax) { razorSourceFile = Path.Combine(projectPath, literalExpressionSyntax.Token.ValueText[1..^ 0].Replace('/', Path.DirectorySeparatorChar));
public async Task Visit(DataStructure dataStructure) { _data = dataStructure; dataStructure.Project = await OpenProjectWithRazorGenerateCommandAsync(dataStructure.ProjectDirectory); }