示例#1
0
        public override AstNode VisitInvocationExpression(InvocationExpression invocationExpression, ICecilArgumentsResolver argumentsResolver)
        {
            MethodReference reference = null;

            invocationExpression.Arguments.ForEach(a => a.AcceptVisitor(this, argumentsResolver));
            invocationExpression.Target.AcceptVisitor(this, argumentsResolver);
            var specification = invocationExpression.Annotation <MethodSpecification>();

            if (specification != null && specification.IsGenericInstance)
            {
                var genericMethod    = specification as GenericInstanceMethod;
                var genericArguments = genericMethod.GenericArguments.ToArray();
                var parameters       = genericMethod.Parameters.Select(p => p.ParameterType);
                reference = specification.GetElementMethod();

                reference = ResolveGenericMethod(parameters, reference, genericArguments, argumentsResolver);
                invocationExpression.RemoveAnnotations <MethodSpecification>();
                invocationExpression.AddAnnotation(reference);
            }
            else
            {
                reference = invocationExpression.Annotation <MethodReference>();

                if (reference != null)
                {
                    TypeReference returnType    = reference.ReturnType;
                    TypeReference declaringType = reference.DeclaringType;

                    if (declaringType.IsGenericInstance || returnType.IsGenericParameter)
                    {
                        if (declaringType.IsGenericInstance)
                        {
                            var genericMethod = declaringType as GenericInstanceType;
                            var parameters    = reference.Parameters.Select(p => p.ParameterType);

                            reference = ResolveGenericMethod(parameters, reference, genericMethod.GenericArguments, argumentsResolver);
                            genericMethod.GenericArguments.Clear();
                            reference.GenericParameters.ForEach(p => genericMethod.GenericArguments.Add(p));
                        }

                        if (reference.ReturnType.IsGenericParameter)
                        {
                            var genericInstanceType = declaringType as GenericInstanceType;
                            var genericParameter    = reference.ReturnType as GenericParameter;
                            var genericReturnType   = genericParameter.GetGenericActualType(genericInstanceType.GenericArguments.ToArray());

                            reference = reference.MakeGenericMethod(new TypeReference[] { }, genericReturnType);
                        }

                        invocationExpression.RemoveAnnotations <MethodReference>();
                        invocationExpression.AddAnnotation(reference);
                    }
                }
            }

            return(invocationExpression);
        }
示例#2
0
        public override void VisitInvocationExpression(InvocationExpression invocationExpression)
        {
            base.VisitInvocationExpression(invocationExpression);
            if (!CanTransformToExtensionMethodCall(resolver, invocationExpression, out var memberRefExpr,
                                                   out var target, out var firstArgument))
            {
                return;
            }
            var method = (IMethod)invocationExpression.GetSymbol();

            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);
            }
        }
示例#3
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);
            }
        }
示例#4
0
文件: CsToTs.cs 项目: RReverser/Netjs
			public override void VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression)
			{
				base.VisitBinaryOperatorExpression (binaryOperatorExpression);

				var leftT = GetTypeDef (binaryOperatorExpression.Left);

				if (leftT != null && !(leftT.IsPrimitive || leftT.FullName=="System.String")) {

					var name = "";

					switch (binaryOperatorExpression.Operator) {
					case BinaryOperatorType.Add:
						name = "op_Addition";
						break;
					case BinaryOperatorType.Subtract:
						name = "op_Subtraction";
						break;
					case BinaryOperatorType.Multiply:
						name = "op_Multiply";
						break;
					case BinaryOperatorType.Divide:
						name = "op_Division";
						break;
					case BinaryOperatorType.Equality:
						name = "op_Equality";
						break;
					case BinaryOperatorType.InEquality:
						name = "op_Inequality";
						break;
					case BinaryOperatorType.LessThan:
						name = "op_LessThan";
						break;
					case BinaryOperatorType.LessThanOrEqual:
						name = "op_LessThanOrEqual";
						break;
					case BinaryOperatorType.GreaterThan:
						name = "op_GreaterThan";
						break;
					case BinaryOperatorType.GreaterThanOrEqual:
						name = "op_GreaterThanOrEqual";
						break;
					}

					var m = FindMethod (leftT, name);

					if (m != null && m.DeclaringType.FullName != "System.MulticastDelegate") {
						var left = binaryOperatorExpression.Left;
						var right = binaryOperatorExpression.Right;
						left.Remove ();
						right.Remove ();
						var n = new InvocationExpression (
						new MemberReferenceExpression (new IdentifierExpression (leftT.Name), name),
							left, right);

						n.AddAnnotation (m.ReturnType);

						binaryOperatorExpression.ReplaceWith (n);
					}
				}
			}
示例#5
0
文件: CsToTs.cs 项目: RReverser/Netjs
			public override void VisitInvocationExpression (InvocationExpression invocationExpression)
			{
				base.VisitInvocationExpression (invocationExpression);

				var memberReferenceExpression = invocationExpression.Target as MemberReferenceExpression;

				if (memberReferenceExpression == null)
					return;

				var t = GetTypeRef (memberReferenceExpression.Target);
				if (t == null)
					return;

				HashSet<string> repls = null;
				string newTypeName = null;
				if (t.FullName == "System.Object") {
					repls = objectRepls;
					newTypeName = "NObject";
				} else if (t.FullName == "System.String") {
					repls = stringRepls;
					newTypeName = "NString";
				} else if (t.FullName == "System.Boolean") {
					repls = boolRepls;
					newTypeName = "NBoolean";
				} else if (t != null && t.IsPrimitive) {
					repls = numberRepls;
					newTypeName = "NNumber";
				}
				if (repls != null && repls.Contains (memberReferenceExpression.MemberName)) {
					if (memberReferenceExpression.MemberName == "Equals") {
						var left = memberReferenceExpression.Target;
						var right = invocationExpression.Arguments.First ();
						left.Remove ();
						right.Remove ();
						invocationExpression.ReplaceWith (new BinaryOperatorExpression (left, BinaryOperatorType.Equality, right));
					} else {
						var newName = memberReferenceExpression.MemberName;
						if (newTypeName == "NObject") {
							newName = "Generic" + newName;
						}
						var n = new InvocationExpression (
							        new MemberReferenceExpression (
								        new TypeReferenceExpression (new SimpleType (newTypeName)), 
								        newName),
							new Expression[] { memberReferenceExpression.Target.Clone () }
								.Concat (invocationExpression.Arguments.Select (x => x.Clone ())));

						var td = t.Resolve ();
						var meth = td.Methods.First (x => x.Name == memberReferenceExpression.MemberName);
						n.AddAnnotation (meth.ReturnType);
						invocationExpression.ReplaceWith (n);
					}
				}
			}