Beispiel #1
0
 public virtual void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     if (this.ThrowException)
     {
         throw (System.Exception) this.CreateException(arrayInitializerExpression);
     }
 }
 public virtual void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(arrayInitializerExpression);
     }
 }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
 public UnifiedElement VisitArrayInitializerExpression(
     ArrayInitializerExpression arrayInit, object data)
 {
     return(arrayInit.Elements
            .Select(e => e.TryAcceptForExpression(this))
            .ToArrayLiteral());
 }
Beispiel #5
0
 public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     foreach (var element in arrayInitializerExpression.Elements)
     {
         element.AcceptVisitor(this);
     }
 }
Beispiel #6
0
        bool TryHandleAddCall(ExpressionStatement expressionStatement)
        {
            var invocationExpression = expressionStatement.Expression as InvocationExpression;

            if (invocationExpression == null)
            {
                return(false);
            }
            var invocationResolveResult = context.Resolve(invocationExpression) as InvocationResolveResult;

            if (invocationResolveResult == null)
            {
                return(false);
            }
            if (invocationResolveResult.Member.Name != "Add")
            {
                return(false);
            }
            var targetResult = invocationResolveResult.TargetResult;

            if (targetResult is MemberResolveResult)
            {
                return(false);
            }

            var tuple = new ArrayInitializerExpression();

            foreach (var argument in invocationExpression.Arguments)
            {
                var argumentLocalResolveResult = context.Resolve(argument) as LocalResolveResult;
                if (argumentLocalResolveResult != null)
                {
                    var initializerPath = AccessPath.FromResolveResult(argumentLocalResolveResult);
                    if (initializerPath == null || !accessPaths.ContainsKey(initializerPath))
                    {
                        return(false);
                    }
                    // Add a clone, since we do not yet know if this is where the initializer will be used
                    var initializerClone = accessPaths[initializerPath].Clone();
                    tuple.Elements.Add(initializerClone);
                }
                else
                {
                    tuple.Elements.Add(argument.Clone());
                }
            }
            ReplacementNodeHelper.AddReplacementAnnotation(tuple, expressionStatement);

            var targetPath = AccessPath.FromResolveResult(targetResult);

            if (targetPath == null || !accessPaths.ContainsKey(targetPath))
            {
                return(false);
            }
            InsertImplicitInitializersForPath(targetPath);
            var targetInitializer = accessPaths [targetPath];

            AddToInitializer(targetInitializer, tuple);
            return(true);
        }
        private static ArrayInitializerExpression CreateSpatialIndexesExpression(IndexDefinition indexDefinition)
        {
            var spatialIndexes = new ArrayInitializerExpression();

            indexDefinition.SpatialIndexes.ForEach(spatialIndex =>
            {
                var property = new ArrayInitializerExpression();
                property.Elements.Add(new StringLiteralExpression(spatialIndex.Key));

                var value = spatialIndex.Value;
                property.Elements.Add(new ObjectCreateExpression
                {
                    Type        = new PrimitiveType("SpatialOptions"),
                    Initializer = new ArrayInitializerExpression(
                        new NamedExpression("Type", new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType("SpatialFieldType")), value.Type.ToString())),
                        new NamedExpression("Strategy", new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType("SpatialSearchStrategy")), value.Strategy.ToString())),
                        new NamedExpression("MaxTreeLevel", new PrimitiveExpression(value.MaxTreeLevel)),
                        new NamedExpression("MinX", new PrimitiveExpression(value.MinX)),
                        new NamedExpression("MaxX", new PrimitiveExpression(value.MaxX)),
                        new NamedExpression("MinY", new PrimitiveExpression(value.MinY)),
                        new NamedExpression("MaxY", new PrimitiveExpression(value.MaxY)),
                        new NamedExpression("Units", new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType("SpatialUnits")), value.Units.ToString()))
                        )
                });

                spatialIndexes.Elements.Add(property);
            });

            return(spatialIndexes);
        }
        public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
        {
            if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) {
                FixOpenBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken);
                curIndent.Push(IndentType.Block);
                foreach (var init in arrayInitializerExpression.Elements) {
                    FixStatementIndentation(init.StartLocation);
                    init.AcceptVisitor(this);
                }
                curIndent.Pop();
                FixClosingBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.RBraceToken);
            } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) {
                ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken);
                ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken);
                foreach (var init in arrayInitializerExpression.Elements) {
                    ForceSpacesBeforeRemoveNewLines(init);
                    init.AcceptVisitor(this);
                }
            } else {
                var lBrace = arrayInitializerExpression.LBraceToken;
                var rBrace = arrayInitializerExpression.RBraceToken;

                foreach (var child in arrayInitializerExpression.Children) {
                    if (child.Role == Roles.LBrace) {
                        if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) {
                            ForceSpaceBefore(child, true);
                            ForceSpacesAfter(child, true);
                        } else {
                            FixOpenBrace(policy.ArrayInitializerBraceStyle, child);
                        }
                        curIndent.Push(IndentType.Block);
                        continue;
                    }
                    if (child.Role == Roles.RBrace) {
                        curIndent.Pop();
                        if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) {
                            ForceSpaceBefore(child, true);

                        } else {
                            FixClosingBrace(policy.ArrayInitializerBraceStyle, child);
                        }
                        continue;
                    }
                    if (child.Role == Roles.Expression) {
                        if (child.PrevSibling != null) {
                            if (child.PrevSibling.Role == Roles.NewLine)
                                FixIndentation(child);
                            if (child.PrevSibling.Role == Roles.Comma)
                                ForceSpaceBefore(child, true);
                        }
                        child.AcceptVisitor(this);
                        if (child.NextSibling != null && child.NextSibling.Role == Roles.Comma)
                            ForceSpacesAfter(child, false);
                        continue;
                    }

                    child.AcceptVisitor(this);
                }
            }
        }
Beispiel #9
0
 public virtual void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     if (ThrowException)
     {
         throw (Exception)CreateException(arrayInitializerExpression);
     }
 }
Beispiel #10
0
        bool InsertImplicitInitializersForPath(AccessPath path)
        {
            if (accessPaths.ContainsKey(path))
            {
                return(true);
            }

            if (path.MemberPath.Count == 0)
            {
                return(false);
            }
            var parentPath = path.GetParentPath();
            var success    = InsertImplicitInitializersForPath(parentPath);

            if (!success)
            {
                return(false);
            }

            var parentInitializer = accessPaths [parentPath];
            var initializer       = new ArrayInitializerExpression();
            var namedExpression   = new NamedExpression(path.MemberPath [path.MemberPath.Count - 1].Name, initializer);

            AddToInitializer(parentInitializer, namedExpression);
            accessPaths [path] = initializer;
            return(true);
        }
Beispiel #11
0
        ArrayInitializerExpression ConvertElementInit(Expression elementsArray)
        {
            IList <Expression> elements = ConvertExpressionsArray(elementsArray);

            if (elements != null)
            {
                return(new ArrayInitializerExpression(elements));
            }
            Match m = elementInitArrayPattern.Match(elementsArray);

            if (!m.Success)
            {
                return(null);
            }
            ArrayInitializerExpression result = new ArrayInitializerExpression();

            foreach (var elementInit in m.Get <Expression>("addArgumentsArrays"))
            {
                IList <Expression> arguments = ConvertExpressionsArray(elementInit);
                if (arguments == null)
                {
                    return(null);
                }
                result.Elements.Add(new ArrayInitializerExpression(arguments));
            }
            return(result);
        }
Beispiel #12
0
 public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     base.VisitArrayInitializerExpression(arrayInitializerExpression);
     foreach (var expr in arrayInitializerExpression.Elements)
     {
         CheckConversion(ctx.GetExpectedType(expr), expr);
     }
 }
Beispiel #13
0
            public override object VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
            {
                if (arrayInitializerExpression.Parent is ArrayCreateExpression)
                {
                    UnlockWith(arrayInitializerExpression);
                }

                return(base.VisitArrayInitializerExpression(arrayInitializerExpression, data));
            }
            public override object VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
            {
                if(arrayInitializerExpression.Parent is ArrayCreateExpression)
                {
                    UnlockWith(arrayInitializerExpression);
                }

                return base.VisitArrayInitializerExpression(arrayInitializerExpression, data);
            }
        private static ArrayInitializerExpression Clone(ArrayInitializerExpression expression)
        {
            var aie = new ArrayInitializerExpression();

            foreach (var item in expression.Items)
            {
                aie.Items.Add(Clone(item));
            }
            return(aie);
        }
        public Expression ConvertConstantValue(ResolveResult rr)
        {
            if (rr == null)
            {
                throw new ArgumentNullException("rr");
            }
            if (rr is ConversionResolveResult)
            {
                // unpack ConversionResolveResult if necessary
                // (e.g. a boxing conversion or string->object reference conversion)
                rr = ((ConversionResolveResult)rr).Input;
            }

            if (rr is TypeOfResolveResult)
            {
                return(new TypeOfExpression(ConvertType(rr.Type)));
            }
            else if (rr is ArrayCreateResolveResult)
            {
                ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr;
                ArrayCreateExpression    ace  = new ArrayCreateExpression();
                ace.Type = ConvertType(acrr.Type);
                ComposedType composedType = ace.Type as ComposedType;
                if (composedType != null)
                {
                    composedType.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
                    if (!composedType.HasNullableSpecifier && composedType.PointerRank == 0)
                    {
                        ace.Type = composedType.BaseType;
                    }
                }

                if (acrr.SizeArguments != null && acrr.InitializerElements == null)
                {
                    ace.AdditionalArraySpecifiers.FirstOrNullObject().Remove();
                    ace.Arguments.AddRange(acrr.SizeArguments.Select(ConvertConstantValue));
                }
                if (acrr.InitializerElements != null)
                {
                    ArrayInitializerExpression initializer = new ArrayInitializerExpression();
                    initializer.Elements.AddRange(acrr.InitializerElements.Select(ConvertConstantValue));
                    ace.Initializer = initializer;
                }
                return(ace);
            }
            else if (rr.IsCompileTimeConstant)
            {
                return(ConvertConstantValue(rr.Type, rr.ConstantValue));
            }
            else
            {
                return(new ErrorExpression());
            }
        }
        private static ArrayInitializerExpression CreateSuggestionsExpression(IndexDefinition indexDefinition)
        {
            var suggestions = new ArrayInitializerExpression();

            indexDefinition.SuggestionsOptions.ForEach(suggestion =>
            {
                suggestions.Elements.Add(new StringLiteralExpression(suggestion));
            });

            return(suggestions);
        }
        public virtual object Visit(ArrayInitializerExpression arrayInitializerExpression, object data)
        {
            Debug.Assert(arrayInitializerExpression != null);
            Debug.Assert(arrayInitializerExpression.CreateExpressions != null);

            foreach (Expression e in arrayInitializerExpression.CreateExpressions)
            {
                Debug.Assert(e != null);
                e.AcceptVisitor(this, data);
            }
            return(data);
        }
			public override void VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression)
			{
				base.VisitArrayInitializerExpression (arrayInitializerExpression);

				if (arrayInitializerExpression.IsSingleElement)
					return;

				var commaToken = arrayInitializerExpression.RBraceToken.PrevSibling as CSharpTokenNode;
				if (commaToken == null || commaToken.GetText () != ",")
					return;
				AddIssue (commaToken, ctx.TranslateString ("Remove redundant comma in array initializer"),
					script => script.Remove (commaToken));
			}
        private static ArrayInitializerExpression CreateAnalizersExpression(IndexDefinition indexDefinition)
        {
            var analyzers = new ArrayInitializerExpression();

            indexDefinition.Analyzers.ForEach(analyzer =>
            {
                var property = new ArrayInitializerExpression();
                property.Elements.Add(new StringLiteralExpression(analyzer.Key));
                property.Elements.Add(new StringLiteralExpression(analyzer.Value));
                analyzers.Elements.Add(property);
            });

            return(analyzers);
        }
Beispiel #21
0
        /// <inheritdoc />
        public override void Visit(ArrayInitializerExpression arrayInitializerExpression)
        {
            Write("{").WriteSpace();
            for (int i = 0; i < arrayInitializerExpression.Items.Count; i++)
            {
                var expression = arrayInitializerExpression.Items[i];
                if (i > 0)
                {
                    Write(",").WriteSpace();
                }

                VisitDynamic(expression);
            }

            Write("}");
        }
        private static ArrayInitializerExpression CreateExpressionFromStringToEnumDictionary <T>(IEnumerable <KeyValuePair <string, T> > dictionary)
        {
            var elements = new ArrayInitializerExpression();

            dictionary.ForEach(keyValuePair =>
            {
                var property = new ArrayInitializerExpression();
                property.Elements.Add(new StringLiteralExpression(keyValuePair.Key));

                var value = keyValuePair.Value;
                property.Elements.Add(new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType(value.GetType().Name)), value.ToString()));

                elements.Elements.Add(property);
            });
            return(elements);
        }
            public override Expression VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, Expression data)
            {
                if (!(arrayInitializerExpression.Parent is ArrayInitializerExpression))
                {
                    return(base.VisitArrayInitializerExpression(arrayInitializerExpression, data));
                }
                // this a tuple in a collection initializer
                var arguments = arrayInitializerExpression.Elements.Select(element => element.AcceptVisitor(this, null).Clone());
                var method    = new MemberReferenceExpression {
                    Target     = data.Clone(),
                    MemberName = "Add"
                };

                statements.Add(new InvocationExpression(method, arguments));

                return(null);
            }
            public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
            {
                base.VisitArrayInitializerExpression(arrayInitializerExpression);

                if (arrayInitializerExpression.IsSingleElement)
                {
                    return;
                }

                var commaToken = arrayInitializerExpression.RBraceToken.PrevSibling as CSharpTokenNode;

                if (commaToken == null || commaToken.GetText() != ",")
                {
                    return;
                }
                AddIssue(commaToken, ctx.TranslateString("Remove redundant comma in array initializer"),
                         script => script.Remove(commaToken));
            }
 public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     foreach (var a in arrayInitializerExpression.Elements)
     {
         if (a is NamedExpression namedElement)
         {
             var result = resolver.Resolve(namedElement, cancellationToken);
             if (result.IsError)
             {
                 Colorize(namedElement.NameToken, syntaxErrorColor);
             }
             namedElement.Expression.AcceptVisitor(this);
         }
         else
         {
             a.AcceptVisitor(this);
         }
     }
 }
Beispiel #26
0
        public int Visit(ArrayInitializerExpression expression)
        {
            _writer.Write("{ ");

            var first = true;

            foreach (var value in expression.Values)
            {
                if (!first)
                {
                    _writer.Write(", ");
                }

                first = false;
                value.Accept(this);
            }

            _writer.Write(" }");
            return(0);
        }
            public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
            {
                base.VisitArrayInitializerExpression(arrayInitializerExpression);

                if (arrayInitializerExpression.IsSingleElement)
                {
                    return;
                }

                var commaToken = arrayInitializerExpression.RBraceToken.PrevSibling as CSharpTokenNode;

                if (commaToken == null || commaToken.ToString() != ",")
                {
                    return;
                }
                string issueDescription;

                if (arrayInitializerExpression.Parent is ObjectCreateExpression)
                {
                    if (arrayInitializerExpression.Elements.FirstOrNullObject() is NamedExpression)
                    {
                        issueDescription = ctx.TranslateString("Redundant comma in object initializer");
                    }
                    else
                    {
                        issueDescription = ctx.TranslateString("Redundant comma in collection initializer");
                    }
                }
                else
                {
                    issueDescription = ctx.TranslateString("Redundant comma in array initializer");
                }
                AddIssue(new CodeIssue(commaToken,
                                       issueDescription,
                                       ctx.TranslateString("Remove ','"),
                                       script => script.Remove(commaToken))
                {
                    IssueMarker = IssueMarker.GrayOut
                });
            }
Beispiel #28
0
        Expression ConvertMemberInit(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 bindings = ConvertMemberBindings(elementsArray);

            if (bindings == null)
            {
                return(null);
            }
            oce.Initializer = bindings;
            return(oce);
        }
 public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) {
         FixOpenBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken);
         curIndent.Push(IndentType.Block);
         foreach (var init in arrayInitializerExpression.Elements) {
             FixStatementIndentation(init.StartLocation);
             init.AcceptVisitor(this);
         }
         curIndent.Pop();
         FixClosingBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.RBraceToken);
     } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) {
         ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken);
         ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken);
         foreach (var init in arrayInitializerExpression.Elements) {
             ForceSpacesBeforeRemoveNewLines(init);
             init.AcceptVisitor(this);
         }
     } else {
         base.VisitArrayInitializerExpression(arrayInitializerExpression);
     }
 }
Beispiel #30
0
        private static ArrayInitializerExpression CreateSuggestionsExpression(IndexDefinition indexDefinition)
        {
            var suggestions = new ArrayInitializerExpression();

            indexDefinition.Suggestions.ForEach(suggestion =>
            {
                var property = new ArrayInitializerExpression();
                property.Elements.Add(new StringLiteralExpression(suggestion.Key));

                var value = suggestion.Value;
                property.Elements.Add(new ObjectCreateExpression
                {
                    Type        = new PrimitiveType("SuggestionOptions"),
                    Initializer = new ArrayInitializerExpression(
                        new NamedExpression("Distance", new MemberReferenceExpression(new TypeReferenceExpression(new PrimitiveType("StringDistanceTypes")), value.Distance.ToString())),
                        new NamedExpression("Accuracy", new PrimitiveExpression(value.Accuracy))
                        )
                });
                suggestions.Elements.Add(property);
            });

            return(suggestions);
        }
Beispiel #31
0
            public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
            {
                base.VisitArrayInitializerExpression(arrayInitializerExpression);

                if (arrayInitializerExpression.IsSingleElement)
                {
                    return;
                }

                var commaToken = arrayInitializerExpression.RBraceToken.PrevSibling as CSharpTokenNode;

                if (commaToken == null || commaToken.GetText() != ",")
                {
                    return;
                }
                string initializerType;

                if (arrayInitializerExpression.Parent is ObjectCreateExpression)
                {
                    if (arrayInitializerExpression.Elements.FirstOrNullObject() is NamedExpression)
                    {
                        initializerType = "object";
                    }
                    else
                    {
                        initializerType = "collection";
                    }
                }
                else
                {
                    initializerType = "array";
                }
                AddIssue(commaToken,
                         ctx.TranslateString(string.Format("Remove redundant comma in {0} initializer", initializerType)),
                         script => script.Remove(commaToken));
            }
			public override void VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression)
			{
				base.VisitArrayInitializerExpression (arrayInitializerExpression);

				if (arrayInitializerExpression.IsSingleElement)
					return;

				var commaToken = arrayInitializerExpression.RBraceToken.PrevSibling as CSharpTokenNode;
				if (commaToken == null || commaToken.GetText () != ",")
					return;
				string initializerType;
				if (arrayInitializerExpression.Parent is ObjectCreateExpression) {
					if (arrayInitializerExpression.Elements.FirstOrNullObject () is NamedExpression) {
						initializerType = "object";
					} else {
						initializerType = "collection";
					}
				} else {
					initializerType = "array";
				}
				AddIssue (commaToken, 
					ctx.TranslateString (string.Format("Remove redundant comma in {0} initializer", initializerType)),
					script => script.Remove (commaToken));
			}
Beispiel #33
0
		public void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
		{
			StartNode(arrayInitializerExpression);
			// "new List<int> { { 1 } }" and "new List<int> { 1 }" are the same semantically.
			// We also use the same AST for both: we always use two nested ArrayInitializerExpressions
			// for collection initializers, even if the user did not write nested brackets.
			// The output visitor will output nested braces only if they are necessary,
			// or if the braces tokens exist in the AST.
			bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1
					&& IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)
					&& !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());
			if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) {
				arrayInitializerExpression.Elements.Single().AcceptVisitor(this);
			} else {
				PrintInitializerElements(arrayInitializerExpression.Elements);
			}
			EndNode(arrayInitializerExpression);
		}
 public override StringBuilder VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, int data)
 {
     throw new NotImplementedException();
 }
Beispiel #35
0
			public override object Visit(ArrayCreation arrayCreationExpression)
			{
				var result = new ArrayCreateExpression();
				
				var location = LocationsBag.GetLocations(arrayCreationExpression);
				result.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Location), ArrayCreateExpression.NewKeywordRole), ArrayCreateExpression.NewKeywordRole);
				if (arrayCreationExpression.TypeExpression != null)
					result.AddChild(ConvertToType(arrayCreationExpression.TypeExpression), Roles.Type);
				
				var next = arrayCreationExpression.Rank;
				if (arrayCreationExpression.Arguments != null) {
					// skip first array rank.
					next = next.Next;
					
					if (location != null)
						result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBracket), Roles.LBracket);
					
					var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Arguments);
					for (int i = 0; i < arrayCreationExpression.Arguments.Count; i++) {
						var arg = arrayCreationExpression.Arguments [i];
						if (arg != null)
							result.AddChild((Expression)arg.Accept(this), Roles.Argument);
						if (commaLocations != null && i < commaLocations.Count)
							result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
					}
					if (location != null && location.Count > 1)
						result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBracket), Roles.RBracket);
					
				}
				
				while (next != null) {
					var spec = new ArraySpecifier(next.Dimension);
					var loc = LocationsBag.GetLocations(next);
					spec.AddChild(new CSharpTokenNode(Convert(next.Location), Roles.LBracket), Roles.LBracket);
					result.AddChild(spec, ArrayCreateExpression.AdditionalArraySpecifierRole);
					if (loc != null)
						result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.RBracket), Roles.RBracket);
					next = next.Next;
				}
				
				if (arrayCreationExpression.Initializers != null) {
					var initLocation = LocationsBag.GetLocations(arrayCreationExpression.Initializers);
					var initializer = new ArrayInitializerExpression();
					
					initializer.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Initializers.Location), Roles.LBrace), Roles.LBrace);
					var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Initializers.Elements);
					for (int i = 0; i < arrayCreationExpression.Initializers.Count; i++) {
						var init = arrayCreationExpression.Initializers [i];
						if (init == null)
							continue;
						initializer.AddChild((Expression)init.Accept(this), Roles.Expression);
						if (commaLocations != null && i < commaLocations.Count) {
							initializer.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
						}
					}
					if (initLocation != null) {
						if (initLocation.Count == 2) // optional comma
							initializer.AddChild(new CSharpTokenNode(Convert(initLocation [0]), Roles.Comma), Roles.Comma);
						initializer.AddChild(new CSharpTokenNode(Convert(initLocation [initLocation.Count - 1]), Roles.RBrace), Roles.RBrace);
					}
					result.AddChild(initializer, ArrayCreateExpression.InitializerRole);
				}
				
				return result;
			}
Beispiel #36
0
			ArrayInitializerExpression ConvertCollectionOrObjectInitializers(CollectionOrObjectInitializers minit)
			{
				if (minit == null)
					return null;
				var init = new ArrayInitializerExpression();
				AddConvertCollectionOrObjectInitializers(init, minit);
				return init;
			}
Beispiel #37
0
 public override object VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, object data)
 {
     // no calls allowed !!!
     return(null);
 }
 ArrayInitializerExpression ConvertElementInit(Expression elementsArray)
 {
     IList<Expression> elements = ConvertExpressionsArray(elementsArray);
     if (elements != null) {
         return new ArrayInitializerExpression(elements);
     }
     Match m = elementInitArrayPattern.Match(elementsArray);
     if (!m.Success)
         return null;
     ArrayInitializerExpression result = new ArrayInitializerExpression();
     foreach (var elementInit in m.Get<Expression>("addArgumentsArrays")) {
         IList<Expression> arguments = ConvertExpressionsArray(elementInit);
         if (arguments == null)
             return null;
         result.Elements.Add(new ArrayInitializerExpression(arguments));
     }
     return result;
 }
Beispiel #39
0
			void AddConvertCollectionOrObjectInitializers (Expression init, CollectionOrObjectInitializers minit)
			{
				var initLoc = LocationsBag.GetLocations (minit);
				var commaLoc = LocationsBag.GetLocations (minit.Initializers);
				int curComma = 0;
				if (initLoc != null)
					init.AddChild (new CSharpTokenNode (Convert (initLoc [0]), 1), ArrayInitializerExpression.Roles.LBrace);
				foreach (var expr in minit.Initializers) {
					var collectionInit = expr as CollectionElementInitializer;
					if (collectionInit != null) {
						var parent = new ArrayInitializerExpression ();
						
						var braceLocs = LocationsBag.GetLocations (expr);
						if (braceLocs != null)
							parent.AddChild (new CSharpTokenNode (Convert (braceLocs [0]), 1), ArrayInitializerExpression.Roles.LBrace);
						
						for (int i = 0; i < collectionInit.Arguments.Count; i++) {
							var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument;
							if (arg == null)
								continue;
							parent.AddChild ((ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept (this), ArrayInitializerExpression.Roles.Expression);
						}
						
						if (braceLocs != null)
							parent.AddChild (new CSharpTokenNode (Convert (braceLocs [1]), 1), ArrayInitializerExpression.Roles.RBrace);
							
						init.AddChild (parent, ArrayInitializerExpression.Roles.Expression);
					} else {
						var eleInit = expr as ElementInitializer;
						if (eleInit != null) {
							var nexpr = new NamedExpression ();
							nexpr.AddChild (Identifier.Create (eleInit.Name, Convert (eleInit.Location)), NamedArgumentExpression.Roles.Identifier);
							var assignLoc = LocationsBag.GetLocations (eleInit);
							if (assignLoc != null)
								nexpr.AddChild (new CSharpTokenNode (Convert (assignLoc [0]), 1), NamedArgumentExpression.Roles.Assign);
							if (eleInit.Source != null) {
								if (eleInit.Source is CollectionOrObjectInitializers) {
									var arrInit = new ArrayInitializerExpression ();
									AddConvertCollectionOrObjectInitializers (arrInit, eleInit.Source as CollectionOrObjectInitializers);
									nexpr.AddChild (arrInit, NamedArgumentExpression.Roles.Expression);
								} else {
									nexpr.AddChild ((Expression)eleInit.Source.Accept (this), NamedArgumentExpression.Roles.Expression);
								}
							}
							
							init.AddChild (nexpr, ArrayInitializerExpression.Roles.Expression);
						}
					}
					if (commaLoc != null && curComma < commaLoc.Count)
						init.AddChild (new CSharpTokenNode (Convert (commaLoc [curComma++]), 1), ArrayInitializerExpression.Roles.Comma);
					
				}
				if (initLoc != null) {
					if (initLoc.Count == 3) // optional comma
						init.AddChild (new CSharpTokenNode (Convert (initLoc [1]), 1), ArrayInitializerExpression.Roles.Comma);
					init.AddChild (new CSharpTokenNode (Convert (initLoc [initLoc.Count - 1]), 1), ArrayInitializerExpression.Roles.RBrace);
				}
			}
 public override object Visit(ArrayInitializerExpression arrayInitializerExpression, object data)
 {
     // no calls allowed !!!
     return null;
 }
			public override object Visit (ArrayInitializer arrayInitializer)
			{
				var result = new ArrayInitializerExpression ();
				var location = LocationsBag.GetLocations (arrayInitializer);
				result.AddChild (new CSharpTokenNode (Convert (arrayInitializer.Location), "[".Length), ArrayInitializerExpression.Roles.LBracket);
				var commaLocations = LocationsBag.GetLocations (arrayInitializer.Elements);
				for (int i = 0; i < arrayInitializer.Count; i++) {
					result.AddChild ((AstNode)arrayInitializer[i].Accept (this), ArrayInitializerExpression.Roles.Initializer);
					if (commaLocations != null && i < commaLocations.Count)
						result.AddChild (new CSharpTokenNode (Convert (commaLocations[i]), ",".Length), ArrayInitializerExpression.Roles.Comma);
				}
				
				if (location != null) {
					if (location.Count == 2) // optional comma
						result.AddChild (new CSharpTokenNode (Convert (location[1]), ",".Length), ArrayInitializerExpression.Roles.Comma);
					result.AddChild (new CSharpTokenNode (Convert (location[location.Count - 1]), "]".Length), ArrayInitializerExpression.Roles.RBracket);
				}
				return result;
			}
Beispiel #42
0
 public ArrayInitializerBlock(IEmitter emitter, ArrayInitializerExpression arrayInitializerExpression)
     : base(emitter, arrayInitializerExpression)
 {
     this.Emitter = emitter;
     this.ArrayInitializerExpression = arrayInitializerExpression;
 }
Beispiel #43
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);
			}
		}
			ArrayInitializerExpression ConvertCollectionOrObjectInitializers (CollectionOrObjectInitializers minit)
			{
				if (minit == null)
					return null;
				var init = new ArrayInitializerExpression ();
				var braceLocs = LocationsBag.GetLocations (minit);
				if (braceLocs != null)
					init.AddChild (new CSharpTokenNode (Convert (braceLocs[0]), 1), ArrayInitializerExpression.Roles.LBrace);
				AddConvertCollectionOrObjectInitializers (init, minit);
				if (braceLocs != null)
					init.AddChild (new CSharpTokenNode (Convert (braceLocs[1]), 1), ArrayInitializerExpression.Roles.RBrace);
				return init;
			}
Beispiel #45
0
 public override StringBuilder VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, int data)
 {
     throw new NotImplementedException();
 }
Beispiel #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);
					#endregion
					#region Arrays
				case ILCode.Newarr:
					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);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						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);
					#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:   return arg1.CastTo(typeof(float));
					case ILCode.Conv_R8:   return arg1.CastTo(typeof(double));
					case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO
				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:      return arg1.CastTo(operandAsTypeRef);
					case ILCode.Isinst:         return arg1.CastAs(operandAsTypeRef);
					case ILCode.Box:            return arg1;
					case ILCode.Unbox:          return InlineAssembly(byteCode, args);
					#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 InlineAssembly(byteCode, args);
					case ILCode.Break:    return InlineAssembly(byteCode, args);
					case ILCode.Call:     return TransformCall(false, operand, methodDef, args);
					case ILCode.Callvirt: return TransformCall(true, operand, methodDef, 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:
					if (args[0] is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), MakeDefaultValue((TypeReference)operand));
					else
						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:  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 new Ast.TypeOfExpression { Type = operandAsTypeRef }.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: return InlineAssembly(byteCode, args);
					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();
						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.Refanytype: return InlineAssembly(byteCode, args);
					case ILCode.Refanyval: 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.InitCollection: {
						ObjectCreateExpression oce = (ObjectCreateExpression)arg1;
						oce.Initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							ArrayInitializerExpression aie = args[i] as ArrayInitializerExpression;
							if (aie != null && aie.Elements.Count == 1)
								oce.Initializer.Elements.Add(aie.Elements.Single().Detach());
							else
								oce.Initializer.Elements.Add(args[i]);
						}
						return oce;
					}
					case ILCode.InitCollectionAddMethod: {
						var collectionInit = new ArrayInitializerExpression();
						collectionInit.Elements.AddRange(args);
						return collectionInit;
					}
					default: throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Beispiel #47
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:
					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);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						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 InlineAssembly(byteCode, args);
					#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:
					if (args[0] is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), MakeDefaultValue((TypeReference)operand));
					else
						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 new Ast.TypeOfExpression { Type = operandAsTypeRef }.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;
						if (oce != null) {
							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);
			}
		}
Beispiel #48
0
			public override object Visit (ArrayInitializer arrayInitializer)
			{
				var result = new ArrayInitializerExpression ();
				var location = LocationsBag.GetLocations (arrayInitializer);
				var commaLocations = LocationsBag.GetLocations (arrayInitializer.Elements);
				for (int i = 0; i < arrayInitializer.Count; i++) {
					result.AddChild((Expression)arrayInitializer[i].Accept(this), ArrayInitializerExpression.Roles.Expression);
				}
				
				return result;
			}
        ArrayInitializerExpression ConvertMemberBindings(Expression elementsArray)
        {
            Match m = memberBindingArrayPattern.Match(elementsArray);
            if (!m.Success)
                return null;
            ArrayInitializerExpression result = new ArrayInitializerExpression();
            foreach (var binding in m.Get<Expression>("binding")) {
                InvocationExpression bindingInvocation = binding as InvocationExpression;
                if (bindingInvocation == null || bindingInvocation.Arguments.Count != 2)
                    return null;
                MemberReferenceExpression bindingMRE = bindingInvocation.Target as MemberReferenceExpression;
                if (bindingMRE == null || !expressionTypeReference.IsMatch(bindingMRE.Target))
                    return null;

                Expression bindingTarget = bindingInvocation.Arguments.ElementAt(0);
                Expression bindingValue = bindingInvocation.Arguments.ElementAt(1);

                string memberName;
                Match m2 = getMethodFromHandlePattern.Match(bindingTarget);
                if (m2.Success) {
                    MethodReference setter = m2.Get<AstNode>("method").Single().Annotation<MethodReference>();
                    if (setter == null)
                        return null;
                    memberName = GetPropertyName(setter);
                } else {
                    return null;
                }

                Expression convertedValue;
                switch (bindingMRE.MemberName) {
                    case "Bind":
                        convertedValue = Convert(bindingValue);
                        break;
                    case "MemberBind":
                        convertedValue = ConvertMemberBindings(bindingValue);
                        break;
                    case "ListBind":
                        convertedValue = ConvertElementInit(bindingValue);
                        break;
                    default:
                        return null;
                }
                if (convertedValue == null)
                    return null;
                result.Elements.Add(new NamedExpression(memberName, convertedValue));
            }
            return result;
        }
 public abstract StringBuilder VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, int data);
Beispiel #51
0
 /// <summary>
 ///     Translates an array initializer, e.g. "{1, 2, 3, 4, ...}".
 /// </summary>
 public override StringBuilder VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitExpr)
 {
     return(JoinArgs(arrayInitExpr.Elements));
 }
        public Expression ConvertConstantValue(ResolveResult rr)
        {
            if (rr == null)
                throw new ArgumentNullException("rr");
            if (rr is ConversionResolveResult) {
                // unpack ConversionResolveResult if necessary
                // (e.g. a boxing conversion or string->object reference conversion)
                rr = ((ConversionResolveResult)rr).Input;
            }

            if (rr is TypeOfResolveResult) {
                return new TypeOfExpression(ConvertType(rr.Type));
            } else if (rr is ArrayCreateResolveResult) {
                ArrayCreateResolveResult acrr = (ArrayCreateResolveResult)rr;
                ArrayCreateExpression ace = new ArrayCreateExpression();
                ace.Type = ConvertType(acrr.Type);
                ComposedType composedType = ace.Type as ComposedType;
                if (composedType != null) {
                    composedType.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
                    if (!composedType.HasNullableSpecifier && composedType.PointerRank == 0)
                        ace.Type = composedType.BaseType;
                }

                if (acrr.SizeArguments != null && acrr.InitializerElements == null) {
                    ace.AdditionalArraySpecifiers.FirstOrNullObject().Remove();
                    ace.Arguments.AddRange(acrr.SizeArguments.Select(ConvertConstantValue));
                }
                if (acrr.InitializerElements != null) {
                    ArrayInitializerExpression initializer = new ArrayInitializerExpression();
                    initializer.Elements.AddRange(acrr.InitializerElements.Select(ConvertConstantValue));
                    ace.Initializer = initializer;
                }
                return ace;
            } else if (rr.IsCompileTimeConstant) {
                return ConvertConstantValue(rr.Type, rr.ConstantValue);
            } else {
                return new ErrorExpression();
            }
        }
Beispiel #53
0
			void AddConvertCollectionOrObjectInitializers(Expression init, CollectionOrObjectInitializers minit)
			{
				var initLoc = LocationsBag.GetLocations(minit);
				var commaLoc = LocationsBag.GetLocations(minit.Initializers);
				int curComma = 0;
				init.AddChild(new CSharpTokenNode(Convert(minit.Location), Roles.LBrace), Roles.LBrace);
				foreach (var expr in minit.Initializers) {
					var collectionInit = expr as CollectionElementInitializer;
					if (collectionInit != null) {
						AstNode parent;
						// For ease of use purposes in the resolver the ast representation
						// of { a, b, c }  is { {a}, {b}, {c} } - but the generated ArrayInitializerExpression
						// can be identified by expr.IsSingleElement.
						if (!collectionInit.IsSingle) {
							parent = new ArrayInitializerExpression();
							parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location), Roles.LBrace), Roles.LBrace);
						} else {
							parent = ArrayInitializerExpression.CreateSingleElementInitializer();
						}

						if (collectionInit.Arguments != null) {
							for (int i = 0; i < collectionInit.Arguments.Count; i++) {
								var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument;
								if (arg == null || arg.Expr == null)
									continue;
								parent.AddChild(
									(Expression)arg.Expr.Accept(this),
									Roles.Expression
								);
							}
						}

						if (!collectionInit.IsSingle) {
							var braceLocs = LocationsBag.GetLocations(expr);
							if (braceLocs != null)
								parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0]), Roles.RBrace), Roles.RBrace);
						}
						init.AddChild((ArrayInitializerExpression)parent, Roles.Expression);
					} else {
						var eleInit = expr as ElementInitializer;
						if (eleInit != null) {
							var nexpr = new NamedExpression();
							nexpr.AddChild(
								Identifier.Create(eleInit.Name, Convert(eleInit.Location)),
								Roles.Identifier
							);
							var assignLoc = LocationsBag.GetLocations(eleInit);
							if (assignLoc != null)
								nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0]), Roles.Assign), Roles.Assign);
							if (eleInit.Source != null) {
								var colInit = eleInit.Source as CollectionOrObjectInitializers;
								if (colInit != null) {
									var arrInit = new ArrayInitializerExpression();
									AddConvertCollectionOrObjectInitializers(
										arrInit,
										colInit
									);
									nexpr.AddChild(arrInit, Roles.Expression);
								} else {
									nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression);
								}
							}

							init.AddChild(nexpr, Roles.Expression);
						}
					}
					if (commaLoc != null && curComma < commaLoc.Count)
						init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++]), Roles.Comma), Roles.Comma);
				}

				if (initLoc != null) {
					if (initLoc.Count == 2) // optional comma
						init.AddChild(new CSharpTokenNode(Convert(initLoc [0]), Roles.Comma), Roles.Comma);
					init.AddChild(new CSharpTokenNode(Convert(initLoc [initLoc.Count - 1]), Roles.RBrace), Roles.RBrace);
				}
			}
		bool TryHandleAddCall(ExpressionStatement expressionStatement)
		{
			var invocationExpression = expressionStatement.Expression as InvocationExpression;
			if (invocationExpression == null)
				return false;
			var invocationResolveResult = context.Resolve(invocationExpression) as InvocationResolveResult;
			if (invocationResolveResult == null)
				return false;
			if (invocationResolveResult.Member.Name != "Add")
				return false;
			var targetResult = invocationResolveResult.TargetResult;
			if (targetResult is MemberResolveResult)
				return false;

			var tuple = new ArrayInitializerExpression();
			foreach (var argument in invocationExpression.Arguments) {
				var argumentLocalResolveResult = context.Resolve(argument) as LocalResolveResult;
				if (argumentLocalResolveResult != null) {
					var initializerPath = AccessPath.FromResolveResult(argumentLocalResolveResult);
					if (initializerPath == null || !accessPaths.ContainsKey(initializerPath))
						return false;
					// Add a clone, since we do not yet know if this is where the initializer will be used
					var initializerClone = accessPaths[initializerPath].Clone();
					tuple.Elements.Add(initializerClone);
				} else {
					tuple.Elements.Add(argument.Clone());
				}
			}
			ReplacementNodeHelper.AddReplacementAnnotation(tuple, expressionStatement);

			var targetPath = AccessPath.FromResolveResult(targetResult);
			if (targetPath == null || !accessPaths.ContainsKey(targetPath))
				return false;
			InsertImplicitInitializersForPath(targetPath);
			var targetInitializer = accessPaths [targetPath];
			AddToInitializer(targetInitializer, tuple);
			return true;
		}
Beispiel #55
0
			public override object Visit(ArrayInitializer arrayInitializer)
			{
				var result = new ArrayInitializerExpression();
				var location = LocationsBag.GetLocations(arrayInitializer);
				result.AddChild(new CSharpTokenNode(Convert(arrayInitializer.Location), Roles.LBrace), Roles.LBrace);
				var commaLocations = LocationsBag.GetLocations(arrayInitializer.Elements);
				for (int i = 0; i < arrayInitializer.Count; i++) {
					var init = arrayInitializer [i];
					if (init == null)
						continue;
					result.AddChild((Expression)init.Accept(this), Roles.Expression);
					if (commaLocations != null && i < commaLocations.Count)
						result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
				}
				
				if (location != null) {
					if (location.Count == 2) // optional comma
						result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Comma), Roles.Comma);
					result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.RBrace), Roles.RBrace);
				}
				return result;
			}
		bool InsertImplicitInitializersForPath(AccessPath path)
		{
			if (accessPaths.ContainsKey(path))
				return true;

			if (path.MemberPath.Count == 0)
				return false;
			var parentPath = path.GetParentPath();
			var success = InsertImplicitInitializersForPath(parentPath);
			if (!success)
				return false;

			var parentInitializer = accessPaths [parentPath];
			var initializer = new ArrayInitializerExpression();
			var namedExpression = new NamedExpression(path.MemberPath [path.MemberPath.Count - 1].Name, initializer);
			AddToInitializer(parentInitializer, namedExpression);
			accessPaths [path] = initializer;
			return true;
		}
		public virtual void VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression)
		{
			VisitChildren (arrayInitializerExpression);
		}
 public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
 {
     new ArrayInitializerBlock(this, arrayInitializerExpression).Emit();
 }
Beispiel #59
0
 public ArrayInitializerBlock(IEmitter emitter, ArrayInitializerExpression arrayInitializerExpression)
     : base(emitter, arrayInitializerExpression)
 {
     this.Emitter = emitter;
     this.ArrayInitializerExpression = arrayInitializerExpression;
 }
			public override object Visit (ArrayCreation arrayCreationExpression)
			{
				var result = new ArrayCreateExpression ();
				
				var location = LocationsBag.GetLocations (arrayCreationExpression);
				if (arrayCreationExpression.NewType != null)
					result.AddChild (ConvertToType (arrayCreationExpression.NewType), ArrayCreateExpression.Roles.Type);
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), ArrayCreateExpression.Roles.LBracket);
				if (arrayCreationExpression.Arguments != null) {
					var commaLocations = LocationsBag.GetLocations (arrayCreationExpression.Arguments);
					for (int i = 0 ;i < arrayCreationExpression.Arguments.Count; i++) {
						result.AddChild ((Expression)arrayCreationExpression.Arguments[i].Accept (this), ArrayCreateExpression.Roles.Argument);
						if (commaLocations != null && i > 0)
							result.AddChild (new CSharpTokenNode (Convert (commaLocations [commaLocations.Count - i]), 1), ArrayCreateExpression.Roles.Comma);
					}
				}
				var next = arrayCreationExpression.Rank.Next;
				while (next != null) {
					ArraySpecifier spec = new ArraySpecifier (next.Dimension);
					var loc = LocationsBag.GetLocations (next);
					spec.AddChild (new CSharpTokenNode (Convert (next.Location), 1), ArraySpecifier.Roles.LBracket);
					if (loc != null)
						result.AddChild (new CSharpTokenNode (Convert (loc[0]), 1), ArraySpecifier.Roles.RBracket);
					result.AddChild (spec, ArrayCreateExpression.AdditionalArraySpecifierRole);
					next = next.Next;
				}
				
				if (location != null)
					result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), ArrayCreateExpression.Roles.RBracket);
				
				if (arrayCreationExpression.Initializers != null && arrayCreationExpression.Initializers.Count != 0) {
					var initLocation = LocationsBag.GetLocations (arrayCreationExpression.Initializers);
					ArrayInitializerExpression initializer = new ArrayInitializerExpression();
					
					initializer.AddChild (new CSharpTokenNode (Convert (arrayCreationExpression.Initializers.Location), 1), ArrayCreateExpression.Roles.LBrace);
					var commaLocations = LocationsBag.GetLocations (arrayCreationExpression.Initializers.Elements);
					for (int i = 0; i < arrayCreationExpression.Initializers.Count; i++) {
						initializer.AddChild ((Expression)arrayCreationExpression.Initializers[i].Accept (this), ArrayInitializerExpression.Roles.Expression);
						if (commaLocations != null && i > 0) {
							initializer.AddChild (new CSharpTokenNode (Convert (commaLocations [commaLocations.Count - i]), 1), IndexerExpression.Roles.Comma);
						}
					}
					
					if (initLocation != null)
						initializer.AddChild (new CSharpTokenNode (Convert (initLocation[initLocation.Count - 1]), 1), ArrayCreateExpression.Roles.RBrace);
					result.AddChild (initializer, ArrayCreateExpression.InitializerRole);
				}
				
				return result;
			}