public void VisitBinaryExpression(JBinaryExpression node) { Visit(node.Left); Write(" "); Write(node.Operator); Write(" "); Visit(node.Right); }
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); }
public JNode VisitOperatorResolveResult(OperatorResolveResult res) { if (res.Operands.Count == 1) { if (res.UserDefinedOperatorMethod != null && !JMeta.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition)) { var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0]); return(Visit(fake)); } var isProperty = false; var meRes = res.Operands[0] as MemberResolveResult; if (meRes != null && meRes.Member != null && IsEntityFunctionProperty(meRes.Member, res)) { isProperty = true; } JExpression node2; if (res.OperatorType == System.Linq.Expressions.ExpressionType.Negate || res.OperatorType == System.Linq.Expressions.ExpressionType.PreDecrementAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.PreIncrementAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.Not || res.OperatorType == System.Linq.Expressions.ExpressionType.OnesComplement) { var simpler = res.OperatorType.ExtractCompoundAssignment(); if (isProperty && simpler != null) { var fakeCs = meRes.Member.AccessSelf().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JPreUnaryExpression { Operator = Visit(res.OperatorType), Right = VisitExpression(res.Operands[0]) }; } } else if (res.OperatorType == System.Linq.Expressions.ExpressionType.PostIncrementAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.PostDecrementAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.PreIncrementAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.PreDecrementAssign) { if (isProperty) { var simpler = res.OperatorType.ExtractCompoundAssignment(); var fakeCs = meRes.Member.AccessSelf().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JPostUnaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]) }; } } else { throw new NotImplementedException(); } return(node2); } else if (res.Operands.Count == 2) { if (res.UserDefinedOperatorMethod != null && !JMeta.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition)) { var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0], res.Operands[1]); return(Visit(fake)); } if (res.OperatorType == System.Linq.Expressions.ExpressionType.Coalesce) { var fake = Cs.Conditional(res.Operands[0].NotEqual(Cs.Null(), Project), res.Operands[0], res.Operands[1], res.Type); var fake2 = Visit(fake); fake2 = new JParenthesizedExpression { Expression = (JExpression)fake2 }; return(fake2); } var mrrOp0 = res.Operands[0] as MemberResolveResult; if (mrrOp0 != null && mrrOp0.Member.SymbolKind == SymbolKind.Event) { var pe = (IEvent)mrrOp0.Member; if (res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.SubtractAssign) { var accessor = res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign ? pe.AddAccessor : pe.RemoveAccessor; var fake = new CSharpInvocationResolveResult(mrrOp0.TargetResult, accessor, new List <ResolveResult> { res.Operands[1] }); var node6 = Visit(fake); return(node6); } } if (mrrOp0 != null && IsEntityFunctionProperty(mrrOp0.Member, res)) { var compOpType = res.OperatorType.ExtractCompoundAssignment(); var pe = (IProperty)mrrOp0.Member; if (compOpType != null) { var fake = new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Setter, new List <ResolveResult> { new OperatorResolveResult(res.Type, compOpType.Value, new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Getter, null), res.Operands[1]) }); var node6 = Visit(fake); return(node6); } else if (res.OperatorType == System.Linq.Expressions.ExpressionType.Assign) { var args = new List <ResolveResult>(); if (pe.IsIndexer) { var irrOp0 = (CSharpInvocationResolveResult)res.Operands[0]; args.AddRange(irrOp0.Arguments); } args.Add(res.Operands[1]); var fake = new CSharpInvocationResolveResult(mrrOp0.TargetResult, pe.Setter, args).AssociateWithOriginal(res); var node6 = Visit(fake); node6 = WrapSetterToReturnValueIfNeeded(res, node6); return(node6); } } if (res.Operands[0] is ConversionResolveResult && res.Operands[1] is ConstantResolveResult) { var leftConv = (ConversionResolveResult)res.Operands[0]; var rightConst = (ConstantResolveResult)res.Operands[1]; if (leftConv.Conversion.IsNumericConversion && leftConv.Input.Type == Cs.CharType(Project)) { var value = ((char)(int)rightConst.ConstantValue).ToString(); var fake = Cs.Binary(leftConv.Input, res.OperatorType, Cs.Value(value, Project), leftConv.Input.Type); return(Visit(fake)); } } if (res.Operands[0].Type.Kind == TypeKind.Delegate && res.Operands[1].Type.Kind == TypeKind.Delegate) { if (res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign || res.OperatorType == System.Linq.Expressions.ExpressionType.SubtractAssign) { var op = res.OperatorType == System.Linq.Expressions.ExpressionType.AddAssign ? System.Linq.Expressions.ExpressionType.Add : System.Linq.Expressions.ExpressionType.Subtract; var fake = Cs.Assign(res.Operands[0], Cs.Binary(res.Operands[0], op, res.Operands[1], res.Type)); var node6 = Visit(fake); return(node6); } else if (res.OperatorType == System.Linq.Expressions.ExpressionType.Add || res.OperatorType == System.Linq.Expressions.ExpressionType.Subtract) { var combineMethod = Compiler.Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Combine").FirstOrDefault(); var removeMethod = Compiler.Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Remove").FirstOrDefault(); var meOp = res.OperatorType == System.Linq.Expressions.ExpressionType.Add ? combineMethod : removeMethod; var fake = Cs.Member(null, meOp).Invoke(res.Operands[0], res.Operands[1]); var node6 = Visit(fake); return(node6); } } var node5 = new JBinaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]), Right = VisitExpression(res.Operands[1]) }; if (res.OperatorType == System.Linq.Expressions.ExpressionType.Equal && node5.Operator == "==") { var att = JMeta.GetJsExportAttribute(Project.Compilation.MainAssembly); if (att != null && att.UseExactEquals) { node5.Operator = "==="; } } if (res.OperatorType == System.Linq.Expressions.ExpressionType.NotEqual && node5.Operator == "!=") { var att = JMeta.GetJsExportAttribute(Project.Compilation.MainAssembly); if (att != null && att.UseExactEquals) { node5.Operator = "!=="; } } return(node5); } else if (res.Operands.Count == 3) { if (res.OperatorType == System.Linq.Expressions.ExpressionType.Conditional) { var node5 = new JConditionalExpression { Condition = VisitExpression(res.Operands[0]), TrueExpression = VisitExpression(res.Operands[1]), FalseExpression = VisitExpression(res.Operands[2]) }; return(node5); } else { throw new NotImplementedException(); } } else { throw new NotImplementedException(); } }