Example #1
0
        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);
        }
Example #2
0
        public JsNode VisitConversionResolveResult(ConversionResolveResult res)
        {
            var input          = res.Input;
            var conversion     = res.Conversion;
            var conversionType = res.Type;

            var info = res.GetInfo();

            if (info == null)
            {
                info = new ResolveResultInfo {
                    Conversion = conversion, ResolveResult = res, ConversionTargetType = res.Type
                };
                res.SetInfo(info);
            }
            var info2 = input.GetInfo();

            if (info2 == null)
            {
                input.SetInfo(new ResolveResultInfo {
                    Nodes = info.Nodes.ToList(), Conversion = conversion, ConversionTargetType = res.Type, ResolveResult = input
                });
            }
            if (conversion.IsUserDefined && res.Type.FullName == "SharpKit.JavaScript.JsCode" && input is ConstantResolveResult)
            {
                var value = ((ConstantResolveResult)input).ConstantValue;
                var node3 = Js.CodeExpression(value == null ? "null" : value.ToString());
                return(node3);
            }
            return(VisitConversion(input, conversion, conversionType));
        }
		public IList<ResolveResult> GetArgumentsWithConversions()
		{
			if (bestCandidate == null)
				return arguments;
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				if (conversions[i] == Conversion.IdentityConversion) {
					args[i] = arguments[i];
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0) {
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					} else {
						parameterType = SpecialType.UnknownType;
					}
					if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
						args[i] = new CppResolver(compilation).ResolveCast(parameterType, arguments[i]);
					} else {
						args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
					}
				}
			}
			return args;
		}
Example #4
0
        Value Visit(ConversionResolveResult result)
        {
            if (result.IsError)
            {
                throw new GetValueException("Cannot convert from '{0}' to '{1}'.", new CSharpAmbience().ConvertType(result.Input.Type), new CSharpAmbience().ConvertType(result.Type));
            }
            var val = Convert(result.Input);

            if (result.Conversion.IsBoxingConversion)
            {
                return(val);
            }
            if (result.Conversion.IsIdentityConversion)
            {
                return(val);
            }
            if (result.Conversion.IsNumericConversion)
            {
                var convVal = CSharpPrimitiveCast.Cast(ReflectionHelper.GetTypeCode(result.Type), val.PrimitiveValue, false);
                return(Eval.CreateValue(evalThread, convVal));
            }
            if (result.Conversion.IsUserDefined)
            {
                return(InvokeMethod(null, result.Conversion.Method, val));
            }
            if (result.Conversion.IsReferenceConversion && result.Conversion.IsImplicit)
            {
                return(val);
            }
            if (result.Conversion.IsNullLiteralConversion)
            {
                return(val);
            }
            throw new GetValueException("conversion '{0}' not implemented!", result.Conversion);
        }
Example #5
0
        public void ParamsAttribute_String()
        {
            ConversionResolveResult rr = (ConversionResolveResult)GetParamsAttributeArgument(4);

            Assert.AreEqual("System.Object", rr.Type.FullName);
            Assert.AreEqual("System.String", rr.Input.Type.FullName);
            Assert.AreEqual("Test", rr.Input.ConstantValue);
        }
Example #6
0
        ResolveResult Unbox(ResolveResult resolveResult)
        {
            ConversionResolveResult crr = (ConversionResolveResult)resolveResult;

            Assert.AreEqual(TypeKind.Class, crr.Type.Kind);
            Assert.AreEqual("System.Object", crr.Type.FullName);
            Assert.AreEqual(Conversion.BoxingConversion, crr.Conversion);
            return(crr.Input);
        }
Example #7
0
        public override void VisitInvocationExpression(InvocationExpression invocationExpression)
        {
            base.VisitInvocationExpression(invocationExpression);
            var method = invocationExpression.GetSymbol() as IMethod;

            if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())
            {
                return;
            }
            IReadOnlyList <IType>     typeArguments;
            MemberReferenceExpression memberRefExpr;

            switch (invocationExpression.Target)
            {
            case MemberReferenceExpression mre:
                typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = mre;
                break;

            case IdentifierExpression ide:
                typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = null;
                break;

            default: return;
            }

            var firstArgument = invocationExpression.Arguments.First();
            var target        = firstArgument.GetResolveResult();

            if (target is ConstantResolveResult crr && crr.ConstantValue == null)
            {
                target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
            }
            var args = invocationExpression.Arguments.Skip(1).Select(a => a.GetResolveResult()).ToArray();

            if (!CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args))
            {
                return;
            }
            if (firstArgument is NullReferenceExpression)
            {
                firstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach()));
            }
            if (invocationExpression.Target is IdentifierExpression identifierExpression)
            {
                identifierExpression.Detach();
                memberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach());
                invocationExpression.Target = memberRefExpr;
            }
            else
            {
                memberRefExpr.Target = firstArgument.Detach();
            }
        }
Example #8
0
        public JsNode VisitConversionResolveResult(ConversionResolveResult res)
        {
            var input          = res.Input;
            var conversion     = res.Conversion;
            var conversionType = res.Type;

            var info = res.GetInfo();

            if (info == null)
            {
                info = new ResolveResultInfo {
                    Conversion = conversion, ResolveResult = res, ConversionTargetType = res.Type
                };
                res.SetInfo(info);
            }
            var info2 = input.GetInfo();

            if (info2 == null)
            {
                input.SetInfo(new ResolveResultInfo {
                    Nodes = info.Nodes.ToList(), Conversion = conversion, ConversionTargetType = res.Type, ResolveResult = input
                });
            }
            if (conversion.IsUserDefined && res.Type.FullName == "SharpKit.JavaScript.JsCode" && input is ConstantResolveResult)
            {
                var value = ((ConstantResolveResult)input).ConstantValue;
                var node3 = Js.CodeExpression(value == null ? "null" : value.ToString());
                return(node3);
            }

            #region 修复c#方法重载导致转js后绑定错误
            var tInfo = input.Tag as ResolveResultInfo;
            if (tInfo != null && tInfo.Conversion != null && tInfo.Conversion.Method != null &&
                conversion != null && conversion.Method != null)
            {
                if (tInfo.Conversion.Method.ToString() != conversion.Method.ToString())
                {
                    //var tMessage = string.Format("方法绑定异常:绑定了错误的方法:{0}\n正确的绑定应该是:{1}", tInfo.Conversion.Method.ToString(), conversion.Method.ToString());
                    //Log.Error(tMessage);

                    //处理方法绑定异常
                    var tNewTag = res.Tag as ResolveResultInfo;
                    var tTag    = input.Tag as ResolveResultInfo;
                    tTag.Conversion           = tNewTag.Conversion;
                    tTag.ConversionTargetType = tNewTag.ConversionTargetType;
                    tTag.ResolveResult        = tNewTag.ResolveResult;
                }
            }
            #endregion

            return(VisitConversion(input, conversion, conversionType));
        }
Example #9
0
        IList <ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult, IParameterizedMember bestCandidateForNamedArguments)
        {
            var conversions = this.ArgumentConversions;

            ResolveResult[] args = new ResolveResult[arguments.Length];
            for (int i = 0; i < args.Length; i++)
            {
                var argument = arguments[i];
                if (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)
                {
                    argument = targetResolveResult;
                }
                int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
                if (parameterIndex >= 0 && conversions[i] != Conversion.IdentityConversion)
                {
                    // Wrap argument in ConversionResolveResult
                    IType parameterType = bestCandidate.ParameterTypes[parameterIndex];
                    if (parameterType.Kind != TypeKind.Unknown)
                    {
                        if (arguments[i].IsCompileTimeConstant && conversions[i].IsValid && !conversions[i].IsUserDefined)
                        {
                            argument = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);
                        }
                        else
                        {
                            argument = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);
                        }
                    }
                }
                if (bestCandidateForNamedArguments != null && argumentNames[i] != null)
                {
                    // Wrap argument in NamedArgumentResolveResult
                    if (parameterIndex >= 0)
                    {
                        argument = new NamedArgumentResolveResult(bestCandidateForNamedArguments.Parameters[parameterIndex], argument, bestCandidateForNamedArguments);
                    }
                    else
                    {
                        argument = new NamedArgumentResolveResult(argumentNames[i], argument);
                    }
                }
                args[i] = argument;
            }
            return(args);
        }
		public override JsExpression VisitConversionResolveResult(ConversionResolveResult rr, object data) {
			var input = VisitResolveResult(rr.Input, null);
			if (rr.Conversion.IsIdentityConversion) {
				return input;
			}
			else if (rr.Conversion.IsAnonymousFunctionConversion) {
				var result = input;
				if (rr.Type.Name == "Expression")
					result = CompileFactoryCall("Quote", new[] { typeof(Expression) }, new[] { result });
				return result;
			}
			else if (rr.Conversion.IsNullLiteralConversion) {
				return CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { input, _instantiateType(rr.Type) });
			}
			else if (rr.Conversion.IsMethodGroupConversion) {
				var methodInfo = _compilation.FindType(typeof(MethodInfo));
				return CompileFactoryCall("Convert", new[] { typeof(Expression), typeof(Type) }, new[] {
				           CompileFactoryCall("Call", new[] { typeof(Expression), typeof(MethodInfo), typeof(Expression[]) }, new[] { 
				               CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { _getMember(rr.Conversion.Method), _instantiateType(methodInfo) }),
				               _getMember(methodInfo.GetMethods().Single(m => m.Name == "CreateDelegate" && m.Parameters.Count == 2 && m.Parameters[0].Type.FullName == typeof(Type).FullName && m.Parameters[1].Type.FullName == typeof(object).FullName)),
				               JsExpression.ArrayLiteral(
				                   _instantiateType(rr.Type),
				                   rr.Conversion.Method.IsStatic ? JsExpression.Null : VisitResolveResult(((MethodGroupResolveResult)rr.Input).TargetResult, null)
				               )
				           }),
				           _instantiateType(rr.Type)
				       });
			}
			else {
				string methodName;
				if (rr.Conversion.IsTryCast)
					methodName = "TypeAs";
				else if (rr.CheckForOverflow)
					methodName = "ConvertChecked";
				else
					methodName = "Convert";
				if (rr.Conversion.IsUserDefined)
					return CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type), typeof(MethodInfo) }, new[] { input, _instantiateType(rr.Type), _getMember(rr.Conversion.Method) });
				else
					return CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type) }, new[] { input, _instantiateType(rr.Type) });
			}
		}
Example #11
0
        static bool CanTransformToExtensionMethodCall(CSharpResolver resolver,
                                                      InvocationExpression invocationExpression, out MemberReferenceExpression memberRefExpr,
                                                      out ResolveResult target,
                                                      out Expression firstArgument)
        {
            var method = invocationExpression.GetSymbol() as IMethod;

            memberRefExpr = null;
            target        = null;
            firstArgument = null;
            if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())
            {
                return(false);
            }
            IReadOnlyList <IType> typeArguments;

            switch (invocationExpression.Target)
            {
            case MemberReferenceExpression mre:
                typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = mre;
                break;

            case IdentifierExpression ide:
                typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = null;
                break;

            default:
                return(false);
            }

            firstArgument = invocationExpression.Arguments.First();
            if (firstArgument is NamedArgumentExpression)
            {
                return(false);
            }
            target = firstArgument.GetResolveResult();
            if (target is ConstantResolveResult crr && crr.ConstantValue == null)
            {
                target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
            }
 public virtual TResult VisitConversionResolveResult(ConversionResolveResult rr, TData data)
 {
     VisitChildResolveResults(rr, data);
     return(default(TResult));
 }
Example #13
0
 public ImplicitConversionAnnotation(ConversionResolveResult conversionResolveResult)
 {
     this.ConversionResolveResult = conversionResolveResult;
 }
		IList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult, IParameterizedMember bestCandidateForNamedArguments)
		{
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				var argument = arguments[i];
				if (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)
					argument = targetResolveResult;
				int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
				if (parameterIndex >= 0 && conversions[i] != Conversion.IdentityConversion) {
					// Wrap argument in ConversionResolveResult
					IType parameterType = bestCandidate.ParameterTypes[parameterIndex];
					if (parameterType.Kind != TypeKind.Unknown) {
						if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
							argument = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);
						} else {
							argument = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);
						}
					}
				}
				if (bestCandidateForNamedArguments != null && argumentNames[i] != null) {
					// Wrap argument in NamedArgumentResolveResult
					if (parameterIndex >= 0) {
						argument = new NamedArgumentResolveResult(bestCandidateForNamedArguments.Parameters[parameterIndex], argument, bestCandidateForNamedArguments);
					} else {
						argument = new NamedArgumentResolveResult(argumentNames[i], argument);
					}
				}
				args[i] = argument;
			}
			return args;
		}
Example #15
0
        public override void VisitInvocationExpression(InvocationExpression invocationExpression)
        {
            base.VisitInvocationExpression(invocationExpression);
            var method = invocationExpression.GetSymbol() as IMethod;

            if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())
            {
                return;
            }
            IReadOnlyList <IType>     typeArguments;
            MemberReferenceExpression memberRefExpr;

            switch (invocationExpression.Target)
            {
            case MemberReferenceExpression mre:
                typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = mre;
                break;

            case IdentifierExpression ide:
                typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = null;
                break;

            default: return;
            }

            var firstArgument = invocationExpression.Arguments.First();

            if (firstArgument is NamedArgumentExpression)
            {
                return;
            }
            var target = firstArgument.GetResolveResult();

            if (target is ConstantResolveResult crr && crr.ConstantValue == null)
            {
                target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
            }
            ResolveResult[] args     = new ResolveResult[invocationExpression.Arguments.Count - 1];
            string[]        argNames = null;
            int             pos      = 0;

            foreach (var arg in invocationExpression.Arguments.Skip(1))
            {
                if (arg is NamedArgumentExpression nae)
                {
                    if (argNames == null)
                    {
                        argNames = new string[args.Length];
                    }
                    argNames[pos] = nae.Name;
                    args[pos]     = nae.Expression.GetResolveResult();
                }
                else
                {
                    args[pos] = arg.GetResolveResult();
                }
                pos++;
            }
            if (!CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args, argNames))
            {
                return;
            }
            if (firstArgument is NullReferenceExpression)
            {
                Debug.Assert(context.RequiredNamespacesSuperset.Contains(method.Parameters[0].Type.Namespace));
                firstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach()));
            }
            if (invocationExpression.Target is IdentifierExpression identifierExpression)
            {
                identifierExpression.Detach();
                memberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach());
                invocationExpression.Target = memberRefExpr;
            }
            else
            {
                memberRefExpr.Target = firstArgument.Detach();
            }
        }
Example #16
0
		// The reason this class exists is that for code like this:
		//    int i = ...;
		//    long n = 0;
		//    n = n + (long)i;
		// The resolver will produce (and process) an CastResolveResult for the cast,
		// (with Conversion = implicit numeric conversion)
		// and then pass it into CSharpResolver.ResolveBinaryOperator().
		// That method normally wraps input arguments into another conversion
		// (the implicit conversion applied by the operator).
		// However, identity conversions do not cause the creation of ConversionResolveResult instances,
		// so the OperatorResolveResult's argument will be the CastResolveResult
		// of the cast.
		// Without this class (and instead using ConversionResolveResult for both purposes),
		// it would be hard for the conversion-processing code
		// in the ResolveVisitor to distinguish the existing conversion from the CastExpression
		// from an implicit conversion introduced by the binary operator.
		// This would cause the conversion to be processed yet again.
		// The following unit tests would fail without this class:
		//  * CastTests.ExplicitConversion_In_Assignment
		//  * FindReferencesTest.FindReferencesForOpImplicitInAssignment_ExplicitCast
		//  * CS0029InvalidConversionIssueTests.ExplicitConversionFromUnknownType
		
		public CastResolveResult(ConversionResolveResult rr)
			: base(rr.Type, rr.Input, rr.Conversion, rr.CheckForOverflow)
		{
		}
Example #17
0
 public virtual object VisitConversionResolveResult(ConversionResolveResult rr, object data)
 {
     VisitChildResolveResults(rr, data);
     return(null);
 }
		private ResolveResult ResolveWithConversion(Expression expr) {
			var rr = _resolver.Resolve(expr);
			var conversion = _resolver.GetConversion(expr);
			if (!conversion.IsIdentityConversion)
				rr = new ConversionResolveResult(_resolver.GetExpectedType(expr), rr, conversion);
			return rr;
		}
Example #19
0
		IList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult)
		{
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				var argument = arguments[i];
				if (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)
					argument = targetResolveResult;
				if (conversions[i] == Conversion.IdentityConversion) {
					args[i] = argument;
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0) {
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					} else {
						parameterType = SpecialType.UnknownType;
					}
					if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
						args[i] = new CSharpResolver(compilation).ResolveCast(parameterType, argument);
					} else {
						args[i] = new ConversionResolveResult(parameterType, argument, conversions[i]);
					}
				}
			}
			return args;
		}
Example #20
0
        public override string VisitConversionResolveResult(ConversionResolveResult rr, object data)
        {
            var input = VisitResolveResult(rr.Input, null);

            if (rr.Conversion.IsIdentityConversion)
            {
                return(input);
            }
            else if (rr.Conversion.IsAnonymousFunctionConversion)
            {
                var result = input;
                if (rr.Type.Name == "Expression")
                {
                    result = CompileFactoryCall("Quote", new[] { typeof(Expression) }, new[] { result });
                }
                return(result);
            }
            else if (rr.Conversion.IsNullLiteralConversion)
            {
                return(CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
            }
            else if (rr.Conversion.IsMethodGroupConversion)
            {
                var methodInfo = _compilation.FindType(typeof(MethodInfo));
                return(CompileFactoryCall("Convert", new[] { typeof(Expression), typeof(Type) }, new[] {
                    CompileFactoryCall("Call", new[] { typeof(Expression), typeof(MethodInfo), typeof(Expression[]) }, new[] {
                        CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { this.GetMember(rr.Conversion.Method), ExpressionTreeBuilder.GetTypeName(methodInfo, this._emitter) }),
                        this.GetMember(methodInfo.GetMethods().Single(m => m.Name == "CreateDelegate" && m.Parameters.Count == 2 && m.Parameters[0].Type.FullName == typeof(Type).FullName && m.Parameters[1].Type.FullName == typeof(object).FullName)),
                        this._emitter.ToJavaScript(new [] {
                            new JRaw(ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter)),
                            new JRaw(rr.Conversion.Method.IsStatic ? "null" : VisitResolveResult(((MethodGroupResolveResult)rr.Input).TargetResult, null))
                        })
                    }),
                    ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter)
                }));
            }
            else
            {
                string methodName;
                if (rr.Conversion.IsTryCast)
                {
                    methodName = "TypeAs";
                }
                else if (rr.CheckForOverflow)
                {
                    methodName = "ConvertChecked";
                }
                else
                {
                    methodName = "Convert";
                }
                if (rr.Conversion.IsUserDefined)
                {
                    return(CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type), typeof(MethodInfo) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter), this.GetMember(rr.Conversion.Method) }));
                }
                else
                {
                    return(CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
                }
            }
        }
        // The reason this class exists is that for code like this:
        //    int i = ...;
        //    long n = 0;
        //    n = n + (long)i;
        // The resolver will produce (and process) an CastResolveResult for the cast,
        // (with Conversion = implicit numeric conversion)
        // and then pass it into CSharpResolver.ResolveBinaryOperator().
        // That method normally wraps input arguments into another conversion
        // (the implicit conversion applied by the operator).
        // However, identity conversions do not cause the creation of ConversionResolveResult instances,
        // so the OperatorResolveResult's argument will be the CastResolveResult
        // of the cast.
        // Without this class (and instead using ConversionResolveResult for both purposes),
        // it would be hard for the conversion-processing code
        // in the ResolveVisitor to distinguish the existing conversion from the CastExpression
        // from an implicit conversion introduced by the binary operator.
        // This would cause the conversion to be processed yet again.
        // The following unit tests would fail without this class:
        //  * CastTests.ExplicitConversion_In_Assignment
        //  * FindReferencesTest.FindReferencesForOpImplicitInAssignment_ExplicitCast
        //  * CS0029InvalidConversionIssueTests.ExplicitConversionFromUnknownType

        public CastResolveResult(ConversionResolveResult rr)
            : base(rr.Type, rr.Input, rr.Conversion, rr.CheckForOverflow)
        {
        }
Example #22
0
		public IList<ResolveResult> GetArgumentsWithConversions()
		{
			if (bestCandidate == null)
				return arguments;
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				if (conversions[i] == Conversion.IdentityConversion || conversions[i] == Conversion.None) {
					args[i] = arguments[i];
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0)
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					else
						parameterType = SpecialType.UnknownType;
					args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
				}
			}
			return args;
		}
		string Visit(ConversionResolveResult result)
		{
			throw new NotImplementedException();
		}
		Value Visit(ConversionResolveResult result)
		{
			if (result.IsError)
				throw new GetValueException("Cannot convert from '{0}' to '{1}'.", new CSharpAmbience().ConvertType(result.Input.Type), new CSharpAmbience().ConvertType(result.Type));
			var val = Convert(result.Input);
			if (result.Conversion.IsBoxingConversion)
				return val;
			if (result.Conversion.IsIdentityConversion)
				return val;
			if (result.Conversion.IsNumericConversion) {
				var convVal = CSharpPrimitiveCast.Cast(ReflectionHelper.GetTypeCode(result.Type), val.PrimitiveValue, false);
				return Eval.CreateValue(evalThread, convVal);
			}
			if (result.Conversion.IsUserDefined)
				return InvokeMethod(null, result.Conversion.Method, val);
			if (result.Conversion.IsReferenceConversion && result.Conversion.IsImplicit)
				return val;
			if (result.Conversion.IsNullLiteralConversion)
				return val;
			throw new GetValueException("conversion '{0}' not implemented!", result.Conversion);
		}
Example #25
0
		public IList<ResolveResult> GetArgumentsWithConversions()
		{
			if (bestCandidate == null)
				return arguments;
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				if (conversions[i] == Conversion.IdentityConversion) {
					args[i] = arguments[i];
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0) {
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					} else {
						parameterType = SpecialType.UnknownType;
					}
					if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
						args[i] = new CSharpResolver(compilation).ResolveCast(parameterType, arguments[i]);
					} else {
						args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
					}
				}
			}
			return args;
		}
Example #26
0
            internal override bool IsMatch(ResolveResult rr)
            {
                ConversionResolveResult crr = rr as ConversionResolveResult;

                return(crr != null && crr.Conversion.IsUserDefined && crr.Conversion.Method.MemberDefinition == op);
            }
Example #27
0
        public object VisitConversionResolveResult(ConversionResolveResult res)
        {
            var value = res.Input.AcceptVisitor(this);

            return(value);
        }
Example #28
0
 string Visit(ConversionResolveResult result)
 {
     throw new NotImplementedException();
 }
Example #29
0
        public override void VisitInvocationExpression(InvocationExpression invocationExpression)
        {
            base.VisitInvocationExpression(invocationExpression);
            var method = invocationExpression.GetSymbol() as IMethod;

            if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())
            {
                return;
            }
            IReadOnlyList <IType>     typeArguments;
            MemberReferenceExpression memberRefExpr;

            switch (invocationExpression.Target)
            {
            case MemberReferenceExpression mre:
                typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = mre;
                break;

            case IdentifierExpression ide:
                typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = null;
                break;

            default: return;
            }

            var firstArgument = invocationExpression.Arguments.First();

            if (firstArgument is NamedArgumentExpression)
            {
                return;
            }
            var target = firstArgument.GetResolveResult();

            if (target is ConstantResolveResult crr && crr.ConstantValue == null)
            {
                target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
            }
            ResolveResult[] args     = new ResolveResult[invocationExpression.Arguments.Count - 1];
            string[]        argNames = null;
            int             pos      = 0;

            foreach (var arg in invocationExpression.Arguments.Skip(1))
            {
                if (arg is NamedArgumentExpression nae)
                {
                    if (argNames == null)
                    {
                        argNames = new string[args.Length];
                    }
                    argNames[pos] = nae.Name;
                    args[pos]     = nae.Expression.GetResolveResult();
                }
                else
                {
                    args[pos] = arg.GetResolveResult();
                }
                pos++;
            }
            if (!CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args, argNames))
            {
                return;
            }
            if (firstArgument is DirectionExpression dirExpr)
            {
                if (!context.Settings.RefExtensionMethods || dirExpr.FieldDirection == FieldDirection.Out)
                {
                    return;
                }
                firstArgument = dirExpr.Expression;
                target        = firstArgument.GetResolveResult();
                dirExpr.Detach();
            }
            else if (firstArgument is NullReferenceExpression)
            {
                Debug.Assert(context.RequiredNamespacesSuperset.Contains(method.Parameters[0].Type.Namespace));
                firstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach()));
            }
            if (invocationExpression.Target is IdentifierExpression identifierExpression)
            {
                identifierExpression.Detach();
                memberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach());
                invocationExpression.Target = memberRefExpr;
            }
            else
            {
                memberRefExpr.Target = firstArgument.Detach();
            }
            if (invocationExpression.GetResolveResult() is CSharpInvocationResolveResult irr)
            {
                // do not forget to update the CSharpInvocationResolveResult => set IsExtensionMethodInvocation == true
                invocationExpression.RemoveAnnotations <CSharpInvocationResolveResult>();
                var newResolveResult = new CSharpInvocationResolveResult(
                    irr.TargetResult, irr.Member, irr.Arguments, irr.OverloadResolutionErrors,
                    isExtensionMethodInvocation: true, irr.IsExpandedForm, irr.IsDelegateInvocation,
                    irr.GetArgumentToParameterMap(), irr.InitializerStatements);
                invocationExpression.AddAnnotation(newResolveResult);
            }
        }
Example #30
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="rr">The input resolve result that should be converted.
		/// If a conversion exists, it is applied to the resolve result</param>
		/// <param name="targetType">The target type that we should convert to</param>
		/// <param name="isNullable">Whether we are dealing with a lifted operator</param>
		/// <param name="enumRR">The resolve result that is enum-typed.
		/// If necessary, a nullable conversion is applied.</param>
		/// <param name="allowConversionFromConstantZero">
		/// Whether the conversion from the constant zero is allowed.
		/// </param>
		/// <returns>True if the conversion is successful; false otherwise.
		/// If the conversion is not successful, the ref parameters will not be modified.</returns>
		bool TryConvertEnum(ref ResolveResult rr, IType targetType, ref bool isNullable, ref ResolveResult enumRR, bool allowConversionFromConstantZero = true)
		{
			Conversion c;
			if (!isNullable) {
				// Try non-nullable
				c = conversions.ImplicitConversion(rr, targetType);
				if (c.IsValid && (allowConversionFromConstantZero || !c.IsEnumerationConversion)) {
					rr = Convert(rr, targetType, c);
					return true;
				}
			}
			// make targetType nullable if it isn't already:
			if (!targetType.IsKnownType(KnownTypeCode.NullableOfT))
				targetType = NullableType.Create(compilation, targetType);
			
			c = conversions.ImplicitConversion(rr, targetType);
			if (c.IsValid && (allowConversionFromConstantZero || !c.IsEnumerationConversion)) {
				rr = Convert(rr, targetType, c);
				isNullable = true;
				// Also convert the enum-typed RR to nullable, if it isn't already
				if (!enumRR.Type.IsKnownType(KnownTypeCode.NullableOfT)) {
					var nullableType = NullableType.Create(compilation, enumRR.Type);
					enumRR = new ConversionResolveResult(nullableType, enumRR, Conversion.ImplicitNullableConversion);
				}
				return true;
			}
			return false;
		}
Example #31
0
        static bool CanTransformToExtensionMethodCall(CSharpResolver resolver,
                                                      InvocationExpression invocationExpression, out MemberReferenceExpression memberRefExpr,
                                                      out ResolveResult target,
                                                      out Expression firstArgument)
        {
            var method = invocationExpression.GetSymbol() as IMethod;

            memberRefExpr = null;
            target        = null;
            firstArgument = null;
            if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())
            {
                return(false);
            }
            IReadOnlyList <IType> typeArguments;

            switch (invocationExpression.Target)
            {
            case MemberReferenceExpression mre:
                typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = mre;
                break;

            case IdentifierExpression ide:
                typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance;
                memberRefExpr = null;
                break;

            default:
                return(false);
            }

            firstArgument = invocationExpression.Arguments.First();
            if (firstArgument is NamedArgumentExpression)
            {
                return(false);
            }
            target = firstArgument.GetResolveResult();
            if (target is ConstantResolveResult crr && crr.ConstantValue == null)
            {
                target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
            }
            ResolveResult[] args     = new ResolveResult[invocationExpression.Arguments.Count - 1];
            string[]        argNames = null;
            int             pos      = 0;

            foreach (var arg in invocationExpression.Arguments.Skip(1))
            {
                if (arg is NamedArgumentExpression nae)
                {
                    if (argNames == null)
                    {
                        argNames = new string[args.Length];
                    }
                    argNames[pos] = nae.Name;
                    args[pos]     = nae.Expression.GetResolveResult();
                }
                else
                {
                    args[pos] = arg.GetResolveResult();
                }
                pos++;
            }
            return(CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args, argNames));
        }
		public JsFunctionDefinitionExpression CompileMethod(IList<IParameter> parameters, IDictionary<IVariable, VariableData> variables, Expression body, IType returnType, bool staticMethodWithThisAsFirstArgument, bool expandParams, StateMachineType stateMachineType, IType iteratorBlockYieldTypeOrAsyncTaskGenericArgument = null) {
			SetRegion(body.Region);
			return CompileMethod(parameters, variables, staticMethodWithThisAsFirstArgument, expandParams, stateMachineType, iteratorBlockYieldTypeOrAsyncTaskGenericArgument, () => {
				bool hasReturnValue = !returnType.IsKnownType(KnownTypeCode.Void);
				var rr = _resolver.Resolve(body);
				if (hasReturnValue) {
					var conversion = CSharpConversions.Get(_compilation).ImplicitConversion(rr, returnType);
					if (!conversion.IsValid)
						_errorReporter.InternalError("No implicit conversion found from " + rr.Type + " to " + returnType);
					else if (!conversion.IsIdentityConversion)
						rr = new ConversionResolveResult(returnType, rr, conversion);
				}

				if (!IsInvocationOfRemovedMethod(rr)) {
					var compiled = _expressionCompiler.Compile(rr, hasReturnValue);
					_result.AddRange(compiled.AdditionalStatements);
					if (hasReturnValue) {
						JsExpression result = compiled.Expression;
						if (IsMutableValueType(returnType)) {
							result = MaybeCloneValueType(result, rr, rr.Type);
						}

						_result.Add(JsStatement.Return(result));
					}
					else if (compiled.Expression.NodeType != ExpressionNodeType.Null)	// The statement "null;" is illegal in C#, so it must have appeared because there was no suitable expression to return.
						_result.Add(compiled.Expression);
				}
			});
		}