提交 1b4ef7a1 编写于 作者: C CyrusNajmabadi

Don't trim using namespaces.

上级 96568b8f
......@@ -337,8 +337,31 @@ public async Task TestMultiplePresortedUsings1()
public async Task TestMultiplePresortedUsings2()
{
await TestAsync(
@"using B.X; using B.Y; class Class { void Method() { [|Foo|].Bar(); } } namespace B.A { class Foo { public static void Bar() { } } }",
@"using B.A; using B.X; using B.Y; class Class { void Method() { Foo.Bar(); } } namespace B.A { class Foo { public static void Bar() { } } }");
@"using B.X;
using B.Y;
class Class {
void Method() {
[|Foo|].Bar();
}
}
namespace B.A {
class Foo {
public static void Bar() { }
}
}",
@"using B.A;
using B.X;
using B.Y;
class Class {
void Method() {
Foo.Bar();
}
}
namespace B.A {
class Foo {
public static void Bar() { }
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddUsing)]
......@@ -1453,8 +1476,27 @@ public async Task TestAddInsideUsingDirective4()
public async Task TestAddInsideUsingDirective5()
{
await TestAsync(
@"using System.IO; namespace ns2 { using System.Diagnostics; namespace ns3 { using System.Collections; namespace ns { using B = [|Byte|]; } } }",
@"using System.IO; namespace ns2 { using System.Diagnostics; namespace ns3 { using System; using System.Collections; namespace ns { using B = Byte; } } }");
@"using System.IO;
namespace ns2 {
using System.Diagnostics;
namespace ns3 {
using System.Collections;
namespace ns {
using B = [|Byte|];
}
}
}",
@"using System.IO;
namespace ns2 {
using System.Diagnostics;
namespace ns3 {
using System;
using System.Collections;
namespace ns {
using B = Byte;
}
}
}");
}
[WorkItem(991463, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")]
......@@ -1562,8 +1604,35 @@ public class E
public async Task TestAmbiguousUsingName()
{
await TestAsync(
@"namespace ClassLibrary1 { using System ; public class SomeTypeUser { [|SomeType|] field ; } } namespace SubNamespaceName { using System ; class SomeType { } } namespace ClassLibrary1 . SubNamespaceName { using System ; class SomeOtherFile { } } ",
@"namespace ClassLibrary1 { using System ; using global::SubNamespaceName ; public class SomeTypeUser { SomeType field ; } } namespace SubNamespaceName { using System ; class SomeType { } } namespace ClassLibrary1 . SubNamespaceName { using System ; class SomeOtherFile { } } ");
@"namespace ClassLibrary1 {
using System ;
public class SomeTypeUser {
[|SomeType|] field ;
}
}
namespace SubNamespaceName {
using System ;
class SomeType { }
}
namespace ClassLibrary1 . SubNamespaceName {
using System ;
class SomeOtherFile { }
} ",
@"namespace ClassLibrary1 {
using System ;
using global::SubNamespaceName ;
public class SomeTypeUser {
SomeType field ;
}
}
namespace SubNamespaceName {
using System ;
class SomeType { }
}
namespace ClassLibrary1 . SubNamespaceName {
using System ;
class SomeOtherFile { }
} ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddUsing)]
......@@ -1745,7 +1814,7 @@ class T1 { }
namespace A.C
{
using System;
using B;
using A.B;
class T2
{
void Test()
......@@ -1754,7 +1823,7 @@ void Test()
T1 t1;
}
}
}");
}", systemSpecialCase: true);
}
[WorkItem(935, "https://github.com/dotnet/roslyn/issues/935")]
......@@ -1798,8 +1867,23 @@ public async Task TestAddUsingWithOtherExtensionsInScope4()
public async Task TestNestedNamespaceSimplified()
{
await TestAsync(
@"namespace Microsoft . MyApp { using Win32 ; class Program { static void Main ( string [ ] args ) { [|SafeRegistryHandle|] h ; } } } ",
@"namespace Microsoft . MyApp { using Win32 ; using Win32 . SafeHandles ; class Program { static void Main ( string [ ] args ) { SafeRegistryHandle h ; } } } ");
@"namespace Microsoft . MyApp {
using Win32 ;
class Program {
static void Main ( string [ ] args ) {
[|SafeRegistryHandle|] h ;
}
}
} ",
@"namespace Microsoft . MyApp {
using Microsoft.Win32 . SafeHandles ;
using Win32 ;
class Program {
static void Main ( string [ ] args ) {
SafeRegistryHandle h ;
}
}
} ");
}
[WorkItem(3080, "https://github.com/dotnet/roslyn/issues/3080")]
......@@ -1807,8 +1891,23 @@ public async Task TestNestedNamespaceSimplified()
public async Task TestNestedNamespaceSimplified2()
{
await TestAsync(
@"namespace Microsoft . MyApp { using Zin32 ; class Program { static void Main ( string [ ] args ) { [|SafeRegistryHandle|] h ; } } } ",
@"namespace Microsoft . MyApp { using Win32 . SafeHandles ; using Zin32 ; class Program { static void Main ( string [ ] args ) { SafeRegistryHandle h ; } } } ");
@"namespace Microsoft . MyApp {
using Zin32 ;
class Program {
static void Main ( string [ ] args ) {
[|SafeRegistryHandle|] h ;
}
}
} ",
@"namespace Microsoft . MyApp {
using Microsoft . Win32 . SafeHandles ;
using Zin32 ;
class Program {
static void Main ( string [ ] args ) {
SafeRegistryHandle h ;
}
}
} ");
}
[WorkItem(3080, "https://github.com/dotnet/roslyn/issues/3080")]
......@@ -1816,8 +1915,25 @@ public async Task TestNestedNamespaceSimplified2()
public async Task TestNestedNamespaceSimplified3()
{
await TestAsync(
@"namespace Microsoft . MyApp { using System ; using Win32 ; class Program { static void Main ( string [ ] args ) { [|SafeRegistryHandle|] h ; } } } ",
@"namespace Microsoft . MyApp { using System ; using Win32 ; using Win32 . SafeHandles ; class Program { static void Main ( string [ ] args ) { SafeRegistryHandle h ; } } } ");
@"namespace Microsoft . MyApp {
using System ;
using Win32 ;
class Program {
static void Main ( string [ ] args ) {
[|SafeRegistryHandle|] h ;
}
}
} ",
@"namespace Microsoft . MyApp {
using System ;
using Microsoft.Win32 . SafeHandles ;
using Win32 ;
class Program {
static void Main ( string [ ] args ) {
SafeRegistryHandle h ;
}
}
} ");
}
[WorkItem(3080, "https://github.com/dotnet/roslyn/issues/3080")]
......@@ -1825,8 +1941,25 @@ public async Task TestNestedNamespaceSimplified3()
public async Task TestNestedNamespaceSimplified4()
{
await TestAsync(
@"namespace Microsoft . MyApp { using System ; using Zin32 ; class Program { static void Main ( string [ ] args ) { [|SafeRegistryHandle|] h ; } } } ",
@"namespace Microsoft . MyApp { using System ; using Win32 . SafeHandles ; using Zin32 ; class Program { static void Main ( string [ ] args ) { SafeRegistryHandle h ; } } } ");
@"namespace Microsoft . MyApp {
using System ;
using Zin32 ;
class Program {
static void Main ( string [ ] args ) {
[|SafeRegistryHandle|] h ;
}
}
} ",
@"namespace Microsoft . MyApp {
using System ;
using Microsoft . Win32 . SafeHandles ;
using Zin32 ;
class Program {
static void Main ( string [ ] args ) {
SafeRegistryHandle h ;
}
}
} ");
}
[WorkItem(3080, "https://github.com/dotnet/roslyn/issues/3080")]
......@@ -1852,8 +1985,8 @@ static void Main(string[] args)
@"namespace Microsoft.MyApp
{
#if true
using Microsoft.Win32.SafeHandles;
using Win32;
using Win32.SafeHandles;
#else
using System;
#endif
......@@ -1890,11 +2023,11 @@ static void Main(string[] args)
@"namespace Microsoft.MyApp
{
using System;
using Microsoft.Win32.SafeHandles;
#if false
using Win32;
#endif
using Win32;
using Win32.SafeHandles;
class Program
{
static void Main(string[] args)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
......
......@@ -64,7 +64,7 @@ class C
{
void M()
{
Action<int> a = (System.Int32 x) => { };
Action<int> a = (global::System.Int32 x) => { };
}
}
]]></code>
......@@ -97,7 +97,7 @@ class C
{
void M()
{
Action<int> a = (System.Int32 x) => { };
Action<int> a = (global::System.Int32 x) => { };
}
}
]]></code>
......@@ -130,7 +130,7 @@ class C
{
void M()
{
Action<int, int> a = (System.Int32 x, System.Int32 y) => { };
Action<int, int> a = (global::System.Int32 x, global::System.Int32 y) => { };
}
}
]]></code>
......@@ -163,13 +163,12 @@ class C
{
void M()
{
Action<int, int, int> a = (System.Int32 x, System.Int32 y, System.Int32 z) => { };
Action<int, int, int> a = (global::System.Int32 x, global::System.Int32 y, global::System.Int32 z) => { };
}
}
]]></code>
Await TestAsync(input, expected, expandParameter:=True)
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -89,9 +89,14 @@ protected override Solution UpdateSolution(Document newDocument)
return newProject.Solution;
}
protected override string GetDescription(Project project, SyntaxNode node, SemanticModel semanticModel)
protected override string TryGetDescription(Project project, SyntaxNode node, SemanticModel semanticModel)
{
var description = base.GetDescription(project, node, semanticModel);
var description = base.TryGetDescription(project, node, semanticModel);
if (description == null)
{
return null;
}
return project.Id == _project.Id
? description
: $"{description} ({string.Format(FeaturesResources.from_0, _project.Name)})";
......
......@@ -84,7 +84,7 @@ public override int GetHashCode()
Document document, SyntaxNode node, bool placeSystemNamespaceFirst, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
string description = GetDescription(document.Project, node, semanticModel);
string description = TryGetDescription(document.Project, node, semanticModel);
if (description == null)
{
return null;
......@@ -102,9 +102,10 @@ public override int GetHashCode()
return null;
}
protected virtual string GetDescription(Project project, SyntaxNode node, SemanticModel semanticModel)
protected virtual string TryGetDescription(
Project project, SyntaxNode node, SemanticModel semanticModel)
{
return provider.GetDescription(SymbolResult.Symbol, semanticModel, node, this.CheckForExistingImport(project));
return provider.TryGetDescription(SymbolResult.Symbol, semanticModel, node, this.CheckForExistingImport(project));
}
}
}
......
......@@ -53,7 +53,7 @@ internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSynt
internal abstract bool IsAddMethodContext(SyntaxNode node, SemanticModel semanticModel);
protected abstract string GetDescription(IReadOnlyList<string> nameParts);
protected abstract string GetDescription(INamespaceOrTypeSymbol symbol, SemanticModel semanticModel, SyntaxNode root, bool checkForExistingImport);
protected abstract string TryGetDescription(INamespaceOrTypeSymbol symbol, SemanticModel semanticModel, SyntaxNode root, bool checkForExistingImport);
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
......
......@@ -247,8 +247,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return $"Imports { String.Join(".", nameParts) }"
End Function
Protected Overrides Function GetDescription(namespaceSymbol As INamespaceOrTypeSymbol, semanticModel As SemanticModel,
root As SyntaxNode, checkForExistingImport As Boolean) As String
Protected Overrides Function TryGetDescription(
namespaceSymbol As INamespaceOrTypeSymbol,
semanticModel As SemanticModel,
root As SyntaxNode,
checkForExistingImport As Boolean) As String
Return $"Imports {namespaceSymbol.ToDisplayString()}"
End Function
......
......@@ -1936,7 +1936,8 @@ private static bool CanReplaceWithReducedName(this NameSyntax name, TypeSyntax r
return CanReplaceWithReducedNameInContext(name, reducedName, semanticModel, cancellationToken);
}
private static bool CanReplaceWithReducedNameInContext(this NameSyntax name, TypeSyntax reducedName, SemanticModel semanticModel, CancellationToken cancellationToken)
private static bool CanReplaceWithReducedNameInContext(
this NameSyntax name, TypeSyntax reducedName, SemanticModel semanticModel, CancellationToken cancellationToken)
{
// Special case. if this new minimal name parses out to a predefined type, then we
// have to make sure that we're not in a using alias. That's the one place where the
......@@ -1946,10 +1947,15 @@ private static bool CanReplaceWithReducedNameInContext(this NameSyntax name, Typ
var invalidTransformation2 = WillConflictWithExistingLocal(name, reducedName);
var invalidTransformation3 = IsAmbiguousCast(name, reducedName);
var invalidTransformation4 = IsNullableTypeInPointerExpression(name, reducedName);
var isNotNullableReplaceable = name.IsNotNullableReplaceable(reducedName);
var invalidTransformation5 = name.IsNotNullableReplaceable(reducedName);
var invalidTransformation6 = IsQualifiedNameInUsingDirective(semanticModel, name, reducedName);
if (invalidTransformation1 || invalidTransformation2 || invalidTransformation3 || invalidTransformation4
|| isNotNullableReplaceable)
if (invalidTransformation1 ||
invalidTransformation2 ||
invalidTransformation3 ||
invalidTransformation4 ||
invalidTransformation5 ||
invalidTransformation6)
{
return false;
}
......@@ -1957,6 +1963,44 @@ private static bool CanReplaceWithReducedNameInContext(this NameSyntax name, Typ
return true;
}
private static bool IsQualifiedNameInUsingDirective(SemanticModel model, NameSyntax name, TypeSyntax reducedName)
{
while (name.IsLeftSideOfQualifiedName())
{
name = (NameSyntax)name.Parent;
}
if (name.IsParentKind(SyntaxKind.UsingDirective) &&
((UsingDirectiveSyntax)name.Parent).Alias == null)
{
// We're a qualified name in a using. We don't want to reduce this name as people like
// fully qualified names in usings so they can properly tell what the name is resolving
// to.
// However, if this name is actually referencing the special Script class, then we do
// want to allow that to be reduced.
return !IsInScriptClass(model, name);
}
return false;
}
private static bool IsInScriptClass(SemanticModel model, NameSyntax name)
{
var symbol = model.GetSymbolInfo(name).Symbol as INamedTypeSymbol;
while (symbol != null)
{
if (symbol.IsScriptClass)
{
return true;
}
symbol = symbol.ContainingType;
}
return false;
}
private static bool IsNotNullableReplaceable(this NameSyntax name, TypeSyntax reducedName)
{
var isNotNullableReplaceable = false;
......
......@@ -24,7 +24,7 @@ private ExpressionSyntaxGeneratorVisitor()
public override ExpressionSyntax DefaultVisit(ISymbol symbol)
{
return symbol.Accept(TypeSyntaxGeneratorVisitor.Instance);
return symbol.Accept(TypeSyntaxGeneratorVisitor.Create());
}
private TExpressionSyntax AddInformationTo<TExpressionSyntax>(TExpressionSyntax syntax, ISymbol symbol)
......@@ -38,7 +38,7 @@ private TExpressionSyntax AddInformationTo<TExpressionSyntax>(TExpressionSyntax
public override ExpressionSyntax VisitNamedType(INamedTypeSymbol symbol)
{
var typeSyntax = TypeSyntaxGeneratorVisitor.Instance.CreateSimpleTypeSyntax(symbol);
var typeSyntax = TypeSyntaxGeneratorVisitor.Create().CreateSimpleTypeSyntax(symbol);
if (!(typeSyntax is SimpleNameSyntax))
{
return typeSyntax;
......
......@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -14,10 +13,16 @@ internal partial class ITypeSymbolExtensions
{
private class TypeSyntaxGeneratorVisitor : SymbolVisitor<TypeSyntax>
{
public static readonly TypeSyntaxGeneratorVisitor Instance = new TypeSyntaxGeneratorVisitor();
private readonly bool _nameOnly;
private TypeSyntaxGeneratorVisitor()
private TypeSyntaxGeneratorVisitor(bool nameOnly)
{
_nameOnly = nameOnly;
}
public static TypeSyntaxGeneratorVisitor Create(bool nameOnly = false)
{
return new TypeSyntaxGeneratorVisitor(nameOnly);
}
public override TypeSyntax DefaultVisit(ISymbol node)
......@@ -39,15 +44,25 @@ public override TypeSyntax VisitAlias(IAliasSymbol symbol)
return AddInformationTo(symbol.Name.ToIdentifierName(), symbol);
}
private void ThrowIfNameOnly()
{
if (_nameOnly)
{
throw new InvalidOperationException("This symbol cannot be converted into a NameSyntax");
}
}
public override TypeSyntax VisitArrayType(IArrayTypeSymbol symbol)
{
ThrowIfNameOnly();
var underlyingNonArrayType = symbol.ElementType;
while (underlyingNonArrayType.Kind == SymbolKind.ArrayType)
{
underlyingNonArrayType = ((IArrayTypeSymbol)underlyingNonArrayType).ElementType;
}
var elementTypeSyntax = underlyingNonArrayType.Accept(this);
var elementTypeSyntax = underlyingNonArrayType.GenerateTypeSyntax();
var ranks = new List<ArrayRankSpecifierSyntax>();
var arrayType = symbol;
......@@ -71,68 +86,25 @@ public override TypeSyntax VisitDynamicType(IDynamicTypeSymbol symbol)
public TypeSyntax CreateSimpleTypeSyntax(INamedTypeSymbol symbol)
{
switch (symbol.SpecialType)
if (!_nameOnly)
{
case SpecialType.System_Object:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object"));
case SpecialType.System_Void:
return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));
case SpecialType.System_Boolean:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Boolean"));
case SpecialType.System_Char:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Char"));
case SpecialType.System_SByte:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("SByte"));
case SpecialType.System_Byte:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Byte"));
case SpecialType.System_Int16:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int16"));
case SpecialType.System_UInt16:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt16"));
case SpecialType.System_Int32:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int32"));
case SpecialType.System_UInt32:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt32"));
case SpecialType.System_Int64:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Int64"));
case SpecialType.System_UInt64:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("UInt64"));
case SpecialType.System_Decimal:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Decimal"));
case SpecialType.System_Single:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Single"));
case SpecialType.System_Double:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Double"));
case SpecialType.System_String:
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("String"));
}
if (symbol.IsTupleType)
{
return CreateTupleTypeSyntax(symbol);
var syntax = TryCreateSpecializedNamedTypeSyntax(symbol);
if (syntax != null)
{
return syntax;
}
}
if (symbol.Name == string.Empty || symbol.IsAnonymousType)
{
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object"));
}
if (symbol.IsNullable())
{
// Can't have a nullable of a pointer type. i.e. "int*?" is illegal.
var innerType = symbol.TypeArguments.First();
if (innerType.TypeKind != TypeKind.Pointer)
{
return AddInformationTo(
SyntaxFactory.NullableType(innerType.Accept(this)), symbol);
}
return CreateSystemObject();
}
if (symbol.TypeParameters.Length == 0)
{
if (symbol.TypeKind == TypeKind.Error && symbol.Name == "var")
{
return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object"));
return CreateSystemObject();
}
return symbol.Name.ToIdentifierName();
......@@ -140,13 +112,53 @@ public TypeSyntax CreateSimpleTypeSyntax(INamedTypeSymbol symbol)
var typeArguments = symbol.IsUnboundGenericType
? Enumerable.Repeat(SyntaxFactory.OmittedTypeArgument(), symbol.TypeArguments.Length)
: symbol.TypeArguments.Select(t => t.Accept(this));
: symbol.TypeArguments.Select(t => t.GenerateTypeSyntax());
return SyntaxFactory.GenericName(
symbol.Name.ToIdentifierToken(),
SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(typeArguments)));
}
private static QualifiedNameSyntax CreateSystemObject()
{
return SyntaxFactory.QualifiedName(
SyntaxFactory.AliasQualifiedName(
CreateGlobalIdentifier(),
SyntaxFactory.IdentifierName("System")),
SyntaxFactory.IdentifierName("Object"));
}
private static IdentifierNameSyntax CreateGlobalIdentifier()
{
return SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword));
}
private TypeSyntax TryCreateSpecializedNamedTypeSyntax(INamedTypeSymbol symbol)
{
if (symbol.SpecialType == SpecialType.System_Void)
{
return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));
}
if (symbol.IsTupleType)
{
return CreateTupleTypeSyntax(symbol);
}
if (symbol.IsNullable())
{
// Can't have a nullable of a pointer type. i.e. "int*?" is illegal.
var innerType = symbol.TypeArguments.First();
if (innerType.TypeKind != TypeKind.Pointer)
{
return AddInformationTo(
SyntaxFactory.NullableType(innerType.GenerateTypeSyntax()), symbol);
}
}
return null;
}
private TupleTypeSyntax CreateTupleTypeSyntax(INamedTypeSymbol symbol)
{
var list = new SeparatedSyntaxList<TupleElementSyntax>();
......@@ -157,10 +169,10 @@ private TupleTypeSyntax CreateTupleTypeSyntax(INamedTypeSymbol symbol)
for (int i = 0; i < types.Length; i++)
{
var name = hasNames ? SyntaxFactory.IdentifierName(names[i]) : null;
list = list.Add(SyntaxFactory.TupleElement(GenerateTypeSyntax(types[i]), name));
list = list.Add(SyntaxFactory.TupleElement(types[i].GenerateTypeSyntax(), name));
}
return SyntaxFactory.TupleType(list);
return AddInformationTo(SyntaxFactory.TupleType(list), symbol);
}
public override TypeSyntax VisitNamedType(INamedTypeSymbol symbol)
......@@ -199,10 +211,7 @@ public override TypeSyntax VisitNamedType(INamedTypeSymbol symbol)
{
if (symbol.TypeKind != TypeKind.Error)
{
return AddInformationTo(
SyntaxFactory.AliasQualifiedName(
SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
simpleNameSyntax), symbol);
return AddGlobalAlias(symbol, simpleNameSyntax);
}
}
else
......@@ -227,10 +236,7 @@ public override TypeSyntax VisitNamespace(INamespaceSymbol symbol)
if (symbol.ContainingNamespace.IsGlobalNamespace)
{
return AddInformationTo(
SyntaxFactory.AliasQualifiedName(
SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
syntax), symbol);
return AddGlobalAlias(symbol, syntax);
}
else
{
......@@ -241,10 +247,20 @@ public override TypeSyntax VisitNamespace(INamespaceSymbol symbol)
}
}
private TypeSyntax AddGlobalAlias(INamespaceOrTypeSymbol symbol, SimpleNameSyntax syntax)
{
return AddInformationTo(
SyntaxFactory.AliasQualifiedName(
CreateGlobalIdentifier(),
syntax), symbol);
}
public override TypeSyntax VisitPointerType(IPointerTypeSymbol symbol)
{
ThrowIfNameOnly();
return AddInformationTo(
SyntaxFactory.PointerType(symbol.PointedAtType.Accept(this)),
SyntaxFactory.PointerType(symbol.PointedAtType.GenerateTypeSyntax()),
symbol);
}
......@@ -254,4 +270,4 @@ public override TypeSyntax VisitTypeParameter(ITypeParameterSymbol symbol)
}
}
}
}
}
\ No newline at end of file
......@@ -6,13 +6,11 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
......@@ -25,10 +23,23 @@ internal static partial class ITypeSymbolExtensions
return typeSymbol.Accept(ExpressionSyntaxGeneratorVisitor.Instance).WithAdditionalAnnotations(Simplifier.Annotation);
}
public static NameSyntax GenerateNameSyntax(
this INamespaceOrTypeSymbol symbol)
{
return (NameSyntax)GenerateTypeSyntax(symbol, nameSyntax: true);
}
public static TypeSyntax GenerateTypeSyntax(
this ITypeSymbol typeSymbol)
this INamespaceOrTypeSymbol symbol)
{
return GenerateTypeSyntax(symbol, nameSyntax: false);
}
private static TypeSyntax GenerateTypeSyntax(
INamespaceOrTypeSymbol symbol, bool nameSyntax)
{
return typeSymbol.Accept(TypeSyntaxGeneratorVisitor.Instance).WithAdditionalAnnotations(Simplifier.Annotation);
return symbol.Accept(TypeSyntaxGeneratorVisitor.Create(nameSyntax))
.WithAdditionalAnnotations(Simplifier.Annotation);
}
public static bool ContainingTypesOrSelfHasUnsafeKeyword(this ITypeSymbol containingType)
......
......@@ -98,6 +98,14 @@ public static IEnumerable<UsingDirectiveSyntax> GetEnclosingUsingDirectives(this
.SelectMany(n => n.Usings));
}
public static IEnumerable<ExternAliasDirectiveSyntax> GetEnclosingExternAliasDirectives(this SyntaxNode node)
{
return node.GetAncestorOrThis<CompilationUnitSyntax>().Externs
.Concat(node.GetAncestorsOrThis<NamespaceDeclarationSyntax>()
.Reverse()
.SelectMany(n => n.Externs));
}
public static bool IsUnsafeContext(this SyntaxNode node)
{
if (node.GetAncestor<UnsafeStatementSyntax>() != null)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Utilities
{
......
......@@ -14,7 +14,7 @@
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editting
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editing
{
public class SymbolEditorTests
{
......
......@@ -12,7 +12,7 @@
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editting
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editing
{
public class SyntaxGeneratorTests
{
......@@ -257,7 +257,7 @@ public void TestSymbolTypeExpressions()
VerifySyntax<QualifiedNameSyntax>(_g.TypeExpression(genericType), "global::System.Collections.Generic.IEnumerable<T>");
var arrayType = _emptyCompilation.CreateArrayTypeSymbol(_emptyCompilation.GetSpecialType(SpecialType.System_Int32));
VerifySyntax<ArrayTypeSyntax>(_g.TypeExpression(arrayType), "System.Int32[]");
VerifySyntax<ArrayTypeSyntax>(_g.TypeExpression(arrayType), "global::System.Int32[]");
}
[Fact]
......@@ -343,7 +343,7 @@ public void TestObjectCreationExpressions()
VerifySyntax<ObjectCreationExpressionSyntax>(
_g.ObjectCreationExpression(listOfIntType, _g.IdentifierName("y")),
"new global::System.Collections.Generic.List<System.Int32>(y)"); // should this be 'int' or if not shouldn't it have global::?
"new global::System.Collections.Generic.List<global::System.Int32>(y)"); // should this be 'int' or if not shouldn't it have global::?
}
[Fact]
......@@ -743,109 +743,109 @@ public void TestOperatorDeclaration()
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Addition, parameters, returnType),
"bool operator +(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator +(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.BitwiseAnd, parameters, returnType),
"bool operator &(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator &(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.BitwiseOr, parameters, returnType),
"bool operator |(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator |(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Decrement, parameters, returnType),
"bool operator --(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator --(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Division, parameters, returnType),
"bool operator /(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator /(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Equality, parameters, returnType),
"bool operator ==(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator ==(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ExclusiveOr, parameters, returnType),
"bool operator ^(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator ^(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.False, parameters, returnType),
"bool operator false (System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator false (global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.GreaterThan, parameters, returnType),
"bool operator>(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator>(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.GreaterThanOrEqual, parameters, returnType),
"bool operator >=(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator >=(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Increment, parameters, returnType),
"bool operator ++(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator ++(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Inequality, parameters, returnType),
"bool operator !=(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator !=(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LeftShift, parameters, returnType),
"bool operator <<(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator <<(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LessThan, parameters, returnType),
"bool operator <(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator <(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LessThanOrEqual, parameters, returnType),
"bool operator <=(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator <=(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LogicalNot, parameters, returnType),
"bool operator !(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator !(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Modulus, parameters, returnType),
"bool operator %(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator %(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Multiply, parameters, returnType),
"bool operator *(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator *(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.OnesComplement, parameters, returnType),
"bool operator ~(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator ~(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.RightShift, parameters, returnType),
"bool operator >>(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator >>(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Subtraction, parameters, returnType),
"bool operator -(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator -(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.True, parameters, returnType),
"bool operator true (System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator true (global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.UnaryNegation, parameters, returnType),
"bool operator -(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator -(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.UnaryPlus, parameters, returnType),
"bool operator +(System.Int32 p0, System.String p1)\r\n{\r\n}");
"bool operator +(global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
// Conversion operators
VerifySyntax<ConversionOperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ImplicitConversion, parameters, returnType),
"implicit operator bool (System.Int32 p0, System.String p1)\r\n{\r\n}");
"implicit operator bool (global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
VerifySyntax<ConversionOperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ExplicitConversion, parameters, returnType),
"explicit operator bool (System.Int32 p0, System.String p1)\r\n{\r\n}");
"explicit operator bool (global::System.Int32 p0, global::System.String p1)\r\n{\r\n}");
}
[Fact]
......
......@@ -12,7 +12,7 @@
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editting
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Editing
{
public class SyntaxEditorTests
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册