コード例 #1
0
        public override void ExitFoxclass([NotNull] XP.FoxclassContext context)
        {
            var fieldNames = new List <String>();
            var members    = _pool.Allocate <MemberDeclarationSyntax>();
            var generated  = ClassEntities.Pop();
            var mods       = context.Modifiers?.GetList <SyntaxToken>() ?? TokenListWithDefaultVisibility();

            context.Data.Partial = mods.Any((int)SyntaxKind.PartialKeyword);
            var baseTypes = _pool.AllocateSeparated <BaseTypeSyntax>();
            var baseType  = context.BaseType?.Get <TypeSyntax>();

            if (baseType != null)
            {
                baseTypes.Add(_syntaxFactory.SimpleBaseType(baseType));
            }
            if (generated.Members.Count > 0)
            {
                members.AddRange(generated.Members);
            }
            if (generated.VoProperties != null)
            {
                foreach (var vop in generated.VoProperties.Values)
                {
                    var prop = GenerateVoProperty(vop, context);
                    if (prop != null)
                    {
                        members.Add(prop);
                    }
                }
            }
            // Collect list of FieldNames from clsvarscontext to prevent generating properties twice
            foreach (var mCtx in context._Members)
            {
                if (mCtx is XP.FoxclsvarsContext fcfc)
                {
                    var mem = fcfc.Member;
                    foreach (var v in mem._Vars)
                    {
                        fieldNames.Add(v.GetText().ToLower());
                    }
                    var list = mem.CsNode as List <MemberDeclarationSyntax>;
                    if (list != null)
                    {
                        foreach (var m1 in list)
                        {
                            members.Add(m1);
                        }
                    }
                }
            }

            // Do this after VOProps generation because GenerateVOProperty sets the members
            // for Access & Assign to NULL
            ConstructorDeclarationSyntax ctor = null;

            foreach (var mCtx in context._Members)
            {
                if (mCtx is XP.FoxclsvarinitContext cvi)
                {
                    var fld = cvi.Member.F.Name.GetText();
                    if (!fieldNames.Contains(fld.ToLower()))
                    {
                        if (mCtx.CsNode != null)
                        {
                            members.Add(mCtx.Get <MemberDeclarationSyntax>());
                        }
                    }
                    else
                    {
                        // field is declared and initialized. No need to generate a second property or field.
                    }
                }
                else if (mCtx is XP.FoximplementsContext fic)
                {
                    var clause = fic.Member as XP.FoximplementsclauseContext;
                    var type   = clause.Type.Get <TypeSyntax>();
                    if (baseTypes.Count > 0)
                    {
                        baseTypes.AddSeparator(SyntaxFactory.MakeToken(SyntaxKind.CommaToken));
                    }
                    baseTypes.Add(_syntaxFactory.SimpleBaseType(type));
                }
                else if (mCtx is XP.FoxclsmethodContext cmc)
                {
                    if (cmc.Member.CsNode is MemberDeclarationSyntax mds)
                    {
                        members.Add(mds);
                    }
                }
                else if (mCtx is XP.FoxaddobjectContext fac)
                {
                    var prop = fac.Get <MemberDeclarationSyntax>();
                    members.Add(prop);
                }
                else
                {
                    if (mCtx.CsNode is MemberDeclarationSyntax mds)
                    {
                        members.Add(mds);
                        if (mds is ConstructorDeclarationSyntax)
                        {
                            ctor = mds as ConstructorDeclarationSyntax;
                        }
                    }
                }
            }
            generated.Free();
            if (ctor != null)
            {
                var newlist = members.ToList();
                members.Clear();
                foreach (var mem in newlist)
                {
                    if (mem != ctor)
                    {
                        members.Add(mem);
                    }
                }

                ctor = createConstructor(context, members, fieldNames, ctor);
                members.Add(ctor);
            }
            else
            {
                ctor = createConstructor(context, members, fieldNames, null);
                members.Add(ctor);
            }
            MemberDeclarationSyntax m = _syntaxFactory.ClassDeclaration(
                attributeLists: context.Attributes?.GetList <AttributeListSyntax>() ?? EmptyList <AttributeListSyntax>(),
                modifiers: mods,
                keyword: SyntaxFactory.MakeToken(SyntaxKind.ClassKeyword),
                identifier: context.Id.Get <SyntaxToken>(),
                typeParameterList: context.TypeParameters?.Get <TypeParameterListSyntax>(),
                baseList: _syntaxFactory.BaseList(SyntaxFactory.MakeToken(SyntaxKind.ColonToken), baseTypes),
                constraintClauses: MakeList <TypeParameterConstraintClauseSyntax>(context._ConstraintsClauses),
                openBraceToken: SyntaxFactory.MakeToken(SyntaxKind.OpenBraceToken),
                members: members,
                closeBraceToken: SyntaxFactory.MakeToken(SyntaxKind.CloseBraceToken),
                semicolonToken: null);

            _pool.Free(members);
            _pool.Free(baseTypes);
            if (context.Namespace != null)
            {
                m = AddNameSpaceToMember(context.Namespace, m);
            }
            else
            {
                m = (MemberDeclarationSyntax)CheckTypeName(context, "CLASS", m);
            }

            context.Put(m);
            if (context.Data.Partial)
            {
                GlobalEntities.NeedsProcessing = true;
            }
        }
コード例 #2
0
        public override void ExitXppclass([NotNull] XP.XppclassContext context)
        {
            context.SetSequencePoint(context.C, context.e.Stop);
            var members   = _pool.Allocate <MemberDeclarationSyntax>();
            var generated = ClassEntities.Pop();
            var mods      = context.Modifiers?.GetList <SyntaxToken>() ?? TokenListWithDefaultVisibility();

            XP.DatatypeContext basetype = null;
            if (generated.Members.Count > 0)                // inline methods, properties and fields
            {
                members.AddRange(generated.Members);
            }
            if (context.Modifiers != null)
            {
                if (context.Modifiers._Tokens.Any(t => t.Type == XP.STATIC))
                {
                    context.Data.HasStatic = true;
                }
            }
            // check if all declared methods have been implemented
            // and if so, then add the methods to the members list
            string className = context.Id.GetText();

            if (context._BaseTypes.Count == 1)
            {
                basetype = context._BaseTypes[0];
            }
            XppClassInfo thisClass = FindClassInfo(className);

            if (thisClass == null || thisClass.Entity != context)
            {
                context.AddError(new ParseErrorData(context, ErrorCode.ERR_ParserError, "Could not locate ClassInfo for class " + className));
                return;
            }

            generated.Free();
            var baseTypes = _pool.AllocateSeparated <BaseTypeSyntax>();
            var baseType  = basetype.Get <TypeSyntax>();

            if (baseType != null)
            {
                baseTypes.Add(_syntaxFactory.SimpleBaseType(baseType));
            }
            foreach (var iCtx in context._Implements)
            {
                if (baseTypes.Count > 0)
                {
                    baseTypes.AddSeparator(SyntaxFactory.MakeToken(SyntaxKind.CommaToken));
                }
                baseTypes.Add(_syntaxFactory.SimpleBaseType(iCtx.Get <TypeSyntax>()));
            }

            MemberDeclarationSyntax m = _syntaxFactory.ClassDeclaration(
                attributeLists: context.Attributes?.GetList <AttributeListSyntax>() ?? EmptyList <AttributeListSyntax>(),
                modifiers: mods,
                keyword: SyntaxFactory.MakeToken(SyntaxKind.ClassKeyword),
                identifier: context.Id.Get <SyntaxToken>(),
                typeParameterList: null,
                baseList: _syntaxFactory.BaseList(SyntaxFactory.MakeToken(SyntaxKind.ColonToken), baseTypes),
                constraintClauses: null,
                openBraceToken: SyntaxFactory.MakeToken(SyntaxKind.OpenBraceToken),
                members: members,
                closeBraceToken: SyntaxFactory.MakeToken(SyntaxKind.CloseBraceToken),
                semicolonToken: null);

            _pool.Free(members);
            _pool.Free(baseTypes);
            context.Put(m);
            _currentClass = null;
        }