Beispiel #1
0
        public ArgumentsInfo(IEmitter emitter, AssignmentExpression assignmentExpression, OperatorResolveResult operatorResolveResult, IMethod method)
        {
            this.Emitter = emitter;
            this.Expression = assignmentExpression;
            this.OperatorResolveResult = operatorResolveResult;

            this.BuildOperatorArgumentsList(new Expression[] { assignmentExpression.Left, assignmentExpression.Right }, operatorResolveResult.UserDefinedOperatorMethod ?? method);
            this.BuildOperatorTypedArguments();
        }
        private JsNode Trinary(OperatorResolveResult res)
        {
            if (res.OperatorType == ExpressionType.Conditional)
            {
                var node5 = new JsConditionalExpression { Condition = VisitExpression(res.Operands[0]), TrueExpression = VisitExpression(res.Operands[1]), FalseExpression = VisitExpression(res.Operands[2]) };
                return node5;

            }
            else
                throw new NotImplementedException();
        }
        /// <summary>
        /// https://github.com/icsharpcode/NRefactory/issues/501
        /// </summary>
        OperatorResolveResult WorkaroundIssue501(OperatorResolveResult res)
        {
            if (res.UserDefinedOperatorMethod == null)
                return res;
            if ((res.OperatorType == ExpressionType.AndAlso && res.UserDefinedOperatorMethod.Name == "op_BitwiseAnd") ||
                (res.OperatorType == ExpressionType.OrElse && res.UserDefinedOperatorMethod.Name == "op_BitwiseOr"))
            {
                var fake = new OperatorResolveResult(res.Type, res.OperatorType, null, res.IsLiftedOperator, res.Operands);
                return fake;

            }
            return res;
        }
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                        new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return true;
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    if (orr.IsLiftedOperator)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.lift(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter,
                        new Expression[] {binaryOperatorExpression.Left, binaryOperatorExpression.Right}, null).Emit();
                    this.WriteCloseParentheses();

                    return true;
                }
            }

            return false;
        }
Beispiel #5
0
        public ArgumentsInfo(IEmitter emitter, BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult operatorResolveResult)
        {
            this.Emitter = emitter;
            this.Expression = binaryOperatorExpression;
            this.OperatorResolveResult = operatorResolveResult;

            if (operatorResolveResult.UserDefinedOperatorMethod != null)
            {
                this.BuildOperatorArgumentsList(new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right });
                this.BuildOperatorTypedArguments();
            }
            else
            {
                this.ArgumentsExpressions = new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right };
                this.ArgumentsNames = new string[] { "left", "right" };
                this.CreateNamedExpressions(this.ArgumentsNames, this.ArgumentsExpressions);
            }
        }
 public JsNode VisitOperatorResolveResult(OperatorResolveResult res)
 {
     if (res.Operands.Count == 1)
         return Unary(res);
     else if (res.Operands.Count == 2)
     {
         var node2 = Binary(res);
         if (Importer.ForceIntegers)
         {
             if (Importer.IsInteger(res.Type) && res.OperatorType == ExpressionType.Divide)
                 node2 = Importer.ForceInteger(node2);
         }
         return node2;
     }
     else if (res.Operands.Count == 3)
         return Trinary(res);
     else
         throw new NotImplementedException();
 }
Beispiel #7
0
        protected bool IsUserOperator(OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    return true;
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    return true;
                }
            }

            return false;
        }
		string Visit(OperatorResolveResult result)
		{
			throw new NotImplementedException();
		}
		Value VisitConditionalOperator(OperatorResolveResult result, BinaryOperatorType bitwiseOperatorType)
		{
			Debug.Assert(result.Operands.Count == 2);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem);
			Value condVal;
			if (bitwiseOperatorType == BinaryOperatorType.BitwiseAnd)
				condVal = Convert(resolver.ResolveConditionFalse(lhs.ToResolveResult(context)));
			else
				condVal = Convert(resolver.ResolveCondition(lhs.ToResolveResult(context)));
			if ((bool)condVal.PrimitiveValue)
				return lhs;
			var rhs = Convert(result.Operands[1]);
			var val = resolver.ResolveBinaryOperator(bitwiseOperatorType, lhs.ToResolveResult(context), rhs.ToResolveResult(context));
			return Convert(val);
		}
		Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 2);
			Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread);
			if (result.UserDefinedOperatorMethod != null)
				return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs);
			var lhsRR = lhs.ToResolveResult(context);
			var rhsRR = rhs.ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			switch (operatorType) {
				case BinaryOperatorType.Equality:
				case BinaryOperatorType.InEquality:
					bool equality = (operatorType == BinaryOperatorType.Equality);
					if (lhsRR.Type.IsKnownType(KnownTypeCode.String) && rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
						if (lhs.IsNull || rhs.IsNull) {
							bool bothNull = lhs.IsNull && rhs.IsNull;
							return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
						} else {
							bool equal = (string)lhs.PrimitiveValue == (string)rhs.PrimitiveValue;
							return Eval.CreateValue(evalThread, equality ? equal : !equal);
						}
					}
					if (lhsRR.Type.IsReferenceType != false && rhsRR.Type.IsReferenceType != false) {
						// Reference comparison
						if (lhs.IsNull || rhs.IsNull) {
							bool bothNull = lhs.IsNull && rhs.IsNull;
							return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
						} else {
							bool equal = lhs.Address == rhs.Address;
							return Eval.CreateValue(evalThread, equality ? equal : !equal);
						}
					}
					goto default;
				case BinaryOperatorType.Add:
					if (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
						var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
							.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
							.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
						return InvokeMethod(null, method, lhs, rhs);
					}
					goto default;
				default:
					throw new GetValueException("Operator {0} is not supported for {1} and {2}!", operatorType, new CSharpAmbience().ConvertType(lhsRR.Type), new CSharpAmbience().ConvertType(rhsRR.Type));
			}
		}
		Value VisitUnaryOperator(OperatorResolveResult result, UnaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 1);
			var operand = Convert(result.Operands[0]).ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveUnaryOperator(operatorType, operand);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			throw new GetValueException("Operator {0} is not supported for {1}!", operatorType, new CSharpAmbience().ConvertType(operand.Type));
		}
		Value VisitTernaryOperator(OperatorResolveResult result)
		{
			Debug.Assert(result.Operands.Count == 3);
			var condition = Convert(result.Operands[0]);
			if (!condition.Type.IsKnownType(KnownTypeCode.Boolean))
				throw new GetValueException("Boolean expression expected!");
			if ((bool)condition.PrimitiveValue)
				return Convert(result.Operands[1]);
			return Convert(result.Operands[2]);
		}
		Value Visit(OperatorResolveResult result)
		{
			switch (result.OperatorType) {
				case ExpressionType.Assign:
					if (!allowSetValue)
						throw new GetValueException("Setting values is not allowed in the current context!");
					Debug.Assert(result.Operands.Count == 2);
					return VisitAssignment((dynamic)result.Operands[0], (dynamic)result.Operands[1]);
				case ExpressionType.Add:
					return VisitBinaryOperator(result, BinaryOperatorType.Add, false);
				case ExpressionType.AddChecked:
					return VisitBinaryOperator(result, BinaryOperatorType.Add, true);
				case ExpressionType.Subtract:
					return VisitBinaryOperator(result, BinaryOperatorType.Subtract, false);
				case ExpressionType.SubtractChecked:
					return VisitBinaryOperator(result, BinaryOperatorType.Subtract, true);
				case ExpressionType.Multiply:
					return VisitBinaryOperator(result, BinaryOperatorType.Multiply, false);
				case ExpressionType.MultiplyChecked:
					return VisitBinaryOperator(result, BinaryOperatorType.Multiply, true);
				case ExpressionType.Divide:
					return VisitBinaryOperator(result, BinaryOperatorType.Divide, false);
				case ExpressionType.Modulo:
					return VisitBinaryOperator(result, BinaryOperatorType.Modulus, false);

				case ExpressionType.And:
					return VisitBinaryOperator(result, BinaryOperatorType.BitwiseAnd);
				case ExpressionType.AndAlso:
					return VisitConditionalOperator(result, BinaryOperatorType.BitwiseAnd);
				case ExpressionType.Or:
					return VisitBinaryOperator(result, BinaryOperatorType.BitwiseOr);
				case ExpressionType.OrElse:
					return VisitConditionalOperator(result, BinaryOperatorType.BitwiseOr);
				case ExpressionType.ExclusiveOr:
					return VisitBinaryOperator(result, BinaryOperatorType.ExclusiveOr);
				case ExpressionType.Not:
					return VisitUnaryOperator(result, UnaryOperatorType.Not);
//				case ExpressionType.OnesComplement:
					

				case ExpressionType.LeftShift:
					return VisitBinaryOperator(result, BinaryOperatorType.ShiftLeft);
				case ExpressionType.RightShift:
					return VisitBinaryOperator(result, BinaryOperatorType.ShiftRight);
					
				case ExpressionType.Equal:
					return VisitBinaryOperator(result, BinaryOperatorType.Equality);
				case ExpressionType.NotEqual:
					return VisitBinaryOperator(result, BinaryOperatorType.InEquality);
				case ExpressionType.GreaterThan:
					return VisitBinaryOperator(result, BinaryOperatorType.GreaterThan);
				case ExpressionType.GreaterThanOrEqual:
					return VisitBinaryOperator(result, BinaryOperatorType.GreaterThanOrEqual);
				case ExpressionType.LessThan:
					return VisitBinaryOperator(result, BinaryOperatorType.LessThan);
				case ExpressionType.LessThanOrEqual:
					return VisitBinaryOperator(result, BinaryOperatorType.LessThanOrEqual);
				case ExpressionType.Conditional:
					return VisitTernaryOperator(result);
				default:
					throw new GetValueException("Unsupported operator: " + result.OperatorType);
			}
		}
Beispiel #14
0
        public ArgumentsInfo(IEmitter emitter, UnaryOperatorExpression unaryOperatorExpression, OperatorResolveResult operatorResolveResult)
        {
            this.Emitter = emitter;
            this.Expression = unaryOperatorExpression;
            this.OperatorResolveResult = operatorResolveResult;

            if (operatorResolveResult.UserDefinedOperatorMethod != null)
            {
                this.BuildOperatorArgumentsList(new Expression[] { unaryOperatorExpression.Expression });
                this.BuildOperatorTypedArguments();
            }
            else
            {
                this.ArgumentsExpressions = new Expression[] { unaryOperatorExpression.Expression };
                this.ArgumentsNames = new string[] { "arg" };
                this.CreateNamedExpressions(this.ArgumentsNames, this.ArgumentsExpressions);
            }
        }
Beispiel #15
0
        public ArgumentsInfo(IEmitter emitter, UnaryOperatorExpression unaryOperatorExpression, OperatorResolveResult operatorResolveResult, IMethod method)
        {
            this.Emitter = emitter;
            this.Expression = unaryOperatorExpression;
            this.OperatorResolveResult = operatorResolveResult;

            this.BuildOperatorArgumentsList(new Expression[] { unaryOperatorExpression.Expression }, operatorResolveResult.UserDefinedOperatorMethod ?? method);
            this.BuildOperatorTypedArguments();
        }
		Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 2);
			Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread);
			if (result.UserDefinedOperatorMethod != null)
				return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs);
			var lhsRR = lhs.ToResolveResult(context);
			var rhsRR = rhs.ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			if (operatorType == BinaryOperatorType.Add &&
			    (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String))) {
				var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
					.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
					.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
				return InvokeMethod(null, method, lhs, rhs);
			}
			throw new InvalidOperationException();
		}
		Value VisitUnaryOperator(OperatorResolveResult result, UnaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 1);
			var operand = Convert(result.Operands[0]).ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveUnaryOperator(operatorType, operand);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			throw new InvalidOperationException();
		}
        private JsNode Unary(OperatorResolveResult res)
        {
            if (res.UserDefinedOperatorMethod != null && !Sk.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;

            JsExpression node2;
            if (res.OperatorType.IsAny(ExpressionType.Negate, ExpressionType.PreDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.Not, ExpressionType.OnesComplement))
            {
                var simpler = res.OperatorType.ExtractCompoundAssignment();
                if (isProperty && simpler != null)
                {
                    var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type);
                    node2 = VisitExpression(fakeCs);
                }
                else
                {
                    node2 = new JsPreUnaryExpression { Operator = Visit(res.OperatorType), Right = VisitExpression(res.Operands[0]) };
                }
            }
            else if (res.OperatorType.IsAny(ExpressionType.PostIncrementAssign, ExpressionType.PostDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.PreDecrementAssign))
            {
                if (isProperty)
                {
                    var simpler = res.OperatorType.ExtractCompoundAssignment();
                    var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type);
                    node2 = VisitExpression(fakeCs);

                }
                else
                {
                    node2 = new JsPostUnaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]) };
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return node2;
        }
        private JsNode Binary(OperatorResolveResult res)
        {
            if (res.UserDefinedOperatorMethod != null && !Sk.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition))
            {
                var op2 = res.OperatorType.ExtractCompoundAssignment();
                if (op2 != null)
                {
                    var fakeRight = new OperatorResolveResult(res.Type, op2.Value, res.UserDefinedOperatorMethod, res.IsLiftedOperator, res.Operands);
                    var fakeAssign = Cs.Assign(res.Operands[0], fakeRight);
                    return Visit(fakeAssign);
                }

                var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0], res.Operands[1]);
                return Visit(fake);
            }

            if (res.OperatorType == 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 JsParenthesizedExpression { Expression = (JsExpression)fake2 };
                return fake2;
            }
            var mrr = res.Operands[0] as MemberResolveResult;
            if (mrr != null && mrr.Member.SymbolKind == SymbolKind.Event)
            {
                var pe = (IEvent)mrr.Member;
                if (res.OperatorType.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign))
                {
                    var accessor = res.OperatorType == ExpressionType.AddAssign ? pe.AddAccessor : pe.RemoveAccessor;
                    var fake = new CSharpInvocationResolveResult(mrr.TargetResult, accessor, new List<ResolveResult>
                            {
                                res.Operands[1]
                            });
                    var node6 = Visit(fake);
                    return node6;
                }
            }
            if (mrr != null && IsEntityFunctionProperty(mrr.Member, res))
            {
                var simpleOp = res.OperatorType.ExtractCompoundAssignment();

                var pe = (IProperty)mrr.Member;
                if (simpleOp != null)
                {
                    // x.Name += "Hello"    ->  x.Name = x.Name + "Hello"
                    // x.Dic["Hello"] += 7  ->  x.Dic["Hello"] = x.Dic["Hello"] + 7;
                    var fake = res.Operands[0].Assign(res.Operands[0].Binary(simpleOp.Value, res.Operands[1], res.Type));
                    var node6 = Visit(fake);
                    return node6;
                }
                else if (res.OperatorType == 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(mrr.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.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign))
                {
                    var op = res.OperatorType == ExpressionType.AddAssign ? ExpressionType.Add : 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.IsAny(ExpressionType.Add, ExpressionType.Subtract))
                {
                    var combineMethod = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Combine").FirstOrDefault();
                    var removeMethod = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Remove").FirstOrDefault();

                    var meOp = res.OperatorType == 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 JsBinaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]), Right = VisitExpression(res.Operands[1]) };
            if (res.OperatorType == ExpressionType.Equal && node5.Operator == "==")
            {
                var att = Compiler.GetJsExportAttribute();
                if (att != null && att.UseExactEquals)
                    node5.Operator = "===";
            }
            if (res.OperatorType == ExpressionType.NotEqual && node5.Operator == "!=")
            {
                var att = Compiler.GetJsExportAttribute();
                if (att != null && att.UseExactEquals)
                    node5.Operator = "!==";
            }

            return node5;
        }
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                        new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return true;
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    string name = OverloadsCollection.Create(this.Emitter, method).GetOverloadName();
                    if(Helpers.GetOperatorMapping(name) != null) {
                        return false;
                    }

                    if (orr.IsLiftedOperator)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.");

                        string action = "lift";

                        switch (this.BinaryOperatorExpression.Operator)
                        {
                            case BinaryOperatorType.GreaterThan:
                                action = "liftcmp";
                                break;

                            case BinaryOperatorType.GreaterThanOrEqual:
                                action = "liftcmp";
                                break;

                            case BinaryOperatorType.Equality:
                                action = "lifteq";
                                break;

                            case BinaryOperatorType.InEquality:
                                action = "liftne";
                                break;

                            case BinaryOperatorType.LessThan:
                                action = "liftcmp";
                                break;

                            case BinaryOperatorType.LessThanOrEqual:
                                action = "liftcmp";
                                break;
                        }

                        this.Write(action + "(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();
                    this.Write(name);

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter, new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null).Emit();
                    this.WriteCloseParentheses();
                    return true;
                }
            }

            return false;
        }
 private object GetConstValue(OperatorResolveResult orr, bool isLeft, bool isChar) {
     var result = isLeft ? orr.Operands.First() : orr.Operands.Last();
     if(result.IsCompileTimeConstant) {
         return WrapConstValue(result.ConstantValue);
     }
     ConversionResolveResult rr = result as ConversionResolveResult;
     if(rr != null && rr.Input.IsCompileTimeConstant) {
         if(isChar) {
             return isLeft ? this.BinaryOperatorExpression.Left.ToString() : this.BinaryOperatorExpression.Right.ToString();
         }
         else if(rr.Input.Type.Kind == TypeKind.Enum) {
             MemberResolveResult reslut = (MemberResolveResult)rr.Input;
             return "\"" + reslut.Member.Name + "\"";
         }
         return WrapConstValue(rr.Input.ConstantValue);
     }
     return null;
 }
 private JsNode WrapSetterToReturnValueIfNeeded(OperatorResolveResult res, JsNode node2)
 {
     return Importer.WrapSetterToReturnValueIfNeeded(res, node2);
 }
		IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func<IType, IType> typePred = null)
		{
			if (resolveResult == null /*			|| resolveResult.IsError*/) {
				return null;
			}

			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);

			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				var namespaceContents = new CompletionDataWrapper(this);

				foreach (var cl in nr.Namespace.Types) {
					if (!lookup.IsAccessible(cl, false))
						continue;
					IType addType = typePred != null ? typePred(cl) : cl;
					if (addType != null)
						namespaceContents.AddType(addType, false);
				}

				foreach (var ns in nr.Namespace.ChildNamespaces) {
					namespaceContents.AddNamespace(lookup, ns);
				}
				return namespaceContents.Result;
			}
			IType type = resolveResult.Type;

			if (type.Namespace == "System" && type.Name == "Void")
				return null;

			if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) {
				resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult);
			}

			//var typeDef = resolveResult.Type.GetDefinition();
			var result = new CompletionDataWrapper(this);
			bool includeStaticMembers = false;

			if (resolveResult is LocalResolveResult) {
				if (resolvedNode is IdentifierExpression) {
					var mrr = (LocalResolveResult)resolveResult;
					includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
				}
			}
			if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
				foreach (var field in type.GetFields ()) {
					if (!lookup.IsAccessible(field, false))
						continue;
					result.AddMember(field);
				}
				return result.Result;
			}

			bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type);
			bool skipNonStaticMembers = (resolveResult is TypeResolveResult);

			if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
				var mrr = (MemberResolveResult)resolveResult;
				includeStaticMembers = mrr.Member.Name == mrr.Type.Name;

				TypeResolveResult trr;
				if (state.IsVariableReferenceWithSameType(
					resolveResult,
					((IdentifierExpression)resolvedNode).Identifier,
					out trr
				)) {
					if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) {
						skipNonStaticMembers = true;

						if (trr.Type.Kind == TypeKind.Enum) {
							foreach (var field in trr.Type.GetFields ()) {
								if (lookup.IsAccessible(field, false))
									result.AddMember(field);
							}
							return result.Result;
						}
					}
				}
				// ADD Aliases
				var scope = ctx.CurrentUsingScope;

				for (var n = scope; n != null; n = n.Parent) {
					foreach (var pair in n.UsingAliases) {
						if (pair.Key == mrr.Member.Name) {
							foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) {
								if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) {
									result.AddMember((IMember)((IEntityCompletionData)r).Entity);
								} else {
									result.Add(r);
								}
							}
						}
					}
				}				


			}
			if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) {
				includeStaticMembers = true;
			}

			//			Console.WriteLine ("type:" + type +"/"+type.GetType ());
			//			Console.WriteLine ("current:" + ctx.CurrentTypeDefinition);
			//			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers);
			//			Console.WriteLine (resolveResult);
			//			Console.WriteLine ("node:" + resolvedNode);
			//			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

			if (resolvedNode.Annotation<ObjectCreateExpression>() == null) {
				//tags the created expression as part of an object create expression.
				/*				
				var filteredList = new List<IMember>();
				foreach (var member in type.GetMembers ()) {
					filteredList.Add(member);
				}
				
				foreach (var member in filteredList) {
					//					Console.WriteLine ("add:" + member + "/" + member.IsStatic);
					result.AddMember(member);
				}*/
				foreach (var member in lookup.GetAccessibleMembers (resolveResult)) {
					if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) {
						continue;
					}
					if (resolvedNode is BaseReferenceExpression && member.IsAbstract) {
						continue;
					}
					if (member is IType) {
						if (resolveResult is TypeResolveResult || includeStaticMembers) {
							if (!lookup.IsAccessible(member, isProtectedAllowed))
								continue;
							result.AddType((IType)member, false);
							continue;
						}
					}
					bool memberIsStatic = member.IsStatic;
					if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) {
						//						Console.WriteLine ("skip static member: " + member.FullName);
						continue;
					}

					var field = member as IField;
					if (field != null) {
						memberIsStatic |= field.IsConst;
					}
					if (!memberIsStatic && skipNonStaticMembers) {
						continue;
					}

					if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
						continue;
					}
					if (member.SymbolKind == SymbolKind.Operator) {
						continue;
					}

					if (member is IMember) {
						result.AddMember((IMember)member);
					}
				}
			}

			if (!(resolveResult is TypeResolveResult || includeStaticMembers)) {
				foreach (var meths in state.GetExtensionMethods (type)) {
					foreach (var m in meths) {
						if (!lookup.IsAccessible(m, isProtectedAllowed))
							continue;
						result.AddMember(new ReducedExtensionMethod(m));
					}
				}
			}

			//			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
			//			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
			//			col.HideExtensionParameter = !resolveResult.StaticResolve;
			//			col.NamePrefix = expressionResult.Expression;
			//			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
			//			if (objects != null) {
			//				foreach (object obj in objects) {
			//					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
			//						continue;
			//					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
			//						continue;
			//					if (showOnlyTypes && !(obj is IType))
			//						continue;
			//					CompletionData data = col.Add (obj);
			//					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
			//						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
			//						data.SetText (newText);
			//					}
			//				}
			//			}

			return result.Result;
		}
 private void VisitStringConcat(OperatorResolveResult orr, bool isLeft, bool isChar) {
     object constValue = GetConstValue(orr, isLeft, isChar);
     if(constValue != null) {
         this.Write(constValue);
     }
     else {
         var express = isLeft ? this.BinaryOperatorExpression.Left : this.BinaryOperatorExpression.Right;
         if(isChar) {
             this.Write("string.char");
             this.WriteOpenParentheses();
             express.AcceptVisitor(this.Emitter);
             this.WriteCloseParentheses();
         }
         else if(express is IdentifierExpression || express is InvocationExpression) {
             var resolverResult = this.Emitter.Resolver.ResolveNode(express, this.Emitter);
             if(resolverResult.Type.Kind == TypeKind.Struct) {
                 express.AcceptVisitor(this.Emitter);
             }
             else if(resolverResult.Type.Kind == TypeKind.Enum) {
                 TransformCtx.ExportEnums.Add(resolverResult.Type);
                 this.Write("System.Enum.toString");
                 this.WriteOpenParentheses();
                 express.AcceptVisitor(this.Emitter);
                 this.WriteComma();
                 string typeName = BridgeTypes.ToJsName(resolverResult.Type, this.Emitter);
                 this.Write(typeName);
                 this.WriteCloseParentheses();
             }
             else {
                 this.Write("System.strconcat");
                 this.WriteOpenParentheses();
                 express.AcceptVisitor(this.Emitter);
                 this.WriteCloseParentheses();
             }
         }
         else {
             express.AcceptVisitor(this.Emitter);
         }
     }
 }