Example #1
0
            // Generates a class declaration for the current alt and its subtypes
            internal void GenerateOutput(ref LNodeList list)
            {
                bool isAbstract = _classAttrs.Any(a => a.IsIdNamed(S.Abstract));

                var baseParts = new List <AdtParam>();

                for (var type = ParentType; type != null; type = type.ParentType)
                {
                    baseParts.InsertRange(0, type.Parts);
                }
                var allParts = baseParts.Concat(Parts);

                var initialization = Parts.Select(p => LNode.Call(CodeSymbols.Assign, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id(CodeSymbols.This), p.NameId)).SetStyle(NodeStyle.Operator), p.NameId)).SetStyle(NodeStyle.Operator)).ToList();

                if (baseParts.Count > 0)
                {
                    initialization.Insert(0, F.Call(S.Base, baseParts.Select(p => p.NameId)));
                }

                var args = new LNodeList(allParts.Select(p => p.OriginalDecl));

                if (!_constructorAttrs.Any(a => a.IsIdNamed(S.Public)))
                {
                    _constructorAttrs.Add(F.Id(S.Public));
                }
                LNode constructor = LNode.Call(LNode.List(_constructorAttrs), CodeSymbols.Constructor, LNode.List(LNode.Missing, _typeNameStem, LNode.Call(CodeSymbols.AltList, LNode.List(args)), LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(initialization).AddRange(_extraConstrLogic)).SetStyle(NodeStyle.StatementBlock)));

                var outBody = new LNodeList();

                outBody.Add(constructor);
                outBody.AddRange(Parts.Select(p => p.GetFieldDecl()));
                outBody.AddRange(baseParts.Select(p => GetWithFn(p, isAbstract, S.Override, allParts)));
                outBody.AddRange(Parts.Select(p => GetWithFn(p, isAbstract, _children.Count > 0 ? S.Virtual : null, allParts)));
                outBody.AddRange(Parts.WithIndexes()
                                 .Where(kvp => kvp.Value.NameId.Name.Name != "Item" + (baseParts.Count + kvp.Key + 1))
                                 .Select(kvp => kvp.Value.GetItemDecl(baseParts.Count + kvp.Key + 1)));
                outBody.AddRange(_classBody);

                list.Add(LNode.Call(LNode.List(_classAttrs), CodeSymbols.Class, LNode.List(TypeName, LNode.Call(CodeSymbols.AltList, LNode.List(BaseTypes)), LNode.Call(CodeSymbols.Braces, LNode.List(outBody)).SetStyle(NodeStyle.StatementBlock))));
                if (_genericArgs.Count > 0 && Parts.Count > 0)
                {
                    var argNames = allParts.Select(p => p.NameId);
                    list.Add(LNode.Call(LNode.List().AddRange(_classAttrs).Add(LNode.Id(CodeSymbols.Static)).Add(LNode.Id(CodeSymbols.Partial)), CodeSymbols.Class, LNode.List(_typeNameStem, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(LNode.List(LNode.Id(CodeSymbols.Public), LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(TypeNameWithoutAttrs, LNode.Call(CodeSymbols.Of, LNode.List().Add(LNode.Id((Symbol)"New")).AddRange(_genericArgs)).SetStyle(NodeStyle.Operator), LNode.Call(CodeSymbols.AltList, LNode.List(args)), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(TypeNameWithoutAttrs, LNode.List(argNames)))))))).SetStyle(NodeStyle.StatementBlock))))).SetStyle(NodeStyle.StatementBlock))));
                }
                foreach (var child in _children)
                {
                    child.GenerateOutput(ref list);
                }
            }
Example #2
0
            private void AddUserAction(LNodeList actions)
            {
                int i = _target.Count;

                _target.AddRange(actions);

                if (actions.Any(stmt => stmt.Range.StartIndex > 0))
                {
                    if (LLPG.AddCsLineDirectives)
                    {
                        // Remove folder name. This only makes sense if the output
                        // file and input file are in the same folder; sadly we have
                        // no access to the output file name, but as of 2015-05 it's
                        // always true that the output file will be in the same folder.
                        string filename = System.IO.Path.GetFileName(_target[i].Range.Source.FileName);
                        var    newline  = F.Id(S.TriviaNewline);
                        int    line     = 0;
                        for (; i < _target.Count; i++, line++)
                        {
                            var r = _target[i].Range;
                            if (line != r.Start.Line)
                            {
                                line = r.Start.Line;
                                if (line <= 0)                                 // sometimes occurs for generated `return result` statement
                                {
                                    _target.Insert(i++, F.Trivia(S.CsPPRawText, "#line default"));
                                }
                                else
                                {
                                    _target.Insert(i++, F.Trivia(S.CsPPRawText, "#line " + line + " " + Ecs.EcsNodePrinter.PrintString(filename, '"')));
                                }
                            }
                        }
                        if (line > 1)
                        {
                            _target.Add(F.Trivia(S.CsPPRawText, "#line default"));
                        }
                    }
                    else
                    {
                        _target[i] = _target[i].PlusAttr(F.Trivia(S.TriviaSLComment,
                                                                  string.Format(" line {0}", _target[i].Range.Start.Line)));
                    }
                }
            }
Example #3
0
 LNode MaybeQuoteList(LNodeList list, bool isAttributes = false)
 {
     if (isAttributes && _ignoreTrivia)
     {
         list = list.SmartWhere(n => !n.IsTrivia || n.IsIdNamed(S.TriviaInParens));
     }
     if (list.IsEmpty)
     {
         return(null);
     }
     else if (_doSubstitutions && list.Any(a => VarArgExpr(a) != null))
     {
         if (list.Count == 1)
         {
             return(F.Call(LNode_List, VarArgExpr(list[0])));
         }
         // If you write something like quote(Foo($x, $(...y), $z)), a special
         // output style is used to accommodate the variable argument list.
         LNode argList = F.Call(LNode_List);
         foreach (LNode arg in list)
         {
             var vae = VarArgExpr(arg);
             if (vae != null)
             {
                 argList = F.Call(F.Dot(argList, F.Id("AddRange")), vae);
             }
             else
             {
                 argList = F.Call(F.Dot(argList, F.Id("Add")), Quote(arg));
             }
         }
         return(argList);
     }
     else
     {
         return(F.Call(LNode_List, list.SmartSelect(item => Quote(item))));
     }
 }