internal static string Generate(ParametrizedNode methodToCall, TypeDeclaration parentType, string returnVariableName) { var template = new MethodCallStub(methodToCall, parentType, returnVariableName); var text = template.TransformText(); return text; }
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); }
/// <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 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); }
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); }
/// <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 ); }
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); } } }
private void VisitParametrizedNode(NR.ParametrizedNode node, bool isConstructor) { if (((isConstructor && this.Method.IsConstructor) || (node.Name == this.Method.Name)) && node.Parameters.Count == this.Method.Parameters.Count) { var doParametersMatch = true; NR.ParameterDeclarationExpression matchingParameter = null; for (var i = 0; i < node.Parameters.Count; i++) { var parsedParameter = node.Parameters[i]; if (parsedParameter.ParameterName != this.Method.Parameters[i].Name) { doParametersMatch = false; break; } else if (parsedParameter.ParameterName == this.Parameter.Name) { matchingParameter = parsedParameter; } } if (doParametersMatch && matchingParameter != null) { this.SequencePoint = (from attributeSection in matchingParameter.Attributes from attribute in attributeSection.Attributes where (attribute.Name == "NotNullAttribute" || attribute.Name == "NotNull") select new SequencePoint(this.Document) { EndColumn = attribute.EndLocation.Column, EndLine = attribute.EndLocation.Line, StartColumn = attribute.StartLocation.Column, StartLine = attribute.StartLocation.Line }).Single(); } } }
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; }
/// <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; }
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)); } } } } } } }
IEnumerable<string> GetNativeImplLines (ParametrizedNode method) { var attr = GetMethodAttribute (method, "Native"); if (attr == null) return null; var result = new List<string> (); foreach (var arg in attr.PositionalArguments) { PrimitiveExpression expr = (PrimitiveExpression)arg; result.Add ((string)expr.Value); } return result; }
// 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; }
/// <summary> /// Adds the method or constructor parameters. /// </summary> void AddParameters(ParametrizedNode method) { Append("("); List<ParameterDeclarationExpression> parameters = method.Parameters; if (parameters.Count > 0) { if (!IsStatic(method)) { Append("self, "); } for (int i = 0; i < parameters.Count; ++i) { if (i > 0) { Append(", "); } Append(parameters[i].ParameterName); } } else { if (!IsStatic(method)) { Append("self"); } } Append("):"); }
// 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; }
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; }
/// <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(); }
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; }
private void AddParameters(ParametrizedNode method) { this.Append("("); List<ParameterDeclarationExpression> parameters = method.Parameters; if (parameters.Count > 0) { if (!this.IsStatic(method)) { this.Append("self, "); } for (int i = 0; i < parameters.Count; i++) { if (i > 0) { this.Append(", "); } this.Append(parameters[i].ParameterName); } } else if (!this.IsStatic(method)) { this.Append("self"); } this.Append("):"); }
/// <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) { }
private bool IsStatic(ParametrizedNode method) { return (method.Modifier & Modifiers.Static) == Modifiers.Static; }
/// <summary> /// Adds the method or constructor parameters. /// </summary> void AddParameters(ParametrizedNode method) { Append("("); List<ParameterDeclarationExpression> parameters = method.Parameters; if (parameters.Count > 0) { for (int i = 0; i < parameters.Count; ++i) { if (i > 0) { Append(", "); } Append(parameters[i].ParameterName); } } Append(")"); }