Example #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;
            }
        }
Example #2
0
        private ConstructorDeclarationSyntax createConstructor(XP.FoxclassContext context, SyntaxListBuilder <MemberDeclarationSyntax> members,
                                                               List <String> fieldNames, ConstructorDeclarationSyntax existingctor)
        {
            var  stmts          = new List <StatementSyntax>();
            bool hasinit        = false;
            var  attributeLists = _pool.Allocate <AttributeListSyntax>();

            ParameterListSyntax          initparams = EmptyParameterList();
            ConstructorDeclarationSyntax ctor       = null;

            foreach (var member in context._Members)
            {
                if (member is XP.FoxclsmethodContext fm)
                {
                    // fetch parameters from procedure/function init
                    var method = fm.Member as XP.FoxmethodContext;
                    if (method.Id.GetText().ToLower() == "init")
                    {
                        var syntax = method.Get <MethodDeclarationSyntax>();
                        initparams = syntax.ParameterList;
                        attributeLists.AddRange(syntax.AttributeLists);
                        hasinit = true;
                    }
                }
                else if (member is XP.FoxclsvarinitContext cvi)
                {
                    // Generate code to initialize properties
                    var fldinit = cvi.Member;
                    var assign  = fldinit.F.Get <ExpressionSyntax>();
                    var stmt    = GenerateExpressionStatement(assign);
                    stmt.XNode = fldinit.F;
                    stmts.Add(stmt);
                }
                else if (member is XP.FoxaddobjectContext fac)
                {
                    // generate object creation and addobject call
                    // Property:= ClassName{}{.......}
                    var addobject = fac.Member;
                    var create    = createAddObject(addobject);
                    var name      = addobject.Id.GetText();
                    var prop      = MakeSimpleMemberAccess(GenerateSelf(), GenerateSimpleName(name));
                    var assign    = MakeSimpleAssignment(prop, create);
                    var stmt      = GenerateExpressionStatement(assign);
                    stmt.XNode = addobject;
                    stmts.Add(stmt);
                    // AddObject(SELF:Property)
                    var arg1  = MakeArgument(GenerateLiteral(name));
                    var arg2  = MakeArgument(prop);
                    var mcall = GenerateMethodCall(XSharpSpecialNames.AddObject, MakeArgumentList(arg1, arg2));
                    stmt       = GenerateExpressionStatement(mcall);
                    stmt.XNode = addobject;
                    stmts.Add(stmt);
                }
            }
            if (_options.fox1)
            {
                if (stmts.Count > 0)
                {
                    // Generate Virtual Protected _InitProperties
                    // SUPER:_InitProperties()
                    // All Statements
                    var mac       = MakeSimpleMemberAccess(GenerateSuper(), GenerateSimpleName(XSharpSpecialNames.InitProperties));
                    var superCall = _syntaxFactory.InvocationExpression(mac, EmptyArgumentList());
                    var stmt      = GenerateExpressionStatement(superCall, true);
                    stmts.Insert(0, stmt);
                    var body = MakeBlock(stmts);
                    body.XGenerated = true;
                    var mods = TokenList(SyntaxKind.ProtectedKeyword, SyntaxKind.OverrideKeyword);
                    var id   = SyntaxFactory.MakeIdentifier(XSharpSpecialNames.InitProperties);
                    var mem  = _syntaxFactory.MethodDeclaration(MakeCompilerGeneratedAttribute(), mods, _voidType, null, id,
                                                                null, EmptyParameterList(), null, body, null, SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken));
                    members.Add(mem);
                    stmts.Clear();
                }
            }
            if (stmts.Count > 0 || hasinit || existingctor != null)
            {
                var argList = new List <ArgumentSyntax>();
                for (int i = 0; i < initparams.Parameters.Count; i++)
                {
                    var par = initparams.Parameters[i];
                    argList.Add(MakeArgument(GenerateSimpleName(par.Identifier.Text)));
                }
                ArgumentListSyntax args = MakeArgumentList(argList.ToArray());
                if (existingctor != null)
                {
                    stmts.AddRange(existingctor.Body.Statements.Nodes);
                    var body = MakeBlock(stmts);
                    ctor = existingctor.Update(existingctor.AttributeLists, existingctor.Modifiers, existingctor.Identifier,
                                               existingctor.ParameterList, existingctor.Initializer, body, existingctor.ExpressionBody, existingctor.SemicolonToken);
                }
                else
                {
                    var chain = _syntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer,
                                                                      SyntaxFactory.MakeToken(SyntaxKind.ColonToken),
                                                                      SyntaxFactory.MakeToken(SyntaxKind.BaseKeyword),
                                                                      args
                                                                      );
                    var mods = TokenList(SyntaxKind.PublicKeyword);
                    var id   = context.Id.Get <SyntaxToken>();
                    GenerateAttributeList(attributeLists, SystemQualifiedNames.CompilerGenerated);
                    var body = MakeBlock(stmts);
                    ctor = _syntaxFactory.ConstructorDeclaration(attributeLists, mods, id, initparams, chain, body, null, null);
                }
            }
            _pool.Free(attributeLists);
            return(ctor);
        }
Example #3
0
 public override void EnterFoxclass([NotNull] XP.FoxclassContext context)
 {
     ClassEntities.Push(CreateClassEntities());
 }