public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) { var docComment = node.GetLeadingTrivia().Select(i => i.GetStructure()).OfType <DocumentationCommentTriviaSyntax>().FirstOrDefault(); _parsedBaseTypes.Add(new ParsedType(node, docComment)); base.VisitInterfaceDeclaration(node); }
/// <summary> /// Adds documentation header async. /// </summary> /// <param name="document">The document.</param> /// <param name="root">The root.</param> /// <param name="declarationSyntax">The declaration syntax.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A Document.</returns> private async Task <Document> AddDocumentationHeaderAsync(Document document, SyntaxNode root, InterfaceDeclarationSyntax declarationSyntax, CancellationToken cancellationToken) { SyntaxTriviaList leadingTrivia = declarationSyntax.GetLeadingTrivia(); string comment = CommentHelper.CreateInterfaceComment(declarationSyntax.Identifier.ValueText); DocumentationCommentTriviaSyntax commentTrivia = await Task.Run(() => DocumentationHeaderHelper.CreateOnlySummaryDocumentationCommentTrivia(comment), cancellationToken); SyntaxTriviaList newLeadingTrivia = leadingTrivia.Insert(leadingTrivia.Count - 1, SyntaxFactory.Trivia(commentTrivia)); InterfaceDeclarationSyntax newDeclaration = declarationSyntax.WithLeadingTrivia(newLeadingTrivia); SyntaxNode newRoot = root.ReplaceNode(declarationSyntax, newDeclaration); return(document.WithSyntaxRoot(newRoot)); }
/// <summary> /// Analyzes node. /// </summary> /// <param name="context">The context.</param> private static void AnalyzeNode(SyntaxNodeAnalysisContext context) { InterfaceDeclarationSyntax node = context.Node as InterfaceDeclarationSyntax; DocumentationCommentTriviaSyntax commentTriviaSyntax = node .GetLeadingTrivia() .Select(o => o.GetStructure()) .OfType <DocumentationCommentTriviaSyntax>() .FirstOrDefault(); if (commentTriviaSyntax != null && CommentHelper.HasComment(commentTriviaSyntax)) { return; } context.ReportDiagnostic(Diagnostic.Create(Rule, node.Identifier.GetLocation())); }
public override SyntaxNode VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) { return(base.VisitInterfaceDeclaration(node).WithLeadingTrivia(node.GetLeadingTrivia())); }
public static SyntaxNode Do(Compilation compilation, Compilation interfacesCompilation, SyntaxNode root, SyntaxNode targetTypeDeclaration) { // Couldn't get SymbolFinder.FindImplementedInterfaceMembersAsync or .FindImplementations working, so doing it the hard hacky way. if (targetTypeDeclaration is StructDeclarationSyntax) { return(root); // not propagating documentation into the structs (used for enumeration entry definitions) } // collect all interfaces and the methods/properties they declare Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaces = new Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> >(); foreach (Compilation compilation1 in new Compilation[] { interfacesCompilation, compilation }) { foreach (SyntaxTree interfaceTree in compilation1.SyntaxTrees) { foreach (SyntaxNode node in interfaceTree.GetRoot().DescendantNodesAndSelf().Where( delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.InterfaceDeclaration)); })) { if (AttributeMatchUtil.HasAttributeSimple(((InterfaceDeclarationSyntax)node).AttributeLists, DocSourceAttributeName)) { List <MemberDeclarationSyntax> members = new List <MemberDeclarationSyntax>(); foreach (SyntaxNode decl in node.DescendantNodesAndSelf().Where(delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); })) { members.Add((MemberDeclarationSyntax)decl); } InterfaceDeclarationSyntax ifaceDecl = (InterfaceDeclarationSyntax)node; interfaces.Add(ifaceDecl, members); } } } } // enumrate base types of generated class List <BaseTypeSyntax> baseTypes = new List <BaseTypeSyntax>(); { IEnumerable <BaseTypeSyntax> baseTypeList = ((ClassDeclarationSyntax)targetTypeDeclaration).BaseList.Types; foreach (BaseTypeSyntax baseType in baseTypeList) { baseTypes.Add(baseType); } } Dictionary <SyntaxNode, SyntaxNode> replacements = new Dictionary <SyntaxNode, SyntaxNode>(); foreach (BaseTypeSyntax baseType in baseTypes) { // can we find an interface that matches this? foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces) { InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key; // hack string baseTypeString = GetStringForBaseTypeComparison(baseType); string patternString = GetStringForInterfaceComparison(interfaceDeclaration); //Console.WriteLine("{2} {0} ? {1}", baseTypeString, patternString, String.Equals(baseTypeString, patternString) ? "*" : " "); if (String.Equals(baseTypeString, patternString)) { // can we find any members we implemented that are in the interface? foreach (SyntaxNode node in targetTypeDeclaration.DescendantNodes(delegate(SyntaxNode descendInto) { return((descendInto == targetTypeDeclaration) || descendInto.IsKind(SyntaxKind.MethodDeclaration) || descendInto.IsKind(SyntaxKind.PropertyDeclaration)); }) .Where(delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); })) { if (node.IsKind(SyntaxKind.MethodDeclaration)) { MethodDeclarationSyntax implementation = (MethodDeclarationSyntax)node; if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); })) { continue; // non-public can't be from an interface } foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value) { if (prototype1.IsKind(SyntaxKind.MethodDeclaration)) { MethodDeclarationSyntax prototype = (MethodDeclarationSyntax)prototype1; // HACK: should check argument and return types if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier) && (implementation.ParameterList.Parameters.Count == prototype.ParameterList.Parameters.Count)) { // copy documentation SyntaxNode replacement = node.WithLeadingTrivia( node.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia()))); if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces { replacements.Add(node, replacement); } break; } } } } else if (node.IsKind(SyntaxKind.PropertyDeclaration)) { PropertyDeclarationSyntax implementation = (PropertyDeclarationSyntax)node; if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); })) { continue; // non-public can't be from an interface } foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value) { if (prototype1.IsKind(SyntaxKind.PropertyDeclaration)) { PropertyDeclarationSyntax prototype = (PropertyDeclarationSyntax)prototype1; // HACK if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier)) { // copy documentation SyntaxNode replacement = node.WithLeadingTrivia( node.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia()))); if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces { replacements.Add(node, replacement); } break; } } } } else { throw new ArgumentException(); } } break; } } } SyntaxNodeReplacementRewriter syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements); root = syntaxNodeReplacementRewriter.Visit(root); // This is probably really slow - but we can use AreEquivalent() since we've only changed trivia targetTypeDeclaration = root.DescendantNodes().First(delegate(SyntaxNode candidate) { return(SyntaxFactory.AreEquivalent(targetTypeDeclaration, candidate)); }); replacements.Clear(); foreach (BaseTypeSyntax baseType in baseTypes) { // can we find an interface that matches this? foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces) { InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key; // hack if (String.Equals(baseType.Type.ToString(), String.Concat(interfaceDeclaration.Identifier.Text, interfaceDeclaration.TypeParameterList != null ? interfaceDeclaration.TypeParameterList.ToString() : null))) { // propagate interface comment to class if (!replacements.ContainsKey(targetTypeDeclaration)) { replacements.Add( targetTypeDeclaration, targetTypeDeclaration.WithLeadingTrivia( targetTypeDeclaration.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(interfaceDeclaration.GetLeadingTrivia())))); } break; } } } syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements); root = syntaxNodeReplacementRewriter.Visit(root); return(root); }
public static SyntaxNode RemoveModifierFromNode(SyntaxNode node, SyntaxKind modifier) { //there seem to be no base classes to support WithModifiers. //dynamic modifiersNode = node; //return modifiersNode.WithModifiers(SyntaxFactory.TokenList(modifiersNode.Modifiers.Where(m => !m.IsKind(SyntaxKind.PrivateKeyword)))); MethodDeclarationSyntax methodNode = node as MethodDeclarationSyntax; if (methodNode != null) { return(methodNode.WithModifiers(SyntaxFactory.TokenList(methodNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(methodNode.GetLeadingTrivia())); } FieldDeclarationSyntax fieldNode = node as FieldDeclarationSyntax; if (fieldNode != null) { return(fieldNode.WithModifiers(SyntaxFactory.TokenList(fieldNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(fieldNode.GetLeadingTrivia())); } PropertyDeclarationSyntax propertyNode = node as PropertyDeclarationSyntax; if (propertyNode != null) { return(propertyNode.WithModifiers(SyntaxFactory.TokenList(propertyNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(propertyNode.GetLeadingTrivia())); } IndexerDeclarationSyntax indexerNode = node as IndexerDeclarationSyntax; if (indexerNode != null) { return(indexerNode.WithModifiers(SyntaxFactory.TokenList(indexerNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(indexerNode.GetLeadingTrivia())); } EventDeclarationSyntax eventNode = node as EventDeclarationSyntax; if (eventNode != null) { return(eventNode.WithModifiers(SyntaxFactory.TokenList(eventNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(eventNode.GetLeadingTrivia())); } ConstructorDeclarationSyntax ctrNode = node as ConstructorDeclarationSyntax; if (ctrNode != null) { return(ctrNode.WithModifiers(SyntaxFactory.TokenList(ctrNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(ctrNode.GetLeadingTrivia())); } OperatorDeclarationSyntax opNode = node as OperatorDeclarationSyntax; if (opNode != null) { return(opNode.WithModifiers(SyntaxFactory.TokenList(opNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(opNode.GetLeadingTrivia())); } ClassDeclarationSyntax classNode = node as ClassDeclarationSyntax; if (classNode != null) { return(classNode.WithModifiers(SyntaxFactory.TokenList(classNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(classNode.GetLeadingTrivia())); } InterfaceDeclarationSyntax interfaceNode = node as InterfaceDeclarationSyntax; if (interfaceNode != null) { return(interfaceNode.WithModifiers(SyntaxFactory.TokenList(interfaceNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(interfaceNode.GetLeadingTrivia())); } StructDeclarationSyntax structNode = node as StructDeclarationSyntax; if (structNode != null) { return(structNode.WithModifiers(SyntaxFactory.TokenList(structNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(structNode.GetLeadingTrivia())); } var enumNode = node as EnumDeclarationSyntax; if (enumNode != null) { return(enumNode.WithModifiers(SyntaxFactory.TokenList(enumNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(enumNode.GetLeadingTrivia())); } var delegateNode = node as DelegateDeclarationSyntax; if (delegateNode != null) { return(delegateNode.WithModifiers(SyntaxFactory.TokenList(delegateNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(delegateNode.GetLeadingTrivia())); } return(node); }
private Interface TraverseInterface(InterfaceDeclarationSyntax ids) { Interface retInterface = new Interface(); if (ids.HasLeadingTrivia) { SetOuterComments(retInterface, ids.GetLeadingTrivia().ToFullString()); } if (ids.HasTrailingTrivia) { SetInnerComments(retInterface, ids.GetTrailingTrivia().ToFullString()); } foreach (SyntaxToken st in ids.Modifiers) { string modifier = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(st.ValueText); Encapsulation encap; Qualifiers qual; if (System.Enum.TryParse<Encapsulation>(modifier, out encap)) { retInterface.Encapsulation.Add(encap); } else if (System.Enum.TryParse<Qualifiers>(modifier, out qual)) { retInterface.Qualifiers.Add(qual); } } var accessVarsDecl = from aAccessVarsDecl in ids.ChildNodes().OfType<LocalDeclarationStatementSyntax>() select aAccessVarsDecl; foreach (LocalDeclarationStatementSyntax ldss in accessVarsDecl) { Method tempMethod = TransverseAccessVars(ldss); retInterface.Fields.AddRange(tempMethod.AccessedVariables); //retInterface.Methods.AddRange(tempMethod.InvokedMethods); } var interfaces = from aInterface in ids.ChildNodes().OfType<InterfaceDeclarationSyntax>() select aInterface; foreach (InterfaceDeclarationSyntax ids2 in interfaces) { Interface tempInterface = TraverseInterface(ids2); retInterface.InheritsInterfaces.Add(tempInterface); } retInterface.Name = ids.Identifier.ValueText; var methods = from aMethod in ids.ChildNodes().OfType<MethodDeclarationSyntax>() select aMethod; foreach (MethodDeclarationSyntax mds in methods) { Method tempMethod = TransverseMethods(mds); retInterface.Fields.AddRange(tempMethod.AccessedVariables); retInterface.Methods.Add(tempMethod); } //public List<string> InheritsStrings { get; set; } //public List<Property> Properties { get; set; } return retInterface; }
public static DocumentedElement LoadFromSyntaxNode(InterfaceDeclarationSyntax node) { SyntaxToken syntaxToken = node.ChildTokens().First(token => token.IsKind(SyntaxKind.IdentifierToken)); return(DocumentedElement.LoadFromSyntaxTokenAndTrivia(syntaxToken, node.GetLeadingTrivia())); }