From 1a69700d48676eb462bb080346a25a8c28a63821 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Mon, 21 Jun 2021 14:18:58 -0700 Subject: [PATCH] Draft implementation of file-scoped-namespaces (#48937) Co-authored-by: Rikki Gibson --- .../CSharpDeclarationComputer.cs | 3 +- .../BinderFactory.BinderFactoryVisitor.cs | 23 +- .../CSharp/Portable/Binder/BinderFactory.cs | 3 +- .../Binder/WithExternAliasesBinder.cs | 2 +- .../Binder/WithExternAndUsingAliasesBinder.cs | 2 +- .../WithUsingNamespacesAndTypesBinder.cs | 2 +- .../CSharp/Portable/CSharpExtensions.cs | 12 + .../CSharp/Portable/CSharpResources.resx | 68 +- .../Compilation/CSharpSemanticModel.cs | 11 + .../Compilation/MemberSemanticModel.cs | 6 + .../Compilation/SyntaxTreeSemanticModel.cs | 26 +- .../Portable/Declarations/DeclarationKind.cs | 4 +- .../Declarations/DeclarationTreeBuilder.cs | 63 +- .../CSharp/Portable/Errors/ErrorCode.cs | 5 + .../CSharp/Portable/Errors/MessageID.cs | 2 + .../Portable/Generated/CSharp.Generated.g4 | 19 +- .../Syntax.xml.Internal.Generated.cs | 310 ++++++- .../Syntax.xml.Main.Generated.cs | 26 + .../Syntax.xml.Syntax.Generated.cs | 187 +++- .../CSharp/Portable/Parser/LanguageParser.cs | 103 ++- .../CSharp/Portable/PublicAPI.Unshipped.txt | 61 ++ .../SymbolDisplayVisitor_Minimal.cs | 2 +- .../Source/SourceMemberContainerSymbol.cs | 8 +- .../SourceNamespaceSymbol.AliasesAndUsings.cs | 14 +- .../CSharp/Portable/Symbols/Symbol.cs | 2 +- .../CSharp/Portable/Syntax/LookupPosition.cs | 7 + .../NamespaceDeclarationSyntaxReference.cs | 2 +- .../CSharp/Portable/Syntax/Syntax.xml | 36 +- .../CSharp/Portable/Syntax/SyntaxKind.cs | 1 + .../CSharp/Portable/Syntax/SyntaxKindFacts.cs | 4 +- .../Portable/xlf/CSharpResources.cs.xlf | 24 +- .../Portable/xlf/CSharpResources.de.xlf | 24 +- .../Portable/xlf/CSharpResources.es.xlf | 24 +- .../Portable/xlf/CSharpResources.fr.xlf | 24 +- .../Portable/xlf/CSharpResources.it.xlf | 24 +- .../Portable/xlf/CSharpResources.ja.xlf | 24 +- .../Portable/xlf/CSharpResources.ko.xlf | 24 +- .../Portable/xlf/CSharpResources.pl.xlf | 24 +- .../Portable/xlf/CSharpResources.pt-BR.xlf | 24 +- .../Portable/xlf/CSharpResources.ru.xlf | 24 +- .../Portable/xlf/CSharpResources.tr.xlf | 24 +- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 24 +- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 24 +- .../Test/Emit/CodeGen/WinMdDelegateTests.cs | 46 + .../Test/Emit/Emit/CompilationEmitTests.cs | 36 +- .../Compilation/SemanticModelAPITests.cs | 19 + .../SemanticModelGetDeclaredSymbolAPITests.cs | 139 +++ .../DocumentationComments/IncludeTests.cs | 62 ++ .../SymbolDisplay/SymbolDisplayTests.cs | 156 +++- .../Symbols/AssemblyAndNamespaceTests.cs | 315 +++++++ .../Symbol/Symbols/Source/BaseClassTests.cs | 27 + .../Source/DeclaringSyntaxNodeTests.cs | 68 +- .../Test/Symbol/Symbols/Source/MethodTests.cs | 85 ++ .../Symbol/Symbols/Source/UsingAliasTests.cs | 43 + .../CSharp/Test/Symbol/Symbols/TypeTests.cs | 62 ++ .../Generated/Syntax.Test.xml.Generated.cs | 92 ++ .../Syntax/Parsing/DeclarationParsingTests.cs | 65 ++ .../Syntax/Parsing/ParserErrorMessageTests.cs | 8 +- .../Parsing/ParsingErrorRecoveryTests.cs | 42 + .../SingleLineDeclarationParsingTests.cs | 818 ++++++++++++++++++ .../Test/Utilities/CSharp/Extensions.cs | 2 +- 61 files changed, 3222 insertions(+), 189 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Syntax/Parsing/SingleLineDeclarationParsingTests.cs diff --git a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs index f7e4503bb47d1..8e4c7e3d0b233 100644 --- a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs +++ b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs @@ -75,8 +75,9 @@ private static void ComputeDeclarations( switch (node.Kind()) { case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: { - var ns = (NamespaceDeclarationSyntax)node; + var ns = (BaseNamespaceDeclarationSyntax)node; foreach (var decl in ns.Members) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs index 3ed7b30065002..455164d0d54af 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs @@ -758,7 +758,7 @@ public override Binder VisitInterfaceDeclaration(InterfaceDeclarationSyntax node public override Binder VisitRecordDeclaration(RecordDeclarationSyntax node) => VisitTypeDeclarationCore(node); - public override Binder VisitNamespaceDeclaration(NamespaceDeclarationSyntax parent) + public sealed override Binder VisitNamespaceDeclaration(NamespaceDeclarationSyntax parent) { if (!LookupPosition.IsInNamespaceDeclaration(_position, parent)) { @@ -774,7 +774,22 @@ public override Binder VisitNamespaceDeclaration(NamespaceDeclarationSyntax pare return VisitNamespaceDeclaration(parent, _position, inBody, inUsing); } - internal Binder VisitNamespaceDeclaration(NamespaceDeclarationSyntax parent, int position, bool inBody, bool inUsing) + public override Binder VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax parent) + { + if (!LookupPosition.IsInNamespaceDeclaration(_position, parent)) + { + return VisitCore(parent.Parent); + } + + // Anywhere after the `;` is in the 'body' of this namespace. + bool inBody = _position >= parent.SemicolonToken.EndPosition; + + bool inUsing = IsInUsing(parent); + + return VisitNamespaceDeclaration(parent, _position, inBody, inUsing); + } + + internal Binder VisitNamespaceDeclaration(BaseNamespaceDeclarationSyntax parent, int position, bool inBody, bool inUsing) { Debug.Assert(!inUsing || inBody, "inUsing => inBody"); @@ -840,7 +855,7 @@ private static Binder MakeNamespaceBinder(CSharpSyntaxNode node, NameSyntax name NamespaceSymbol ns = ((NamespaceSymbol)container).GetNestedNamespace(name); if ((object)ns == null) return outer; - if (node is NamespaceDeclarationSyntax namespaceDecl) + if (node is BaseNamespaceDeclarationSyntax namespaceDecl) { outer = AddInImportsBinders((SourceNamespaceSymbol)outer.Compilation.SourceModule.GetModuleNamespace(ns), namespaceDecl, outer, inUsing); } @@ -957,7 +972,7 @@ internal Binder VisitCompilationUnit(CompilationUnitSyntax compilationUnit, bool private static Binder AddInImportsBinders(SourceNamespaceSymbol declaringSymbol, CSharpSyntaxNode declarationSyntax, Binder next, bool inUsing) { - Debug.Assert(declarationSyntax.IsKind(SyntaxKind.CompilationUnit) || declarationSyntax.IsKind(SyntaxKind.NamespaceDeclaration)); + Debug.Assert(declarationSyntax.Kind() is SyntaxKind.CompilationUnit or SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration); if (inUsing) { diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs b/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs index fd5996f50e13c..78ba2950bb17d 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs @@ -175,10 +175,11 @@ internal Binder GetInNamespaceBinder(CSharpSyntaxNode unit) switch (unit.Kind()) { case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: { BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); visitor.Initialize(0, null, null); - Binder result = visitor.VisitNamespaceDeclaration((NamespaceDeclarationSyntax)unit, unit.SpanStart, inBody: true, inUsing: false); + Binder result = visitor.VisitNamespaceDeclaration((BaseNamespaceDeclarationSyntax)unit, unit.SpanStart, inBody: true, inUsing: false); _binderFactoryVisitorPool.Free(visitor); return result; } diff --git a/src/Compilers/CSharp/Portable/Binder/WithExternAliasesBinder.cs b/src/Compilers/CSharp/Portable/Binder/WithExternAliasesBinder.cs index afcd6d04cc841..17b6f77dd037e 100644 --- a/src/Compilers/CSharp/Portable/Binder/WithExternAliasesBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/WithExternAliasesBinder.cs @@ -90,7 +90,7 @@ private sealed class FromSyntax : WithExternAliasesBinder internal FromSyntax(SourceNamespaceSymbol declaringSymbol, CSharpSyntaxNode declarationSyntax, Binder next) : base(next) { - Debug.Assert(declarationSyntax.IsKind(SyntaxKind.CompilationUnit) || declarationSyntax.IsKind(SyntaxKind.NamespaceDeclaration)); + Debug.Assert(declarationSyntax.Kind() is SyntaxKind.CompilationUnit or SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration); _declaringSymbol = declaringSymbol; _declarationSyntax = declarationSyntax; } diff --git a/src/Compilers/CSharp/Portable/Binder/WithExternAndUsingAliasesBinder.cs b/src/Compilers/CSharp/Portable/Binder/WithExternAndUsingAliasesBinder.cs index 8c941649433af..42ebe29cda4b3 100644 --- a/src/Compilers/CSharp/Portable/Binder/WithExternAndUsingAliasesBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/WithExternAndUsingAliasesBinder.cs @@ -117,7 +117,7 @@ private sealed class FromSyntax : WithExternAndUsingAliasesBinder internal FromSyntax(SourceNamespaceSymbol declaringSymbol, CSharpSyntaxNode declarationSyntax, WithUsingNamespacesAndTypesBinder next) : base(next) { - Debug.Assert(declarationSyntax.IsKind(SyntaxKind.CompilationUnit) || declarationSyntax.IsKind(SyntaxKind.NamespaceDeclaration)); + Debug.Assert(declarationSyntax.Kind() is SyntaxKind.CompilationUnit or SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration); _declaringSymbol = declaringSymbol; _declarationSyntax = declarationSyntax; } diff --git a/src/Compilers/CSharp/Portable/Binder/WithUsingNamespacesAndTypesBinder.cs b/src/Compilers/CSharp/Portable/Binder/WithUsingNamespacesAndTypesBinder.cs index 8ca9aa8054f37..3841b7637dd10 100644 --- a/src/Compilers/CSharp/Portable/Binder/WithUsingNamespacesAndTypesBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/WithUsingNamespacesAndTypesBinder.cs @@ -276,7 +276,7 @@ private sealed class FromSyntax : WithUsingNamespacesAndTypesBinder internal FromSyntax(SourceNamespaceSymbol declaringSymbol, CSharpSyntaxNode declarationSyntax, Binder next, bool withImportChainEntry) : base(next, withImportChainEntry) { - Debug.Assert(declarationSyntax.IsKind(SyntaxKind.CompilationUnit) || declarationSyntax.IsKind(SyntaxKind.NamespaceDeclaration)); + Debug.Assert(declarationSyntax.Kind() is SyntaxKind.CompilationUnit or SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration); _declaringSymbol = declaringSymbol; _declarationSyntax = declarationSyntax; } diff --git a/src/Compilers/CSharp/Portable/CSharpExtensions.cs b/src/Compilers/CSharp/Portable/CSharpExtensions.cs index 569b75764631f..857b08a4b9be8 100644 --- a/src/Compilers/CSharp/Portable/CSharpExtensions.cs +++ b/src/Compilers/CSharp/Portable/CSharpExtensions.cs @@ -1317,6 +1317,18 @@ public static Conversion ClassifyConversion(this SemanticModel? semanticModel, i return csmodel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); } + /// + /// Given a namespace declaration syntax node, get the corresponding namespace symbol for + /// the declaration assembly. + /// +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters + public static INamespaceSymbol? GetDeclaredSymbol(this SemanticModel? semanticModel, SingleLineNamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters + { + var csmodel = semanticModel as CSharpSemanticModel; + return csmodel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); + } + /// /// Given a type declaration, get the corresponding type symbol. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 6a05f90e59e15..665fff1c56014 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -1,17 +1,17 @@  - @@ -682,7 +682,7 @@ '{0}': no suitable method found to override - A namespace cannot directly contain members such as fields or methods + A namespace cannot directly contain members such as fields, methods or statements '{0}' does not contain a definition for '{1}' @@ -6601,6 +6601,18 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ A function pointer cannot be called with named arguments. + + single-line namespace + + + Source file can only contain one single-line namespace declaration. + + + Source file can not contain both single-line and normal namespace declarations. + + + Single-line namespace must precede all other members in a file. + Parameter '{0}' is unread. Did you forget to use it to initialize the property with that name? diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs index 84236d3cd16a3..ef1810f0f28e5 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs @@ -2887,6 +2887,15 @@ internal Conversion ClassifyConversionForCast(int position, ExpressionSyntax exp /// The namespace symbol that was declared by the namespace declaration. public abstract INamespaceSymbol GetDeclaredSymbol(NamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Given a namespace declaration syntax node, get the corresponding namespace symbol for + /// the declaration assembly. + /// + /// The syntax node that declares a namespace. + /// The cancellation token. + /// The namespace symbol that was declared by the namespace declaration. + public abstract INamespaceSymbol GetDeclaredSymbol(SingleLineNamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)); + /// /// Given a type declaration, get the corresponding type symbol. /// @@ -5033,6 +5042,8 @@ protected sealed override ISymbol GetDeclaredSymbolCore(SyntaxNode node, Cancell return this.GetDeclaredSymbol((TupleElementSyntax)node, cancellationToken); case SyntaxKind.NamespaceDeclaration: return this.GetDeclaredSymbol((NamespaceDeclarationSyntax)node, cancellationToken); + case SyntaxKind.SingleLineNamespaceDeclaration: + return this.GetDeclaredSymbol((SingleLineNamespaceDeclarationSyntax)node, cancellationToken); case SyntaxKind.Parameter: return this.GetDeclaredSymbol((ParameterSyntax)node, cancellationToken); case SyntaxKind.TypeParameter: diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index 85c6f95ffd137..d5b3d730e0d42 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -580,6 +580,12 @@ private static BoundNode GetLowerBoundNode(ImmutableArray boundNodes) return null; } + public override INamespaceSymbol GetDeclaredSymbol(SingleLineNamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) + { + // Can't defined namespace inside a member. + return null; + } + public override INamedTypeSymbol GetDeclaredSymbol(BaseTypeDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { // Can't define type inside a member. diff --git a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs index 7592924da90f0..89dd46fa80261 100644 --- a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs @@ -1330,13 +1330,7 @@ private bool IsRegularCSharp #region "GetDeclaredSymbol overloads for MemberDeclarationSyntax and its subtypes" - /// - /// Given a namespace declaration syntax node, get the corresponding namespace symbol for the declaration - /// assembly. - /// - /// The syntax node that declares a namespace. - /// The cancellation token. - /// The namespace symbol that was declared by the namespace declaration. + /// public override INamespaceSymbol GetDeclaredSymbol(NamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { CheckSyntaxNode(declarationSyntax); @@ -1344,7 +1338,15 @@ private bool IsRegularCSharp return GetDeclaredNamespace(declarationSyntax).GetPublicSymbol(); } - private NamespaceSymbol GetDeclaredNamespace(NamespaceDeclarationSyntax declarationSyntax) + /// + public override INamespaceSymbol GetDeclaredSymbol(SingleLineNamespaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default) + { + CheckSyntaxNode(declarationSyntax); + + return GetDeclaredNamespace(declarationSyntax).GetPublicSymbol(); + } + + private NamespaceSymbol GetDeclaredNamespace(BaseNamespaceDeclarationSyntax declarationSyntax) { Debug.Assert(declarationSyntax != null); @@ -1429,7 +1431,7 @@ private NamedTypeSymbol GetDeclaredNamedType(CSharpSyntaxNode declarationSyntax, private NamespaceOrTypeSymbol GetDeclaredNamespaceOrType(CSharpSyntaxNode declarationSyntax) { - var namespaceDeclarationSyntax = declarationSyntax as NamespaceDeclarationSyntax; + var namespaceDeclarationSyntax = declarationSyntax as BaseNamespaceDeclarationSyntax; if (namespaceDeclarationSyntax != null) { return GetDeclaredNamespace(namespaceDeclarationSyntax); @@ -2276,7 +2278,8 @@ private NamespaceOrTypeSymbol GetDeclaredTypeMemberContainer(CSharpSyntaxNode me if (memberDeclaration.Parent.Kind() == SyntaxKind.CompilationUnit) { // top-level namespace: - if (memberDeclaration.Kind() == SyntaxKind.NamespaceDeclaration) + if (memberDeclaration.Kind() == SyntaxKind.NamespaceDeclaration || + memberDeclaration.Kind() == SyntaxKind.SingleLineNamespaceDeclaration) { return _compilation.Assembly.GlobalNamespace; } @@ -2307,7 +2310,8 @@ private NamespaceOrTypeSymbol GetDeclaredTypeMemberContainer(CSharpSyntaxNode me } // a namespace or a type in an explicitly declared namespace: - if (memberDeclaration.Kind() == SyntaxKind.NamespaceDeclaration || SyntaxFacts.IsTypeDeclaration(memberDeclaration.Kind())) + if (memberDeclaration.Kind() is SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration || + SyntaxFacts.IsTypeDeclaration(memberDeclaration.Kind())) { return container; } diff --git a/src/Compilers/CSharp/Portable/Declarations/DeclarationKind.cs b/src/Compilers/CSharp/Portable/Declarations/DeclarationKind.cs index 67a98d7fceb9f..61c3d7f97e92a 100644 --- a/src/Compilers/CSharp/Portable/Declarations/DeclarationKind.cs +++ b/src/Compilers/CSharp/Portable/Declarations/DeclarationKind.cs @@ -36,7 +36,9 @@ internal static DeclarationKind ToDeclarationKind(this SyntaxKind kind) case SyntaxKind.ClassDeclaration: return DeclarationKind.Class; case SyntaxKind.InterfaceDeclaration: return DeclarationKind.Interface; case SyntaxKind.StructDeclaration: return DeclarationKind.Struct; - case SyntaxKind.NamespaceDeclaration: return DeclarationKind.Namespace; + case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: + return DeclarationKind.Namespace; case SyntaxKind.EnumDeclaration: return DeclarationKind.Enum; case SyntaxKind.DelegateDeclaration: return DeclarationKind.Delegate; case SyntaxKind.RecordDeclaration: return DeclarationKind.Record; diff --git a/src/Compilers/CSharp/Portable/Declarations/DeclarationTreeBuilder.cs b/src/Compilers/CSharp/Portable/Declarations/DeclarationTreeBuilder.cs index a71e95949fec6..f2ae673eab73f 100644 --- a/src/Compilers/CSharp/Portable/Declarations/DeclarationTreeBuilder.cs +++ b/src/Compilers/CSharp/Portable/Declarations/DeclarationTreeBuilder.cs @@ -43,7 +43,9 @@ private ImmutableArray VisitNamespaceChildren( SyntaxList members, CoreInternalSyntax.SyntaxList internalMembers) { - Debug.Assert(node.Kind() == SyntaxKind.NamespaceDeclaration || (node.Kind() == SyntaxKind.CompilationUnit && _syntaxTree.Options.Kind == SourceCodeKind.Regular)); + Debug.Assert( + node.Kind() is SyntaxKind.NamespaceDeclaration or SyntaxKind.SingleLineNamespaceDeclaration || + (node.Kind() == SyntaxKind.CompilationUnit && _syntaxTree.Options.Kind == SourceCodeKind.Regular)); if (members.Count == 0) { @@ -294,9 +296,15 @@ private RootSingleNamespaceDeclaration CreateRootSingleNamespaceDeclaration(Comp diagnostics: diagnostics.ToReadOnlyAndFree()); } + public override SingleNamespaceOrTypeDeclaration VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) + => this.VisitBaseNamespaceDeclaration(node); + public override SingleNamespaceOrTypeDeclaration VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) + => this.VisitBaseNamespaceDeclaration(node); + + private SingleNamespaceDeclaration VisitBaseNamespaceDeclaration(BaseNamespaceDeclarationSyntax node) { - var children = VisitNamespaceChildren(node, node.Members, node.Green.Members); + var children = VisitNamespaceChildren(node, node.Members, ((Syntax.InternalSyntax.BaseNamespaceDeclarationSyntax)node.Green).Members); bool hasUsings = node.Usings.Any(); bool hasExterns = node.Externs.Any(); @@ -322,6 +330,57 @@ public override SingleNamespaceOrTypeDeclaration VisitNamespaceDeclaration(Names } var diagnostics = DiagnosticBag.GetInstance(); + + if (node is SingleLineNamespaceDeclarationSyntax) + { + if (node.Parent is SingleLineNamespaceDeclarationSyntax) + { + // Happens when user writes: + // namespace A.B; + // namespace X.Y; + diagnostics.Add(ErrorCode.ERR_MultipleSingleLineNamespace, node.Name.GetLocation()); + } + else if (node.Parent is NamespaceDeclarationSyntax) + { + // Happens with: + // + // namespace A.B + // { + // namespace X.Y; + diagnostics.Add(ErrorCode.ERR_SingleLineAndNormalNamespace, node.Name.GetLocation()); + } + else + { + // Happens with cases like: + // + // namespace A.B { } + // namespace X.Y; + // + // or even + // + // class C { } + // namespace X.Y; + + Debug.Assert(node.Parent is CompilationUnitSyntax); + var compilationUnit = (CompilationUnitSyntax)node.Parent; + if (node != compilationUnit.Members[0]) + { + diagnostics.Add(ErrorCode.ERR_SingleLineNamespaceNotBeforeAllMembers, node.Name.GetLocation()); + } + } + } + else + { + Debug.Assert(node is NamespaceDeclarationSyntax); + + // namespace X.Y; + // namespace A.B { } + if (node.Parent is SingleLineNamespaceDeclarationSyntax) + { + diagnostics.Add(ErrorCode.ERR_SingleLineAndNormalNamespace, node.Name.GetLocation()); + } + } + if (ContainsGeneric(node.Name)) { // We're not allowed to have generics. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 63fdfd9bee009..bc6782530ae78 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1939,6 +1939,11 @@ internal enum ErrorCode ERR_AttributesRequireParenthesizedLambdaExpression = 8916, ERR_CannotInferDelegateType = 8917, + ERR_MultipleSingleLineNamespace = 8930, + ERR_SingleLineAndNormalNamespace = 8931, + ERR_SingleLineNamespaceNotBeforeAllMembers = 8932, + + #endregion // Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd) diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 6272644a9d2d3..99a9c412aad03 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -224,6 +224,7 @@ internal enum MessageID IDS_FeatureInferredDelegateType = MessageBase + 12799, IDS_FeatureLambdaAttributes = MessageBase + 12800, IDS_FeatureWithOnAnonymousTypes = MessageBase + 12801, + IDS_SingleLineNamespace = MessageBase + 12802, } // Message IDs may refer to strings that need to be localized. @@ -371,6 +372,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) case MessageID.IDS_FeatureVarianceSafetyForStaticInterfaceMembers: //semantic check case MessageID.IDS_FeatureConstantInterpolatedStrings: //semantic check + case MessageID.IDS_SingleLineNamespace: // syntax check return LanguageVersion.Preview; // C# 8.0 features. diff --git a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 index 17406ac149b7d..9c522c8962fc2 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 +++ b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 @@ -76,13 +76,13 @@ name_colon member_declaration : base_field_declaration | base_method_declaration + | base_namespace_declaration | base_property_declaration | base_type_declaration | delegate_declaration | enum_member_declaration | global_statement | incomplete_member - | namespace_declaration ; base_field_declaration @@ -232,6 +232,19 @@ operator_declaration : attribute_list* modifier* type 'operator' ('+' | '-' | '!' | '~' | '++' | '--' | '*' | '/' | '%' | '<<' | '>>' | '|' | '&' | '^' | '==' | '!=' | '<' | '<=' | '>' | '>=' | 'false' | 'true' | 'is') parameter_list (block | (arrow_expression_clause ';')) ; +base_namespace_declaration + : namespace_declaration + | single_line_namespace_declaration + ; + +namespace_declaration + : attribute_list* modifier* 'namespace' name '{' extern_alias_directive* using_directive* member_declaration* '}' ';'? + ; + +single_line_namespace_declaration + : attribute_list* modifier* 'namespace' name ';' extern_alias_directive* using_directive* member_declaration* + ; + base_property_declaration : event_declaration | indexer_declaration @@ -327,10 +340,6 @@ incomplete_member : attribute_list* modifier* type? ; -namespace_declaration - : attribute_list* modifier* 'namespace' name '{' extern_alias_directive* using_directive* member_declaration* '}' ';'? - ; - type : array_type | function_pointer_type diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs index 6bced1a20ae46..7bda2eaec5698 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs @@ -19358,7 +19358,35 @@ protected MemberDeclarationSyntax(ObjectReader reader) public abstract Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Modifiers { get; } } - internal sealed partial class NamespaceDeclarationSyntax : MemberDeclarationSyntax + internal abstract partial class BaseNamespaceDeclarationSyntax : MemberDeclarationSyntax + { + internal BaseNamespaceDeclarationSyntax(SyntaxKind kind, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + } + + internal BaseNamespaceDeclarationSyntax(SyntaxKind kind) + : base(kind) + { + } + + protected BaseNamespaceDeclarationSyntax(ObjectReader reader) + : base(reader) + { + } + + public abstract SyntaxToken NamespaceKeyword { get; } + + public abstract NameSyntax Name { get; } + + public abstract Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Externs { get; } + + public abstract Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Usings { get; } + + public abstract Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Members { get; } + } + + internal sealed partial class NamespaceDeclarationSyntax : BaseNamespaceDeclarationSyntax { internal readonly GreenNode? attributeLists; internal readonly GreenNode? modifiers; @@ -19506,12 +19534,12 @@ internal NamespaceDeclarationSyntax(SyntaxKind kind, GreenNode? attributeLists, public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList AttributeLists => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.attributeLists); public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Modifiers => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.modifiers); - public SyntaxToken NamespaceKeyword => this.namespaceKeyword; - public NameSyntax Name => this.name; + public override SyntaxToken NamespaceKeyword => this.namespaceKeyword; + public override NameSyntax Name => this.name; public SyntaxToken OpenBraceToken => this.openBraceToken; - public Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Externs => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.externs); - public Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Usings => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.usings); - public Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Members => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.members); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Externs => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.externs); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Usings => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.usings); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Members => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.members); public SyntaxToken CloseBraceToken => this.closeBraceToken; /// Gets the optional semicolon token. public SyntaxToken? SemicolonToken => this.semicolonToken; @@ -19635,6 +19663,244 @@ static NamespaceDeclarationSyntax() } } + internal sealed partial class SingleLineNamespaceDeclarationSyntax : BaseNamespaceDeclarationSyntax + { + internal readonly GreenNode? attributeLists; + internal readonly GreenNode? modifiers; + internal readonly SyntaxToken namespaceKeyword; + internal readonly NameSyntax name; + internal readonly SyntaxToken semicolonToken; + internal readonly GreenNode? externs; + internal readonly GreenNode? usings; + internal readonly GreenNode? members; + + internal SingleLineNamespaceDeclarationSyntax(SyntaxKind kind, GreenNode? attributeLists, GreenNode? modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, GreenNode? externs, GreenNode? usings, GreenNode? members, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + this.SlotCount = 8; + if (attributeLists != null) + { + this.AdjustFlagsAndWidth(attributeLists); + this.attributeLists = attributeLists; + } + if (modifiers != null) + { + this.AdjustFlagsAndWidth(modifiers); + this.modifiers = modifiers; + } + this.AdjustFlagsAndWidth(namespaceKeyword); + this.namespaceKeyword = namespaceKeyword; + this.AdjustFlagsAndWidth(name); + this.name = name; + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + if (externs != null) + { + this.AdjustFlagsAndWidth(externs); + this.externs = externs; + } + if (usings != null) + { + this.AdjustFlagsAndWidth(usings); + this.usings = usings; + } + if (members != null) + { + this.AdjustFlagsAndWidth(members); + this.members = members; + } + } + + internal SingleLineNamespaceDeclarationSyntax(SyntaxKind kind, GreenNode? attributeLists, GreenNode? modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, GreenNode? externs, GreenNode? usings, GreenNode? members, SyntaxFactoryContext context) + : base(kind) + { + this.SetFactoryContext(context); + this.SlotCount = 8; + if (attributeLists != null) + { + this.AdjustFlagsAndWidth(attributeLists); + this.attributeLists = attributeLists; + } + if (modifiers != null) + { + this.AdjustFlagsAndWidth(modifiers); + this.modifiers = modifiers; + } + this.AdjustFlagsAndWidth(namespaceKeyword); + this.namespaceKeyword = namespaceKeyword; + this.AdjustFlagsAndWidth(name); + this.name = name; + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + if (externs != null) + { + this.AdjustFlagsAndWidth(externs); + this.externs = externs; + } + if (usings != null) + { + this.AdjustFlagsAndWidth(usings); + this.usings = usings; + } + if (members != null) + { + this.AdjustFlagsAndWidth(members); + this.members = members; + } + } + + internal SingleLineNamespaceDeclarationSyntax(SyntaxKind kind, GreenNode? attributeLists, GreenNode? modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, GreenNode? externs, GreenNode? usings, GreenNode? members) + : base(kind) + { + this.SlotCount = 8; + if (attributeLists != null) + { + this.AdjustFlagsAndWidth(attributeLists); + this.attributeLists = attributeLists; + } + if (modifiers != null) + { + this.AdjustFlagsAndWidth(modifiers); + this.modifiers = modifiers; + } + this.AdjustFlagsAndWidth(namespaceKeyword); + this.namespaceKeyword = namespaceKeyword; + this.AdjustFlagsAndWidth(name); + this.name = name; + this.AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + if (externs != null) + { + this.AdjustFlagsAndWidth(externs); + this.externs = externs; + } + if (usings != null) + { + this.AdjustFlagsAndWidth(usings); + this.usings = usings; + } + if (members != null) + { + this.AdjustFlagsAndWidth(members); + this.members = members; + } + } + + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList AttributeLists => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.attributeLists); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Modifiers => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.modifiers); + public override SyntaxToken NamespaceKeyword => this.namespaceKeyword; + public override NameSyntax Name => this.name; + public SyntaxToken SemicolonToken => this.semicolonToken; + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Externs => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.externs); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Usings => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.usings); + public override Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList Members => new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(this.members); + + internal override GreenNode? GetSlot(int index) + => index switch + { + 0 => this.attributeLists, + 1 => this.modifiers, + 2 => this.namespaceKeyword, + 3 => this.name, + 4 => this.semicolonToken, + 5 => this.externs, + 6 => this.usings, + 7 => this.members, + _ => null, + }; + + internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.SingleLineNamespaceDeclarationSyntax(this, parent, position); + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSingleLineNamespaceDeclaration(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSingleLineNamespaceDeclaration(this); + + public SingleLineNamespaceDeclarationSyntax Update(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList externs, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList usings, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList members) + { + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || namespaceKeyword != this.NamespaceKeyword || name != this.Name || semicolonToken != this.SemicolonToken || externs != this.Externs || usings != this.Usings || members != this.Members) + { + var newNode = SyntaxFactory.SingleLineNamespaceDeclaration(attributeLists, modifiers, namespaceKeyword, name, semicolonToken, externs, usings, members); + var diags = GetDiagnostics(); + if (diags?.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations?.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; + } + + return this; + } + + internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics) + => new SingleLineNamespaceDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.namespaceKeyword, this.name, this.semicolonToken, this.externs, this.usings, this.members, diagnostics, GetAnnotations()); + + internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) + => new SingleLineNamespaceDeclarationSyntax(this.Kind, this.attributeLists, this.modifiers, this.namespaceKeyword, this.name, this.semicolonToken, this.externs, this.usings, this.members, GetDiagnostics(), annotations); + + internal SingleLineNamespaceDeclarationSyntax(ObjectReader reader) + : base(reader) + { + this.SlotCount = 8; + var attributeLists = (GreenNode?)reader.ReadValue(); + if (attributeLists != null) + { + AdjustFlagsAndWidth(attributeLists); + this.attributeLists = attributeLists; + } + var modifiers = (GreenNode?)reader.ReadValue(); + if (modifiers != null) + { + AdjustFlagsAndWidth(modifiers); + this.modifiers = modifiers; + } + var namespaceKeyword = (SyntaxToken)reader.ReadValue(); + AdjustFlagsAndWidth(namespaceKeyword); + this.namespaceKeyword = namespaceKeyword; + var name = (NameSyntax)reader.ReadValue(); + AdjustFlagsAndWidth(name); + this.name = name; + var semicolonToken = (SyntaxToken)reader.ReadValue(); + AdjustFlagsAndWidth(semicolonToken); + this.semicolonToken = semicolonToken; + var externs = (GreenNode?)reader.ReadValue(); + if (externs != null) + { + AdjustFlagsAndWidth(externs); + this.externs = externs; + } + var usings = (GreenNode?)reader.ReadValue(); + if (usings != null) + { + AdjustFlagsAndWidth(usings); + this.usings = usings; + } + var members = (GreenNode?)reader.ReadValue(); + if (members != null) + { + AdjustFlagsAndWidth(members); + this.members = members; + } + } + + internal override void WriteTo(ObjectWriter writer) + { + base.WriteTo(writer); + writer.WriteValue(this.attributeLists); + writer.WriteValue(this.modifiers); + writer.WriteValue(this.namespaceKeyword); + writer.WriteValue(this.name); + writer.WriteValue(this.semicolonToken); + writer.WriteValue(this.externs); + writer.WriteValue(this.usings); + writer.WriteValue(this.members); + } + + static SingleLineNamespaceDeclarationSyntax() + { + ObjectBinder.RegisterTypeReader(typeof(SingleLineNamespaceDeclarationSyntax), r => new SingleLineNamespaceDeclarationSyntax(r)); + } + } + /// Class representing one or more attributes applied to a language construct. internal sealed partial class AttributeListSyntax : CSharpSyntaxNode { @@ -33204,6 +33470,7 @@ internal partial class CSharpSyntaxVisitor public virtual TResult VisitExternAliasDirective(ExternAliasDirectiveSyntax node) => this.DefaultVisit(node); public virtual TResult VisitUsingDirective(UsingDirectiveSyntax node) => this.DefaultVisit(node); public virtual TResult VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => this.DefaultVisit(node); + public virtual TResult VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) => this.DefaultVisit(node); public virtual TResult VisitAttributeList(AttributeListSyntax node) => this.DefaultVisit(node); public virtual TResult VisitAttributeTargetSpecifier(AttributeTargetSpecifierSyntax node) => this.DefaultVisit(node); public virtual TResult VisitAttribute(AttributeSyntax node) => this.DefaultVisit(node); @@ -33439,6 +33706,7 @@ internal partial class CSharpSyntaxVisitor public virtual void VisitExternAliasDirective(ExternAliasDirectiveSyntax node) => this.DefaultVisit(node); public virtual void VisitUsingDirective(UsingDirectiveSyntax node) => this.DefaultVisit(node); public virtual void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => this.DefaultVisit(node); + public virtual void VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) => this.DefaultVisit(node); public virtual void VisitAttributeList(AttributeListSyntax node) => this.DefaultVisit(node); public virtual void VisitAttributeTargetSpecifier(AttributeTargetSpecifierSyntax node) => this.DefaultVisit(node); public virtual void VisitAttribute(AttributeSyntax node) => this.DefaultVisit(node); @@ -33966,6 +34234,9 @@ public override CSharpSyntaxNode VisitUsingDirective(UsingDirectiveSyntax node) public override CSharpSyntaxNode VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), (SyntaxToken)Visit(node.NamespaceKeyword), (NameSyntax)Visit(node.Name), (SyntaxToken)Visit(node.OpenBraceToken), VisitList(node.Externs), VisitList(node.Usings), VisitList(node.Members), (SyntaxToken)Visit(node.CloseBraceToken), (SyntaxToken)Visit(node.SemicolonToken)); + public override CSharpSyntaxNode VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) + => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), (SyntaxToken)Visit(node.NamespaceKeyword), (NameSyntax)Visit(node.Name), (SyntaxToken)Visit(node.SemicolonToken), VisitList(node.Externs), VisitList(node.Usings), VisitList(node.Members)); + public override CSharpSyntaxNode VisitAttributeList(AttributeListSyntax node) => node.Update((SyntaxToken)Visit(node.OpenBracketToken), (AttributeTargetSpecifierSyntax)Visit(node.Target), VisitList(node.Attributes), (SyntaxToken)Visit(node.CloseBracketToken)); @@ -37331,6 +37602,19 @@ public NamespaceDeclarationSyntax NamespaceDeclaration(Microsoft.CodeAnalysis.Sy return new NamespaceDeclarationSyntax(SyntaxKind.NamespaceDeclaration, attributeLists.Node, modifiers.Node, namespaceKeyword, name, openBraceToken, externs.Node, usings.Node, members.Node, closeBraceToken, semicolonToken, this.context); } + public SingleLineNamespaceDeclarationSyntax SingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList externs, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList usings, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList members) + { +#if DEBUG + if (namespaceKeyword == null) throw new ArgumentNullException(nameof(namespaceKeyword)); + if (namespaceKeyword.Kind != SyntaxKind.NamespaceKeyword) throw new ArgumentException(nameof(namespaceKeyword)); + if (name == null) throw new ArgumentNullException(nameof(name)); + if (semicolonToken == null) throw new ArgumentNullException(nameof(semicolonToken)); + if (semicolonToken.Kind != SyntaxKind.SemicolonToken) throw new ArgumentException(nameof(semicolonToken)); +#endif + + return new SingleLineNamespaceDeclarationSyntax(SyntaxKind.SingleLineNamespaceDeclaration, attributeLists.Node, modifiers.Node, namespaceKeyword, name, semicolonToken, externs.Node, usings.Node, members.Node, this.context); + } + public AttributeListSyntax AttributeList(SyntaxToken openBracketToken, AttributeTargetSpecifierSyntax? target, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList attributes, SyntaxToken closeBracketToken) { #if DEBUG @@ -42225,6 +42509,19 @@ public static NamespaceDeclarationSyntax NamespaceDeclaration(Microsoft.CodeAnal return new NamespaceDeclarationSyntax(SyntaxKind.NamespaceDeclaration, attributeLists.Node, modifiers.Node, namespaceKeyword, name, openBraceToken, externs.Node, usings.Node, members.Node, closeBraceToken, semicolonToken); } + public static SingleLineNamespaceDeclarationSyntax SingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList attributeLists, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList externs, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList usings, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList members) + { +#if DEBUG + if (namespaceKeyword == null) throw new ArgumentNullException(nameof(namespaceKeyword)); + if (namespaceKeyword.Kind != SyntaxKind.NamespaceKeyword) throw new ArgumentException(nameof(namespaceKeyword)); + if (name == null) throw new ArgumentNullException(nameof(name)); + if (semicolonToken == null) throw new ArgumentNullException(nameof(semicolonToken)); + if (semicolonToken.Kind != SyntaxKind.SemicolonToken) throw new ArgumentException(nameof(semicolonToken)); +#endif + + return new SingleLineNamespaceDeclarationSyntax(SyntaxKind.SingleLineNamespaceDeclaration, attributeLists.Node, modifiers.Node, namespaceKeyword, name, semicolonToken, externs.Node, usings.Node, members.Node); + } + public static AttributeListSyntax AttributeList(SyntaxToken openBracketToken, AttributeTargetSpecifierSyntax? target, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList attributes, SyntaxToken closeBracketToken) { #if DEBUG @@ -44163,6 +44460,7 @@ internal static IEnumerable GetNodeTypes() typeof(ExternAliasDirectiveSyntax), typeof(UsingDirectiveSyntax), typeof(NamespaceDeclarationSyntax), + typeof(SingleLineNamespaceDeclarationSyntax), typeof(AttributeListSyntax), typeof(AttributeTargetSpecifierSyntax), typeof(AttributeSyntax), diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs index 66690ae17168a..3884d9fca1638 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs @@ -453,6 +453,9 @@ public partial class CSharpSyntaxVisitor /// Called when the visitor visits a NamespaceDeclarationSyntax node. public virtual TResult? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a SingleLineNamespaceDeclarationSyntax node. + public virtual TResult? VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a AttributeListSyntax node. public virtual TResult? VisitAttributeList(AttributeListSyntax node) => this.DefaultVisit(node); @@ -1149,6 +1152,9 @@ public partial class CSharpSyntaxVisitor /// Called when the visitor visits a NamespaceDeclarationSyntax node. public virtual void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a SingleLineNamespaceDeclarationSyntax node. + public virtual void VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a AttributeListSyntax node. public virtual void VisitAttributeList(AttributeListSyntax node) => this.DefaultVisit(node); @@ -1845,6 +1851,9 @@ public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor public override SyntaxNode? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), VisitToken(node.NamespaceKeyword), (NameSyntax?)Visit(node.Name) ?? throw new ArgumentNullException("name"), VisitToken(node.OpenBraceToken), VisitList(node.Externs), VisitList(node.Usings), VisitList(node.Members), VisitToken(node.CloseBraceToken), VisitToken(node.SemicolonToken)); + public override SyntaxNode? VisitSingleLineNamespaceDeclaration(SingleLineNamespaceDeclarationSyntax node) + => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), VisitToken(node.NamespaceKeyword), (NameSyntax?)Visit(node.Name) ?? throw new ArgumentNullException("name"), VisitToken(node.SemicolonToken), VisitList(node.Externs), VisitList(node.Usings), VisitList(node.Members)); + public override SyntaxNode? VisitAttributeList(AttributeListSyntax node) => node.Update(VisitToken(node.OpenBracketToken), (AttributeTargetSpecifierSyntax?)Visit(node.Target), VisitList(node.Attributes), VisitToken(node.CloseBracketToken)); @@ -4611,6 +4620,23 @@ public static NamespaceDeclarationSyntax NamespaceDeclaration(SyntaxList SyntaxFactory.NamespaceDeclaration(default, default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.NamespaceKeyword), name, SyntaxFactory.Token(SyntaxKind.OpenBraceToken), default, default, default, SyntaxFactory.Token(SyntaxKind.CloseBraceToken), default); + /// Creates a new SingleLineNamespaceDeclarationSyntax instance. + public static SingleLineNamespaceDeclarationSyntax SingleLineNamespaceDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, SyntaxList externs, SyntaxList usings, SyntaxList members) + { + if (namespaceKeyword.Kind() != SyntaxKind.NamespaceKeyword) throw new ArgumentException(nameof(namespaceKeyword)); + if (name == null) throw new ArgumentNullException(nameof(name)); + if (semicolonToken.Kind() != SyntaxKind.SemicolonToken) throw new ArgumentException(nameof(semicolonToken)); + return (SingleLineNamespaceDeclarationSyntax)Syntax.InternalSyntax.SyntaxFactory.SingleLineNamespaceDeclaration(attributeLists.Node.ToGreenList(), modifiers.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)namespaceKeyword.Node!, (Syntax.InternalSyntax.NameSyntax)name.Green, (Syntax.InternalSyntax.SyntaxToken)semicolonToken.Node!, externs.Node.ToGreenList(), usings.Node.ToGreenList(), members.Node.ToGreenList()).CreateRed(); + } + + /// Creates a new SingleLineNamespaceDeclarationSyntax instance. + public static SingleLineNamespaceDeclarationSyntax SingleLineNamespaceDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, NameSyntax name, SyntaxList externs, SyntaxList usings, SyntaxList members) + => SyntaxFactory.SingleLineNamespaceDeclaration(attributeLists, modifiers, SyntaxFactory.Token(SyntaxKind.NamespaceKeyword), name, SyntaxFactory.Token(SyntaxKind.SemicolonToken), externs, usings, members); + + /// Creates a new SingleLineNamespaceDeclarationSyntax instance. + public static SingleLineNamespaceDeclarationSyntax SingleLineNamespaceDeclaration(NameSyntax name) + => SyntaxFactory.SingleLineNamespaceDeclaration(default, default(SyntaxTokenList), SyntaxFactory.Token(SyntaxKind.NamespaceKeyword), name, SyntaxFactory.Token(SyntaxKind.SemicolonToken), default, default, default); + /// Creates a new AttributeListSyntax instance. public static AttributeListSyntax AttributeList(SyntaxToken openBracketToken, AttributeTargetSpecifierSyntax? target, SeparatedSyntaxList attributes, SyntaxToken closeBracketToken) { diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs index e5528217336a2..59dd22175a229 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs @@ -9061,13 +9061,57 @@ internal MemberDeclarationSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNo internal abstract MemberDeclarationSyntax AddModifiersCore(params SyntaxToken[] items); } + public abstract partial class BaseNamespaceDeclarationSyntax : MemberDeclarationSyntax + { + internal BaseNamespaceDeclarationSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } + + public abstract SyntaxToken NamespaceKeyword { get; } + public BaseNamespaceDeclarationSyntax WithNamespaceKeyword(SyntaxToken namespaceKeyword) => WithNamespaceKeywordCore(namespaceKeyword); + internal abstract BaseNamespaceDeclarationSyntax WithNamespaceKeywordCore(SyntaxToken namespaceKeyword); + + public abstract NameSyntax Name { get; } + public BaseNamespaceDeclarationSyntax WithName(NameSyntax name) => WithNameCore(name); + internal abstract BaseNamespaceDeclarationSyntax WithNameCore(NameSyntax name); + + public abstract SyntaxList Externs { get; } + public BaseNamespaceDeclarationSyntax WithExterns(SyntaxList externs) => WithExternsCore(externs); + internal abstract BaseNamespaceDeclarationSyntax WithExternsCore(SyntaxList externs); + + public BaseNamespaceDeclarationSyntax AddExterns(params ExternAliasDirectiveSyntax[] items) => AddExternsCore(items); + internal abstract BaseNamespaceDeclarationSyntax AddExternsCore(params ExternAliasDirectiveSyntax[] items); + + public abstract SyntaxList Usings { get; } + public BaseNamespaceDeclarationSyntax WithUsings(SyntaxList usings) => WithUsingsCore(usings); + internal abstract BaseNamespaceDeclarationSyntax WithUsingsCore(SyntaxList usings); + + public BaseNamespaceDeclarationSyntax AddUsings(params UsingDirectiveSyntax[] items) => AddUsingsCore(items); + internal abstract BaseNamespaceDeclarationSyntax AddUsingsCore(params UsingDirectiveSyntax[] items); + + public abstract SyntaxList Members { get; } + public BaseNamespaceDeclarationSyntax WithMembers(SyntaxList members) => WithMembersCore(members); + internal abstract BaseNamespaceDeclarationSyntax WithMembersCore(SyntaxList members); + + public BaseNamespaceDeclarationSyntax AddMembers(params MemberDeclarationSyntax[] items) => AddMembersCore(items); + internal abstract BaseNamespaceDeclarationSyntax AddMembersCore(params MemberDeclarationSyntax[] items); + + public new BaseNamespaceDeclarationSyntax WithAttributeLists(SyntaxList attributeLists) => (BaseNamespaceDeclarationSyntax)WithAttributeListsCore(attributeLists); + public new BaseNamespaceDeclarationSyntax WithModifiers(SyntaxTokenList modifiers) => (BaseNamespaceDeclarationSyntax)WithModifiersCore(modifiers); + + public new BaseNamespaceDeclarationSyntax AddAttributeLists(params AttributeListSyntax[] items) => (BaseNamespaceDeclarationSyntax)AddAttributeListsCore(items); + + public new BaseNamespaceDeclarationSyntax AddModifiers(params SyntaxToken[] items) => (BaseNamespaceDeclarationSyntax)AddModifiersCore(items); + } + /// /// This node is associated with the following syntax kinds: /// /// /// /// - public sealed partial class NamespaceDeclarationSyntax : MemberDeclarationSyntax + public sealed partial class NamespaceDeclarationSyntax : BaseNamespaceDeclarationSyntax { private SyntaxNode? attributeLists; private NameSyntax? name; @@ -9091,17 +9135,17 @@ public override SyntaxTokenList Modifiers } } - public SyntaxToken NamespaceKeyword => new SyntaxToken(this, ((Syntax.InternalSyntax.NamespaceDeclarationSyntax)this.Green).namespaceKeyword, GetChildPosition(2), GetChildIndex(2)); + public override SyntaxToken NamespaceKeyword => new SyntaxToken(this, ((Syntax.InternalSyntax.NamespaceDeclarationSyntax)this.Green).namespaceKeyword, GetChildPosition(2), GetChildIndex(2)); - public NameSyntax Name => GetRed(ref this.name, 3)!; + public override NameSyntax Name => GetRed(ref this.name, 3)!; public SyntaxToken OpenBraceToken => new SyntaxToken(this, ((Syntax.InternalSyntax.NamespaceDeclarationSyntax)this.Green).openBraceToken, GetChildPosition(4), GetChildIndex(4)); - public SyntaxList Externs => new SyntaxList(GetRed(ref this.externs, 5)); + public override SyntaxList Externs => new SyntaxList(GetRed(ref this.externs, 5)); - public SyntaxList Usings => new SyntaxList(GetRed(ref this.usings, 6)); + public override SyntaxList Usings => new SyntaxList(GetRed(ref this.usings, 6)); - public SyntaxList Members => new SyntaxList(GetRed(ref this.members, 7)); + public override SyntaxList Members => new SyntaxList(GetRed(ref this.members, 7)); public SyntaxToken CloseBraceToken => new SyntaxToken(this, ((Syntax.InternalSyntax.NamespaceDeclarationSyntax)this.Green).closeBraceToken, GetChildPosition(8), GetChildIndex(8)); @@ -9156,12 +9200,17 @@ public NamespaceDeclarationSyntax Update(SyntaxList attribu public new NamespaceDeclarationSyntax WithAttributeLists(SyntaxList attributeLists) => Update(attributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); internal override MemberDeclarationSyntax WithModifiersCore(SyntaxTokenList modifiers) => WithModifiers(modifiers); public new NamespaceDeclarationSyntax WithModifiers(SyntaxTokenList modifiers) => Update(this.AttributeLists, modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); - public NamespaceDeclarationSyntax WithNamespaceKeyword(SyntaxToken namespaceKeyword) => Update(this.AttributeLists, this.Modifiers, namespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); - public NamespaceDeclarationSyntax WithName(NameSyntax name) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); + internal override BaseNamespaceDeclarationSyntax WithNamespaceKeywordCore(SyntaxToken namespaceKeyword) => WithNamespaceKeyword(namespaceKeyword); + public new NamespaceDeclarationSyntax WithNamespaceKeyword(SyntaxToken namespaceKeyword) => Update(this.AttributeLists, this.Modifiers, namespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); + internal override BaseNamespaceDeclarationSyntax WithNameCore(NameSyntax name) => WithName(name); + public new NamespaceDeclarationSyntax WithName(NameSyntax name) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); public NamespaceDeclarationSyntax WithOpenBraceToken(SyntaxToken openBraceToken) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, openBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); - public NamespaceDeclarationSyntax WithExterns(SyntaxList externs) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); - public NamespaceDeclarationSyntax WithUsings(SyntaxList usings) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, usings, this.Members, this.CloseBraceToken, this.SemicolonToken); - public NamespaceDeclarationSyntax WithMembers(SyntaxList members) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, members, this.CloseBraceToken, this.SemicolonToken); + internal override BaseNamespaceDeclarationSyntax WithExternsCore(SyntaxList externs) => WithExterns(externs); + public new NamespaceDeclarationSyntax WithExterns(SyntaxList externs) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, externs, this.Usings, this.Members, this.CloseBraceToken, this.SemicolonToken); + internal override BaseNamespaceDeclarationSyntax WithUsingsCore(SyntaxList usings) => WithUsings(usings); + public new NamespaceDeclarationSyntax WithUsings(SyntaxList usings) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, usings, this.Members, this.CloseBraceToken, this.SemicolonToken); + internal override BaseNamespaceDeclarationSyntax WithMembersCore(SyntaxList members) => WithMembers(members); + public new NamespaceDeclarationSyntax WithMembers(SyntaxList members) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, members, this.CloseBraceToken, this.SemicolonToken); public NamespaceDeclarationSyntax WithCloseBraceToken(SyntaxToken closeBraceToken) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, closeBraceToken, this.SemicolonToken); public NamespaceDeclarationSyntax WithSemicolonToken(SyntaxToken semicolonToken) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.OpenBraceToken, this.Externs, this.Usings, this.Members, this.CloseBraceToken, semicolonToken); @@ -9169,9 +9218,119 @@ public NamespaceDeclarationSyntax Update(SyntaxList attribu public new NamespaceDeclarationSyntax AddAttributeLists(params AttributeListSyntax[] items) => WithAttributeLists(this.AttributeLists.AddRange(items)); internal override MemberDeclarationSyntax AddModifiersCore(params SyntaxToken[] items) => AddModifiers(items); public new NamespaceDeclarationSyntax AddModifiers(params SyntaxToken[] items) => WithModifiers(this.Modifiers.AddRange(items)); - public NamespaceDeclarationSyntax AddExterns(params ExternAliasDirectiveSyntax[] items) => WithExterns(this.Externs.AddRange(items)); - public NamespaceDeclarationSyntax AddUsings(params UsingDirectiveSyntax[] items) => WithUsings(this.Usings.AddRange(items)); - public NamespaceDeclarationSyntax AddMembers(params MemberDeclarationSyntax[] items) => WithMembers(this.Members.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddExternsCore(params ExternAliasDirectiveSyntax[] items) => AddExterns(items); + public new NamespaceDeclarationSyntax AddExterns(params ExternAliasDirectiveSyntax[] items) => WithExterns(this.Externs.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddUsingsCore(params UsingDirectiveSyntax[] items) => AddUsings(items); + public new NamespaceDeclarationSyntax AddUsings(params UsingDirectiveSyntax[] items) => WithUsings(this.Usings.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddMembersCore(params MemberDeclarationSyntax[] items) => AddMembers(items); + public new NamespaceDeclarationSyntax AddMembers(params MemberDeclarationSyntax[] items) => WithMembers(this.Members.AddRange(items)); + } + + /// + /// This node is associated with the following syntax kinds: + /// + /// + /// + /// + public sealed partial class SingleLineNamespaceDeclarationSyntax : BaseNamespaceDeclarationSyntax + { + private SyntaxNode? attributeLists; + private NameSyntax? name; + private SyntaxNode? externs; + private SyntaxNode? usings; + private SyntaxNode? members; + + internal SingleLineNamespaceDeclarationSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } + + public override SyntaxList AttributeLists => new SyntaxList(GetRed(ref this.attributeLists, 0)); + + public override SyntaxTokenList Modifiers + { + get + { + var slot = this.Green.GetSlot(1); + return slot != null ? new SyntaxTokenList(this, slot, GetChildPosition(1), GetChildIndex(1)) : default; + } + } + + public override SyntaxToken NamespaceKeyword => new SyntaxToken(this, ((Syntax.InternalSyntax.SingleLineNamespaceDeclarationSyntax)this.Green).namespaceKeyword, GetChildPosition(2), GetChildIndex(2)); + + public override NameSyntax Name => GetRed(ref this.name, 3)!; + + public SyntaxToken SemicolonToken => new SyntaxToken(this, ((Syntax.InternalSyntax.SingleLineNamespaceDeclarationSyntax)this.Green).semicolonToken, GetChildPosition(4), GetChildIndex(4)); + + public override SyntaxList Externs => new SyntaxList(GetRed(ref this.externs, 5)); + + public override SyntaxList Usings => new SyntaxList(GetRed(ref this.usings, 6)); + + public override SyntaxList Members => new SyntaxList(GetRed(ref this.members, 7)); + + internal override SyntaxNode? GetNodeSlot(int index) + => index switch + { + 0 => GetRedAtZero(ref this.attributeLists)!, + 3 => GetRed(ref this.name, 3)!, + 5 => GetRed(ref this.externs, 5)!, + 6 => GetRed(ref this.usings, 6)!, + 7 => GetRed(ref this.members, 7)!, + _ => null, + }; + + internal override SyntaxNode? GetCachedSlot(int index) + => index switch + { + 0 => this.attributeLists, + 3 => this.name, + 5 => this.externs, + 6 => this.usings, + 7 => this.members, + _ => null, + }; + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSingleLineNamespaceDeclaration(this); + public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitSingleLineNamespaceDeclaration(this); + + public SingleLineNamespaceDeclarationSyntax Update(SyntaxList attributeLists, SyntaxTokenList modifiers, SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken semicolonToken, SyntaxList externs, SyntaxList usings, SyntaxList members) + { + if (attributeLists != this.AttributeLists || modifiers != this.Modifiers || namespaceKeyword != this.NamespaceKeyword || name != this.Name || semicolonToken != this.SemicolonToken || externs != this.Externs || usings != this.Usings || members != this.Members) + { + var newNode = SyntaxFactory.SingleLineNamespaceDeclaration(attributeLists, modifiers, namespaceKeyword, name, semicolonToken, externs, usings, members); + var annotations = GetAnnotations(); + return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode; + } + + return this; + } + + internal override MemberDeclarationSyntax WithAttributeListsCore(SyntaxList attributeLists) => WithAttributeLists(attributeLists); + public new SingleLineNamespaceDeclarationSyntax WithAttributeLists(SyntaxList attributeLists) => Update(attributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.SemicolonToken, this.Externs, this.Usings, this.Members); + internal override MemberDeclarationSyntax WithModifiersCore(SyntaxTokenList modifiers) => WithModifiers(modifiers); + public new SingleLineNamespaceDeclarationSyntax WithModifiers(SyntaxTokenList modifiers) => Update(this.AttributeLists, modifiers, this.NamespaceKeyword, this.Name, this.SemicolonToken, this.Externs, this.Usings, this.Members); + internal override BaseNamespaceDeclarationSyntax WithNamespaceKeywordCore(SyntaxToken namespaceKeyword) => WithNamespaceKeyword(namespaceKeyword); + public new SingleLineNamespaceDeclarationSyntax WithNamespaceKeyword(SyntaxToken namespaceKeyword) => Update(this.AttributeLists, this.Modifiers, namespaceKeyword, this.Name, this.SemicolonToken, this.Externs, this.Usings, this.Members); + internal override BaseNamespaceDeclarationSyntax WithNameCore(NameSyntax name) => WithName(name); + public new SingleLineNamespaceDeclarationSyntax WithName(NameSyntax name) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, name, this.SemicolonToken, this.Externs, this.Usings, this.Members); + public SingleLineNamespaceDeclarationSyntax WithSemicolonToken(SyntaxToken semicolonToken) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, semicolonToken, this.Externs, this.Usings, this.Members); + internal override BaseNamespaceDeclarationSyntax WithExternsCore(SyntaxList externs) => WithExterns(externs); + public new SingleLineNamespaceDeclarationSyntax WithExterns(SyntaxList externs) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.SemicolonToken, externs, this.Usings, this.Members); + internal override BaseNamespaceDeclarationSyntax WithUsingsCore(SyntaxList usings) => WithUsings(usings); + public new SingleLineNamespaceDeclarationSyntax WithUsings(SyntaxList usings) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.SemicolonToken, this.Externs, usings, this.Members); + internal override BaseNamespaceDeclarationSyntax WithMembersCore(SyntaxList members) => WithMembers(members); + public new SingleLineNamespaceDeclarationSyntax WithMembers(SyntaxList members) => Update(this.AttributeLists, this.Modifiers, this.NamespaceKeyword, this.Name, this.SemicolonToken, this.Externs, this.Usings, members); + + internal override MemberDeclarationSyntax AddAttributeListsCore(params AttributeListSyntax[] items) => AddAttributeLists(items); + public new SingleLineNamespaceDeclarationSyntax AddAttributeLists(params AttributeListSyntax[] items) => WithAttributeLists(this.AttributeLists.AddRange(items)); + internal override MemberDeclarationSyntax AddModifiersCore(params SyntaxToken[] items) => AddModifiers(items); + public new SingleLineNamespaceDeclarationSyntax AddModifiers(params SyntaxToken[] items) => WithModifiers(this.Modifiers.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddExternsCore(params ExternAliasDirectiveSyntax[] items) => AddExterns(items); + public new SingleLineNamespaceDeclarationSyntax AddExterns(params ExternAliasDirectiveSyntax[] items) => WithExterns(this.Externs.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddUsingsCore(params UsingDirectiveSyntax[] items) => AddUsings(items); + public new SingleLineNamespaceDeclarationSyntax AddUsings(params UsingDirectiveSyntax[] items) => WithUsings(this.Usings.AddRange(items)); + internal override BaseNamespaceDeclarationSyntax AddMembersCore(params MemberDeclarationSyntax[] items) => AddMembers(items); + public new SingleLineNamespaceDeclarationSyntax AddMembers(params MemberDeclarationSyntax[] items) => WithMembers(this.Members.AddRange(items)); } /// Class representing one or more attributes applied to a language construct. diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 88bc472607d29..306acbc556218 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -233,7 +233,7 @@ private TNode CreateForGlobalFailure(int position, TNode node) where TNod return AddError(node, position, 0, ErrorCode.ERR_InsufficientStack); } - private NamespaceDeclarationSyntax ParseNamespaceDeclaration( + private BaseNamespaceDeclarationSyntax ParseNamespaceDeclaration( SyntaxList attributeLists, SyntaxListBuilder modifiers) { @@ -244,7 +244,7 @@ private NamespaceDeclarationSyntax ParseNamespaceDeclaration( return result; } - private NamespaceDeclarationSyntax ParseNamespaceDeclarationCore( + private BaseNamespaceDeclarationSyntax ParseNamespaceDeclarationCore( SyntaxList attributeLists, SyntaxListBuilder modifiers) { @@ -258,8 +258,14 @@ private NamespaceDeclarationSyntax ParseNamespaceDeclarationCore( var name = this.ParseQualifiedName(); - SyntaxToken openBrace; - if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken || IsPossibleNamespaceMemberDeclaration()) + SyntaxToken openBrace = null; + SyntaxToken semicolon = null; + + if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken) + { + semicolon = this.EatToken(SyntaxKind.SemicolonToken); + } + else if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken || IsPossibleNamespaceMemberDeclaration()) { //either we see the brace we expect here or we see something that could come after a brace //so we insert a missing one @@ -273,19 +279,48 @@ private NamespaceDeclarationSyntax ParseNamespaceDeclarationCore( openBrace = this.ConvertToMissingWithTrailingTrivia(openBrace, SyntaxKind.OpenBraceToken); } + Debug.Assert(semicolon != null || openBrace != null); + var body = new NamespaceBodyBuilder(_pool); - SyntaxListBuilder initialBadNodes = null; try { - this.ParseNamespaceBody(ref openBrace, ref body, ref initialBadNodes, SyntaxKind.NamespaceDeclaration); + if (openBrace == null) + { + Debug.Assert(semicolon != null); - var closeBrace = this.EatToken(SyntaxKind.CloseBraceToken); - var semicolon = this.TryEatToken(SyntaxKind.SemicolonToken); + SyntaxListBuilder initialBadNodes = null; + this.ParseNamespaceBody(ref semicolon, ref body, ref initialBadNodes, SyntaxKind.SingleLineNamespaceDeclaration); + Debug.Assert(initialBadNodes == null); // init bad nodes should have been attached to open brace... + + namespaceToken = CheckFeatureAvailability(namespaceToken, MessageID.IDS_SingleLineNamespace); + return _syntaxFactory.SingleLineNamespaceDeclaration( + attributeLists, + modifiers.ToList(), + namespaceToken, + name, + semicolon, + body.Externs, + body.Usings, + body.Members); + } + else + { + SyntaxListBuilder initialBadNodes = null; + this.ParseNamespaceBody(ref openBrace, ref body, ref initialBadNodes, SyntaxKind.NamespaceDeclaration); + Debug.Assert(initialBadNodes == null); // init bad nodes should have been attached to open brace... - Debug.Assert(initialBadNodes == null); // init bad nodes should have been attached to open brace... - return _syntaxFactory.NamespaceDeclaration( - attributeLists, modifiers.ToList(), - namespaceToken, name, openBrace, body.Externs, body.Usings, body.Members, closeBrace, semicolon); + return _syntaxFactory.NamespaceDeclaration( + attributeLists, + modifiers.ToList(), + namespaceToken, + name, + openBrace, + body.Externs, + body.Usings, + body.Members, + this.EatToken(SyntaxKind.CloseBraceToken), + this.TryEatToken(SyntaxKind.SemicolonToken)); + } } finally { @@ -319,7 +354,7 @@ private static bool IsPossibleStartOfTypeDeclaration(SyntaxKind kind) } private void AddSkippedNamespaceText( - ref SyntaxToken openBrace, + ref SyntaxToken openBraceOrSemicolon, ref NamespaceBodyBuilder body, ref SyntaxListBuilder initialBadNodes, CSharpSyntaxNode skippedSyntax) @@ -340,9 +375,9 @@ private void AddSkippedNamespaceText( { AddTrailingSkippedSyntax(body.Externs, skippedSyntax); } - else if (openBrace != null) + else if (openBraceOrSemicolon != null) { - openBrace = AddTrailingSkippedSyntax(openBrace, skippedSyntax); + openBraceOrSemicolon = AddTrailingSkippedSyntax(openBraceOrSemicolon, skippedSyntax); } else { @@ -367,12 +402,12 @@ private enum NamespaceParts TopLevelStatementsAfterTypesAndNamespaces = 6, } - private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuilder body, ref SyntaxListBuilder initialBadNodes, SyntaxKind parentKind) + private void ParseNamespaceBody(ref SyntaxToken openBraceOrSemicolon, ref NamespaceBodyBuilder body, ref SyntaxListBuilder initialBadNodes, SyntaxKind parentKind) { // "top-level" expressions and statements should never occur inside an asynchronous context Debug.Assert(!IsInAsync); - bool isGlobal = openBrace == null; + bool isGlobal = openBraceOrSemicolon == null; var saveTerm = _termState; _termState |= TerminatorState.IsNamespaceMemberStartOrStop; @@ -411,13 +446,13 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil if (isGlobal) { // incomplete members must be processed before we add any nodes to the body: - ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBrace, ref body, ref initialBadNodes); + ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBraceOrSemicolon, ref body, ref initialBadNodes); var token = this.EatToken(); token = this.AddError(token, IsScript ? ErrorCode.ERR_GlobalDefinitionOrStatementExpected : ErrorCode.ERR_EOFExpected); - this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, token); + this.AddSkippedNamespaceText(ref openBraceOrSemicolon, ref body, ref initialBadNodes, token); reportUnexpectedToken = true; break; } @@ -440,13 +475,13 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil else { // incomplete members must be processed before we add any nodes to the body: - ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBrace, ref body, ref initialBadNodes); + ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBraceOrSemicolon, ref body, ref initialBadNodes); var @extern = ParseExternAliasDirective(); if (seen > NamespaceParts.ExternAliases) { @extern = this.AddErrorToFirstToken(@extern, ErrorCode.ERR_ExternAfterElements); - this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, @extern); + this.AddSkippedNamespaceText(ref openBraceOrSemicolon, ref body, ref initialBadNodes, @extern); } else { @@ -466,7 +501,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil } else { - parseUsingDirective(ref openBrace, ref body, ref initialBadNodes, ref seen, ref pendingIncompleteMembers); + parseUsingDirective(ref openBraceOrSemicolon, ref body, ref initialBadNodes, ref seen, ref pendingIncompleteMembers); } reportUnexpectedToken = true; @@ -479,7 +514,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil } else { - parseUsingDirective(ref openBrace, ref body, ref initialBadNodes, ref seen, ref pendingIncompleteMembers); + parseUsingDirective(ref openBraceOrSemicolon, ref body, ref initialBadNodes, ref seen, ref pendingIncompleteMembers); } reportUnexpectedToken = true; @@ -489,13 +524,13 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil if (this.IsPossibleGlobalAttributeDeclaration()) { // incomplete members must be processed before we add any nodes to the body: - ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBrace, ref body, ref initialBadNodes); + ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBraceOrSemicolon, ref body, ref initialBadNodes); var attribute = this.ParseAttributeDeclaration(); if (!isGlobal || seen > NamespaceParts.GlobalAttributes) { attribute = this.AddError(attribute, attribute.Target.Identifier, ErrorCode.ERR_GlobalAttributesNotFirst); - this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, attribute); + this.AddSkippedNamespaceText(ref openBraceOrSemicolon, ref body, ref initialBadNodes, attribute); } else { @@ -514,7 +549,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil if (memberOrStatement == null) { // incomplete members must be processed before we add any nodes to the body: - ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBrace, ref body, ref initialBadNodes); + ReduceIncompleteMembers(ref pendingIncompleteMembers, ref openBraceOrSemicolon, ref body, ref initialBadNodes); // eat one token and try to parse declaration or statement again: var skippedToken = EatToken(); @@ -527,7 +562,7 @@ private void ParseNamespaceBody(ref SyntaxToken openBrace, ref NamespaceBodyBuil reportUnexpectedToken = false; } - this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, skippedToken); + this.AddSkippedNamespaceText(ref openBraceOrSemicolon, ref body, ref initialBadNodes, skippedToken); } else if (memberOrStatement.Kind == SyntaxKind.IncompleteMember && seen < NamespaceParts.MembersAndStatements) { @@ -577,6 +612,7 @@ MemberDeclarationSyntax adjustStateAndReportStatementOutOfOrder(ref NamespacePar break; case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.ClassDeclaration: @@ -640,12 +676,15 @@ private static void AddIncompleteMembers(ref SyntaxListBuilder incompleteMembers, - ref SyntaxToken openBrace, ref NamespaceBodyBuilder body, ref SyntaxListBuilder initialBadNodes) + private void ReduceIncompleteMembers( + ref SyntaxListBuilder incompleteMembers, + ref SyntaxToken openBraceOrSemicolon, + ref NamespaceBodyBuilder body, + ref SyntaxListBuilder initialBadNodes) { for (int i = 0; i < incompleteMembers.Count; i++) { - this.AddSkippedNamespaceText(ref openBrace, ref body, ref initialBadNodes, incompleteMembers[i]); + this.AddSkippedNamespaceText(ref openBraceOrSemicolon, ref body, ref initialBadNodes, incompleteMembers[i]); } incompleteMembers.Clear(); } @@ -2131,6 +2170,7 @@ private bool CanReuseMemberDeclaration(SyntaxKind kind, bool isGlobal) case SyntaxKind.DestructorDeclaration: case SyntaxKind.ConstructorDeclaration: case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: return true; @@ -2622,7 +2662,7 @@ private bool IsNoneOrIncompleteMember(SyntaxKind parentKind, SyntaxList Microsoft.CodeAnalysis.SyntaxList +*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Members.get -> Microsoft.CodeAnalysis.SyntaxList +*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Name.get -> Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax +*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.NamespaceKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Usings.get -> Microsoft.CodeAnalysis.SyntaxList +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.AddAttributeLists(params Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.AddExterns(params Microsoft.CodeAnalysis.CSharp.Syntax.ExternAliasDirectiveSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.AddMembers(params Microsoft.CodeAnalysis.CSharp.Syntax.MemberDeclarationSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.AddModifiers(params Microsoft.CodeAnalysis.SyntaxToken[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.AddUsings(params Microsoft.CodeAnalysis.CSharp.Syntax.UsingDirectiveSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithAttributeLists(Microsoft.CodeAnalysis.SyntaxList attributeLists) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithExterns(Microsoft.CodeAnalysis.SyntaxList externs) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithMembers(Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithName(Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithNamespaceKeyword(Microsoft.CodeAnalysis.SyntaxToken namespaceKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.WithUsings(Microsoft.CodeAnalysis.SyntaxList usings) -> Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AddAttributeLists(params Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AddExterns(params Microsoft.CodeAnalysis.CSharp.Syntax.ExternAliasDirectiveSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AddMembers(params Microsoft.CodeAnalysis.CSharp.Syntax.MemberDeclarationSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AddModifiers(params Microsoft.CodeAnalysis.SyntaxToken[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AddUsings(params Microsoft.CodeAnalysis.CSharp.Syntax.UsingDirectiveSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.SemicolonToken.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken namespaceKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name, Microsoft.CodeAnalysis.SyntaxToken semicolonToken, Microsoft.CodeAnalysis.SyntaxList externs, Microsoft.CodeAnalysis.SyntaxList usings, Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithAttributeLists(Microsoft.CodeAnalysis.SyntaxList attributeLists) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithExterns(Microsoft.CodeAnalysis.SyntaxList externs) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithMembers(Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithName(Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithNamespaceKeyword(Microsoft.CodeAnalysis.SyntaxToken namespaceKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.WithUsings(Microsoft.CodeAnalysis.SyntaxList usings) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineNamespaceDeclaration = 8845 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.Externs.get -> Microsoft.CodeAnalysis.SyntaxList +abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.Members.get -> Microsoft.CodeAnalysis.SyntaxList +abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.Name.get -> Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax +abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.NamespaceKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseNamespaceDeclarationSyntax.Usings.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitSingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode +override Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Externs.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Members.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Name.get -> Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax +override Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.NamespaceKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Usings.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.AttributeLists.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Externs.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Members.get -> Microsoft.CodeAnalysis.SyntaxList +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Modifiers.get -> Microsoft.CodeAnalysis.SyntaxTokenList +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Name.get -> Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.NamespaceKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax.Usings.get -> Microsoft.CodeAnalysis.SyntaxList +static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(this Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax declarationSyntax, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.INamespaceSymbol +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name, Microsoft.CodeAnalysis.SyntaxList externs, Microsoft.CodeAnalysis.SyntaxList usings, Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken namespaceKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax name, Microsoft.CodeAnalysis.SyntaxToken semicolonToken, Microsoft.CodeAnalysis.SyntaxList externs, Microsoft.CodeAnalysis.SyntaxList usings, Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitSingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax node) -> void +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitSingleLineNamespaceDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.SingleLineNamespaceDeclarationSyntax node) -> TResult Microsoft.CodeAnalysis.CSharp.SyntaxKind.RecordStructDeclaration = 9068 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind override Microsoft.CodeAnalysis.CSharp.CSharpCompilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray Microsoft.CodeAnalysis.CSharp.Syntax.LambdaExpressionSyntax.AddAttributeLists(params Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.LambdaExpressionSyntax diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor_Minimal.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor_Minimal.cs index 76dbaa0e0f28b..de9e3461b256f 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor_Minimal.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor_Minimal.cs @@ -197,7 +197,7 @@ private IDictionary CreateAliasMap() startNode = usingDirective.Parent.Parent; } - var usingAliases = GetAncestorsOrThis(startNode) + var usingAliases = GetAncestorsOrThis(startNode) .SelectMany(n => n.Usings) .Concat(GetAncestorsOrThis(startNode).SelectMany(c => c.Usings)) .Where(u => u.Alias != null) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 14e882e2d0feb..0e1814bf36755 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -2957,8 +2957,9 @@ private void AddDeclaredNontypeMembers(DeclaredMembersAndInitializersBuilder bui break; case SyntaxKind.NamespaceDeclaration: + case SyntaxKind.SingleLineNamespaceDeclaration: // The members of a global anonymous type is in a syntax tree of a namespace declaration or a compilation unit. - AddNonTypeMembers(builder, ((NamespaceDeclarationSyntax)syntax).Members, diagnostics); + AddNonTypeMembers(builder, ((BaseNamespaceDeclarationSyntax)syntax).Members, diagnostics); break; case SyntaxKind.CompilationUnit: @@ -4482,8 +4483,9 @@ private void AddNonTypeMembers( default: Debug.Assert( SyntaxFacts.IsTypeDeclaration(m.Kind()) || - m.Kind() == SyntaxKind.NamespaceDeclaration || - m.Kind() == SyntaxKind.IncompleteMember); + m.Kind() is SyntaxKind.NamespaceDeclaration or + SyntaxKind.SingleLineNamespaceDeclaration or + SyntaxKind.IncompleteMember); break; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.AliasesAndUsings.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.AliasesAndUsings.cs index ab846338eba59..6cb042bc845ac 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.AliasesAndUsings.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.AliasesAndUsings.cs @@ -43,7 +43,7 @@ public Imports GetImports(CSharpSyntaxNode declarationSyntax, ConsList GetExternAliases(CSharpSynta } break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: if (!namespaceDecl.Externs.Any()) { #if DEBUG @@ -143,7 +143,7 @@ public ImmutableArray GetUsingAliases(CSharpSyntaxNode d } break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: if (!namespaceDecl.Usings.Any()) { #if DEBUG @@ -175,7 +175,7 @@ public ImmutableDictionary GetUsingAliasesMap(CS } break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: if (!namespaceDecl.Usings.Any()) { #if DEBUG @@ -207,7 +207,7 @@ public ImmutableArray GetUsingNamespacesOrType } break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: if (!namespaceDecl.Usings.Any()) { #if DEBUG @@ -420,7 +420,7 @@ private ExternAliasesAndDiagnostics GetExternAliasesAndDiagnostics(SourceNamespa externAliasDirectives = compilationUnit.Externs; break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: externAliasDirectives = namespaceDecl.Externs; break; @@ -549,7 +549,7 @@ private UsingsAndDiagnostics GetUsingsAndDiagnostics(ref UsingsAndDiagnostics? u usingDirectives = compilationUnit.Usings; break; - case NamespaceDeclarationSyntax namespaceDecl: + case BaseNamespaceDeclarationSyntax namespaceDecl: Debug.Assert(!onlyGlobal); applyIsGlobalFilter = null; // Global Using directives are not allowed in namespaces, treat them as regular, an error is reported elsewhere. usingDirectives = namespaceDecl.Usings; diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index 4858cf03c15bf..3ec4988c3297b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -320,7 +320,7 @@ internal virtual LexicalSortKey GetLexicalSortKey() /// /// Note that for namespace symbol, the declaring syntax might be declaring a nested /// namespace. For example, the declaring syntax node for N1 in "namespace N1.N2 {...}" is - /// the entire for N1.N2. For the global namespace, the declaring + /// the entire for N1.N2. For the global namespace, the declaring /// syntax will be the . /// /// diff --git a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs index 2b94b2d586928..4b99caba975f2 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs @@ -167,6 +167,13 @@ internal static bool IsInNamespaceDeclaration(int position, NamespaceDeclaration return IsBetweenTokens(position, namespaceDecl.NamespaceKeyword, namespaceDecl.CloseBraceToken); } + internal static bool IsInNamespaceDeclaration(int position, SingleLineNamespaceDeclarationSyntax namespaceDecl) + { + Debug.Assert(namespaceDecl != null); + + return position >= namespaceDecl.SpanStart; + } + internal static bool IsInConstructorParameterScope(int position, ConstructorDeclarationSyntax constructorDecl) { Debug.Assert(constructorDecl != null); diff --git a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs index 10aae6d6b8710..2bc80f592d079 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs @@ -37,7 +37,7 @@ internal static SyntaxNode GetSyntax(SyntaxReference reference, CancellationToke node = node.Parent; } - Debug.Assert(node is CompilationUnitSyntax || node is NamespaceDeclarationSyntax); + Debug.Assert(node is CompilationUnitSyntax || node is BaseNamespaceDeclarationSyntax); return node; } diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 92ce9b7773454..bc24be922e652 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -3033,20 +3033,29 @@ - + + + + + + + + + + - + - + - - - + + + @@ -3057,6 +3066,21 @@ + + + + + + + + + + + + + + + Class representing one or more attributes applied to a language construct. diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index a4a34e3c4048d..8097f75d88db1 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -735,6 +735,7 @@ public enum SyntaxKind : ushort NamespaceDeclaration = 8842, UsingDirective = 8843, ExternAliasDirective = 8844, + SingleLineNamespaceDeclaration = 8845, // attributes AttributeList = 8847, diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs index 00c44edd37bc8..b111c0095c230 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs @@ -353,7 +353,9 @@ public static bool IsTypeDeclaration(SyntaxKind kind) } public static bool IsNamespaceMemberDeclaration(SyntaxKind kind) - => IsTypeDeclaration(kind) || (kind == SyntaxKind.NamespaceDeclaration); + => IsTypeDeclaration(kind) || + kind == SyntaxKind.NamespaceDeclaration || + kind == SyntaxKind.SingleLineNamespaceDeclaration; public static bool IsAnyUnaryExpression(SyntaxKind token) { diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 4dd8850d512fe..9d6f386ad8a48 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -652,6 +652,11 @@ Seznam parametrů může mít jenom částečná deklarace jednoho záznamu. + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Omezení new() nejde používat s omezením unmanaged. @@ -892,6 +897,16 @@ Vzor deconstruct s jedním elementem vyžaduje určitou další syntaxi pro zajištění jednoznačnosti. Doporučuje se přidat označení discard „_“ za koncovou závorku „)“. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Člen záznamu {0} nemůže být statický. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. Sestavení {0}, které obsahuje typ {1}, se odkazuje na architekturu .NET Framework, což se nepodporuje. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Obor názvů nemůže přímo obsahovat členy, jako jsou pole a metody. + A namespace cannot directly contain members such as fields, methods or statements + Obor názvů nemůže přímo obsahovat členy, jako jsou pole a metody. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 87df0b3c48442..9ae626ff9b5fc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -652,6 +652,11 @@ Nur eine partielle Deklaration eines einzelnen Datensatzes darf eine Parameterliste aufweisen. + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Die new()-Einschränkung kann nicht mit der unmanaged-Einschränkung verwendet werden. @@ -892,6 +897,16 @@ Ein aus einem Element bestehendes deconstruct-Muster erfordert zur Vermeidung einer Mehrdeutigkeit eine etwas andere Syntax. Es wird empfohlen, nach der schließenden Klammer ")" einen discard-Kennzeichner "_" hinzuzufügen. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Der Datensatzmember "{0}" darf nicht statisch sein. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. Die Assembly "{0}" mit dem Typ "{1}" verweist auf das .NET Framework. Dies wird nicht unterstützt. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Member, wie z. B. Felder oder Methoden, können nicht direkt in einem Namespace enthalten sein. + A namespace cannot directly contain members such as fields, methods or statements + Member, wie z. B. Felder oder Methoden, können nicht direkt in einem Namespace enthalten sein. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 152290f4c9c0e..ae4fa94fc4f03 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -652,6 +652,11 @@ Solo una declaración parcial de un registro puede tener una lista de parámetros + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint La restricción "new()" no se puede utilizar con la restricción "unmanaged" @@ -892,6 +897,16 @@ Un patrón de deconstrucción de un solo elemento requiere más sintaxis para la desambiguación. Se recomienda agregar un designador de descarte "_" después del paréntesis de cierre ")". + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. El miembro del registro "{0}" no puede ser estático. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. El ensamblado "{0}" que contiene el tipo "{1}" hace referencia a .NET Framework, lo cual no se admite. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Un espacio de nombres no puede contener directamente miembros como campos o métodos. + A namespace cannot directly contain members such as fields, methods or statements + Un espacio de nombres no puede contener directamente miembros como campos o métodos. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 4c722d4180d60..1b9bc6c7c2033 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -652,6 +652,11 @@ Seule une déclaration partielle d'un seul enregistrement peut avoir une liste de paramètres + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint La contrainte 'new()' ne peut pas être utilisée avec la contrainte 'unmanaged' @@ -892,6 +897,16 @@ Un modèle de déconstruction d'un seul élément nécessite une autre syntaxe pour la désambiguïsation. Il est recommandé d'ajouter un désignateur d'abandon '_' après la parenthèse de fermeture ')'. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Le membre d'enregistrement '{0}' ne peut pas être static. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. L'assembly '{0}' contenant le type '{1}' référence le .NET Framework, ce qui n'est pas pris en charge. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Un espace de noms ne peut pas contenir directement des membres tels que des champs ou des méthodes + A namespace cannot directly contain members such as fields, methods or statements + Un espace de noms ne peut pas contenir directement des membres tels que des champs ou des méthodes diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index c5fe96b48b4bd..919a31350de4c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -652,6 +652,11 @@ Solo una dichiarazione parziale di singolo record può includere un elenco di parametri + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Non è possibile usare il vincolo 'new()' con il vincolo 'unmanaged' @@ -892,6 +897,16 @@ Per risolvere le ambiguità, è necessario usare una sintassi diversa per il criterio di decostruzione di singoli elementi. È consigliabile aggiungere un indicatore di rimozione '_' dopo la parentesi di chiusura ')'. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Il membro di record '{0}' non può essere statico. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. L'assembly '{0}' che contiene il tipo '{1}' fa riferimento a .NET Framework, che non è supportato. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Uno spazio dei nomi non può contenere direttamente membri come campi o metodi + A namespace cannot directly contain members such as fields, methods or statements + Uno spazio dei nomi non può contenere direttamente membri come campi o metodi diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index ae625bf8f8479..5f06b89c68412 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -652,6 +652,11 @@ 1 つのレコードの部分宣言のみがパラメーター リストを持つことができます + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 制約は 'unmanaged' 制約と一緒には使用できません @@ -892,6 +897,16 @@ 単一要素の分解パターンには、あいまいさを排除するための他の構文が必要です。破棄指定子 '_' を閉じかっこ ')' の後に追加することをお勧めします。 + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. レコード メンバー '{0}' を static にすることはできません。 @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. 型 '{1}' を含むアセンブリ '{0}' が .NET Framework を参照しています。これはサポートされていません。 @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - 名前空間にフィールドやメソッドのようなメンバーを直接含めることはできません + A namespace cannot directly contain members such as fields, methods or statements + 名前空間にフィールドやメソッドのようなメンバーを直接含めることはできません diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 8f0f818383244..0a03bdfb8b850 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -652,6 +652,11 @@ 단일 레코드 partial 선언에만 매개 변수 목록을 사용할 수 있습니다. + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 제약 조건은 'unmanaged' 제약 조건과 함께 사용할 수 없습니다. @@ -892,6 +897,16 @@ 단일 요소 분해 패턴은 명확성을 위해 다른 구문이 필요합니다. 닫는 괄호 ')' 뒤에 무시 항목 지정자 '_'을 추가하는 것이 좋습니다. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. 레코드 멤버 '{0}'이(가) 정적이지 않을 수 있습니다. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. '{1}' 형식을 포함하는 '{0}' 어셈블리가 지원되지 않는 .NET Framework를 참조합니다. @@ -3546,8 +3566,8 @@ - A namespace cannot directly contain members such as fields or methods - 네임스페이스는 필드나 메서드와 같은 멤버를 직접 포함할 수 없습니다. + A namespace cannot directly contain members such as fields, methods or statements + 네임스페이스는 필드나 메서드와 같은 멤버를 직접 포함할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index c7e04062445c4..450da8e93f645 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -652,6 +652,11 @@ Tylko pojedyncza częściowa deklaracja rekordu może mieć listę parametrów + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Ograniczenie „new()” nie może być używane z ograniczeniem „unmanaged” @@ -892,6 +897,16 @@ Wzorzec dekonstrukcji z jednym elementem wymaga innej składni w celu ujednoznacznienia. Zaleca się dodanie desygnatora odrzucania „_” po nawiasie zamykającym „)”. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Składowa rekordu „{0}” nie może być statyczna. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. Zestaw „{0}” zawierający typ „{1}” odwołuje się do platformy .NET Framework, co nie jest obsługiwane. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Przestrzeń nazw nie może bezpośrednio zawierać składowych, takich jak pola lub metody + A namespace cannot directly contain members such as fields, methods or statements + Przestrzeń nazw nie może bezpośrednio zawierać składowych, takich jak pola lub metody diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index abf8209997982..534f42e5cc009 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -652,6 +652,11 @@ Apenas uma declaração parcial de registro único pode ter uma lista de parâmetros + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint A restrição 'new()' não pode ser usada com a restrição 'unmanaged' @@ -892,6 +897,16 @@ Um padrão de desconstrução de elemento único requer alguma outra sintaxe para desambiguação. É recomendado adicionar um designador de descarte '_' após o parêntese de fechamento ')'. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. O membro do registro '{0}' não pode ser estático. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. O assembly '{0}' contendo o tipo '{1}' referencia o .NET Framework, mas não há suporte para isso. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Um namespace não pode conter diretamente membros, como campos ou métodos + A namespace cannot directly contain members such as fields, methods or statements + Um namespace não pode conter diretamente membros, como campos ou métodos diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 0e780bbea42ee..d3d54110a1549 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -652,6 +652,11 @@ Только частичное объявление отдельной записи может иметь список параметров. + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint Ограничение "new()" невозможно использовать вместе с ограничением "unmanaged" @@ -892,6 +897,16 @@ Для шаблона деконструкции с одним элементом требуется другой синтаксис для устранения неоднозначности. Рекомендуется добавить указатель отмены "_" после закрывающей скобки ")". + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. Элемент записи "{0}" не может быть статическим. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. Сборка "{0}", содержащая тип "{1}", ссылается на платформу .NET Framework, которая не поддерживается. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Пространство имен не может напрямую включать в себя такие члены, как поля или методы. + A namespace cannot directly contain members such as fields, methods or statements + Пространство имен не может напрямую включать в себя такие члены, как поля или методы. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 9ab6883e83acc..d071fe8477966 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -652,6 +652,11 @@ Yalnızca tek kaydın kısmi bildiriminde parametre listesi olabilir + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint 'new()' kısıtlaması, 'unmanaged' kısıtlamasıyla kullanılamaz @@ -892,6 +897,16 @@ Tek öğeli bir ayrıştırma deseni, kesinleştirme için başka bir söz dizimi gerektirir. ')' kapanış parantezinden sonra '_' atma belirleyicisinin eklenmesi önerilir. + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. '{0}' kayıt üyesi statik olmayabilir. @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. '{1}' türünü içeren '{0}' bütünleştirilmiş kodu, desteklenmeyen .NET Framework'e başvuruyor. @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - Ad uzayı, alanlar veya yöntemler gibi üyeleri doğrudan içeremez + A namespace cannot directly contain members such as fields, methods or statements + Ad uzayı, alanlar veya yöntemler gibi üyeleri doğrudan içeremez diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index d6d00dde3bc9b..c6f7be8b1f6a6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -652,6 +652,11 @@ 只有一个记录分部声明可以具有参数列表 + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint "new()" 约束不能与 "unmanaged" 约束一起使用 @@ -892,6 +897,16 @@ 单元素解构模式需要一些其他语法来消除歧义。建议在关闭 paren ")" 之后添加放弃指示符 "_"。 + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. 记录成员“{0}”可能不是静态的。 @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. 包含类型“{1}”的程序集“{0}”引用了 .NET Framework,而此操作不受支持。 @@ -3552,8 +3572,8 @@ - A namespace cannot directly contain members such as fields or methods - 命名空间不能直接包含字段或方法之类的成员 + A namespace cannot directly contain members such as fields, methods or statements + 命名空间不能直接包含字段或方法之类的成员 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 8356fd02a7354..54b41ece52b83 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -652,6 +652,11 @@ 只有一筆記錄可以在部分宣告中包含參數清單 + + Source file can only contain one single-line namespace declaration. + Source file can only contain one single-line namespace declaration. + + The 'new()' constraint cannot be used with the 'unmanaged' constraint new()' 條件約束不能和 'unmanaged' 條件約束一起使用 @@ -892,6 +897,16 @@ 單一元素解構模式需要一些其他語法才能使其明確。建議在右括弧 ')' 後新增捨棄指示項 '_'。 + + Source file can not contain both single-line and normal namespace declarations. + Source file can not contain both single-line and normal namespace declarations. + + + + Single-line namespace must precede all other members in a file. + Single-line namespace must precede all other members in a file. + + Record member '{0}' may not be static. 記錄成員 '{0}' 不可以是靜態。 @@ -1042,6 +1057,11 @@ with on structs + + single-line namespace + single-line namespace + + The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported. 包含類型 '{1}' 的組件 '{0}' 參考了 .NET Framework,此情形不受支援。 @@ -3547,8 +3567,8 @@ - A namespace cannot directly contain members such as fields or methods - 命名空間不能直接包含如欄位或方法等成員 + A namespace cannot directly contain members such as fields, methods or statements + 命名空間不能直接包含如欄位或方法等成員 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/WinMdDelegateTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/WinMdDelegateTests.cs index 91944f42f246e..c9091eb7b8844 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/WinMdDelegateTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/WinMdDelegateTests.cs @@ -71,6 +71,52 @@ public void SimpleDelegateMembersTest() WellKnownMemberNames.DelegateEndInvokeName); } + [Fact(), WorkItem(1003193, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1003193")] + public void SimpleDelegateMembersTestSingleLineNamespace() + { + const string libSrc = +@"namespace Test; +public delegate void voidDelegate(); +"; + Func> getValidator = expectedMembers => m => + { + { + var actualMembers = + m.GlobalNamespace.GetMember("Test"). + GetMember("voidDelegate").GetMembers().ToArray(); + + AssertEx.SetEqual(actualMembers.Select(s => s.Name), expectedMembers); + }; + }; + + + VerifyType verify = (winmd, expected) => + { + var validator = getValidator(expected); + + // We should see the same members from both source and metadata + var verifier = CompileAndVerify( + libSrc, + sourceSymbolValidator: validator, + symbolValidator: validator, + options: winmd ? TestOptions.ReleaseWinMD : TestOptions.ReleaseDll, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); + verifier.VerifyDiagnostics(); + }; + + // Test winmd + verify(true, + WellKnownMemberNames.InstanceConstructorName, + WellKnownMemberNames.DelegateInvokeName); + + // Test normal + verify(false, + WellKnownMemberNames.InstanceConstructorName, + WellKnownMemberNames.DelegateInvokeName, + WellKnownMemberNames.DelegateBeginInvokeName, + WellKnownMemberNames.DelegateEndInvokeName); + } + [Fact] public void TestAllDelegates() { diff --git a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs index fe1000a62b48a..0418727fdc762 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs @@ -149,7 +149,7 @@ public static void Main() } } -namespace N.Goo; +namespace N.; "); EmitResult emitResult; @@ -161,22 +161,24 @@ namespace N.Goo; Assert.False(emitResult.Success); emitResult.Diagnostics.Verify( - // (13,16): error CS1514: { expected - // namespace N.Foo; - Diagnostic(ErrorCode.ERR_LbraceExpected, ";").WithLocation(13, 16), - // (13,17): error CS1513: } expected - // namespace N.Foo; - Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(13, 17), - // (4,16): error CS0246: The type or namespace name 'Blah' could not be found (are you missing a using directive or an assembly reference?) - // public Blah field; - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Blah").WithArguments("Blah").WithLocation(4, 16), - // (8,13): error CS0198: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer) - // ro = 4; - Diagnostic(ErrorCode.ERR_AssgReadonlyStatic, "ro").WithLocation(8, 13), - // (4,21): warning CS0649: Field 'X.field' is never assigned to, and will always have its default value null - // public Blah field; - Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("N.X.field", "null").WithLocation(4, 21) - ); + // (13,1): error CS8652: The feature 'single-line namespace' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // namespace N.; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "namespace").WithArguments("single-line namespace").WithLocation(13, 1), + // (13,13): error CS1001: Identifier expected + // namespace N.; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(13, 13), + // (13,11): error CS8909: Single-line namespace must precede all other members in a file. + // namespace N.; + Diagnostic(ErrorCode.ERR_SingleLineNamespaceNotBeforeAllMembers, "N.").WithLocation(13, 11), + // (4,16): error CS0246: The type or namespace name 'Blah' could not be found (are you missing a using directive or an assembly reference?) + // public Blah field; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Blah").WithArguments("Blah").WithLocation(4, 16), + // (8,13): error CS0198: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer) + // ro = 4; + Diagnostic(ErrorCode.ERR_AssgReadonlyStatic, "ro").WithLocation(8, 13), + // (4,21): warning CS0649: Field 'X.field' is never assigned to, and will always have its default value null + // public Blah field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("N.X.field", "null").WithLocation(4, 21)); } // Check that EmitMetadataOnly works diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs index 7ddb76fe3375a..b21a960f39f2f 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs @@ -401,6 +401,25 @@ public void NamespaceWithoutName() Assert.Equal(string.Empty, symbol.Name); } + [WorkItem(539740, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539740")] + [Fact] + public void SingleLineNamespaceWithoutName() + { + var text = "namespace;"; + var tree = Parse(text); + var comp = CreateCompilation(tree); + var model = comp.GetSemanticModel(tree); + var errors = comp.GetDiagnostics().ToArray(); + Assert.Equal(2, errors.Length); + + var nsArray = tree.GetCompilationUnitRoot().DescendantNodes().Where(node => node.IsKind(SyntaxKind.SingleLineNamespaceDeclaration)).ToArray(); + Assert.Equal(1, nsArray.Length); + + var nsSyntax = nsArray[0] as SingleLineNamespaceDeclarationSyntax; + var symbol = model.GetDeclaredSymbol(nsSyntax); + Assert.Equal(string.Empty, symbol.Name); + } + [Fact] public void LazyBoundUsings1() { diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs index cc831c33af8c5..d1f10510e6b4a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs @@ -83,6 +83,21 @@ namespace A.B Assert.Equal("B", symbol.Name); } + [Fact] + public void TestGetDeclaredSymbolFromSingleLineNamespace() + { + var compilation = CreateCompilation(@" +namespace A.B; +"); + var tree = compilation.SyntaxTrees[0]; + var root = tree.GetCompilationUnitRoot(); + var decl = (BaseNamespaceDeclarationSyntax)root.Members[0]; + var model = compilation.GetSemanticModel(tree); + var symbol = model.GetDeclaredSymbol(decl); + Assert.NotNull(symbol); + Assert.Equal("B", symbol.Name); + } + [Fact] public void NamespaceAndClassWithNoNames() { @@ -129,6 +144,23 @@ namespace C.D Assert.Equal("D", symbol.Name); } + [Fact] + public void TestGetDeclaredSymbolFromNestedSingleLineNamespace() + { + var compilation = CreateCompilation(@" +namespace A.B; +namespace C.D; +"); + var tree = compilation.SyntaxTrees[0]; + var root = tree.GetCompilationUnitRoot(); + var abns = (SingleLineNamespaceDeclarationSyntax)root.Members[0]; + var cdns = (SingleLineNamespaceDeclarationSyntax)abns.Members[0]; + var model = compilation.GetSemanticModel(tree); + var symbol = model.GetDeclaredSymbol(cdns); + Assert.NotNull(symbol); + Assert.Equal("D", symbol.Name); + } + [Fact] public void IncompleteNamespaceDeclaration() { @@ -218,6 +250,27 @@ class Y { } Assert.Equal("C.B.Y", symbol.ToTestDisplayString()); } + [Fact] + public void GenericNameInSingleLineNamespaceName() + { + var compilation = CreateCompilation(@" +namespace C.B; +class Y { } +"); + + var tree = compilation.SyntaxTrees[0]; + var root = tree.GetCompilationUnitRoot(); + var classY = ((root. + Members[0] as SingleLineNamespaceDeclarationSyntax). + Members[0] as TypeDeclarationSyntax); + + var model = compilation.GetSemanticModel(tree); + + var symbol = model.GetDeclaredSymbol(classY); + Assert.NotNull(symbol); + Assert.Equal("C.B.Y", symbol.ToTestDisplayString()); + } + [Fact] public void AliasedNameInNamespaceName() { @@ -241,6 +294,27 @@ class Y { } Assert.Equal("C.B.Y", symbol.ToTestDisplayString()); } + [Fact] + public void AliasedNameInSingleLineNamespaceName() + { + var compilation = CreateCompilation(@" +namespace alias::C.B; +class Y { } +"); + + var tree = compilation.SyntaxTrees[0]; + var root = tree.GetCompilationUnitRoot(); + var classY = ((root. + Members[0] as SingleLineNamespaceDeclarationSyntax). + Members[0] as TypeDeclarationSyntax); + + var model = compilation.GetSemanticModel(tree); + + var symbol = model.GetDeclaredSymbol(classY); + Assert.NotNull(symbol); + Assert.Equal("C.B.Y", symbol.ToTestDisplayString()); + } + [Fact] public void TestGetDeclaredSymbolFromType() { @@ -1034,6 +1108,26 @@ public class B : C // should validate type here } + [WorkItem(537230, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537230")] + [Fact] + public void TestLookupUnresolvableNamespaceUsingInSingleLineNamespace() + { + var compilation = CreateCompilation(@" + namespace A; + using B.C; + + public class B : C + { + } + "); + var tree = compilation.SyntaxTrees.Single(); + var usingDirective = (UsingDirectiveSyntax)tree.FindNodeOrTokenByKind(SyntaxKind.UsingDirective).AsNode(); + var model = compilation.GetSemanticModel(tree); + var type = model.GetTypeInfo(usingDirective.Name); + Assert.NotEmpty(compilation.GetDeclarationDiagnostics()); + // should validate type here + } + [Fact] public void TestLookupSourceSymbolHidesMetadataSymbol() { @@ -1057,6 +1151,28 @@ public class DateTime Assert.Equal(1, symbols.Length); } + [Fact] + public void TestLookupSourceSymbolHidesMetadataSymbolSingleLineNamespace() + { + var compilation = CreateCompilation(@" +namespace System; +public class DateTime +{ + string TheDateAndTime; +} +"); + + var tree = compilation.SyntaxTrees.Single(); + + var namespaceDecl = (SingleLineNamespaceDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0]; + var classDecl = (ClassDeclarationSyntax)namespaceDecl.Members[0]; + var memberDecl = (FieldDeclarationSyntax)classDecl.Members[0]; + + var model = compilation.GetSemanticModel(tree); + var symbols = model.LookupSymbols(memberDecl.SpanStart, null, "DateTime"); + Assert.Equal(1, symbols.Length); + } + [Fact] public void TestLookupAllArities() { @@ -3022,6 +3138,29 @@ protected class A { } Assert.Equal(srcSym, declSym); } + [WorkItem(537953, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537953")] + [Fact] + public void GetDeclaredSymbolNoTypeSymbolWithErrSingleLineNamespace() + { + var compilation = (Compilation)CreateCompilation(@" +namespace NS; + +protected class A { } +"); + var tree = compilation.SyntaxTrees.First(); + var root = tree.GetCompilationUnitRoot(); + var model = compilation.GetSemanticModel(tree); + + var globalNS = compilation.SourceModule.GlobalNamespace; + var ns1 = globalNS.GetMembers("NS").Single() as INamespaceSymbol; + var srcSym = ns1.GetMembers("A").Single() as INamedTypeSymbol; + + var nsSyntax = (root.Members[0] as SingleLineNamespaceDeclarationSyntax); + var declSym = model.GetDeclaredSymbol(nsSyntax.Members[0] as TypeDeclarationSyntax); + + Assert.Equal(srcSym, declSym); + } + [WorkItem(537954, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537954")] [Fact] public void GetDeclaredSymbolExtraForDupTypesErr() diff --git a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/IncludeTests.cs b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/IncludeTests.cs index 6a16e41bc8b41..f2bfd4ed38ec6 100644 --- a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/IncludeTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/IncludeTests.cs @@ -74,6 +74,68 @@ class NamedType { } $@" +", symbol.GetDocumentationCommentXml(expandIncludes: false)); + } + + [Theory] + [InlineData("Field", "F:Acme.Widget.Field")] + [InlineData(WellKnownMemberNames.StaticConstructorName, "M:Acme.Widget.#cctor")] + [InlineData("Event", "E:Acme.Widget.Event")] + [InlineData("Property", "P:Acme.Widget.Property")] + [InlineData("Method", "M:Acme.Widget.Method")] + [InlineData("NamedType", "T:Acme.Widget.NamedType")] + public void TestDocumentationCachingSingleLineNamespace(string symbolName, string documentationId) + { + using var _ = new EnsureEnglishUICulture(); + + var compilation = CreateCompilationWithMscorlib40AndDocumentationComments(@"namespace Acme; + +class Widget +{ + /// + int Field; + + /// + static Widget() { } + + /// + event EventHandler Event; + + /// + int Property { get; } + + /// + void Method() { } + + /// + class NamedType { } +} +"); + + var acmeNamespace = (NamespaceSymbol)compilation.GlobalNamespace.GetMembers("Acme").Single(); + var widgetClass = acmeNamespace.GetTypeMembers("Widget").Single(); + + var symbol = widgetClass.GetMembers(symbolName).Single(); + Assert.Equal(documentationId, symbol.GetDocumentationCommentId()); + Assert.Equal( +$@" + + +", symbol.GetDocumentationCommentXml(expandIncludes: true)); + Assert.Equal( +$@" + + +", symbol.GetDocumentationCommentXml(expandIncludes: false)); + Assert.Equal( +$@" + + +", symbol.GetDocumentationCommentXml(expandIncludes: true)); + Assert.Equal( +$@" + + ", symbol.GetDocumentationCommentXml(expandIncludes: false)); } } diff --git a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs index 2fb52eb889c1c..4dd542733b3ef 100644 --- a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs @@ -2523,6 +2523,33 @@ class C1 { } SymbolDisplayPartKind.ClassName); } + [Fact] + public void TestAlias3SingleLineNamespace() + { + var text = @" +using Goo = N1.C1; + +namespace N1; +class Goo { } +class C1 { } +"; + + Func findSymbol = global => + global.GetNestedNamespace("N1"). + GetTypeMembers("C1").Single(); + + var format = SymbolDisplayFormat.MinimallyQualifiedFormat; + + TestSymbolDescription( + text, + findSymbol, + format, + "C1", + text.IndexOf("class Goo", StringComparison.Ordinal), + true, + SymbolDisplayPartKind.ClassName); + } + [Fact] public void TestMinimalNamespace1() { @@ -4468,6 +4495,99 @@ class C SymbolDisplayPartKind.EventName); } + [WorkItem(791756, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/791756")] + [Fact] + public void KindOptionsSingleLineNamespace() + { + var source = @" +namespace N; +class C +{ + event System.Action E; +} +"; + var memberFormat = new SymbolDisplayFormat( + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, + memberOptions: SymbolDisplayMemberOptions.IncludeContainingType, + kindOptions: SymbolDisplayKindOptions.IncludeMemberKeyword); + var typeFormat = new SymbolDisplayFormat( + memberOptions: SymbolDisplayMemberOptions.IncludeContainingType, + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, + kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword); + var namespaceFormat = new SymbolDisplayFormat( + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, + memberOptions: SymbolDisplayMemberOptions.IncludeContainingType, + kindOptions: SymbolDisplayKindOptions.IncludeNamespaceKeyword); + + var comp = CreateCompilation(source); + var namespaceSymbol = comp.GlobalNamespace.GetMember("N"); + var typeSymbol = namespaceSymbol.GetMember("C"); + var eventSymbol = typeSymbol.GetMember("E"); + + Verify( + namespaceSymbol.ToDisplayParts(memberFormat), + "N", + SymbolDisplayPartKind.NamespaceName); + Verify( + namespaceSymbol.ToDisplayParts(typeFormat), + "N", + SymbolDisplayPartKind.NamespaceName); + Verify( + namespaceSymbol.ToDisplayParts(namespaceFormat), + "namespace N", + SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.NamespaceName); + + Verify( + typeSymbol.ToDisplayParts(memberFormat), + "N.C", + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName); + Verify( + typeSymbol.ToDisplayParts(typeFormat), + "class N.C", + SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName); + Verify( + typeSymbol.ToDisplayParts(namespaceFormat), + "N.C", + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName); + + Verify( + eventSymbol.ToDisplayParts(memberFormat), + "event N.C.E", + SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.EventName); + Verify( + eventSymbol.ToDisplayParts(typeFormat), + "N.C.E", + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.EventName); + Verify( + eventSymbol.ToDisplayParts(namespaceFormat), + "N.C.E", + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.ClassName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.EventName); + } + [WorkItem(765287, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/765287")] [Fact] public void TestVbSymbols() @@ -6454,7 +6574,6 @@ enum E : long SymbolDisplayPartKind.NumericLiteral); } - [Fact] public void TestRefStructs() { @@ -7108,6 +7227,41 @@ readonly void M() { } SymbolDisplayPartKind.Punctuation); } + [Fact] + public void TestReadOnlyStruct_Nested_SingleLineNamespace() + { + var source = @" +namespace Nested; +struct X +{ + readonly void M() { } +} +"; + var format = SymbolDisplayFormat.TestFormat + .AddMemberOptions(SymbolDisplayMemberOptions.IncludeModifiers) + .AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + + var comp = CreateCompilation(source, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)).VerifyDiagnostics(); + var semanticModel = comp.GetSemanticModel(comp.SyntaxTrees.Single()); + + var declaration = (BaseTypeDeclarationSyntax)semanticModel.SyntaxTree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.StructDeclaration); + var members = semanticModel.GetDeclaredSymbol(declaration).GetMembers(); + + Verify(members[0].ToDisplayParts(format), + "readonly void Nested.X.M()", + SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.NamespaceName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.StructName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.MethodName, + SymbolDisplayPartKind.Punctuation, + SymbolDisplayPartKind.Punctuation); + } + [Fact] public void TestPassingVBSymbolsToStructSymbolDisplay() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/AssemblyAndNamespaceTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/AssemblyAndNamespaceTests.cs index 260082a4d5353..0081c65d7e67d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/AssemblyAndNamespaceTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/AssemblyAndNamespaceTests.cs @@ -83,6 +83,41 @@ class A {} Assert.Equal("Module: Test.dll", ext.ToString()); } + [Fact, WorkItem(1979, "DevDiv_Projects/Roslyn"), WorkItem(2026, "DevDiv_Projects/Roslyn"), WorkItem(544009, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544009")] + public void SourceModuleSingleLineNamespace() + { + var text = @"namespace NS.NS1.NS2; +class A {} +"; + var comp = CreateCompilation(text, assemblyName: "Test"); + + var sym = comp.SourceModule; + Assert.Equal("Test.dll", sym.Name); + // Bug: 2026 + Assert.Equal("Test.dll", sym.ToDisplayString()); + Assert.Equal(String.Empty, sym.GlobalNamespace.Name); + Assert.Equal(SymbolKind.NetModule, sym.Kind); + Assert.Equal(Accessibility.NotApplicable, sym.DeclaredAccessibility); + Assert.False(sym.IsStatic); + Assert.False(sym.IsVirtual); + Assert.False(sym.IsOverride); + Assert.False(sym.IsAbstract); + Assert.False(sym.IsSealed); + Assert.Equal("Test", sym.ContainingAssembly.Name); + Assert.Equal("Test", sym.ContainingSymbol.Name); + + var ns = comp.GlobalNamespace.GetMembers("NS").Single() as NamespaceSymbol; + var ns1 = (ns.GetMembers("NS1").Single() as NamespaceSymbol).GetMembers("NS2").Single() as NamespaceSymbol; + // NamespaceExtent + var ext = ns1.Extent; + Assert.Equal(NamespaceKind.Module, ext.Kind); + Assert.Equal(1, ns1.ConstituentNamespaces.Length); + Assert.Same(ns1, ns1.ConstituentNamespaces[0]); + + // Bug: 1979 + Assert.Equal("Module: Test.dll", ext.ToString()); + } + [Fact] public void SimpleNamespace() { @@ -228,6 +263,47 @@ struct SGoo {} } } + [Fact] + public void MultiModulesSingleLineNamespace() + { + var text1 = @"namespace N1; +class A {} +"; + var text2 = @"namespace N1; +interface IGoo {} +"; + var text3 = @"namespace N1; +struct SGoo {} +"; + var comp1 = CreateCompilation(text1, assemblyName: "Compilation1"); + var comp2 = CreateCompilation(text2, assemblyName: "Compilation2"); + + var compRef1 = new CSharpCompilationReference(comp1); + var compRef2 = new CSharpCompilationReference(comp2); + + var comp = CreateEmptyCompilation(new string[] { text3 }, references: new MetadataReference[] { compRef1, compRef2 }.ToList(), assemblyName: "Test3"); + //Compilation.Create(outputName: "Test3", options: CompilationOptions.Default, + // syntaxTrees: new SyntaxTree[] { SyntaxTree.ParseCompilationUnit(text3) }, + // references: new MetadataReference[] { compRef1, compRef2 }); + + var global = comp.GlobalNamespace; // throw + var ns = global.GetMembers("N1").Single() as NamespaceSymbol; + Assert.Equal(3, ns.GetTypeMembers().Length); // A, IGoo & SGoo + Assert.Equal(NamespaceKind.Compilation, ns.Extent.Kind); + + var constituents = ns.ConstituentNamespaces; + Assert.Equal(3, constituents.Length); + Assert.True(constituents.Contains(comp.SourceAssembly.GlobalNamespace.GetMembers("N1").Single() as NamespaceSymbol)); + Assert.True(constituents.Contains(comp.GetReferencedAssemblySymbol(compRef1).GlobalNamespace.GetMembers("N1").Single() as NamespaceSymbol)); + Assert.True(constituents.Contains(comp.GetReferencedAssemblySymbol(compRef2).GlobalNamespace.GetMembers("N1").Single() as NamespaceSymbol)); + + foreach (var constituentNs in constituents) + { + Assert.Equal(NamespaceKind.Module, constituentNs.Extent.Kind); + Assert.Equal(ns.ToTestDisplayString(), constituentNs.ToTestDisplayString()); + } + } + [WorkItem(537287, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537287")] [Fact] public void MultiModulesNamespaceCorLibraries() @@ -306,6 +382,40 @@ int b(string s){} Assert.Equal(5, b.Length); } + /// Container with nested types and non-type members with the same name + [Fact] + public void ClassWithNestedTypesAndMembersWithSameNameSingleLineNamespace() + { + var text1 = @"namespace N1; +class A +{ + class b + { + } + + class b + { + } + + int b; + + int b() {} + + int b(string s){} +} +"; + + var comp = CSharpCompilation.Create( + assemblyName: "Test1", + syntaxTrees: new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(text1) }, + references: new MetadataReference[] { }); + var global = comp.GlobalNamespace; // throw + var ns = global.GetMembers("N1").Single() as NamespaceSymbol; + Assert.Equal(1, ns.GetTypeMembers().Length); // A + var b = ns.GetTypeMembers("A")[0].GetMembers("b"); + Assert.Equal(5, b.Length); + } + [WorkItem(537958, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537958")] [Fact] public void GetDeclaredSymbolDupNsAliasErr() @@ -364,6 +474,31 @@ static void Main() Assert.NotNull(method); } + [WorkItem(540785, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540785")] + [Fact] + public void GenericNamespaceSingleLineNamespace() + { + var compilation = CreateEmptyCompilation(@" +namespace Goo; +class Program +{ + static void Main() + { + } +} +"); + var global = compilation.GlobalNamespace; + + var @namespace = global.GetMember("Goo"); + Assert.NotNull(@namespace); + + var @class = @namespace.GetMember("Program"); + Assert.NotNull(@class); + + var method = @class.GetMember("Main"); + Assert.NotNull(method); + } + [WorkItem(690871, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/690871")] [Fact] public void SpecialTypesAndAliases() @@ -460,6 +595,25 @@ public static int Main() Diagnostic(ErrorCode.ERR_BadModifiersOnNamespace, "public").WithLocation(2, 1)); } + [WorkItem(863435, "DevDiv/Personal")] + [Fact] + public void CS1671ERR_BadModifiersOnNamespace01SingleLineNamespace() + { + var test = @" +public namespace NS; // CS1671 +class Test +{ + public static int Main() + { + return 1; + } +} +"; + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (2,1): error CS1671: A namespace declaration cannot have modifiers or attributes + Diagnostic(ErrorCode.ERR_BadModifiersOnNamespace, "public").WithLocation(2, 1)); + } + [Fact] public void CS1671ERR_BadModifiersOnNamespace02() { @@ -471,5 +625,166 @@ namespace N { } // (2,1): error CS1671: A namespace declaration cannot have modifiers or attributes Diagnostic(ErrorCode.ERR_BadModifiersOnNamespace, "[System.Obsolete]").WithLocation(1, 1)); } + + private static readonly CSharpParseOptions s_previewOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview); + + [Fact] + public void NamespaceWithSemicolon1() + { + var test = +@"namespace A;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics(); + } + + [Fact] + public void NamespaceWithSemicolon3() + { + var test = +@"namespace A.B;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics(); + } + + [Fact] + public void MultipleSingleLineNamespaces() + { + var test = +@"namespace A; +namespace B;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (2,11): error CS8907: Source file can only contain one single-line namespace declaration. + // namespace B; + Diagnostic(ErrorCode.ERR_MultipleSingleLineNamespace, "B").WithLocation(2, 11)); + } + + [Fact] + public void SingleLineNamespaceNestedInNormalNamespace() + { + var test = +@"namespace A +{ + namespace B; +}"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (3,15): error CS8908: Source file can not contain both single-line and normal namespace declarations. + // namespace B; + Diagnostic(ErrorCode.ERR_SingleLineAndNormalNamespace, "B").WithLocation(3, 15)); + } + + [Fact] + public void NormalAndSingleLineNamespace1() + { + var test = +@"namespace A; +namespace B +{ +}"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (2,11): error CS8908: Source file can only contain single-line and normal namespace declarations. + // namespace B + Diagnostic(ErrorCode.ERR_SingleLineAndNormalNamespace, "B").WithLocation(2, 11)); + } + + [Fact] + public void NormalAndSingleLineNamespace2() + { + var test = +@"namespace A +{ +} +namespace B;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (4,11): error CS8909: Single-line namespace must precede all other members in a file. + // namespace B; + Diagnostic(ErrorCode.ERR_SingleLineNamespaceNotBeforeAllMembers, "B").WithLocation(4, 11)); + } + + [Fact] + public void NamespaceWithPrecedingUsing() + { + var test = +@"using System; +namespace A;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using System; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System;").WithLocation(1, 1)); + } + + [Fact] + public void NamespaceWithFollowingUsing() + { + var test = +@"namespace X; +using System;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (2,1): hidden CS8019: Unnecessary using directive. + // using System; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System;").WithLocation(2, 1)); + } + + [Fact] + public void NamespaceWithPrecedingType() + { + var test = +@"class X { } +namespace System;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (2,11): error CS8909: Single-line namespace must precede all other members in a file. + // namespace System; + Diagnostic(ErrorCode.ERR_SingleLineNamespaceNotBeforeAllMembers, "System").WithLocation(2, 11)); + } + + [Fact] + public void NamespaceWithFollowingType() + { + var test = +@"namespace System; +class X { }"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics(); + } + + [Fact] + public void SingleLineNamespaceWithPrecedingStatement() + { + var test = +@" +System.Console.WriteLine(); +namespace B;"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (3,11): error CS8914: Single-line namespace must precede all other members in a file. + // namespace B; + Diagnostic(ErrorCode.ERR_SingleLineNamespaceNotBeforeAllMembers, "B").WithLocation(3, 11)); + } + + [Fact] + public void SingleLineNamespaceWithFollowingStatement() + { + var test = +@" +namespace B; +System.Console.WriteLine();"; + + CreateCompilationWithMscorlib45(test, parseOptions: s_previewOptions).VerifyDiagnostics( + // (3,16): error CS0116: A namespace cannot directly contain members such as fields or methods + // System.Console.WriteLine(); + Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "WriteLine").WithLocation(3, 16), + // (3,26): error CS8124: Tuple must contain at least two elements. + // System.Console.WriteLine(); + Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(3, 26), + // (3,27): error CS1022: Type or namespace definition, or end-of-file expected + // System.Console.WriteLine(); + Diagnostic(ErrorCode.ERR_EOFExpected, ";").WithLocation(3, 27)); + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs index e37e1eaad7c06..a2ad021b8546d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs @@ -1267,6 +1267,33 @@ private class D { } Assert.NotEqual(d, b.BaseType()); } + [Fact] + public void NestedNames1SingleLineNamespace() + { + var text = +@" +namespace N; +static class C +{ + class A + { + class B : A>.D { } + private class D { } + } +} +"; + var comp = CreateEmptyCompilation(text); + var global = comp.GlobalNamespace; + var n = global.GetMembers("N").OfType().Single(); + var c = n.GetTypeMembers("C", 0).Single(); + var a = c.GetTypeMembers("A", 1).Single(); + var b = a.GetTypeMembers("B", 1).Single(); + var d = a.GetTypeMembers("D", 0).Single(); + Assert.Equal(Accessibility.Private, d.DeclaredAccessibility); + Assert.Equal(d.OriginalDefinition, b.BaseType().OriginalDefinition); + Assert.NotEqual(d, b.BaseType()); + } + [Fact] public void Using1() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DeclaringSyntaxNodeTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DeclaringSyntaxNodeTests.cs index 1d996cb9da9d4..380ff124f0dd1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DeclaringSyntaxNodeTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DeclaringSyntaxNodeTests.cs @@ -211,6 +211,49 @@ enum E1 { Red } } } + [Fact] + public void SourceNamedTypeDeclaringSyntaxSingleLineNamespace() + { + var text = +@" +namespace N1; +class C1 { + class Nested {} + delegate int NestedDel(string s); +} +public struct S1 { + C1 f; +} +internal interface I1 {} +enum E1 { Red } +delegate void D1(int i); +"; + var comp = (Compilation)CreateCompilation(text); + var global = comp.GlobalNamespace; + var n1 = global.GetMembers("N1").Single() as INamespaceSymbol; + + Assert.False(n1.IsImplicitlyDeclared); + Assert.True(comp.SourceModule.GlobalNamespace.IsImplicitlyDeclared); + + var types = n1.GetTypeMembers(); + foreach (ISymbol s in types) + { + CheckDeclaringSyntaxNodes(comp, s, 1); + } + + var c1 = n1.GetTypeMembers("C1").Single() as INamedTypeSymbol; + var s1 = n1.GetTypeMembers("S1").Single() as INamedTypeSymbol; + var f = s1.GetMembers("f").Single() as IFieldSymbol; + + CheckDeclaringSyntaxNodes(comp, f.Type, 1); // constructed type C1. + + // Nested types. + foreach (ISymbol s in c1.GetTypeMembers()) + { + CheckDeclaringSyntaxNodes(comp, s, 1); + } + } + [Fact] public void NonSourceTypeDeclaringSyntax() { @@ -421,28 +464,27 @@ namespace System {} } [Fact] - public void TypeParameterDeclaringSyntax() + public void TypeParameterDeclaringSyntaxSingleLineNamespace() { var text = @" using System; using System.Collections.Generic; -namespace N1 { - class C1 { - class C2 { - public C1.C2 f1; - public void m(); - } - class C3 { - IEnumerable f2; - Goo f3; - } +namespace N1; +class C1 { + class C2 { + public C1.C2 f1; + public void m(); } - - class M { + class C3 { + IEnumerable f2; + Goo f3; } } + +class M { +} "; var comp = (Compilation)CreateCompilation(text); var global = comp.GlobalNamespace; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs index 056af7e3cf087..2fe8bc2dff5a6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/MethodTests.cs @@ -537,6 +537,91 @@ void IGoo.M(ref T t) {} // Assert.Equal(1, mem2.ExplicitInterfaceImplementation.Count()); } + [Fact] + public void InterfaceImplementsCrossTreesSingleLineNamespace() + { + var text1 = +@"using System; +using System.Collections.Generic; + +namespace NS; +public class Abc {} + +public interface IGoo +{ + void M(ref T t); +} + +public interface I1 +{ + void M(ref string p); + int M1(short p1, params object[] ary); +} + +public interface I2 : I1 +{ + void M21(); + Abc M22(ref Abc p); +} +"; + + var text2 = +@"using System; +using System.Collections.Generic; + +namespace NS.NS1; +public class Impl : I2, IGoo, I1 +{ + void IGoo.M(ref string p) { } + void I1.M(ref string p) { } + public int M1(short p1, params object[] ary) { return p1; } + public void M21() {} + public Abc M22(ref Abc p) { return p; } +} + +struct S: IGoo +{ + void IGoo.M(ref T t) {} +} +"; + + var comp = CreateCompilation(new[] { text1, text2 }); + Assert.Equal(0, comp.GetDeclarationDiagnostics().Count()); + var ns = comp.GlobalNamespace.GetMembers("NS").Single() as NamespaceSymbol; + var ns1 = ns.GetMembers("NS1").Single() as NamespaceSymbol; + + var classImpl = ns1.GetTypeMembers("Impl", 0).Single() as NamedTypeSymbol; + Assert.Equal(3, classImpl.Interfaces().Length); + // + var itfc = classImpl.Interfaces().First() as NamedTypeSymbol; + Assert.Equal(1, itfc.Interfaces().Length); + itfc = itfc.Interfaces().First() as NamedTypeSymbol; + Assert.Equal("I1", itfc.Name); + + // explicit interface member names include the explicit interface + var mems = classImpl.GetMembers("M"); + Assert.Equal(0, mems.Length); + //var mem1 = mems.First() as MethodSymbol; + // not impl + // Assert.Equal(MethodKind.ExplicitInterfaceImplementation, mem1.MethodKind); + // Assert.Equal(1, mem1.ExplicitInterfaceImplementation.Count()); + + var mem1 = classImpl.GetMembers("M22").Single() as MethodSymbol; + // not impl + // Assert.Equal(0, mem1.ExplicitInterfaceImplementation.Count()); + var param = mem1.Parameters.First() as ParameterSymbol; + Assert.Equal(RefKind.Ref, param.RefKind); + Assert.Equal("ref NS.Abc p", param.ToTestDisplayString()); + + var structImpl = ns1.GetTypeMembers("S").Single() as NamedTypeSymbol; + Assert.Equal(1, structImpl.Interfaces().Length); + itfc = structImpl.Interfaces().First() as NamedTypeSymbol; + Assert.Equal("NS.IGoo", itfc.ToTestDisplayString()); + //var mem2 = structImpl.GetMembers("M").Single() as MethodSymbol; + // not impl + // Assert.Equal(1, mem2.ExplicitInterfaceImplementation.Count()); + } + [Fact] public void AbstractVirtualMethodsCrossTrees() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs index cdb2cfbd0aaeb..82e358d763d30 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs @@ -369,5 +369,48 @@ public object Method1() Assert.Equal(0, symbolInfo.CandidateSymbols.Length); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); } + + [ClrOnlyFact, WorkItem(2805, "https://github.com/dotnet/roslyn/issues/2805")] + public void AliasWithAnErrorSingleLineNamespace() + { + var text = +@" +namespace NS; +using Short = LongNamespace; +class Test +{ + public object Method1() + { + return (new Short.MyClass()).Prop; + } +} +"; + + var compilation = CreateCompilation(text, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); + + compilation.VerifyDiagnostics( + // (3,15): error CS0246: The type or namespace name 'LongNamespace' could not be found (are you missing a using directive or an assembly reference?) + // using Short = LongNamespace; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "LongNamespace").WithArguments("LongNamespace").WithLocation(3, 15)); + + var tree = compilation.SyntaxTrees.Single(); + + var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "Short").Skip(1).Single(); + + Assert.Equal("Short.MyClass", node.Parent.ToString()); + + var model = compilation.GetSemanticModel(tree); + + var alias = model.GetAliasInfo(node); + Assert.Equal("Short=LongNamespace", alias.ToTestDisplayString()); + Assert.Equal(SymbolKind.ErrorType, alias.Target.Kind); + Assert.Equal("LongNamespace", alias.Target.ToTestDisplayString()); + + var symbolInfo = model.GetSymbolInfo(node); + + Assert.Null(symbolInfo.Symbol); + Assert.Equal(0, symbolInfo.CandidateSymbols.Length); + Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/TypeTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/TypeTests.cs index 75418afed0f12..de9d3d47974c2 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/TypeTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/TypeTests.cs @@ -157,6 +157,68 @@ orderby i.Name Assert.Equal(3, type33.AllInterfaces().Length); } + [Fact] + public void InheritedTypesCrossTrees_SingleLineNamespace() + { + var text = @"namespace MT; +public interface IGoo { void Goo(); } +public interface IGoo { R Goo(T t); } +"; + var text1 = @"namespace MT; +public interface IBar : IGoo { void Bar(T t); } +"; + var text2 = @"namespace NS; +using System; +using MT; +public class A : IGoo, IBar { + void IGoo.Goo() { } + void IBar.Bar(string s) { } + public string Goo(T t) { return null; } +} + +public class B : A {} +"; + var text3 = @"namespace NS; +public class C : B {} +"; + + var comp = CreateCompilation(new[] { text, text1, text2, text3 }); + var global = comp.GlobalNamespace; + var ns = global.GetMembers("NS").Single() as NamespaceSymbol; + + var type1 = ns.GetTypeMembers("C", 0).SingleOrDefault() as NamedTypeSymbol; + Assert.Equal(0, type1.Interfaces().Length); + Assert.Equal(3, type1.AllInterfaces().Length); + var sorted = (from i in type1.AllInterfaces() + orderby i.Name + select i).ToArray(); + var i1 = sorted[0] as NamedTypeSymbol; + var i2 = sorted[1] as NamedTypeSymbol; + var i3 = sorted[2] as NamedTypeSymbol; + Assert.Equal("MT.IBar", i1.ToTestDisplayString()); + Assert.Equal(1, i1.Arity); + Assert.Equal("MT.IGoo", i2.ToTestDisplayString()); + Assert.Equal(2, i2.Arity); + Assert.Equal("MT.IGoo", i3.ToTestDisplayString()); + Assert.Equal(0, i3.Arity); + + Assert.Equal("B", type1.BaseType().Name); + // B + var type2 = type1.BaseType() as NamedTypeSymbol; + Assert.Equal(3, type2.AllInterfaces().Length); + Assert.NotNull(type2.BaseType()); + // A + var type3 = type2.BaseType() as NamedTypeSymbol; + Assert.Equal("NS.A", type3.ToTestDisplayString()); + Assert.Equal(2, type3.Interfaces().Length); + Assert.Equal(3, type3.AllInterfaces().Length); + + var type33 = ns.GetTypeMembers("A", 1).SingleOrDefault() as NamedTypeSymbol; + Assert.Equal("NS.A", type33.ToTestDisplayString()); + Assert.Equal(2, type33.Interfaces().Length); + Assert.Equal(3, type33.AllInterfaces().Length); + } + [WorkItem(537752, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537752")] [Fact] public void InheritedTypesCrossComps() diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs index 6180e30fec559..e36f3d955f7ff 100644 --- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs +++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs @@ -448,6 +448,9 @@ private static Syntax.InternalSyntax.UsingDirectiveSyntax GenerateUsingDirective private static Syntax.InternalSyntax.NamespaceDeclarationSyntax GenerateNamespaceDeclaration() => InternalSyntaxFactory.NamespaceDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.NamespaceKeyword), GenerateIdentifierName(), InternalSyntaxFactory.Token(SyntaxKind.OpenBraceToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseBraceToken), null); + private static Syntax.InternalSyntax.SingleLineNamespaceDeclarationSyntax GenerateSingleLineNamespaceDeclaration() + => InternalSyntaxFactory.SingleLineNamespaceDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.NamespaceKeyword), GenerateIdentifierName(), InternalSyntaxFactory.Token(SyntaxKind.SemicolonToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList()); + private static Syntax.InternalSyntax.AttributeListSyntax GenerateAttributeList() => InternalSyntaxFactory.AttributeList(InternalSyntaxFactory.Token(SyntaxKind.OpenBracketToken), null, new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseBracketToken)); @@ -2516,6 +2519,23 @@ public void TestNamespaceDeclarationFactoryAndProperties() AttachAndCheckDiagnostics(node); } + [Fact] + public void TestSingleLineNamespaceDeclarationFactoryAndProperties() + { + var node = GenerateSingleLineNamespaceDeclaration(); + + Assert.Equal(default, node.AttributeLists); + Assert.Equal(default, node.Modifiers); + Assert.Equal(SyntaxKind.NamespaceKeyword, node.NamespaceKeyword.Kind); + Assert.NotNull(node.Name); + Assert.Equal(SyntaxKind.SemicolonToken, node.SemicolonToken.Kind); + Assert.Equal(default, node.Externs); + Assert.Equal(default, node.Usings); + Assert.Equal(default, node.Members); + + AttachAndCheckDiagnostics(node); + } + [Fact] public void TestAttributeListFactoryAndProperties() { @@ -7462,6 +7482,32 @@ public void TestNamespaceDeclarationIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestSingleLineNamespaceDeclarationTokenDeleteRewriter() + { + var oldNode = GenerateSingleLineNamespaceDeclaration(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestSingleLineNamespaceDeclarationIdentityRewriter() + { + var oldNode = GenerateSingleLineNamespaceDeclaration(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestAttributeListTokenDeleteRewriter() { @@ -10115,6 +10161,9 @@ private static UsingDirectiveSyntax GenerateUsingDirective() private static NamespaceDeclarationSyntax GenerateNamespaceDeclaration() => SyntaxFactory.NamespaceDeclaration(new SyntaxList(), new SyntaxTokenList(), SyntaxFactory.Token(SyntaxKind.NamespaceKeyword), GenerateIdentifierName(), SyntaxFactory.Token(SyntaxKind.OpenBraceToken), new SyntaxList(), new SyntaxList(), new SyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseBraceToken), default(SyntaxToken)); + private static SingleLineNamespaceDeclarationSyntax GenerateSingleLineNamespaceDeclaration() + => SyntaxFactory.SingleLineNamespaceDeclaration(new SyntaxList(), new SyntaxTokenList(), SyntaxFactory.Token(SyntaxKind.NamespaceKeyword), GenerateIdentifierName(), SyntaxFactory.Token(SyntaxKind.SemicolonToken), new SyntaxList(), new SyntaxList(), new SyntaxList()); + private static AttributeListSyntax GenerateAttributeList() => SyntaxFactory.AttributeList(SyntaxFactory.Token(SyntaxKind.OpenBracketToken), default(AttributeTargetSpecifierSyntax), new SeparatedSyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseBracketToken)); @@ -12183,6 +12232,23 @@ public void TestNamespaceDeclarationFactoryAndProperties() Assert.Equal(node, newNode); } + [Fact] + public void TestSingleLineNamespaceDeclarationFactoryAndProperties() + { + var node = GenerateSingleLineNamespaceDeclaration(); + + Assert.Equal(default, node.AttributeLists); + Assert.Equal(default, node.Modifiers); + Assert.Equal(SyntaxKind.NamespaceKeyword, node.NamespaceKeyword.Kind()); + Assert.NotNull(node.Name); + Assert.Equal(SyntaxKind.SemicolonToken, node.SemicolonToken.Kind()); + Assert.Equal(default, node.Externs); + Assert.Equal(default, node.Usings); + Assert.Equal(default, node.Members); + var newNode = node.WithAttributeLists(node.AttributeLists).WithModifiers(node.Modifiers).WithNamespaceKeyword(node.NamespaceKeyword).WithName(node.Name).WithSemicolonToken(node.SemicolonToken).WithExterns(node.Externs).WithUsings(node.Usings).WithMembers(node.Members); + Assert.Equal(node, newNode); + } + [Fact] public void TestAttributeListFactoryAndProperties() { @@ -17129,6 +17195,32 @@ public void TestNamespaceDeclarationIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestSingleLineNamespaceDeclarationTokenDeleteRewriter() + { + var oldNode = GenerateSingleLineNamespaceDeclaration(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestSingleLineNamespaceDeclarationIdentityRewriter() + { + var oldNode = GenerateSingleLineNamespaceDeclaration(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestAttributeListTokenDeleteRewriter() { diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs index a43d90daffd80..6f107ef7413b8 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs @@ -578,6 +578,27 @@ public void TestNamespace() Assert.NotEqual(default, ns.CloseBraceToken); } + [Fact] + public void TestSingleLineNamespace() + { + var text = "namespace a;"; + var file = this.ParseFile(text, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); + + Assert.NotNull(file); + Assert.Equal(1, file.Members.Count); + Assert.Equal(text, file.ToString()); + Assert.Equal(0, file.Errors().Length); + + Assert.Equal(SyntaxKind.SingleLineNamespaceDeclaration, file.Members[0].Kind()); + var ns = (SingleLineNamespaceDeclarationSyntax)file.Members[0]; + Assert.NotEqual(default, ns.NamespaceKeyword); + Assert.NotNull(ns.Name); + Assert.Equal("a", ns.Name.ToString()); + Assert.NotEqual(default, ns.SemicolonToken); + Assert.Equal(0, ns.Usings.Count); + Assert.Equal(0, ns.Members.Count); + } + [Fact] public void TestNamespaceWithDottedName() { @@ -623,6 +644,28 @@ public void TestNamespaceWithUsing() Assert.NotEqual(default, ns.CloseBraceToken); } + [Fact] + public void TestSingleLineNamespaceWithUsing() + { + var text = "namespace a; using b.c;"; + var file = this.ParseFile(text, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); + + Assert.NotNull(file); + Assert.Equal(1, file.Members.Count); + Assert.Equal(text, file.ToString()); + Assert.Equal(0, file.Errors().Length); + + Assert.Equal(SyntaxKind.SingleLineNamespaceDeclaration, file.Members[0].Kind()); + var ns = (SingleLineNamespaceDeclarationSyntax)file.Members[0]; + Assert.NotEqual(default, ns.NamespaceKeyword); + Assert.NotNull(ns.Name); + Assert.Equal("a", ns.Name.ToString()); + Assert.NotEqual(default, ns.SemicolonToken); + Assert.Equal(1, ns.Usings.Count); + Assert.Equal("using b.c;", ns.Usings[0].ToString()); + Assert.Equal(0, ns.Members.Count); + } + [Fact] public void TestNamespaceWithExternAlias() { @@ -646,6 +689,28 @@ public void TestNamespaceWithExternAlias() Assert.NotEqual(default, ns.CloseBraceToken); } + [Fact] + public void TestSingleLineNamespaceWithExternAlias() + { + var text = "namespace a; extern alias b;"; + var file = this.ParseFile(text, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); + + Assert.NotNull(file); + Assert.Equal(1, file.Members.Count); + Assert.Equal(text, file.ToString()); + Assert.Equal(0, file.Errors().Length); + + Assert.Equal(SyntaxKind.SingleLineNamespaceDeclaration, file.Members[0].Kind()); + var ns = (SingleLineNamespaceDeclarationSyntax)file.Members[0]; + Assert.NotEqual(default, ns.NamespaceKeyword); + Assert.NotNull(ns.Name); + Assert.Equal("a", ns.Name.ToString()); + Assert.NotEqual(default, ns.SemicolonToken); + Assert.Equal(1, ns.Externs.Count); + Assert.Equal("extern alias b;", ns.Externs[0].ToString()); + Assert.Equal(0, ns.Members.Count); + } + [Fact] public void TestNamespaceWithExternAliasFollowingUsingBad() { diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index 6d651a3a88adc..04d23622f6f12 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -239,12 +239,12 @@ public static int Main() // (2,7): error CS1041: Identifier expected; 'namespace' is a keyword // using namespace System; Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "namespace").WithArguments("", "namespace").WithLocation(2, 7), - // (2,23): error CS1514: { expected - // using namespace System; - Diagnostic(ErrorCode.ERR_LbraceExpected, ";").WithLocation(2, 23), // (4,42): error CS0150: A constant value is expected // public enum e1 {one=1, two=2, three= }; - Diagnostic(ErrorCode.ERR_ConstantExpected, "}").WithLocation(4, 42)); + Diagnostic(ErrorCode.ERR_ConstantExpected, "}").WithLocation(4, 42), + // (10,1): error CS1022: Type or namespace definition, or end-of-file expected + // } + Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(10, 1)); } [WorkItem(862028, "DevDiv/Personal")] diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs index eeee72d89f53c..6862d05245d57 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParsingErrorRecoveryTests.cs @@ -6251,6 +6251,28 @@ public void TestNamespaceDeclarationInUsingDirective() Assert.False(((NamespaceDeclarationSyntax)namespaceDeclaration).Name.IsMissing); } + [Fact] + public void TestSingleLineNamespaceDeclarationInUsingDirective() + { + var text = @"using namespace Goo;"; + var file = this.ParseTree(text); + + Assert.Equal(text, file.ToFullString()); + Assert.Equal(2, file.Errors().Length); + Assert.Equal((int)ErrorCode.ERR_IdentifierExpectedKW, file.Errors()[0].Code); + + var usings = file.Usings; + Assert.Equal(1, usings.Count); + Assert.True(usings[0].Name.IsMissing); + + var members = file.Members; + Assert.Equal(1, members.Count); + + var namespaceDeclaration = members[0]; + Assert.Equal(SyntaxKind.SingleLineNamespaceDeclaration, namespaceDeclaration.Kind()); + Assert.False(((SingleLineNamespaceDeclarationSyntax)namespaceDeclaration).Name.IsMissing); + } + [Fact] public void TestContextualKeywordAsFromVariable() { @@ -7056,6 +7078,26 @@ class c Assert.False(ns.CloseBraceToken.IsMissing); } + + [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] + [Fact] + public void MissingOpenBraceForClassSingleLineNamespace() + { + var source = @"namespace n; + +class c +"; + var root = SyntaxFactory.ParseSyntaxTree(source).GetRoot(); + + Assert.Equal(source, root.ToFullString()); + // Verify incomplete class decls don't eat tokens of surrounding nodes + var classDecl = root.DescendantNodes().OfType().Single(); + Assert.False(classDecl.Identifier.IsMissing); + Assert.True(classDecl.OpenBraceToken.IsMissing); + Assert.True(classDecl.CloseBraceToken.IsMissing); + var ns = root.DescendantNodes().OfType().Single(); + } + [WorkItem(947819, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/947819")] [Fact] public void MissingOpenBraceForStruct() diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/SingleLineDeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/SingleLineDeclarationParsingTests.cs new file mode 100644 index 0000000000000..0c6c917115334 --- /dev/null +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/SingleLineDeclarationParsingTests.cs @@ -0,0 +1,818 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public class SingleLineDeclarationParsingTests : ParsingTests + { + public SingleLineDeclarationParsingTests(ITestOutputHelper output) : base(output) { } + + protected override SyntaxTree ParseTree(string text, CSharpParseOptions options) + { + return SyntaxFactory.ParseSyntaxTree(text, options); + } + + [Fact] + public void NamespaceWithNoNameSemicolonOrBraces() + { + UsingNode( +@"namespace", TestOptions.RegularPreview, + // (1,10): error CS1001: Identifier expected + // namespace + Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(1, 10), + // (1,10): error CS1514: { expected + // namespace + Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(1, 10), + // (1,10): error CS1513: } expected + // namespace + Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 10)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + M(SyntaxKind.OpenBraceToken); + M(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithNoSemicolonOrBraces1() + { + UsingNode( +@"namespace A", TestOptions.RegularPreview, + // (1,12): error CS1514: { expected + // namespace A + Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(1, 12), + // (1,12): error CS1513: } expected + // namespace A + Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 12)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + M(SyntaxKind.OpenBraceToken); + M(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithNoSemicolonOrBraces2() + { + UsingNode( +@"namespace A.", TestOptions.RegularPreview, + // (1,13): error CS1001: Identifier expected + // namespace A. + Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(1, 13), + // (1,13): error CS1514: { expected + // namespace A. + Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(1, 13), + // (1,13): error CS1513: } expected + // namespace A. + Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 13)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.QualifiedName); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.DotToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + M(SyntaxKind.OpenBraceToken); + M(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithNoSemicolonOrBraces3() + { + UsingNode( +@"namespace A.B", TestOptions.RegularPreview, + // (1,14): error CS1514: { expected + // namespace A.B + Diagnostic(ErrorCode.ERR_LbraceExpected, "").WithLocation(1, 14), + // (1,14): error CS1513: } expected + // namespace A.B + Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(1, 14)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.QualifiedName); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + } + M(SyntaxKind.OpenBraceToken); + M(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolon1() + { + UsingNode( +@"namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolon_CSharp9() + { + UsingNode( +@"namespace A;", TestOptions.Regular9, + // (1,1): error CS8652: The feature 'single-line namespace' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // namespace A; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "namespace").WithArguments("single-line namespace").WithLocation(1, 1)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolon2() + { + UsingNode( +@"namespace A.;", TestOptions.RegularPreview, + // (1,13): error CS1001: Identifier expected + // namespace A.; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(1, 13)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.QualifiedName); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.DotToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolon3() + { + UsingNode( +@"namespace A.B;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.QualifiedName); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolonAndOpenBrace() + { + UsingNode( +@"namespace A; {", TestOptions.RegularPreview, + // (1,14): error CS1022: Type or namespace definition, or end-of-file expected + // namespace A; { + Diagnostic(ErrorCode.ERR_EOFExpected, "{").WithLocation(1, 14)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolonAndBraces() + { + UsingNode( +@"namespace A; { }", TestOptions.RegularPreview, + // (1,14): error CS1022: Type or namespace definition, or end-of-file expected + // namespace A; { } + Diagnostic(ErrorCode.ERR_EOFExpected, "{").WithLocation(1, 14), + // (1,16): error CS1022: Type or namespace definition, or end-of-file expected + // namespace A; { } + Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(1, 16)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithSemicolonAndCloseBrace() + { + UsingNode( +@"namespace A; }", TestOptions.RegularPreview, + // (1,14): error CS1022: Type or namespace definition, or end-of-file expected + // namespace A; } + Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(1, 14)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void MultipleSingleLineNamespaces() + { + UsingNode( +@"namespace A; +namespace B;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void SingleLineNamespaceNestedInNormalNamespace() + { + UsingNode( +@"namespace A +{ + namespace B; +}", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NormalAndSingleLineNamespace1() + { + UsingNode( +@"namespace A; +namespace B +{ +}", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NormalAndSingleLineNamespace2() + { + UsingNode( +@"namespace A +{ +} +namespace B;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.NamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithPrecedingUsing() + { + UsingNode( +@"using X; +namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.UsingDirective); + { + N(SyntaxKind.UsingKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "X"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithFollowingUsing() + { + UsingNode( +@"namespace A; +using X;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.UsingDirective); + { + N(SyntaxKind.UsingKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "X"); + } + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithPrecedingType() + { + UsingNode( +@"class X { } +namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "X"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithFollowingType() + { + UsingNode( +@"namespace A; +class X { }", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "X"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithPrecedingExtern() + { + UsingNode( +@"extern alias X; +namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ExternAliasDirective); + { + N(SyntaxKind.ExternKeyword); + N(SyntaxKind.AliasKeyword); + N(SyntaxKind.IdentifierToken, "X"); + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithFollowingExtern() + { + UsingNode( +@"namespace A; +extern alias X;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + N(SyntaxKind.ExternAliasDirective); + { + N(SyntaxKind.ExternKeyword); + N(SyntaxKind.AliasKeyword); + N(SyntaxKind.IdentifierToken, "X"); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithExtraSemicolon() + { + UsingNode( +@"namespace A;;", TestOptions.RegularPreview, + // (1,13): error CS1022: Type or namespace definition, or end-of-file expected + // namespace A;; + Diagnostic(ErrorCode.ERR_EOFExpected, ";").WithLocation(1, 13)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithGenericName() + { + UsingNode( +@"namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.GenericName); + { + N(SyntaxKind.IdentifierToken, "A"); + N(SyntaxKind.TypeArgumentList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "X"); + } + N(SyntaxKind.GreaterThanToken); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithAlias() + { + UsingNode( +@"namespace A::B;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.AliasQualifiedName); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.ColonColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "B"); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithModifiers() + { + UsingNode( +@"public namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.PublicKeyword); + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void NamespaceWithAttributes() + { + UsingNode( +@"[X] namespace A;", TestOptions.RegularPreview); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.SingleLineNamespaceDeclaration); + { + N(SyntaxKind.AttributeList); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.Attribute); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "X"); + } + } + N(SyntaxKind.CloseBracketToken); + } + N(SyntaxKind.NamespaceKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + } +} diff --git a/src/Compilers/Test/Utilities/CSharp/Extensions.cs b/src/Compilers/Test/Utilities/CSharp/Extensions.cs index a1485cb2efc0f..ddf6c8d3a5648 100644 --- a/src/Compilers/Test/Utilities/CSharp/Extensions.cs +++ b/src/Compilers/Test/Utilities/CSharp/Extensions.cs @@ -611,7 +611,7 @@ declaration is ForEachStatementSyntax || declaration is JoinIntoClauseSyntax || declaration is LabeledStatementSyntax || declaration is MemberDeclarationSyntax || - declaration is NamespaceDeclarationSyntax || + declaration is BaseNamespaceDeclarationSyntax || declaration is ParameterSyntax || declaration is QueryClauseSyntax || declaration is QueryContinuationSyntax ||