Пример #1
0
        public static JMemberExpression EntityMethodToJsFunctionRef(IMethod me)
        {
            var ownerType = me.GetDeclaringTypeDefinition();

            if (JMeta.IsGlobalMethod(me))
            {
                var member = J.Member(JNaming.JName(me));
                return(member);
            }
            else
            {
                var member = JNaming.JAccess(ownerType);
                if (!me.IsStatic)
                {
                    if (JMeta.IsNativeType(ownerType))
                    {
                        member = member.Member("prototype");
                    }
                    else
                    {
                        member = member.Member("commonPrototype");
                    }
                }
                member = member.Member(JNaming.JName(me));
                return(member);
            }
        }
Пример #2
0
        public JNode VisitMemberResolveResult(MemberResolveResult res)
        {
            var   me = res.Member;
            JNode node2;
            bool  enumValuesAsNames;

            if (me == null) //TODO: dynamics
            {
                throw new NotImplementedException();
                //var node3 = Js.Member(node.MemberName);
                //if (node.Target != null)
                //    node3.PreviousMember = VisitExpression(node.Target);
                //return node3;
            }
            else if (IsEntityFunctionProperty(res.Member, res))//(Entity)node.entity))
            {
                var pe  = (IProperty)me;
                var xxx = new CSharpInvocationResolveResult(res.TargetResult, pe.Getter, null);
                node2 = Visit(xxx);
                return(node2);
            }
            else if (me.IsEnumMember() && JMeta.UseJsonEnums(me, out enumValuesAsNames))
            {
                var me2 = (IField)me;
                if (enumValuesAsNames)
                {
                    return(J.String(JNaming.JName(me2)));
                }
                else
                {
                    return(J.Value(me2.ConstantValue));
                }
            }
            //TODO: Support a way to override this (JsField.ConstantInlining=false)
            else if (res.IsCompileTimeConstant && !me.IsEnumMember())
            {
                return(J.Value(res.ConstantValue));
            }
            else
            {
                var node3 = JNaming.JAccess(me);
                node2 = node3;
                if (res.TargetResult != null && !me.IsStatic())
                {
                    var instanceContext = VisitExpression(res.TargetResult);
                    if (node3.Name.IsNullOrEmpty()) //support Name=""
                    {
                        node2 = instanceContext;
                    }
                    else
                    {
                        node3.PreviousMember = instanceContext;
                    }
                }
            }
            return(node2);
        }
Пример #3
0
        public JNode VisitTypeIsResolveResult(TypeIsResolveResult res)
        {
            var typeDef = res.TargetType.GetDefinitionOrArrayType(Compiler);
            //if (Sk.OmitCasts(typeDef))
            //{
            //    return J.True();
            //    //var node2 = Visit(res.Input);
            //    //return node2;
            //}
            //else
            //{
            var node2 = VisitExpression(res.Input).InstanceOf(JNaming.JAccess(res.TargetType));

            return(node2);
            //}
        }
Пример #4
0
        public JNode VisitConstantResolveResult(ConstantResolveResult res)
        {
            var nodes = res.GetNodes();

            if (res.Type is DefaultTypeParameter)
            {
                return(J.Member("Default").Invoke(JNaming.JAccess(res.Type)));
            }
            if (res.Type != null && res.Type.Kind == TypeKind.Enum)
            {
                return(Visit(JTypeImporter.GetValueTypeInitializer(res.Type, Compiler)));
            }
            //var nodes = res.GetNodes();
            //if (nodes.IsNotNullOrEmpty())
            //{
            //    var node = nodes[0];
            //    if (node != null && node is PrimitiveExpression)
            //    {
            //        var node2 = Visit(node); //use literal value instead
            //        return node2;
            //    }
            //}
            return(J.Value(res.ConstantValue));
        }
Пример #5
0
        private JNode VisitInvocationResolveResult(CSharpInvocationResolveResult res)
        {
            ////TODO: LET LINQ
            //var firstNode = res.GetFirstNode();
            //if (firstNode != null && firstNode is QueryLetClause)
            //{
            //    foreach (var arg in res.Arguments)
            //    {
            //        if (arg.GetInfo() == null)
            //            arg.SetInfo(new ResolveResultInfo { Nodes = { firstNode } });
            //    }
            //}
            var member = res.Member;
            var me     = member as IMethod;

            if (me == null)
            {
                var pe = member as IProperty;
                if (pe != null)
                {
                    me     = pe.Getter;
                    member = me;
                }
            }
            var att = me != null?JMeta.GetJMethodAttribute(me) : null;

            if (att != null && att.InlineCode != null)
            {
                return(J.Code(att.InlineCode));
            }
            //TODO: move defines locally
            var condAtt = me.GetMetadata <System.Diagnostics.ConditionalAttribute>();

            if (condAtt != null && Compiler != null && Compiler.Defines != null && !Compiler.Defines.Contains(condAtt.ConditionString))
            {
                return(null);
            }
            if (att != null && att.OmitCalls)
            {
                if (me.IsStatic() && !me.IsExtensionMethod)
                {
                    return(null);
                }
                if (me.IsExtensionMethod && !res.IsExtensionMethodInvocation)
                {
                    return(null);
                }
                if (res.Arguments.IsEmpty() && res.TargetResult != null)
                {
                    return(VisitExpression(res.TargetResult));
                }
                return(Visit(res.Arguments[0]));
            }
            var jsMember = JNaming.JAccess(member);

            if (res.TargetResult != null && !member.IsStatic() && member.SymbolKind != SymbolKind.Constructor) //TargetResult==null when ctor
            {
                var target = VisitExpression(res.TargetResult);
                if (jsMember.PreviousMember != null)
                {
                    throw new NotSupportedException();
                }
                jsMember.PreviousMember = target;
            }
            var bindings = res.GetArgumentsForCall2();

            if (JMeta.OmitOptionalParameters(me))
            {
                bindings.RemoveAll(t => t.ArgResult == null);
            }
            if (JMeta.IsNativeParams(me))
            {
                var binding = bindings.Where(t => t.Parameter.IsParams).FirstOrDefault();
                if (binding != null)
                {
                    if (binding.CallResult is ArrayCreateResolveResult)
                    {
                        var arrayRes = (ArrayCreateResolveResult)binding.CallResult;
                        bindings.Remove(binding);
                        if (arrayRes.InitializerElements.IsNotNullOrEmpty())
                        {
                            foreach (var init in arrayRes.InitializerElements)
                            {
                                var b = binding.Clone();
                                b.CallResult = init;
                                bindings.Add(b);
                            }
                        }
                    }
                    else
                    {
                        Log.Warn(res.GetFirstNode(), "Invalid params parameter passed to method with NativeParams=true");
                    }
                }
            }
            var        byRefs    = new List <ByReferenceResolveResult>();
            List <int> refToRefs = new List <int>();
            var        c         = 0;

            foreach (var binding in bindings)
            {
                var byRef = binding.CallResult as ByReferenceResolveResult;
                if (byRef == null)
                {
                    c++;
                    continue;
                }
                var x = byRef.ElementResult as LocalResolveResult;
                if (x != null && x.Variable != null && x.Variable.Type.Kind == TypeKind.ByReference)
                {
                    if (binding.Parameter.IsRef || binding.Parameter.IsOut)
                    {
                        refToRefs.Add(c);
                    }
                    c++;
                    continue;
                }
                byRefs.Add(byRef);
                c++;
            }
            var callArgs = bindings.Select(t => t.CallResult).ToList();
            var node2    = new JInvocationExpression
            {
                Member    = jsMember,
                Arguments = VisitExpressions(callArgs),
            };

            foreach (var i in refToRefs)
            {
                JMemberExpression jsmex = node2.Arguments[i] as JMemberExpression;
                if (jsmex != null)
                {
                    node2.Arguments[i] = jsmex.PreviousMember;//remove the .Value ref wrapper
                }
            }
            if (me != null && me.IsExtensionMethod && res.IsExtensionMethodInvocation && JMeta.ExtensionImplementedInInstance(me))
            {
                var arg = node2.Arguments[0];
                node2.Arguments.RemoveAt(0);
                if (jsMember.PreviousMember != null)
                {
                    throw new NotImplementedException();
                }
                jsMember.PreviousMember = arg;
            }

            TransformIntoBaseMethodCallIfNeeded(res, node2);
            if (att != null)
            {
                if (att.OmitParanthesis)
                {
                    node2.OmitParanthesis = true;
                }
                if (node2.Arguments == null)
                {
                    node2.Arguments = new List <JExpression>();
                }
                if (att.InsertArg2 != null)
                {
                    node2.Arguments.InsertOrAdd(2, new JCodeExpression {
                        Code = att.InsertArg2.ToString()
                    });
                }
                if (att.InsertArg1 != null)
                {
                    node2.Arguments.InsertOrAdd(1, new JCodeExpression {
                        Code = att.InsertArg1.ToString()
                    });
                }
                if (att.InsertArg0 != null)
                {
                    node2.Arguments.InsertOrAdd(0, new JCodeExpression {
                        Code = att.InsertArg0.ToString()
                    });
                }
                node2.OmitCommas      = att.OmitCommas;
                node2.ArgumentsPrefix = att.ArgumentsPrefix;
                node2.ArgumentsSuffix = att.ArgumentsSuffix;
                if (att.InstanceImplementedAsExtension)
                {
                    var ext = (JMemberExpression)node2.Member;
                    node2.Arguments.Insert(0, ext.PreviousMember);
                    ext.PreviousMember = null;
                }
            }


            //if (me != null && me is SpecializedMethod && !Sk.IgnoreGenericMethodArguments(me))
            //{
            //    List<JsExpression> genericArgs;
            //    if (me.IsConstructor)
            //    {
            //        var ce = me.DeclaringType as ParameterizedType;
            //        if (ce != null)
            //            genericArgs = ce.TypeArguments.Select(t => SkJs.EntityTypeRefToMember(t, true)).ToList();
            //        else
            //            genericArgs = new List<JsExpression>();
            //    }
            //    else
            //    {
            //        var sme = (SpecializedMethod)me;
            //        genericArgs = sme.TypeArguments.Select(t => SkJs.EntityTypeRefToMember(t, true)).ToList();
            //    }
            //    if (node2.Arguments == null)
            //        node2.Arguments = new List<JsExpression>(genericArgs);
            //    else
            //        node2.Arguments.InsertRange(0, genericArgs);
            //}
            if (att != null && att.OmitDotOperator)
            {
                if (node2.Member is JMemberExpression && node2.Arguments.Count == 1 && att.OmitParanthesis)
                {
                    var meNode = (JMemberExpression)node2.Member;
                    var node3  = new JBinaryExpression {
                        Left = meNode.PreviousMember, Operator = meNode.Name, Right = node2.Arguments[0]
                    };
                    return(node3);
                }
                else
                {
                    Log.Warn(res.GetFirstNode(), "TODO:OmitDotOperator is not supported in this syntax.");
                }
            }
            if (node2.Member is JMemberExpression)
            {
                var x = (JMemberExpression)node2.Member;
                if (x.Name.IsNullOrEmpty() && jsMember.PreviousMember != null)
                {
                    node2.Member = x.PreviousMember;
                }
            }
            if (res.Member.SymbolKind == SymbolKind.Indexer && JMeta.UseNativeIndexer((IProperty)res.Member))
            {
                var node3 = new JIndexerAccessExpression
                {
                    Member    = node2.Member,
                    Arguments = node2.Arguments,
                };

                return(node3);
            }

            if (byRefs.IsNotNullOrEmpty())
            {
                var func = J.Function();
                foreach (var byRef in byRefs)
                {
                    func.Add(J.Assign(VisitExpression(byRef), J.Json().Add("Value", VisitExpression(byRef))).Statement());
                }
                func.Add(J.Var("$res", res.Type.JAccess(), node2).Statement());
                foreach (var byRef in byRefs)
                {
                    func.Add(J.Assign(VisitExpression(byRef), VisitExpression(byRef).Member("Value")).Statement());
                }
                func.Add(J.Return(J.Member("$res")));
                var node5 = WrapFunctionAndInvoke(res, func.Block);
                return(node5);
            }


            return(node2);
        }
Пример #6
0
 private JNode VisitConversion(ResolveResult input, Conversion conversion, IType conversionType)
 {
     ////TODO: HACK: https://github.com/icsharpcode/NRefactory/issues/183
     //var isImplicit = res.Conversion.IsImplicit;
     //if (!isImplicit && res.Conversion.IsExplicit && res.Conversion.Method != null && res.Conversion.Method.Name != null && res.Conversion.Method.Name.Contains("Implicit"))
     //    isImplicit = true;
     if (conversion.IsMethodGroupConversion)
     {
         var me      = conversion.Method;
         var delType = conversionType;
         var exp     = me.JAccess().Invoke(me.Parameters.Select(t => J.Member(t.Name)).ToArray());
         var st      = J.Return(exp);
         var block   = J.Block().Add(st);
         var del2    = CreateDelegate(delType, me.Parameters, me.ReturnType, block);
         return(del2);
         //J.CreateDelegate(conversionType.JAccess(), me.Parameters.Select(t=>t.Acc
         //TODO:  J.CreateDelegate(conversionType.JAccess(),
     }
     else if (conversion.IsUserDefined)
     {
         ITypeDefinition typeDef;
         if (conversion.Method != null && conversion.Method.DeclaringType != null)
         {
             typeDef = conversion.Method.DeclaringType.GetDefinitionOrArrayType(Compiler);
         }
         else
         {
             typeDef = conversionType.GetDefinitionOrArrayType(Compiler);
         }
         var nativeOverloads = JMeta.UseNativeOperatorOverloads(typeDef);
         if (nativeOverloads)
         {
             return(Visit(input));
         }
         var fake  = conversion.Method.InvokeMethod(null, input);
         var node2 = Visit(fake);
         return(node2);
     }
     else if (conversion.IsTryCast || conversion.IsExplicit)
     {
         var typeDef   = conversionType.GetDefinitionOrArrayType(Compiler);
         var omitCasts = JMeta.OmitCasts(typeDef, Project);
         if (omitCasts)
         {
             return(Visit(input));
         }
         if (true)//Sk.NativeCasts(typeDef))
         {
             var exp2  = VisitExpression(input);
             var type2 = JNaming.JAccess(conversionType);
             if (conversion.IsTryCast)
             {
                 var node2 = exp2.InstanceOf(type2).Conditional(exp2, J.Null());
                 return(node2);
             }
             else
             {
                 return(J.Cast(exp2, type2));
             }
         }
         //else
         //{
         //    var cast = conversion.IsTryCast ? "As" : "Cast";
         //    var node2 = J.Member(cast).Invoke(VisitExpression(input), JNaming.JAccess(conversionType));
         //    return node2;
         //}
     }
     return(Visit(input));
 }
Пример #7
0
 public JNode VisitTypeResolveResult(TypeResolveResult res)
 {
     return(JNaming.JAccess(res.Type));
     //throw new NotImplementedException();
 }
Пример #8
0
 public JNode VisitTypeOfResolveResult(TypeOfResolveResult res)
 {
     return(J.Member("Typeof").Invoke(JNaming.JAccess(res.ReferencedType)));
 }
Пример #9
0
        public JNode VisitMethodGroupResolveResult(MethodGroupResolveResult res)
        {
            var     info = res.GetInfo();
            IMethod me;

            if (info != null && info.Conversion != null && info.Conversion.Method != null)
            {
                me = info.Conversion.Method;
            }
            else //happens when invoking a method with overloads, and a parameter is dynamic
            {
                var list = res.Methods.ToList();
                if (list.Count == 0)
                {
                    throw new Exception("Method group not resolved to any method");
                }
                else if (list.Count == 1)
                {
                    me = list[0];
                }
                else
                {
                    me = list[0];
                }
                //TODO: verify all methods has the same js name
            }
            var         isExtensionMethodStyle = me.IsExtensionMethod && !(res.TargetResult is TypeResolveResult);//TODO: IsExtensionMethodStyle(new CsInvocationExpression { entity = me, expression = node });
            JExpression firstPrm = null;

            if (isExtensionMethodStyle)
            {
                firstPrm = (JExpression)Visit(res.TargetResult);
            }
            var         node2 = JNaming.JAccess(me);
            JExpression node3;
            JExpression instanceContext = null;

            if (me.IsStatic || res.TargetResult == null) //getting ThisResolveResult even on static methods, getting TargetResult=null when MethodGroupResolveResult when using delegates
            {
                node3 = node2;
            }
            else
            {
                instanceContext = VisitExpression(res.TargetResult);
                node3           = instanceContext.Member(node2);
            }
            if (info != null && (instanceContext != null || firstPrm != null))
            {
                var conv = info.Conversion;
                if (info.ConversionTargetType != null && !UseNativeFunctions(info.ConversionTargetType))//delegate type
                {
                    var parentMethod = info.Nodes.FirstOrDefault().GetCurrentMethod();
                    if (parentMethod == null || !JMeta.ForceDelegatesAsNativeFunctions(parentMethod))
                    {
                        if (parentMethod == null)
                        {
                            Log.Warn(info.Nodes.FirstOrDefault(), "GetParentMethod() returned null");
                        }
                        var func = (JExpression)node2;
                        if (instanceContext != null)
                        {
                            node3 = CreateJsDelegate(instanceContext, func);
                        }
                        else if (firstPrm != null)
                        {
                            node3 = CreateJsExtensionDelegate(firstPrm, func);
                        }
                    }
                }
            }
            return(node3);
        }
Пример #10
0
        protected JBlock ExportMethodBody(IMethod me)
        {
            if (me.DeclaringTypeDefinition.IsInterface())
            {
                return(null);
            }
            if (CompilerConfig.Current.EnableLogging)
            {
                Log.Debug("JsTypeImporter: Visit Method: " + me.ToString());
            }
            var nativeCode = JMeta.GetNativeCode(me);

            if (nativeCode != null)
            {
                var block = J.Block().Add(J.Code(nativeCode).Statement()); //TODO: double semicolon?
                var x     = block.ToJs();
                return(block);
            }
            var def = me.GetDefinition();

            if (def == null || def.IsNull)
            {
                if (me.DeclaringTypeDefinition.IsDelegate())
                {
                    var block = J.Block();
                    if (!me.ReturnType.IsVoid())
                    {
                        block.Add(J.Return(J.Null()));
                    }
                    return(block);
                }
                if (me.IsAutomaticEventAccessor())
                {
                    if (me.IsEventAddAccessor())
                    {
                        var node = GenerateAutomaticEventAccessor((IEvent)me.GetOwner(), false);
                        return(node.Block);
                    }
                    else if (me.IsEventRemoveAccessor())
                    {
                        var node = GenerateAutomaticEventAccessor((IEvent)me.GetOwner(), true);
                        return(node.Block);
                    }
                }
                else if (me.IsAutomaticPropertyAccessor())
                {
                    var bf = J.Member(JNaming.JName(me.AccessorOwner).ToJavaNaming());
                    if (!me.IsStatic)
                    {
                        bf.PreviousMember = J.This();
                    }
                    else if (!JMeta.IsGlobalMethod(me))
                    {
                        bf.PreviousMember = JNaming.JAccess(me.DeclaringType);
                    }
                    if (me.IsGetter())
                    {
                        return(J.Block().Add(J.Return(bf)));
                    }
                    else
                    {
                        return(J.Block().Add(bf.Assign(J.Member("value")).Statement()));
                    }
                }
                return(null);
            }
            var block2 = (JBlock)JsCodeImporter.Visit(def);

            if (def.Descendants.OfType <YieldReturnStatement>().FirstOrDefault() != null)
            {
                if (!JsCodeImporter.SupportClrYield)
                {
                    if (block2.Statements == null)
                    {
                        block2.Statements = new List <JStatement>();
                    }
                    var arg      = me.ReturnType.TypeArguments[0].JAccess();
                    var listType = J.Members("java.util.ArrayList").AddGenericArg(arg);
                    var yieldVar = J.Var("$yield", listType, J.New(listType)).Statement();
                    block2.Statements.Insert(0, yieldVar);
                    block2.Statements.Add(JCodeImporter.GenerateYieldReturnStatement(me));
                }
            }
            return(block2);
        }