示例#1
0
        private static string[] GetNonTypeMemberNames(
            CoreInternalSyntax.SyntaxList <Syntax.InternalSyntax.MemberDeclarationSyntax> members, ref SingleTypeDeclaration.TypeDeclarationFlags declFlags)
        {
            bool anyMethodHadExtensionSyntax = false;
            bool anyMemberHasAttributes      = false;
            bool anyNonTypeMembers           = false;

            var set = PooledHashSet <string> .GetInstance();

            foreach (var member in members)
            {
                AddNonTypeMemberNames(member, set, ref anyNonTypeMembers);

                // Check to see if any method contains a 'this' modifier on its first parameter.
                // This data is used to determine if a type needs to have its members materialized
                // as part of extension method lookup.
                if (!anyMethodHadExtensionSyntax && CheckMethodMemberForExtensionSyntax(member))
                {
                    anyMethodHadExtensionSyntax = true;
                }

                if (!anyMemberHasAttributes && CheckMemberForAttributes(member))
                {
                    anyMemberHasAttributes = true;
                }
            }

            if (anyMethodHadExtensionSyntax)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.AnyMemberHasExtensionMethodSyntax;
            }

            if (anyMemberHasAttributes)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.AnyMemberHasAttributes;
            }

            if (anyNonTypeMembers)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.HasAnyNontypeMembers;
            }

            // PERF: The member names collection tends to be long-lived. Use a string array since
            // that uses less memory than a HashSet<string>.
            string[] result;
            if (set.Count == 0)
            {
                result = Array.Empty <string>();
            }
            else
            {
                result = new string[set.Count];
                set.CopyTo(result);
            }

            set.Free();
            return(result);
        }
示例#2
0
        private static ImmutableHashSet <string> GetNonTypeMemberNames(
            CoreInternalSyntax.SyntaxList <Syntax.InternalSyntax.MemberDeclarationSyntax> members, ref SingleTypeDeclaration.TypeDeclarationFlags declFlags)
        {
            bool anyMethodHadExtensionSyntax = false;
            bool anyMemberHasAttributes      = false;
            bool anyNonTypeMembers           = false;

            var memberNameBuilder = s_memberNameBuilderPool.Allocate();

            foreach (var member in members)
            {
                AddNonTypeMemberNames(member, memberNameBuilder, ref anyNonTypeMembers);

                // Check to see if any method contains a 'this' modifier on its first parameter.
                // This data is used to determine if a type needs to have its members materialized
                // as part of extension method lookup.
                if (!anyMethodHadExtensionSyntax && CheckMethodMemberForExtensionSyntax(member))
                {
                    anyMethodHadExtensionSyntax = true;
                }

                if (!anyMemberHasAttributes && CheckMemberForAttributes(member))
                {
                    anyMemberHasAttributes = true;
                }
            }

            if (anyMethodHadExtensionSyntax)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.AnyMemberHasExtensionMethodSyntax;
            }

            if (anyMemberHasAttributes)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.AnyMemberHasAttributes;
            }

            if (anyNonTypeMembers)
            {
                declFlags |= SingleTypeDeclaration.TypeDeclarationFlags.HasAnyNontypeMembers;
            }

            return(ToImmutableAndFree(memberNameBuilder));
        }
示例#3
0
        private ImmutableArray <SingleNamespaceOrTypeDeclaration> VisitNamespaceChildren(
            CSharpSyntaxNode node,
            SyntaxList <MemberDeclarationSyntax> members,
            CoreInternalSyntax.SyntaxList <Syntax.InternalSyntax.MemberDeclarationSyntax> internalMembers)
        {
            Debug.Assert(node.Kind() == SyntaxKind.NamespaceDeclaration || (node.Kind() == SyntaxKind.CompilationUnit && _syntaxTree.Options.Kind == SourceCodeKind.Regular));

            if (members.Count == 0)
            {
                return(ImmutableArray <SingleNamespaceOrTypeDeclaration> .Empty);
            }

            // We look for members that are not allowed in a namespace.
            // If there are any we create an implicit class to wrap them.
            bool hasGlobalMembers = false;

            var childrenBuilder = ArrayBuilder <SingleNamespaceOrTypeDeclaration> .GetInstance();

            foreach (var member in members)
            {
                SingleNamespaceOrTypeDeclaration namespaceOrType = Visit(member);
                if (namespaceOrType != null)
                {
                    childrenBuilder.Add(namespaceOrType);
                }
                else
                {
                    hasGlobalMembers = hasGlobalMembers || member.Kind() != SyntaxKind.IncompleteMember;
                }
            }

            // wrap all members that are defined in a namespace or compilation unit into an implicit type:
            if (hasGlobalMembers)
            {
                //The implicit class is not static and has no extensions
                SingleTypeDeclaration.TypeDeclarationFlags declFlags = SingleTypeDeclaration.TypeDeclarationFlags.None;
                var memberNames = GetNonTypeMemberNames(internalMembers, ref declFlags);
                var container   = _syntaxTree.GetReference(node);

                childrenBuilder.Add(CreateImplicitClass(memberNames, container, declFlags));
            }

            return(childrenBuilder.ToImmutableAndFree());
        }
        private ImmutableArray <SingleNamespaceOrTypeDeclaration> VisitNamespaceChildren(
            CSharpSyntaxNode node,
            SyntaxList <MemberDeclarationSyntax> members,
            CoreInternalSyntax.SyntaxList <Syntax.InternalSyntax.MemberDeclarationSyntax> internalMembers)
        {
            Debug.Assert(
                node.Kind() is SyntaxKind.NamespaceDeclaration or SyntaxKind.FileScopedNamespaceDeclaration ||
                (node.Kind() == SyntaxKind.CompilationUnit && _syntaxTree.Options.Kind == SourceCodeKind.Regular));

            if (members.Count == 0)
            {
                return(ImmutableArray <SingleNamespaceOrTypeDeclaration> .Empty);
            }

            // We look for members that are not allowed in a namespace.
            // If there are any we create an implicit class to wrap them.
            bool hasGlobalMembers        = false;
            bool acceptSimpleProgram     = node.Kind() == SyntaxKind.CompilationUnit && _syntaxTree.Options.Kind == SourceCodeKind.Regular;
            bool hasAwaitExpressions     = false;
            bool isIterator              = false;
            bool hasReturnWithExpression = false;
            GlobalStatementSyntax firstGlobalStatement = null;
            bool hasNonEmptyGlobalStatement            = false;

            var childrenBuilder = ArrayBuilder <SingleNamespaceOrTypeDeclaration> .GetInstance();

            foreach (var member in members)
            {
                SingleNamespaceOrTypeDeclaration namespaceOrType = Visit(member);
                if (namespaceOrType != null)
                {
                    childrenBuilder.Add(namespaceOrType);
                }
                else if (acceptSimpleProgram && member.IsKind(SyntaxKind.GlobalStatement))
                {
                    var global = (GlobalStatementSyntax)member;
                    firstGlobalStatement ??= global;
                    var topLevelStatement = global.Statement;

                    if (!topLevelStatement.IsKind(SyntaxKind.EmptyStatement))
                    {
                        hasNonEmptyGlobalStatement = true;
                    }

                    if (!hasAwaitExpressions)
                    {
                        hasAwaitExpressions = SyntaxFacts.HasAwaitOperations(topLevelStatement);
                    }

                    if (!isIterator)
                    {
                        isIterator = SyntaxFacts.HasYieldOperations(topLevelStatement);
                    }

                    if (!hasReturnWithExpression)
                    {
                        hasReturnWithExpression = SyntaxFacts.HasReturnWithExpression(topLevelStatement);
                    }
                }
                else if (!hasGlobalMembers && member.Kind() != SyntaxKind.IncompleteMember)
                {
                    hasGlobalMembers = true;
                }
            }

            // wrap all global statements in a compilation unit into a simple program type:
            if (firstGlobalStatement is object)
            {
                var diagnostics = ImmutableArray <Diagnostic> .Empty;

                if (!hasNonEmptyGlobalStatement)
                {
                    var bag = DiagnosticBag.GetInstance();
                    bag.Add(ErrorCode.ERR_SimpleProgramIsEmpty, ((EmptyStatementSyntax)firstGlobalStatement.Statement).SemicolonToken.GetLocation());
                    diagnostics = bag.ToReadOnlyAndFree();
                }

                childrenBuilder.Add(CreateSimpleProgram(firstGlobalStatement, hasAwaitExpressions, isIterator, hasReturnWithExpression, diagnostics));
            }

            // wrap all members that are defined in a namespace or compilation unit into an implicit type:
            if (hasGlobalMembers)
            {
                //The implicit class is not static and has no extensions
                SingleTypeDeclaration.TypeDeclarationFlags declFlags = SingleTypeDeclaration.TypeDeclarationFlags.None;
                var memberNames = GetNonTypeMemberNames(internalMembers, ref declFlags, skipGlobalStatements: acceptSimpleProgram);
                var container   = _syntaxTree.GetReference(node);

                childrenBuilder.Add(CreateImplicitClass(memberNames, container, declFlags));
            }

            return(childrenBuilder.ToImmutableAndFree());
        }