예제 #1
0
 public NoSuchMemberException(RelinqScriptExpression root, MemberAccessExpression mae, RelinqScriptType typeOfTarget)
     : base(mae.Parent is InvokeExpression && mae.ChildIndex == 0 ?
                                                                      JSToCSharpExceptionType.NoSuchMethod :
                                                                                                               JSToCSharpExceptionType.NoSuchFieldOrProp, root, mae)
 {
     InferredTypeOfTarget = typeOfTarget;
     MemberName = mae.Name;
 }
예제 #2
0
        private void InferMemberAccess(MemberAccessExpression mae, TypeInferenceCache cache)
        {
            InferTypes(mae.Target, cache);
            var typeofTarget = cache[mae.Target];

            if (typeofTarget is ClrType)
            {
                // nb: the member access also covers method group lookup
                // i.e. object.Method(arg1, arg2) is in fact resolved in two steps:
                // 1) object.Method -> resolves to all instance or extension methods
                //    (on this step fields and properties are omitted because the expression
                //    is being used in the context of an invocation)
                // 2) MG(arg1, arg2) -> picks up the best method from the MG that matches arglist

                var usedInContextOfInvocation = mae.Parent is InvokeExpression && mae.ChildIndex == 0;
                cache.Add(mae, usedInContextOfInvocation ? 
                    typeofTarget.LookupMethodGroup(mae.Name) : 
                    typeofTarget.LookupMemberAccess(mae.Name));

                if (cache[mae] == null)
                {
                    throw new NoSuchMemberException(Root, mae, typeofTarget);
                }
            }
            else if (typeofTarget is Variant)
            {
                cache.Add(mae, new Variant());
            }
            else
            {
                throw new NoSuchMemberException(Root, mae, typeofTarget);
            }
        }
예제 #3
0
        private LinqExpression CompileMemberAccess(MemberAccessExpression mae, CompilationContext ctx)
        {
            if (ctx.Types[mae] is ClrType)
            {
                var clrType = ((ClrType)ctx.Types[mae.Target]).Type;
                if (clrType.IsArray && mae.Name == "Length")
                {
                    return LinqExpression.ArrayLength(Compile(mae.Target, ctx));
                }
                else
                {
                    var fop = clrType.GetFieldOrProperty(mae.Name);
                    //no validation for fop != null and being only of 2 possible types - I'm sick & tired!
                    return fop is FieldInfo ?
                        LinqExpression.Field(Compile(mae.Target, ctx), (FieldInfo)fop) :
                        LinqExpression.Property(Compile(mae.Target, ctx), (PropertyInfo)fop);
                }
            }
            else if (ctx.Types[mae] is MethodGroup)
            {
                // we have three variants here:
                // 1) mae is a target of an Invoke -> note. processed, but not here
                // 2) mae is an argument of a call -> we need to emit a CreateDelegate stuff
                // 3) mae is a branch of a conditional -> same as 2

                var expected = AcquireExpectedTypeFromContext(mae, ctx);
                if (!expected.IsDelegate())
                {
                    throw new CSharpBuilderException(
                        JSToCSharpExceptionType.UnexpectedInferredAst, Ast, mae, ctx);
                }

                var createDelegate = typeof(Delegate).GetMethod("CreateDelegate", new []{
                    typeof(Type), typeof(Object), typeof(MethodInfo)});
                return LinqExpression.Call(createDelegate, new []{
                    LinqExpression.Constant(expected, typeof(Type)), 
                    Compile(mae.Target, ctx),
                    LinqExpression.Constant(ctx.Invocations[mae], typeof(MethodInfo))});
            }
            else
            {
                throw new CSharpBuilderException(
                    JSToCSharpExceptionType.UnexpectedInferredAst, Ast, mae, ctx);
            }
        }