コード例 #1
0
ファイル: ScopeProcessor.cs プロジェクト: mortend/uno
        StageValue Process()
        {
            Method.Body.Visit(this);

            var min = MinStage;
            var max = MaxStage;

            for (int i = 0; i < Arguments.Count; i++)
            {
                if (Arguments[i].Value.MinStage > min)
                {
                    min = Arguments[i].Value.MinStage;
                }

                if (Arguments[i].Value.MaxStage < max)
                {
                    max = Arguments[i].Value.MaxStage;
                }

                if (Arguments[i].Value.MinStage > MaxStage)
                {
                    Log.Error(Arguments[i].Source, ErrorCode.E5009, "Cannot access " + min.Quote() + " symbol from stage " + MaxStage.Quote());
                }
            }

            if (max < min)
            {
                max = min;
            }

            var pl = new List <Parameter>();
            var al = new List <Expression>();

            var map = new Dictionary <int, Expression>();

            for (int i = 0; i < Arguments.Count; i++)
            {
                var e = Generator.ProcessStage(Arguments[i].Value, min, max).Value;

                if (min >= MetaStage.Vertex && Expressions.IsVariableOrGlobal(e))
                {
                    map.Add(i, e);
                    continue;
                }

                pl.Add(new Parameter(Arguments[i].Source, AttributeList.Empty,
                                     e.ReturnType is FixedArrayType ? ParameterModifier.Ref : 0, e.ReturnType,
                                     Generator.CreateShaderName(Property, Location, Arguments[i].Value.Value), null));

                al.Add(e);
                map.Add(i, new LoadArgument(e.Source, Method, pl.Count - 1));
            }

            Method.SetParameters(pl.ToArray());

            if (min <= MetaStage.Volatile)
            {
                // See if an equivalent method is already generated on this class scope
                foreach (var m in Generator.Path.DrawBlock.Method.DeclaringType.Methods)
                {
                    if (m.Source == Method.Source &&
                        m.Modifiers == Method.Modifiers &&
                        m.ReturnType == Method.ReturnType &&
                        m.CompareParameters(Method))
                    {
                        return(new StageValue(new CallMethod(m.Source, m.IsStatic ? null : new This(m.Source, m.DeclaringType), m, al.ToArray()), min, max));
                    }
                }

                Generator.Path.DrawBlock.Method.DeclaringType.Methods.Add(Method);
            }
            else
            {
                Method.SetName(Generator.CreateShaderName(Property, Location));
            }

            Method.Body.Visit(new ArgumentResolver(this, map));
            return(new StageValue(new CallMethod(Method.Source, Method.IsStatic ? null : new This(Method.Source, Method.DeclaringType), Method, al.ToArray()), min, max));
        }