public override SyntaxNode VisitCastExpression(CastExpressionSyntax node) { // reassociate trivia from cast's enclosing open paren to type expression node = node .WithOpenParenToken( node.OpenParenToken.WithTrailingTrivia(SyntaxTriviaList.Empty)) .WithType( node.Type.WithLeadingTrivia( node.OpenParenToken.TrailingTrivia.AddRange(node.Type.GetLeadingTrivia()))); PredefinedTypeSyntax predefinedType; if ((predefinedType = node.Type as PredefinedTypeSyntax) != null) { if (predefinedType.Keyword.IsKind(SyntaxKind.IntKeyword) || predefinedType.Keyword.IsKind(SyntaxKind.UIntKeyword)) { if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.Type.GetLeadingTrivia(), WidenAttributeName)) { node = node.WithType(WidenType(node.Type)); } } } node = (CastExpressionSyntax)base.VisitCastExpression(node); return(node); }
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), WidenAttributeName)) { node = (IdentifierNameSyntax)WidenType(node); } node = (IdentifierNameSyntax)base.VisitIdentifierName(node); return(node); }
public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { node = (LocalDeclarationStatementSyntax)base.VisitLocalDeclarationStatement(node); if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), CountAttributeName)) { node = node.WithDeclaration(node.Declaration.WithType(NarrowIntegerType(node.Declaration.Type))); } return node; }
public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) { node = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node); if (AttributeMatchUtil.HasAttributeSimple(node.AttributeLists, CountAttributeName)) { node = node.WithDeclaration(node.Declaration.WithType(NarrowIntegerType(node.Declaration.Type))); } return node; }
public override SyntaxNode VisitGenericName(GenericNameSyntax node) { node = node.WithTypeArgumentList((TypeArgumentListSyntax)VisitTypeArgumentList(node.TypeArgumentList)); // Don't call base.VisitGenericName(), since VisitIdentifierName() may double-widen identifier if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), WidenAttributeName)) { node = (GenericNameSyntax)WidenType(node); } return(node); }
// this one does both proper and pseudo attributes public override SyntaxNode VisitParameter(ParameterSyntax node) { // Normal parameter lists use a proper attribute: [Widen] // Anonymous delegate parameter lists do not permit attributes, so must use trivia: /*[Widen]*/ // Therefore, check for both if (AttributeMatchUtil.HasAttributeSimple(node.AttributeLists, WidenAttributeName) || AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), WidenAttributeName)) { node = node.WithType(WidenType(node.Type)); } node = (ParameterSyntax)base.VisitParameter(node); return(node); }
public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { node = (LocalDeclarationStatementSyntax)base.VisitLocalDeclarationStatement(node); if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), WidenAttributeName)) { if (node.Declaration.Type.IsKind(SyntaxKind.PredefinedType)) { node = node.WithDeclaration( node.Declaration.WithType( WidenType(node.Declaration.Type)).WithTriviaFrom(node.Declaration.Type)); } } return(node); }
private bool Rename(SyntaxList <AttributeListSyntax> attributeLists, out ExpressionSyntax newNameStringOut) { foreach (FacetList facetsList in facetAxes) { if (AttributeMatchUtil.TestEnumeratedFacetAttribute( attributeLists, out newNameStringOut, RenameAttributes, facetsList)) { return(true); } } newNameStringOut = null; return(false); }
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { node = (IdentifierNameSyntax)base.VisitIdentifierName(node); ExpressionSyntax newNameString; if (Rename(AttributeMatchUtil.TriviaAnnotationToAttributesList(node.GetLeadingTrivia()), out newNameString)) { string newName = ((LiteralExpressionSyntax)newNameString).Token.Text; if (newName.StartsWith("\"") && newName.EndsWith("\"")) { newName = newName.Substring(1, newName.Length - 2); } node = node.WithIdentifier(SyntaxFactory.Identifier(newName)); } return(node); }
public override SyntaxNode VisitTypeArgumentList(TypeArgumentListSyntax node) { node = (TypeArgumentListSyntax)base.VisitTypeArgumentList(node); int i = 0; foreach (TypeSyntax type in node.Arguments) { if (AttributeMatchUtil.HasTriviaAnnotationSimple(type.GetLeadingTrivia(), WidenAttributeName)) { if ((type is PredefinedTypeSyntax) || (type is GenericNameSyntax)) { node = node.WithArguments( node.Arguments.RemoveAt(i).Insert(i, WidenType(type).WithTriviaFrom(type))); } } i++; } return(node); }
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { if (AttributeMatchUtil.HasAttributeSimple(node.AttributeLists, WidenAttributeName)) { node = node.WithReturnType(WidenType(node.ReturnType)); } if (node.ExplicitInterfaceSpecifier != null) { // reassociate trivia from return type expression to interface type node = node .WithReturnType( node.ReturnType.WithTrailingTrivia(SyntaxTriviaList.Empty)) .WithExplicitInterfaceSpecifier( node.ExplicitInterfaceSpecifier.WithLeadingTrivia( node.ReturnType.GetTrailingTrivia().AddRange(node.ExplicitInterfaceSpecifier.GetLeadingTrivia()))); } node = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node); return(node); }
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); }
private bool TestConstSubstAttribute(SyntaxList <AttributeListSyntax> attributeLists, out ExpressionSyntax substConst) { return(AttributeMatchUtil.TestEnumeratedFacetAttribute(attributeLists, out substConst, ConstAttributeAliases, featureFacetAxis)); }
private bool RemoveBaseType(SimpleBaseTypeSyntax baseType) { return(!AttributeMatchUtil.TestTriviaAnnotation(baseType.GetLeadingTrivia(), facetAxes)); }
// Used for statements - where real attributes are not permitted, a fake attribute in a C-style comment // can be specified. private bool RemoveTestTriviaAnnotation(IEnumerable <SyntaxTrivia> trivia) { return(!AttributeMatchUtil.TestTriviaAnnotation(trivia, facetAxes)); }
private bool RemoveTestAttributes(SyntaxList <AttributeListSyntax> attributeLists) { return(AttributeMatchUtil.TestAttributes(attributeLists, facetAxes) == AttributeMatchUtil.FindResult.Exclude); }