public void Run (RefactoringContext context)
		{
			var foreachStatement = GetForeachStatement (context);
			
			var result = context.ResolveType (foreachStatement.InExpression);
			var countProperty = GetCountProperty (result);
			
			var initializer = new VariableDeclarationStatement (new PrimitiveType ("int"), "i", new PrimitiveExpression (0));
			var id1 = new IdentifierExpression ("i");
			var id2 = id1.Clone ();
			var id3 = id1.Clone ();
			
			var forStatement = new ForStatement () {
				Initializers = { initializer },
				Condition = new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new MemberReferenceExpression (foreachStatement.InExpression.Clone (), countProperty)),
				Iterators = { new ExpressionStatement (new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2)) },
				EmbeddedStatement = new BlockStatement {
					new VariableDeclarationStatement (foreachStatement.VariableType.Clone (), foreachStatement.VariableName, new IndexerExpression (foreachStatement.InExpression.Clone (), id3))
				}
			};
			
			if (foreachStatement.EmbeddedStatement is BlockStatement) {
				foreach (var child in ((BlockStatement)foreachStatement.EmbeddedStatement).Statements) {
					forStatement.EmbeddedStatement.AddChild (child.Clone (), BlockStatement.StatementRole);
				}
			} else {
				forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole);
			}
			
			using (var script = context.StartScript ()) {
				script.Replace (foreachStatement, forStatement);
				script.Link (initializer.Variables.First ().NameToken, id1, id2, id3);
			}
		}
        public IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            var foreachStatement = GetForeachStatement(context);

            if (foreachStatement == null)
            {
                yield break;
            }
            yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script =>
            {
                var result = context.Resolve(foreachStatement.InExpression);
                var countProperty = GetCountProperty(result.Type);

                // TODO: use another variable name if 'i' is already in use
                var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), "i", new PrimitiveExpression(0));
                var id1 = new IdentifierExpression("i");
                var id2 = id1.Clone();
                var id3 = id1.Clone();

                var variableDeclarationStatement = new VariableDeclarationStatement(
                    foreachStatement.VariableType.Clone(),
                    foreachStatement.VariableName,
                    new IndexerExpression(foreachStatement.InExpression.Clone(), id3)
                    );
                var forStatement = new ForStatement()
                {
                    Initializers = { initializer },
                    Condition = new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new MemberReferenceExpression(foreachStatement.InExpression.Clone(), countProperty)),
                    Iterators = { new ExpressionStatement(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2)) },
                    EmbeddedStatement = new BlockStatement
                    {
                        variableDeclarationStatement
                    }
                };

                if (foreachStatement.EmbeddedStatement is BlockStatement)
                {
                    variableDeclarationStatement.Remove();
                    var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
                    if (oldBlock.Statements.Any())
                    {
                        oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
                    }
                    else
                    {
                        oldBlock.Statements.Add(variableDeclarationStatement);
                    }
                    forStatement.EmbeddedStatement = oldBlock;
                }
                else
                {
                    forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole);
                }
                script.Replace(foreachStatement, forStatement);
                script.Link(initializer.Variables.First().NameToken, id1, id2, id3);
            }));
        }
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var foreachStatement = GetForeachStatement(context);
			if (foreachStatement == null) {
				yield break;
			}
			yield return new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => {
				var result = context.Resolve(foreachStatement.InExpression);
				var countProperty = GetCountProperty(result.Type);
				
				// TODO: use another variable name if 'i' is already in use
				var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), "i", new PrimitiveExpression(0));
				var id1 = new IdentifierExpression("i");
				var id2 = id1.Clone();
				var id3 = id1.Clone();
				
				var variableDeclarationStatement = new VariableDeclarationStatement(
					foreachStatement.VariableType.Clone(),
					foreachStatement.VariableName,
					new IndexerExpression(foreachStatement.InExpression.Clone(), id3)
				);
				var forStatement = new ForStatement() {
					Initializers = { initializer },
					Condition = new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new MemberReferenceExpression (foreachStatement.InExpression.Clone (), countProperty)),
					Iterators = { new ExpressionStatement (new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2)) },
					EmbeddedStatement = new BlockStatement {
						variableDeclarationStatement
					}
				};
				
				if (foreachStatement.EmbeddedStatement is BlockStatement) {
					variableDeclarationStatement.Remove();
					var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
					if (oldBlock.Statements.Any()) {
						oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
					} else {
						oldBlock.Statements.Add(variableDeclarationStatement);
					}
					forStatement.EmbeddedStatement = oldBlock;
				} else {
					forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole);
				}
				script.Replace (foreachStatement, forStatement);
				script.Link (initializer.Variables.First ().NameToken, id1, id2, id3);
			});
		}
        public void Run(RefactoringContext context)
        {
            var foreachStatement = GetForeachStatement(context);

            var result        = context.Resolve(foreachStatement.InExpression);
            var countProperty = GetCountProperty(result.Type);

            var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), "i", new PrimitiveExpression(0));
            var id1         = new IdentifierExpression("i");
            var id2         = id1.Clone();
            var id3         = id1.Clone();

            var forStatement = new ForStatement()
            {
                Initializers      = { initializer },
                Condition         = new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new MemberReferenceExpression(foreachStatement.InExpression.Clone(), countProperty)),
                Iterators         = { new ExpressionStatement(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2)) },
                EmbeddedStatement = new BlockStatement {
                    new VariableDeclarationStatement(foreachStatement.VariableType.Clone(), foreachStatement.VariableName, new IndexerExpression(foreachStatement.InExpression.Clone(), id3))
                }
            };

            if (foreachStatement.EmbeddedStatement is BlockStatement)
            {
                foreach (var child in ((BlockStatement)foreachStatement.EmbeddedStatement).Statements)
                {
                    forStatement.EmbeddedStatement.AddChild(child.Clone(), BlockStatement.StatementRole);
                }
            }
            else
            {
                forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole);
            }

            using (var script = context.StartScript()) {
                script.Replace(foreachStatement, forStatement);
                script.Link(initializer.Variables.First().NameToken, id1, id2, id3);
            }
        }
Esempio n. 5
0
        private void CreateParameterAssignmentIfNeeded(Type type, IdentifierExpression identifier)
        {
            Func <AssignmentExpression, bool> predicate = (assign) => AssignmentPredicate(assign, identifier);
            var assignment = _assignmentVisitor.VisitAndCompare(_methodDeclaration, predicate);

            if (assignment == null)
            {
                var mainModule = _methodDeclaration.Annotation <MethodReference>().Module.Assembly.MainModule;
                var getTypeFromHandleInvocation = GetTypeFromHandleInvocation(type, mainModule);
                var parameterCreationInvocation = GetParameterCreationInvocation(mainModule, getTypeFromHandleInvocation);
                var assignmentExpression        = new AssignmentExpression(identifier.Clone(), AssignmentOperatorType.Assign, parameterCreationInvocation);
                var expressionStatement         = new ExpressionStatement(assignmentExpression);

                _block.Statements.Add(expressionStatement);
            }
        }
        public IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            var foreachStatement = GetForeachStatement(context);

            if (foreachStatement == null)
            {
                yield break;
            }

            var    state = context.GetResolverStateBefore(foreachStatement.EmbeddedStatement);
            string name  = GetName(state, VariableNames);

            if (name == null)             // very unlikely, but just in case ...
            {
                yield break;
            }

            yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => {
                var result = context.Resolve(foreachStatement.InExpression);
                var countProperty = GetCountProperty(result.Type);

                // TODO: use another variable name if 'i' is already in use
                var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0));
                var id1 = new IdentifierExpression(name);
                var id2 = id1.Clone();
                var id3 = id1.Clone();
                var inExpression = foreachStatement.InExpression;
                Statement declarationStatement = null;
                if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression)
                {
                    string listName = GetName(state, CollectionNames) ?? "col";
                    declarationStatement = new VariableDeclarationStatement(
                        new PrimitiveType("var"),
                        listName,
                        inExpression.Clone()
                        );
                    inExpression = new IdentifierExpression(listName);
                }

                var variableDeclarationStatement = new VariableDeclarationStatement(
                    foreachStatement.VariableType.Clone(),
                    foreachStatement.VariableName,
                    new IndexerExpression(inExpression.Clone(), id3)
                    );
                var forStatement = new ForStatement()
                {
                    Initializers = { initializer },
                    Condition = new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new MemberReferenceExpression(inExpression.Clone(), countProperty)),
                    Iterators = { new ExpressionStatement(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2)) },
                    EmbeddedStatement = new BlockStatement {
                        variableDeclarationStatement
                    }
                };

                if (foreachStatement.EmbeddedStatement is BlockStatement)
                {
                    variableDeclarationStatement.Remove();
                    var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
                    if (oldBlock.Statements.Any())
                    {
                        oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
                    }
                    else
                    {
                        oldBlock.Statements.Add(variableDeclarationStatement);
                    }
                    forStatement.EmbeddedStatement = oldBlock;
                }
                else
                {
                    forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole);
                }
                if (declarationStatement != null)
                {
                    script.InsertBefore(foreachStatement, declarationStatement);
                }
                script.Replace(foreachStatement, forStatement);
                script.Link(initializer.Variables.First().NameToken, id1, id2, id3);
            }, foreachStatement));
        }
Esempio n. 7
0
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            bool hasIndexAccess;
            var  foreachStatement = GetForeachStatement(context, out hasIndexAccess);

            if (foreachStatement == null || foreachStatement.EmbeddedStatement.IsNull)
            {
                yield break;
            }
            var    state = context.GetResolverStateBefore(foreachStatement.EmbeddedStatement);
            string name  = GetName(state, VariableNames);

            if (name == null)             // very unlikely, but just in case ...
            {
                yield break;
            }

            yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => {
                var result = context.Resolve(foreachStatement.InExpression);
                var countProperty = GetCountProperty(result.Type);
                var inExpression = foreachStatement.InExpression;

                var initializer = hasIndexAccess ? new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0)) :
                                  new VariableDeclarationStatement(new SimpleType("var"), name, new InvocationExpression(new MemberReferenceExpression(inExpression.Clone(), "GetEnumerator")));
                var id1 = new IdentifierExpression(name);
                var id2 = id1.Clone();
                var id3 = id1.Clone();
                Statement declarationStatement = null;
                if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression)
                {
                    string listName = GetName(state, CollectionNames) ?? "col";
                    declarationStatement = new VariableDeclarationStatement(
                        new PrimitiveType("var"),
                        listName,
                        inExpression.Clone()
                        );
                    inExpression = new IdentifierExpression(listName);
                }

                var variableDeclarationStatement = new VariableDeclarationStatement(
                    foreachStatement.VariableType.Clone(),
                    foreachStatement.VariableName,
                    hasIndexAccess ? (Expression) new IndexerExpression(inExpression.Clone(), id3) : new MemberReferenceExpression(id1, "Current")
                    );

                var forStatement = new ForStatement {
                    Initializers = { initializer },
                    Condition = hasIndexAccess ? (Expression) new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new MemberReferenceExpression(inExpression.Clone(), countProperty)) :
                                new InvocationExpression(new MemberReferenceExpression(id2, "MoveNext")),
                    EmbeddedStatement = new BlockStatement {
                        variableDeclarationStatement
                    }
                };

                if (hasIndexAccess)
                {
                    forStatement.Iterators.Add(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2));
                }

                if (foreachStatement.EmbeddedStatement is BlockStatement)
                {
                    variableDeclarationStatement.Remove();
                    var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
                    if (oldBlock.Statements.Any())
                    {
                        oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
                    }
                    else
                    {
                        oldBlock.Statements.Add(variableDeclarationStatement);
                    }
                    forStatement.EmbeddedStatement = oldBlock;
                }
                else
                {
                    forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole);
                }
                if (declarationStatement != null)
                {
                    script.InsertBefore(foreachStatement, declarationStatement);
                }
                script.Replace(foreachStatement, forStatement);
                if (hasIndexAccess)
                {
                    script.Link(initializer.Variables.First().NameToken, id1, id2, id3);
                }
                else
                {
                    script.Link(initializer.Variables.First().NameToken, id1, id2);
                }
            }, foreachStatement));

            if (!hasIndexAccess)
            {
                yield break;
            }
            yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to optimized 'for'"), script => {
                var result = context.Resolve(foreachStatement.InExpression);
                var countProperty = GetCountProperty(result.Type);

                var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0));
                var id1 = new IdentifierExpression(name);
                var id2 = id1.Clone();
                var id3 = id1.Clone();
                var inExpression = foreachStatement.InExpression;
                Statement declarationStatement = null;
                if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression)
                {
                    string listName = GetName(state, CollectionNames) ?? "col";
                    declarationStatement = new VariableDeclarationStatement(
                        new PrimitiveType("var"),
                        listName,
                        inExpression.Clone()
                        );
                    inExpression = new IdentifierExpression(listName);
                }

                var variableDeclarationStatement = new VariableDeclarationStatement(
                    foreachStatement.VariableType.Clone(),
                    foreachStatement.VariableName,
                    new IndexerExpression(inExpression.Clone(), id3)
                    );

                string optimizedUpperBound = GetBoundName(inExpression) + countProperty;
                initializer.Variables.Add(new VariableInitializer(optimizedUpperBound, new MemberReferenceExpression(inExpression.Clone(), countProperty)));
                var forStatement = new ForStatement {
                    Initializers = { initializer },
                    Condition = new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new IdentifierExpression(optimizedUpperBound)),
                    Iterators = { new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2) },
                    EmbeddedStatement = new BlockStatement {
                        variableDeclarationStatement
                    }
                };

                if (foreachStatement.EmbeddedStatement is BlockStatement)
                {
                    variableDeclarationStatement.Remove();
                    var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
                    if (oldBlock.Statements.Any())
                    {
                        oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
                    }
                    else
                    {
                        oldBlock.Statements.Add(variableDeclarationStatement);
                    }
                    forStatement.EmbeddedStatement = oldBlock;
                }
                else
                {
                    forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole);
                }
                if (declarationStatement != null)
                {
                    script.InsertBefore(foreachStatement, declarationStatement);
                }
                script.Replace(foreachStatement, forStatement);
                script.Link(initializer.Variables.First().NameToken, id1, id2, id3);
            }, foreachStatement));
        }
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				// Genereate Equals
				MethodDeclaration methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "Equals";

				methodDeclaration.ReturnType = DomReturnType.Bool.ConvertToTypeReference ();
				methodDeclaration.Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();
				methodDeclaration.Parameters.Add (new ParameterDeclaration (DomReturnType.Object.ConvertToTypeReference (), "obj"));
				IdentifierExpression paramId = new IdentifierExpression ("obj");
				IfElseStatement ifStatement = new IfElseStatement ();
				ifStatement.Condition = new BinaryOperatorExpression (paramId, BinaryOperatorType.Equality, new PrimitiveExpression (null));
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false));
				methodDeclaration.Body.Statements.Add (ifStatement);

				ifStatement = new IfElseStatement ();
				List<Expression> arguments = new List<Expression> ();
				arguments.Add (new ThisReferenceExpression ());
				arguments.Add (paramId.Clone ());
				ifStatement.Condition = new InvocationExpression (new IdentifierExpression ("ReferenceEquals"), arguments);
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (true));
				methodDeclaration.Body.Statements.Add (ifStatement);

				ifStatement = new IfElseStatement ();
				ifStatement.Condition = new BinaryOperatorExpression (new InvocationExpression (new MemberReferenceExpression (paramId.Clone (), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression (new SimpleType (Options.EnclosingType.Name)));
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false));
				methodDeclaration.Body.Statements.Add (ifStatement);

				AstType varType = new DomReturnType (Options.EnclosingType).ConvertToTypeReference ();
				var varDecl = new VariableDeclarationStatement (varType, "other", new CastExpression (varType.Clone (), paramId.Clone ()));
				methodDeclaration.Body.Statements.Add (varDecl);
				
				IdentifierExpression otherId = new IdentifierExpression ("other");
				Expression binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right = new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression (otherId, member.Name));
					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.ConditionalAnd, right);
					}
				}

				methodDeclaration.Body.Statements.Add (new ReturnStatement (binOp));
				yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);

				methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "GetHashCode";

				methodDeclaration.ReturnType = DomReturnType.Int32.ConvertToTypeReference ();
				methodDeclaration.Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();

				binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right;
					right = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression (member.Name), "GetHashCode"));

					IType type = Options.Dom.SearchType (Options.Document.ParsedDocument.CompilationUnit, member is IType ? ((IType)member) : member.DeclaringType, member.Location, member.ReturnType);
					if (type != null && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Struct&& type.ClassType != MonoDevelop.Projects.Dom.ClassType.Enum)
						right = new ParenthesizedExpression (new ConditionalExpression (new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), right, new PrimitiveExpression (0)));

					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.ExclusiveOr, right);
					}
				}
				BlockStatement uncheckedBlock = new BlockStatement ();
				uncheckedBlock.Statements.Add (new ReturnStatement (binOp));

				methodDeclaration.Body.Statements.Add (new UncheckedStatement (uncheckedBlock));
				yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);
			}
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			bool hasIndexAccess;
			var foreachStatement = GetForeachStatement(context, out hasIndexAccess);
			if (foreachStatement == null || foreachStatement.EmbeddedStatement == null)
				yield break;
			var state = context.GetResolverStateBefore (foreachStatement.EmbeddedStatement);
			string name = GetName(state, VariableNames);
			if (name == null) // very unlikely, but just in case ...
				yield break;

			yield return new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => {
				var result = context.Resolve(foreachStatement.InExpression);
				var countProperty = GetCountProperty(result.Type);
				var inExpression = foreachStatement.InExpression;

				var initializer = hasIndexAccess ? new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0)) :
				                  new VariableDeclarationStatement(new SimpleType("var"), name, new InvocationExpression(new MemberReferenceExpression (inExpression.Clone (), "GetEnumerator")));
				var id1 = new IdentifierExpression(name);
				var id2 = id1.Clone();
				var id3 = id1.Clone();
				Statement declarationStatement = null;
				if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression) {
					string listName = GetName(state, CollectionNames) ?? "col";
					declarationStatement = new VariableDeclarationStatement (
						new PrimitiveType ("var"),
						listName,
						inExpression.Clone ()
					);
					inExpression = new IdentifierExpression (listName);
				}

				var variableDeclarationStatement = new VariableDeclarationStatement(
					foreachStatement.VariableType.Clone(),
					foreachStatement.VariableName,
					hasIndexAccess ? (Expression)new IndexerExpression(inExpression.Clone(), id3) : new MemberReferenceExpression(id1, "Current")
				);

				var forStatement = new ForStatement {
					Initializers = { initializer },
					Condition = hasIndexAccess ? (Expression)new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new MemberReferenceExpression (inExpression.Clone (), countProperty)) :
					            new InvocationExpression(new MemberReferenceExpression (id2, "MoveNext")),
					EmbeddedStatement = new BlockStatement {
						variableDeclarationStatement
					}
				};

				if (hasIndexAccess)
					forStatement.Iterators.Add(new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2));

				if (foreachStatement.EmbeddedStatement is BlockStatement) {
					variableDeclarationStatement.Remove();
					var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
					if (oldBlock.Statements.Any()) {
						oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
					} else {
						oldBlock.Statements.Add(variableDeclarationStatement);
					}
					forStatement.EmbeddedStatement = oldBlock;
				} else {
					forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole);
				}
				if (declarationStatement != null)
					script.InsertBefore (foreachStatement, declarationStatement);
				script.Replace (foreachStatement, forStatement);
				if (hasIndexAccess) {
					script.Link (initializer.Variables.First ().NameToken, id1, id2, id3);
				} else {
					script.Link (initializer.Variables.First ().NameToken, id1, id2);
				}
			}, foreachStatement);

			if (!hasIndexAccess)
				yield break;
			yield return new CodeAction(context.TranslateString("Convert 'foreach' loop to optimized 'for'"), script => {
				var result = context.Resolve(foreachStatement.InExpression);
				var countProperty = GetCountProperty(result.Type);

				var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0));
				var id1 = new IdentifierExpression(name);
				var id2 = id1.Clone();
				var id3 = id1.Clone();
				var inExpression = foreachStatement.InExpression;
				Statement declarationStatement = null;
				if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression) {
					string listName = GetName(state, CollectionNames) ?? "col";
					declarationStatement = new VariableDeclarationStatement (
						new PrimitiveType ("var"),
						listName,
						inExpression.Clone ()
						);
					inExpression = new IdentifierExpression (listName);
				}

				var variableDeclarationStatement = new VariableDeclarationStatement(
					foreachStatement.VariableType.Clone(),
					foreachStatement.VariableName,
					new IndexerExpression(inExpression.Clone(), id3)
					);

				string optimizedUpperBound = GetBoundName(inExpression) + countProperty;
				initializer.Variables.Add(new VariableInitializer(optimizedUpperBound, new MemberReferenceExpression (inExpression.Clone (), countProperty)));
				var forStatement = new ForStatement {
					Initializers = { initializer },
					Condition = new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new IdentifierExpression(optimizedUpperBound)),
					Iterators = { new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2) },
					EmbeddedStatement = new BlockStatement {
						variableDeclarationStatement
					}
				};

				if (foreachStatement.EmbeddedStatement is BlockStatement) {
					variableDeclarationStatement.Remove();
					var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
					if (oldBlock.Statements.Any()) {
						oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
					} else {
						oldBlock.Statements.Add(variableDeclarationStatement);
					}
					forStatement.EmbeddedStatement = oldBlock;
				} else {
					forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole);
				}
				if (declarationStatement != null)
					script.InsertBefore (foreachStatement, declarationStatement);
				script.Replace (foreachStatement, forStatement);
				script.Link (initializer.Variables.First ().NameToken, id1, id2, id3);
			}, foreachStatement);
		}
			protected override IEnumerable<string> GenerateCode (List<object> includedMembers)
			{
				// Genereate Equals
				var methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "Equals";

				methodDeclaration.ReturnType = new PrimitiveType ("bool");
				methodDeclaration.Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();
				methodDeclaration.Parameters.Add (new ParameterDeclaration (new PrimitiveType ("object"), "obj"));
				var paramId = new IdentifierExpression ("obj");
				IfElseStatement ifStatement = new IfElseStatement ();
				ifStatement.Condition = new BinaryOperatorExpression (paramId, BinaryOperatorType.Equality, new PrimitiveExpression (null));
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false));
				methodDeclaration.Body.Statements.Add (ifStatement);

				ifStatement = new IfElseStatement ();
				var arguments = new List<Expression> ();
				arguments.Add (new ThisReferenceExpression ());
				arguments.Add (paramId.Clone ());
				ifStatement.Condition = new InvocationExpression (new IdentifierExpression ("ReferenceEquals"), arguments);
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (true));
				methodDeclaration.Body.Statements.Add (ifStatement);

				ifStatement = new IfElseStatement ();
				ifStatement.Condition = new BinaryOperatorExpression (new InvocationExpression (new MemberReferenceExpression (paramId.Clone (), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression (new SimpleType (Options.EnclosingType.Name)));
				ifStatement.TrueStatement = new ReturnStatement (new PrimitiveExpression (false));
				methodDeclaration.Body.Statements.Add (ifStatement);

				var varType = new SimpleType (Options.EnclosingType.Name);
				var varDecl = new VariableDeclarationStatement (varType, "other", new CastExpression (varType.Clone (), paramId.Clone ()));
				methodDeclaration.Body.Statements.Add (varDecl);
				
				var otherId = new IdentifierExpression ("other");
				Expression binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right = new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression (otherId.Clone (), member.Name));
					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.ConditionalAnd, right);
					}
				}

				methodDeclaration.Body.Statements.Add (new ReturnStatement (binOp));
				yield return methodDeclaration.ToString (Options.FormattingOptions);

				methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "GetHashCode";

				methodDeclaration.ReturnType = new PrimitiveType ("int");
				methodDeclaration.Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();

				binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right;
					right = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression (member.Name), "GetHashCode"));

					IType type = member.ReturnType;
					if (type != null && type.Kind != TypeKind.Struct && type.Kind != TypeKind.Enum)
						right = new ParenthesizedExpression (new ConditionalExpression (new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), right, new PrimitiveExpression (0)));

					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.ExclusiveOr, right);
					}
				}
				var uncheckedBlock = new BlockStatement ();
				uncheckedBlock.Statements.Add (new ReturnStatement (binOp));

				methodDeclaration.Body.Statements.Add (new UncheckedStatement (uncheckedBlock));
				yield return methodDeclaration.ToString (Options.FormattingOptions);
			}
Esempio n. 11
0
            protected override IEnumerable <string> GenerateCode(List <object> includedMembers)
            {
                // Genereate Equals
                var methodDeclaration = new MethodDeclaration();

                methodDeclaration.Name = "Equals";

                methodDeclaration.ReturnType = new PrimitiveType("bool");
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();
                methodDeclaration.Parameters.Add(new ParameterDeclaration(new PrimitiveType("object"), "obj"));
                var             paramId     = new IdentifierExpression("obj");
                IfElseStatement ifStatement = new IfElseStatement();

                ifStatement.Condition     = new BinaryOperatorExpression(paramId, BinaryOperatorType.Equality, new PrimitiveExpression(null));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement = new IfElseStatement();
                var arguments = new List <Expression> ();

                arguments.Add(new ThisReferenceExpression());
                arguments.Add(paramId.Clone());
                ifStatement.Condition     = new InvocationExpression(new IdentifierExpression("ReferenceEquals"), arguments);
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(true));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement               = new IfElseStatement();
                ifStatement.Condition     = new BinaryOperatorExpression(new InvocationExpression(new MemberReferenceExpression(paramId.Clone(), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression(new SimpleType(Options.EnclosingType.Name)));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                var varType = new SimpleType(Options.EnclosingType.Name);
                var varDecl = new VariableDeclarationStatement(varType, "other", new CastExpression(varType.Clone(), paramId.Clone()));

                methodDeclaration.Body.Statements.Add(varDecl);

                var        otherId = new IdentifierExpression("other");
                Expression binOp   = null;

                foreach (IMember member in includedMembers)
                {
                    Expression right = new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression(otherId.Clone(), member.Name));
                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ConditionalAnd, right);
                    }
                }

                methodDeclaration.Body.Statements.Add(new ReturnStatement(binOp));
                yield return(methodDeclaration.ToString(Options.FormattingOptions));

                methodDeclaration      = new MethodDeclaration();
                methodDeclaration.Name = "GetHashCode";

                methodDeclaration.ReturnType = new PrimitiveType("int");
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();

                binOp = null;
                foreach (IMember member in includedMembers)
                {
                    Expression right;
                    right = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression(member.Name), "GetHashCode"));

                    IType type = member.ReturnType;
                    if (type != null && type.Kind != TypeKind.Struct && type.Kind != TypeKind.Enum)
                    {
                        right = new ParenthesizedExpression(new ConditionalExpression(new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression(null)), right, new PrimitiveExpression(0)));
                    }

                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ExclusiveOr, right);
                    }
                }
                var uncheckedBlock = new BlockStatement();

                uncheckedBlock.Statements.Add(new ReturnStatement(binOp));

                methodDeclaration.Body.Statements.Add(new UncheckedStatement(uncheckedBlock));
                yield return(methodDeclaration.ToString(Options.FormattingOptions));
            }
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                // Genereate Equals
                MethodDeclaration methodDeclaration = new MethodDeclaration();

                methodDeclaration.Name = "Equals";

                methodDeclaration.ReturnType = DomReturnType.Bool.ConvertToTypeReference();
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();
                methodDeclaration.Parameters.Add(new ParameterDeclaration(DomReturnType.Object.ConvertToTypeReference(), "obj"));
                IdentifierExpression paramId     = new IdentifierExpression("obj");
                IfElseStatement      ifStatement = new IfElseStatement();

                ifStatement.Condition     = new BinaryOperatorExpression(paramId, BinaryOperatorType.Equality, new PrimitiveExpression(null));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement = new IfElseStatement();
                List <Expression> arguments = new List <Expression> ();

                arguments.Add(new ThisReferenceExpression());
                arguments.Add(paramId.Clone());
                ifStatement.Condition     = new InvocationExpression(new IdentifierExpression("ReferenceEquals"), arguments);
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(true));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement               = new IfElseStatement();
                ifStatement.Condition     = new BinaryOperatorExpression(new InvocationExpression(new MemberReferenceExpression(paramId.Clone(), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression(new SimpleType(Options.EnclosingType.Name)));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                AstType varType = new DomReturnType(Options.EnclosingType).ConvertToTypeReference();
                var     varDecl = new VariableDeclarationStatement(varType, "other", new CastExpression(varType.Clone(), paramId.Clone()));

                methodDeclaration.Body.Statements.Add(varDecl);

                IdentifierExpression otherId = new IdentifierExpression("other");
                Expression           binOp   = null;

                foreach (IMember member in includedMembers)
                {
                    Expression right = new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression(otherId, member.Name));
                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ConditionalAnd, right);
                    }
                }

                methodDeclaration.Body.Statements.Add(new ReturnStatement(binOp));
                yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));

                methodDeclaration      = new MethodDeclaration();
                methodDeclaration.Name = "GetHashCode";

                methodDeclaration.ReturnType = DomReturnType.Int32.ConvertToTypeReference();
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();

                binOp = null;
                foreach (IMember member in includedMembers)
                {
                    Expression right;
                    right = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression(member.Name), "GetHashCode"));

                    IType type = Options.Dom.SearchType(Options.Document.ParsedDocument.CompilationUnit, member is IType ? ((IType)member) : member.DeclaringType, member.Location, member.ReturnType);
                    if (type != null && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Struct && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Enum)
                    {
                        right = new ParenthesizedExpression(new ConditionalExpression(new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression(null)), right, new PrimitiveExpression(0)));
                    }

                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ExclusiveOr, right);
                    }
                }
                BlockStatement uncheckedBlock = new BlockStatement();

                uncheckedBlock.Statements.Add(new ReturnStatement(binOp));

                methodDeclaration.Body.Statements.Add(new UncheckedStatement(uncheckedBlock));
                yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));
            }
        public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            var foreachStatement = GetForeachStatement(context);
            if (foreachStatement == null) {
                yield break;
            }

            var state = context.GetResolverStateBefore (foreachStatement.EmbeddedStatement);
            string name = GetName(state, VariableNames);
            if (name == null) // very unlikely, but just in case ...
                yield break;

            yield return new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => {
                var result = context.Resolve(foreachStatement.InExpression);
                var countProperty = GetCountProperty(result.Type);

                // TODO: use another variable name if 'i' is already in use
                var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0));
                var id1 = new IdentifierExpression(name);
                var id2 = id1.Clone();
                var id3 = id1.Clone();
                var inExpression = foreachStatement.InExpression;
                Statement declarationStatement = null;
                if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression) {
                    string listName = GetName(state, CollectionNames) ?? "col";
                    declarationStatement = new VariableDeclarationStatement (
                        new PrimitiveType ("var"),
                        listName,
                        inExpression.Clone ()
                    );
                    inExpression = new IdentifierExpression (listName);
                }

                var variableDeclarationStatement = new VariableDeclarationStatement(
                    foreachStatement.VariableType.Clone(),
                    foreachStatement.VariableName,
                    new IndexerExpression(inExpression.Clone(), id3)
                    );
                var forStatement = new ForStatement() {
                    Initializers = { initializer },
                    Condition = new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new MemberReferenceExpression (inExpression.Clone (), countProperty)),
                    Iterators = { new ExpressionStatement (new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2)) },
                    EmbeddedStatement = new BlockStatement {
                        variableDeclarationStatement
                    }
                };

                if (foreachStatement.EmbeddedStatement is BlockStatement) {
                    variableDeclarationStatement.Remove();
                    var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone();
                    if (oldBlock.Statements.Any()) {
                        oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement);
                    } else {
                        oldBlock.Statements.Add(variableDeclarationStatement);
                    }
                    forStatement.EmbeddedStatement = oldBlock;
                } else {
                    forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole);
                }
                if (declarationStatement != null)
                    script.InsertBefore (foreachStatement, declarationStatement);
                script.Replace (foreachStatement, forStatement);
                script.Link (initializer.Variables.First ().NameToken, id1, id2, id3);
            }, foreachStatement);
        }
Esempio n. 14
0
        /// <summary>
        /// Applies the transformation
        /// </summary>
        /// <returns>The transformed item.</returns>
        /// <param name="el">The item to visit.</param>
        public ASTItem Transform(ASTItem el)
        {
            var ss = el as SwitchStatement;
            if (ss == null)
                return el;

            var exptype = State.VHDLType(ss.SwitchExpression);

            // Extract expression types
            var targets = ss
                .Cases
                .SelectMany(x => x.Item1)
                .Where(x => x != null && !(x is EmptyExpression))
                .Select(x => State.VHDLType(x))
                .Distinct()
                .ToArray();

            // Case where the expressions are all integer literals, 
            // but the source is some numeric
            if (targets.Length == 1 && targets.First() != exptype)
            {
                var mp = ss.GetNearestParent<Method>();
                if (mp != null)
                {
                    var targettype = ss
                        .Cases
                        .SelectMany(x => x.Item1)
                        .First(x => x != null && !(x is EmptyExpression))
                        .SourceResultType;

                    // Create a variable the same type as the cases
                    // and set it to the switch expression
                    var nvar = State.RegisterTemporaryVariable(mp, targettype);
                    State.TypeLookup[nvar] = targets.First();

                    var nvexp = new IdentifierExpression()
                    {
                        Name = nvar.Name,
                        SourceExpression = ss.SwitchExpression.SourceExpression,
                        SourceResultType = nvar.CecilType,
                        Target = nvar
                    };

                    var asss = new AST.ExpressionStatement()
                    {
                        Expression = new AST.AssignmentExpression()
                        {
                            Left = nvexp,
                            Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign,
                            Right = ss.SwitchExpression,
                            SourceExpression = ss.SwitchExpression.SourceExpression,
                            SourceResultType = nvar.CecilType
                        }
                    };

                    ss.SwitchExpression = nvexp.Clone();
                    ss.SwitchExpression.Parent = ss;

                    asss.UpdateParents();
                    ss.PrependStatement(asss);
                    return null;
                }
            }

            return el;
        }
Esempio n. 15
0
        public static Expression ConvertExpression(RenderState render, Method method, Expression s, VHDLType target, Mono.Cecil.TypeReference targetsource, bool fromCast)
        {
            var svhdl = render.VHDLType(s);

            // Deal with pesky integers that overflow the 32bit VHDL specs
            if (IsTooLargeIntegerLiteral(s, target))
            {
                svhdl = render.TypeScope.StdLogicVectorEquivalent(target);
            }

            // Already the real target type, just return it
            if (svhdl == target)
            {
                return(s);
            }

            // Stuff we do not care about
            if (!svhdl.IsStdLogicVector && !svhdl.IsUnsigned && !svhdl.IsSigned && svhdl.IsArray && target.IsArray && render.TypeScope.GetByName(svhdl.ElementName) == render.TypeScope.GetByName(target.ElementName))
            {
                return(s);
            }

            // Array lengths
            var targetlengthstr = string.IsNullOrWhiteSpace(target.Alias) ? target.Length.ToString() : target.Alias + "'length";

            if (target == VHDLTypes.SYSTEM_BOOL)
            {
                // Boolean to std_logic is fine
                if (string.Equals("STD_LOGIC", svhdl.Name, StringComparison.OrdinalIgnoreCase))
                {
                    return(s);
                }

                // Source is numeric, and output is bool
                if (svhdl.IsNumeric || svhdl.IsStdLogicVector)
                {
                    var zero = new PrimitiveExpression()
                    {
                        SourceExpression = s.SourceExpression,
                        SourceResultType = s.SourceResultType,
                        Value            = 0
                    };

                    var eval = new BinaryOperatorExpression()
                    {
                        Parent           = s.Parent,
                        Name             = s.Name,
                        SourceExpression = s.SourceExpression,
                        SourceResultType = s.SourceResultType.LoadType(typeof(bool)),
                        Left             = s,
                        Operator         = ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.InEquality,
                        Right            = zero
                    };

                    zero.Parent = eval;

                    s.ReplaceWith(eval);
                    s.Parent = eval;

                    return(eval);
                }
                else if (svhdl == VHDLTypes.BOOL)
                {
                    var truexp = new PrimitiveExpression()
                    {
                        Value            = true,
                        SourceExpression = s.SourceExpression,
                        SourceResultType = s.SourceResultType.LoadType(typeof(bool)),
                    };

                    var falseexp = new PrimitiveExpression()
                    {
                        Value            = false,
                        SourceExpression = s.SourceExpression,
                        SourceResultType = s.SourceResultType.LoadType(typeof(bool)),
                    };

                    var eval = new ConditionalExpression()
                    {
                        ConditionExpression = s,
                        TrueExpression      = truexp,
                        FalseExpression     = falseexp,
                        SourceExpression    = s.SourceExpression,
                        SourceResultType    = truexp.SourceResultType
                    };

                    truexp.Parent   = eval;
                    falseexp.Parent = eval;

                    s.ReplaceWith(eval);
                    s.Parent = eval;

                    return(eval);
                }
                else
                {
                    throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target));
                }
            }
            else if (svhdl == VHDLTypes.INTEGER && (target.IsStdLogicVector || target.IsNumeric))
            {
                if (target.IsSigned && target.IsNumeric)
                {
                    return(WrapExpression(render, s, string.Format("TO_SIGNED({0}, {1})", "{0}", targetlengthstr), target));
                }
                else if (target.IsUnsigned && target.IsNumeric)
                {
                    return(WrapExpression(render, s, string.Format("TO_UNSIGNED({0}, {1})", "{0}", targetlengthstr), target));
                }
                else if (target.IsStdLogicVector)
                {
                    return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(TO_UNSIGNED({0}, {1}))", "{0}", targetlengthstr), target));
                }
                else
                {
                    throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target));
                }
            }
            else if (target.IsNumeric && !svhdl.IsEnum)
            {
                if (svhdl.IsStdLogicVector || svhdl.IsSigned || svhdl.IsUnsigned)
                {
                    var      str     = "{0}";
                    var      resized = false;
                    Variable tmpvar  = null;
                    if (target.Length != svhdl.Length)
                    {
                        if (svhdl.IsVHDLSigned)
                        {
                            // Resizing with signed is bad because we may chop the upper bit
                            resized = true;
                            str     = string.Format("SIGNED(resize(UNSIGNED({0}), {1}))", str, targetlengthstr);
                        }
                        else if (svhdl.IsVHDLUnsigned)
                        {
                            resized = true;
                            str     = string.Format("resize({0}, {1})", str, targetlengthstr);
                        }
                        else if (svhdl.IsSystemSigned)
                        {
                            // Resizing with signed is bad because we may chop the upper bit
                            str     = string.Format("SIGNED(resize(UNSIGNED({0}), {1}))", str, targetlengthstr);
                            svhdl   = render.TypeScope.NumericEquivalent(svhdl);
                            resized = true;
                        }
                        else if (svhdl.IsSystemUnsigned)
                        {
                            str     = string.Format("resize(UNSIGNED({0}), {1})", str, targetlengthstr);
                            svhdl   = render.TypeScope.NumericEquivalent(svhdl);
                            resized = true;
                        }

                        else if (target.Length > svhdl.Length)
                        {
                            // This must be a variable as bit concatenation is only allowed in assignment statements:
                            // http://stackoverflow.com/questions/209458/concatenating-bits-in-vhdl

                            tmpvar = render.RegisterTemporaryVariable(method, targetsource);
                            render.TypeLookup[tmpvar] = target;

                            var iexp = new IdentifierExpression()
                            {
                                Name             = tmpvar.Name,
                                Target           = tmpvar,
                                SourceExpression = s.SourceExpression,
                                SourceResultType = targetsource
                            };

                            string wstr;
                            if (render.Config.USE_EXPLICIT_CONCATENATION_OPERATOR)
                            {
                                wstr = string.Format("IEEE.STD_LOGIC_1164.\"&\"(\"{0}\", {1})", new string('0', target.Length - svhdl.Length), "{0}");
                            }
                            else
                            {
                                wstr = string.Format("\"{0}\" & {1}", new string('0', target.Length - svhdl.Length), "{0}");
                            }

                            s.ReplaceWith(iexp);

                            var asstm = new ExpressionStatement()
                            {
                                Expression = new AssignmentExpression()
                                {
                                    Left  = iexp.Clone(),
                                    Right = new CustomNodes.ConversionExpression()
                                    {
                                        Expression       = s,
                                        SourceExpression = s.SourceExpression,
                                        SourceResultType = targetsource,
                                        WrappingTemplate = wstr,
                                    },
                                    Operator         = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign,
                                    SourceExpression = s.SourceExpression,
                                    SourceResultType = targetsource
                                },
                            };

                            s.PrependStatement(asstm);
                            asstm.UpdateParents();

                            resized = true;

                            s = iexp;
                        }
                    }

                    if (svhdl.IsVHDLSigned != target.IsSigned || svhdl.IsVHDLUnsigned != target.IsUnsigned)
                    {
                        str = string.Format("{1}({0})", str, target.IsSigned ? "SIGNED" : "UNSIGNED");
                    }

                    if (target.Length != svhdl.Length && !resized)
                    {
                        str = string.Format("resize({0}, {1})", str, targetlengthstr);
                    }

                    return(WrapExpression(render, s, str, target));
                }


                /*if (svhdl.IsStdLogicVector && target.IsSigned)
                 *                      return new VHDLConvertedExpression(s, target, "SIGNED({0})");
                 *              else if (svhdl.IsStdLogicVector && target.IsUnsigned)
                 *                      return new VHDLConvertedExpression(s, target, "UNSIGNED({0})");
                 *              else*/
                throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target));
            }
            else if (target.IsStdLogicVector)
            {
                if (svhdl.IsNumeric)
                {
                    if (svhdl.Length == target.Length)
                    {
                        return(WrapExpression(render, s, "STD_LOGIC_VECTOR({0})", target));
                    }
                    else
                    {
                        if (!fromCast)
                        {
                            Console.WriteLine("WARN: Incompatible array lengths, from {0} to {1}", svhdl, target);
                        }
                        //throw new Exception(string.Format("Incompatible array lengths, from {0} to {1}", svhdl, target));

                        if (target.Length < svhdl.Length && svhdl.IsNumericSigned)
                        {
                            return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(UNSIGNED({0}), {1}))", "{0}", targetlengthstr), target));
                        }
                        else
                        {
                            return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize({0}, {1}))", "{0}", targetlengthstr), target));
                        }
                    }
                }
                else if (svhdl.IsStdLogicVector)
                {
                    if (target.Length == svhdl.Length)
                    {
                        render.TypeLookup[s] = target;
                        return(s);
                    }

                    if (!fromCast)
                    {
                        Console.WriteLine("WARN: Incompatible array lengths, from {0} to {1}", svhdl, target);
                    }
                    //throw new Exception(string.Format("Incompatible array lengths, from {0} to {1}", svhdl, target));

                    if (target.Length < svhdl.Length)
                    {
                        // If the expression is a simple identifier, we can select bits from it
                        // otherwise we need to inject a variable with the expression
                        // and select the required bits from it
                        if (!(s is IdentifierExpression || s is MemberReferenceExpression || s is IndexerExpression))
                        {
                            var tmp = render.RegisterTemporaryVariable(method, s.SourceResultType);
                            render.TypeLookup[tmp] = svhdl;

                            var aleft = new IdentifierExpression()
                            {
                                Name             = tmp.Name,
                                Target           = tmp,
                                SourceExpression = s.SourceExpression,
                                SourceResultType = s.SourceResultType
                            };

                            var aexp = new AssignmentExpression()
                            {
                                Left             = aleft,
                                Right            = s,
                                SourceExpression = s.SourceExpression,
                                SourceResultType = s.SourceResultType
                            };

                            var astm = new ExpressionStatement()
                            {
                                Expression = aexp,
                                Parent     = method,
                            };

                            var iexp = new IdentifierExpression()
                            {
                                SourceExpression = s.SourceExpression,
                                SourceResultType = s.SourceResultType,
                                Target           = tmp
                            };

                            s.ReplaceWith(iexp);
                            s.PrependStatement(astm);
                            astm.UpdateParents();

                            return(WrapExpression(render, iexp, string.Format("{0}({1} downto 0)", "{0}", target.Length - 1), target));
                        }

                        return(WrapExpression(render, s, string.Format("{0}({1} downto 0)", "{0}", target.Length - 1), target));
                    }
                    else if (svhdl.IsSigned)
                    {
                        return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(SIGNED({0}), {1}))", "{0}", targetlengthstr), target));
                    }
                    else if (svhdl.IsUnsigned)
                    {
                        return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(UNSIGNED({0}), {1}))", "{0}", targetlengthstr), target));
                    }
                    else
                    {
                        var tmp = render.RegisterTemporaryVariable(method, targetsource);
                        render.TypeLookup[tmp] = target;

                        var iexp = new IdentifierExpression()
                        {
                            Name             = tmp.Name,
                            Target           = tmp,
                            SourceExpression = s.SourceExpression,
                            SourceResultType = targetsource
                        };

                        render.TypeLookup[iexp] = target;

                        string wexpr;
                        if (render.Config.USE_EXPLICIT_CONCATENATION_OPERATOR)
                        {
                            wexpr = string.Format("IEEE.STD_LOGIC_1164.\"&\"(\"{0}\", {1})", new string('0', target.Length - svhdl.Length), "{0}");
                        }
                        else
                        {
                            wexpr = string.Format("\"{0}\" & {1}", new string('0', target.Length - svhdl.Length), "{0}");
                        }

                        s.ReplaceWith(iexp);

                        var asstm = new ExpressionStatement();

                        s.PrependStatement(asstm);


                        var asexp = new AssignmentExpression()
                        {
                            Left     = iexp.Clone(),
                            Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign,
                            Right    = new CustomNodes.ConversionExpression()
                            {
                                Expression       = s,
                                SourceExpression = s.SourceExpression,
                                SourceResultType = targetsource,
                                WrappingTemplate = wexpr
                            },
                            SourceExpression = s.SourceExpression,
                            SourceResultType = targetsource
                        };

                        render.TypeLookup[asexp.Left]  = target;
                        render.TypeLookup[asexp.Right] = target;
                        asexp.Left.SourceResultType    = targetsource;
                        asexp.Right.SourceResultType   = targetsource;
                        asstm.Expression = asexp;

                        asstm.UpdateParents();

                        return(iexp);
                    }
                }
                else if (svhdl.IsSigned || svhdl.IsUnsigned)
                {
                    if (target.Length == svhdl.Length)
                    {
                        return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR({0})", "{0}"), target));
                    }
                    else
                    {
                        return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize({0}, {1}))", "{0}", targetlengthstr), target));
                    }
                }
                else
                {
                    throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl.Name, target.Name));
                }
            }
            else if (target == VHDLTypes.INTEGER && (svhdl.IsStdLogicVector || svhdl.IsNumeric))
            {
                if (svhdl.IsNumeric)
                {
                    return(WrapExpression(render, s, "TO_INTEGER({0})", target));
                }

                if (svhdl.IsSigned)
                {
                    return(WrapExpression(render, s, "TO_INTEGER(SIGNED({0}))", target));
                }
                else
                {
                    return(WrapExpression(render, s, "TO_INTEGER(UNSIGNED({0}))", target));
                }
            }
            else if (target == VHDLTypes.INTEGER && (svhdl.IsSystemSigned || svhdl.IsSystemUnsigned))
            {
                return(WrapExpression(render, s, "TO_INTEGER({0})", target));
            }
            else if (target == VHDLTypes.BOOL && svhdl == VHDLTypes.SYSTEM_BOOL)
            {
                return(WrapInParenthesis(render, WrapExpression(render, s, "{0} = '1'", target)));
            }
            else if ((target.IsSigned || target.IsUnsigned) && svhdl.IsStdLogicVector)
            {
                if (target.Length == svhdl.Length)
                {
                    return(WrapExpression(render, s, string.Format("{1}({0})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED"), target));
                }
                else
                {
                    return(WrapExpression(render, s, string.Format("resize({1}({0}), {2})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED", targetlengthstr), target));
                }
            }
            else if ((target.IsSigned || target.IsUnsigned) && svhdl == VHDLTypes.INTEGER)
            {
                if (target.IsSigned)
                {
                    return(WrapExpression(render, s, string.Format("TO_SIGNED({0}, {1})", "{0}", target.Length), target));
                }
                else if (target.IsUnsigned)
                {
                    return(WrapExpression(render, s, string.Format("TO_UNSIGNED({0}, {1})", "{0}", target.Length), target));
                }
                else
                {
                    throw new Exception("Unexpected case");
                }
            }
            else if ((svhdl.IsSigned || svhdl.IsUnsigned) && (target.IsSigned || target.IsUnsigned))
            {
                if (target.Length == svhdl.Length)
                {
                    if (svhdl.IsSigned == target.IsSigned)
                    {
                        return(s);
                    }
                    else
                    {
                        return(WrapExpression(render, s, string.Format("{1}({0})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED"), target));
                    }
                }
                else
                {
                    if (svhdl.IsSigned == target.IsSigned)
                    {
                        return(WrapExpression(render, s, string.Format("resize({0}, {1})", "{0}", targetlengthstr), target));
                    }
                    else if (svhdl.IsSigned && svhdl.Length > target.Length)
                    {
                        return(WrapExpression(render, s, string.Format("resize(UNSIGNED({0}), {1})", "{0}", targetlengthstr), target));
                    }
                    else
                    {
                        return(WrapExpression(render, s, string.Format("{2}(resize({0}, {1}))", "{0}", targetlengthstr, target.IsSigned ? "SIGNED" : "UNSIGNED"), target));
                    }
                }
            }
            else if (target.IsEnum && (svhdl.IsSigned || svhdl.IsUnsigned || svhdl == VHDLTypes.INTEGER))
            {
                if (target.IsIrregularEnum)
                {
                    return(WrapExpression(render, s, string.Format("fromValue_{1}({0})", svhdl == VHDLTypes.INTEGER ? "{0}" : "TO_INTEGER({0})", target.ToSafeVHDLName()), target));
                }
                else
                {
                    return(WrapExpression(render, s, string.Format("{1}'VAL({0})", svhdl == VHDLTypes.INTEGER ? "{0}" : "TO_INTEGER({0})", target.ToSafeVHDLName()), target));
                }
            }
            else if (svhdl.IsEnum && (target.IsSigned || target.IsUnsigned || target == VHDLTypes.INTEGER))
            {
                Expression wrapped;
                if (target.IsIrregularEnum)
                {
                    wrapped = WrapExpression(render, s, string.Format("toValue_{1}({0})", "{0}", svhdl.ToSafeVHDLName()), target);
                }
                else
                {
                    wrapped = WrapExpression(render, s, string.Format("{1}'POS({0})", "{0}", svhdl.ToSafeVHDLName()), target);
                }

                render.TypeLookup[wrapped] = VHDLTypes.INTEGER;

                if (target != VHDLTypes.INTEGER)
                {
                    wrapped = ConvertExpression(render, method, wrapped, target, targetsource, false);
                }

                return(wrapped);
            }
            else
            {
                throw new Exception(string.Format("Unexpected target type: {0} for source: {1}", target, svhdl));
            }
        }
Esempio n. 16
0
			public override void VisitArrayCreateExpression (ArrayCreateExpression arrayCreateExpression)
			{
				base.VisitArrayCreateExpression (arrayCreateExpression);

				if (arrayCreateExpression.Arguments.Count != 1 || !arrayCreateExpression.Initializer.IsNull)
					return;

				var count = arrayCreateExpression.Arguments.First ();
				if (count is PrimitiveExpression && Convert.ToInt32 (((PrimitiveExpression)count).Value) == 0)
					return;

				var s = arrayCreateExpression.GetParent<Statement> ();
				if (s == null)
					return;

				var find = new FindFirstUseOfArray ();

				var variableDeclarationStatement = s as VariableDeclarationStatement;
				if (variableDeclarationStatement != null) {
					var v = arrayCreateExpression.GetParent <VariableInitializer> ();
					find.Variable = new IdentifierExpression (v.Name);

				} else {
					var es = s as ExpressionStatement;
					if (es != null && es.Expression is AssignmentExpression) {
						find.Variable = ((AssignmentExpression)es.Expression).Left;
					} else {
						return; // Don't know what's going on
					}
				}

				if (find.Variable == null)
					return;

				arrayCreateExpression.GetParent<EntityDeclaration> ().AcceptVisitor (find);
				if ((find.First is AssignmentExpression))
					return;

				var i = new IdentifierExpression ("_ai");
				var def = GetDefaultValue (arrayCreateExpression.Type);

				var init = new ForStatement {
					Condition = new BinaryOperatorExpression (
						i,
						BinaryOperatorType.LessThan,
						new MemberReferenceExpression ((Expression)find.Variable.Clone (), "length")),
					EmbeddedStatement = new ExpressionStatement (
						new AssignmentExpression (
							new IndexerExpression ((Expression)find.Variable.Clone (), i.Clone ()),
							def.Clone ())),
				};
				init.Initializers.Add (new VariableDeclarationStatement (new PrimitiveType ("number"), i.Identifier, new PrimitiveExpression (0)));
				init.Iterators.Add (new ExpressionStatement (new UnaryOperatorExpression (UnaryOperatorType.Increment, (Expression)i.Clone ())));

				s.Parent.InsertChildAfter (s, init, (Role<Statement>)s.Role);
			}