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