/// <summary> /// Convenience method to create an instance of <see cref="TestMethod"/> initialized with the provided /// <paramref name="methodToTest"/> and then execute the template to produce the string representation of the /// unit test method. /// </summary> /// /// <param name="methodToTest"> /// The <see cref="ParametrizedNode"/> representing the method or constructor for which tests are to be written. /// </param> /// /// <returns> /// The string representation of the source code of the generated method to test /// <paramref name="methodToTest"/>. /// </returns> public static string Generate(ParametrizedNode methodToTest) { var testMethodGenerator = new TestMethod(methodToTest, (TypeDeclaration)methodToTest.Parent); var testMethodCode = testMethodGenerator.TransformText(); return(testMethodCode); }
private List <Expression> ReplaceNullArguments(TypeDeclaration typeDeclaration, List <Expression> ArgExpressions, INode node) { int index = 0; List <Expression> args = new List <Expression>(); foreach (Expression argument in ArgExpressions) { bool flag = true; if (argument is PrimitiveExpression && ((PrimitiveExpression)argument).Value == null) { ParametrizedNode member = GetAssociateMember(typeDeclaration, node, ArgExpressions); if (member != null) { TypeReference typeReference = ((ParameterDeclarationExpression)member.Parameters[index]).TypeReference; if (typeReference.RankSpecifier == null || typeReference.RankSpecifier.Length == 0) { string fullTypeName = GetFullName(typeReference); if (types.Contains(fullTypeName)) { Expression minValue = (Expression)values[fullTypeName]; args.Add(minValue); flag = false; } } } } if (flag) { args.Add(argument); } index++; } return(args); }
protected static Statement CreateCaller(ParametrizedNode parent, MethodDeclaration method, VariableDeclaration returnVariable) { Statement caller; InvocationExpression expr = new InvocationExpression(new IdentifierExpression(method.Name), CreateArgumentExpressions(method.Parameters)); if (method.TypeReference.Type != "System.Void") { if (parent is MethodDeclaration) { if (method.TypeReference == (parent as MethodDeclaration).TypeReference) { caller = new ReturnStatement(expr); } else { returnVariable.Initializer = expr; caller = new LocalVariableDeclaration(returnVariable); } } else { returnVariable.Initializer = expr; caller = new LocalVariableDeclaration(returnVariable); } } else { caller = new ExpressionStatement(expr); } return(caller); }
internal static string Generate(ParametrizedNode methodToCall, TypeDeclaration parentType, string returnVariableName) { var template = new MethodCallStub(methodToCall, parentType, returnVariableName); var text = template.TransformText(); return(text); }
/// <summary> /// Adds a <see cref="ParameterDeclarationExpression"/> to <see cref="ParametrizedNode.Parameters"/> in a single /// call, for convenience. /// </summary> /// /// <param name="node"> /// The method or constructor to add the parameter to. /// </param> /// /// <param name="parameterType"> /// The <see cref="TypeReference"/> of the parameter to add. /// </param> /// /// <param name="parameterName"> /// The name of the parameter to add. /// </param> /// /// <returns> /// The <see cref="ParameterDeclarationExpression"/> instance that was created and added to /// <paramref name="node"/>. /// </returns> public static ParameterDeclarationExpression AddParameter(this ParametrizedNode node, TypeReference parameterType, string parameterName) { var parameter = new ParameterDeclarationExpression(parameterType, parameterName); node.Parameters.Add(parameter); return(parameter); }
/// <summary> /// Initializes a new instance of the <see cref="MethodCallStub"/> parameterized template with the specified /// <paramref name="methodToCall"/> and <paramref name="parentType"/>. /// </summary> /// /// <param name="methodToCall"> /// The <see cref="ParametrizedNode"/> representing the method or constructor for which a call stub is to be /// written. /// </param> /// /// <param name="parentType"> /// The <see cref="TypeDeclaration"/> that contains <paramref name="methodToCall"/>. /// </param> /// /// <param name="variableName"> /// The name of the variable to which the result of the method will be assigned, if appropriate. /// </param> public MethodCallStub(ParametrizedNode methodToCall, TypeDeclaration parentType, string variableName) : base(methodToCall, parentType) { VariableName = variableName ?? "result"; InstanceOrClass = NeedsInstance ? DetermineInstanceVariableName(parentType) : parentType.Name; Invocation = methodToCall is MethodDeclaration ? InstanceOrClass + "." + methodToCall.Name : "new " + parentType.Name; }
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) { if ((propertyDeclaration.BodyStart < new Location(startColumn + 1, startLine + 1)) && (propertyDeclaration.BodyEnd > new Location(endColumn + 1, endLine + 1))) { this.member = propertyDeclaration; } return(base.VisitPropertyDeclaration(propertyDeclaration, data)); }
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data) { if ((methodDeclaration.Body.StartLocation < new Location(startColumn + 1, startLine + 1)) && (methodDeclaration.Body.EndLocation > new Location(endColumn + 1, endLine + 1))) { this.member = methodDeclaration; } return(base.VisitMethodDeclaration(methodDeclaration, data)); }
// TODO: We should add support for test class source code coming from a TextReader/IEnumerable<string> // TODO: The test method generation should be aware of the destination type so that it can know how to correctly // reference the class under test (i.e. prefix with Parent or include a namespace reference) /// <summary> /// Generates a test for the provided <paramref name="methodToTest"/> and inserts it near the end of the /// <paramref name="testClassSourceCode"/>. /// </summary> /// /// <param name="testClassSourceCode"> /// The source code to the compilation unit containing the class for testing the class under test. /// </param> /// /// <param name="methodToTest"> /// A method of the class under test. /// </param> /// /// <returns> /// The source code to the compilation unit with the new test method stub added to it. /// </returns> public static string InsertTestFor(this string testClassSourceCode, ParametrizedNode methodToTest) { string sourceCodeToInsert = methodToTest.GenerateTest(); var cu = Parser.ParseCompilationUnit(testClassSourceCode); int lineNumber = cu.DetermineMethodInsertionLine(); string result = testClassSourceCode.InsertLines(sourceCodeToInsert, lineNumber); return(result); }
public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data) { if ((constructorDeclaration.Body.StartLocation < new Location(startColumn + 1, startLine + 1)) && (constructorDeclaration.Body.EndLocation > new Location(endColumn + 1, endLine + 1))) { this.member = constructorDeclaration; } return(base.VisitConstructorDeclaration(constructorDeclaration, data)); }
public override object VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data) { if ((operatorDeclaration.Body.StartLocation < new Location(startColumn + 1, startLine + 1)) && (operatorDeclaration.Body.EndLocation > new Location(endColumn + 1, endLine + 1))) { this.member = operatorDeclaration; } return(base.VisitOperatorDeclaration(operatorDeclaration, data)); }
public static void RenameConflicting(ParametrizedNode method) { // variable name => case sensitive variable name // value is null if there are multiple casings for the variable -> the variable is conflicting Dictionary <string, string> caseInsensitive = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); LookupTableVisitor ltv = new LookupTableVisitor(SupportedLanguage.CSharp); method.AcceptVisitor(ltv, null); // add method name to caseInsensitive AddVariableToDict(caseInsensitive, method.Name, true); // add method parameters to caseInsensitive foreach (ParameterDeclarationExpression pde in method.Parameters) { AddVariableToDict(caseInsensitive, pde.ParameterName, true); } // add local variables to caseInsensitive foreach (KeyValuePair <string, List <LocalLookupVariable> > var in ltv.Variables) { AddVariableToDict(caseInsensitive, var.Key, true); } // add used identifiers to caseInsensitive FindIdentifiersVisitor fvv = new FindIdentifiersVisitor(); method.AcceptVisitor(fvv, null); foreach (KeyValuePair <string, string> pair in fvv.usedIdentifiers) { AddVariableToDict(caseInsensitive, pair.Key, false); } int index = 0; foreach (ParameterDeclarationExpression pde in method.Parameters) { if (caseInsensitive[pde.ParameterName] == null) { RenameVariable(method, pde.ParameterName, ref index); } } foreach (KeyValuePair <string, List <LocalLookupVariable> > var in ltv.Variables) { if (caseInsensitive[var.Key] == null) { RenameVariable(method, var.Key, ref index); } } }
/// <summary> /// Initializes a new instance of the <see cref="AbstractMethodTemplate"/> parameterized template with the /// specified <paramref name="node"/> and <paramref name="parentType"/>. /// </summary> /// /// <param name="node"> /// The <see cref="ParametrizedNode"/> representing the node for which templates are to be written. /// </param> /// /// <param name="parentType"> /// The <see cref="TypeDeclaration"/> that contains <paramref name="node"/>. /// </param> protected AbstractMethodTemplate(ParametrizedNode node, TypeDeclaration parentType) { _method = node; _parentType = parentType; NeedsInstance = !_method.Modifier.HasFlag(Modifiers.Static); ReturnValue = node.GetTypeReference(parentType); HasReturnValue = !( ReturnValue.IsNull || "System.Void" == ReturnValue.Type || "void" == ReturnValue.Type ); }
private bool IsContainIdentifier(ParametrizedNode parametrizedNode, IdentifierExpression identifierExpression) { if (parametrizedNode != null) { foreach (ParameterDeclarationExpression pm in parametrizedNode.Parameters) { if (pm.ParameterName == identifierExpression.Identifier) { return(true); } } } return(false); }
// protected Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, TextLocation location) // { // return GetParentMember(textEditor, location.Line, location.Column); // } // protected Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, int line, int column) // { // Dom.ParseInformation parseInfo = ParserService.GetParseInformation(textEditor.FileName); // if (parseInfo != null) { // Dom.IClass c = parseInfo.MostRecentCompilationUnit.GetInnermostClass(line, column); // if (c != null) { // foreach (Dom.IMember member in c.Properties) { // if (member.BodyRegion.IsInside(line, column)) { // return member; // } // } // foreach (Dom.IMember member in c.Methods) { // if (member.BodyRegion.IsInside(line, column)) { // return member; // } // } // } // } // // return null; // } // protected ParametrizedNode GetParentMember(int startLine, int startColumn, int endLine, int endColumn) // { // using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(this.currentDocument.TextContent))) { // parser.Parse(); // // if (parser.Errors.Count > 0) { // MessageService.ShowError(null, parser.Errors.ErrorOutput); // return null; // } // // FindMemberVisitor fmv = new FindMemberVisitor(startColumn, startLine, endColumn, endLine); // // parser.CompilationUnit.AcceptVisitor(fmv, null); // // return fmv.Member; // } // } protected static bool HasOccurrencesAfter(StringComparer nameComparer, ParametrizedNode member, Location location, string name, Location start, Location end) { FindReferenceVisitor frv = new FindReferenceVisitor(nameComparer, name, start, end); member.AcceptVisitor(frv, null); foreach (IdentifierExpression identifier in frv.Identifiers) { if (identifier.StartLocation > location) { return(true); } } return(false); }
// TODO: the results of this method could be cached // TODO: visibility should probably be abstracted out, since it could depend on actual set-up or an option internal static ParametrizedNode DetermineConstructor(TypeDeclaration source) { // TODO: TypeDeclaration could have the Static modifier, at which point there are no constructors possible! // TODO: The TypeDeclaration could be _partial_, at which point the search would be inconclusive! // We would then have to either scan the rest of the project and/or the resulting/compiled assembly ParametrizedNode simplestConstructor = null; source.Children.Filter(node => node is ConstructorDeclaration).ForElse( node => { var constructor = (ConstructorDeclaration)node; if (constructor.Modifier.HasFlag(Modifiers.Public) || constructor.Modifier.HasFlag(Modifiers.Internal)) { if (null == simplestConstructor) { simplestConstructor = constructor; } else { // TODO: Improve the meaning of "better", because in this case, there is "another kind of // better". For example, maybe we should avoid recursive constructors, deprecated ones, etc. // TODO: consider the types of the parameters, as well if (constructor.Parameters.Count < simplestConstructor.Parameters.Count) { simplestConstructor = constructor; } } } }, () => { // there were no constructor declarations; default constructor should be available simplestConstructor = new ConstructorDeclaration(source.Name, Modifiers.Public, EmptyParameterList, EmptyAttributeList); }); if (null == simplestConstructor) { // there was at least one constructor declaration, but none were visible // TODO: scan for factory methods: // visible static methods with a return type equal to TypeDeclaration } return(simplestConstructor); }
void CreateInterfaceImplementations(IMember currentMember, ParametrizedNode memberDecl, List <InterfaceImplementation> interfaceImplementations) { if (currentMember != null && (memberDecl.Modifier & Modifiers.Visibility) == Modifiers.None && interfaceImplementations.Count == 1) { // member is explicitly implementing an interface member // to convert explicit interface implementations to VB, make the member private // and ensure its name does not collide with another member memberDecl.Modifier |= Modifiers.Private; memberDecl.Name = interfaceImplementations[0].InterfaceType.Type.Replace('.', '_') + "_" + memberDecl.Name; } if (currentMember != null && currentMember.IsPublic && currentMember.DeclaringType.ClassType != ClassType.Interface) { // member could be implicitly implementing an interface member, // search for interfaces containing the member foreach (IReturnType directBaseType in currentMember.DeclaringType.GetCompoundClass().BaseTypes) { IClass directBaseClass = directBaseType.GetUnderlyingClass(); if (directBaseClass != null && directBaseClass.ClassType == ClassType.Interface) { // include members inherited from other interfaces in the search: foreach (IReturnType baseType in MemberLookupHelper.GetTypeInheritanceTree(directBaseType)) { IClass baseClass = baseType.GetUnderlyingClass(); if (baseClass != null && baseClass.ClassType == ClassType.Interface) { IMember similarMember = MemberLookupHelper.FindSimilarMember(baseClass, currentMember); // add an interface implementation for similarMember // only when similarMember is not explicitly implemented by another member in this class if (similarMember != null && !HasExplicitImplementationFor(similarMember, baseType, memberDecl.Parent)) { interfaceImplementations.Add(new InterfaceImplementation( Refactoring.CodeGenerator.ConvertType(baseType, CreateContext()), currentMember.Name)); } } } } } } }
/// <summary> /// Provides a mechanism for making a <see cref="ConstructorDeclaration"/> a bit more like a /// <see cref="MethodDeclaration"/> by simulating a common method for the result of their respective executions. /// </summary> /// /// <param name="node"> /// A constructor or method. /// </param> /// /// <param name="parentType"> /// The <see cref="TypeDeclaration"/> in which the constructor or method denoted by <paramref name="node"/> can /// be found. /// </param> /// /// <returns> /// A <see cref="TypeReference"/>, if one could be determined; otherwise <see cref="NullTypeReference"/>. /// </returns> public static TypeReference GetTypeReference(this ParametrizedNode node, TypeDeclaration parentType) { var result = TypeReference.Null; var method = node as MethodDeclaration; if (method != null) { result = method.TypeReference; } else { var constructor = node as ConstructorDeclaration; if (constructor != null) { result = new TypeReference(parentType.Name); } } return(result); }
public static void RenameConflicting(ParametrizedNode method) { // variable name => case sensitive variable name // value is null if there are multiple casings for the variable -> the variable is conflicting Dictionary<string, string> caseInsensitive = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); LookupTableVisitor ltv = new LookupTableVisitor(SupportedLanguage.CSharp); method.AcceptVisitor(ltv, null); // add method parameters to caseInsensitive foreach (ParameterDeclarationExpression pde in method.Parameters) { AddVariableToDict(caseInsensitive, pde.ParameterName, true); } // add local variables to caseInsensitive foreach (KeyValuePair<string, List<LocalLookupVariable>> var in ltv.Variables) { AddVariableToDict(caseInsensitive, var.Key, true); } // add used identifiers to caseInsensitive FindIdentifiersVisitor fvv = new FindIdentifiersVisitor(); method.AcceptVisitor(fvv, null); foreach (KeyValuePair<string, string> pair in fvv.usedIdentifiers) { AddVariableToDict(caseInsensitive, pair.Key, false); } int index = 0; foreach (ParameterDeclarationExpression pde in method.Parameters) { if (caseInsensitive[pde.ParameterName] == null) { RenameVariable(method, pde.ParameterName, ref index); } } foreach (KeyValuePair<string, List<LocalLookupVariable>> var in ltv.Variables) { if (caseInsensitive[var.Key] == null) { RenameVariable(method, var.Key, ref index); } } }
B.TypeMemberModifiers ConvertModifier(AttributedNode node, B.TypeMemberModifiers defaultVisibility) { Modifiers m = node.Modifier; B.TypeMemberModifiers r = B.TypeMemberModifiers.None; if ((m & Modifiers.Private) != 0) { r |= B.TypeMemberModifiers.Private; } if ((m & Modifiers.Internal) != 0) { r |= B.TypeMemberModifiers.Internal; } if ((m & Modifiers.Public) != 0) { r |= B.TypeMemberModifiers.Public; } if ((m & Modifiers.Protected) != 0) { r |= B.TypeMemberModifiers.Protected; } if (r == B.TypeMemberModifiers.None) { r = defaultVisibility; } if ((m & Modifiers.Abstract) != 0) { r |= B.TypeMemberModifiers.Abstract; } if ((m & Modifiers.Virtual) != 0) { r |= B.TypeMemberModifiers.Virtual; } if ((m & Modifiers.Sealed) != 0) { r |= B.TypeMemberModifiers.Final; } if ((m & Modifiers.Static) != 0) { r |= B.TypeMemberModifiers.Static; } else if (currentType != null && currentType.IsStatic) { if (!(node is TypeDeclaration)) { r |= B.TypeMemberModifiers.Static; } } if ((m & Modifiers.Override) != 0) { r |= B.TypeMemberModifiers.Override; } if ((m & Modifiers.ReadOnly) != 0 && !(node is PropertyDeclaration)) { r |= B.TypeMemberModifiers.Final; } if ((m & Modifiers.Const) != 0) { r |= B.TypeMemberModifiers.Final | B.TypeMemberModifiers.Static; } if ((m & Modifiers.New) != 0) { AddError(node, "shadowing is not supported"); } if ((m & Modifiers.Partial) != 0) { r |= B.TypeMemberModifiers.Partial; } if ((m & Modifiers.Extern) != 0) { // not necessary in Boo } if ((m & Modifiers.Volatile) != 0) { AddError(node, "Volatile modifier is not supported"); } if ((m & Modifiers.Unsafe) != 0) { AddError(node, "Unsafe modifier is not supported"); } if ((m & Modifiers.Overloads) != 0) { // not necessary in Boo } if ((m & Modifiers.WithEvents) != 0) { // not necessary in Boo } if ((m & Modifiers.Default) != 0) { ParametrizedNode parametrizedNode = node as ParametrizedNode; string name = null; if (parametrizedNode != null) { name = parametrizedNode.Name; } else { AddError(node, "Default modifier is not supported on this member."); } if (name != null && currentType != null) { currentType.Attributes.Add(MakeAttribute("System.Reflection.DefaultMember", new B.StringLiteralExpression(name))); } } return(r); }
/// <summary> /// Generates a unit test method that exercises the provided <paramref name="methodToTest"/>. /// </summary> /// /// <param name="methodToTest"> /// The <see cref="ParametrizedNode"/> representing the method or constructor for which a test is to be written. /// </param> /// /// <returns> /// The string representation of the source code of the generated method to test /// <paramref name="methodToTest"/>. /// </returns> public static string GenerateTest(this ParametrizedNode methodToTest) { return(TestMethod.Generate(methodToTest)); }
/// <summary> /// Initializes a new instance of the <see cref="TestMethod"/> parameterized template with the specified /// <paramref name="methodToTest"/> and <paramref name="classUnderTest"/>. /// </summary> /// /// <param name="methodToTest"> /// The <see cref="ParametrizedNode"/> representing the method or constructor for which tests are to be written. /// </param> /// /// <param name="classUnderTest"> /// The <see cref="TypeDeclaration"/> that contains <paramref name="methodToTest"/>. /// </param> public TestMethod(ParametrizedNode methodToTest, TypeDeclaration classUnderTest) : base(methodToTest, classUnderTest) { }
static bool CreateEventHandlerCode(CompletionContext context, NewEventCompletionItem completionItem, out int discriminator) { ParseInformation p = ParserService.GetParseInformation(context.Editor.FileName); var unit = p.CompilationUnit; var loc = context.Editor.Document.OffsetToPosition(context.StartOffset); IClass c = unit.GetInnermostClass(loc.Line, loc.Column); discriminator = 1; if (c == null) { return(false); } IMethod initializeComponent = c.Methods[0]; CompoundClass compound = c.GetCompoundClass() as CompoundClass; IMethod invokeMethod = completionItem.EventType.ReturnType.GetMethods().FirstOrDefault(m => m.Name == "Invoke"); string handlerName = completionItem.HandlerName; if (invokeMethod == null) { throw new ArgumentException("delegateType is not a valid delegate!"); } if (compound != null) { foreach (IClass part in compound.Parts) { IMember lastMember = part.Methods.LastOrDefault(); if (lastMember != null && lastMember.ToString() == initializeComponent.ToString()) { continue; } if (completionItem.EventType.ReturnType == null) { return(false); } while (part.Methods.Any(m => m.Name == handlerName && m.Parameters.Count == invokeMethod.Parameters.Count && m.Parameters.SequenceEqual(invokeMethod.Parameters, new ParameterComparer()) )) { handlerName = completionItem.HandlerName + discriminator; discriminator++; } discriminator--; ParametrizedNode node = (ParametrizedNode)CodeGenerator.ConvertMember(invokeMethod, new ClassFinder(part, context.Editor.Caret.Line, context.Editor.Caret.Column)); node.Name = handlerName; node.Modifier = Modifiers.None; IViewContent viewContent = FileService.OpenFile(part.CompilationUnit.FileName, XamlBindingOptions.SwitchToCodeViewAfterInsertion); IFileDocumentProvider document = viewContent as IFileDocumentProvider; if (viewContent != null && document != null) { DomRegion domRegion; if (lastMember != null) { unit.ProjectContent.Language.CodeGenerator.InsertCodeAfter(lastMember, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); domRegion = lastMember.BodyRegion; } else { unit.ProjectContent.Language.CodeGenerator.InsertCodeAtEnd(part.Region, new RefactoringDocumentAdapter(document.GetDocumentForFile(viewContent.PrimaryFile)), node); domRegion = part.Region; } // move caret to generated code ITextEditorProvider provider = viewContent as ITextEditorProvider; if (provider != null) { provider.TextEditor.JumpTo(domRegion.EndLine + 2, domRegion.EndColumn - 1); } } return(true); } } return(false); }
// public override bool Extract(MethodDeclaration md, Window window, List<INode> children) public bool Extract(ParametrizedNode parentNode, Window window, List <INode> children) { this.currentSelection = new MySelection(children.GetRange(window.Top, window.Size)); // this.start = new Location(this.currentSelection.StartPosition.Column + 1, this.currentSelection.StartPosition.Line + 1); // this.end = new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1); this.start = this.currentSelection.StartPosition; this.end = this.currentSelection.EndPosition; this.parentNode = parentNode; MethodDeclaration newMethod = new MethodDeclaration(); // Initialise new method newMethod.Body = GetBlock(currentSelection.Nodes); newMethod.Body.StartLocation = new Location(0, 0); List <VariableDeclaration> possibleReturnValues = new List <VariableDeclaration>(); List <VariableDeclaration> otherReturnValues = new List <VariableDeclaration>(); if (!CheckForJumpInstructions(newMethod, this.currentSelection)) { return(false); } newMethod.Modifier = parentNode.Modifier; newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public | Modifiers.Override); LookupTableVisitor ltv = new LookupTableVisitor(SupportedLanguage.CSharp); parentNode.AcceptVisitor(ltv, null); var variablesList = (from list in ltv.Variables.Values from item in list select new Variable(item)).Where(v => !(v.StartPos > end || v.EndPos < start) && HasReferencesInSelection(currentSelection, v)).Union(FromParameters(newMethod)).Select(va => ResolveVariable(va)); foreach (var variable in variablesList) { bool hasOccurrencesAfter = HasOccurrencesAfter(CSharpNameComparer, this.parentNode, end, variable.Name, variable.StartPos, variable.EndPos); bool isInitialized = (variable.Initializer != null) ? !variable.Initializer.IsNull : false; bool hasAssignment = HasAssignment(newMethod, variable); if (IsInSel(variable.StartPos, this.currentSelection) && hasOccurrencesAfter) { possibleReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type)); otherReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type)); } if (!(IsInSel(variable.StartPos, this.currentSelection) || IsInSel(variable.EndPos, this.currentSelection))) { ParameterDeclarationExpression newParam = null; if ((hasOccurrencesAfter && isInitialized) || variable.WasRefParam) { newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.Ref); } else { if ((hasOccurrencesAfter && hasAssignment) || variable.WasOutParam) { newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.Out); } else { if (!hasOccurrencesAfter) { newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.None); } else { if (!hasOccurrencesAfter && !isInitialized) { newMethod.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type))); } else { newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.In); } } } } if (newParam != null) { newMethod.Parameters.Add(newParam); } } } List <VariableDeclaration> paramsAsVarDecls = new List <VariableDeclaration>(); this.beforeCallDeclarations = new List <LocalVariableDeclaration>(); for (int i = 0; i < otherReturnValues.Count - 1; i++) { VariableDeclaration varDecl = otherReturnValues[i]; paramsAsVarDecls.Add(varDecl); ParameterDeclarationExpression p = new ParameterDeclarationExpression(varDecl.TypeReference, varDecl.Name); p.ParamModifier = ParameterModifiers.Out; if (!newMethod.Parameters.Contains(p)) { newMethod.Parameters.Add(p); } else { this.beforeCallDeclarations.Add(new LocalVariableDeclaration(varDecl)); } } CreateReturnStatement(newMethod, possibleReturnValues); newMethod.Name = "NewMethod"; this.extractedMethod = newMethod; return(true); }
/// <summary> /// Generates a string representation of a C# unit test method that tests <paramref name="methodToTest"/>. /// </summary> /// /// <param name="methodToTest"> /// A <see cref="ParametrizedNode"/> representing the method for which a test is to be written. /// </param> /// /// <param name="classUnderTest"> /// The class in which the method to test is located. /// </param> /// /// <returns> /// A C# NUnit test method stub. /// </returns> public static string GenerateTestMethod(ParametrizedNode methodToTest, TypeDeclaration classUnderTest) { var template = new TestMethod(methodToTest, classUnderTest); return(template.TransformText()); }