Esempio n. 1
0
        public override StringBuilder VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, int data)
        {
            var typ = objectCreateExpression.Type.Annotation <TypeReference>().ToHlsl();

            if ("1234".Contains(typ.Last()))
            {
                // either vector or matrix type
                var numRows = int.Parse(typ.Last().ToString());
                if (typ[typ.Length - 2] == 'x')
                {
                    // its a matrix type
                }
                else
                {
                    // its a vector type
                    if ((objectCreateExpression.Arguments.Count == 1) && (numRows > 1))
                    {
                        // scalar intialize all elements to a const
                        // TODO: rather use a float3 widen(float f) { return float3{f,f,f}; } util func or temporary var than expanding to float3(ast,ast,ast)
                        var args = new List <Expression>();
                        for (var i = 0; i < numRows; i++)
                        {
                            args.Add(objectCreateExpression.Arguments.First());
                        }
                        return
                            (objectCreateExpression.Type.AcceptVisitor(this, data).Append("(").Append(
                                 ArgsToString(args).Append(")")));
                    }
                }
            }

            return(objectCreateExpression.Type.AcceptVisitor(this, data).Append("(").Append(
                       ArgsToString(objectCreateExpression.Arguments)).Append(")"));
        }
Esempio n. 2
0
        /// <summary>
        /// var a = new A
        /// {
        ///     b = 2,
        ///     c = 3,
        /// }
        ///
        /// var a = new A();
        /// a.b = 2;
        /// a.c = 3;
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public override Ust VisitAnonymousObjectCreationExpression(AnonymousObjectCreationExpressionSyntax node)
        {
            var typeToken = new TypeToken("Anonymous", node.OpenBraceToken.GetTextSpan());

            Expression[] args = node.Initializers.Select(init =>
            {
                try
                {
                    var left = init.NameEquals == null ? null :
                               new MemberReferenceExpression(typeToken,
                                                             ConvertId(init.NameEquals.Name.Identifier), init.NameEquals.Name.GetTextSpan());
                    var right = (Expression)base.Visit(init.Expression);

                    var assignment = new AssignmentExpression(left, right, init.GetTextSpan());
                    return(assignment);
                }
                catch (Exception ex) when(!(ex is ThreadAbortException))
                {
                    Logger.LogError(new ConversionException(root?.SourceFile, message: ex.Message));
                    return(null);
                }
            }).ToArray();
            var argsNode = new ArgsUst(args, node.GetTextSpan());

            var result = new ObjectCreateExpression(typeToken, argsNode, node.GetTextSpan());

            return(result);
        }
        ObjectCreateExpression ConvertXmlElementExpression(XmlElementExpression xmlElementExpression)
        {
            var newNode = new ObjectCreateExpression(new TypeReference("XElement"), xmlElementExpression.NameIsExpression ? new List <Expression> {
                xmlElementExpression.NameExpression
            } : Expressions(xmlElementExpression.XmlName));

            foreach (XmlExpression attr in xmlElementExpression.Attributes)
            {
                if (attr is XmlAttributeExpression)
                {
                    var a = attr as XmlAttributeExpression;
                    newNode.Parameters.Add(new ObjectCreateExpression(new TypeReference("XAttribute"), new List <Expression> {
                        new PrimitiveExpression(a.Name),
                        a.IsLiteralValue ? new PrimitiveExpression(ConvertEntities(a.LiteralValue)) : a.ExpressionValue
                    }));
                }
                else if (attr is XmlEmbeddedExpression)
                {
                    newNode.Parameters.Add((attr as XmlEmbeddedExpression).InlineVBExpression);
                }
            }

            foreach (XmlExpression expr in xmlElementExpression.Children)
            {
                XmlContentExpression c = expr as XmlContentExpression;
                // skip whitespace text
                if (!(expr is XmlContentExpression && c.Type == XmlContentType.Text && StringExtensions.IsNullOrWhiteSpace(c.Content)))
                {
                    newNode.Parameters.Add(ConvertXmlExpression(expr));
                }
            }

            return(newNode);
        }
Esempio n. 4
0
        /// <summary>
        ///     Translates an object creation, e.g. "new float4(...)".
        /// </summary>
        /// <remarks>
        ///     GLSL 1.1 does not support matrix casts.
        /// </remarks>
        public override StringBuilder VisitObjectCreateExpression(ObjectCreateExpression objCreateExpr)
        {
            if (!(objCreateExpr.Type.GetType() == typeof(SimpleType)))
            {
                return(base.VisitObjectCreateExpression(objCreateExpr));
            }

            var simpleType = (SimpleType)objCreateExpr.Type;
            var dataType   = simpleType.Annotation <TypeReference>().ToType();

            if (dataType == typeof(float3x3))
            {
                var methodRef   = (MethodReference)objCreateExpr.Annotations.First();
                var methodDef   = methodRef.Resolve();
                var methodParam = methodDef.Parameters.FirstOrDefault();

                if (methodParam != null && methodParam.ParameterType.IsType <float4x4>())
                {
                    var instr = GetInstructionFromStmt(objCreateExpr.GetParent <Statement>());
                    DebugLog.Warning("Matrix casting (float4x4 to float3x3) is not supported " +
                                     "in GLSL 1.1. Expression has been converted automatically", instr);

                    var argName = objCreateExpr.Arguments.First().AcceptVisitor(this);

                    var row1 = argName + "[0].xyz";
                    var row2 = argName + "[1].xyz";
                    var row3 = argName + "[2].xyz";

                    var type = objCreateExpr.Type.AcceptVisitor(this).ToString();
                    return(new StringBuilder().Method(type, row1, row2, row3));
                }
            }

            return(base.VisitObjectCreateExpression(objCreateExpr));
        }
        Expression ConvertListInit(InvocationExpression invocation)
        {
            if (invocation.Arguments.Count != 2)
            {
                return(NotSupported(invocation));
            }
            ObjectCreateExpression oce = Convert(invocation.Arguments.ElementAt(0)) as ObjectCreateExpression;

            if (oce == null)
            {
                return(null);
            }
            Expression elementsArray = invocation.Arguments.ElementAt(1);
            ArrayInitializerExpression initializer = ConvertElementInit(elementsArray);

            if (initializer != null)
            {
                oce.Initializer = initializer;
                return(oce);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 6
0
        public void CSharpComplexCollectionInitializer()
        {
            ObjectCreateExpression oce = ParseUtilCSharp.ParseExpression <ObjectCreateExpression>(
                @"new List<Contact> {
	new Contact {
		Name = ""Chris"",
		PhoneNumbers = { ""206-555-0101"" }
	},
	new Contact(additionalParameter) {
		Name = ""Bob"",
		PhoneNumbers = { ""650-555-0199"", ""425-882-8080"" }
	}
}");

            Assert.AreEqual(0, oce.Parameters.Count);
            Assert.AreEqual(2, oce.ObjectInitializer.CreateExpressions.Count);

            oce = (ObjectCreateExpression)oce.ObjectInitializer.CreateExpressions[1];             // look at Bob
            Assert.AreEqual(1, oce.Parameters.Count);
            Assert.IsInstanceOf(typeof(IdentifierExpression), oce.Parameters[0]);
            Assert.IsInstanceOf(typeof(PrimitiveExpression), CheckPropertyInitializationExpression(oce.ObjectInitializer.CreateExpressions[0], "Name"));
            CollectionInitializerExpression phoneNumbers = (CollectionInitializerExpression)CheckPropertyInitializationExpression(oce.ObjectInitializer.CreateExpressions[1], "PhoneNumbers");

            Assert.AreEqual(2, phoneNumbers.CreateExpressions.Count);
        }
            public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
            {
                base.VisitObjectCreateExpression(objectCreateExpression);

                CheckMethodCall(objectCreateExpression, objectCreateExpression.Arguments,
                                (objectCreation, args) => new ObjectCreateExpression(objectCreation.Type.Clone(), args));
            }
Esempio n. 8
0
 void CheckPointObjectCreation(ObjectCreateExpression oce)
 {
     Assert.AreEqual(0, oce.Parameters.Count);
     Assert.AreEqual(2, oce.ObjectInitializer.CreateExpressions.Count);
     Assert.IsInstanceOf(typeof(PrimitiveExpression), CheckPropertyInitializationExpression(oce.ObjectInitializer.CreateExpressions[0], "X"));
     Assert.IsInstanceOf(typeof(PrimitiveExpression), CheckPropertyInitializationExpression(oce.ObjectInitializer.CreateExpressions[1], "Y"));
 }
Esempio n. 9
0
 public virtual void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(objectCreateExpression);
     }
 }
Esempio n. 10
0
            public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
            {
                base.VisitObjectCreateExpression(objectCreateExpression);

                // test for var foo = new ...
                var parentVarDecl = objectCreateExpression.Parent.Parent as VariableDeclarationStatement;

                if (parentVarDecl != null && parentVarDecl.Type.IsVar())
                {
                    return;
                }

                var rr = ctx.Resolve(objectCreateExpression);

                if (!NullableType.IsNullable(rr.Type))
                {
                    return;
                }
                var arg = objectCreateExpression.Arguments.FirstOrDefault();

                if (arg == null)
                {
                    return;
                }
                AddIssue(new CodeIssue(
                             objectCreateExpression.StartLocation,
                             objectCreateExpression.Type.EndLocation,
                             ctx.TranslateString("Redundant explicit nullable type creation"),
                             ctx.TranslateString("Remove redundant 'new'"),
                             s => s.Replace(objectCreateExpression, arg.Clone())
                             )
                {
                    IssueMarker = IssueMarker.GrayOut
                });
            }
Esempio n. 11
0
        public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
        {
            ForceSpacesBefore(objectCreateExpression.LParToken, policy.NewParentheses);

            if (objectCreateExpression.Arguments.Any())
            {
                if (!objectCreateExpression.LParToken.IsNull)
                {
                    ForceSpacesAfter(objectCreateExpression.LParToken, policy.WithinNewParentheses);
                }
                if (!objectCreateExpression.RParToken.IsNull)
                {
                    ForceSpacesBefore(objectCreateExpression.RParToken, policy.WithinNewParentheses);
                }
            }
            else
            {
                if (!objectCreateExpression.LParToken.IsNull)
                {
                    ForceSpacesAfter(objectCreateExpression.LParToken, policy.BetweenEmptyNewParentheses);
                }
                if (!objectCreateExpression.RParToken.IsNull)
                {
                    ForceSpacesBefore(objectCreateExpression.RParToken, policy.BetweenEmptyNewParentheses);
                }
            }
            FormatCommas(objectCreateExpression, policy.BeforeNewParameterComma, policy.AfterNewParameterComma);

            return(base.VisitObjectCreateExpression(objectCreateExpression, data));
        }
        bool CanBeSimplified(VariableDeclarationStatement varDecl)
        {
            if (FixUtil.Instance.NeedFix("SimplyLocalVariableDeclarationsUsingVar.CanBeSimplified"))
            {
                FixUtil.Instance.Fix("SimplyLocalVariableDeclarationsUsingVar.CanBeSimplified", this, varDecl);
                return;
            }

            if (varDecl.Variables.Count != 1)
            {
                return(false);
            }
            if (varDecl.Modifiers != Modifiers.None)             // this line was "forgotten" in the article
            {
                return(false);
            }
            VariableInitializer    v   = varDecl.Variables.Single();
            ObjectCreateExpression oce = v.Initializer as ObjectCreateExpression;

            if (oce == null)
            {
                return(false);
            }
            //return ?AreEqualTypes?(varDecl.Type, oce.Type);
            return(varDecl.Type.IsMatch(oce.Type));
        }
Esempio n. 13
0
            public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
            {
                base.VisitObjectCreateExpression(objectCreateExpression);

                if (objectCreateExpression.Initializer.IsNull ||
                    objectCreateExpression.Arguments.Count > 0 ||
                    objectCreateExpression.LParToken.IsNull)
                {
                    return;
                }

                AddIssue(new CodeIssue(objectCreateExpression.LParToken.StartLocation, objectCreateExpression.RParToken.EndLocation,
                                       ctx.TranslateString("Empty argument list is redundant"),
                                       ctx.TranslateString("Remove '()'"), script => {
                    var l1 = objectCreateExpression.LParToken.GetPrevNode().EndLocation;
                    var l2 = objectCreateExpression.RParToken.GetNextNode().StartLocation;
                    var o1 = script.GetCurrentOffset(l1);
                    var o2 = script.GetCurrentOffset(l2);

                    script.Replace(o1, o2 - o1, " ");
                })
                {
                    IssueMarker = IssueMarker.GrayOut
                });
            }
Esempio n. 14
0
        public UnifiedElement VisitObjectCreateExpression(
            ObjectCreateExpression create, object data)
        {
            var uType = LookupType(create.Type);
            var args  = create.Arguments.AcceptVisitorAsArgs(this, data);

            return(UnifiedNew.Create(uType, args));
        }
Esempio n. 15
0
 public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
 {
     if (objectCreateExpressionVisit != null)
     {
         data = objectCreateExpressionVisit(objectCreateExpression, data);
     }
     return(base.VisitObjectCreateExpression(objectCreateExpression, data));
 }
Esempio n. 16
0
        public void CSharpNullableObjectCreateExpressionTest()
        {
            ObjectCreateExpression oce = ParseUtilCSharp.ParseExpression <ObjectCreateExpression>("new IntPtr?(1)");

            Assert.AreEqual("System.Nullable", oce.CreateType.Type);
            Assert.AreEqual(1, oce.CreateType.GenericTypes.Count);
            Assert.AreEqual("IntPtr", oce.CreateType.GenericTypes[0].Type);
        }
Esempio n. 17
0
            public IList <Statement> ConvertInitializer(ObjectCreateExpression initializer, out Expression finalExpression)
            {
                statements = new List <Statement>();

                finalExpression = initializer.AcceptVisitor(this, null);

                return(statements);
            }
Esempio n. 18
0
 public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
 {
     foreach (var arg in objectCreateExpression.Arguments)
     {
         arg.AcceptVisitor(this);
     }
     objectCreateExpression.Initializer.AcceptVisitor(this);
 }
        public override object VisitXmlElementExpression(XmlElementExpression xmlElementExpression, object data)
        {
            ObjectCreateExpression newNode = ConvertXmlElementExpression(xmlElementExpression);

            ReplaceCurrentNode(newNode);

            return(base.VisitObjectCreateExpression(newNode, data));
        }
        public void VBNetNullableObjectArrayCreateExpressionTest()
        {
            ObjectCreateExpression oce = ParseUtil.ParseExpression <ObjectCreateExpression>("New Integer?()");

            Assert.AreEqual("System.Nullable", oce.CreateType.Type);
            Assert.AreEqual(1, oce.CreateType.GenericTypes.Count);
            Assert.AreEqual("System.Int32", oce.CreateType.GenericTypes[0].Type);
        }
Esempio n. 21
0
 public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
 {
     if (objectCreateExpression.CreateType.GenericTypes.Count > 0)
     {
         UnlockWith(objectCreateExpression);
     }
     return(base.VisitObjectCreateExpression(objectCreateExpression, data));
 }
            public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                var type = objectCreateExpression.Type as SimpleType;
                if (type != null && type.TypeArguments.Count > 0)
                    UnlockWith(objectCreateExpression);

                return base.VisitObjectCreateExpression(objectCreateExpression, data);
            }
Esempio n. 23
0
        public override object VisitQueryExpression(QueryExpression queryExpression, object data)
        {
            if (this.queryExpression != null)             // prevent endloss loop: var n = from n select n; n.$ (doesn't make sense, but you can type this)
            {
                return(null);
            }
            this.queryExpression = queryExpression;
            IReturnType type = null;
            QueryExpressionSelectClause selectClause = queryExpression.SelectOrGroupClause as QueryExpressionSelectClause;

            if (selectClause != null)
            {
                InvocationExpression selectInvocation = new InvocationExpression(new MemberReferenceExpression(queryExpression.FromClause.InExpression, "Select"));
                LambdaExpression     selectLambdaExpr = new LambdaExpression();
                selectLambdaExpr.Parent = selectInvocation;
                selectLambdaExpr.Parameters.Add(new ParameterDeclarationExpression(null, "par"));
                selectLambdaExpr.ExpressionBody = selectClause.Projection;
                TypeReference typeRef = new TypeReference("System.Func");
                typeRef.GenericTypes.Add(TypeReference.Null);
                ResolveResult result = resolver.ResolveExpression(selectLambdaExpr, resolver.ResolvePosition);

                typeRef.GenericTypes.Add(result.ResolvedType.ConvertToTypeReference());

                ObjectCreateExpression createExpression = new ObjectCreateExpression(typeRef, new List <Expression> (new Expression [] {
                    null,
                    selectLambdaExpr
                }));

                selectInvocation.Arguments.Add(createExpression);
                return(CreateResult(ResolveType(selectInvocation)));
            }

            QueryExpressionGroupClause groupClause = queryExpression.SelectOrGroupClause as QueryExpressionGroupClause;

            if (groupClause != null)
            {
                InvocationExpression groupInvocation = new InvocationExpression(new MemberReferenceExpression(queryExpression.FromClause.InExpression, "GroupBy"));

                LambdaExpression keyLambdaExpr = new LambdaExpression();
                keyLambdaExpr.Parent = groupInvocation;
                keyLambdaExpr.Parameters.Add(new ParameterDeclarationExpression(null, "par"));
                keyLambdaExpr.ExpressionBody = groupClause.GroupBy;
                groupInvocation.Arguments.Add(keyLambdaExpr);

                LambdaExpression elementLambdaExpr = new LambdaExpression();
                elementLambdaExpr.Parent = groupInvocation;
                elementLambdaExpr.Parameters.Add(new ParameterDeclarationExpression(null, "par"));
                elementLambdaExpr.ExpressionBody = groupClause.Projection;
                groupInvocation.Arguments.Add(elementLambdaExpr);
                return(CreateResult(ResolveType(groupInvocation)));
            }

            if (type != null)
            {
                return(CreateResult(new DomReturnType("System.Collections.Generic.IEnumerable", false, new List <IReturnType> (new IReturnType[] { type }))));
            }
            return(null);
        }
Esempio n. 24
0
        TranslatedExpression HandleDelegateConstruction(CallInstruction inst)
        {
            ILInstruction func = inst.Arguments[1];
            IMethod       method;

            switch (func.OpCode)
            {
            case OpCode.LdFtn:
                method = ((LdFtn)func).Method;
                break;

            case OpCode.LdVirtFtn:
                method = ((LdVirtFtn)func).Method;
                break;

            default:
                method = (IMethod)typeSystem.Resolve(((ILFunction)func).Method);
                break;
            }
            var target = expressionBuilder.TranslateTarget(method, inst.Arguments[0], func.OpCode == OpCode.LdFtn);
            var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
            var or     = new OverloadResolution(resolver.Compilation, method.Parameters.SelectArray(p => new TypeResolveResult(p.Type)));
            var result = lookup.Lookup(target.ResolveResult, method.Name, method.TypeArguments, true) as MethodGroupResolveResult;

            if (result == null)
            {
                target = target.ConvertTo(method.DeclaringType, expressionBuilder);
            }
            else
            {
                or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray());
                if (or.BestCandidateErrors != OverloadResolutionErrors.None || !IsAppropriateCallTarget(method, or.BestCandidate, func.OpCode == OpCode.LdVirtFtn))
                {
                    target = target.ConvertTo(method.DeclaringType, expressionBuilder);
                }
            }

            var mre = new MemberReferenceExpression(target, method.Name);

            mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
            var oce = new ObjectCreateExpression(expressionBuilder.ConvertType(inst.Method.DeclaringType), mre)
                      //				.WithAnnotation(new DelegateConstruction.Annotation(func.OpCode == OpCode.LdVirtFtn, target, method.Name))
                      .WithILInstruction(inst)
                      .WithRR(new ConversionResolveResult(
                                  inst.Method.DeclaringType,
                                  new MemberResolveResult(target.ResolveResult, method),
                                  // TODO handle extension methods capturing the first argument
                                  Conversion.MethodGroupConversion(method, func.OpCode == OpCode.LdVirtFtn, false)));

            if (func is ILFunction)
            {
                return(expressionBuilder.TranslateFunction(oce, target, (ILFunction)func));
            }
            else
            {
                return(oce);
            }
        }
            public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                if(objectCreateExpression.Initializer.Elements.Count > 0)
                {
                    UnlockWith(objectCreateExpression.Initializer);
                }

                return base.VisitObjectCreateExpression(objectCreateExpression, data);
            }
 internal NewObjectEmitter(ObjectCreateExpression objectCreateExpression, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor <ILGenerator, AstNode> visitor, List <LocalBuilder> locals)
 {
     _locals                 = locals;
     _visitor                = visitor;
     ILGenerator             = ilGenerator;
     InstructionsIndexer     = instructionsIndexer;
     _objectCreateExpression = objectCreateExpression;
     Type = _objectCreateExpression.Type.GetActualType();
 }
Esempio n. 27
0
        public UstNode VisitObjectCreationExpression(DslParser.ObjectCreationExpressionContext context)
        {
            var      literal   = (Token)VisitLiteralOrPatternId(context.literalOrPatternId());
            var      typeToken = new TypeToken(literal.TextValue, literal.TextSpan, null);
            ArgsNode args      = context.args() == null ? new ArgsNode() : (ArgsNode)VisitArgs(context.args());
            var      result    = new ObjectCreateExpression(typeToken, args, context.GetTextSpan(), null);

            return(result);
        }
Esempio n. 28
0
        public override object TrackedVisitBlockStatement(BlockStatement blockStatement, object data)
        {
            blockStatement.Children.Clear();
            TypeReference          notImplmentedException = new TypeReference("System.NotImplementedException");
            ObjectCreateExpression objectCreate           = new ObjectCreateExpression(notImplmentedException, new List <Expression>());

            blockStatement.Children.Add(new ThrowStatement(objectCreate));
            return(null);
        }
Esempio n. 29
0
            public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                if (objectCreateExpression.Initializer.Elements.Count > 0)
                {
                    UnlockWith(objectCreateExpression.Initializer);
                }

                return(base.VisitObjectCreateExpression(objectCreateExpression, data));
            }
Esempio n. 30
0
        public override object TrackedVisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
        {
            string fullName = GetFullName(objectCreateExpression.CreateType);

            if (CodeBase.References.Contains("Cons:" + fullName))
            {
                objectCreateExpression.Parameters.Add(new ThisReferenceExpression());
            }
            return(base.TrackedVisitObjectCreateExpression(objectCreateExpression, data));
        }
Esempio n. 31
0
        public override object VisitThrowStatement(ThrowStatement throwStatement, object data)
        {
            ObjectCreateExpression oce = throwStatement.Expression as ObjectCreateExpression;

            if (oce != null)
            {
                Exceptions.Add(oce.CreateType);
            }
            return(null);
        }
 public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
 {
     base.VisitObjectCreateExpression(objectCreateExpression);
     if (!(objectCreateExpression.Parent is ExpressionStatement))
     {
         return;
     }
     AddIssue(new CodeIssue(objectCreateExpression.NewToken,
                            ctx.TranslateString("Possible unassigned object created by 'new' expression")));
 }
Esempio n. 33
0
        public ArgumentsInfo(IEmitter emitter, ObjectCreateExpression objectCreateExpression)
        {
            this.Emitter = emitter;
            this.Expression = objectCreateExpression;

            var arguments = objectCreateExpression.Arguments.ToList();
            this.ResolveResult = emitter.Resolver.ResolveNode(objectCreateExpression, emitter) as InvocationResolveResult;

            this.BuildArgumentsList(arguments);
            this.BuildTypedArguments(objectCreateExpression.Type);
        }
			IEnumerable<CodeAction> GetActions(ObjectCreateExpression objectCreateExpression,
			                                   PrimitiveExpression firstParam, PrimitiveExpression secondParam)
			{
				yield return new CodeAction(context.TranslateString("Swap parameters"), script =>  {
					var newOCE = objectCreateExpression.Clone() as ObjectCreateExpression;
					newOCE.Arguments.Clear();
					newOCE.Arguments.Add(secondParam.Clone());
					newOCE.Arguments.Add(firstParam.Clone());
					script.Replace(objectCreateExpression, newOCE);
				});
			}
Esempio n. 35
0
		public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
		{
			if (objectCreateExpression.Arguments.Count() == 2) {
				Expression obj = objectCreateExpression.Arguments.First();
				Expression func = objectCreateExpression.Arguments.Last();
				Annotation annotation = func.Annotation<Annotation>();
				if (annotation != null) {
					IdentifierExpression methodIdent = (IdentifierExpression)((InvocationExpression)func).Arguments.Single();
					MethodReference method = methodIdent.Annotation<MethodReference>();
					if (method != null) {
						if (HandleAnonymousMethod(objectCreateExpression, obj, method))
							return null;
						// Perform the transformation to "new Action(obj.func)".
						obj.Remove();
						methodIdent.Remove();
						if (!annotation.IsVirtual && obj is ThisReferenceExpression) {
							// maybe it's getting the pointer of a base method?
							if (method.DeclaringType != context.CurrentType) {
								obj = new BaseReferenceExpression();
							}
						}
						if (!annotation.IsVirtual && obj is NullReferenceExpression && !method.HasThis) {
							// We're loading a static method.
							// However it is possible to load extension methods with an instance, so we compare the number of arguments:
							bool isExtensionMethod = false;
							TypeReference delegateType = objectCreateExpression.Type.Annotation<TypeReference>();
							if (delegateType != null) {
								TypeDefinition delegateTypeDef = delegateType.Resolve();
								if (delegateTypeDef != null) {
									MethodDefinition invokeMethod = delegateTypeDef.Methods.FirstOrDefault(m => m.Name == "Invoke");
									if (invokeMethod != null) {
										isExtensionMethod = (invokeMethod.Parameters.Count + 1 == method.Parameters.Count);
									}
								}
							}
							if (!isExtensionMethod) {
								obj = new TypeReferenceExpression { Type = AstBuilder.ConvertType(method.DeclaringType) };
							}
						}
						// now transform the identifier into a member reference
						MemberReferenceExpression mre = new MemberReferenceExpression();
						mre.Target = obj;
						mre.MemberName = methodIdent.Identifier;
						methodIdent.TypeArguments.MoveTo(mre.TypeArguments);
						mre.AddAnnotation(method);
						objectCreateExpression.Arguments.Clear();
						objectCreateExpression.Arguments.Add(mre);
						return null;
					}
				}
			}
			return base.VisitObjectCreateExpression(objectCreateExpression, data);
		}
Esempio n. 36
0
		public void AssignmentInCollectionInitializer()
		{
			Expression expr = new ObjectCreateExpression {
				Type = new SimpleType("List"),
				Initializer = new ArrayInitializerExpression(
					new ArrayInitializerExpression(
						new AssignmentExpression(new IdentifierExpression("a"), new PrimitiveExpression(1))
					)
				)
			};
			
			AssertOutput("new List {\n${\n$$a = 1\n$}\n}", expr);
		}
			public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
			{
				base.VisitObjectCreateExpression (objectCreateExpression);
				if (objectCreateExpression.Initializer.IsNull || objectCreateExpression.Initializer.Elements.Count > 0)
					return;

				AddIssue (objectCreateExpression.Initializer, ctx.TranslateString ("Remove redundant empty initializer"),
					script => {
						var expr = (ObjectCreateExpression)objectCreateExpression.Clone ();
						expr.Initializer = ArrayInitializerExpression.Null;
						script.Replace (objectCreateExpression, expr);
					});
			}
			public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
			{
				base.VisitObjectCreateExpression (objectCreateExpression);

				if (objectCreateExpression.Initializer.IsNull ||
					objectCreateExpression.Arguments.Count > 0 ||
					objectCreateExpression.LParToken.IsNull)
					return;

				AddIssue (objectCreateExpression.LParToken.StartLocation, objectCreateExpression.RParToken.EndLocation,
					ctx.TranslateString ("Remove redundant empty argument list"), script => {
						var expr = new ObjectCreateExpression (objectCreateExpression.Type.Clone ()) {
							Initializer = (ArrayInitializerExpression)objectCreateExpression.Initializer.Clone ()
						};
						script.Replace (objectCreateExpression, expr);
					});
			}
			public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
			{
				base.VisitObjectCreateExpression (objectCreateExpression);

				if (objectCreateExpression.Initializer.IsNull ||
					objectCreateExpression.Arguments.Count > 0 ||
					objectCreateExpression.LParToken.IsNull)
					return;

				AddIssue (objectCreateExpression.LParToken.StartLocation, objectCreateExpression.RParToken.EndLocation,
					ctx.TranslateString ("Remove redundant empty argument list"), script => {
						var l1 = objectCreateExpression.LParToken.GetPrevNode ().EndLocation;
						var l2 = objectCreateExpression.RParToken.GetNextNode ().StartLocation;
						var o1 = script.GetCurrentOffset (l1);
						var o2 = script.GetCurrentOffset (l2);

						script.Replace (o1, o2 - o1, " ");
					});
			}
Esempio n. 40
0
		static IEnumerable<IType> GetAllValidTypesFromObjectCreation(CSharpAstResolver resolver, ObjectCreateExpression invoke, AstNode parameter)
		{
			int index = GetArgumentIndex(invoke.Arguments, parameter);
			if (index < 0)
				yield break;

			var targetResult = resolver.Resolve(invoke.Type);
			if (targetResult is TypeResolveResult) {
				var type = ((TypeResolveResult)targetResult).Type;
				if (type.Kind == TypeKind.Delegate && index == 0) {
					yield return type;
					yield break;
				}
				foreach (var constructor in type.GetConstructors ()) {
					if (index < constructor.Parameters.Count)
						yield return constructor.Parameters [index].Type;
				}
			}
		}
Esempio n. 41
0
        public ArgumentsInfo(IEmitter emitter, ObjectCreateExpression objectCreateExpression)
        {
            this.Emitter = emitter;
            this.Expression = objectCreateExpression;

            var arguments = objectCreateExpression.Arguments.ToList();
            var rr = emitter.Resolver.ResolveNode(objectCreateExpression, emitter);
            var drr = rr as DynamicInvocationResolveResult;
            if (drr != null)
            {
                var group = drr.Target as MethodGroupResolveResult;

                if (group != null && group.Methods.Count() > 1)
                {
                    throw new EmitterException(objectCreateExpression, "Cannot compile this dynamic invocation because there are two or more method overloads with the same parameter count. To work around this limitation, assign the dynamic value to a non-dynamic variable before use or call a method with different parameter count");
                }
            }

            this.ResolveResult = rr as InvocationResolveResult;
            this.BuildArgumentsList(arguments);
            this.BuildTypedArguments(objectCreateExpression.Type);
        }
			public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
			{
				var type = context.Resolve(objectCreateExpression.Type) as TypeResolveResult;
				if (type == null)
					return;
				var parameters = objectCreateExpression.Arguments;
				if (parameters.Count != 2)
					return;
				var firstParam = parameters.FirstOrNullObject() as PrimitiveExpression;
				var secondParam = parameters.LastOrNullObject() as PrimitiveExpression;
				if (firstParam == null || firstParam.Value.GetType() != typeof(string) ||
					secondParam == null || firstParam.Value.GetType() != typeof(string))
					return;
				var leftLength = (firstParam.Value as string).Length;
				var rightLength = (secondParam.Value as string).Length;

				Func<int, int, bool> func;
				if (!rules.TryGetValue(type.Type.FullName, out func))
					return;
				if (!func(leftLength, rightLength))
					AddIssue(objectCreateExpression,
					         context.TranslateString("The parameters are in the wrong order"),
					         GetActions(objectCreateExpression, firstParam, secondParam));
			}
Esempio n. 43
0
 public ObjectCreateBlock(IEmitter emitter, ObjectCreateExpression objectCreateExpression)
     : base(emitter, objectCreateExpression)
 {
     this.Emitter = emitter;
     this.ObjectCreateExpression = objectCreateExpression;
 }
Esempio n. 44
0
		bool HandleAnonymousMethod(ObjectCreateExpression objectCreateExpression, Expression target, MethodReference methodRef)
		{
			// Anonymous methods are defined in the same assembly, so there's no need to Resolve().
			MethodDefinition method = methodRef as MethodDefinition;
			if (method == null || !method.Name.StartsWith("<", StringComparison.Ordinal))
				return false;
			if (!(method.IsCompilerGenerated() || IsPotentialClosure(method.DeclaringType)))
				return false;
			
			// Decompile the anonymous method:
			
			DecompilerContext subContext = context.Clone();
			subContext.CurrentMethod = method;
			BlockStatement body = AstMethodBodyBuilder.CreateMethodBody(method, subContext);
			TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext);
			body.AcceptVisitor(this, null);
			
			AnonymousMethodExpression ame = new AnonymousMethodExpression();
			bool isLambda = false;
			if (method.Parameters.All(p => string.IsNullOrEmpty(p.Name))) {
				ame.HasParameterList = false;
			} else {
				ame.HasParameterList = true;
				ame.Parameters.AddRange(AstBuilder.MakeParameters(method.Parameters));
				if (ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None)) {
					isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);
				}
			}
			
			// Replace all occurrences of 'this' in the method body with the delegate's target:
			foreach (AstNode node in body.Descendants) {
				if (node is ThisReferenceExpression)
					node.ReplaceWith(target.Clone());
				
			}
			if (isLambda) {
				LambdaExpression lambda = new LambdaExpression();
				ame.Parameters.MoveTo(lambda.Parameters);
				Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
				returnExpr.Remove();
				lambda.Body = returnExpr;
				objectCreateExpression.ReplaceWith(lambda);
			} else {
				ame.Body = body;
				objectCreateExpression.ReplaceWith(ame);
			}
			return true;
		}
Esempio n. 45
0
		AstNode TransformByteCode(ILExpression byteCode)
		{
			object operand = byteCode.Operand;
			AstType operandAsTypeRef = AstBuilder.ConvertType(operand as ITypeDefOrRef);

			List<Ast.Expression> args = new List<Expression>();
			foreach(ILExpression arg in byteCode.Arguments) {
				args.Add((Ast.Expression)TransformExpression(arg));
			}
			Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
			Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
			Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
			
			switch (byteCode.Code) {
					#region Arithmetic
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PtrSig) {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
							if (byteCode.Arguments[0].ExpectedType is PtrSig ||
								byteCode.Arguments[1].ExpectedType is PtrSig) {
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Add ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PtrSig) {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
							if (byteCode.Arguments[0].ExpectedType is PtrSig) {
								boe.WithAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Sub ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
					case ILCode.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
					case ILCode.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
					case ILCode.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
					case ILCode.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
					case ILCode.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
				case ILCode.PostIncrement:
				case ILCode.PostIncrement_Ovf:
				case ILCode.PostIncrement_Ovf_Un:
					{
						if (arg1 is DirectionExpression)
							arg1 = ((DirectionExpression)arg1).Expression.Detach();
						var uoe = new Ast.UnaryOperatorExpression(
							(int)byteCode.Operand > 0 ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement, arg1);
						uoe.AddAnnotation((byteCode.Code == ILCode.PostIncrement) ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return uoe;
					}
					#endregion
					#region Arrays
					case ILCode.Newarr: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null) {
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						return ace;
					}
					case ILCode.InitArray: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null)
						{
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
							ace.Initializer = new ArrayInitializerExpression();
						}
						var arySig = ((TypeSpec)operand).TypeSig.RemovePinnedAndModifiers() as ArraySigBase;
						if (arySig == null) {
						}
						else if (arySig.IsSingleDimensional)
						{
							ace.Initializer.Elements.AddRange(args);
						}
						else
						{
							var newArgs = new List<Expression>();
							foreach (var length in arySig.GetLengths().Skip(1).Reverse())
							{
								for (int j = 0; j < args.Count; j += length)
								{
									var child = new ArrayInitializerExpression();
									child.Elements.AddRange(args.GetRange(j, length));
									newArgs.Add(child);
								}
								var temp = args;
								args = newArgs;
								newArgs = temp;
								newArgs.Clear();
							}
							ace.Initializer.Elements.AddRange(args);
						}
						return ace;
					}
					case ILCode.Ldlen: return arg1.Member("Length", TextTokenType.InstanceProperty).WithAnnotation(Create_SystemArray_get_Length());
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_Ref:
				case ILCode.Ldelem:
					return arg1.Indexer(arg2);
				case ILCode.Ldelema:
					return MakeRef(arg1.Indexer(arg2));
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem:
					return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
				case ILCode.CompoundAssignment:
					{
						CastExpression cast = arg1 as CastExpression;
						var boe = cast != null ? (BinaryOperatorExpression)cast.Expression : arg1 as BinaryOperatorExpression;
						// AssignmentExpression doesn't support overloaded operators so they have to be processed to BinaryOperatorExpression
						if (boe == null) {
							var tmp = new ParenthesizedExpression(arg1);
							ReplaceMethodCallsWithOperators.ProcessInvocationExpression((InvocationExpression)arg1);
							boe = (BinaryOperatorExpression)tmp.Expression;
						}
						var assignment = new Ast.AssignmentExpression {
							Left = boe.Left.Detach(),
							Operator = ReplaceMethodCallsWithOperators.GetAssignmentOperatorForBinaryOperator(boe.Operator),
							Right = boe.Right.Detach()
						}.CopyAnnotationsFrom(boe);
						// We do not mark the resulting assignment as RestoreOriginalAssignOperatorAnnotation, because
						// the operator cannot be translated back to the expanded form (as the left-hand expression
						// would be evaluated twice, and might have side-effects)
						if (cast != null) {
							cast.Expression = assignment;
							return cast;
						} else {
							return assignment;
						}
					}
					#endregion
					#region Comparison
					case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
					case ILCode.Cne: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
					case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					case ILCode.Cgt_Un: {
						// can also mean Inequality, when used with object references
						TypeSig arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !DnlibExtensions.IsValueType(arg1Type)) goto case ILCode.Cne;

						// when comparing signed integral values using Cgt_Un with 0
						// the Ast should actually contain InEquality since "(uint)a > 0u" is identical to "a != 0"
						if (arg1Type.IsSignedIntegralType())
						{
							var p = arg2 as Ast.PrimitiveExpression;
							if (p != null && p.Value.IsZero()) goto case ILCode.Cne;
						}

						goto case ILCode.Cgt;
					}
					case ILCode.Cle_Un: {
						// can also mean Equality, when used with object references
						TypeSig arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !DnlibExtensions.IsValueType(arg1Type)) goto case ILCode.Ceq;

						// when comparing signed integral values using Cle_Un with 0
						// the Ast should actually contain Equality since "(uint)a <= 0u" is identical to "a == 0"
						if (arg1Type.IsSignedIntegralType())
						{
							var p = arg2 as Ast.PrimitiveExpression;
							if (p != null && p.Value.IsZero()) goto case ILCode.Ceq;
						}

						goto case ILCode.Cle;
					}
					case ILCode.Cle: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2);
				case ILCode.Cge_Un:
					case ILCode.Cge: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2);
				case ILCode.Clt_Un:
					case ILCode.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					#endregion
					#region Logical
					case ILCode.LogicNot:   return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
					case ILCode.LogicAnd:   return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
					case ILCode.LogicOr:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
					case ILCode.TernaryOp:  return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
					case ILCode.NullCoalescing: 	return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.NullCoalescing, arg2);
					#endregion
					#region Branch
					case ILCode.Br:         return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
				case ILCode.Brtrue:
					return new Ast.IfElseStatement() {
						Condition = arg1,
						TrueStatement = new BlockStatement() {
							new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
						}
					};
					case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
					case ILCode.LoopContinue:      return new Ast.ContinueStatement();
					#endregion
					#region Conversions
				case ILCode.Conv_I1:
				case ILCode.Conv_I2:
				case ILCode.Conv_I4:
				case ILCode.Conv_I8:
				case ILCode.Conv_U1:
				case ILCode.Conv_U2:
				case ILCode.Conv_U4:
				case ILCode.Conv_U8:
				case ILCode.Conv_I:
				case ILCode.Conv_U:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Conv_R4:
				case ILCode.Conv_R8:
				case ILCode.Conv_R_Un: // TODO
					return arg1;
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_I1_Un:
				case ILCode.Conv_Ovf_I2_Un:
				case ILCode.Conv_Ovf_I4_Un:
				case ILCode.Conv_Ovf_I8_Un:
				case ILCode.Conv_Ovf_U1_Un:
				case ILCode.Conv_Ovf_U2_Un:
				case ILCode.Conv_Ovf_U4_Un:
				case ILCode.Conv_Ovf_U8_Un:
				case ILCode.Conv_Ovf_I:
				case ILCode.Conv_Ovf_U:
				case ILCode.Conv_Ovf_I_Un:
				case ILCode.Conv_Ovf_U_Un:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Unbox_Any:
					// unboxing does not require a cast if the argument was an isinst instruction
					if (arg1 is AsExpression && byteCode.Arguments[0].Code == ILCode.Isinst && TypeAnalysis.IsSameType(operand as ITypeDefOrRef, byteCode.Arguments[0].Operand as ITypeDefOrRef))
						return arg1;
					else
						goto case ILCode.Castclass;
				case ILCode.Castclass:
					if ((byteCode.Arguments[0].InferredType != null && byteCode.Arguments[0].InferredType.IsGenericParameter) || (operand as ITypeDefOrRef).TryGetGenericSig() != null)
						return arg1.CastTo(new PrimitiveType("object")).CastTo(operandAsTypeRef);
					else
						return arg1.CastTo(operandAsTypeRef);
				case ILCode.Isinst:
					return arg1.CastAs(operandAsTypeRef);
				case ILCode.Box:
					return arg1;
				case ILCode.Unbox:
					return MakeRef(arg1.CastTo(operandAsTypeRef));
					#endregion
					#region Indirect
				case ILCode.Ldind_Ref:
				case ILCode.Ldobj:
					if (arg1 is DirectionExpression)
						return ((DirectionExpression)arg1).Expression.Detach();
					else
						return new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1);
				case ILCode.Stind_Ref:
				case ILCode.Stobj:
					if (arg1 is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)arg1).Expression.Detach(), arg2);
					else
						return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
					#endregion
				case ILCode.Arglist:
					return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess };
					case ILCode.Break:    return InlineAssembly(byteCode, args);
				case ILCode.Call:
				case ILCode.CallGetter:
				case ILCode.CallSetter:
					return TransformCall(false, byteCode, args);
				case ILCode.Callvirt:
				case ILCode.CallvirtGetter:
				case ILCode.CallvirtSetter:
					return TransformCall(true, byteCode,  args);
					case ILCode.Ldftn: {
						IMethod cecilMethod = (IMethod)operand;
						var expr = Ast.IdentifierExpression.Create(cecilMethod.Name, cecilMethod);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return IdentifierExpression.Create("ldftn", TextTokenType.OpCode).Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
					}
					case ILCode.Ldvirtftn: {
						IMethod cecilMethod = (IMethod)operand;
						var expr = Ast.IdentifierExpression.Create(cecilMethod.Name, cecilMethod);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return IdentifierExpression.Create("ldvirtftn", TextTokenType.OpCode).Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
					}
					case ILCode.Calli:       return InlineAssembly(byteCode, args);
					case ILCode.Ckfinite:    return InlineAssembly(byteCode, args);
					case ILCode.Constrained: return InlineAssembly(byteCode, args);
					case ILCode.Cpblk:       return InlineAssembly(byteCode, args);
					case ILCode.Cpobj:       return InlineAssembly(byteCode, args);
					case ILCode.Dup:         return arg1;
					case ILCode.Endfilter:   return InlineAssembly(byteCode, args);
					case ILCode.Endfinally:  return null;
					case ILCode.Initblk:     return InlineAssembly(byteCode, args);
					case ILCode.Initobj:      return InlineAssembly(byteCode, args);
				case ILCode.DefaultValue:
					return MakeDefaultValue((operand as ITypeDefOrRef).ToTypeSig());
					case ILCode.Jmp: return InlineAssembly(byteCode, args);
				case ILCode.Ldc_I4:
						return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType.ToTypeDefOrRef());
				case ILCode.Ldc_I8:
						return AstBuilder.MakePrimitive((long)operand, byteCode.InferredType.ToTypeDefOrRef());
				case ILCode.Ldc_R4:
				case ILCode.Ldc_R8:
				case ILCode.Ldc_Decimal:
					return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand);
				case ILCode.Ldsfld:
					return AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand);
				case ILCode.Stfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return new AssignmentExpression(arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand), arg2);
				case ILCode.Stsfld:
					return new AssignmentExpression(
						AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand),
						arg1);
				case ILCode.Ldflda:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return MakeRef(arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand));
				case ILCode.Ldsflda:
					return MakeRef(
						AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand));
					case ILCode.Ldloc: {
						ILVariable v = (ILVariable)operand;
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						Expression expr;
						if (v.IsParameter && v.OriginalParameter.IsHiddenThisParameter)
							expr = new ThisReferenceExpression().WithAnnotation(methodDef.DeclaringType);
						else
							expr = Ast.IdentifierExpression.Create(((ILVariable)operand).Name, ((ILVariable)operand).IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(operand);
						return v.IsParameter && v.Type is ByRefSig ? MakeRef(expr) : expr;
					}
					case ILCode.Ldloca: {
						ILVariable v = (ILVariable)operand;
						if (v.IsParameter && v.OriginalParameter.IsHiddenThisParameter)
							return MakeRef(new ThisReferenceExpression().WithAnnotation(methodDef.DeclaringType));
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						return MakeRef(Ast.IdentifierExpression.Create(((ILVariable)operand).Name, ((ILVariable)operand).IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(operand));
					}
					case ILCode.Ldnull: return new Ast.NullReferenceExpression();
					case ILCode.Ldstr:  return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldtoken:
					if (operand is ITypeDefOrRef) {
						var th = Create_SystemType_get_TypeHandle();
						return AstBuilder.CreateTypeOfExpression((ITypeDefOrRef)operand).Member("TypeHandle", TextTokenType.InstanceProperty).WithAnnotation(th);
					} else {
						Expression referencedEntity;
						string loadName;
						string handleName;
						if (operand is IField && ((IField)operand).FieldSig != null) {
							loadName = "fieldof";
							handleName = "FieldHandle";
							IField fr = (IField)operand;
							referencedEntity = AstBuilder.ConvertType(fr.DeclaringType).Member(fr.Name, fr).WithAnnotation(fr);
						} else if (operand is IMethod) {
							loadName = "methodof";
							handleName = "MethodHandle";
							IMethod mr = (IMethod)operand;
							var methodParameters = mr.MethodSig.GetParameters().Select(p => new TypeReferenceExpression(AstBuilder.ConvertType(p)));
							referencedEntity = AstBuilder.ConvertType(mr.DeclaringType).Invoke(mr, mr.Name, methodParameters).WithAnnotation(mr);
						} else {
							loadName = "ldtoken";
							handleName = "Handle";
							var ie = IdentifierExpression.Create(FormatByteCodeOperand(byteCode.Operand), byteCode.Operand);
							ie.IdentifierToken.AddAnnotation(IdentifierEscaper.IdentifierFormatted);
							referencedEntity = ie;
						}
						return IdentifierExpression.Create(loadName, TextTokenType.Keyword).Invoke(referencedEntity).WithAnnotation(new LdTokenAnnotation()).Member(handleName, TextTokenType.InstanceProperty);
					}
					case ILCode.Leave:    return new GotoStatement() { Label = ((ILLabel)operand).Name };
				case ILCode.Localloc:
					{
						PtrSig ptrType = byteCode.InferredType as PtrSig;
						TypeSig type;
						if (ptrType != null) {
							type = ptrType.Next;
						} else {
							type = corLib.Byte;
						}
						return new StackAllocExpression {
							Type = AstBuilder.ConvertType(type),
                            CountExpression = arg1
						};
					}
				case ILCode.Mkrefany:
					{
						DirectionExpression dir = arg1 as DirectionExpression;
						if (dir != null) {
							return new UndocumentedExpression {
								UndocumentedExpressionType = UndocumentedExpressionType.MakeRef,
								Arguments = { dir.Expression.Detach() }
							};
						} else {
							return InlineAssembly(byteCode, args);
						}
					}
				case ILCode.Refanytype:
					return new UndocumentedExpression {
						UndocumentedExpressionType = UndocumentedExpressionType.RefType,
						Arguments = { arg1 }
					}.Member("TypeHandle", TextTokenType.InstanceProperty).WithAnnotation(Create_SystemType_get_TypeHandle());
				case ILCode.Refanyval:
					return MakeRef(
						new UndocumentedExpression {
							UndocumentedExpressionType = UndocumentedExpressionType.RefValue,
							Arguments = { arg1, new TypeReferenceExpression(operandAsTypeRef) }
						});
					case ILCode.Newobj: {
						ITypeDefOrRef declaringType = ((IMethod)operand).DeclaringType;
						if (declaringType.TryGetSZArraySig() != null || declaringType.TryGetArraySig() != null) {
							ComposedType ct = AstBuilder.ConvertType(declaringType) as ComposedType;
							if (ct != null && ct.ArraySpecifiers.Count >= 1) {
								var ace = new Ast.ArrayCreateExpression();
								ct.ArraySpecifiers.First().Remove();
								ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
								ace.Type = ct;
								ace.Arguments.AddRange(args);
								return ace;
							}
						}
						if (declaringType.IsAnonymousType()) {
							MethodDef ctor = ((IMethod)operand).Resolve();
							if (methodDef != null) {
								AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
								if (CanInferAnonymousTypePropertyNamesFromArguments(args, ctor.Parameters)) {
									atce.Initializers.AddRange(args);
								} else {
									int skip = ctor.Parameters.GetParametersSkip();
									for (int i = 0; i < args.Count; i++) {
										atce.Initializers.Add(
											new NamedExpression {
												NameToken = Identifier.Create(ctor.Parameters[i + skip].Name).WithAnnotation(ctor.Parameters[i + skip]),
												Expression = args[i]
											});
									}
								}
								return atce;
							}
						}
						var oce = new Ast.ObjectCreateExpression();
						oce.Type = AstBuilder.ConvertType(declaringType);
						oce.Arguments.AddRange(args);
						return oce.WithAnnotation(operand);
					}
					case ILCode.No: return InlineAssembly(byteCode, args);
					case ILCode.Nop: return null;
					case ILCode.Pop: return arg1;
					case ILCode.Readonly: return InlineAssembly(byteCode, args);
				case ILCode.Ret:
					if (methodDef.ReturnType.GetFullName() != "System.Void") {
						return new Ast.ReturnStatement { Expression = arg1 };
					} else {
						return new Ast.ReturnStatement();
					}
					case ILCode.Rethrow: return new Ast.ThrowStatement();
					case ILCode.Sizeof:  return new Ast.SizeOfExpression { Type = operandAsTypeRef };
					case ILCode.Stloc: {
						ILVariable locVar = (ILVariable)operand;
						if (!locVar.IsParameter)
							localVariablesToDefine.Add(locVar);
						return new Ast.AssignmentExpression(Ast.IdentifierExpression.Create(locVar.Name, locVar.IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(locVar), arg1);
					}
					case ILCode.Switch: return InlineAssembly(byteCode, args);
					case ILCode.Tailcall: return InlineAssembly(byteCode, args);
					case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
					case ILCode.Unaligned: return InlineAssembly(byteCode, args);
					case ILCode.Volatile: return InlineAssembly(byteCode, args);
				case ILCode.YieldBreak:
					return new Ast.YieldBreakStatement();
				case ILCode.YieldReturn:
					return new Ast.YieldReturnStatement { Expression = arg1 };
				case ILCode.InitObject:
				case ILCode.InitCollection:
					{
						ArrayInitializerExpression initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							Match m = objectInitializerPattern.Match(args[i]);
							if (m.Success) {
								MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single();
								initializer.Elements.Add(
									new NamedExpression {
										NameToken = (Identifier)mre.MemberNameToken.Clone(),
										Expression = m.Get<Expression>("right").Single().Detach()
									}.CopyAnnotationsFrom(mre));
							} else {
								m = collectionInitializerPattern.Match(args[i]);
								if (m.Success) {
									if (m.Get("arg").Count() == 1) {
										initializer.Elements.Add(m.Get<Expression>("arg").Single().Detach());
									} else {
										ArrayInitializerExpression argList = new ArrayInitializerExpression();
										foreach (var expr in m.Get<Expression>("arg")) {
											argList.Elements.Add(expr.Detach());
										}
										initializer.Elements.Add(argList);
									}
								} else {
									initializer.Elements.Add(args[i]);
								}
							}
						}
						ObjectCreateExpression oce = arg1 as ObjectCreateExpression;
						DefaultValueExpression dve = arg1 as DefaultValueExpression;
						if (oce != null) {
							oce.Initializer = initializer;
							return oce;
						} else if (dve != null) {
							oce = new ObjectCreateExpression(dve.Type.Detach());
							oce.CopyAnnotationsFrom(dve);
							oce.Initializer = initializer;
							return oce;
						} else {
							return new AssignmentExpression(arg1, initializer);
						}
					}
				case ILCode.InitializedObject:
					return new InitializedObjectExpression();
				case ILCode.Wrap:
					return arg1.WithAnnotation(PushNegation.LiftedOperatorAnnotation);
				case ILCode.AddressOf:
					return MakeRef(arg1);
				case ILCode.ExpressionTreeParameterDeclarations:
					args[args.Count - 1].AddAnnotation(new ParameterDeclarationAnnotation(byteCode));
					return args[args.Count - 1];
				case ILCode.Await:
					return new UnaryOperatorExpression(UnaryOperatorType.Await, UnpackDirectionExpression(arg1));
				case ILCode.NullableOf:
				case ILCode.ValueOf: 
					return arg1;
				default:
					throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Esempio n. 46
0
		AstNode TransformByteCode(ILExpression byteCode)
		{
			object operand = byteCode.Operand;
			AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference);

			List<Ast.Expression> args = new List<Expression>();
			foreach(ILExpression arg in byteCode.Arguments) {
				args.Add((Ast.Expression)TransformExpression(arg));
			}
			Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
			Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
			Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
			
			switch (byteCode.Code) {
					#region Arithmetic
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else if (byteCode.Arguments[1].ExpectedType is PointerType) {
								arg1 = DivideBySize(arg1, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Add ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
								boe.WithAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Sub ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
					case ILCode.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
					case ILCode.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
					case ILCode.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
					case ILCode.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
					case ILCode.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
				case ILCode.PostIncrement:
				case ILCode.PostIncrement_Ovf:
				case ILCode.PostIncrement_Ovf_Un:
					{
						if (arg1 is DirectionExpression)
							arg1 = ((DirectionExpression)arg1).Expression.Detach();
						var uoe = new Ast.UnaryOperatorExpression(
							(int)byteCode.Operand > 0 ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement, arg1);
						uoe.AddAnnotation((byteCode.Code == ILCode.PostIncrement) ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return uoe;
					}
					#endregion
					#region Arrays
					case ILCode.Newarr: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null) {
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						return ace;
					}
					case ILCode.InitArray: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						var arrayType = (ArrayType) operand;
						if (ct != null)
						{
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
							ace.Initializer = new ArrayInitializerExpression();
							var first = ace.AdditionalArraySpecifiers.First();
							first.Remove();
							ace.Arguments.AddRange(Enumerable.Repeat(0, first.Dimensions).Select(i => new EmptyExpression()));
						}
						var newArgs = new List<Expression>();
						foreach (var arrayDimension in arrayType.Dimensions.Skip(1).Reverse())
						{
							int length = (int)arrayDimension.UpperBound - (int)arrayDimension.LowerBound;
							for (int j = 0; j < args.Count; j += length)
							{
								var child = new ArrayInitializerExpression();
								child.Elements.AddRange(args.GetRange(j, length));
								newArgs.Add(child);
							}
							var temp = args;
							args = newArgs;
							newArgs = temp;
							newArgs.Clear();
						}
						ace.Initializer.Elements.AddRange(args);
						return ace;
					}
					case ILCode.Ldlen: return arg1.Member("Length");
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_Ref:
				case ILCode.Ldelem_Any:
					return arg1.Indexer(arg2);
				case ILCode.Ldelema:
					return MakeRef(arg1.Indexer(arg2));
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem_Any:
					return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
				case ILCode.CompoundAssignment:
					{
						CastExpression cast = arg1 as CastExpression;
						BinaryOperatorExpression boe = (BinaryOperatorExpression)(cast != null ? cast.Expression : arg1);
						var assignment = new Ast.AssignmentExpression {
							Left = boe.Left.Detach(),
							Operator = ReplaceMethodCallsWithOperators.GetAssignmentOperatorForBinaryOperator(boe.Operator),
							Right = boe.Right.Detach()
						}.CopyAnnotationsFrom(boe);
						// We do not mark the resulting assignment as RestoreOriginalAssignOperatorAnnotation, because
						// the operator cannot be translated back to the expanded form (as the left-hand expression
						// would be evaluated twice, and might have side-effects)
						if (cast != null) {
							cast.Expression = assignment;
							return cast;
						} else {
							return assignment;
						}
					}
					#endregion
					#region Comparison
					case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
					case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					case ILCode.Cgt_Un: {
						// can also mean Inequality, when used with object references
						TypeReference arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !arg1Type.IsValueType)
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
						else
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					}
					case ILCode.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					case ILCode.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					#endregion
					#region Logical
					case ILCode.LogicNot:   return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
					case ILCode.LogicAnd:   return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
					case ILCode.LogicOr:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
					case ILCode.TernaryOp:  return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
					case ILCode.NullCoalescing: 	return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.NullCoalescing, arg2);
					#endregion
					#region Branch
					case ILCode.Br:         return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
				case ILCode.Brtrue:
					return new Ast.IfElseStatement() {
						Condition = arg1,
						TrueStatement = new BlockStatement() {
							new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
						}
					};
					case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
					case ILCode.LoopContinue:      return new Ast.ContinueStatement();
					#endregion
					#region Conversions
				case ILCode.Conv_I1:
				case ILCode.Conv_I2:
				case ILCode.Conv_I4:
				case ILCode.Conv_I8:
				case ILCode.Conv_U1:
				case ILCode.Conv_U2:
				case ILCode.Conv_U4:
				case ILCode.Conv_U8:
				case ILCode.Conv_I:
				case ILCode.Conv_U:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Conv_R4:
				case ILCode.Conv_R8:
				case ILCode.Conv_R_Un: // TODO
					return arg1;
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_I1_Un:
				case ILCode.Conv_Ovf_I2_Un:
				case ILCode.Conv_Ovf_I4_Un:
				case ILCode.Conv_Ovf_I8_Un:
				case ILCode.Conv_Ovf_U1_Un:
				case ILCode.Conv_Ovf_U2_Un:
				case ILCode.Conv_Ovf_U4_Un:
				case ILCode.Conv_Ovf_U8_Un:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);
						}
						return arg1;
					}
					case ILCode.Conv_Ovf_I:     return arg1.CastTo(typeof(IntPtr)); // TODO
					case ILCode.Conv_Ovf_U:     return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Conv_Ovf_I_Un:  return arg1.CastTo(typeof(IntPtr));
					case ILCode.Conv_Ovf_U_Un:  return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Castclass:      return arg1.CastTo(operandAsTypeRef);
				case ILCode.Unbox_Any:
					// unboxing does not require a cast if the argument was an isinst instruction
					if (arg1 is AsExpression && byteCode.Arguments[0].Code == ILCode.Isinst && TypeAnalysis.IsSameType(operand as TypeReference, byteCode.Arguments[0].Operand as TypeReference))
						return arg1;
					else
						return arg1.CastTo(operandAsTypeRef);
				case ILCode.Isinst:
					return arg1.CastAs(operandAsTypeRef);
				case ILCode.Box:
					return arg1;
				case ILCode.Unbox:
					return MakeRef(arg1.CastTo(operandAsTypeRef));
					#endregion
					#region Indirect
				case ILCode.Ldind_Ref:
				case ILCode.Ldobj:
					if (arg1 is DirectionExpression)
						return ((DirectionExpression)arg1).Expression.Detach();
					else
						return new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1);
				case ILCode.Stind_Ref:
				case ILCode.Stobj:
					if (arg1 is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)arg1).Expression.Detach(), arg2);
					else
						return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
					#endregion
				case ILCode.Arglist:
					return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess };
					case ILCode.Break:    return InlineAssembly(byteCode, args);
				case ILCode.Call:
				case ILCode.CallGetter:
				case ILCode.CallSetter:
					return TransformCall(false, byteCode, args);
				case ILCode.Callvirt:
				case ILCode.CallvirtGetter:
				case ILCode.CallvirtSetter:
					return TransformCall(true, byteCode,  args);
					case ILCode.Ldftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
					}
					case ILCode.Ldvirtftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldvirtftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
					}
					case ILCode.Calli:       return InlineAssembly(byteCode, args);
					case ILCode.Ckfinite:    return InlineAssembly(byteCode, args);
					case ILCode.Constrained: return InlineAssembly(byteCode, args);
					case ILCode.Cpblk:       return InlineAssembly(byteCode, args);
					case ILCode.Cpobj:       return InlineAssembly(byteCode, args);
					case ILCode.Dup:         return arg1;
					case ILCode.Endfilter:   return InlineAssembly(byteCode, args);
					case ILCode.Endfinally:  return null;
					case ILCode.Initblk:     return InlineAssembly(byteCode, args);
					case ILCode.Initobj:      return InlineAssembly(byteCode, args);
				case ILCode.DefaultValue:
					return MakeDefaultValue((TypeReference)operand);
					case ILCode.Jmp: return InlineAssembly(byteCode, args);
				case ILCode.Ldc_I4:
					return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
				case ILCode.Ldc_I8:
					return AstBuilder.MakePrimitive((long)operand, byteCode.InferredType);
				case ILCode.Ldc_R4:
				case ILCode.Ldc_R8:
				case ILCode.Ldc_Decimal:
					return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand);
				case ILCode.Ldsfld:
					return AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand);
				case ILCode.Stfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return new AssignmentExpression(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand), arg2);
				case ILCode.Stsfld:
					return new AssignmentExpression(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand),
						arg1);
				case ILCode.Ldflda:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
				case ILCode.Ldsflda:
					return MakeRef(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand));
					case ILCode.Ldloc: {
						ILVariable v = (ILVariable)operand;
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						Expression expr;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							expr = new ThisReferenceExpression();
						else
							expr = new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand);
						return v.IsParameter && v.Type is ByReferenceType ? MakeRef(expr) : expr;
					}
					case ILCode.Ldloca: {
						ILVariable v = (ILVariable)operand;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							return MakeRef(new ThisReferenceExpression());
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand));
					}
					case ILCode.Ldnull: return new Ast.NullReferenceExpression();
					case ILCode.Ldstr:  return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldtoken:
					if (operand is Cecil.TypeReference) {
						return AstBuilder.CreateTypeOfExpression((TypeReference)operand).Member("TypeHandle");
					} else {
						return InlineAssembly(byteCode, args);
					}
					case ILCode.Leave:    return new GotoStatement() { Label = ((ILLabel)operand).Name };
				case ILCode.Localloc:
					{
						PointerType ptrType = byteCode.InferredType as PointerType;
						TypeReference type;
						if (ptrType != null) {
							type = ptrType.ElementType;
						} else {
							type = typeSystem.Byte;
						}
						return new StackAllocExpression {
							Type = AstBuilder.ConvertType(type),
							CountExpression = DivideBySize(arg1, type)
						};
					}
				case ILCode.Mkrefany:
					{
						DirectionExpression dir = arg1 as DirectionExpression;
						if (dir != null) {
							return new UndocumentedExpression {
								UndocumentedExpressionType = UndocumentedExpressionType.MakeRef,
								Arguments = { dir.Expression.Detach() }
							};
						} else {
							return InlineAssembly(byteCode, args);
						}
					}
				case ILCode.Refanytype:
					return new UndocumentedExpression {
						UndocumentedExpressionType = UndocumentedExpressionType.RefType,
						Arguments = { arg1 }
					}.Member("TypeHandle");
				case ILCode.Refanyval:
					return MakeRef(
						new UndocumentedExpression {
							UndocumentedExpressionType = UndocumentedExpressionType.RefValue,
							Arguments = { arg1, new TypeReferenceExpression(operandAsTypeRef) }
						});
					case ILCode.Newobj: {
						Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
						if (declaringType is ArrayType) {
							ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
							if (ct != null && ct.ArraySpecifiers.Count >= 1) {
								var ace = new Ast.ArrayCreateExpression();
								ct.ArraySpecifiers.First().Remove();
								ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
								ace.Type = ct;
								ace.Arguments.AddRange(args);
								return ace;
							}
						}
						var oce = new Ast.ObjectCreateExpression();
						if (declaringType.IsAnonymousType()) {
							MethodDefinition ctor = ((MethodReference)operand).Resolve();
							if (methodDef != null) {
								oce.Initializer = new ArrayInitializerExpression();
								for (int i = 0; i < args.Count; i++) {
									oce.Initializer.Elements.Add(
										new NamedArgumentExpression {
											Identifier = ctor.Parameters[i].Name,
											Expression = args[i]
										});
								}
							}
							return oce;
						}
						oce.Type = AstBuilder.ConvertType(declaringType);
						oce.Arguments.AddRange(args);
						return oce.WithAnnotation(operand);
					}
					case ILCode.No: return InlineAssembly(byteCode, args);
					case ILCode.Nop: return null;
					case ILCode.Pop: return arg1;
					case ILCode.Readonly: return InlineAssembly(byteCode, args);
				case ILCode.Ret:
					if (methodDef.ReturnType.FullName != "System.Void") {
						return new Ast.ReturnStatement { Expression = arg1 };
					} else {
						return new Ast.ReturnStatement();
					}
					case ILCode.Rethrow: return new Ast.ThrowStatement();
					case ILCode.Sizeof:  return new Ast.SizeOfExpression { Type = operandAsTypeRef };
					case ILCode.Stloc: {
						ILVariable locVar = (ILVariable)operand;
						if (!locVar.IsParameter)
							localVariablesToDefine.Add(locVar);
						return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1);
					}
					case ILCode.Switch: return InlineAssembly(byteCode, args);
					case ILCode.Tail: return InlineAssembly(byteCode, args);
					case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
					case ILCode.Unaligned: return InlineAssembly(byteCode, args);
					case ILCode.Volatile: return InlineAssembly(byteCode, args);
				case ILCode.YieldBreak:
					return new Ast.YieldBreakStatement();
				case ILCode.YieldReturn:
					return new Ast.YieldStatement { Expression = arg1 };
				case ILCode.InitObject:
				case ILCode.InitCollection:
					{
						ArrayInitializerExpression initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							Match m = objectInitializerPattern.Match(args[i]);
							if (m.Success) {
								MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single();
								initializer.Elements.Add(
									new NamedArgumentExpression {
										Identifier = mre.MemberName,
										Expression = m.Get<Expression>("right").Single().Detach()
									}.CopyAnnotationsFrom(mre));
							} else {
								m = collectionInitializerPattern.Match(args[i]);
								if (m.Success) {
									if (m.Get("arg").Count() == 1) {
										initializer.Elements.Add(m.Get<Expression>("arg").Single().Detach());
									} else {
										ArrayInitializerExpression argList = new ArrayInitializerExpression();
										foreach (var expr in m.Get<Expression>("arg")) {
											argList.Elements.Add(expr.Detach());
										}
										initializer.Elements.Add(argList);
									}
								} else {
									initializer.Elements.Add(args[i]);
								}
							}
						}
						ObjectCreateExpression oce = arg1 as ObjectCreateExpression;
						DefaultValueExpression dve = arg1 as DefaultValueExpression;
						if (oce != null) {
							oce.Initializer = initializer;
							return oce;
						} else if (dve != null) {
							oce = new ObjectCreateExpression(dve.Type.Detach());
							oce.CopyAnnotationsFrom(dve);
							oce.Initializer = initializer;
							return oce;
						} else {
							return new AssignmentExpression(arg1, initializer);
						}
					}
				case ILCode.InitializedObject:
					return new InitializedObjectExpression();
				case ILCode.AddressOf:
					return MakeRef(arg1);
				default:
					throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Esempio n. 47
0
			public override object Visit (New newExpression)
			{
				var result = new ObjectCreateExpression ();
				var location = LocationsBag.GetLocations (newExpression);
				result.AddChild (new CSharpTokenNode (Convert (newExpression.Location), "new".Length), ObjectCreateExpression.Roles.Keyword);
				
				if (newExpression.TypeRequested != null)
					result.AddChild (ConvertToType (newExpression.TypeRequested), ObjectCreateExpression.Roles.Type);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), ObjectCreateExpression.Roles.LPar);
				AddArguments (result, location, newExpression.Arguments);
				
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), ObjectCreateExpression.Roles.RPar);
				
				return result;
			}
        public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
        {
            ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses);

            if (objectCreateExpression.Arguments.Any()) {
                if (!objectCreateExpression.LParToken.IsNull)
                    ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses);
            } else {
                if (!objectCreateExpression.LParToken.IsNull)
                    ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses);
            }

            if (!objectCreateExpression.Type.IsNull)
                objectCreateExpression.Type.AcceptVisitor(this);
            objectCreateExpression.Initializer.AcceptVisitor(this);
            FormatArguments(objectCreateExpression);
        }
Esempio n. 49
0
			public override object Visit (NewInitialize newInitializeExpression)
			{
				var result = new ObjectCreateExpression ();
				result.AddChild (new CSharpTokenNode (Convert (newInitializeExpression.Location), "new".Length), ObjectCreateExpression.Roles.Keyword);
				
				if (newInitializeExpression.NewType != null)
					result.AddChild ((INode)newInitializeExpression.NewType.Accept (this), ObjectCreateExpression.Roles.ReturnType);
				
				var location = LocationsBag.GetLocations (newInitializeExpression);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), ObjectCreateExpression.Roles.LPar);
				AddArguments (result, location, newInitializeExpression.NewArguments);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), ObjectCreateExpression.Roles.RPar);
				
				return result;
			}
Esempio n. 50
0
			public override object Visit(NewInitialize newInitializeExpression)
			{
				var result = new ObjectCreateExpression();
				result.AddChild(new CSharpTokenNode(Convert(newInitializeExpression.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole);
				
				if (newInitializeExpression.TypeRequested != null)
					result.AddChild(ConvertToType(newInitializeExpression.TypeRequested), Roles.Type);
				
				var location = LocationsBag.GetLocations(newInitializeExpression);
				if (location != null)
					result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
				AddArguments(result, newInitializeExpression.Arguments);
				if (location != null && location.Count > 1)
					result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
				
				var init = ConvertCollectionOrObjectInitializers(newInitializeExpression.Initializers);
				if (init != null)
					result.AddChild(init, ObjectCreateExpression.InitializerRole);
				
				return result;
			}
Esempio n. 51
0
		AstNode TransformCall(bool isVirtual, ILExpression byteCode, List<Ast.Expression> args)
		{
			Cecil.MethodReference cecilMethod = (MethodReference)byteCode.Operand;
			Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve();
			Ast.Expression target;
			List<Ast.Expression> methodArgs = new List<Ast.Expression>(args);
			if (cecilMethod.HasThis) {
				target = methodArgs[0];
				methodArgs.RemoveAt(0);
				
				// Unpack any DirectionExpression that is used as target for the call
				// (calling methods on value types implicitly passes the first argument by reference)
				if (target is DirectionExpression) {
					target = ((DirectionExpression)target).Expression;
					target.Remove(); // detach from DirectionExpression
				}
				if (cecilMethodDef != null && cecilMethodDef.DeclaringType.IsInterface) {
					TypeReference tr = byteCode.Arguments[0].InferredType;
					if (tr != null) {
						TypeDefinition td = tr.Resolve();
						if (td != null && !td.IsInterface) {
							// Calling an interface method on a non-interface object:
							// we need to introduce an explicit cast
							target = target.CastTo(AstBuilder.ConvertType(cecilMethod.DeclaringType));
						}
					}
				}
			} else {
				target = new TypeReferenceExpression { Type = AstBuilder.ConvertType(cecilMethod.DeclaringType) };
			}
			if (target is ThisReferenceExpression && !isVirtual) {
				// a non-virtual call on "this" might be a "base"-call.
				if (cecilMethod.DeclaringType.GetElementType() != methodDef.DeclaringType) {
					// If we're not calling a method in the current class; we must be calling one in the base class.
					target = new BaseReferenceExpression();
				}
			}
			
			if (cecilMethod.Name == ".ctor" && cecilMethod.DeclaringType.IsValueType) {
				// On value types, the constructor can be called.
				// This is equivalent to 'target = new ValueType(args);'.
				ObjectCreateExpression oce = new ObjectCreateExpression();
				oce.Type = AstBuilder.ConvertType(cecilMethod.DeclaringType);
				AdjustArgumentsForMethodCall(cecilMethod, methodArgs);
				oce.Arguments.AddRange(methodArgs);
				return new AssignmentExpression(target, oce);
			}
			
			if (cecilMethod.Name == "Get" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 1) {
				return target.Indexer(methodArgs);
			} else if (cecilMethod.Name == "Set" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 2) {
				return new AssignmentExpression(target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)), methodArgs.Last());
			}
			
			// Test whether the method is an accessor:
			if (cecilMethodDef != null) {
				if (cecilMethodDef.IsGetter && methodArgs.Count == 0) {
					foreach (var prop in cecilMethodDef.DeclaringType.Properties) {
						if (prop.GetMethod == cecilMethodDef)
							return target.Member(prop.Name).WithAnnotation(prop);
					}
				} else if (cecilMethodDef.IsGetter) { // with parameters
					PropertyDefinition indexer = GetIndexer(cecilMethodDef);
					if (indexer != null)
						return target.Indexer(methodArgs).WithAnnotation(indexer);
				} else if (cecilMethodDef.IsSetter && methodArgs.Count == 1) {
					foreach (var prop in cecilMethodDef.DeclaringType.Properties) {
						if (prop.SetMethod == cecilMethodDef)
							return new Ast.AssignmentExpression(target.Member(prop.Name).WithAnnotation(prop), methodArgs[0]);
					}
				} else if (cecilMethodDef.IsSetter && methodArgs.Count > 1) {
					PropertyDefinition indexer = GetIndexer(cecilMethodDef);
					if (indexer != null)
						return new AssignmentExpression(
							target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)).WithAnnotation(indexer),
							methodArgs[methodArgs.Count - 1]
						);
				} else if (cecilMethodDef.IsAddOn && methodArgs.Count == 1) {
					foreach (var ev in cecilMethodDef.DeclaringType.Events) {
						if (ev.AddMethod == cecilMethodDef) {
							return new Ast.AssignmentExpression {
								Left = target.Member(ev.Name).WithAnnotation(ev),
								Operator = AssignmentOperatorType.Add,
								Right = methodArgs[0]
							};
						}
					}
				} else if (cecilMethodDef.IsRemoveOn && methodArgs.Count == 1) {
					foreach (var ev in cecilMethodDef.DeclaringType.Events) {
						if (ev.RemoveMethod == cecilMethodDef) {
							return new Ast.AssignmentExpression {
								Left = target.Member(ev.Name).WithAnnotation(ev),
								Operator = AssignmentOperatorType.Subtract,
								Right = methodArgs[0]
							};
						}
					}
				} else if (cecilMethodDef.Name == "Invoke" && cecilMethodDef.DeclaringType.BaseType != null && cecilMethodDef.DeclaringType.BaseType.FullName == "System.MulticastDelegate") {
					AdjustArgumentsForMethodCall(cecilMethod, methodArgs);
					return target.Invoke(methodArgs);
				}
			}
			// Default invocation
			AdjustArgumentsForMethodCall(cecilMethodDef ?? cecilMethod, methodArgs);
			return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod);
		}
		public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) {
			CheckByRefArguments( objectCreateExpression.Arguments);
			base.VisitObjectCreateExpression(objectCreateExpression);
		}
Esempio n. 53
0
		public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
		{
			ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses);
			
			if (objectCreateExpression.Arguments.Any()) {
				if (!objectCreateExpression.LParToken.IsNull) {
					ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses);
				}
				if (!objectCreateExpression.RParToken.IsNull) {
					ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesWithinNewParentheses);
				}
			} else {
				if (!objectCreateExpression.LParToken.IsNull) {
					ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses);
				}
				if (!objectCreateExpression.RParToken.IsNull) {
					ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesBetweenEmptyNewParentheses);
				}
			}
			FormatCommas(objectCreateExpression, policy.SpaceBeforeNewParameterComma, policy.SpaceAfterNewParameterComma);
			
			base.VisitObjectCreateExpression(objectCreateExpression);
		}
 public virtual void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(objectCreateExpression);
     }
 }
Esempio n. 55
0
        Expression ConvertNewObject(InvocationExpression invocation)
        {
            if (invocation.Arguments.Count < 1 || invocation.Arguments.Count > 3)
                return NotSupported(invocation);

            Match m = newObjectCtorPattern.Match(invocation.Arguments.First());
            if (!m.Success)
                return NotSupported(invocation);

            MethodReference ctor = m.Get<AstNode>("ctor").Single().Annotation<MethodReference>();
            if (ctor == null)
                return null;

            AstType declaringTypeNode;
            TypeReference declaringType;
            if (m.Has("declaringType")) {
                declaringTypeNode = m.Get<AstType>("declaringType").Single().Clone();
                declaringType = declaringTypeNode.Annotation<TypeReference>();
            } else {
                declaringTypeNode = AstBuilder.ConvertType(ctor.DeclaringType);
                declaringType = ctor.DeclaringType;
            }
            if (declaringTypeNode == null)
                return null;

            ObjectCreateExpression oce = new ObjectCreateExpression(declaringTypeNode);
            if (invocation.Arguments.Count >= 2) {
                IList<Expression> arguments = ConvertExpressionsArray(invocation.Arguments.ElementAtOrDefault(1));
                if (arguments == null)
                    return null;
                oce.Arguments.AddRange(arguments);
            }
            if (invocation.Arguments.Count >= 3 && declaringType.IsAnonymousType()) {
                MethodDefinition resolvedCtor = ctor.Resolve();
                if (resolvedCtor == null || resolvedCtor.Parameters.Count != oce.Arguments.Count)
                    return null;
                AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
                var arguments = oce.Arguments.ToArray();
                if (AstMethodBodyBuilder.CanInferAnonymousTypePropertyNamesFromArguments(arguments, resolvedCtor.Parameters)) {
                    oce.Arguments.MoveTo(atce.Initializers);
                } else {
                    for (int i = 0; i < resolvedCtor.Parameters.Count; i++) {
                        atce.Initializers.Add(
                            new NamedExpression {
                                Name = resolvedCtor.Parameters[i].Name,
                                Expression = arguments[i].Detach()
                            });
                    }
                }
                return atce;
            }

            return oce;
        }
            public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
            {
                UnlockWith(objectCreateExpression);

                return base.VisitObjectCreateExpression(objectCreateExpression, data);
            }
		public virtual void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
		{
			VisitChildren (objectCreateExpression);
		}
Esempio n. 58
0
 public override StringBuilder VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, int data)
 {
     return objectCreateExpression.Type.AcceptVisitor(this, data).Append("(").Append(
         ArgsToString(objectCreateExpression.Arguments)).Append(")");
 }
Esempio n. 59
0
		public void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
		{
			StartNode(objectCreateExpression);
			WriteKeyword(ObjectCreateExpression.NewKeywordRole);
			objectCreateExpression.Type.AcceptVisitor(this);
			bool useParenthesis = objectCreateExpression.Arguments.Any() || objectCreateExpression.Initializer.IsNull;
			// also use parenthesis if there is an '(' token
			if (!objectCreateExpression.LParToken.IsNull) {
				useParenthesis = true;
			}
			if (useParenthesis) {
				Space(policy.SpaceBeforeMethodCallParentheses);
				WriteCommaSeparatedListInParenthesis(objectCreateExpression.Arguments, policy.SpaceWithinMethodCallParentheses);
			}
			objectCreateExpression.Initializer.AcceptVisitor(this);
			EndNode(objectCreateExpression);
		}
Esempio n. 60
0
		public override void VisitCXXMethodDecl(CXXMethodDecl decl, VisitKind visitKind)
		{
			if (!MethodIsBindable (decl, visitKind))
				return;

			var cmethodBuilder = new StringBuilder();

			AstType pinvokeReturn, methodReturn;
			WrapKind returnIsWrapped;
			ICSharpCode.NRefactory.CSharp.ParameterModifier pinvokeMod, methodMod;

			LookupMarshalTypes(decl.ReturnQualType, out pinvokeReturn, out pinvokeMod, out methodReturn, out methodMod, out returnIsWrapped, isReturn: true);
			var methodReturn2 = methodReturn.Clone();

			var propertyInfo = ScanBaseTypes.GetPropertyInfo(decl);
			if (propertyInfo != null) {
				propertyInfo.HostType = currentType;
				if (decl.Name.StartsWith("Get") || decl.Name.StartsWith("Is"))
					propertyInfo.MethodReturn = methodReturn.Clone();
			}

			var methodName = decl.Name;
			if (currentTypeNames.Contains(methodName))
				methodName += (uniqueMethodName++).ToString();
			currentTypeNames.Add(methodName);

			//
			// PInvoke declaration + C counterpart declaration
			//
			string pinvoke_name = currentType.Name + "_" + methodName;
			var isConstructor = decl is CXXConstructorDecl;

			if (isConstructor) {
				pinvokeReturn = new SimpleType ("IntPtr");

				// Do not bind a default constructor for Skeleton
				if (currentType.Name == "Skeleton")
					return;
			}

			var pinvoke = new MethodDeclaration
			{
				Name = pinvoke_name,
				ReturnType = pinvokeReturn,
				Modifiers = Modifiers.Extern | Modifiers.Static | Modifiers.Internal
			};
			if (!decl.IsStatic && !isConstructor)
				pinvoke.Parameters.Add(new ParameterDeclaration(new SimpleType("IntPtr"), "handle"));

			var dllImport = new Attribute { Type = new SimpleType("DllImport") };
			dllImport.Arguments.Add (new PrimitiveExpression ("mono-urho"));
			dllImport.Arguments.Add (new AssignmentExpression (new IdentifierExpression ("CallingConvention"), csParser.ParseExpression ("CallingConvention.Cdecl")));
			pinvoke.Attributes.Add(new AttributeSection(dllImport));

			// The C counterpart
			var cinvoke = new StringBuilder();
			string marshalReturn = "{0}";
			string creturnType = CleanTypeCplusplus(decl.ReturnQualType);

			switch (creturnType) {
			case "bool":
				creturnType = "int";
				break;
			case "Urho3D::StringHash":
				creturnType = "int";
				marshalReturn = "({0}).Value ()";
				break;
			case "Urho3D::String":
			case "const Urho3D::String &":
			case "const class Urho3D::String &":
				creturnType = "const char *";
				marshalReturn = "strdup(({0}).CString ())";
				break;
			case "const struct Urho3D::TileMapInfo2D &":
				creturnType = "Urho3D::TileMapInfo2D";
				break;
			case "const struct Urho3D::CrowdObstacleAvoidanceParams &":
				creturnType = "Urho3D::CrowdObstacleAvoidanceParams";
				break;
			case "const class Urho3D::Vector3 &":
			case "const class Urho3D::Vector2 &":
			case "const class Urho3D::Vector4 &":
			case "const class Urho3D::IntVector2 &":
			case "const class Urho3D::Quaternion &":
			case "const class Urho3D::Plane &":
			case "const class Urho3D::BoundingBox &": 
			case "const class Urho3D::Color &":
				
			case "Urho3D::Vector3":
			case "Urho3D::Vector2":
			case "Urho3D::Vector4":
			case "Urho3D::IntVector2":
			case "Urho3D::Quaternion":
			case "Urho3D::Plane":
			case "Urho3D::BoundingBox":
			case "Urho3D::Color":
				var nsIndex = creturnType.IndexOf ("Urho3D::") + "Urho3D".Length;
				creturnType = "Interop" + creturnType.Remove (0, nsIndex).Trim ('&', ' ') + " ";
				marshalReturn = "*((" + creturnType + " *) &({0}))";
				break;
			}

			if (creturnType.StartsWith("SharedPtr<"))
			{
				creturnType = creturnType.ExtractGenericParameter().DropClassOrStructPrefix() + " *";
				marshalReturn =
					"auto copy = {0};\n" +
					"\tauto plain = copy.Get();\n" +
					"\tcopy.Detach();\n" +
					"\tdelete copy;\n" +
					"\treturn plain;";
			}

			const string methodNameSuffix = "%MethodSuffix%";
			const string variantConverterMask = "%VariantConvertor%";

			if (isConstructor)
				cmethodBuilder.Append($"DllExport void *\n{pinvoke_name}{methodNameSuffix} (");
			else
				cmethodBuilder.Append($"DllExport {creturnType}\n{pinvoke_name}{methodNameSuffix} (");

			if (decl.IsStatic) {
				cinvoke.Append($"{decl.Parent.Name}::{decl.Name} (");

			} else if (isConstructor) {
				cinvoke.Append($"new {decl.Name}(");
			}

			else {
				cmethodBuilder.Append($"Urho3D::{decl.Parent.Name} *_target");
				if (decl.Parameters.Any())
					cmethodBuilder.Append(", ");
				cinvoke.Append($"_target->{decl.Name} (");
			}

			//
			// Method declaration
			//
			MethodDeclaration method = null;
			ConstructorDeclaration constructor = null;

			if (isConstructor) {
				constructor = new ConstructorDeclaration
				{
					Name = RemapMemberName(decl.Parent.Name, decl.Name),

					Modifiers = (decl.IsStatic ? Modifiers.Static : 0) |
						(propertyInfo != null ? Modifiers.Private : Modifiers.Public)  |
						(decl.Name == "ToString" ? Modifiers.Override : 0)
				};
				constructor.Body = new BlockStatement();
			} else {
				method = new MethodDeclaration
				{
					Name = RemapMemberName(decl.Parent.Name, decl.Name),
					ReturnType = methodReturn,
					Modifiers = (decl.IsStatic ? Modifiers.Static : 0) |
						(propertyInfo != null ? Modifiers.Private : Modifiers.Public)
				};
				method.Body = new BlockStatement();
			}

			// 
			// Marshal from C# to C and the C support to call into C++
			//
			var invoke = new InvocationExpression(new IdentifierExpression(pinvoke_name));
			if (!decl.IsStatic && !isConstructor)
				invoke.Arguments.Add(new IdentifierExpression("handle"));
			bool first = true;
			int anonymousParameterNameCount = 1;
			int currentParamCount = -1;
			foreach (var param in decl.Parameters) {
				currentParamCount++;
				AstType pinvokeParameter, parameter;
				WrapKind wrapKind;

				if (!first) {
					cinvoke.Append(", ");
					cmethodBuilder.Append(", ");
				} else
					first = false;

				LookupMarshalTypes(param.QualType, out pinvokeParameter, out pinvokeMod, out parameter, out methodMod, out wrapKind);

				string paramName = param.Name;
				if (string.IsNullOrEmpty(paramName))
					paramName = "param" + (anonymousParameterNameCount++);

				Expression parameterReference = new IdentifierExpression (paramName);
				switch (currentType.Name) {
				case "Input":
					switch (decl.Name) {
					case "GetMouseButtonDown":
					case "GetMouseButtonPress":
						parameter = new SimpleType ("MouseButton");
						parameterReference = new CastExpression (new PrimitiveType ("int"), parameterReference);
						break;
					case "GetKeyPress":
					case "GetKeyDown":
					case "GetScancodeFromKey":
					case "GetKeyName":
						if (currentParamCount == 0 && paramName == "key") {
							parameter = new SimpleType ("Key");
							parameterReference = new CastExpression (new PrimitiveType ("int"), parameterReference);
						}
						break;
					}
					break;
				case "VertexBuffer":
					switch (decl.Name) {
					case "SetSize":
						if (currentParamCount == 1 && paramName == "elementMask") {
							parameter = new SimpleType ("ElementMask");
							parameterReference = new CastExpression (new PrimitiveType ("uint"), parameterReference);
						}
						break;
					case "GetVertexSize":
						if (currentParamCount == 0 && paramName == "elementMask") {
							parameter = new SimpleType ("ElementMask");
							parameterReference = new CastExpression (new PrimitiveType ("uint"), parameterReference);
						}
						break;
					case "GetElementOffset":
						if (currentParamCount == 0 && paramName == "elementMask") {
							parameter = new SimpleType ("ElementMask");
							parameterReference = new CastExpression (new PrimitiveType ("uint"), parameterReference);
						}
						break;
					}
					break;
				case "Log":
					switch (decl.Name) {
					case "Write":
						if (currentParamCount == 0 && paramName == "level") {
							parameter = new SimpleType ("LogLevel");
							parameterReference = new CastExpression (new PrimitiveType ("int"), parameterReference);
						}
						break;
					}
					break;
				}

				if (constructor == null)
					method.Parameters.Add(new ParameterDeclaration(parameter, paramName, methodMod));
				else
					constructor.Parameters.Add(new ParameterDeclaration(parameter, paramName, methodMod));

				pinvoke.Parameters.Add(new ParameterDeclaration(pinvokeParameter, paramName, pinvokeMod));
				switch (wrapKind) {
				case WrapKind.None:
					invoke.Arguments.Add(parameterReference);
					break;
				case WrapKind.HandleMember:
				case WrapKind.UrhoObject:
					var cond = new ConditionalExpression (new BinaryOperatorExpression (new CastExpression (new PrimitiveType ("object"), parameterReference), BinaryOperatorType.Equality, new PrimitiveExpression (null)),
					csParser.ParseExpression ("IntPtr.Zero"), csParser.ParseExpression (paramName + ".Handle"));
					invoke.Arguments.Add (cond);
					break;
				case WrapKind.EventHandler:
					invoke.Arguments.Add(parameterReference);
					break;
				case WrapKind.StringHash:
					invoke.Arguments.Add (csParser.ParseExpression (paramName + ".Code"));
					break;
				case WrapKind.RefBlittable:
					invoke.Arguments.Add (new DirectionExpression (FieldDirection.Ref, parameterReference));
					break;
				case WrapKind.VectorSharedPtr:
					throw new NotImplementedException ("Vector marshaling not supported for parameters yet");
				}

				var ctype = CleanTypeCplusplus (param.QualType);
				string paramInvoke = paramName;
				switch (ctype) {
				case "bool":
					ctype = "int";
					break;
				case "Urho3D::Deserializer &":
				case "Urho3D::Serializer &":
					ctype = "File *";
					paramInvoke = $"*{paramInvoke}";
					break;
				case "const class Urho3D::String &":
					ctype = "const char *";
					paramInvoke = $"Urho3D::String({paramInvoke})";
					break;
				case "Urho3D::StringHash":
					ctype = "int";
					paramInvoke = $"Urho3D::StringHash({paramInvoke})";
					break;
				case "const class Urho3D::Variant &":
					paramInvoke = $"{variantConverterMask}({paramInvoke})";
					break;
				}

				cmethodBuilder.Append($"{ctype} {paramName}");
				cinvoke.Append($"{paramInvoke}");
			}
			cinvoke.Append(")");
			cmethodBuilder.Append(")\n{\n\t");

			// if the type has a ctor accepting Context - add a parameterless one that will use "this(Application.CurrentContext)"
			if (isConstructor &&
				decl.Parameters.Count() == 1 &&
				decl.Parameters.ElementAt(0).QualType.ToString() == "class Urho3D::Context *") {
				var ctor = new ConstructorDeclaration {
						Modifiers = Modifiers.Public,
						Body = new BlockStatement(),
						Initializer = new ConstructorInitializer { ConstructorInitializerType = ConstructorInitializerType.This }
					};
				ctor.Initializer.Arguments.Add(csParser.ParseExpression("Application.CurrentContext"));
				currentType.Members.Add(ctor);
			}

			if (method != null && methodReturn is Sharpie.Bind.Types.VoidType) {
				method.Body.Add(invoke);
				//	pn ($"fprintf (stderr,\"DEBUG {creturnType} {pinvoke_name} (...)\\n\");");
				cmethodBuilder.AppendLine($"{cinvoke.ToString()};");
			} else {
				ReturnStatement ret = null;
				Expression returnExpression;


				if (!isConstructor)
					ret = new ReturnStatement();

				switch (returnIsWrapped) {
				case WrapKind.HandleMember:
					returnExpression = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression ("Runtime"), "LookupRefCounted", methodReturn2), invoke);
					break;
				case WrapKind.UrhoObject:
					returnExpression = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression ("Runtime"), "LookupObject", methodReturn2), invoke);
					break;
				case WrapKind.EventHandler:
					returnExpression = invoke;
					break;
				case WrapKind.StringHash:
					returnExpression = new ObjectCreateExpression (new SimpleType ("StringHash"), invoke);
					break;
				case WrapKind.MarshalPtrToString:
					returnExpression = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression("Marshal"), "PtrToStringAnsi"), invoke);
					break;
				case WrapKind.MarshalPtrToStruct:
					returnExpression = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression("Marshal"), "PtrToStructure"), invoke, new TypeOfExpression(methodReturn2));
					returnExpression = new CastExpression(methodReturn2.Clone(), returnExpression);
					break;
				case WrapKind.VectorSharedPtr:
					var cacheName = "_" + method.Name + "_cache";
					var f = new FieldDeclaration () {
						ReturnType = method.ReturnType.Clone (),
						Modifiers = Modifiers.Private | (method.Modifiers & Modifiers.Static)
					};
					f.Variables.Add (new VariableInitializer (cacheName, null));
					currentType.Members.Add (f);
					
					var sharedPtrType = (methodReturn as SimpleType).TypeArguments.First ().Clone ();
					//TODO: check if UrhoObject
					var create = (sharedPtrType.ToString() == "AnimationState") ? "CreateVectorSharedPtrRefcountedProxy" : "CreateVectorSharedPtrProxy";

					returnExpression = new ConditionalExpression (
						new BinaryOperatorExpression (new IdentifierExpression (cacheName), BinaryOperatorType.InEquality, new PrimitiveExpression (null)),
						new IdentifierExpression (cacheName),
						new AssignmentExpression (
							new IdentifierExpression (cacheName), 
							new InvocationExpression (
								new MemberReferenceExpression (
									new IdentifierExpression ("Runtime"), create, sharedPtrType),
								invoke)));
						
						
					break;
				default:
					returnExpression = invoke;
					break;
				}
				if (ret != null) {
					ret.Expression = returnExpression;
					method.Body.Add(ret);
				} else {
					if (currentType.ClassType == ClassType.Class){
						//usually, the Context is the first object user creates so let's add additional check if engine is inited
						if (currentType.Name == "Context") {
							constructor.Body.Add (new InvocationExpression (new IdentifierExpression ("CheckEngine"), null));
						}
						bool hasBaseTypes = currentType.BaseTypes.Count != 0;
						if (hasBaseTypes) {
							constructor.Initializer = new ConstructorInitializer {
								ConstructorInitializerType = ConstructorInitializerType.Base,
							};
							constructor.Initializer.Arguments.Add(csParser.ParseExpression("UrhoObjectFlag.Empty"));
						}
						var ctorAssign = new AssignmentExpression(new IdentifierExpression("handle"), returnExpression);
						constructor.Body.Add(new ExpressionStatement(ctorAssign));
						if (hasBaseTypes) { 
							constructor.Body.Add (new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression ("Runtime"), "RegisterObject"), new ThisReferenceExpression ()));
						}
					}
				}
				var rstr = String.Format(marshalReturn, cinvoke.ToString());
				CXXRecordDecl returnType;

				//Wrap with WeakPtr all RefCounted subclasses constructors
				if (isConstructor) {
					if (ScanBaseTypes.nameToDecl.TryGetValue(decl.Parent.QualifiedName, out returnType) && returnType.IsDerivedFrom(ScanBaseTypes.UrhoRefCounted))
						rstr = $"WeakPtr<{decl.Name}>({rstr})";
				}

				cmethodBuilder.AppendLine(!rstr.Contains("\treturn ") ? $"return {rstr};" : rstr);
			}
			cmethodBuilder.AppendLine("}\n");

			var code = cmethodBuilder.ToString();

			const string variantArgDef = "const class Urho3D::Variant &";

			//if methods contains Variant argument -- replace it with overloads
			if (code.Contains(variantArgDef))
			{
				var variantSupportedTypes = new Dictionary<string, string>
					{
						//C++ - C# types map
						{"const class Urho3D::Vector3 &", "Vector3"},
						{"const class Urho3D::IntRect &", "IntRect"},
						{"const class Urho3D::Color &", "Color"},
						{"const class Urho3D::Vector2 &", "Vector2"},
						{"const class Urho3D::Vector4 &", "Vector4"},
						{"const class Urho3D::IntVector2 &", "IntVector2"},
						{"const class Urho3D::Quaternion &", "Quaternion"},
						{"int", "int"},
						{"float", "float"},
						{"const char *", "string"},
						//TODO: Matrix, StringHash?
					};
				var primitiveTypes = new[] { "int", "float", "string" };

				pn("// Urho3D::Variant overloads begin:");
				int index = 0;
				foreach (var item in variantSupportedTypes)
				{
					//C:
					p(code
						.Replace(variantArgDef, item.Key)
						.Replace(methodNameSuffix, index.ToString())
						.Replace(variantConverterMask, item.Key == "const char *" ? "Urho3D::String" : string.Empty));
					//methodNameSuffix to avoid error:
					//  error C2733: second C linkage of overloaded function 'function name' not allowed.

					//C#:
					var isPrimitive = primitiveTypes.Contains(item.Value);

					AstType argumentType;
					var argumentModifier = ICSharpCode.NRefactory.CSharp.ParameterModifier.None;
					if (!isPrimitive)
					{
						argumentType = new SimpleType(item.Value);
						argumentModifier = ICSharpCode.NRefactory.CSharp.ParameterModifier.Ref;
					}
					else
					{
						argumentType = new PrimitiveType(item.Value);
					}

					var dllImportItem = (MethodDeclaration)pinvoke.Clone();
					var originalEntryPointName = dllImportItem.Name;
					dllImportItem.Name += index;
					var variantParam = dllImportItem.Parameters.First(p => p.ToString().Contains(variantArgDef));
					variantParam.Type = argumentType.Clone();
					variantParam.ParameterModifier = argumentModifier;
					currentType.Members.Add(dllImportItem);

					var clonedMethod = (MethodDeclaration)method.Clone();
					variantParam = clonedMethod.Parameters.First(p => p.ToString().Contains(variantArgDef));
					variantParam.Type = argumentType.Clone();

					//add 'index' to all EntryPoint invocations inside the method (no mater how complex method body is):
					//and 'ref' keyword for the argument
					clonedMethod.Body.Descendants
						.OfType<InvocationExpression>()
						.Where(ie => ie.Target is IdentifierExpression && ((IdentifierExpression)ie.Target).Identifier == originalEntryPointName)
						.ToList()
						.ForEach(ie =>
							{
								if (!isPrimitive)
								{
									//non-primitive types should be marked with 'ref' keyword
									var argument = ie.Arguments.OfType<IdentifierExpression>().First(arg => arg.Identifier == variantParam.Name);
									ie.Arguments.Remove(argument);
									ie.Arguments.Add(new DirectionExpression(FieldDirection.Ref, argument));
								}

								var exp = (IdentifierExpression)ie.Target;
								exp.Identifier += index;
							});

					currentType.Members.Add(clonedMethod);
					InsertSummaryComments(clonedMethod, StringUtil.GetMethodComments(decl));

					index++;
				}
				pn("// Urho3D::Variant overloads end.");
			}
			//method does not have "Variant" arguments
			else
			{
				//C:
				pn(code
					.Replace(methodNameSuffix, string.Empty)
					.Replace(variantConverterMask, string.Empty));

				//C#:
				currentType.Members.Add(pinvoke);

				if (method == null)
					currentType.Members.Add(constructor);
				else
				{
					currentType.Members.Add(method);
					InsertSummaryComments(method, StringUtil.GetMethodComments(decl));
				}
			}

		}