private ISet <INamespaceSymbol> GetNamespacesInScope(CancellationToken cancellationToken) { // Add all the namespaces brought in by imports/usings. var set = _owner.GetImportNamespacesInScope( _semanticModel, _node, cancellationToken ); // Also add all the namespaces we're contained in. We don't want // to add imports for these namespaces either. for ( var containingNamespace = _semanticModel.GetEnclosingNamespace( _node.SpanStart, cancellationToken ); containingNamespace != null; containingNamespace = containingNamespace.ContainingNamespace ) { set.Add(MapToCompilationNamespaceIfPossible(containingNamespace)); } return(set); }
private bool DetermineNamespaceOrTypeToGenerateInWorker( TService service, SemanticModel semanticModel, CancellationToken cancellationToken ) { // If we're on the right of a dot, see if we can figure out what's on the left. If // it doesn't bind to a type or a namespace, then we can't proceed. if (SimpleName != NameOrMemberAccessExpression) { return(DetermineNamespaceOrTypeToGenerateIn( service, semanticModel, service.GetLeftSideOfDot(SimpleName), cancellationToken )); } else { // The name is standing alone. We can either generate the type into our // containing type, or into our containing namespace. // // TODO(cyrusn): We need to make this logic work if the type is in the // base/interface list of a type. var format = SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle( SymbolDisplayGlobalNamespaceStyle.Omitted ); TypeToGenerateInOpt = service.DetermineTypeToGenerateIn( semanticModel, SimpleName, cancellationToken ); if (TypeToGenerateInOpt != null) { NamespaceToGenerateInOpt = TypeToGenerateInOpt.ContainingNamespace.ToDisplayString(format); } else { var namespaceSymbol = semanticModel.GetEnclosingNamespace( SimpleName.SpanStart, cancellationToken ); if (namespaceSymbol != null) { NamespaceToGenerateInOpt = namespaceSymbol.ToDisplayString(format); } } } return(true); }
private bool IsInsideNamespace(SyntaxNode node, INamespaceSymbol symbol, SemanticModel model, CancellationToken cancellationToken) { var containedNamespace = model.GetEnclosingNamespace(node.SpanStart, cancellationToken); while (containedNamespace != null) { if (containedNamespace.Equals(symbol)) { return(true); } containedNamespace = containedNamespace.ContainingNamespace; } return(false); }
protected static ImmutableArray <ISymbol> GetRecommendedNamespaceNameSymbols( SemanticModel semanticModel, SyntaxNode declarationSyntax, CancellationToken cancellationToken) { if (declarationSyntax == null) { throw new ArgumentNullException(nameof(declarationSyntax)); } var containingNamespaceSymbol = semanticModel.Compilation.GetCompilationNamespace( semanticModel.GetEnclosingNamespace(declarationSyntax.SpanStart, cancellationToken)); var symbols = semanticModel.LookupNamespacesAndTypes(declarationSyntax.SpanStart, containingNamespaceSymbol) .WhereAsArray(recommendationSymbol => IsNonIntersectingNamespace(recommendationSymbol, declarationSyntax)); return(symbols); }
protected static IEnumerable<ISymbol> GetRecommendedNamespaceNameSymbols( SemanticModel semanticModel, SyntaxNode declarationSyntax, CancellationToken cancellationToken) { if (declarationSyntax == null) { throw new ArgumentNullException(nameof(declarationSyntax)); } var containingNamespaceSymbol = semanticModel.Compilation.GetCompilationNamespace( semanticModel.GetEnclosingNamespace(declarationSyntax.SpanStart, cancellationToken)); var symbols = semanticModel.LookupNamespacesAndTypes(declarationSyntax.SpanStart, containingNamespaceSymbol) .Where(recommendationSymbol => IsNonIntersectingNamespace(recommendationSymbol, declarationSyntax)); return symbols; }
IEnumerable <IMethodSymbol> GetExtensionMethods(SemanticModel semanticModel, ITypeSymbol typeToExtend, InvocationExpressionSyntax node, CancellationToken cancellationToken) { var usedNamespaces = new HashSet <string> (); foreach (var un in semanticModel.GetUsingNamespacesInScope(node)) { usedNamespaces.Add(un.GetFullName()); } var enclosingNamespaceName = semanticModel.GetEnclosingNamespace(node.SpanStart, cancellationToken).GetFullName(); var stack = new Stack <INamespaceOrTypeSymbol> (); stack.Push(semanticModel.Compilation.GlobalNamespace); while (stack.Count > 0) { if (cancellationToken.IsCancellationRequested) { break; } var current = stack.Pop(); var currentNs = current as INamespaceSymbol; if (currentNs != null) { foreach (var member in currentNs.GetNamespaceMembers()) { var currentNsName = member.GetFullName(); if (usedNamespaces.Contains(currentNsName) || enclosingNamespaceName == currentNsName || (enclosingNamespaceName.StartsWith(currentNsName, StringComparison.Ordinal) && enclosingNamespaceName [currentNsName.Length] == '.')) { stack.Push(member); } } foreach (var member in currentNs.GetTypeMembers()) { stack.Push(member); } } else { var type = (INamedTypeSymbol)current; if (type.IsImplicitClass || type.IsScriptClass) { continue; } if (type.DeclaredAccessibility != Accessibility.Public) { if (type.DeclaredAccessibility != Accessibility.Internal) { continue; } if (!type.IsAccessibleWithin(semanticModel.Compilation.Assembly)) { continue; } } if (!type.MightContainExtensionMethods) { continue; } foreach (var extMethod in type.GetMembers().OfType <IMethodSymbol> ().Where(method => method.IsExtensionMethod)) { var reducedMethod = extMethod.ReduceExtensionMethod(typeToExtend); if (reducedMethod != null) { yield return(reducedMethod); } } } } }
internal void AddImportCompletionData(CSharpSyntaxContext ctx, CompletionDataList result, SemanticModel semanticModel, int position, CancellationToken cancellationToken = default(CancellationToken)) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } if (semanticModel == null) { throw new ArgumentNullException(nameof(semanticModel)); } try { if (result.Count == 0 || position < 0) { return; } var syntaxTree = semanticModel.SyntaxTree; var root = syntaxTree.GetRoot(); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return; } var extensionMethodImport = syntaxTree.IsRightOfDotOrArrowOrColonColon( position, syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position), cancellationToken); ITypeSymbol extensionMethodReceiverType = null; if (extensionMethodImport) { if (ctx.TargetToken.Parent is MemberAccessExpressionSyntax memberAccess) { var symbol = ctx.SemanticModel.GetSymbolInfo(memberAccess.Expression).Symbol; if (symbol != null && symbol.Kind == SymbolKind.NamedType) { return; } extensionMethodReceiverType = ctx.SemanticModel.GetTypeInfo(memberAccess.Expression).Type; if (extensionMethodReceiverType == null) { return; } } else { return; } } var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); if (extensionMethodImport || syntaxTree.IsGlobalStatementContext(position, cancellationToken) || syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) || syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsTypeContext(position, cancellationToken) || syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsLabelContext(position, cancellationToken)) { var usedNamespaces = new HashSet <string> (); var node = root.FindNode(TextSpan.FromBounds(position, position)); if (node != null) { foreach (var un in semanticModel.GetUsingNamespacesInScope(node)) { usedNamespaces.Add(un.GetFullName()); } } var enclosingNamespaceName = semanticModel.GetEnclosingNamespace(position, cancellationToken)?.GetFullName() ?? ""; var stack = new Stack <INamespaceOrTypeSymbol> (); foreach (var member in semanticModel.Compilation.GlobalNamespace.GetNamespaceMembers()) { stack.Push(member); } var extMethodDict = extensionMethodImport ? new Dictionary <INamespaceSymbol, List <ImportSymbolCompletionData> > () : null; var typeDict = new Dictionary <INamespaceSymbol, HashSet <string> > (); while (stack.Count > 0) { if (cancellationToken.IsCancellationRequested) { break; } var current = stack.Pop(); if (current is INamespaceSymbol currentNs) { var currentNsName = currentNs.GetFullName(); if (usedNamespaces.Contains(currentNsName) || enclosingNamespaceName == currentNsName || (enclosingNamespaceName.StartsWith(currentNsName, StringComparison.Ordinal) && enclosingNamespaceName [currentNsName.Length] == '.')) { foreach (var member in currentNs.GetNamespaceMembers()) { stack.Push(member); } } else { foreach (var member in currentNs.GetMembers()) { stack.Push(member); } } continue; } if (current is INamedTypeSymbol type) { if (type.IsImplicitClass || type.IsScriptClass) { continue; } if (type.DeclaredAccessibility != Accessibility.Public) { if (type.DeclaredAccessibility != Accessibility.Internal) { continue; } if (!type.IsAccessibleWithin(semanticModel.Compilation.Assembly)) { continue; } } if (extensionMethodImport) { if (type.MightContainExtensionMethods) { AddImportExtensionMethodCompletionData(result, ctx, type, extensionMethodReceiverType, extMethodDict); } } else { if (!typeDict.TryGetValue(type.ContainingNamespace, out var existingTypeHashSet)) { typeDict.Add(type.ContainingNamespace, existingTypeHashSet = new HashSet <string> ()); } if (!existingTypeHashSet.Contains(type.Name)) { result.Add(new ImportSymbolCompletionData(this, ctx, type, false)); existingTypeHashSet.Add(type.Name); } } } } } } catch (Exception e) { LoggingService.LogError("Exception while AddImportCompletionData", e); } }
internal void AddImportCompletionData(CSharpSyntaxContext ctx, CompletionDataList result, SemanticModel semanticModel, int position, CancellationToken cancellationToken = default(CancellationToken)) { if (result.Count == 0) { return; } var root = semanticModel.SyntaxTree.GetRoot(); var node = root.FindNode(TextSpan.FromBounds(position, position)); var syntaxTree = root.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return; } var extensionMethodImport = syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken); ITypeSymbol extensionType = null; if (extensionMethodImport) { var memberAccess = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (memberAccess != null) { var symbolInfo = ctx.SemanticModel.GetSymbolInfo(memberAccess.Expression); if (symbolInfo.Symbol.Kind == SymbolKind.NamedType) { return; } extensionType = ctx.SemanticModel.GetTypeInfo(memberAccess.Expression).Type; if (extensionType == null) { return; } } else { return; } } var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); if (extensionMethodImport || syntaxTree.IsGlobalStatementContext(position, cancellationToken) || syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) || syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsTypeContext(position, cancellationToken) || syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsLabelContext(position, cancellationToken)) { var usedNamespaces = new HashSet <string> (); foreach (var un in semanticModel.GetUsingNamespacesInScope(node)) { usedNamespaces.Add(un.GetFullName()); } var enclosingNamespaceName = semanticModel.GetEnclosingNamespace(position, cancellationToken).GetFullName(); var stack = new Stack <INamespaceOrTypeSymbol> (); foreach (var member in semanticModel.Compilation.GlobalNamespace.GetNamespaceMembers()) { stack.Push(member); } var extMethodDict = extensionMethodImport ? new Dictionary <INamespaceSymbol, List <ImportSymbolCompletionData> > () : null; var typeDict = new Dictionary <INamespaceSymbol, HashSet <string> > (); while (stack.Count > 0) { if (cancellationToken.IsCancellationRequested) { break; } var current = stack.Pop(); var currentNs = current as INamespaceSymbol; if (currentNs != null) { var currentNsName = currentNs.GetFullName(); if (usedNamespaces.Contains(currentNsName) || enclosingNamespaceName == currentNsName || (enclosingNamespaceName.StartsWith(currentNsName, StringComparison.Ordinal) && enclosingNamespaceName [currentNsName.Length] == '.')) { foreach (var member in currentNs.GetNamespaceMembers()) { stack.Push(member); } } else { foreach (var member in currentNs.GetMembers()) { stack.Push(member); } } } else { var type = (INamedTypeSymbol)current; if (type.IsImplicitClass || type.IsScriptClass) { continue; } if (type.DeclaredAccessibility != Accessibility.Public) { if (type.DeclaredAccessibility != Accessibility.Internal) { continue; } if (!type.IsAccessibleWithin(semanticModel.Compilation.Assembly)) { continue; } } if (extensionMethodImport) { if (!type.MightContainExtensionMethods) { continue; } foreach (var extMethod in type.GetMembers().OfType <IMethodSymbol> ().Where(method => method.IsExtensionMethod)) { var reducedMethod = extMethod.ReduceExtensionMethod(extensionType); if (reducedMethod != null) { List <ImportSymbolCompletionData> importSymbolList; if (!extMethodDict.TryGetValue(type.ContainingNamespace, out importSymbolList)) { extMethodDict.Add(type.ContainingNamespace, importSymbolList = new List <ImportSymbolCompletionData> ()); } var newData = new ImportSymbolCompletionData(this, reducedMethod, false); var existingItem = importSymbolList.FirstOrDefault(data => data.Symbol.Name == extMethod.Name); if (existingItem != null) { existingItem.AddOverload(newData); } else { result.Add(newData); importSymbolList.Add(newData); } } } } else { HashSet <string> existingTypeHashSet; if (!typeDict.TryGetValue(type.ContainingNamespace, out existingTypeHashSet)) { typeDict.Add(type.ContainingNamespace, existingTypeHashSet = new HashSet <string> ()); } if (!existingTypeHashSet.Contains(type.Name)) { result.Add(new ImportSymbolCompletionData(this, type, false)); existingTypeHashSet.Add(type.Name); } } } } } }