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()));
        }
Esempio n. 2
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));
        }
Esempio n. 3
0
        private SingleNamespaceOrTypeDeclaration CreateScriptClass(
            CompilationUnitSyntax parent,
            ImmutableArray <SingleTypeDeclaration> children,
            ImmutableHashSet <string> memberNames,
            SingleTypeDeclaration.TypeDeclarationFlags declFlags
            )
        {
            Debug.Assert(
                parent.Kind() == SyntaxKind.CompilationUnit &&
                _syntaxTree.Options.Kind != SourceCodeKind.Regular
                );

            // script type is represented by the parent node:
            var parentReference = _syntaxTree.GetReference(parent);
            var fullName        = _scriptClassName.Split('.');

            // Note: The symbol representing the merged declarations uses parentReference to enumerate non-type members.
            SingleNamespaceOrTypeDeclaration decl = new SingleTypeDeclaration(
                kind: _isSubmission ? DeclarationKind.Submission : DeclarationKind.Script,
                name: fullName.Last(),
                arity: 0,
                modifiers: DeclarationModifiers.Internal
                | DeclarationModifiers.Partial
                | DeclarationModifiers.Sealed,
                declFlags: declFlags,
                syntaxReference: parentReference,
                nameLocation: new SourceLocation(parentReference),
                memberNames: memberNames,
                children: children,
                diagnostics: ImmutableArray <Diagnostic> .Empty
                );

            for (int i = fullName.Length - 2; i >= 0; i--)
            {
                decl = SingleNamespaceDeclaration.Create(
                    name: fullName[i],
                    hasUsings: false,
                    hasExternAliases: false,
                    syntaxReference: parentReference,
                    nameLocation: new SourceLocation(parentReference),
                    children: ImmutableArray.Create(decl),
                    diagnostics: ImmutableArray <Diagnostic> .Empty
                    );
            }

            return(decl);
        }
Esempio n. 4
0
        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()));
        }