예제 #1
0
		public static bool TryGetFormattingParameters(CSharpInvocationResolveResult invocationResolveResult, InvocationExpression invocationExpression,
		                                     		  out Expression formatArgument, out TextLocation formatStart, out IList<Expression> arguments,
		                                              Func<IParameter, Expression, bool> argumentFilter)
		{
			if (argumentFilter == null)
				argumentFilter = (p, e) => true;

			formatArgument = null;
			formatStart = default(TextLocation);
			arguments = new List<Expression>();
			var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap();
			var resolvedParameters = invocationResolveResult.Member.Parameters;
			var allArguments = invocationExpression.Arguments.ToArray();
			for (int i = 0; i < allArguments.Length; i++) {
				var parameterIndex = argumentToParameterMap[i];
				if (parameterIndex < 0 || parameterIndex >= resolvedParameters.Count) {
					// No valid mapping for this parameter, skip it
					continue;
				}
				var parameter = resolvedParameters[parameterIndex];
				var argument = allArguments[i];
				if (parameter.Type.IsKnownType(KnownTypeCode.String) && parameterNames.Contains(parameter.Name)) {
					formatArgument = argument;
					formatStart = argument.StartLocation;
				} else if ((formatArgument != null || parameter.IsParams) && argumentFilter(parameter, argument)) {
					arguments.Add(argument);
				}
			}
			return formatArgument != null;
		}
예제 #2
0
 private static void OutputMethodCall(CSharpInvocationResolveResult resolved)
 {
     Console.WriteLine(String.Format("\t\t\tmethod call to ({0}.){1} but on {2}",
         resolved.TargetResult.Type.FullName,
         resolved.Member.Name,
         resolved.Member.FullName));
 }
        AstNode ToStaticMethodInvocation(InvocationExpression invocation, MemberReferenceExpression memberReference,
		                                 CSharpInvocationResolveResult invocationRR)
        {
            var newArgumentList = invocation.Arguments.Select(arg => arg.Clone()).ToList();
            newArgumentList.Insert(0, memberReference.Target.Clone());
            var newTarget = memberReference.Clone() as MemberReferenceExpression;
            newTarget.Target = new IdentifierExpression(invocationRR.Member.DeclaringType.Name);
            return new InvocationExpression(newTarget, newArgumentList);
        }
예제 #4
0
		public static bool TryGetFormattingParameters(CSharpInvocationResolveResult invocationResolveResult, InvocationExpression invocationExpression,
		                                     		  out Expression formatArgument, out IList<Expression> arguments,
		                                              Func<IParameter, Expression, bool> argumentFilter)
		{
			if (argumentFilter == null)
				argumentFilter = (p, e) => true;

			formatArgument = null;
			arguments = new List<Expression>();

			// Serach for method of type: void Name(string format, params object[] args);
			if (invocationResolveResult.Member.SymbolKind == SymbolKind.Method && invocationResolveResult.Member.DeclaringType != null) {
				var methods = invocationResolveResult.Member.DeclaringType.GetMethods(m => m.Name == invocationResolveResult.Member.Name).ToList();
				if (!methods.Any(m => m.Parameters.Count == 2 && 
					m.Parameters[0].Type.IsKnownType(KnownTypeCode.String) && parameterNames.Contains(m.Parameters[0].Name) && 
					m.Parameters[1].IsParams))
					return false;
			}

			var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap();
			var resolvedParameters = invocationResolveResult.Member.Parameters;
			var allArguments = invocationExpression.Arguments.ToArray();
			for (int i = 0; i < allArguments.Length; i++) {
				var parameterIndex = argumentToParameterMap[i];
				if (parameterIndex < 0 || parameterIndex >= resolvedParameters.Count) {
					// No valid mapping for this argument, skip it
					continue;
				}
				var parameter = resolvedParameters[parameterIndex];
				var argument = allArguments[i];
				if (i == 0 && parameter.Type.IsKnownType(KnownTypeCode.String) && parameterNames.Contains(parameter.Name)) {
					formatArgument = argument;
				} else if (formatArgument != null && parameter.IsParams && !invocationResolveResult.IsExpandedForm) {
					var ace = argument as ArrayCreateExpression;
					if (ace == null || ace.Initializer.IsNull)
						return false;
					foreach (var element in ace.Initializer.Elements) {
						if (argumentFilter(parameter, element))
							arguments.Add(argument);
					}
				} else if (formatArgument != null && argumentFilter(parameter, argument)) {
					arguments.Add(argument);
				}
			}
			return formatArgument != null;
		}
예제 #5
0
        public static bool TryGetFormattingParameters(CSharpInvocationResolveResult invocationResolveResult, InvocationExpression invocationExpression,
		                                     		  out Expression formatArgument, out IList<Expression> arguments,
		                                              Func<IParameter, Expression, bool> argumentFilter)
        {
            if (argumentFilter == null)
                argumentFilter = (p, e) => true;

            formatArgument = null;
            arguments = new List<Expression>();
            var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap();
            var resolvedParameters = invocationResolveResult.Member.Parameters;
            var allArguments = invocationExpression.Arguments.ToArray();
            for (int i = 0; i < allArguments.Length; i++) {
                var parameterIndex = argumentToParameterMap[i];
                if (parameterIndex < 0 || parameterIndex >= resolvedParameters.Count) {
                    // No valid mapping for this argument, skip it
                    continue;
                }
                var parameter = resolvedParameters[parameterIndex];
                var argument = allArguments[i];
                if (parameter.Type.IsKnownType(KnownTypeCode.String) && parameterNames.Contains(parameter.Name)) {
                    formatArgument = argument;
                } else if (formatArgument != null && parameter.IsParams && !invocationResolveResult.IsExpandedForm) {
                    var ace = argument as ArrayCreateExpression;
                    if (ace == null || ace.Initializer.IsNull)
                        return false;
                    foreach (var element in ace.Initializer.Elements) {
                        if (argumentFilter(parameter, element))
                            arguments.Add(argument);
                    }
                } else if (formatArgument != null && argumentFilter(parameter, argument)) {
                    arguments.Add(argument);
                }
            }
            return formatArgument != null;
        }
			void CheckFormattingCall(InvocationExpression invocationExpression, CSharpInvocationResolveResult invocationResolveResult)
			{
				Expression formatArgument;
				IList<Expression> formatArguments;
				TextLocation formatStart;
				// Only check parameters that are of type object: String means it is neccessary, others
				// means that there is another problem (ie no matching overload of the method).
				Func<IParameter, Expression, bool> predicate = (parameter, argument) => {
					var type = parameter.Type;
					if (type is TypeWithElementType && parameter.IsParams) {
						type = ((TypeWithElementType)type).ElementType;
					}
					var typeDefinition = type.GetDefinition();
					if (typeDefinition == null)
						return false;
					return typeDefinition.IsKnownType(KnownTypeCode.Object);
				};
				if (FormatStringHelper.TryGetFormattingParameters(invocationResolveResult, invocationExpression,
				                                                  out formatArgument, out formatStart, out formatArguments, predicate)) {
					foreach (var argument in formatArguments) {
						CheckExpressionInAutoCallContext(argument);
					}
				}
			}
        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;
        }
        public JsNode VisitInvocationResolveResultAsCtor(CSharpInvocationResolveResult res)
        {
            if (res.Type.Kind == TypeKind.Delegate)
                return Visit(res.Arguments.Single());
            var me = (IMethod)res.Member;
            var meAtt = Sk.GetJsMethodAttribute(me);
            var ce = me.GetDeclaringTypeDefinition();
            var att = ce == null ? null : ce.GetJsTypeAttribute();
            if (att != null && att.Mode == JsMode.Json && (meAtt == null || meAtt.Name == null))
            {
                var jtfn = ce == null ? null : Sk.GetJsonTypeFieldName(ce);
                var node2 = VisitInvocationResolveResult(res);
                var json = Importer.InitializersToJson(res.InitializerStatements, res.Type);
                if (jtfn != null)
                {
                    var x = json as JsJsonObjectExpression;
                    if (x != null)
                    {
                        x.Add(jtfn, SkJs.EntityTypeRefToMember(res.Type));
                    }
                }
                return json;
            }
            else
            {
                var invokeExp = (JsInvocationExpression)VisitInvocationResolveResult(res);
                var newExp = new JsNewObjectExpression { Invocation = invokeExp };
                JsExpression finalExp;
                if (meAtt != null && meAtt.OmitNewOperator)
                    finalExp = invokeExp;
                else
                    finalExp = newExp;

                if (meAtt != null && meAtt.JsonInitializers)
                {
                    var json = Importer.InitializersToJson(res.InitializerStatements, res.Type);
                    invokeExp.Arguments.Add(json);
                }
                else if (res.InitializerStatements.IsNotNullOrEmpty())
                {
                    var func = Js.Function();

                    var inits2 = res.InitializerStatements.Select(t => Visit(t)).ToList();
                    var init1 = res.InitializerStatements[0];

                    var target = AstNodeConverter.FindInitializedObjectResolveResult(res);// ((init1 as OperatorResolveResult).Operands[0] as MemberResolveResult).TargetResult as InitializedObjectResolveResult;
                    var varName = Importer.Initializers[target];
                    func.Add(Js.Var(varName, finalExp).Statement());

                    foreach (var init in inits2)
                    {
                        var exp = ((JsExpression)init);
                        func.Add(exp.Statement());
                    }
                    func.Add(Js.Return(Js.Member(varName)));
                    finalExp = Importer.WrapFunctionAndInvoke(res, func);
                }

                return finalExp;
            }

        }
        public JsNode VisitInvocationResolveResult(CSharpInvocationResolveResult res)
        {
            Res = res;

            ProcessMember();

            if (MethodAtt != null && MethodAtt.InlineCode != null)
                return Js.CodeExpression(MethodAtt.InlineCode);

            var conditional = ProcessConditional();
            if (conditional)
                return null;

            bool omittedCalls;
            var omittedCallsNode = ProcessOmitCalls(out omittedCalls);
            if (omittedCalls)
                return omittedCallsNode;

            JsMember = SkJs.EntityToMember(Member);
            ProcessTarget();

            ProcessPrmBindings();

            ProcessNativeParams();

            ProcessByRefs1();

            PrmBindings.ForEach(t => t.JsCallResult = VisitExpression(t.Binding.CallResult));
            Node2 = new JsInvocationExpression
            {
                Member = JsMember,
                Arguments = PrmBindings.Select(t => t.JsCallResult).ToList(),
            };

            ProcessByRefs2();

            ProcessExtensionImplementedInInstance();

            TransformIntoBaseMethodCallIfNeeded(Res, Node2);

            ProcessArgsCustomization();

            ProcessGenericMethodArgs();

            var inlineCodeExpression = ProcessInlineCodeExpression();
            if (inlineCodeExpression != null)
                return inlineCodeExpression;



            var omittedDotOperator = ProcessOmitDotOperator();
            if (omittedDotOperator != null)
                return omittedDotOperator;

            ProcessRemoveEmptyPreviousMemberName();

            var indexerAccess = ProcessIndexer();
            if (indexerAccess != null)
                return indexerAccess;

            ProcessByRefs3();

            return Node2;

        }
        void TransformIntoBaseMethodCallIfNeeded(CSharpInvocationResolveResult res, JsInvocationExpression node2)
        {
            var target = res.TargetResult as ThisResolveResult;
            if (target != null && target.CausesNonVirtualInvocation) //base.
            {
                //var info = res.GetInfo();
                //var node = info.Nodes.FirstOrDefault();
                var ce = target.Type;// node.FindThisEntity();
                if (ce != null && Sk.IsExtJsType(ce.GetDefinitionOrArrayType()))
                {
                    node2.Member = Js.This().Member("callParent");
                    if (node2.Arguments.IsNotNullOrEmpty())
                        node2.Arguments = new List<JsExpression> { Js.NewJsonArray(node2.Arguments.ToArray()) };
                    //var me2 = (node2.Member as JsMemberExpression);
                    //me2.Name = "callParent";
                    return;

                }
                IMethod me2;
                var me = res.Member;
                if (me is IProperty)
                    me2 = ((IProperty)me).Getter;
                else if (me is IMethod)
                    me2 = (IMethod)res.Member;
                else
                    throw new Exception("Can't resolve method from member: " + res.Member);
                var member = SkJs.EntityMethodToJsFunctionRef(me2);
                member = member.Member("call");
                node2.Member = member;
                if (node2.Arguments == null)
                    node2.Arguments = new List<JsExpression>();
                node2.Arguments.Insert(0, Js.This());

            }
        }