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); } }
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)); }
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); }
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); }
/// <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; }
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)); } }
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); }