protected override string TryGetDescription( INamespaceOrTypeSymbol namespaceOrTypeSymbol, SemanticModel semanticModel, SyntaxNode contextNode, bool checkForExistingUsing) { var root = GetCompilationUnitSyntaxNode(contextNode); // See if this is a reference to a type from a reference that has a specific alias // associated with it. If that extern alias hasn't already been brought into scope // then add that one. var externAlias = TryGetExternAliasDirective( namespaceOrTypeSymbol, semanticModel, contextNode, checkForExistingExternAlias: true); if (externAlias != null) { return($"extern alias {externAlias.Identifier.ValueText};"); } var usingDirective = TryGetUsingDirective( namespaceOrTypeSymbol, semanticModel, root, contextNode); if (usingDirective != null) { var displayString = namespaceOrTypeSymbol.ToDisplayString(); return(namespaceOrTypeSymbol.IsKind(SymbolKind.Namespace) ? $"using {displayString};" : $"using static {displayString};"); } return(null); }
private UsingDirectiveSyntax TryGetUsingDirective( Document document, INamespaceOrTypeSymbol namespaceOrTypeSymbol, SemanticModel semanticModel, CompilationUnitSyntax root, SyntaxNode contextNode) { var addImportService = document.GetLanguageService <IAddImportsService>(); var nameSyntax = namespaceOrTypeSymbol.GenerateNameSyntax(); // We need to create our using in two passes. This is because we need a using // directive so we can figure out where to put it. Then, once we figure out // where to put it, we might need to change it a bit (e.g. removing 'global' // from it if necessary). So we first create a dummy using directive just to // determine which container we're going in. Then we'll use the container to // help create the final using. var dummyUsing = SyntaxFactory.UsingDirective(nameSyntax); var container = addImportService.GetImportContainer(root, contextNode, dummyUsing); var namespaceToAddTo = container as NamespaceDeclarationSyntax; // Replace the alias that GenerateTypeSyntax added if we want this to be looked // up off of an extern alias. var externAliasDirective = TryGetExternAliasDirective( namespaceOrTypeSymbol, semanticModel, contextNode, checkForExistingExternAlias: false); var externAlias = externAliasDirective?.Identifier.ValueText; if (externAlias != null) { nameSyntax = AddOrReplaceAlias(nameSyntax, SyntaxFactory.IdentifierName(externAlias)); } else { // The name we generated will have the global:: alias on it. We only need // that if the name of our symbol is actually ambiguous in this context. // If so, keep global:: on it, otherwise remove it. // // Note: doing this has a couple of benefits. First, it's easy for us to see // if we have an existing using for this with the same syntax. Second, // it's easy to sort usings properly. If "global::" was attached to the // using directive, then it would make both of those operations more difficult // to achieve. nameSyntax = RemoveGlobalAliasIfUnnecessary(semanticModel, nameSyntax, namespaceToAddTo); } var usingDirective = SyntaxFactory.UsingDirective(nameSyntax) .WithAdditionalAnnotations(Formatter.Annotation); if (addImportService.HasExistingImport(root, contextNode, usingDirective)) { return(null); } return(namespaceOrTypeSymbol.IsKind(SymbolKind.Namespace) ? usingDirective : usingDirective.WithStaticKeyword(SyntaxFactory.Token(SyntaxKind.StaticKeyword))); }
private string GetUsingDirectiveString(INamespaceOrTypeSymbol namespaceOrTypeSymbol) { var displayString = namespaceOrTypeSymbol.ToDisplayString(); return(namespaceOrTypeSymbol.IsKind(SymbolKind.Namespace) ? $"using {displayString};" : $"using static {displayString};"); }
private UsingDirectiveSyntax TryGetUsingDirective( INamespaceOrTypeSymbol namespaceOrTypeSymbol, SemanticModel semanticModel, CompilationUnitSyntax root, SyntaxNode contextNode) { var namespaceToAddTo = GetFirstContainingNamespaceWithUsings(contextNode); var usingDirectives = namespaceToAddTo?.Usings ?? root.Usings; var nameSyntax = namespaceOrTypeSymbol.GenerateNameSyntax(); // Replace the alias that GenerateTypeSyntax added if we want this to be looked // up off of an extern alias. var externAliasDirective = TryGetExternAliasDirective( namespaceOrTypeSymbol, semanticModel, contextNode, checkForExistingExternAlias: false); var externAlias = externAliasDirective?.Identifier.ValueText; if (externAlias != null) { nameSyntax = AddOrReplaceAlias(nameSyntax, SyntaxFactory.IdentifierName(externAlias)); } else { // The name we generated will have the global:: alias on it. We only need // that if the name of our symbol is actually ambiguous in this context. // If so, keep global:: on it, otherwise remove it. // // Note: doing this has a couple of benefits. First, it's easy for us to see // if we have an existing using for this with the same syntax. Second, // it's easy to sort usings properly. If "global::" was attached to the // using directive, then it would make both of those operations more difficult // to achieve. nameSyntax = RemoveGlobalAliasIfUnnecessary(semanticModel, nameSyntax, namespaceToAddTo); } var usingDirective = SyntaxFactory.UsingDirective(nameSyntax) .WithAdditionalAnnotations(Formatter.Annotation); if (HasExistingUsingDirective(root, namespaceToAddTo, usingDirective)) { return(null); } return(namespaceOrTypeSymbol.IsKind(SymbolKind.Namespace) ? usingDirective : usingDirective.WithStaticKeyword(SyntaxFactory.Token(SyntaxKind.StaticKeyword))); }