IEnumerable <string> GetGroups(CSharpSyntaxContext ctx, ISymbol symbol) { var root = ctx.SyntaxTree.GetRoot(); foreach (var decl in symbol.DeclaringSyntaxReferences) { Optional <object> val = null; var node = root.FindNode(decl.Span) as VariableDeclaratorSyntax; if (node == null) { continue; } var invocation = node.Initializer.Value as InvocationExpressionSyntax; var invocationSymbol = ctx.SemanticModel.GetSymbolInfo(invocation).Symbol; if (invocationSymbol.Name == "Match" && SemanticHighlightingVisitor <string> .IsRegexType(invocationSymbol.ContainingType)) { if (invocation.ArgumentList.Arguments.Count == 1) { var memberAccess = invocation.Expression as MemberAccessExpressionSyntax; if (memberAccess == null) { continue; } var target = ctx.SemanticModel.GetSymbolInfo(memberAccess.Expression).Symbol; if (target.DeclaringSyntaxReferences.Length == 0) { continue; } var targetNode = root.FindNode(target.DeclaringSyntaxReferences.First().Span) as VariableDeclaratorSyntax; if (targetNode == null) { continue; } var objectCreation = targetNode.Initializer.Value as ObjectCreationExpressionSyntax; if (objectCreation == null) { continue; } var targetNodeSymbol = ctx.SemanticModel.GetSymbolInfo(objectCreation).Symbol; if (SemanticHighlightingVisitor <string> .IsRegexType(targetNodeSymbol.ContainingType)) { if (objectCreation.ArgumentList.Arguments.Count < 1) { continue; } val = ctx.SemanticModel.GetConstantValue(objectCreation.ArgumentList.Arguments [0].Expression); } } else { if (invocation.ArgumentList.Arguments.Count < 2) { continue; } val = ctx.SemanticModel.GetConstantValue(invocation.ArgumentList.Arguments [1].Expression); } if (!val.HasValue) { continue; } var str = val.Value.ToString(); int idx = -1; while ((idx = str.IndexOf("(?<", idx + 1, StringComparison.Ordinal)) >= 0) { var closingIndex = str.IndexOf(">", idx, StringComparison.Ordinal); if (closingIndex >= idx) { yield return(str.Substring(idx + 3, closingIndex - idx - 3)); idx = closingIndex - 1; } } } } }
public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context) { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false); var workspace = document.Project.Solution.Workspace; var ctx = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken); if (context.Trigger.Character == '\\') { if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument)) { var argument = ctx.TargetToken.Parent.Parent as ArgumentSyntax; var symbolInfo = semanticModel.GetSymbolInfo(ctx.TargetToken.Parent.Parent.Parent.Parent); if (symbolInfo.Symbol == null) { return; } if (SemanticHighlightingVisitor <string> .IsRegexMatchMethod(symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument) { return; } AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@'); return; } if (SemanticHighlightingVisitor <string> .IsRegexConstructor(symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument) { return; } AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@'); return; } } } else { var ma = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (ma != null) { var symbolInfo = semanticModel.GetSymbolInfo(ma.Expression); var typeInfo = semanticModel.GetTypeInfo(ma.Expression); var type = typeInfo.Type; if (type != null && type.Name == "Match" && type.ContainingNamespace.GetFullName() == "System.Text.RegularExpressions") { foreach (var grp in GetGroups(ctx, symbolInfo.Symbol)) { context.AddItem(FormatItemCompletionProvider.CreateCompletionItem("Groups[\"" + grp + "\"]", null, null)); } } } } }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var semanticModel = ctx.SemanticModel; if (info.TriggerCharacter == '\\') { if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument)) { var argument = ctx.TargetToken.Parent.Parent as ArgumentSyntax; var symbolInfo = semanticModel.GetSymbolInfo(ctx.TargetToken.Parent.Parent.Parent.Parent); if (symbolInfo.Symbol == null) { return(Enumerable.Empty <CompletionData> ()); } if (SemanticHighlightingVisitor <int> .IsRegexMatchMethod(symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument) { return(Enumerable.Empty <CompletionData> ()); } completionResult.AutoSelect = false; return(GetFormatCompletionData(engine, argument.Expression.ToString() [0] == '@')); } if (SemanticHighlightingVisitor <int> .IsRegexConstructor(symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument) { return(Enumerable.Empty <CompletionData> ()); } completionResult.AutoSelect = false; return(GetFormatCompletionData(engine, argument.Expression.ToString() [0] == '@')); } } } else { var ma = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (ma != null) { var symbolInfo = semanticModel.GetSymbolInfo(ma.Expression); var typeInfo = semanticModel.GetTypeInfo(ma.Expression); var type = typeInfo.Type; if (type != null && type.Name == "Match" && type.ContainingNamespace.GetFullName() == "System.Text.RegularExpressions") { var items = new List <CompletionData>(); foreach (var grp in GetGroups(ctx, symbolInfo.Symbol)) { items.Add(engine.Factory.CreateGenericData(this, "Groups[\"" + grp + "\"]", GenericDataType.Undefined)); } return(items); } } } return(Enumerable.Empty <CompletionData> ()); }