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; } }
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); }
public override void EnterFoxclass([NotNull] XP.FoxclassContext context) { ClassEntities.Push(CreateClassEntities()); }