Ancestry.QueryProcessor.Type.TupleType.CompileDereference C# (CSharp) Method

CompileDereference() private method

private CompileDereference ( Compiler compiler, Frame frame, ExpressionContext left, Parse expression, Type typeHint ) : ExpressionContext
compiler Compiler
frame Frame
left ExpressionContext
expression Parse
typeHint System.Type
return ExpressionContext
        private ExpressionContext CompileDereference(Compiler compiler, Frame frame, ExpressionContext left, Parse.BinaryExpression expression, Type.BaseType typeHint)
        {
            var local = compiler.AddFrame(frame, expression);
            var native = left.ActualNative(compiler.Emitter);

            LocalBuilder valueVariable = null;

            // Create symbol for each tuple member
            foreach (var a in ((TupleType)left.Type).Attributes)
            {
                var field = native.GetField(a.Key.ToString(), BindingFlags.Public | BindingFlags.Instance);
                local.Add(expression, a.Key, field);
                compiler.ContextsBySymbol.Add
                (
                    field,
                    new ExpressionContext
                    (
                        null,
                        a.Value,
                        Characteristic.Default,
                        m =>
                        {
                            m.IL.Emit(OpCodes.Ldloc, valueVariable);
                            m.IL.Emit(OpCodes.Ldfld, field);
                        }
                    )
                );
            }

            var right = compiler.CompileExpression(local, expression.Right, typeHint);

            return
                new ExpressionContext
                (
                    expression,
                    right.Type,
                    Compiler.MergeCharacteristics(left.Characteristics, right.Characteristics),
                    m =>
                    {
                        m.IL.BeginScope();

                        left.EmitGet(m);
                        valueVariable = m.DeclareLocal(expression.Right, native, "value");
                        m.IL.Emit(OpCodes.Stloc, valueVariable);

                        right.EmitGet(m);

                        m.IL.EndScope();
                    }
                );
        }