diff --git a/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs b/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs index 37340ebdf8..69dfabe617 100644 --- a/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs +++ b/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs @@ -170,6 +170,12 @@ namespace PyWalker return base.Walk(node); } + public override bool Walk(IndexExpression node) + { + writer.WriteLine("Index: " + node.Index.ToString()); + return base.Walk(node); + } + public override bool Walk(UnaryExpression node) { writer.WriteLine("Unary"); diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj index a3399086e2..fa83bc4fc2 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj @@ -77,7 +77,6 @@ - diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs index 52d0619b5b..47a1c6a96f 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs @@ -34,6 +34,13 @@ namespace ICSharpCode.PythonBinding /// void Add(IComponent component, string name); + /// + /// Gets a component that have been added via the Add method. + /// + /// The component name. + /// Null if the component cannot be found. + IComponent GetComponent(string name); + /// /// Creates a new instance of the object given its type. /// diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverterOld.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverterOld.cs deleted file mode 100644 index ed0d5b1365..0000000000 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverterOld.cs +++ /dev/null @@ -1,1621 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.CodeDom; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.IO; -using System.Text; -using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.Ast; -using ICSharpCode.NRefactory.Visitors; - -namespace ICSharpCode.PythonBinding -{ - /// - /// Base class for the CSharpToPythonConverter and - /// VBNetToPythonConverter. Used to convert VB.NET and C# to - /// Python. - /// - public class NRefactoryToPythonConverterOld : IAstVisitor - { - CodeCompileUnit pythonCodeCompileUnit; - CodeNamespace currentNamespace; - CodeTypeDeclaration currentClass; - List currentClassFields = new List(); - List allCurrentClassFields = new List(); - Stack statementsStack = new Stack(); - CodeStatementCollection nullStatementCollection = new CodeStatementCollection(); - - public NRefactoryToPythonConverterOld() - { - } - - /// - /// Generates compilation unit from the code. - /// - /// - /// The code to convert to a compilation unit. - /// - public CompilationUnit GenerateCompilationUnit(string source, SupportedLanguage language) - { - using (IParser parser = ParserFactory.CreateParser(language, new StringReader(source))) { - parser.Parse(); - return parser.CompilationUnit; - } - } - - /// - /// Converts a code compile unit to Python source code. - /// - public string ConvertCodeCompileUnitToPython(CodeCompileUnit codeCompileUnit) - { - return String.Empty; - } - - /// - /// Converts the source code to Python. - /// - public string Convert(string source, SupportedLanguage language) - { - CodeCompileUnit pythonCodeCompileUnit = ConvertToCodeCompileUnit(source, language); - - // Convert to Python source code. - return ConvertCodeCompileUnitToPython(pythonCodeCompileUnit); - } - - /// - /// Converts the C# or VB.NET source code to a code DOM that - /// the PythonProvider can use to generate Python. Using the - /// NRefactory code DOM (CodeDomVisitor class) does not - /// create a code DOM that is easy to convert to Python. - /// - public CodeCompileUnit ConvertToCodeCompileUnit(string source, SupportedLanguage language) - { - // Convert to code DOM. - CompilationUnit unit = GenerateCompilationUnit(source, language); - - // Convert to Python code DOM. - return (CodeCompileUnit)unit.AcceptVisitor(this, null); - } - - /// - /// Converts from the NRefactory's binary operator type to the - /// CodeDom's binary operator type. - /// - public static CodeBinaryOperatorType ConvertBinaryOperatorType(BinaryOperatorType binaryOperatorType) - { - switch (binaryOperatorType) { - case BinaryOperatorType.Add: - return CodeBinaryOperatorType.Add; - case BinaryOperatorType.BitwiseAnd: - return CodeBinaryOperatorType.BitwiseAnd; - case BinaryOperatorType.BitwiseOr: - return CodeBinaryOperatorType.BitwiseOr; - case BinaryOperatorType.Divide: - case BinaryOperatorType.DivideInteger: - return CodeBinaryOperatorType.Divide; - case BinaryOperatorType.GreaterThan: - return CodeBinaryOperatorType.GreaterThan; - case BinaryOperatorType.GreaterThanOrEqual: - return CodeBinaryOperatorType.GreaterThanOrEqual; - case BinaryOperatorType.InEquality: - return CodeBinaryOperatorType.IdentityInequality; - case BinaryOperatorType.LessThan: - return CodeBinaryOperatorType.LessThan; - case BinaryOperatorType.LessThanOrEqual: - return CodeBinaryOperatorType.LessThanOrEqual; - case BinaryOperatorType.LogicalAnd: - return CodeBinaryOperatorType.BooleanAnd; - case BinaryOperatorType.LogicalOr: - return CodeBinaryOperatorType.BooleanOr; - case BinaryOperatorType.Modulus: - return CodeBinaryOperatorType.Modulus; - case BinaryOperatorType.Multiply: - return CodeBinaryOperatorType.Multiply; - case BinaryOperatorType.ReferenceEquality: - return CodeBinaryOperatorType.IdentityEquality; - case BinaryOperatorType.Subtract: - return CodeBinaryOperatorType.Subtract; - default: - return CodeBinaryOperatorType.ValueEquality; - } - } - - public object VisitAddHandlerStatement(AddHandlerStatement addHandlerStatement, object data) - { - Console.WriteLine("VisitAddHandlerStatement"); - return null; - } - - public object VisitAddressOfExpression(AddressOfExpression addressOfExpression, object data) - { - Console.WriteLine("VisitAddressOfExpression"); - return null; - } - - public object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data) - { - Console.WriteLine("VisitAnonymousMethodExpression"); - return null; - } - - /// - /// Converts an NRefactory array creation expression to - /// code dom array creation expression. - /// - public object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data) - { - CodeArrayCreateExpression codeArrayCreateExpression = new CodeArrayCreateExpression(); - codeArrayCreateExpression.CreateType.BaseType = arrayCreateExpression.CreateType.Type; - - // Add initializers. - foreach (CodeExpression expression in ConvertExpressions(arrayCreateExpression.ArrayInitializer.CreateExpressions)) { - codeArrayCreateExpression.Initializers.Add(expression); - } - return codeArrayCreateExpression; - } - - /// - /// Converts an NRefactory's assignment expression to a - /// CodeDom's CodeAssignmentStatement. - /// - public object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) - { - if (IsAddEventHandler(assignmentExpression)) { - return CreateAttachEventStatement(assignmentExpression.Left, assignmentExpression.Right); - } else if (IsRemoveEventHandler(assignmentExpression)) { - return CreateRemoveEventStatement(assignmentExpression.Left, assignmentExpression.Right); - } else if (assignmentExpression.Op == AssignmentOperatorType.Add) { - return CreateAddAssignmentStatement(assignmentExpression); - } else if (assignmentExpression.Op == AssignmentOperatorType.Subtract) { - return CreateSubtractAssignmentStatement(assignmentExpression); - } - - // Create a simple assignment - CodeAssignStatement codeAssignStatement = new CodeAssignStatement(); - codeAssignStatement.Left = (CodeExpression)assignmentExpression.Left.AcceptVisitor(this, data); - codeAssignStatement.Right = (CodeExpression)assignmentExpression.Right.AcceptVisitor(this, data); - return codeAssignStatement; - } - - public object VisitAttribute(ICSharpCode.NRefactory.Ast.Attribute attribute, object data) - { - return null; - } - - public object VisitAttributeSection(AttributeSection attributeSection, object data) - { - return null; - } - - /// - /// Converts a base class reference to a this reference. - /// Python has no concept of a direct base class reference so - /// "base" is converted to "self". - /// - public object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data) - { - return new CodeThisReferenceExpression(); - } - - /// - /// Converts from the NRefactory's binary operator expression to - /// a CodeDom's CodeBinaryOperatorExpression. - /// - public object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) - { - CodeBinaryOperatorExpression codeBinaryOperatorExpression = new CodeBinaryOperatorExpression(); - codeBinaryOperatorExpression.Operator = ConvertBinaryOperatorType(binaryOperatorExpression.Op); - codeBinaryOperatorExpression.Left = (CodeExpression)binaryOperatorExpression.Left.AcceptVisitor(this, data); - codeBinaryOperatorExpression.Right = (CodeExpression)binaryOperatorExpression.Right.AcceptVisitor(this, data); - return codeBinaryOperatorExpression; - } - - /// - /// Visits the statement's children. - /// - public object VisitBlockStatement(BlockStatement blockStatement, object data) - { - return blockStatement.AcceptChildren(this, data); - } - - public object VisitBreakStatement(BreakStatement breakStatement, object data) - { - Console.WriteLine("VisitBreakStatement"); - return null; - } - - public object VisitCaseLabel(CaseLabel caseLabel, object data) - { - Console.WriteLine("VisitCaseLabel"); - return null; - } - - /// - /// Ignore the cast and just visit the expression inside the cast. - /// - public object VisitCastExpression(CastExpression castExpression, object data) - { - return castExpression.Expression.AcceptVisitor(this, data); - } - - public object VisitCatchClause(CatchClause catchClause, object data) - { - Console.WriteLine("VisitCatchClause"); - return null; - } - - public object VisitCheckedExpression(CheckedExpression checkedExpression, object data) - { - Console.WriteLine("VisitCheckedExpression"); - return null; - } - - public object VisitCheckedStatement(CheckedStatement checkedStatement, object data) - { - Console.WriteLine("VisitCheckedStatement"); - return null; - } - - public object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data) - { - Console.WriteLine("VisitClassReferenceExpression"); - return null; - } - - /// - /// Converts from an NRefactory's compilation unit to a code dom's - /// compilation unit. - /// - public object VisitCompilationUnit(CompilationUnit compilationUnit, object data) - { - // Create code compile unit with one root namespace - // that has no name. - pythonCodeCompileUnit = new CodeCompileUnit(); - currentNamespace = new CodeNamespace(); - pythonCodeCompileUnit.Namespaces.Add(currentNamespace); - - // Visit the child items of the compilation unit. - compilationUnit.AcceptChildren(this, data); - - return pythonCodeCompileUnit; - } - - public object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data) - { - Console.WriteLine("VisitConditionalExpression"); - return null; - } - - /// - /// Adds a CodeMemberMethod to the current class being visited. - /// - public object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data) - { - CodeConstructor codeConstructor = new CodeConstructor(); - codeConstructor.Name = constructorDeclaration.Name; - currentClass.Members.Add(codeConstructor); - - // Add the constructor body. - Console.WriteLine(constructorDeclaration.Body.ToString()); - statementsStack.Push(codeConstructor.Statements); - constructorDeclaration.Body.AcceptVisitor(this, data); - statementsStack.Pop(); - - return null; - } - - public object VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data) - { - Console.WriteLine("VisitConstructorInitializer"); - return null; - } - - public object VisitContinueStatement(ContinueStatement continueStatement, object data) - { - Console.WriteLine("VisitContinueStatement"); - return null; - } - - public object VisitDeclareDeclaration(DeclareDeclaration declareDeclaration, object data) - { - Console.WriteLine("VisitDeclareDeclaration"); - return null; - } - - public object VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data) - { - Console.WriteLine("VisitDefaultValueExpression"); - return null; - } - - public object VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data) - { - Console.WriteLine("VisitDelegateDeclaration"); - return null; - } - - public object VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, object data) - { - Console.WriteLine("VisitDestructorDeclaration"); - return null; - } - - public object VisitDirectionExpression(DirectionExpression directionExpression, object data) - { - Console.WriteLine("VisitDirectionExpression"); - return null; - } - - public object VisitDoLoopStatement(DoLoopStatement doLoopStatement, object data) - { - Console.WriteLine("VisitDoLoopStatement"); - return null; - } - - /// - /// Converts the else if statement to a code dom statement. The - /// code dom does not support else if directly so we need to - /// add the condition to the false statements of the original if. - /// - /// if test1 - /// else if test2 - /// end if - /// - /// converts to: - /// - /// if test1 - /// else - /// if test 2 - /// end if - /// end if - /// - public object VisitElseIfSection(ElseIfSection elseIfSection, object data) - { - // Convert condition. - CodeConditionStatement conditionStatement = new CodeConditionStatement(); - conditionStatement.Condition = (CodeExpression)elseIfSection.Condition.AcceptVisitor(this, data); - - // Convert else if body statements. - statementsStack.Push(conditionStatement.TrueStatements); - elseIfSection.EmbeddedStatement.AcceptVisitor(this, data); - statementsStack.Pop(); - - AddStatement(conditionStatement); - return null; - } - - public object VisitEmptyStatement(EmptyStatement emptyStatement, object data) - { - Console.WriteLine("VisitEmptyStatement"); - return null; - } - - public object VisitEndStatement(EndStatement endStatement, object data) - { - Console.WriteLine("VistEndStatement"); - return null; - } - - public object VisitEraseStatement(EraseStatement eraseStatement, object data) - { - Console.WriteLine("VisitEraseStatement"); - return null; - } - - public object VisitErrorStatement(ErrorStatement errorStatement, object data) - { - Console.WriteLine("VisitErrorStatement"); - return null; - } - - public object VisitEventAddRegion(EventAddRegion eventAddRegion, object data) - { - Console.WriteLine("VisitEventAddRegion"); - return null; - } - - public object VisitEventDeclaration(EventDeclaration eventDeclaration, object data) - { - Console.WriteLine("VisitEventDeclaration"); - return null; - } - - public object VisitEventRaiseRegion(EventRaiseRegion eventRaiseRegion, object data) - { - Console.WriteLine("VisitEventRaiseRegion"); - return null; - } - - public object VisitEventRemoveRegion(EventRemoveRegion eventRemoveRegion, object data) - { - Console.WriteLine("VisitEventRemoveRegion"); - return null; - } - - public object VisitExitStatement(ExitStatement exitStatement, object data) - { - Console.WriteLine("VisitExitStatement"); - return null; - } - - public object VisitExternAliasDirective(ExternAliasDirective aliasDirective, object data) - { - return null; - } - - /// - /// Visits the expression statement. - /// - /// - /// When converting the ExpressionStatement's expression we - /// allow it to be either an Expression or a Statement. - /// One example is NRefactory's AssignExpression which - /// is converted to a code dom's CodeAssignStatement. If - /// the expression is really an expression then we wrap - /// the expression inside a CodeExpressionStatement. - /// - public object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) - { - Console.WriteLine("VisitExpressionStatement: " + expressionStatement.ToString()); - - // Convert the expression. - // Sometimes an expression is actually a statement - object convertedExpression = expressionStatement.Expression.AcceptVisitor(this, data); - if (convertedExpression is CodeStatement) { - CodeStatement convertedStatement = (CodeStatement)convertedExpression; - AddStatement(convertedStatement); - return convertedStatement; - } - - // Create a code expression statement to contain the expression. - CodeExpressionStatement createdStatement = new CodeExpressionStatement(); - createdStatement.Expression = (CodeExpression)convertedExpression; - AddStatement(createdStatement); - - return createdStatement; - } - - /// - /// Saves the field information so it can be added to the - /// class constructor. This is done since python requires you - /// to initialize any class instance variables in the - /// __init__ method. For example, consider the equivalent - /// C# and Python code: - /// - /// class Foo - /// { - /// private int i = 0; - /// } - /// - /// class Foo: - /// def __init__(self): - /// i = 0 - /// - /// The only difference is that the initialization is moved to the - /// class constructor. - /// - public object VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data) - { - // Save the field until the class has been processed. - currentClassFields.Add(fieldDeclaration); - return null; - } - - public object VisitFixedStatement(FixedStatement fixedStatement, object data) - { - Console.WriteLine("VisitFixedStatement"); - return null; - } - - /// - /// Converts a NRefactory's foreach statement to a CodeDom - /// CodeIterationStatement. - /// - public object VisitForeachStatement(ForeachStatement foreachStatement, object data) - { - // Convert the for loop's initializers. - CodeIterationStatement codeIterationStatement = new CodeIterationStatement(); - statementsStack.Push(nullStatementCollection); - codeIterationStatement.InitStatement = CreateInitStatement(foreachStatement); - statementsStack.Pop(); - - // Convert the for loop's test expression. - codeIterationStatement.TestExpression = CreateTestExpression(foreachStatement); - - // Move the initializer in the foreach loop to the - // first line of the for loop's body since the - // code dom does not support multiple InitStatements. - codeIterationStatement.Statements.Add(CreateIteratorVariableDeclaration(foreachStatement)); - - // Visit the for loop's body. - statementsStack.Push(codeIterationStatement.Statements); - foreachStatement.EmbeddedStatement.AcceptVisitor(this, data); - statementsStack.Pop(); - - AddStatement(codeIterationStatement); - return null; - } - - public object VisitForNextStatement(ForNextStatement forNextStatement, object data) - { - Console.WriteLine("VisitForNextStatement"); - return null; - } - - /// - /// Converts from an NRefactory for loop to a CodeDOM iteration - /// statement. - /// - public object VisitForStatement(ForStatement forStatement, object data) - { - CodeIterationStatement codeIterationStatement = new CodeIterationStatement(); - - // Convert the for loop's initializers. - statementsStack.Push(nullStatementCollection); - foreach (Statement statement in forStatement.Initializers) { - codeIterationStatement.InitStatement = (CodeStatement)statement.AcceptVisitor(this, data); - } - statementsStack.Pop(); - - // Convert the for loop's test expression. - codeIterationStatement.TestExpression = (CodeExpression)forStatement.Condition.AcceptVisitor(this, data); - - // Convert the for loop's increment statement. - statementsStack.Push(nullStatementCollection); - foreach (Statement statement in forStatement.Iterator) { - codeIterationStatement.IncrementStatement = (CodeStatement)statement.AcceptVisitor(this, data); - } - statementsStack.Pop(); - - // Visit the for loop's body. - statementsStack.Push(codeIterationStatement.Statements); - forStatement.EmbeddedStatement.AcceptVisitor(this, data); - statementsStack.Pop(); - - AddStatement(codeIterationStatement); - return null; - } - - public object VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement, object data) - { - Console.WriteLine("VisitGotoCaseStatement"); - return null; - } - - public object VisitGotoStatement(GotoStatement gotoStatement, object data) - { - Console.WriteLine("VisitGotoStatement"); - return null; - } - - /// - /// Converts from an NRefactory IdentifierExpression to a - /// CodeFieldReferenceExpression if the identifier refers to - /// a field. If it refers to a local variable it returns a - /// CodeVariableReferenceExpression. - /// - public object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) - { - if (IsField(identifierExpression.Identifier)) { - CodeFieldReferenceExpression fieldRef = new CodeFieldReferenceExpression(); - fieldRef.FieldName = "_" + identifierExpression.Identifier; - fieldRef.TargetObject = new CodeThisReferenceExpression(); - return fieldRef; - } else { - CodeVariableReferenceExpression variableRef = new CodeVariableReferenceExpression(); - variableRef.VariableName = identifierExpression.Identifier; - return variableRef; - } - } - - /// - /// Converts an NRefactory's if-else statement to a - /// CodeDOM's CodeConditionStatement. - /// - public object VisitIfElseStatement(IfElseStatement ifElseStatement, object data) - { - // Convert condition. - CodeConditionStatement conditionStatement = new CodeConditionStatement(); - conditionStatement.Condition = (CodeExpression)ifElseStatement.Condition.AcceptVisitor(this, data); - - // Convert true statements. - statementsStack.Push(conditionStatement.TrueStatements); - foreach (Statement statement in ifElseStatement.TrueStatement) { - statement.AcceptVisitor(this, data); - } - statementsStack.Pop(); - - // Convert false statements. - statementsStack.Push(conditionStatement.FalseStatements); - foreach (Statement statement in ifElseStatement.FalseStatement) { - statement.AcceptVisitor(this, data); - } - statementsStack.Pop(); - - // Convert else if sections. - statementsStack.Push(conditionStatement.FalseStatements); - foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) { - elseIfSection.AcceptVisitor(this, data); - } - statementsStack.Pop(); - - // Add condition statement to current method. - AddStatement(conditionStatement); - return null; - } - - public object VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration, object data) - { - Console.WriteLine("VisitIndexerDeclaration"); - return null; - } - - /// - /// Converts from an NRefactory array indexer expression to a - /// code dom CodeArrayIndexerExpression. - /// - public object VisitIndexerExpression(IndexerExpression indexerExpression, object data) - { - CodeArrayIndexerExpression codeArrayIndexerExpression = new CodeArrayIndexerExpression(); - codeArrayIndexerExpression.TargetObject = (CodeExpression)indexerExpression.TargetObject.AcceptVisitor(this, data); - - // Add indices. - foreach (CodeExpression expression in ConvertExpressions(indexerExpression.Indexes)) { - codeArrayIndexerExpression.Indices.Add(expression); - } - - return codeArrayIndexerExpression; - } - - public object VisitInnerClassTypeReference(InnerClassTypeReference innerClassTypeReference, object data) - { - Console.WriteLine("VisitInnerClassTypeReference"); - return null; - } - - public object VisitInterfaceImplementation(InterfaceImplementation interfaceImplementation, object data) - { - Console.WriteLine("VisitInterfaceImplementation"); - return null; - } - - /// - /// Converts an NRefactory Invocation Expression to a code dom's - /// CodeMethodInvokeStatement. - /// - public object VisitInvocationExpression(InvocationExpression invocationExpression, object data) - { - CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression(); - - MemberReferenceExpression memberRefExpression = invocationExpression.TargetObject as MemberReferenceExpression; - IdentifierExpression identifierExpression = invocationExpression.TargetObject as IdentifierExpression; - if (memberRefExpression != null) { - methodRef.MethodName = memberRefExpression.MemberName; - methodRef.TargetObject = (CodeExpression)memberRefExpression.TargetObject.AcceptVisitor(this, data); - - } else if (identifierExpression != null) { - methodRef.MethodName = identifierExpression.Identifier; - methodRef.TargetObject = new CodeThisReferenceExpression(); - } - - // Create method invoke. - CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); - methodInvoke.Parameters.AddRange(ConvertExpressions(invocationExpression.Arguments)); - methodInvoke.Method = methodRef; - return methodInvoke; - } - - public object VisitLabelStatement(LabelStatement labelStatement, object data) - { - Console.WriteLine("VisitLabelStatement"); - return null; - } - - /// - /// Adds the local variable declaration to the current method if - /// this one exists. - /// - public object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data) - { - // Create variable declaration. - VariableDeclaration variableDeclaration = localVariableDeclaration.Variables[0]; - string variableType = localVariableDeclaration.TypeReference.Type; - string variableName = variableDeclaration.Name; - CodeVariableDeclarationStatement codeVariableDeclarationStatement = new CodeVariableDeclarationStatement(variableType, variableName); - - // Convert the variable initializer from an NRefactory AST - // expression to a code dom expression. - codeVariableDeclarationStatement.InitExpression = (CodeExpression)variableDeclaration.Initializer.AcceptVisitor(this, data); - - // Add variable to current block. - AddStatement(codeVariableDeclarationStatement); - return codeVariableDeclarationStatement; - } - - public object VisitLockStatement(LockStatement lockStatement, object data) - { - Console.WriteLine("VisitLockStatement"); - return null; - } - - /// - /// Adds a CodeMemberMethod to the current class being visited. - /// - public object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data) - { - CodeMemberMethod codeMemberMethod = new CodeMemberMethod(); - codeMemberMethod.Name = methodDeclaration.Name; - codeMemberMethod.Attributes = ConvertMethodModifier(methodDeclaration.Modifier); - currentClass.Members.Add(codeMemberMethod); - - // Set user data so accepts and returns statements - // are not added before method. - codeMemberMethod.UserData["HasAccepts"] = false; - codeMemberMethod.UserData["HasReturns"] = false; - - // Add the parameters. - foreach (ParameterDeclarationExpression parameter in methodDeclaration.Parameters) { - codeMemberMethod.Parameters.Add(ConvertParameter(parameter)); - } - - // Add the method body. - statementsStack.Push(codeMemberMethod.Statements); - methodDeclaration.Body.AcceptVisitor(this, data); - statementsStack.Pop(); - - return null; - } - - public object VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, object data) - { - Console.WriteLine("VisitNamedArgumentExpression"); - return null; - } - - /// - /// Visits the namespace declaration and all child nodes. - /// - public object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) - { - return namespaceDeclaration.AcceptChildren(this, data); - } - - /// - /// Converts an NRefactory's ObjectCreateExpression to a code dom's - /// CodeObjectCreateExpression. - /// - public object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) - { - CodeObjectCreateExpression codeObjectCreateExpression = new CodeObjectCreateExpression(); - codeObjectCreateExpression.CreateType.BaseType = objectCreateExpression.CreateType.Type; - return codeObjectCreateExpression; - } - - public object VisitOnErrorStatement(OnErrorStatement onErrorStatement, object data) - { - return null; - } - - public object VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data) - { - Console.WriteLine("VisitOperatorDeclaration"); - return null; - } - - public object VisitOptionDeclaration(OptionDeclaration optionDeclaration, object data) - { - Console.WriteLine("VisitOptionDeclaration"); - return null; - } - - public object VisitParameterDeclarationExpression(ParameterDeclarationExpression parameterDeclarationExpression, object data) - { - Console.WriteLine("VisitParameterDeclarationExpression"); - return null; - } - - public object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data) - { - Console.WriteLine("VisitParenthesizedExpression"); - return null; - } - - public object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data) - { - Console.WriteLine("VisitPointerReferenceExpression"); - return null; - } - - /// - /// Converts a NRefactory primitive expression to a CodeDom's - /// CodePrimitiveExpression. - /// - public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) - { - return new CodePrimitiveExpression(primitiveExpression.Value); - } - - /// - /// Converts an NRefactory property declaration to a code dom - /// property. - /// - public object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) - { - CodeMemberProperty property = new CodeMemberProperty(); - property.Name = propertyDeclaration.Name; - property.Attributes = MemberAttributes.Public; - - // Set user data so accepts and returns statements - // are not added before get and set methods. - property.UserData["HasAccepts"] = false; - property.UserData["HasReturns"] = false; - - // Add get statements. - statementsStack.Push(property.GetStatements); - propertyDeclaration.GetRegion.Block.AcceptVisitor(this, data); - statementsStack.Pop(); - - // Add set statements. - statementsStack.Push(property.SetStatements); - propertyDeclaration.SetRegion.Block.AcceptVisitor(this, data); - statementsStack.Pop(); - - // Add the property to the current class. - currentClass.Members.Add(property); - return null; - } - - public object VisitPropertyGetRegion(PropertyGetRegion propertyGetRegion, object data) - { - Console.WriteLine("VisitPropertyGetRegion"); - return null; - } - - public object VisitPropertySetRegion(PropertySetRegion propertySetRegion, object data) - { - Console.WriteLine("VisitPropertySetRegion"); - return null; - } - - public object VisitRaiseEventStatement(RaiseEventStatement raiseEventStatement, object data) - { - Console.WriteLine("VisitRaiseEventStatement"); - return null; - } - - public object VisitReDimStatement(ReDimStatement reDimStatement, object data) - { - Console.WriteLine("VisitReDimStatement"); - return null; - } - - /// - /// Converts a NRefactory remove handler statement - /// (e.g. button.Click -= ButtonClick) to a - /// code dom statement. - /// - public object VisitRemoveHandlerStatement(RemoveHandlerStatement removeHandlerStatement, object data) - { - Console.WriteLine("VisitRemoveHandlerStatement"); - return null; - } - - public object VisitResumeStatement(ResumeStatement resumeStatement, object data) - { - Console.WriteLine("VisitResumeStatement"); - return null; - } - - /// - /// Converts a NRefactory ReturnStatement to a code dom's - /// CodeMethodReturnStatement. - /// - public object VisitReturnStatement(ReturnStatement returnStatement, object data) - { - CodeMethodReturnStatement codeMethodReturnStatement = new CodeMethodReturnStatement(); - codeMethodReturnStatement.Expression = (CodeExpression)returnStatement.Expression.AcceptVisitor(this, data); - AddStatement(codeMethodReturnStatement); - return null; - } - - public object VisitSizeOfExpression(SizeOfExpression sizeOfExpression, object data) - { - Console.WriteLine("VisitSizeOfExpression"); - return null; - } - - public object VisitStackAllocExpression(StackAllocExpression stackAllocExpression, object data) - { - return null; - } - - public object VisitStopStatement(StopStatement stopStatement, object data) - { - return null; - } - - public object VisitSwitchSection(SwitchSection switchSection, object data) - { - return null; - } - - public object VisitSwitchStatement(SwitchStatement switchStatement, object data) - { - return null; - } - - public object VisitTemplateDefinition(TemplateDefinition templateDefinition, object data) - { - return null; - } - - public object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) - { - Console.WriteLine("VisitThisReferenceExpression"); - return null; - } - - /// - /// Converts an NRefactory throw statement to a code dom's throw exception statement. - /// - public object VisitThrowStatement(ThrowStatement throwStatement, object data) - { - CodeThrowExceptionStatement codeThrowExceptionStatement = new CodeThrowExceptionStatement(); - codeThrowExceptionStatement.ToThrow = (CodeExpression)throwStatement.Expression.AcceptVisitor(this, data); - AddStatement(codeThrowExceptionStatement); - return null; - } - - /// - /// Converts an NRefactory try-catch statement to a code dom - /// try-catch statement. - /// - public object VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data) - { - // Convert try-catch body. - CodeTryCatchFinallyStatement codeTryCatchStatement = new CodeTryCatchFinallyStatement(); - statementsStack.Push(codeTryCatchStatement.TryStatements); - tryCatchStatement.StatementBlock.AcceptVisitor(this, data); - statementsStack.Pop(); - - // Convert catches. - foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) { - CodeCatchClause codeCatchClause = new CodeCatchClause(); - codeCatchClause.CatchExceptionType.BaseType = catchClause.TypeReference.Type; - codeCatchClause.LocalName = catchClause.VariableName; - - // Convert catch child statements. - statementsStack.Push(codeCatchClause.Statements); - catchClause.StatementBlock.AcceptVisitor(this, data); - statementsStack.Pop(); - - codeTryCatchStatement.CatchClauses.Add(codeCatchClause); - } - - // Convert finally block. - statementsStack.Push(codeTryCatchStatement.FinallyStatements); - tryCatchStatement.FinallyBlock.AcceptVisitor(this, data); - statementsStack.Pop(); - - AddStatement(codeTryCatchStatement); - return null; - } - - /// - /// Visits a class. - /// - public object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) - { - // Create a new type. - CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(typeDeclaration.Name); - currentClass = codeTypeDeclaration; - - // Ensure __slots__ is not added to generated code. - codeTypeDeclaration.UserData["HasSlots"] = false; - - // Add the type to the current namespace. - currentNamespace.Types.Add(codeTypeDeclaration); - - // Visit the rest of the class. - object o = typeDeclaration.AcceptChildren(this, data); - - // Add any class fields that were found to the constructor. - if (currentClassFields.Count > 0) { - AddFieldsToConstructor(); - currentClassFields.Clear(); - } - - return o; - } - - public object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data) - { - return null; - } - - public object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data) - { - Console.WriteLine("VisitTypeOfIsExpression"); - return null; - } - - public object VisitTypeReference(TypeReference typeReference, object data) - { - Console.WriteLine("VisitTypeReference"); - return null; - } - - public object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data) - { - Console.WriteLine("VisitTypeReferenceExpression"); - return null; - } - - /// - /// Converts a unary operator expression to a code dom expression. - /// - public object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) - { - switch (unaryOperatorExpression.Op) { - case UnaryOperatorType.PostIncrement: - case UnaryOperatorType.Increment: - // Change i++ or ++i to i = i + 1 - return CreateIncrementStatement(unaryOperatorExpression); - case UnaryOperatorType.Decrement: - case UnaryOperatorType.PostDecrement: - // Change --i or i-- to i = i - 1. - return CreateDecrementStatement(unaryOperatorExpression); - } - return null; - } - - public object VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data) - { - return null; - } - - public object VisitUncheckedStatement(UncheckedStatement uncheckedStatement, object data) - { - return null; - } - - public object VisitUnsafeStatement(UnsafeStatement unsafeStatement, object data) - { - return null; - } - - public object VisitUsing(Using @using, object data) - { - return null; - } - - /// - /// Converts using declarations into Python import statements. - /// - public object VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data) - { - foreach (Using @using in usingDeclaration.Usings) { - // Add import statements for each using. - CodeNamespaceImport import = new CodeNamespaceImport(@using.Name); - currentNamespace.Imports.Add(import); - } - - return usingDeclaration.AcceptChildren(this, data); - } - - public object VisitUsingStatement(UsingStatement usingStatement, object data) - { - return null; - } - - public object VisitVariableDeclaration(VariableDeclaration variableDeclaration, object data) - { - Console.WriteLine("VisitVariableDeclaration"); - return null; - } - - public object VisitWithStatement(WithStatement withStatement, object data) - { - return null; - } - - public object VisitYieldStatement(YieldStatement yieldStatement, object data) - { - return null; - } - - public object VisitCollectionInitializerExpression(CollectionInitializerExpression collectionInitializerExpression, object data) - { - return null; - } - - public object VisitLambdaExpression(LambdaExpression lambdaExpression, object data) - { - return null; - } - - /// - /// Converts an NRefactory MemberReferenceExpression to a - /// code dom's CodeFieldReferenceExpression. - /// - public object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) - { - CodeFieldReferenceExpression codeFieldReferenceExpression = new CodeFieldReferenceExpression(); - codeFieldReferenceExpression.FieldName = memberReferenceExpression.MemberName; - codeFieldReferenceExpression.TargetObject = (CodeExpression)memberReferenceExpression.TargetObject.AcceptVisitor(this, data); - return codeFieldReferenceExpression; - } - - public object VisitQueryExpression(QueryExpression queryExpression, object data) - { - return null; - } - - public object VisitQueryExpressionFromClause(QueryExpressionFromClause queryExpressionFromClause, object data) - { - return null; - } - - public object VisitQueryExpressionGroupClause(QueryExpressionGroupClause queryExpressionGroupClause, object data) - { - return null; - } - - public object VisitQueryExpressionJoinClause(QueryExpressionJoinClause queryExpressionJoinClause, object data) - { - return null; - } - - public object VisitQueryExpressionLetClause(QueryExpressionLetClause queryExpressionLetClause, object data) - { - return null; - } - - public object VisitQueryExpressionOrderClause(QueryExpressionOrderClause queryExpressionOrderClause, object data) - { - return null; - } - - public object VisitQueryExpressionOrdering(QueryExpressionOrdering queryExpressionOrdering, object data) - { - return null; - } - - public object VisitQueryExpressionSelectClause(QueryExpressionSelectClause queryExpressionSelectClause, object data) - { - return null; - } - - public object VisitQueryExpressionWhereClause(QueryExpressionWhereClause queryExpressionWhereClause, object data) - { - return null; - } - - public object VisitExpressionRangeVariable(ExpressionRangeVariable expressionRangeVariable, object data) - { - return null; - } - - public object VisitQueryExpressionAggregateClause(QueryExpressionAggregateClause queryExpressionAggregateClause, object data) - { - return null; - } - - public object VisitQueryExpressionDistinctClause(QueryExpressionDistinctClause queryExpressionDistinctClause, object data) - { - return null; - } - - public object VisitQueryExpressionGroupJoinVBClause(QueryExpressionGroupJoinVBClause queryExpressionGroupJoinVBClause, object data) - { - return null; - } - - public object VisitQueryExpressionGroupVBClause(QueryExpressionGroupVBClause queryExpressionGroupVBClause, object data) - { - return null; - } - - public object VisitQueryExpressionJoinConditionVB(QueryExpressionJoinConditionVB queryExpressionJoinConditionVB, object data) - { - return null; - } - - public object VisitQueryExpressionJoinVBClause(QueryExpressionJoinVBClause queryExpressionJoinVBClause, object data) - { - return null; - } - - public object VisitQueryExpressionLetVBClause(QueryExpressionLetVBClause queryExpressionLetVBClause, object data) - { - return null; - } - - public object VisitQueryExpressionPartitionVBClause(QueryExpressionPartitionVBClause queryExpressionPartitionVBClause, object data) - { - return null; - } - - public object VisitQueryExpressionSelectVBClause(QueryExpressionSelectVBClause queryExpressionSelectVBClause, object data) - { - return null; - } - - /// - /// Converts from the NRefactory method modifier to code DOM - /// member attributes. - /// - MemberAttributes ConvertMethodModifier(Modifiers modifiers) - { - MemberAttributes attributes = MemberAttributes.Public; - -// if (modifiers & Modifiers.Public == Modifiers.Public) { -// atributes -// } - - return attributes; - } - - /// - /// Adds fields to the constructor. - /// - /// - /// The fields should be inserted in the same order as they are - /// in the currentClassFields collection and they should be - /// inserted before any other code in the constructor. - /// - void AddFieldsToConstructor() - { - CodeConstructor constructor = GetOrCreateConstructor(currentClass); - - // Add fields to the constructor only if they have - // initializers. - for (int i = 0; i < currentClassFields.Count; ++i) { - FieldDeclaration fieldDeclaration = currentClassFields[i]; - if (FieldHasInitialValue(fieldDeclaration)) { - CodeAssignStatement assignStatement = CreateAssignStatement(fieldDeclaration); - constructor.Statements.Insert(i, assignStatement); - } - } - } - - /// - /// Checks that the field declaration has an initializer that - /// sets an initial value. - /// - static bool FieldHasInitialValue(FieldDeclaration fieldDeclaration) - { - VariableDeclaration variableDeclaration = fieldDeclaration.Fields[0]; - Expression initializer = variableDeclaration.Initializer; - return !initializer.IsNull; - } - - /// - /// Converts a field declaration into an assign statement. This - /// assign statement should then be added to the class's constructor. - /// This method is used when adding field initializer statements - /// to the constructor. - /// - CodeAssignStatement CreateAssignStatement(FieldDeclaration fieldDeclaration) - { - // Create the lhs of the assign statement. - CodeAssignStatement assignStatement = new CodeAssignStatement(); - CodeThisReferenceExpression thisReferenceExpression = new CodeThisReferenceExpression(); - VariableDeclaration variableDeclaration = fieldDeclaration.Fields[0]; - string fieldName = variableDeclaration.Name; - CodeFieldReferenceExpression fieldReferenceExpression = new CodeFieldReferenceExpression(thisReferenceExpression, "_" + fieldName); - assignStatement.Left = fieldReferenceExpression; - - // Create the rhs of the assign statement. - assignStatement.Right = (CodeExpression)variableDeclaration.Initializer.AcceptVisitor(this, null); - - return assignStatement; - } - - /// - /// Gets the constructor for the class or creates a new one if - /// it does not exist. - /// - static CodeConstructor GetOrCreateConstructor(CodeTypeDeclaration typeDeclaration) - { - // Find an existing constructor. - CodeConstructor constructor = GetConstructor(typeDeclaration); - if (constructor == null) { - // Create a new constructor. - constructor = new CodeConstructor(); - typeDeclaration.Members.Add(constructor); - } - return constructor; - } - - /// - /// Gets the constructor for the class. Returns null if none is - /// found. - /// - static CodeConstructor GetConstructor(CodeTypeDeclaration typeDeclaration) - { - foreach (CodeTypeMember member in typeDeclaration.Members) { - CodeConstructor constructor = member as CodeConstructor; - if (constructor != null) { - return constructor; - } - } - return null; - } - - /// - /// Adds the statement to the currently active statement collection. - /// - void AddStatement(CodeStatement statement) - { - CodeStatementCollection currentStatementCollection = statementsStack.Peek(); - currentStatementCollection.Add(statement); - } - - /// - /// Converts an NRefactory parameter to a CodeDom parameter declaration. - /// - CodeParameterDeclarationExpression ConvertParameter(ParameterDeclarationExpression expression) - { - CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(); - parameter.Name = expression.ParameterName; - return parameter; - } - - /// - /// Converts a post or pre increment expression to an assign statement. - /// This converts "i++" and "++i" to "i = i + 1" since the code dom - /// does not support post increment expressions. - /// - CodeAssignStatement CreateIncrementStatement(UnaryOperatorExpression unaryOperatorExpression) - { - return CreateIncrementStatement(unaryOperatorExpression, 1, CodeBinaryOperatorType.Add); - } - - /// - /// Converts a post or pre decrement expression to an assign statement. - /// This converts "i--" and "--i" to "i = i - 1" since the code dom - /// does not support post increment expressions. - /// - CodeAssignStatement CreateDecrementStatement(UnaryOperatorExpression unaryOperatorExpression) - { - return CreateIncrementStatement(unaryOperatorExpression, 1, CodeBinaryOperatorType.Subtract); - } - - /// - /// Converts a post or pre increment expression to an assign statement. - /// This converts "i++" and "++i" to "i = i + 1" since the code dom - /// does not support post increment expressions. - /// - CodeAssignStatement CreateIncrementStatement(UnaryOperatorExpression unaryOperatorExpression, int increment, CodeBinaryOperatorType binaryOperatorType) - { - // Lhs: i - CodeExpression expression = (CodeExpression)unaryOperatorExpression.Expression.AcceptVisitor(this, null); - CodeAssignStatement assignStatement = new CodeAssignStatement(); - assignStatement.Left = expression; - - // Rhs: i + increment - CodeBinaryOperatorExpression binaryExpression = new CodeBinaryOperatorExpression(); - binaryExpression.Operator = binaryOperatorType; - binaryExpression.Left = expression; - binaryExpression.Right = new CodePrimitiveExpression(increment); - assignStatement.Right = binaryExpression; - - return assignStatement; - } - - /// - /// Creates the code dom's expression for test expression for the - /// NRefactory foreach statement. The test expression will be - /// "enumerator.MoveNext()" which simulates what happens the test - /// condition in a foreach loop. - /// - CodeExpression CreateTestExpression(ForeachStatement foreachStatement) - { - CodeVariableReferenceExpression variableRef = new CodeVariableReferenceExpression(); - variableRef.VariableName = "enumerator"; - - CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); - methodInvoke.Method.MethodName = "MoveNext"; - methodInvoke.Method.TargetObject = variableRef; - return methodInvoke; - } - - /// - /// Creates the statement used to initialize the for loop. The - /// initialize statement will be "enumerator = variableName.GetEnumerator()" - /// which simulates what happens in a foreach loop. - /// - CodeStatement CreateInitStatement(ForeachStatement foreachStatement) - { - CodeVariableReferenceExpression variableRef = new CodeVariableReferenceExpression(); - variableRef.VariableName = GetForeachVariableName(foreachStatement); - - CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); - methodInvoke.Method.MethodName = "GetEnumerator"; - methodInvoke.Method.TargetObject = variableRef; - - CodeVariableDeclarationStatement variableDeclarationStatement = new CodeVariableDeclarationStatement(); - variableDeclarationStatement.InitExpression = methodInvoke; - variableDeclarationStatement.Name = "enumerator"; - - return variableDeclarationStatement; - } - - /// - /// Gets the name of the variable that is used in the - /// foreach loop as the item being iterated. - /// - string GetForeachVariableName(ForeachStatement foreachStatement) - { - IdentifierExpression identifierExpression = foreachStatement.Expression as IdentifierExpression; - return identifierExpression.Identifier; - } - - /// - /// Creates a code variable declaration statement for the iterator - /// used in the foreach loop. This statement should be like: - /// - /// "i = enumerator.Current" - /// - CodeVariableDeclarationStatement CreateIteratorVariableDeclaration(ForeachStatement foreachStatement) - { - CodePropertyReferenceExpression propertyRef = new CodePropertyReferenceExpression(); - propertyRef.PropertyName = "Current"; - propertyRef.TargetObject = new CodeVariableReferenceExpression("enumerator"); - - CodeVariableDeclarationStatement variableDeclaration = new CodeVariableDeclarationStatement(); - variableDeclaration.Name = foreachStatement.VariableName; - variableDeclaration.InitExpression = propertyRef; - - return variableDeclaration; - } - - /// - /// Determines whether the identifier refers to a field in the - /// current class. - /// - bool IsField(string name) - { - foreach (FieldDeclaration field in currentClassFields) { - if (field.Fields[0].Name == name) { - return true; - } - } - return false; - } - - /// - /// Converts a collection of NRefactory expressions to code dom expressions. - /// - CodeExpression[] ConvertExpressions(List expressions) - { - List codeExpressions = new List(); - foreach (Expression expression in expressions) { - CodeExpression convertedCodeExpression = (CodeExpression)expression.AcceptVisitor(this, null); - if (convertedCodeExpression != null) { - codeExpressions.Add(convertedCodeExpression); - } - } - return codeExpressions.ToArray(); - } - - /// - /// Creates a CodeAttachEventStatement - /// (i.e. button.Click += ButtonClick) - /// - CodeAttachEventStatement CreateAttachEventStatement(Expression eventExpression, Expression eventHandlerExpression) - { - // Create statement. - CodeAttachEventStatement attachEventStatement = new CodeAttachEventStatement(); - attachEventStatement.Event = CreateEventReferenceExpression(eventExpression); - attachEventStatement.Listener = CreateDelegateCreateExpression(eventHandlerExpression); - - return attachEventStatement; - } - - /// - /// Creates a CodeRemoveEventStatement - /// (i.e. button.Click -= ButtonClick) - /// - CodeRemoveEventStatement CreateRemoveEventStatement(Expression eventExpression, Expression eventHandlerExpression) - { - // Create statement. - CodeRemoveEventStatement removeEventStatement = new CodeRemoveEventStatement(); - removeEventStatement.Event = CreateEventReferenceExpression(eventExpression); - removeEventStatement.Listener = CreateDelegateCreateExpression(eventHandlerExpression); - return removeEventStatement; - } - - /// - /// Converts an expression to a CodeEventReferenceExpression - /// (i.e. the "button.Click" part of "button.Click += ButtonClick". - /// - CodeEventReferenceExpression CreateEventReferenceExpression(Expression eventExpression) - { - // Create event reference. - MemberReferenceExpression memberRef = eventExpression as MemberReferenceExpression; - CodeEventReferenceExpression eventRef = new CodeEventReferenceExpression(); - eventRef.TargetObject = (CodeExpression)memberRef.AcceptVisitor(this, null); - return eventRef; - } - - /// - /// Converts an event handler expression to a CodeDelegateCreateExpression. - /// (i.e. the "ButtonClick" part of "button.Click += ButtonClick") - /// - CodeDelegateCreateExpression CreateDelegateCreateExpression(Expression eventHandlerExpression) - { - // Create event handler expression. - IdentifierExpression identifierExpression = eventHandlerExpression as IdentifierExpression; - CodeDelegateCreateExpression listenerExpression = new CodeDelegateCreateExpression(); - listenerExpression.MethodName = identifierExpression.Identifier; - return listenerExpression; - } - - /// - /// Determines whether the assignment expression is actually an - /// event handler attach statement. - /// - static bool IsAddEventHandler(AssignmentExpression assignmentExpression) - { - return (assignmentExpression.Op == AssignmentOperatorType.Add) && - (assignmentExpression.Left is MemberReferenceExpression); - } - - /// - /// Determines whether the assignment expression is actually an - /// event handler remove statement. - /// - static bool IsRemoveEventHandler(AssignmentExpression assignmentExpression) - { - return (assignmentExpression.Op == AssignmentOperatorType.Subtract) && - (assignmentExpression.Left is MemberReferenceExpression); - } - - /// - /// Creates an assignment statement of the form: - /// i = i + 10. - /// - CodeAssignStatement CreateAddAssignmentStatement(AssignmentExpression assignmentExpression) - { - return CreateAssignmentStatementWithBinaryOperatorExpression(assignmentExpression, CodeBinaryOperatorType.Add); - } - - /// - /// Creates an assign statement with the right hand side of the - /// assignment using a binary operator. - /// - CodeAssignStatement CreateAssignmentStatementWithBinaryOperatorExpression(AssignmentExpression assignmentExpression, CodeBinaryOperatorType binaryOperatorType) - { - // Create the left hand side of the assignment. - CodeAssignStatement codeAssignStatement = new CodeAssignStatement(); - codeAssignStatement.Left = (CodeExpression)assignmentExpression.Left.AcceptVisitor(this, null); - - // Create the right hand side of the assignment. - CodeBinaryOperatorExpression binaryExpression = new CodeBinaryOperatorExpression(); - binaryExpression.Operator = binaryOperatorType; - binaryExpression.Left = codeAssignStatement.Left; - binaryExpression.Right = (CodeExpression)assignmentExpression.Right.AcceptVisitor(this, null); - codeAssignStatement.Right = binaryExpression; - - return codeAssignStatement; - } - - /// - /// Creates an assignment statement of the form: - /// i = i - 10. - /// - CodeAssignStatement CreateSubtractAssignmentStatement(AssignmentExpression assignmentExpression) - { - return CreateAssignmentStatementWithBinaryOperatorExpression(assignmentExpression, CodeBinaryOperatorType.Subtract); - } - } -} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs index f94c892aa4..3cac677273 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs @@ -85,20 +85,16 @@ namespace ICSharpCode.PythonBinding /// Deserializes expressions of the form: /// /// 1) System.Drawing.Color.FromArgb(0, 192, 0) + /// 2) System.Array[String](["a", "b"]) /// object Deserialize(CallExpression callExpression) { MemberExpression memberExpression = callExpression.Target as MemberExpression; - PythonControlFieldExpression field = PythonControlFieldExpression.Create(memberExpression); - Type type = GetType(field); - if (type != null) { - foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { - if (method.Name == field.MemberName) { - if (method.GetParameters().Length == callExpression.Args.Length) { - return method.Invoke(null, GetArguments(callExpression).ToArray()); - } - } - } + IndexExpression indexExpression = callExpression.Target as IndexExpression; + if (memberExpression != null) { + return DeserializeMethodCallExpression(callExpression, memberExpression); + } else if (indexExpression != null) { + return DeserializeCreateArrayExpression(callExpression, indexExpression); } return null; } @@ -130,5 +126,51 @@ namespace ICSharpCode.PythonBinding { return componentCreator.GetType(PythonControlFieldExpression.GetPrefix(field.FullMemberName)); } + + /// + /// Deserializes a call expression where the target is an array expression. + /// + /// System.Array[String](["a", "b"]) + /// + object DeserializeCreateArrayExpression(CallExpression callExpression, IndexExpression target) + { + ListExpression list = callExpression.Args[0].Expression as ListExpression; + MemberExpression arrayTypeMemberExpression = target.Index as MemberExpression; + Type arrayType = componentCreator.GetType(PythonControlFieldExpression.GetMemberName(arrayTypeMemberExpression)); + Array array = Array.CreateInstance(arrayType, list.Items.Length); + for (int i = 0; i < list.Items.Length; ++i) { + Expression listItemExpression = list.Items[i]; + ConstantExpression constantExpression = listItemExpression as ConstantExpression; + MemberExpression memberExpression = listItemExpression as MemberExpression; + if (constantExpression != null) { + array.SetValue(constantExpression.Value, i); + } else if (memberExpression != null) { + string name = PythonControlFieldExpression.GetVariableName(memberExpression.Name.ToString()); + array.SetValue(componentCreator.GetComponent(name), i); + } + } + return array; + } + + /// + /// Deserializes an expression of the form: + /// + /// System.Drawing.Color.FromArgb(0, 192, 0) + /// + object DeserializeMethodCallExpression(CallExpression callExpression, MemberExpression memberExpression) + { + PythonControlFieldExpression field = PythonControlFieldExpression.Create(memberExpression); + Type type = GetType(field); + if (type != null) { + foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { + if (method.Name == field.MemberName) { + if (method.GetParameters().Length == callExpression.Args.Length) { + return method.Invoke(null, GetArguments(callExpression).ToArray()); + } + } + } + } + return null; + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs index 6d27ecd5b2..1a88604094 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs @@ -7,6 +7,8 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; using System.Text; using IronPython.Compiler.Ast; @@ -23,12 +25,14 @@ namespace ICSharpCode.PythonBinding string memberName = String.Empty; string fullMemberName = String.Empty; string variableName = String.Empty; + string methodName = String.Empty; - PythonControlFieldExpression(string memberName, string fullMemberName) + PythonControlFieldExpression(string memberName, string variableName, string methodName, string fullMemberName) { this.memberName = memberName; + this.variableName = variableName; + this.methodName = methodName; this.fullMemberName = fullMemberName; - this.variableName = GetVariableNameFromSelfReference(fullMemberName); } /// @@ -52,6 +56,32 @@ namespace ICSharpCode.PythonBinding get { return variableName; } } + /// + /// Returns the method being called by the field reference. + /// + public string MethodName { + get { return methodName; } + } + + public override string ToString() + { + return fullMemberName; + } + + public override bool Equals(object obj) + { + PythonControlFieldExpression rhs = obj as PythonControlFieldExpression; + if (rhs != null) { + return rhs.fullMemberName == fullMemberName; + } + return false; + } + + public override int GetHashCode() + { + return fullMemberName.GetHashCode(); + } + /// /// Creates a PythonControlField from a member expression: /// @@ -60,11 +90,28 @@ namespace ICSharpCode.PythonBinding /// public static PythonControlFieldExpression Create(MemberExpression expression) { - string memberName = expression.Name.ToString(); - string fullMemberName = PythonControlFieldExpression.GetMemberName(expression); - return new PythonControlFieldExpression(memberName, fullMemberName); + return Create(GetMemberNames(expression)); } + /// + /// Creates a PythonControlField from a call expression: + /// + /// self._menuItem1.Items.AddRange(...) + /// + public static PythonControlFieldExpression Create(CallExpression expression) + { + string[] allNames = GetMemberNames(expression.Target as MemberExpression); + + // Remove last member since it is the method name. + int lastItemIndex = allNames.Length - 1; + string[] memberNames = new string[lastItemIndex]; + Array.Copy(allNames, memberNames, lastItemIndex); + + PythonControlFieldExpression field = Create(memberNames); + field.methodName = allNames[lastItemIndex]; + return field; + } + /// /// From a name such as "System.Windows.Forms.Cursors.AppStarting" this method returns: /// "System.Windows.Forms.Cursors" @@ -122,7 +169,7 @@ namespace ICSharpCode.PythonBinding public static string GetVariableName(string name) { if (!String.IsNullOrEmpty(name)) { - if (name.Length > 1) { + if (name.Length > 0) { if (name[0] == '_') { return name.Substring(1); } @@ -136,22 +183,57 @@ namespace ICSharpCode.PythonBinding /// public static string GetMemberName(MemberExpression expression) { - StringBuilder typeName = new StringBuilder(); - + return GetMemberName(GetMemberNames(expression)); + } + + /// + /// Gets the member names that make up the MemberExpression in order. + /// + public static string[] GetMemberNames(MemberExpression expression) + { + List names = new List(); while (expression != null) { - typeName.Insert(0, expression.Name); - typeName.Insert(0, "."); + names.Insert(0, expression.Name.ToString()); NameExpression nameExpression = expression.Target as NameExpression; expression = expression.Target as MemberExpression; if (expression == null) { if (nameExpression != null) { - typeName.Insert(0, nameExpression.Name); + names.Insert(0, nameExpression.Name.ToString()); } } } + return names.ToArray(); + } + + /// + /// Gets the member object that matches the field member. + /// + public object GetMember(IComponentCreator componentCreator) + { + object obj = componentCreator.GetComponent(variableName); + if (obj == null) { + return null; + } - return typeName.ToString(); + Type type = obj.GetType(); + string[] memberNames = fullMemberName.Split('.'); + for (int i = 2; i < memberNames.Length; ++i) { + string name = memberNames[i]; + BindingFlags propertyBindingFlags = BindingFlags.Public | BindingFlags.GetField | BindingFlags.Static | BindingFlags.Instance; + PropertyInfo property = type.GetProperty(name, propertyBindingFlags); + if (property != null) { + obj = property.GetValue(obj, null); + } else { + return null; + } + } + return obj; + } + + static string GetMemberName(string[] names) + { + return String.Join(".", names); } /// @@ -173,6 +255,16 @@ namespace ICSharpCode.PythonBinding return String.Empty; } return name; - } + } + + static PythonControlFieldExpression Create(string[] memberNames) + { + string memberName = String.Empty; + if (memberNames.Length > 1) { + memberName = memberNames[memberNames.Length - 1]; + } + string fullMemberName = PythonControlFieldExpression.GetMemberName(memberNames); + return new PythonControlFieldExpression(memberName, GetVariableNameFromSelfReference(fullMemberName), String.Empty, fullMemberName); + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs index 27c0b14bf7..2d961183fe 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs @@ -8,6 +8,7 @@ using System; using System.CodeDom; using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; @@ -29,6 +30,7 @@ namespace ICSharpCode.PythonBinding { IPythonDesignerGenerator generator; IDesignerSerializationManager serializationManager; + Dictionary addedObjects = new Dictionary(); public PythonDesignerLoader(IPythonDesignerGenerator generator) { @@ -61,6 +63,18 @@ namespace ICSharpCode.PythonBinding public void Add(IComponent component, string name) { base.LoaderHost.Container.Add(component, name); + addedObjects.Add(name, component); + } + + /// + /// Gets a component that has been added to the loader. + /// + /// Null if the component cannot be found. + public IComponent GetComponent(string name) + { + IComponent component = null; + addedObjects.TryGetValue(name, out component); + return component; } /// diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs index b49ab41a8d..57fef3c03d 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs @@ -130,9 +130,8 @@ namespace ICSharpCode.PythonBinding void GenerateInitializeComponentMethodBodyInternal(Form form) { - AppendChildControlCreation(form.Controls); + AppendChildControlCreation(form); AppendChildControlSuspendLayout(form.Controls); - AppendIndentedLine("self.SuspendLayout()"); AppendForm(form); AppendChildControlResumeLayout(form.Controls); @@ -166,30 +165,25 @@ namespace ICSharpCode.PythonBinding { AppendComment(control.Name); - string propertyOwnerName = String.Empty; - if (addControlNameToProperty) { - propertyOwnerName = control.Name; - } - - foreach (PropertyDescriptor property in GetSerializableProperties(control)) { - AppendProperty(propertyOwnerName, control, property); - } + string propertyOwnerName = GetPropertyOwnerName(control, addControlNameToProperty); + AppendProperties(propertyOwnerName, control); foreach (Control childControl in control.Controls) { - if (IsSitedControl(childControl)) { + if (IsSitedComponent(childControl)) { AppendIndentedLine(GetPropertyName(propertyOwnerName, "Controls") + ".Add(self._" + childControl.Name + ")"); } } - + + AppendEventHandlers(propertyOwnerName, control); + + MenuStrip menuStrip = control as MenuStrip; + if (menuStrip != null) { + AppendMenuStripItems(menuStrip); + } + if (addChildControlProperties) { - foreach (Control childControl in control.Controls) { - if (IsSitedControl(childControl)) { - AppendControl(childControl, true, true); - } - } + AppendChildControlProperties(control.Controls); } - - AppendEventHandlers(propertyOwnerName, control); } /// @@ -236,6 +230,11 @@ namespace ICSharpCode.PythonBinding { ++indent; } + + void DecreaseIndent() + { + --indent; + } void Append(string text) { @@ -260,19 +259,52 @@ namespace ICSharpCode.PythonBinding codeBuilder.Append(text); } + void AppendChildControlCreation(Control parentControl) + { + MenuStrip menuStrip = parentControl as MenuStrip; + if (menuStrip != null) { + AppendChildControlCreation(menuStrip.Items); + } else { + AppendChildControlCreation(parentControl.Controls); + } + } + void AppendChildControlCreation(Control.ControlCollection controls) { foreach (Control control in controls) { - if (IsSitedControl(control)) { - AppendControlCreation(control); - AppendChildControlCreation(control.Controls); + if (IsSitedComponent(control)) { + AppendComponentCreation(control); + AppendChildControlCreation(control); } } } - void AppendControlCreation(Control control) + void AppendChildControlCreation(ToolStripItemCollection toolStripItems) { - AppendIndentedLine("self._" + control.Name + " = " + control.GetType().FullName + "()"); + foreach (ToolStripItem item in toolStripItems) { + if (IsSitedComponent(item)) { + AppendComponentCreation(item); + } + ToolStripMenuItem menuItem = item as ToolStripMenuItem; + if (menuItem != null) { + AppendChildControlCreation(menuItem.DropDownItems); + } + } + } + + void AppendComponentCreation(Control control) + { + AppendComponentCreation(control.Name, control); + } + + void AppendComponentCreation(ToolStripItem item) + { + AppendComponentCreation(item.Name, item); + } + + void AppendComponentCreation(string name, object obj) + { + AppendIndentedLine("self._" + name + " = " + obj.GetType().FullName + "()"); } void AppendChildControlSuspendLayout(Control.ControlCollection controls) @@ -282,21 +314,20 @@ namespace ICSharpCode.PythonBinding void AppendChildControlResumeLayout(Control.ControlCollection controls) { - AppendChildControlLayoutMethodCalls(controls, new string[] {"ResumeLayout(false)", "PerformLayout()"}); + AppendChildControlLayoutMethodCalls(controls, new string[] {"ResumeLayout(False)", "PerformLayout()"}); } - void AppendChildControlLayoutMethodCalls(Control.ControlCollection controls, string[] methods) { foreach (Control control in controls) { - if (HasSitedChildControls(control)) { + if (HasSitedChildComponents(control)) { foreach (string method in methods) { AppendIndentedLine("self._" + control.Name + "." + method); } AppendChildControlLayoutMethodCalls(control.Controls, methods); } } - } + } /// /// Generates code that wires an event to an event handler. @@ -326,16 +357,21 @@ namespace ICSharpCode.PythonBinding } } - static bool IsSitedControl(Control control) + static bool IsSitedComponent(IComponent component) { - return control.Site != null; + return component.Site != null; } - bool HasSitedChildControls(Control control) + bool HasSitedChildComponents(Control control) { + MenuStrip menuStrip = control as MenuStrip; + if (menuStrip != null) { + return HasSitedComponents(menuStrip.Items); + } + if (control.Controls.Count > 0) { foreach (Control childControl in control.Controls) { - if (!IsSitedControl(childControl)) { + if (!IsSitedComponent(childControl)) { return false; } } @@ -343,5 +379,111 @@ namespace ICSharpCode.PythonBinding } return false; } + + bool HasSitedComponents(ToolStripItemCollection items) + { + foreach (ToolStripItem item in items) { + if (IsSitedComponent(item)) { + return true; + } + } + return false; + } + + /// + /// Adds ToolStripItems that are stored on the MenuStrip. + /// + void AppendMenuStripItems(MenuStrip menuStrip) + { + List items = GetSitedToolStripItems(menuStrip.Items); + AppendMenuStripItemsAddRange(menuStrip.Name, items); + AppendToolStripItems(items); + } + + void AppendSystemArray(string componentName, string methodName, string typeName, IList components) + { + if (components.Count > 0) { + AppendIndentedLine("self._" + componentName + "." + methodName + "(System.Array[" + typeName + "]("); + IncreaseIndent(); + for (int i = 0; i < components.Count; ++i) { + if (i == 0) { + AppendIndented("["); + } else { + Append(","); + AppendLine(); + AppendIndented(String.Empty); + } + Append("self._" + ((IComponent)components[i]).Site.Name); + } + Append("]))"); + AppendLine(); + DecreaseIndent(); + } + } + + void AppendMenuStripItemsAddRange(string menuStripName, List items) + { + AppendSystemArray(menuStripName, "Items.AddRange", typeof(ToolStripItem).FullName, items); + } + + List GetSitedToolStripItems(ToolStripItemCollection items) + { + List sitedItems = new List(); + foreach (ToolStripItem item in items) { + if (IsSitedComponent(item)) { + sitedItems.Add(item); + } + } + return sitedItems; + } + + void AppendToolStripItems(IList items) + { + foreach (ToolStripItem item in items) { + AppendToolStripItem(item); + } + } + + void AppendToolStripItem(ToolStripItem item) + { + AppendComment(item.Name); + AppendProperties(item.Name, item); + + ToolStripMenuItem menuItem = item as ToolStripMenuItem; + if (menuItem != null) { + List sitedItems = GetSitedToolStripItems(menuItem.DropDownItems); + AppendToolStripMenuItemDropDownItems(menuItem.Name, sitedItems); + AppendToolStripItems(sitedItems); + } + } + + void AppendToolStripMenuItemDropDownItems(string menuItemName, List items) + { + AppendSystemArray(menuItemName, "DropDownItems.AddRange", typeof(ToolStripItem).FullName, items); + } + + void AppendProperties(string propertyOwnerName, object obj) + { + foreach (PropertyDescriptor property in GetSerializableProperties(obj)) { + AppendProperty(propertyOwnerName, obj, property); + } + } + + string GetPropertyOwnerName(Control control, bool addControlNameToProperty) + { + if (addControlNameToProperty) { + return control.Name; + } + return String.Empty; + } + + void AppendChildControlProperties(Control.ControlCollection controls) + { + foreach (Control childControl in controls) { + if (IsSitedComponent(childControl)) { + AppendControl(childControl, true, true); + } + } + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs index 54ee73995f..6e965d24a1 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs @@ -27,7 +27,6 @@ namespace ICSharpCode.PythonBinding PythonControlFieldExpression fieldExpression; IComponentCreator componentCreator; bool walkingAssignment; - Dictionary createdObjects = new Dictionary(); string formName = String.Empty; PythonCodeDeserializer deserializer; @@ -65,7 +64,7 @@ namespace ICSharpCode.PythonBinding public override bool Walk(FunctionDefinition node) { - if (IsInitializeComponentMethod(node)) { + if (IsInitializeComponentMethod(node)) { form = (Form)componentCreator.CreateComponent(typeof(Form), formName); node.Body.Walk(this); } @@ -78,7 +77,6 @@ namespace ICSharpCode.PythonBinding MemberExpression lhsMemberExpression = node.Left[0] as MemberExpression; if (lhsMemberExpression != null) { fieldExpression = PythonControlFieldExpression.Create(lhsMemberExpression); - MemberExpression rhsMemberExpression = node.Right as MemberExpression; if (rhsMemberExpression != null) { object propertyValue = GetPropertyValueFromAssignmentRhs(rhsMemberExpression); @@ -130,6 +128,13 @@ namespace ICSharpCode.PythonBinding string parentControlName = PythonControlFieldExpression.GetParentControlNameAddingChildControls(name); if (parentControlName != null) { AddChildControl(parentControlName, node); + } else { + PythonControlFieldExpression field = PythonControlFieldExpression.Create(node); + object member = field.GetMember(componentCreator); + if (member != null) { + object parameter = deserializer.Deserialize(node.Args[0].Expression); + member.GetType().InvokeMember(field.MethodName, BindingFlags.InvokeMethod, Type.DefaultBinder, member, new object[] {parameter}); + } } } } @@ -187,19 +192,18 @@ namespace ICSharpCode.PythonBinding /// bool SetPropertyValue(string name, object propertyValue) { - Control control = GetCurrentControl(); - return SetPropertyValue(control, name, propertyValue); + return SetPropertyValue(GetCurrentComponent(), name, propertyValue); } /// - /// Sets the value of a property on the control. + /// Sets the value of a property on the component. /// - bool SetPropertyValue(Control control, string name, object propertyValue) + bool SetPropertyValue(object component, string name, object propertyValue) { - PropertyDescriptor property = TypeDescriptor.GetProperties(control).Find(name, true); + PropertyDescriptor property = TypeDescriptor.GetProperties(component).Find(name, true); if (property != null) { propertyValue = ConvertPropertyValue(property, propertyValue); - property.SetValue(control, propertyValue); + property.SetValue(component, propertyValue); return true; } return false; @@ -222,9 +226,7 @@ namespace ICSharpCode.PythonBinding /// Control GetControl(string name) { - object o = null; - createdObjects.TryGetValue(name, out o); - return o as Control; + return componentCreator.GetComponent(name) as Control; } /// @@ -234,16 +236,15 @@ namespace ICSharpCode.PythonBinding { string variableName = PythonControlFieldExpression.GetVariableName(name); componentCreator.Add(component as IComponent, variableName); - createdObjects.Add(variableName, component); } /// /// Gets the current control being walked. /// - Control GetCurrentControl() + object GetCurrentComponent() { if (fieldExpression.VariableName.Length > 0) { - return GetControl(fieldExpression.VariableName); + return componentCreator.GetComponent(fieldExpression.VariableName); } return form; } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs index 9c95351632..f3044a972e 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs @@ -38,7 +38,7 @@ namespace PythonBinding.Tests.Designer [Test] public void CursorsTypeResolved() { - Assert.AreEqual("System.Windows.Forms.Cursors", base.LastTypeNameResolved); + Assert.AreEqual("System.Windows.Forms.Cursors", base.componentCreator.LastTypeNameResolved); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeAssignmentTestFixtureBase.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeAssignmentTestFixtureBase.cs index 9e04f8f402..e77529458b 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeAssignmentTestFixtureBase.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeAssignmentTestFixtureBase.cs @@ -21,25 +21,25 @@ namespace PythonBinding.Tests.Designer /// Base class for all tests of the PythonCodeDeserialize when deserializing an /// assignment. /// - public abstract class DeserializeAssignmentTestFixtureBase : LoadFormTestFixtureBase + public abstract class DeserializeAssignmentTestFixtureBase { protected Node rhsAssignmentNode; protected object deserializedObject; protected MockDesignerLoaderHost mockDesignerLoaderHost; protected MockTypeResolutionService typeResolutionService; + protected MockComponentCreator componentCreator; [TestFixtureSetUp] - public new void SetUpFixture() + public void SetUpFixture() { - PythonParser parser = new PythonParser(); - PythonAst ast = parser.CreateAst(@"snippet.py", GetPythonCode()); - SuiteStatement suiteStatement = (SuiteStatement)ast.Body; - AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; + componentCreator = new MockComponentCreator(); + + AssignmentStatement assignment = PythonParserHelper.GetAssignmentStatement(GetPythonCode()); rhsAssignmentNode = assignment.Right; mockDesignerLoaderHost = new MockDesignerLoaderHost(); typeResolutionService = mockDesignerLoaderHost.TypeResolutionService; - PythonCodeDeserializer deserializer = new PythonCodeDeserializer(this); + PythonCodeDeserializer deserializer = new PythonCodeDeserializer(componentCreator); deserializedObject = deserializer.Deserialize(rhsAssignmentNode); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeColorFromArgbTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeColorFromArgbTestFixture.cs index a4455dd857..e73343538b 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeColorFromArgbTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeColorFromArgbTestFixture.cs @@ -39,7 +39,7 @@ namespace PythonBinding.Tests.Designer [Test] public void ColorTypeResolved() { - Assert.AreEqual("System.Drawing.Color", LastTypeNameResolved); + Assert.AreEqual("System.Drawing.Color", componentCreator.LastTypeNameResolved); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeStringArrayTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeStringArrayTestFixture.cs new file mode 100644 index 0000000000..12f4dd4401 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeStringArrayTestFixture.cs @@ -0,0 +1,46 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + /// + /// Tests that the string "System.Array" can be converted to an array. + /// + [TestFixture] + public class DeserializeStringArrayTestFixture : DeserializeAssignmentTestFixtureBase + { + public override string GetPythonCode() + { + return "self.Items = System.Array[System.String](\r\n" + + " [\"a\",\r\n" + + " \"b\"])"; + } + + [Test] + public void DeserializedObjectIsExpectedArray() + { + string[] expectedArray = new string[] {"a", "b"}; + Assert.AreEqual(expectedArray, deserializedObject); + } + + [Test] + public void StringTypeResolved() + { + Assert.AreEqual("System.String", componentCreator.LastTypeNameResolved); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeToolStripItemArrayTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeToolStripItemArrayTestFixture.cs new file mode 100644 index 0000000000..17c6aa8c90 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/DeserializeToolStripItemArrayTestFixture.cs @@ -0,0 +1,52 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class DeserializeToolStripItemArrayTestFixture : DeserializeAssignmentTestFixtureBase + { + ToolStripMenuItem fileMenuItem; + ToolStripMenuItem editMenuItem; + + public override string GetPythonCode() + { + fileMenuItem = (ToolStripMenuItem)componentCreator.CreateComponent(typeof(ToolStripMenuItem), "fileToolStripMenuItem"); + editMenuItem = (ToolStripMenuItem)componentCreator.CreateComponent(typeof(ToolStripMenuItem), "editToolStripMenuItem"); + + componentCreator.Add(fileMenuItem, "fileToolStripMenuItem"); + componentCreator.Add(editMenuItem, "editToolStripMenuItem"); + + return "self.Items = System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._fileToolStripMenuItem,\r\n" + + " self._editToolStripMenuItem])"; + } + + [Test] + public void DeserializedObjectIsExpectedCustomColor() + { + ToolStripItem[] expectedArray = new ToolStripItem[] {fileMenuItem, editMenuItem}; + Assert.AreEqual(expectedArray, deserializedObject); + } + + [Test] + public void StringTypeResolved() + { + Assert.AreEqual("System.Windows.Forms.ToolStripItem", componentCreator.LastTypeNameResolved); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs new file mode 100644 index 0000000000..1328e131df --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateMenuStripItemsTestFixture.cs @@ -0,0 +1,141 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Serialization; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class GenerateMenuStripItemsFormTestFixture + { + string generatedPythonCode; + + [TestFixtureSetUp] + public void SetUpFixture() + { + using (DesignSurface designSurface = new DesignSurface(typeof(Form))) { + IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost)); + IEventBindingService eventBindingService = new MockEventBindingService(host); + Form form = (Form)host.RootComponent; + form.ClientSize = new Size(200, 300); + + PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form); + PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false); + namePropertyDescriptor.SetValue(form, "MainForm"); + + // Add menu strip. + MenuStrip menuStrip = (MenuStrip)host.CreateComponent(typeof(MenuStrip), "menuStrip1"); + menuStrip.Text = "menuStrip1"; + menuStrip.TabIndex = 0; + menuStrip.Location = new Point(0, 0); + menuStrip.Size = new System.Drawing.Size(200, 24); + + // Add menu strip items. + ToolStripMenuItem fileMenuItem = (ToolStripMenuItem)host.CreateComponent(typeof(ToolStripMenuItem), "fileToolStripMenuItem"); + fileMenuItem.Size = new Size(37, 20); + fileMenuItem.Text = "&File"; + + ToolStripMenuItem openMenuItem = (ToolStripMenuItem)host.CreateComponent(typeof(ToolStripMenuItem), "openToolStripMenuItem"); + openMenuItem.Size = new Size(37, 20); + openMenuItem.Text = "&Open"; + + ToolStripMenuItem exitMenuItem = (ToolStripMenuItem)host.CreateComponent(typeof(ToolStripMenuItem), "exitToolStripMenuItem"); + exitMenuItem.Size = new Size(37, 20); + exitMenuItem.Text = "E&xit"; + fileMenuItem.DropDownItems.Add(openMenuItem); + fileMenuItem.DropDownItems.Add(exitMenuItem); + + // Add non-sited component. + fileMenuItem.DropDownItems.Add(new ToolStripMenuItem()); + + menuStrip.Items.Add(fileMenuItem); + + ToolStripMenuItem editMenuItem = (ToolStripMenuItem)host.CreateComponent(typeof(ToolStripMenuItem), "editToolStripMenuItem"); + editMenuItem.Size = new Size(39, 20); + editMenuItem.Text = "&Edit"; + menuStrip.Items.Add(editMenuItem); + + form.Controls.Add(menuStrip); + + PythonForm pythonForm = new PythonForm(" "); + generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form); + } + } + + [Test] + public void GeneratedCode() + { + string expectedCode = "def InitializeComponent(self):\r\n" + + " self._menuStrip1 = System.Windows.Forms.MenuStrip()\r\n" + + " self._fileToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._openToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._exitToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._editToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._menuStrip1.SuspendLayout()\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # menuStrip1\r\n" + + " # \r\n" + + " self._menuStrip1.Location = System.Drawing.Point(0, 0)\r\n" + + " self._menuStrip1.Name = \"menuStrip1\"\r\n" + + " self._menuStrip1.Size = System.Drawing.Size(200, 24)\r\n" + + " self._menuStrip1.TabIndex = 0\r\n" + + " self._menuStrip1.Text = \"menuStrip1\"\r\n" + + " self._menuStrip1.Items.AddRange(System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._fileToolStripMenuItem,\r\n" + + " self._editToolStripMenuItem]))\r\n" + + " # \r\n" + + " # fileToolStripMenuItem\r\n" + + " # \r\n" + + " self._fileToolStripMenuItem.Name = \"fileToolStripMenuItem\"\r\n" + + " self._fileToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._fileToolStripMenuItem.Text = \"&File\"\r\n" + + " self._fileToolStripMenuItem.DropDownItems.AddRange(System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._openToolStripMenuItem,\r\n" + + " self._exitToolStripMenuItem]))\r\n" + + " # \r\n" + + " # openToolStripMenuItem\r\n" + + " # \r\n" + + " self._openToolStripMenuItem.Name = \"openToolStripMenuItem\"\r\n" + + " self._openToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._openToolStripMenuItem.Text = \"&Open\"\r\n" + + " # \r\n" + + " # exitToolStripMenuItem\r\n" + + " # \r\n" + + " self._exitToolStripMenuItem.Name = \"exitToolStripMenuItem\"\r\n" + + " self._exitToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._exitToolStripMenuItem.Text = \"E&xit\"\r\n" + + " # \r\n" + + " # editToolStripMenuItem\r\n" + + " # \r\n" + + " self._editToolStripMenuItem.Name = \"editToolStripMenuItem\"\r\n" + + " self._editToolStripMenuItem.Size = System.Drawing.Size(39, 20)\r\n" + + " self._editToolStripMenuItem.Text = \"&Edit\"\r\n" + + " # \r\n" + + " # MainForm\r\n" + + " # \r\n" + + " self.ClientSize = System.Drawing.Size(200, 300)\r\n" + + " self.Name = \"MainForm\"\r\n" + + " self.Controls.Add(self._menuStrip1)\r\n" + + " self._menuStrip1.ResumeLayout(False)\r\n" + + " self._menuStrip1.PerformLayout()\r\n" + + " self.ResumeLayout(False)\r\n" + + " self.PerformLayout()\r\n"; + + Assert.AreEqual(expectedCode, generatedPythonCode); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs index eff6ec00b4..93cfd0797d 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateNestedPanelFormTestFixture.cs @@ -100,9 +100,9 @@ namespace PythonBinding.Tests.Designer " self.ClientSize = System.Drawing.Size(284, 264)\r\n" + " self.Name = \"MainForm\"\r\n" + " self.Controls.Add(self._panel1)\r\n" + - " self._panel1.ResumeLayout(false)\r\n" + + " self._panel1.ResumeLayout(False)\r\n" + " self._panel1.PerformLayout()\r\n" + - " self._panel2.ResumeLayout(false)\r\n" + + " self._panel2.ResumeLayout(False)\r\n" + " self._panel2.PerformLayout()\r\n" + " self.ResumeLayout(False)\r\n" + " self.PerformLayout()\r\n"; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs index f0e50c98d6..4aa2687e40 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GeneratePanelFormTestFixture.cs @@ -26,6 +26,7 @@ namespace PythonBinding.Tests.Designer { using (DesignSurface designSurface = new DesignSurface(typeof(Form))) { IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost)); + IEventBindingService eventBindingService = new MockEventBindingService(host); Form form = (Form)host.RootComponent; form.ClientSize = new Size(284, 264); @@ -43,6 +44,13 @@ namespace PythonBinding.Tests.Designer textBox.Size = new Size(110, 20); panel.Controls.Add(textBox); + // Add an event handler to the panel to check that this code is generated + // before the text box is initialized. + EventDescriptorCollection events = TypeDescriptor.GetEvents(panel); + EventDescriptor clickEvent = events.Find("Click", false); + PropertyDescriptor clickEventProperty = eventBindingService.GetEventProperty(clickEvent); + clickEventProperty.SetValue(panel, "Panel1Click"); + form.Controls.Add(panel); string indentString = " "; @@ -67,6 +75,7 @@ namespace PythonBinding.Tests.Designer " self._panel1.Size = System.Drawing.Size(100, 120)\r\n" + " self._panel1.TabIndex = 0\r\n" + " self._panel1.Controls.Add(self._textBox1)\r\n" + + " self._panel1.Click += self.Panel1Click\r\n" + " # \r\n" + " # textBox1\r\n" + " # \r\n" + @@ -80,7 +89,7 @@ namespace PythonBinding.Tests.Designer " self.ClientSize = System.Drawing.Size(284, 264)\r\n" + " self.Name = \"MainForm\"\r\n" + " self.Controls.Add(self._panel1)\r\n" + - " self._panel1.ResumeLayout(false)\r\n" + + " self._panel1.ResumeLayout(False)\r\n" + " self._panel1.PerformLayout()\r\n" + " self.ResumeLayout(False)\r\n" + " self.PerformLayout()\r\n"; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs new file mode 100644 index 0000000000..65c91beaa7 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GetComponentFromDesignerLoaderTestFixture.cs @@ -0,0 +1,79 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + /// + /// Tests the GetComponent method of the PythonDesignerLoader. + /// + [TestFixture] + public class GetComponentFromDesignerLoaderTestFixture + { + PythonDesignerLoader loader; + TextBox textBox; + MockDesignerLoaderHost host; + Label label; + + [SetUp] + public void Init() + { + host = new MockDesignerLoaderHost(); + loader = new PythonDesignerLoader(new MockDesignerGenerator()); + loader.BeginLoad(host); + + textBox = (TextBox)loader.CreateComponent(typeof(TextBox), "textBox1"); + label = (Label)loader.CreateComponent(typeof(Label), "label1"); + loader.Add(label, "label1"); + } + + [TearDown] + public void TearDown() + { + if (textBox != null) { + textBox.Dispose(); + } + } + + [Test] + public void LabelAddedToContainer() + { + Assert.AreEqual(label, host.Container.Components["label1"]); + } + + [Test] + public void TextBoxIsNotAddedToContainer() + { + Assert.IsNull(host.Container.Components["textBox1"]); + } + + [Test] + public void GetUnknownCreatedComponent() + { + Assert.IsNull(loader.GetComponent("unknown")); + } + + [Test] + public void GetTextBoxComponent() + { + Assert.IsNull(loader.GetComponent("textBox1")); + } + + [Test] + public void GetLabelComponent() + { + Assert.AreEqual(label, loader.GetComponent("label1")); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadControlEventHandlerTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadControlEventHandlerTestFixture.cs index da7fc4b643..e38e68560e 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadControlEventHandlerTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadControlEventHandlerTestFixture.cs @@ -49,7 +49,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public new void SetUpFixture() { - base.SetEventPropertyDescriptor(new MockPropertyDescriptor("abc", "Button2KeyDown", true)); + base.ComponentCreator.SetEventPropertyDescriptor(new MockPropertyDescriptor("abc", "Button2KeyDown", true)); base.SetUpFixture(); } @@ -67,7 +67,7 @@ namespace PythonBinding.Tests.Designer public MockPropertyDescriptor GetButtonKeyDownEventPropertyDescriptor() { EventDescriptor eventDescriptor = GetButtonKeyDownEventDescriptor(); - return base.GetEventProperty(eventDescriptor) as MockPropertyDescriptor; + return base.ComponentCreator.GetEventProperty(eventDescriptor) as MockPropertyDescriptor; } [Test] diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs index 7c01b50d7d..1d2abf5256 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs @@ -39,7 +39,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public new void SetUpFixture() { - base.SetEventPropertyDescriptor(new MockPropertyDescriptor("abc", "TestFormLoad", true)); + base.ComponentCreator.SetEventPropertyDescriptor(new MockPropertyDescriptor("abc", "TestFormLoad", true)); base.SetUpFixture(); } @@ -51,7 +51,7 @@ namespace PythonBinding.Tests.Designer public MockPropertyDescriptor GetLoadEventPropertyDescriptor() { EventDescriptor loadEventDescriptor = GetLoadEventDescriptor(); - return base.GetEventProperty(loadEventDescriptor) as MockPropertyDescriptor; + return base.ComponentCreator.GetEventProperty(loadEventDescriptor) as MockPropertyDescriptor; } [Test] diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs index d2f6ecdb48..46e3a90202 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs @@ -6,11 +6,6 @@ // using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.ComponentModel.Design.Serialization; using System.Drawing; using System.Reflection; using System.Windows.Forms; @@ -24,15 +19,9 @@ namespace PythonBinding.Tests.Designer /// /// Base class for all LoadFormTestFixture classes. /// - public class LoadFormTestFixtureBase : IComponentCreator - { - List createdComponents = new List(); - List createdInstances = new List(); - List addedComponents = new List(); - List typeNames = new List(); - PropertyDescriptor propertyDescriptor; - EventDescriptor eventDescriptor; - + public class LoadFormTestFixtureBase + { + MockComponentCreator componentCreator = new MockComponentCreator(); Form form; public LoadFormTestFixtureBase() @@ -42,7 +31,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(componentCreator); form = walker.CreateForm(PythonCode); } @@ -59,112 +48,12 @@ namespace PythonBinding.Tests.Designer get { return String.Empty; } } - public IComponent CreateComponent(Type componentClass, string name) - { - CreatedComponent c = new CreatedComponent(componentClass.FullName, name); - createdComponents.Add(c); - - object instance = componentClass.Assembly.CreateInstance(componentClass.FullName); - return (IComponent)instance; - } - - public void Add(IComponent component, string name) - { - AddedComponent addedComponent = new AddedComponent(component, name); - addedComponents.Add(addedComponent); - } - - public object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer) - { - CreatedInstance createdInstance = new CreatedInstance(type, arguments, name, addToContainer); - createdInstances.Add(createdInstance); - - object[] argumentsArray = new object[arguments.Count]; - arguments.CopyTo(argumentsArray, 0); - - object o = null; - DesignerSerializationManager designerSerializationManager = new DesignerSerializationManager(); - using (designerSerializationManager.CreateSession()) { - IDesignerSerializationManager manager = designerSerializationManager as IDesignerSerializationManager; - o = manager.CreateInstance(type, arguments, name, addToContainer); - } - createdInstance.Object = o; - return o; - } - - public Type GetType(string typeName) - { - typeNames.Add(typeName); - - // Lookup type in System.Windows.Forms assembly. - Type type = typeof(Form).Assembly.GetType(typeName); - if (type == null) { - // Lookup type System.Drawing assembly. - type = typeof(Size).Assembly.GetType(typeName); - } - return type; - } - - public PropertyDescriptor GetEventProperty(EventDescriptor e) - { - this.eventDescriptor = e; - return propertyDescriptor; - } - - public EventDescriptor EventDescriptorPassedToGetEventProperty { - get { return eventDescriptor; } - } - - /// - /// Sets the property descriptor to return from the GetEventProperty method. - /// - public void SetEventPropertyDescriptor(PropertyDescriptor propertyDescriptor) - { - this.propertyDescriptor = propertyDescriptor; + protected MockComponentCreator ComponentCreator { + get { return componentCreator; } } - + protected Form Form { get { return form; } - } - - protected List CreatedComponents { - get { return createdComponents; } - } - - protected List AddedComponents { - get { return addedComponents; } - } - - protected List CreatedInstances { - get { return createdInstances; } - } - - protected List TypeNames { - get { return typeNames; } - } - - protected string LastTypeNameResolved { - get { return TypeNames[TypeNames.Count - 1]; } - } - - protected CreatedInstance GetCreatedInstance(Type type) - { - foreach (CreatedInstance instance in createdInstances) { - if (instance.InstanceType == type) { - return instance; - } - } - return null; - } - - protected CreatedInstance GetCreatedInstance(string name) - { - foreach (CreatedInstance instance in createdInstances) { - if (instance.Name == name) { - return instance; - } - } - return null; - } + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadMenuStripFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadMenuStripFormTestFixture.cs new file mode 100644 index 0000000000..81d15cf121 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadMenuStripFormTestFixture.cs @@ -0,0 +1,130 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class LoadMenuStripTestFixture : LoadFormTestFixtureBase + { + public override string PythonCode { + get { + return "class MainForm(System.Windows.Forms.Form):\r\n" + + " def InitializeComponent(self):\r\n" + + " self._menuStrip1 = System.Windows.Forms.MenuStrip()\r\n" + + " self._fileToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._openToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._exitToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._editToolStripMenuItem = System.Windows.Forms.ToolStripMenuItem()\r\n" + + " self._menuStrip1.SuspendLayout()\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # menuStrip1\r\n" + + " # \r\n" + + " self._menuStrip1.Location = System.Drawing.Point(0, 0)\r\n" + + " self._menuStrip1.Name = \"menuStrip1\"\r\n" + + " self._menuStrip1.Size = System.Drawing.Size(200, 24)\r\n" + + " self._menuStrip1.TabIndex = 0\r\n" + + " self._menuStrip1.Text = \"menuStrip1\"\r\n" + + " self._menuStrip1.Items.AddRange(System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._fileToolStripMenuItem,\r\n" + + " self._editToolStripMenuItem]))\r\n" + + " # \r\n" + + " # fileToolStripMenuItem\r\n" + + " # \r\n" + + " self._fileToolStripMenuItem.Name = \"fileToolStripMenuItem\"\r\n" + + " self._fileToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._fileToolStripMenuItem.Text = \"&File\"\r\n" + + " self._fileToolStripMenuItem.DropDownItems.AddRange(System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._openToolStripMenuItem,\r\n" + + " self._exitToolStripMenuItem]))\r\n" + + " # \r\n" + + " # openToolStripMenuItem\r\n" + + " # \r\n" + + " self._openToolStripMenuItem.Name = \"openToolStripMenuItem\"\r\n" + + " self._openToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._openToolStripMenuItem.Text = \"&Open\"\r\n" + + " # \r\n" + + " # exitToolStripMenuItem\r\n" + + " # \r\n" + + " self._exitToolStripMenuItem.Name = \"exitToolStripMenuItem\"\r\n" + + " self._exitToolStripMenuItem.Size = System.Drawing.Size(37, 20)\r\n" + + " self._exitToolStripMenuItem.Text = \"E&xit\"\r\n" + + " # \r\n" + + " # editToolStripMenuItem\r\n" + + " # \r\n" + + " self._editToolStripMenuItem.Name = \"editToolStripMenuItem\"\r\n" + + " self._editToolStripMenuItem.Size = System.Drawing.Size(39, 20)\r\n" + + " self._editToolStripMenuItem.Text = \"&Edit\"\r\n" + + " # \r\n" + + " # MainForm\r\n" + + " # \r\n" + + " self.ClientSize = System.Drawing.Size(200, 300)\r\n" + + " self.Name = \"MainForm\"\r\n" + + " self.Controls.Add(self._menuStrip1)\r\n" + + " self._menuStrip1.ResumeLayout(False)\r\n" + + " self._menuStrip1.PerformLayout()\r\n" + + " self.ResumeLayout(False)\r\n" + + " self.PerformLayout()\r\n"; + } + } + + public MenuStrip MenuStrip { + get { return Form.Controls[0] as MenuStrip; } + } + + public ToolStripMenuItem FileMenuItem { + get { return MenuStrip.Items[0] as ToolStripMenuItem; } + } + + [Test] + public void MenuStripAddedToForm() + { + Assert.IsNotNull(MenuStrip); + } + + [Test] + public void MenuStripHasTwoItems() + { + Assert.AreEqual(2, MenuStrip.Items.Count); + } + + [Test] + public void MenuStripFirstItemIsFileMenuItem() + { + Assert.AreEqual("fileToolStripMenuItem", FileMenuItem.Name); + } + + [Test] + public void FileMenuItemText() + { + Assert.AreEqual("&File", FileMenuItem.Text); + } + + [Test] + public void MenuStripSecondItemIsEditMenuItem() + { + Assert.AreEqual("editToolStripMenuItem", MenuStrip.Items[1].Name); + } + + [Test] + public void FileMenuItemHasDropDownItems() + { + Assert.AreEqual(2, FileMenuItem.DropDownItems.Count); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs index 8f177d9774..4869067357 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs @@ -35,7 +35,7 @@ namespace PythonBinding.Tests.Designer } public CreatedComponent FormComponent { - get { return CreatedComponents[0]; } + get { return ComponentCreator.CreatedComponents[0]; } } [Test] @@ -53,7 +53,7 @@ namespace PythonBinding.Tests.Designer [Test] public void OneComponentCreated() { - Assert.AreEqual(1, CreatedComponents.Count); + Assert.AreEqual(1, ComponentCreator.CreatedComponents.Count); } [Test] @@ -82,13 +82,13 @@ namespace PythonBinding.Tests.Designer [Test] public void TypeNameLookedUp() { - Assert.AreEqual("System.Drawing.Size", TypeNames[0]); + Assert.AreEqual("System.Drawing.Size", ComponentCreator.TypeNames[0]); } [Test] public void OneObjectCreated() { - Assert.AreEqual(1, CreatedInstances.Count); + Assert.AreEqual(1, ComponentCreator.CreatedInstances.Count); } [Test] @@ -101,7 +101,7 @@ namespace PythonBinding.Tests.Designer args.Add(height); CreatedInstance expectedInstance = new CreatedInstance(typeof(Size), args, null, false); - Assert.AreEqual(expectedInstance, CreatedInstances[0]); + Assert.AreEqual(expectedInstance, ComponentCreator.CreatedInstances[0]); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxOnPanelTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxOnPanelTestFixture.cs index c92cc7542c..0ffbae1011 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxOnPanelTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxOnPanelTestFixture.cs @@ -69,34 +69,6 @@ namespace PythonBinding.Tests.Designer public void TextBoxAddedToPanel() { Assert.IsNotNull(TextBox); - } - - [Test] - public void ParentControlNameAddingChildControls() - { - string code = "self._panel1.Controls.Add"; - Assert.AreEqual("panel1", PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); - } - - [Test] - public void EmptyControlNameAddingChildControls() - { - string code = "self.Controls.Add"; - Assert.AreEqual(String.Empty, PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); - } - - [Test] - public void CaseInsensitiveCheckForControlsAddStatement() - { - string code = "self._panel1.controls.add"; - Assert.AreEqual("panel1", PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); - } - - [Test] - public void CodeDoesNotIncludeControlsAddStatement() - { - string code = "self._panel1.SuspendLayout"; - Assert.IsNull(PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); - } + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs index af504a21ee..2f2a99a5eb 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs @@ -49,17 +49,17 @@ namespace PythonBinding.Tests.Designer [Test] public void AddedComponentsContainsTextBox() { - CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); + CreatedInstance instance = ComponentCreator.GetCreatedInstance(typeof(TextBox)); AddedComponent component = new AddedComponent(instance.Object as IComponent, "textBox1"); - Assert.Contains(component, AddedComponents); + Assert.Contains(component, ComponentCreator.AddedComponents); } [Test] public void TextBoxInstanceCreated() { CreatedInstance instance = new CreatedInstance(typeof(TextBox), new List(), null, false); - Assert.Contains(instance, CreatedInstances); + Assert.Contains(instance, ComponentCreator.CreatedInstances); } [Test] @@ -71,7 +71,7 @@ namespace PythonBinding.Tests.Designer [Test] public void TextBoxObjectMatchesObjectAddedToComponentCreator() { - CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); + CreatedInstance instance = ComponentCreator.GetCreatedInstance(typeof(TextBox)); Assert.AreSame(TextBox, instance.Object as TextBox); } @@ -90,7 +90,7 @@ namespace PythonBinding.Tests.Designer [Test] public void CreatedInstancesDoesNotIncludeLocation() { - Assert.IsNull(GetCreatedInstance("Location")); + Assert.IsNull(ComponentCreator.GetCreatedInstance("Location")); } [Test] diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs index 8164904cd7..e63c5a32bb 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs @@ -74,11 +74,16 @@ namespace PythonBinding.Tests.Designer throw new NotImplementedException(); } - public void Add(System.ComponentModel.IComponent component, string name) + public void Add(IComponent component, string name) { throw new NotImplementedException(); } + public IComponent GetComponent(string name) + { + return null; + } + public object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer) { throw new NotImplementedException(); diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs index 77c8a7a4cc..c48c3fc18d 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs @@ -18,14 +18,16 @@ using PythonBinding.Tests.Utils; namespace PythonBinding.Tests.Designer { [TestFixture] - public class PythonCodeDeserializerTests : LoadFormTestFixtureBase + public class PythonCodeDeserializerTests { PythonCodeDeserializer deserializer; + MockComponentCreator componentCreator; [TestFixtureSetUp] - public new void SetUpFixture() + public void SetUpFixture() { - deserializer = new PythonCodeDeserializer(this); + componentCreator = new MockComponentCreator(); + deserializer = new PythonCodeDeserializer(componentCreator); } [Test] @@ -40,31 +42,28 @@ namespace PythonBinding.Tests.Designer public void UnknownTypeName() { string pythonCode = "self.Cursors = System.Windows.Forms.UnknownType.AppStarting"; - Assert.IsNull(Deserialize(pythonCode)); + Assert.IsNull(DeserializeRhsAssignment(pythonCode)); } [Test] public void UnknownPropertyName() { string pythonCode = "self.Cursors = System.Windows.Forms.Cursors.UnknownCursorsProperty"; - Assert.IsNull(Deserialize(pythonCode)); + Assert.IsNull(DeserializeRhsAssignment(pythonCode)); } [Test] public void UnknownTypeNameInCallExpression() { string pythonCode = "self.Cursors = System.Windows.Forms.UnknownType.CreateDefaultCursor()"; - Assert.IsNull(Deserialize(pythonCode)); + Assert.IsNull(DeserializeRhsAssignment(pythonCode)); } [Test] public void EnumReturnedInArgumentsPassedToConstructor() { string pythonCode = "self.Font = System.Drawing.Font(\"Times New Roman\", System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point)"; - PythonParser parser = new PythonParser(); - PythonAst ast = parser.CreateAst(@"snippet.py", pythonCode); - SuiteStatement suiteStatement = (SuiteStatement)ast.Body; - AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; + AssignmentStatement assignment = PythonParserHelper.GetAssignmentStatement(pythonCode); List expectedArgs = new List(); expectedArgs.Add("Times New Roman"); @@ -82,7 +81,7 @@ namespace PythonBinding.Tests.Designer string pythonCode = "self.textBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom"; AnchorStyles expectedStyles = AnchorStyles.Top | AnchorStyles.Bottom; - Assert.AreEqual(expectedStyles, Deserialize(pythonCode)); + Assert.AreEqual(expectedStyles, DeserializeRhsAssignment(pythonCode)); } [Test] @@ -91,19 +90,15 @@ namespace PythonBinding.Tests.Designer string pythonCode = "self.textBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left"; AnchorStyles expectedStyles = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; - Assert.AreEqual(expectedStyles, Deserialize(pythonCode)); + Assert.AreEqual(expectedStyles, DeserializeRhsAssignment(pythonCode)); } /// /// Deserializes the right hand side of the assignment. /// - object Deserialize(string pythonCode) + object DeserializeRhsAssignment(string pythonCode) { - PythonParser parser = new PythonParser(); - PythonAst ast = parser.CreateAst(@"snippet.py", pythonCode); - SuiteStatement suiteStatement = (SuiteStatement)ast.Body; - AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; - return deserializer.Deserialize(assignment.Right); + return deserializer.Deserialize(PythonParserHelper.GetAssignmentStatement(pythonCode).Right); } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs new file mode 100644 index 0000000000..7fcbefc179 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs @@ -0,0 +1,175 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class PythonControlFieldExpressionTests + { + [Test] + public void HasPrefixTest() + { + Assert.AreEqual("a", PythonControlFieldExpression.GetPrefix("a.b")); + } + + [Test] + public void NoDotHasPrefixTest() + { + Assert.AreEqual("a", PythonControlFieldExpression.GetPrefix("a")); + } + + [Test] + public void ParentControlNameAddingChildControls() + { + string code = "self._panel1.Controls.Add"; + Assert.AreEqual("panel1", PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); + } + + [Test] + public void EmptyControlNameAddingChildControls() + { + string code = "self.Controls.Add"; + Assert.AreEqual(String.Empty, PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); + } + + [Test] + public void CaseInsensitiveCheckForControlsAddStatement() + { + string code = "self._panel1.controls.add"; + Assert.AreEqual("panel1", PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); + } + + [Test] + public void CodeDoesNotIncludeControlsAddStatement() + { + string code = "self._panel1.SuspendLayout"; + Assert.IsNull(PythonControlFieldExpression.GetParentControlNameAddingChildControls(code)); + } + + [Test] + public void GetVariableName() + { + Assert.AreEqual("abc", PythonControlFieldExpression.GetVariableName("_abc")); + } + + [Test] + public void VariableNameHasOnlyUnderscore() + { + Assert.AreEqual(String.Empty, PythonControlFieldExpression.GetVariableName("_")); + } + + [Test] + public void VariableNameIsEmpty() + { + Assert.AreEqual(String.Empty, PythonControlFieldExpression.GetVariableName(String.Empty)); + } + + [Test] + public void FullMemberExpression() + { + CallExpression call = PythonParserHelper.GetCallExpression("self._a.b.Add()"); + Assert.AreEqual("self._a.b.Add", PythonControlFieldExpression.GetMemberName(call.Target as MemberExpression)); + } + + [Test] + public void NullMemberExpression() + { + Assert.AreEqual(String.Empty, PythonControlFieldExpression.GetMemberName(null)); + } + + [Test] + public void PythonControlFieldExpressionEquals() + { + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._textBox1.Name = \"abc\""); + PythonControlFieldExpression field1 = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + statement = PythonParserHelper.GetAssignmentStatement("self._textBox1.Name = \"def\""); + PythonControlFieldExpression field2 = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + + Assert.AreEqual(field1, field2); + } + + [Test] + public void NullPassedToPythonControlFieldExpressionEquals() + { + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._textBox1.Name = \"abc\""); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); + Assert.IsFalse(field.Equals(null)); + } + + [Test] + public void GetControlNameBeingAdded() + { + string code = "self.Controls.Add(self._menuItem1)"; + CallExpression expression = PythonParserHelper.GetCallExpression(code); + Assert.AreEqual("menuItem1", PythonControlFieldExpression.GetControlNameBeingAdded(expression)); + } + + [Test] + public void MethodName() + { + string code = "self.menuItem.Items.Add(self._fileMenuItem)"; + CallExpression expression = PythonParserHelper.GetCallExpression(code); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(expression); + AssertAreEqual(field, "menuItem", "Items", "Add", "self.menuItem.Items"); + } + + [Test] + public void GetMemberNames() + { + string[] expected = new string[] { "a", "b" }; + string code = "a.b = 0"; + AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement(code); + Assert.AreEqual(expected, PythonControlFieldExpression.GetMemberNames(statement.Left[0] as MemberExpression)); + } + + [Test] + public void GetObjectInMethodCall() + { + string pythonCode = "self._menuStrip1.Items.AddRange(System.Array[System.Windows.Forms.ToolStripItem](\r\n" + + " [self._fileToolStripMenuItem,\r\n" + + " self._editToolStripMenuItem]))"; + + CallExpression callExpression = PythonParserHelper.GetCallExpression(pythonCode); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(callExpression); + + using (MenuStrip menuStrip = new MenuStrip()) { + MockComponentCreator creator = new MockComponentCreator(); + creator.Add(menuStrip, "menuStrip1"); + Assert.AreEqual(menuStrip.Items, field.GetMember(creator)); + } + } + + [Test] + public void GetObjectForUnknownComponent() + { + string pythonCode = "self._menuStrip1.SuspendLayout()"; + + CallExpression callExpression = PythonParserHelper.GetCallExpression(pythonCode); + PythonControlFieldExpression field = PythonControlFieldExpression.Create(callExpression); + + using (MenuStrip menuStrip = new MenuStrip()) { + MockComponentCreator creator = new MockComponentCreator(); + creator.Add(menuStrip, "unknown"); + Assert.IsNull(field.GetMember(creator)); + } + } + + void AssertAreEqual(PythonControlFieldExpression field, string variableName, string memberName, string methodName, string fullMemberName) + { + string expected = "Variable: " + variableName + " Member: " + memberName + " Method: " + methodName + " FullMemberName: " + fullMemberName; + string actual = "Variable: " + field.VariableName + " Member: " + field.MemberName + " Method: " + field.MethodName + " FullMemberName: " + field.FullMemberName; + Assert.AreEqual(expected, actual); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs index c301bce54e..ff7e126862 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs @@ -67,7 +67,7 @@ namespace PythonBinding.Tests.Designer designedForm = new Form(); designedForm.Name = "NewMainForm"; - mockDesignerLoaderHost.RootComponent = designedForm; + mockDesignerLoaderHost.RootComponent = designedForm; loader.CallPerformFlush(); } @@ -89,11 +89,11 @@ namespace PythonBinding.Tests.Designer public void CreateComponent() { List expectedCreatedComponents = new List(); - expectedCreatedComponents.Add(new CreatedComponent(typeof(Form).FullName, "MainForm")); + expectedCreatedComponents.Add(new CreatedComponent(typeof(Form).FullName, "MainForm", null)); Assert.AreEqual(expectedCreatedComponents, mockDesignerLoaderHost.CreatedComponents); } - + [Test] public void ComponentSerializationServiceCreated() { diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs index a419f36eaa..c84a994eea 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs @@ -48,10 +48,10 @@ namespace PythonBinding.Tests.Designer [Test] public void AddedComponentsContainsTextBox() { - CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); + CreatedInstance instance = ComponentCreator.GetCreatedInstance(typeof(TextBox)); AddedComponent c = new AddedComponent(instance.Object as IComponent, "textBox1"); - Assert.Contains(c, AddedComponents); + Assert.Contains(c, ComponentCreator.AddedComponents); } [Test] diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs index 83521d3566..89fd7f5ce4 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs @@ -24,7 +24,7 @@ namespace PythonBinding.Tests.Designer /// form. /// [TestFixture] - public class UnknownTypeTestFixture : LoadFormTestFixtureBase + public class UnknownTypeTestFixture { string pythonCode = "from System.Windows.Forms import Form\r\n" + "\r\n" + @@ -35,17 +35,11 @@ namespace PythonBinding.Tests.Designer " def InitializeComponent(self):\r\n" + " self.ClientSize = Unknown.Type(10)\r\n"; - [TestFixtureSetUp] - public new void SetUpFixture() - { - // Do not call base class SetUpFixture. - } - [Test] [ExpectedException(typeof(PythonFormWalkerException))] public void PythonFormWalkerExceptionThrown() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(new MockComponentCreator()); walker.CreateForm(pythonCode); Assert.Fail("Exception should have been thrown before this."); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index c45532050f..f7010a6c70 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -148,6 +148,8 @@ + + @@ -162,6 +164,7 @@ + @@ -169,6 +172,7 @@ + @@ -183,6 +187,7 @@ + @@ -191,6 +196,7 @@ + @@ -253,6 +259,7 @@ + @@ -281,6 +288,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/CreatedComponent.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/CreatedComponent.cs index fc0cd2dde5..77fd41a59c 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/CreatedComponent.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/CreatedComponent.cs @@ -6,6 +6,7 @@ // using System; +using System.ComponentModel; namespace PythonBinding.Tests.Utils { @@ -14,14 +15,16 @@ namespace PythonBinding.Tests.Utils /// public class CreatedComponent { - public CreatedComponent(string typeName, string name) + public CreatedComponent(string typeName, string name, IComponent component) { TypeName = typeName; Name = name; + Component = component; } public string TypeName { get; set; } public string Name { get; set; } + public IComponent Component { get; set; } public override bool Equals(object obj) { diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs new file mode 100644 index 0000000000..2a5b77dae8 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockComponentCreator.cs @@ -0,0 +1,152 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; + +namespace PythonBinding.Tests.Utils +{ + public class MockComponentCreator : IComponentCreator + { + List createdComponents = new List(); + List createdInstances = new List(); + List addedComponents = new List(); + List typeNames = new List(); + PropertyDescriptor propertyDescriptor; + EventDescriptor eventDescriptor; + + public MockComponentCreator() + { + } + + public IComponent CreateComponent(Type componentClass, string name) + { + object instance = componentClass.Assembly.CreateInstance(componentClass.FullName); + + CreatedComponent c = new CreatedComponent(componentClass.FullName, name, (IComponent)instance); + createdComponents.Add(c); + + return (IComponent)instance; + } + + public void Add(IComponent component, string name) + { + AddedComponent addedComponent = new AddedComponent(component, name); + addedComponents.Add(addedComponent); + } + + public IComponent GetComponent(string name) + { + foreach (AddedComponent c in addedComponents) { + if (c.Name == name) { + return c.Component; + } + } + return null; + } + + public object CreateInstance(Type type, ICollection arguments, string name, bool addToContainer) + { + CreatedInstance createdInstance = new CreatedInstance(type, arguments, name, addToContainer); + createdInstances.Add(createdInstance); + + object[] argumentsArray = new object[arguments.Count]; + arguments.CopyTo(argumentsArray, 0); + + object o = null; + DesignerSerializationManager designerSerializationManager = new DesignerSerializationManager(); + using (designerSerializationManager.CreateSession()) { + IDesignerSerializationManager manager = designerSerializationManager as IDesignerSerializationManager; + o = manager.CreateInstance(type, arguments, name, addToContainer); + } + createdInstance.Object = o; + return o; + } + + public Type GetType(string typeName) + { + typeNames.Add(typeName); + + // Lookup type in System.Windows.Forms assembly. + Type type = typeof(Form).Assembly.GetType(typeName); + if (type == null) { + // Lookup type System.Drawing assembly. + type = typeof(Size).Assembly.GetType(typeName); + } + if (type == null) { + type = typeof(String).Assembly.GetType(typeName); + } + + return type; + } + + public PropertyDescriptor GetEventProperty(EventDescriptor e) + { + this.eventDescriptor = e; + return propertyDescriptor; + } + + public EventDescriptor EventDescriptorPassedToGetEventProperty { + get { return eventDescriptor; } + } + + /// + /// Sets the property descriptor to return from the GetEventProperty method. + /// + public void SetEventPropertyDescriptor(PropertyDescriptor propertyDescriptor) + { + this.propertyDescriptor = propertyDescriptor; + } + + public List CreatedComponents { + get { return createdComponents; } + } + + public List AddedComponents { + get { return addedComponents; } + } + + public List CreatedInstances { + get { return createdInstances; } + } + + public List TypeNames { + get { return typeNames; } + } + + public string LastTypeNameResolved { + get { return TypeNames[TypeNames.Count - 1]; } + } + + public CreatedInstance GetCreatedInstance(Type type) + { + foreach (CreatedInstance instance in createdInstances) { + if (instance.InstanceType == type) { + return instance; + } + } + return null; + } + + public CreatedInstance GetCreatedInstance(string name) + { + foreach (CreatedInstance instance in createdInstances) { + if (instance.Name == name) { + return instance; + } + } + return null; + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs index fedf47f70b..75ccd73bfc 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs @@ -23,7 +23,8 @@ namespace PythonBinding.Tests.Utils List createdComponents = new List(); IComponent rootComponent; MockTypeResolutionService typeResolutionService = new MockTypeResolutionService(); - + Container container = new Container(); + public MockDesignerLoaderHost() { AddService(typeof(IServiceContainer), serviceContainer); @@ -62,9 +63,7 @@ namespace PythonBinding.Tests.Utils } public IContainer Container { - get { - throw new NotImplementedException(); - } + get { return container; } } public IComponent RootComponent { @@ -104,11 +103,11 @@ namespace PythonBinding.Tests.Utils public IComponent CreateComponent(Type componentClass, string name) { - createdComponents.Add(new CreatedComponent(componentClass.FullName, name)); IComponent component = componentClass.Assembly.CreateInstance(componentClass.FullName) as IComponent; if (rootComponent == null) { rootComponent = component; } + createdComponents.Add(new CreatedComponent(componentClass.FullName, name, component)); return component; } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonParserHelper.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonParserHelper.cs new file mode 100644 index 0000000000..c0cfc229a9 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/PythonParserHelper.cs @@ -0,0 +1,44 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; + +namespace PythonBinding.Tests.Utils +{ + /// + /// Description of PythonParserHelper. + /// + public class PythonParserHelper + { + /// + /// Parses the code and returns the first statement as an assignment statement. + /// + public static AssignmentStatement GetAssignmentStatement(string code) + { + return GetFirstStatement(code) as AssignmentStatement; + } + + /// + /// Parses the code and returns the first statement's expression as call expression. + /// + public static CallExpression GetCallExpression(string code) + { + ExpressionStatement expressionStatement = GetFirstStatement(code) as ExpressionStatement; + return expressionStatement.Expression as CallExpression; + } + + static Statement GetFirstStatement(string code) + { + PythonParser parser = new PythonParser(); + PythonAst ast = parser.CreateAst(@"snippet.py", code); + SuiteStatement suiteStatement = (SuiteStatement)ast.Body; + return suiteStatement.Statements[0]; + } + } +}