예제 #1
0
        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);
        }
예제 #2
0
        public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
        {
            if (AttributeMatchUtil.HasTriviaAnnotationSimple(node.GetLeadingTrivia(), WidenAttributeName))
            {
                node = (IdentifierNameSyntax)WidenType(node);
            }

            node = (IdentifierNameSyntax)base.VisitIdentifierName(node);
            return(node);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
        }
예제 #5
0
        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);
        }
예제 #6
0
        // 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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 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);
 }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
 private bool TestConstSubstAttribute(SyntaxList <AttributeListSyntax> attributeLists, out ExpressionSyntax substConst)
 {
     return(AttributeMatchUtil.TestEnumeratedFacetAttribute(attributeLists, out substConst, ConstAttributeAliases, featureFacetAxis));
 }
예제 #14
0
 private bool RemoveBaseType(SimpleBaseTypeSyntax baseType)
 {
     return(!AttributeMatchUtil.TestTriviaAnnotation(baseType.GetLeadingTrivia(), facetAxes));
 }
예제 #15
0
 // 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));
 }
예제 #16
0
 private bool RemoveTestAttributes(SyntaxList <AttributeListSyntax> attributeLists)
 {
     return(AttributeMatchUtil.TestAttributes(attributeLists, facetAxes) == AttributeMatchUtil.FindResult.Exclude);
 }