Beispiel #1
0
        internal NamespaceSymbol GetNestedNamespace(NameSyntax name)
        {
            switch (name.Kind())
            {
            case SyntaxKind.GenericName:     // DeclarationTreeBuilder.VisitNamespace uses the PlainName, even for generic names
            case SyntaxKind.IdentifierName:
                return(this.GetNestedNamespace(((SimpleNameSyntax)name).Identifier.ValueText));

            case SyntaxKind.QualifiedName:
                var qn     = (QualifiedNameSyntax)name;
                var leftNs = this.GetNestedNamespace(qn.Left);
                if ((object)leftNs != null)
                {
                    return(leftNs.GetNestedNamespace(qn.Right));
                }
                break;

            case SyntaxKind.AliasQualifiedName:
                // This is an error scenario, but we should still handle it.
                // We recover in the same way as DeclarationTreeBuilder.VisitNamespaceDeclaration.
                return(this.GetNestedNamespace(name.GetUnqualifiedName().Identifier.ValueText));
            }

            return(null);
        }
        public override SingleNamespaceOrTypeDeclaration VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
        {
            var children = VisitNamespaceChildren(node, node.Members, node.Green.Members);

            bool                hasUsings   = node.Usings.Any();
            bool                hasExterns  = node.Externs.Any();
            NameSyntax          name        = node.Name;
            CSharpSyntaxNode    currentNode = node;
            QualifiedNameSyntax dotted;

            while ((dotted = name as QualifiedNameSyntax) != null)
            {
                var ns = SingleNamespaceDeclaration.Create(
                    name: dotted.Right.Identifier.ValueText,
                    hasUsings: hasUsings,
                    hasExternAliases: hasExterns,
                    syntaxReference: _syntaxTree.GetReference(currentNode),
                    nameLocation: new SourceLocation(dotted.Right),
                    children: children,
                    diagnostics: ImmutableArray <Diagnostic> .Empty);

                var nsDeclaration = new[] { ns };
                children    = nsDeclaration.AsImmutableOrNull <SingleNamespaceOrTypeDeclaration>();
                currentNode = name = dotted.Left;
                hasUsings   = false;
                hasExterns  = false;
            }

            var diagnostics = DiagnosticBag.GetInstance();

            if (ContainsGeneric(node.Name))
            {
                // We're not allowed to have generics.
                diagnostics.Add(ErrorCode.ERR_UnexpectedGenericName, node.Name.GetLocation());
            }

            if (ContainsAlias(node.Name))
            {
                diagnostics.Add(ErrorCode.ERR_UnexpectedAliasedName, node.Name.GetLocation());
            }

            // NOTE: *Something* has to happen for alias-qualified names.  It turns out that we
            // just grab the part after the colons (via GetUnqualifiedName, below).  This logic
            // must be kept in sync with NamespaceSymbol.GetNestedNamespace.
            return(SingleNamespaceDeclaration.Create(
                       name: name.GetUnqualifiedName().Identifier.ValueText,
                       hasUsings: hasUsings,
                       hasExternAliases: hasExterns,
                       syntaxReference: _syntaxTree.GetReference(currentNode),
                       nameLocation: new SourceLocation(name),
                       children: children,
                       diagnostics: diagnostics.ToReadOnlyAndFree()));
        }
Beispiel #3
0
        public override SingleNamespaceOrTypeDeclaration VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
        {
            var children = VisitNamespaceChildren(node, node.Members, node.Green.Members);

            if (syntaxTree.Options.Kind == SourceCodeKind.Interactive || syntaxTree.Options.Kind == SourceCodeKind.Script)
            {
                referenceDirectiveDiagnostics = referenceDirectiveDiagnostics ?? new List <Diagnostic>();

                referenceDirectiveDiagnostics.Add(new CSDiagnostic(
                                                      new DiagnosticInfo(MessageProvider.Instance, (int)ErrorCode.ERR_NamespaceNotAllowedInScript),
                                                      new SourceLocation(node.NamespaceKeyword)));
            }

            bool             hasUsings   = node.Usings.Any();
            bool             hasExterns  = node.Externs.Any();
            NameSyntax       name        = node.Name;
            CSharpSyntaxNode currentNode = node;

            while (name is QualifiedNameSyntax)
            {
                var dotted = name as QualifiedNameSyntax;
                var ns     = SingleNamespaceDeclaration.Create(
                    name: dotted.Right.Identifier.ValueText,
                    hasUsings: hasUsings,
                    hasExternAliases: hasExterns,
                    syntaxReference: syntaxTree.GetReference(currentNode),
                    nameLocation: new SourceLocation(dotted.Right),
                    children: children);

                var nsDeclaration = new[] { ns };
                children    = nsDeclaration.AsImmutableOrNull <SingleNamespaceOrTypeDeclaration>();
                currentNode = name = dotted.Left;
                hasUsings   = false;
                hasExterns  = false;
            }

            // NOTE: *Something* has to happen for alias-qualified names.  It turns out that we
            // just grab the part after the colons (via GetUnqualifiedName, below).  This logic
            // must be kept in sync with NamespaceSymbol.GetNestedNamespace.
            return(SingleNamespaceDeclaration.Create(
                       name: name.GetUnqualifiedName().Identifier.ValueText,
                       hasUsings: hasUsings,
                       hasExternAliases: hasExterns,
                       syntaxReference: syntaxTree.GetReference(currentNode),
                       nameLocation: new SourceLocation(name),
                       children: children));
        }
        public override SingleNamespaceOrTypeDeclaration VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
        {
            var children = VisitNamespaceChildren(node, node.Members, node.Green.Members);

            bool             hasUsings   = node.Usings.Any();
            bool             hasExterns  = node.Externs.Any();
            NameSyntax       name        = node.Name;
            CSharpSyntaxNode currentNode = node;

            while (name is QualifiedNameSyntax)
            {
                var dotted = name as QualifiedNameSyntax;
                var ns     = SingleNamespaceDeclaration.Create(
                    name: dotted.Right.Identifier.ValueText,
                    hasUsings: hasUsings,
                    hasExternAliases: hasExterns,
                    syntaxReference: _syntaxTree.GetReference(currentNode),
                    nameLocation: new SourceLocation(dotted.Right),
                    children: children);

                var nsDeclaration = new[] { ns };
                children    = nsDeclaration.AsImmutableOrNull <SingleNamespaceOrTypeDeclaration>();
                currentNode = name = dotted.Left;
                hasUsings   = false;
                hasExterns  = false;
            }

            // NOTE: *Something* has to happen for alias-qualified names.  It turns out that we
            // just grab the part after the colons (via GetUnqualifiedName, below).  This logic
            // must be kept in sync with NamespaceSymbol.GetNestedNamespace.
            return(SingleNamespaceDeclaration.Create(
                       name: name.GetUnqualifiedName().Identifier.ValueText,
                       hasUsings: hasUsings,
                       hasExternAliases: hasExterns,
                       syntaxReference: _syntaxTree.GetReference(currentNode),
                       nameLocation: new SourceLocation(name),
                       children: children));
        }
        private SingleNamespaceDeclaration VisitBaseNamespaceDeclaration(BaseNamespaceDeclarationSyntax node)
        {
            var children = VisitNamespaceChildren(node, node.Members, ((Syntax.InternalSyntax.BaseNamespaceDeclarationSyntax)node.Green).Members);

            bool                hasUsings   = node.Usings.Any();
            bool                hasExterns  = node.Externs.Any();
            NameSyntax          name        = node.Name;
            CSharpSyntaxNode    currentNode = node;
            QualifiedNameSyntax dotted;

            while ((dotted = name as QualifiedNameSyntax) != null)
            {
                var ns = SingleNamespaceDeclaration.Create(
                    name: dotted.Right.Identifier.ValueText,
                    hasUsings: hasUsings,
                    hasExternAliases: hasExterns,
                    syntaxReference: _syntaxTree.GetReference(currentNode),
                    nameLocation: new SourceLocation(dotted.Right),
                    children: children,
                    diagnostics: ImmutableArray <Diagnostic> .Empty);

                var nsDeclaration = new[] { ns };
                children    = nsDeclaration.AsImmutableOrNull <SingleNamespaceOrTypeDeclaration>();
                currentNode = name = dotted.Left;
                hasUsings   = false;
                hasExterns  = false;
            }

            var diagnostics = DiagnosticBag.GetInstance();

            if (node is FileScopedNamespaceDeclarationSyntax)
            {
                if (node.Parent is FileScopedNamespaceDeclarationSyntax)
                {
                    // Happens when user writes:
                    //      namespace A.B;
                    //      namespace X.Y;
                    diagnostics.Add(ErrorCode.ERR_MultipleFileScopedNamespace, node.Name.GetLocation());
                }
                else if (node.Parent is NamespaceDeclarationSyntax)
                {
                    // Happens with:
                    //
                    //      namespace A.B
                    //      {
                    //          namespace X.Y;
                    diagnostics.Add(ErrorCode.ERR_FileScopedAndNormalNamespace, 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_FileScopedNamespaceNotBeforeAllMembers, node.Name.GetLocation());
                    }
                }
            }
            else
            {
                Debug.Assert(node is NamespaceDeclarationSyntax);

                //      namespace X.Y;
                //      namespace A.B { }
                if (node.Parent is FileScopedNamespaceDeclarationSyntax)
                {
                    diagnostics.Add(ErrorCode.ERR_FileScopedAndNormalNamespace, node.Name.GetLocation());
                }
            }

            if (ContainsGeneric(node.Name))
            {
                // We're not allowed to have generics.
                diagnostics.Add(ErrorCode.ERR_UnexpectedGenericName, node.Name.GetLocation());
            }

            if (ContainsAlias(node.Name))
            {
                diagnostics.Add(ErrorCode.ERR_UnexpectedAliasedName, node.Name.GetLocation());
            }

            if (node.AttributeLists.Count > 0)
            {
                diagnostics.Add(ErrorCode.ERR_BadModifiersOnNamespace, node.AttributeLists[0].GetLocation());
            }

            if (node.Modifiers.Count > 0)
            {
                diagnostics.Add(ErrorCode.ERR_BadModifiersOnNamespace, node.Modifiers[0].GetLocation());
            }

            foreach (var directive in node.Usings)
            {
                if (directive.GlobalKeyword.IsKind(SyntaxKind.GlobalKeyword))
                {
                    diagnostics.Add(ErrorCode.ERR_GlobalUsingInNamespace, directive.GlobalKeyword.GetLocation());
                    break;
                }
            }

            // NOTE: *Something* has to happen for alias-qualified names.  It turns out that we
            // just grab the part after the colons (via GetUnqualifiedName, below).  This logic
            // must be kept in sync with NamespaceSymbol.GetNestedNamespace.
            return(SingleNamespaceDeclaration.Create(
                       name: name.GetUnqualifiedName().Identifier.ValueText,
                       hasUsings: hasUsings,
                       hasExternAliases: hasExterns,
                       syntaxReference: _syntaxTree.GetReference(currentNode),
                       nameLocation: new SourceLocation(name),
                       children: children,
                       diagnostics: diagnostics.ToReadOnlyAndFree()));
        }