/// <summary> /// Creates a new DeclarationHeader for the declaration and assigns it to the declaration. /// </summary> /// <param name="declaration"> /// The declaration to create the header for. /// </param> /// <param name="docConfig"> /// Provides the configuration for the current ProjectFile. /// </param> /// <returns> /// A DeclarationHeader for the declaration passed in. /// </returns> public static DeclarationHeader CreateNewHeader(IDeclaration declaration, DocumentationRulesConfiguration docConfig) { IFile file = declaration.GetContainingFile(); using (WriteLockCookie.Create(file.IsPhysical())) { IDeclaration declarationTreeNode = declaration; IContextBoundSettingsStore settingsStore = PsiSourceFileExtensions.GetSettingsStore(null, declaration.GetSolution()); bool useSingleLineDeclarationComments = settingsStore.GetValue((StyleCopOptionsSettingsKey key) => key.UseSingleLineDeclarationComments); string middleText = useSingleLineDeclarationComments ? string.Empty : Environment.NewLine; string emptyDocHeader = string.Format("<summary>{0}</summary>", middleText); if (!(declarationTreeNode is IMultipleDeclarationMember)) { emptyDocHeader = CreateDocumentationForElement((IDocCommentBlockOwnerNode)declaration, docConfig); emptyDocHeader = emptyDocHeader.Substring(0, emptyDocHeader.Length - Environment.NewLine.Length); } string header = LayoutDocumentationHeader(emptyDocHeader, declaration); IDocCommentBlockNode newDocCommentNode = Utils.CreateDocCommentBlockNode(file, header); IDocCommentBlockOwnerNode docCommentBlockOwnerNode = Utils.GetDocCommentBlockOwnerNodeForDeclaration(declaration); if (docCommentBlockOwnerNode != null) { docCommentBlockOwnerNode.SetDocCommentBlockNode(newDocCommentNode); } return(new DeclarationHeader(declaration)); } }
/// <summary> /// Our internal implementation of the bulb item which assumes it is running within a transaction /// </summary> /// <param name="solution">The currently open solution</param> /// <param name="textControl">The text control that is currently open</param> public void ExecuteEx(ISolution solution, ITextControl textControl) { // Get the comment block owner (ie the part of the declaration which will own the comment). IDocCommentBlockOwnerNode docCommentBlockOwnerNode = XmlDocTemplateUtil.FindDocCommentOwner(_declaration as ITypeMemberDeclaration); // If we didn't get an owner then give up if (docCommentBlockOwnerNode == null) { return; } // We got one // Ask resharper to create the xml for us. int myCursorOffset; string text = XmlDocTemplateUtil.GetDocTemplate(docCommentBlockOwnerNode, out myCursorOffset); // Get a factory which can create elements in the C# docs CSharpElementFactory factory = CSharpElementFactory.GetInstance(docCommentBlockOwnerNode.GetPsiModule()); // Create the comment block IDocCommentBlockNode comment = factory.CreateDocCommentBlock(text); // And set the comment on the declaration. docCommentBlockOwnerNode.SetDocCommentBlockNode(comment); }
/// <summary> /// Creates a new DeclarationHeader for the declaration and assigns it to the declaration. /// </summary> /// <param name="declaration"> /// The declaration to create the header for. /// </param> /// <param name="docConfig"> /// Provides the configuration for the current ProjectFile. /// </param> /// <returns> /// A DeclarationHeader for the declaration passed in. /// </returns> public static DeclarationHeader CreateNewHeader(IDeclaration declaration, DocumentationRulesConfiguration docConfig) { IFile file = declaration.GetContainingFile(); using (WriteLockCookie.Create(file.IsPhysical())) { IDeclaration declarationTreeNode = declaration; string middleText = StyleCopOptions.Instance.UseSingleLineDeclarationComments ? string.Empty : Environment.NewLine; string emptyDocHeader = string.Format("<summary>{0}</summary>", middleText); if (!(declarationTreeNode is IMultipleDeclarationMember)) { emptyDocHeader = CreateDocumentationForElement((IDocCommentBlockOwnerNode)declaration, docConfig); emptyDocHeader = emptyDocHeader.Substring(0, emptyDocHeader.Length - Environment.NewLine.Length); } string header = LayoutDocumentationHeader(emptyDocHeader); IDocCommentBlockNode newDocCommentNode = Utils.CreateDocCommentBlockNode(file, header); IDocCommentBlockOwnerNode docCommentBlockOwnerNode = Utils.GetDocCommentBlockOwnerNodeForDeclaration(declaration); if (docCommentBlockOwnerNode != null) { docCommentBlockOwnerNode.SetDocCommentBlockNode(newDocCommentNode); } return(new DeclarationHeader(declaration)); } }
public static void SetDocComment(IDocCommentBlockOwnerNode docCommentBlockOwnerNode, string text, ISolution solution) { text = String.Format("///{0}\r\nclass Tmp {{}}", text.Replace("\n", "\n///")); ICSharpTypeMemberDeclaration declaration = CSharpElementFactory.GetInstance(docCommentBlockOwnerNode.GetPsiModule()).CreateTypeMemberDeclaration(text, new object[0]); docCommentBlockOwnerNode.SetDocCommentBlockNode( ((IDocCommentBlockOwnerNode)declaration).GetDocCommentBlockNode()); }
private static int CalcLineOffset(IDocCommentBlockOwnerNode node) { ITreeNode prev = node.PrevSibling; if (prev != null && prev is IWhitespaceNode && !((IWhitespaceNode)prev).IsNewLine) { return(prev.GetTextLength()); } return(0); }
public static void ReflowAndRetagCommentBlockNode(ISolution solution, IProgressIndicator progress, IDocCommentBlockNode docCommentBlockNode) { if (docCommentBlockNode == null) { return; } // Get the settings. IContextBoundSettingsStore settingsStore = Shell.Instance.GetComponent <ISettingsStore>().BindToContextTransient(ContextRange.ApplicationWide); XmlDocumentationSettings settings = settingsStore.GetKey <XmlDocumentationSettings>(SettingsOptimization.OptimizeDefault); ReflowAndRetagSettings reflowSettings = settingsStore.GetKey <ReflowAndRetagSettings>(SettingsOptimization.OptimizeDefault); int maxLength = settings.MaxCharactersPerLine; // Get the comment block owner (ie the part of the declaration which will own the comment). IDocCommentBlockOwnerNode ownerNode = docCommentBlockNode.GetContainingNode <IDocCommentBlockOwnerNode>(); // If we didn't get an owner then give up if (ownerNode == null) { return; } // Get a factory which can create elements in the C# docs //CSharpElementFactory factory = CSharpElementFactory.GetInstance(ownerNode.GetPsiModule()); // Calculate line offset where /// starts and add 4 for the slashes and space int startPos = CalcLineOffset(ownerNode) + 4; // Create a new comment block with the adjusted text IDocCommentBlockNode comment = docCommentBlockNode; //factory.CreateDocCommentBlock(text); string reflownText = new XmlCommentReflower(settings, reflowSettings).ReflowAndRetag(comment, maxLength - startPos); // If the xml was malformed then the comment will now be empty - detect this and do nothing if (string.IsNullOrEmpty(reflownText)) { return; } /*comment = factory.CreateDocCommentBlock(reflownText); * * // And set the comment on the declaration. * ownerNode.SetDocCommentBlockNode(comment);*/ SetDocComment(ownerNode, reflownText, solution); }
public static void ReFlowCommentBlockNode(ISolution solution, IProgressIndicator progress, IDocCommentBlockNode docCommentBlockNode) { if (docCommentBlockNode == null) { return; } // Get the settings. IContextBoundSettingsStore settingsStore = Shell.Instance.GetComponent <ISettingsStore>().BindToContextTransient(ContextRange.ApplicationWide); XmlDocumentationSettings settings = settingsStore.GetKey <XmlDocumentationSettings>(SettingsOptimization.OptimizeDefault); ReflowAndRetagSettings reflowSettings = settingsStore.GetKey <ReflowAndRetagSettings>(SettingsOptimization.OptimizeDefault); int maxLength = settings.MaxCharactersPerLine; IDocCommentBlockOwnerNode ownerNode = docCommentBlockNode.GetContainingNode <IDocCommentBlockOwnerNode>(); // If we didn't get an owner then give up if (ownerNode == null) { return; } // Get a factory which can create elements in the C# docs //CSharpElementFactory factory = CSharpElementFactory.GetInstance(ownerNode.GetPsiModule()); // Calculate line offset where /// starts and add 3 for each // slash. int startPos = CalcLineOffset(ownerNode) + 3; // Create a new comment block with the adjusted text IDocCommentBlockNode comment = docCommentBlockNode; //factory.CreateDocCommentBlock(text); // Work out if we have a space between the /// and <summary> string reflownText = new XmlCommentReflower(settings, reflowSettings).Reflow(comment, maxLength - startPos); //comment = factory.CreateDocCommentBlock(reflownText); SetDocComment(ownerNode, reflownText, solution); // And set the comment on the declaration. //ownerNode.SetDocCommentBlockNode(comment); }
/// <summary> /// Returns an xml string of the documentation for an element. /// </summary> /// <param name="owner"> /// The owner of the doc comment block. /// </param> /// <param name="docConfig"> /// The config for the current ProjectFile. /// </param> /// <returns> /// A string of the declarations summary text. /// </returns> private static string CreateDocumentationForElement(IDocCommentBlockOwnerNode owner, DocumentationRulesConfiguration docConfig) { ITreeNode element = owner; IDeclaredElement declaredElement = (element is IDeclaration) ? ((IDeclaration)element).DeclaredElement : null; StringBuilder text = new StringBuilder(); text.AppendLine("<summary>"); string summaryText = string.Empty; if (element is IConstructorDeclaration) { summaryText = Utils.CreateSummaryForConstructorDeclaration((IConstructorDeclaration)element); } if (element is IDestructorDeclaration) { summaryText = Utils.CreateSummaryForDestructorDeclaration((IDestructorDeclaration)element); } if (element is IPropertyDeclaration) { summaryText = Utils.CreateSummaryDocumentationForProperty((IPropertyDeclaration)element); } text.AppendLine(summaryText); text.AppendLine("</summary>"); ICSharpParametersOwnerDeclaration declarationWithParameters = element as ICSharpParametersOwnerDeclaration; if (declarationWithParameters != null) { foreach (IRegularParameterDeclaration parameterDeclaration in declarationWithParameters.ParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(parameterDeclaration)); } } ICSharpTypeDeclaration typeDeclaration = element as ICSharpTypeDeclaration; if (typeDeclaration != null && (typeDeclaration.TypeParameters.Count > 0)) { foreach (ITypeParameterOfTypeDeclaration typeParameter in typeDeclaration.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } ITypeParametersOwner typeParametersOwner = element as ITypeParametersOwner; if (typeParametersOwner != null && (typeParametersOwner.TypeParameters.Count > 0)) { foreach (ITypeParameter typeParameter in typeParametersOwner.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForTypeParameterDeclaration((ITypeParameterDeclaration)typeParameter)); } } IMethodDeclaration methodDeclaration = element as IMethodDeclaration; if (methodDeclaration != null && (methodDeclaration.TypeParameterDeclarations.Count > 0)) { foreach (ITypeParameterOfMethodDeclaration typeParameter in methodDeclaration.TypeParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } IParametersOwner parametersOwner = declaredElement as IParametersOwner; if ((parametersOwner != null && ((parametersOwner is IMethod) || (parametersOwner is IOperator))) && !parametersOwner.ReturnType.Equals(parametersOwner.Module.GetPredefinedType().Void)) { text.AppendLine("<returns></returns>"); } bool ruleIsEnabled = docConfig.GetStyleCopRuleEnabled("PropertyDocumentationMustHaveValue"); if (element is IPropertyDeclaration && ruleIsEnabled) { text.AppendLine(Utils.CreateValueDocumentationForProperty((IPropertyDeclaration)element)); } List <IType> exceptions = new List <IType>(); ICSharpFunctionDeclaration functionDeclaration = element as ICSharpFunctionDeclaration; if (functionDeclaration != null && functionDeclaration.Body != null) { CollectExceptions(functionDeclaration.Body, exceptions); } IPropertyDeclaration propertyDeclaration = element as IPropertyDeclaration; if (propertyDeclaration != null) { CollectExceptions(propertyDeclaration.AccessorDeclarations, exceptions); } IIndexerDeclaration indexerDeclaration = element as IIndexerDeclaration; if (indexerDeclaration != null) { CollectExceptions(indexerDeclaration.AccessorDeclarations, exceptions); } IEventDeclaration eventDeclaration = element as IEventDeclaration; if (eventDeclaration != null) { CollectExceptions(eventDeclaration.AccessorDeclarations, exceptions); } foreach (IType exception in exceptions) { string presentableName = exception.GetPresentableName(CSharpLanguage.Instance); string a = Utils.StripClassName(presentableName); string b = exception.ToString(); text.AppendLine("<exception cref=\"" + Utils.SwapGenericTypeToDocumentation(a) + "\"></exception>"); } return(text.ToString()); }
/// <summary> /// Returns an xml string of the documentation for an element. /// </summary> /// <param name="owner"> /// The owner of the doc comment block. /// </param> /// <param name="docConfig"> /// The config for the current ProjectFile. /// </param> /// <returns> /// A string of the declarations summary text. /// </returns> private static string CreateDocumentationForElement(IDocCommentBlockOwnerNode owner, DocumentationRulesConfiguration docConfig) { ITreeNode element = owner; IDeclaredElement declaredElement = (element is IDeclaration) ? ((IDeclaration)element).DeclaredElement : null; StringBuilder text = new StringBuilder(); text.AppendLine("<summary>"); string summaryText = string.Empty; if (element is IConstructorDeclaration) { summaryText = Utils.CreateSummaryForConstructorDeclaration((IConstructorDeclaration)element); } if (element is IDestructorDeclaration) { summaryText = Utils.CreateSummaryForDestructorDeclaration((IDestructorDeclaration)element); } if (element is IPropertyDeclaration) { summaryText = Utils.CreateSummaryDocumentationForProperty((IPropertyDeclaration)element); } text.AppendLine(summaryText); text.AppendLine("</summary>"); ICSharpParametersOwnerDeclaration declarationWithParameters = element as ICSharpParametersOwnerDeclaration; if (declarationWithParameters != null) { foreach (ICSharpParameterDeclaration parameterDeclaration in declarationWithParameters.ParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(parameterDeclaration)); } } ICSharpTypeDeclaration typeDeclaration = element as ICSharpTypeDeclaration; if (typeDeclaration != null && (typeDeclaration.TypeParameters.Count > 0)) { foreach (ITypeParameterOfTypeDeclaration typeParameter in typeDeclaration.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } ITypeParametersOwner typeParametersOwner = element as ITypeParametersOwner; if (typeParametersOwner != null && (typeParametersOwner.TypeParameters.Count > 0)) { foreach (ITypeParameter typeParameter in typeParametersOwner.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForTypeParameterDeclaration((ITypeParameterDeclaration)typeParameter)); } } IMethodDeclaration methodDeclaration = element as IMethodDeclaration; if (methodDeclaration != null && (methodDeclaration.TypeParameterDeclarations.Count > 0)) { foreach (ITypeParameterOfMethodDeclaration typeParameter in methodDeclaration.TypeParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } IParametersOwner parametersOwner = declaredElement as IParametersOwner; if ((parametersOwner != null && ((parametersOwner is IMethod) || (parametersOwner is IOperator))) && !parametersOwner.ReturnType.Equals(parametersOwner.Module.GetPredefinedType().Void)) { text.AppendLine("<returns></returns>"); } bool ruleIsEnabled = docConfig.GetStyleCopRuleEnabled("PropertyDocumentationMustHaveValue"); if (element is IPropertyDeclaration && ruleIsEnabled) { text.AppendLine(Utils.CreateValueDocumentationForProperty((IPropertyDeclaration)element)); } List<IType> exceptions = new List<IType>(); ICSharpFunctionDeclaration functionDeclaration = element as ICSharpFunctionDeclaration; if (functionDeclaration != null && functionDeclaration.Body != null) { CollectExceptions(functionDeclaration.Body, exceptions); } IPropertyDeclaration propertyDeclaration = element as IPropertyDeclaration; if (propertyDeclaration != null) { CollectExceptions(propertyDeclaration.AccessorDeclarations, exceptions); } IIndexerDeclaration indexerDeclaration = element as IIndexerDeclaration; if (indexerDeclaration != null) { CollectExceptions(indexerDeclaration.AccessorDeclarations, exceptions); } IEventDeclaration eventDeclaration = element as IEventDeclaration; if (eventDeclaration != null) { CollectExceptions(eventDeclaration.AccessorDeclarations, exceptions); } foreach (IType exception in exceptions) { string presentableName = exception.GetPresentableName(CSharpLanguage.Instance); string a = Utils.StripClassName(presentableName); string b = exception.ToString(); text.AppendLine("<exception cref=\"" + Utils.SwapGenericTypeToDocumentation(a) + "\"></exception>"); } return text.ToString(); }