예제 #1
0
 static LNode GetForwardingTarget(LNode fwd, LNode methodName)
 {
     if (fwd.Calls(S.Forward, 1))
     {
         LNode target = fwd.Args[0];
         if (target.Calls(S.Dot, 2) && (target.Args[1].IsIdNamed(_hash) || target.Args[1].IsIdNamed(__)))
         {
             return(target.WithArgChanged(1, target.Args[1].WithName(
                                              EcsNodePrinter.KeyNameComponentOf(methodName))));
         }
         return(target);
     }
     else
     {
         return(null);
     }
 }
예제 #2
0
        public static LNode SetOrCreateMember(LNode fn, IMessageSink sink)
        {
            // Expecting #fn(Type, Name, #(args), {body})
            if (fn.ArgCount < 3 || !fn.Args[2].Calls(S.AltList))
            {
                return(null);
            }
            var   args = fn.Args[2].Args;
            LNode body = null;

            VList <LNode> propOrFieldDecls = VList <LNode> .Empty;
            VList <LNode> setStmts         = VList <LNode> .Empty;

            for (int i = 0; i < args.Count; i++)
            {
                var    arg             = args[i];
                Symbol a               = S.Property;
                Symbol fieldName       = null;
                Symbol paramName       = null;
                LNode  plainArg        = null;
                LNode  propOrFieldDecl = null;
                if (arg.CallsMin(S.Property, 4))
                {
                    // #property(Type, Name<T>, {...})
                    var name = arg.Args[1];
                    fieldName = EcsNodePrinter.KeyNameComponentOf(name);
                    paramName = ChooseArgName(fieldName);
                    if (arg.ArgCount == 5)                       // initializer is Args[4]
                    {
                        plainArg        = F.Var(arg.Args[0], F.Call(S.Assign, F.Id(paramName), arg.Args[4]));
                        propOrFieldDecl = arg.WithArgs(arg.Args.First(4));
                    }
                    else
                    {
                        plainArg        = F.Var(arg.Args[0], paramName);
                        propOrFieldDecl = arg;
                    }
                }
                else
                {
                    LNode type, defaultValue;
                    if (IsVar(arg, out type, out paramName, out defaultValue))
                    {
                        int a_i = 0;
                        foreach (var attr in arg.Attrs)
                        {
                            if (attr.IsId)
                            {
                                a = attr.Name;
                                if (a == _set ||
                                    a == S.Public || a == S.Internal || a == S.Protected || a == S.Private ||
                                    a == S.ProtectedIn || a == S.Static || a == S.Partial)
                                {
                                    fieldName = paramName;
                                    paramName = ChooseArgName(fieldName);
                                    if (a == _set)
                                    {
                                        plainArg = F.Var(type, paramName, defaultValue).WithAttrs(arg.Attrs.RemoveAt(a_i));
                                    }
                                    else
                                    {
                                        // in case of something like "[A] public params T arg = value",
                                        // assume that "= value" represents a default value, not a field
                                        // initializer, that [A] belongs on the field, except `params`
                                        // which stays on the argument.
                                        plainArg        = F.Var(type, paramName, defaultValue);
                                        propOrFieldDecl = arg;
                                        if (arg.Args[1].Calls(S.Assign, 2))
                                        {
                                            propOrFieldDecl = arg.WithArgChanged(1,
                                                                                 arg.Args[1].Args[0]);
                                        }
                                        int i_params = arg.Attrs.IndexWithName(S.Params);
                                        if (i_params > -1)
                                        {
                                            plainArg        = plainArg.PlusAttr(arg.Attrs[i_params]);
                                            propOrFieldDecl = propOrFieldDecl.WithAttrs(propOrFieldDecl.Attrs.RemoveAt(i_params));
                                        }
                                    }
                                    break;
                                }
                            }
                            a_i++;
                        }
                    }
                }
                if (plainArg != null)
                {
                    if (body == null)
                    {
                        if (fn.ArgCount < 4 || !fn.Args[3].Calls(S.Braces))
                        {
                            return(Reject(sink, arg, Localize.Localized("'{0}': to set or create a field or property, the method must have a body in braces {{}}.", a)));
                        }
                        body = fn.Args[3];
                    }

                    args[i] = plainArg;
                    LNode assignment;
                    if (fieldName == paramName)
                    {
                        assignment = F.Call(S.Assign, F.Dot(F.@this, F.Id(fieldName)), F.Id(paramName));
                    }
                    else
                    {
                        assignment = F.Call(S.Assign, F.Id(fieldName), F.Id(paramName));
                    }
                    setStmts.Add(assignment);
                    if (propOrFieldDecl != null)
                    {
                        propOrFieldDecls.Add(propOrFieldDecl);
                    }
                }
            }
            if (body != null)             // if this macro has been used...
            {
                var parts = fn.Args;
                parts[2] = parts[2].WithArgs(args);
                parts[3] = body.WithArgs(body.Args.InsertRange(0, setStmts));
                fn       = fn.WithArgs(parts);
                if (propOrFieldDecls.IsEmpty)
                {
                    return(fn);
                }
                else
                {
                    propOrFieldDecls.Add(fn);
                    return(F.Call(S.Splice, propOrFieldDecls));
                }
            }
            return(null);
        }
예제 #3
0
        private static bool DetectSetOrCreateMember(LNode arg, out Symbol relevantAttribute, out Symbol fieldName, out Symbol paramName, out LNode newArg, out LNode propOrFieldDecl)
        {
            relevantAttribute = null;
            fieldName         = null;
            paramName         = null;
            newArg            = null;
            propOrFieldDecl   = null;
            LNode _, type, name, defaultValue, propArgs;

            if (EcsValidators.IsPropertyDefinition(arg, out type, out name, out propArgs, out _, out defaultValue) && propArgs.ArgCount == 0)
            {
                // #property(Type, Name<T>, {...})
                relevantAttribute = S.Property;
                fieldName         = EcsNodePrinter.KeyNameComponentOf(name);
                paramName         = ChooseArgName(fieldName);
                if (defaultValue != null)                   // initializer is Args[4]
                {
                    newArg          = LNode.Call(S.Var, LNode.List(type, F.Assign(paramName, defaultValue)), arg);
                    propOrFieldDecl = arg.WithArgs(arg.Args.Initial(4));
                }
                else
                {
                    newArg          = LNode.Call(S.Var, LNode.List(type, F.Id(paramName)), arg);
                    propOrFieldDecl = arg;
                }
                DSOCM_DistributeAttributes(arg.Attrs, ref newArg, ref propOrFieldDecl);
                return(true);
            }
            else if (IsVar(arg, out type, out paramName, out defaultValue))
            {
                int a_i = 0;
                foreach (var attr in arg.Attrs)
                {
                    if (attr.IsId)
                    {
                        var a = attr.Name;
                        if (a == _set || FieldCreationAttributes.Contains(a))
                        {
                            relevantAttribute = a;
                            fieldName         = paramName;
                            paramName         = ChooseArgName(fieldName);
                            if (a == _set)
                            {
                                newArg = F.Var(type, paramName, defaultValue).WithAttrs(arg.Attrs.Without(attr));
                            }
                            else
                            {
                                // in case of something like "[A] public params T arg = value",
                                // assume that "= value" represents a default value, not a field
                                // initializer. Most attributes stay on the argument.
                                newArg = arg.WithArgChanged(1,
                                                            defaultValue != null ? F.Assign(paramName, defaultValue) : F.Id(paramName));
                                propOrFieldDecl = LNode.Call(S.Var, LNode.List(type, F.Id(fieldName)), arg);
                                DSOCM_DistributeAttributes(arg.Attrs, ref newArg, ref propOrFieldDecl);
                            }
                            break;
                        }
                    }
                    a_i++;
                }
                return(newArg != null);
            }
            return(false);
        }
예제 #4
0
        private static bool DetectSetOrCreateMember(LNode arg, out Symbol relevantAttribute, out Symbol fieldName, out Symbol paramName, out LNode plainArg, out LNode propOrFieldDecl)
        {
            relevantAttribute = null;
            fieldName         = null;
            paramName         = null;
            plainArg          = null;
            propOrFieldDecl   = null;
            LNode _, type, name, defaultValue, propArgs;

            if (EcsValidators.IsPropertyDefinition(arg, out type, out name, out propArgs, out _, out defaultValue) && propArgs.ArgCount == 0)
            {
                // #property(Type, Name<T>, {...})
                relevantAttribute = S.Property;
                fieldName         = EcsNodePrinter.KeyNameComponentOf(name);
                paramName         = ChooseArgName(fieldName);
                if (defaultValue != null)                   // initializer is Args[4]
                {
                    plainArg        = F.Var(type, paramName, defaultValue);
                    propOrFieldDecl = arg.WithArgs(arg.Args.First(4));
                }
                else
                {
                    plainArg        = F.Var(type, paramName);
                    propOrFieldDecl = arg;
                }
                return(true);
            }
            else if (IsVar(arg, out type, out paramName, out defaultValue))
            {
                int a_i = 0;
                foreach (var attr in arg.Attrs)
                {
                    if (attr.IsId)
                    {
                        var a = attr.Name;
                        if (a == _set ||
                            a == S.Public || a == S.Internal || a == S.Protected || a == S.Private ||
                            a == S.ProtectedIn || a == S.Static || a == S.Partial)
                        {
                            relevantAttribute = a;
                            fieldName         = paramName;
                            paramName         = ChooseArgName(fieldName);
                            if (a == _set)
                            {
                                plainArg = F.Var(type, paramName, defaultValue).WithAttrs(arg.Attrs.Without(attr));
                            }
                            else
                            {
                                // in case of something like "[A] public params T arg = value",
                                // assume that "= value" represents a default value, not a field
                                // initializer, that [A] belongs on the field, except `params`
                                // which stays on the argument.
                                plainArg        = F.Var(type, paramName, defaultValue);
                                propOrFieldDecl = arg;
                                if (arg.Args[1].Calls(S.Assign, 2))
                                {
                                    propOrFieldDecl = arg.WithArgChanged(1,
                                                                         arg.Args[1].Args[0]);
                                }
                                int i_params = arg.Attrs.IndexWithName(S.Params);
                                if (i_params > -1)
                                {
                                    plainArg        = plainArg.PlusAttr(arg.Attrs[i_params]);
                                    propOrFieldDecl = propOrFieldDecl.WithAttrs(propOrFieldDecl.Attrs.RemoveAt(i_params));
                                }
                            }
                            break;
                        }
                    }
                    a_i++;
                }
                return(plainArg != null);
            }
            return(false);
        }