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); }