internal SyntaxNode CreateOrdinalMemberAccess(SyntaxGenerator syntaxFactoryService, SemanticModel model)
 {
     var stringComparisonType = WellKnownTypes.StringComparison(model.Compilation);
     return syntaxFactoryService.MemberAccessExpression(
         syntaxFactoryService.TypeExpression(stringComparisonType),
         syntaxFactoryService.IdentifierName(UseOrdinalStringComparisonAnalyzer.OrdinalText));
 }
 private SyntaxNode GetInvertedStatement(
     SyntaxGenerator generator, IMethodSymbol containingOperator, Compilation compilation)
 {
     if (containingOperator.Name == WellKnownMemberNames.EqualityOperatorName)
     {
         return generator.ReturnStatement(
             generator.LogicalNotExpression(
                 generator.ValueEqualsExpression(
                     generator.IdentifierName(containingOperator.Parameters[0].Name),
                     generator.IdentifierName(containingOperator.Parameters[1].Name))));
     }
     else if (containingOperator.Name == WellKnownMemberNames.InequalityOperatorName)
     {
         return generator.ReturnStatement(
             generator.LogicalNotExpression(
                 generator.ValueNotEqualsExpression(
                     generator.IdentifierName(containingOperator.Parameters[0].Name),
                     generator.IdentifierName(containingOperator.Parameters[1].Name))));
     }
     else
     {
         // If it's a  <   >   <=   or  >=   operator then we can't simply invert a call
         // to the existing operator.  i.e. the body of the "<" method should *not* be:
         //    return !(a > b);
         // Just provide a throwing impl for now.
         return generator.DefaultMethodStatement(compilation);
     }
 }
 private Task<Document> AddNonSerializedAttribute(Document document, SemanticModel model, SyntaxNode root, SyntaxNode fieldNode, SyntaxGenerator generator)
 {
     var attr = generator.Attribute(generator.TypeExpression(WellKnownTypes.NonSerializedAttribute(model.Compilation)));
     var newNode = generator.AddAttributes(fieldNode, attr);
     var newDocument = document.WithSyntaxRoot(root.ReplaceNode(fieldNode, newNode));
     return Task.FromResult(newDocument);
 }
 private void AddFix(string codeFixTitle, CodeFixContext context, SyntaxNode root, SyntaxNode classDecl, SyntaxGenerator generator, params string[] languages)
 {
     var fix = new MyCodeAction(
         codeFixTitle,
         c => GetFix(context.Document, root, classDecl, generator, languages));
     context.RegisterCodeFix(fix, context.Diagnostics);
 }
 internal SyntaxNode CreateOrdinalMemberAccess(SyntaxGenerator generator, SemanticModel model)
 {
     INamedTypeSymbol stringComparisonType = WellKnownTypes.StringComparison(model.Compilation);
     return generator.MemberAccessExpression(
         generator.TypeExpression(stringComparisonType),
         generator.IdentifierName(UseOrdinalStringComparisonAnalyzer.OrdinalText));
 }
 protected override async Task<Document> FixEquals(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode node, CancellationToken cancellationToken)
 {
     SemanticModel model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     var binaryExpression = (BinaryExpressionSyntax)node;
     SyntaxNode invocation = CreateEqualsExpression(generator, model, binaryExpression.Left, binaryExpression.Right, node.Kind() == SyntaxKind.EqualsExpression).WithAdditionalAnnotations(Formatter.Annotation);
     SyntaxNode newRoot = root.ReplaceNode(node, invocation);
     return document.WithSyntaxRoot(newRoot);
 }
        public RoslynGenerator(Job job)
        {
            _namespace = job.DestinationNamespace;
            _customAnnotations = job.CustomAnnotations;
            _nullableClasses = job.NullableClasses;

            _workspace = new AdhocWorkspace();
            _generator = SyntaxGenerator.GetGenerator(_workspace, LanguageNames.CSharp);
        }
        private static async Task<Document> Fix(CodeFixContext context, SyntaxNode root, SyntaxGenerator generator, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            SyntaxNode node = root.FindNode(context.Span);
            Diagnostic diagnostic = context.Diagnostics.First();
            switch (diagnostic.Properties[OperatorOverloadsHaveNamedAlternatesAnalyzer.DiagnosticKindText])
            {
                case OperatorOverloadsHaveNamedAlternatesAnalyzer.AddAlternateText:
                    SyntaxNode methodDeclaration = generator.GetDeclaration(node, DeclarationKind.Operator) ?? generator.GetDeclaration(node, DeclarationKind.ConversionOperator);
                    var operatorOverloadSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken);
                    INamedTypeSymbol typeSymbol = operatorOverloadSymbol.ContainingType;

                    // For C# the following `typeDeclarationSyntax` and `typeDeclaration` nodes are identical, but for VB they're different so in
                    // an effort to keep this as language-agnostic as possible, the heavy-handed approach is used.
                    SyntaxNode typeDeclarationSyntax = typeSymbol.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken);
                    SyntaxNode typeDeclaration = generator.GetDeclaration(typeDeclarationSyntax, DeclarationKind.Class);

                    SyntaxNode addedMember;
                    ImmutableArray<SyntaxNode> bodyStatements = ImmutableArray.Create(
                        generator.ThrowStatement(generator.ObjectCreationExpression(semanticModel.Compilation.GetTypeByMetadataName("System.NotImplementedException"))));
                    if (OperatorOverloadsHaveNamedAlternatesAnalyzer.IsPropertyExpected(operatorOverloadSymbol.Name))
                    {
                        // add a property
                        addedMember = generator.PropertyDeclaration(
                            name: OperatorOverloadsHaveNamedAlternatesAnalyzer.IsTrueText,
                            type: generator.TypeExpression(SpecialType.System_Boolean),
                            accessibility: Accessibility.Public,
                            modifiers: DeclarationModifiers.ReadOnly,
                            getAccessorStatements: bodyStatements);
                    }
                    else
                    {
                        // add a method
                        ExpectedMethodSignature expectedSignature = GetExpectedMethodSignature(operatorOverloadSymbol, semanticModel.Compilation);
                        addedMember = generator.MethodDeclaration(
                            name: expectedSignature.Name,
                            parameters: expectedSignature.Parameters.Select(p => generator.ParameterDeclaration(p.Item1, generator.TypeExpression(p.Item2))),
                            returnType: generator.TypeExpression(expectedSignature.ReturnType),
                            accessibility: Accessibility.Public,
                            modifiers: expectedSignature.IsStatic ? DeclarationModifiers.Static : DeclarationModifiers.None,
                            statements: bodyStatements);
                    }

                    SyntaxNode newTypeDeclaration = generator.AddMembers(typeDeclaration, addedMember);
                    return context.Document.WithSyntaxRoot(root.ReplaceNode(typeDeclaration, newTypeDeclaration));
                case OperatorOverloadsHaveNamedAlternatesAnalyzer.FixVisibilityText:
                    SyntaxNode badVisibilityNode = generator.GetDeclaration(node, DeclarationKind.Method) ?? generator.GetDeclaration(node, DeclarationKind.Property);
                    ISymbol badVisibilitySymbol = semanticModel.GetDeclaredSymbol(badVisibilityNode, cancellationToken);
                    SymbolEditor symbolEditor = SymbolEditor.Create(context.Document);
                    ISymbol newSymbol = await symbolEditor.EditOneDeclarationAsync(badVisibilitySymbol,
                        (documentEditor, syntaxNode) => documentEditor.SetAccessibility(badVisibilityNode, Accessibility.Public)).ConfigureAwait(false);
                    Document newDocument = symbolEditor.GetChangedDocuments().Single();
                    SyntaxNode newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                    return context.Document.WithSyntaxRoot(newRoot);
                default:
                    return context.Document;
            }
        }
        private SyntaxNode GetExplicitlyAssignedField(IFieldSymbol originalField, SyntaxNode declaration, SyntaxGenerator generator)
        {
            SyntaxNode originalInitializer = generator.GetExpression(declaration);
            if (originalInitializer != null || !originalField.HasConstantValue)
            {
                return declaration;
            }

            return generator.WithExpression(declaration, generator.LiteralExpression(originalField.ConstantValue));
        }
        private static SyntaxNode RemoveFlagsAttribute(SyntaxGenerator generator, SemanticModel model, SyntaxNode enumTypeSyntax, INamedTypeSymbol flagsAttributeType, CancellationToken cancellationToken)
        {
            var enumType = model.GetDeclaredSymbol(enumTypeSyntax, cancellationToken) as INamedTypeSymbol;
            Debug.Assert(enumType != null);

            AttributeData flagsAttribute = enumType.GetAttributes().First(a => a.AttributeClass == flagsAttributeType);
            SyntaxNode attributeNode = flagsAttribute.ApplicationSyntaxReference.GetSyntax(cancellationToken);

            return generator.RemoveNode(enumTypeSyntax, attributeNode);
        }
        private static async Task<Solution> AddSerializableAttributeToType(Document document, SemanticModel model, SyntaxGenerator generator, ITypeSymbol type, CancellationToken cancellationToken)
        {
            var typeDeclNode = type.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken);

            var serializableAttr = generator.Attribute(generator.TypeExpression(WellKnownTypes.SerializableAttribute(model.Compilation)));
            var newTypeDeclNode = generator.AddAttributes(typeDeclNode, serializableAttr);
            var documentContainingNode = document.Project.Solution.GetDocument(typeDeclNode.SyntaxTree);
            var docRoot = await documentContainingNode.GetSyntaxRootAsync(cancellationToken);
            var newDocumentContainingNode = documentContainingNode.WithSyntaxRoot(docRoot.ReplaceNode(typeDeclNode, newTypeDeclNode));
            return newDocumentContainingNode.Project.Solution;
        }
        public TimeSpanParameterConverter(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator)
        {
            if (semanticModel == null)
            throw new ArgumentNullException("semanticModel", "semanticModel is null.");

             if (syntaxGenerator == null)
            throw new ArgumentNullException("syntaxGenerator", "syntaxGenerator is null.");

             m_syntaxGenerator = syntaxGenerator;
             m_semanticModel = semanticModel;
        }
        protected override Task<Document> FixArgument(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode argument)
        {
            var memberAccess = ((ArgumentSyntax)argument)?.Expression as MemberAccessExpressionSyntax;
            if (memberAccess != null)
            {
                // preserve the "IgnoreCase" suffix if present
                bool isIgnoreCase = memberAccess.Name.GetText().ToString().EndsWith(UseOrdinalStringComparisonAnalyzer.IgnoreCaseText, StringComparison.Ordinal);
                string newOrdinalText = isIgnoreCase ? UseOrdinalStringComparisonAnalyzer.OrdinalIgnoreCaseText : UseOrdinalStringComparisonAnalyzer.OrdinalText;
                SyntaxNode newIdentifier = generator.IdentifierName(newOrdinalText);
                MemberAccessExpressionSyntax newMemberAccess = memberAccess.WithName((SimpleNameSyntax)newIdentifier).WithAdditionalAnnotations(Formatter.Annotation);
                SyntaxNode newRoot = root.ReplaceNode(memberAccess, newMemberAccess);
                return Task.FromResult(document.WithSyntaxRoot(newRoot));
            }

            return Task.FromResult(document);
        }
Beispiel #14
0
        /// <summary>
        /// Creates a new <see cref="SyntaxEditor"/> instance.
        /// </summary>
        public SyntaxEditor(SyntaxNode root, Workspace workspace)
        {
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }

            if (workspace == null)
            {
                throw new ArgumentNullException(nameof(workspace));
            }

            _root = root;
            _generator = SyntaxGenerator.GetGenerator(workspace, root.Language);
            _changes = new List<Change>();
        }
Beispiel #15
0
        protected override SyntaxNode InsertNamespaceImport(SyntaxNode root, SyntaxGenerator gen, SyntaxNode import, OptionSet options)
        {
            var comparer = options.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp)
                    ? UsingsAndExternAliasesDirectiveComparer.SystemFirstInstance
                    : UsingsAndExternAliasesDirectiveComparer.NormalInstance;

            // find insertion point
            foreach (var existingImport in gen.GetNamespaceImports(root))
            {
                if (comparer.Compare(import, existingImport) < 0)
                {
                    return gen.InsertNodesBefore(root, existingImport, new[] { import });
                }
            }

            return gen.AddNamespaceImports(root, import);
        }
        private Task<Document> GetFix(Document document, SyntaxNode root, SyntaxNode classDecl, SyntaxGenerator generator, params string[] languages)
        {
            var languageNamesFullName = typeof(LanguageNames).FullName;
            var arguments = new SyntaxNode[languages.Length];

            for (int i = 0; i < languages.Length; i++)
            {
                var language = languages[i] == LanguageNames.CSharp ? nameof(LanguageNames.CSharp) : nameof(LanguageNames.VisualBasic);
                var expressionToParse = languageNamesFullName + "." + language;
                var parsedExpression = ParseExpression(expressionToParse);
                arguments[i] = generator.AttributeArgument(parsedExpression);
            }

            SyntaxNode attribute = generator.Attribute(DiagnosticAnalyzerCorrectnessAnalyzer.DiagnosticAnalyzerAttributeFullName, arguments);
            var newClassDecl = generator.AddAttributes(classDecl, attribute);
            var newRoot = root.ReplaceNode(classDecl, newClassDecl);
            return Task.FromResult(document.WithSyntaxRoot(newRoot));
        }
        protected override async Task<Document> FixIdentifierName(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode identifier, CancellationToken cancellationToken)
        {
            InvocationExpressionSyntax invokeParent = identifier?.Parent?.FirstAncestorOrSelf<InvocationExpressionSyntax>();
            if (invokeParent != null)
            {
                SemanticModel model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                var methodSymbol = model.GetSymbolInfo((IdentifierNameSyntax)identifier, cancellationToken).Symbol as IMethodSymbol;
                if (methodSymbol != null && CanAddStringComparison(methodSymbol, model))
                {
                    // append a new StringComparison.Ordinal argument
                    SyntaxNode newArg = generator.Argument(CreateOrdinalMemberAccess(generator, model))
                        .WithAdditionalAnnotations(Formatter.Annotation);
                    InvocationExpressionSyntax newInvoke = invokeParent.AddArgumentListArguments((ArgumentSyntax)newArg).WithAdditionalAnnotations(Formatter.Annotation);
                    SyntaxNode newRoot = root.ReplaceNode(invokeParent, newInvoke);
                    return document.WithSyntaxRoot(newRoot);
                }
            }

            return document;
        }
		public static SyntaxNode GenerateThrowStatement(
			SyntaxGenerator factory,
			SemanticDocument document,
			string exceptionMetadataName,
			CancellationToken cancellationToken)
		{
			var compilation = document.SemanticModel.Compilation;
			var exceptionType = compilation.GetTypeByMetadataName(exceptionMetadataName);

			// If we can't find the Exception, we obviously can't generate anything.
			if (exceptionType == null)
			{
				return null;
			}

			var exceptionCreationExpression = factory.ObjectCreationExpression(
				exceptionType,
				SpecializedCollections.EmptyList<SyntaxNode>());

			return factory.ThrowStatement(exceptionCreationExpression);
		}
        internal SyntaxNode CreateEqualsExpression(SyntaxGenerator syntaxFactoryService, SemanticModel model, SyntaxNode operand1, SyntaxNode operand2, bool isEquals)
        {
            var stringType = model.Compilation.GetSpecialType(SpecialType.System_String);
            var memberAccess = syntaxFactoryService.MemberAccessExpression(
                        syntaxFactoryService.TypeExpression(stringType),
                        syntaxFactoryService.IdentifierName(UseOrdinalStringComparisonAnalyzer.EqualsMethodName));
            var ordinal = CreateOrdinalMemberAccess(syntaxFactoryService, model);
            var invocation = syntaxFactoryService.InvocationExpression(
                memberAccess,
                operand1,
                operand2.WithoutTrailingTrivia(),
                ordinal)
                .WithAdditionalAnnotations(Formatter.Annotation);
            if (!isEquals)
            {
                invocation = syntaxFactoryService.LogicalNotExpression(invocation);
            }

            invocation = invocation.WithTrailingTrivia(operand2.GetTrailingTrivia());

            return invocation;
        }
      public InterfaceDeclarationSyntax GenerateProxyInterface(SemanticModel semanticModel, SyntaxGenerator generator, INamedTypeSymbol sourceServiceInterface, string targetInterfaceName, Accessibility accessibility = Accessibility.Public, bool inheritServiceInterface = false, bool suppressAsyncMethodGeneration = false, bool suppressWarningComments = false)
      {
         SyntaxNode targetInterface = generator.InterfaceDeclaration(targetInterfaceName, accessibility: accessibility);

         targetInterface = generator.AddAttributes(targetInterface, sourceServiceInterface.GetAttributes().Select(attr => generator.Attribute(attr)));

         foreach (SyntaxNode method in GetOperationContractMethodDeclarations(semanticModel, generator, sourceServiceInterface, true, !inheritServiceInterface, suppressAsyncMethodGeneration))
         {
            targetInterface = generator.AddMembers(targetInterface, generator.AddWarningCommentIf(!suppressWarningComments, method));
         }

         if (inheritServiceInterface)
         {
            targetInterface = generator.AddInterfaceType(targetInterface, generator.TypeExpression(sourceServiceInterface));
         }

         targetInterface = AddGeneratedCodeAttribute(generator, targetInterface);

         targetInterface = generator.AddWarningCommentIf(!suppressWarningComments, targetInterface);

         return (InterfaceDeclarationSyntax)targetInterface;
      }
Beispiel #21
0
 public static ImmutableArray <SyntaxNode> CreateThrowNotImplementedStatementBlock(
     this SyntaxGenerator codeDefinitionFactory, Compilation compilation)
 => ImmutableArray.Create(CreateThrowNotImplementedStatement(codeDefinitionFactory, compilation));
Beispiel #22
0
 private protected override SyntaxNode Build(SyntaxGenerator generator)
 => generator.ArrayTypeExpression(Type.BuildInternal(generator));
Beispiel #23
0
        private (ImmutableArray <SyntaxNode> imports, IEnumerable <INamespaceSymbol> namespaceSymbols, SyntaxNode?context) GetImportDirectivesFromSyntaxes(
            IEnumerable <SyntaxNode> syntaxNodes,
            ref SyntaxNode root,
            SemanticModel model,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            CancellationToken cancellationToken
            )
        {
            var importsToAdd = ArrayBuilder <SyntaxNode> .GetInstance();

            var nodesWithExplicitNamespaces = syntaxNodes
                                              .Select(n => (syntaxnode: n, namespaceSymbol: GetExplicitNamespaceSymbol(n, model)))
                                              .Where(x => x.namespaceSymbol != null);

            using var _ = ArrayBuilder <SyntaxNode> .GetInstance(out var nodesToSimplify);

            var addedSymbols = new HashSet <INamespaceSymbol>();

            foreach (var(node, namespaceSymbol) in nodesWithExplicitNamespaces)
            {
                cancellationToken.ThrowIfCancellationRequested();

                nodesToSimplify.Add(node);

                if (addedSymbols.Contains(namespaceSymbol))
                {
                    continue;
                }

                var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);

                if (addImportsService.HasExistingImport(model.Compilation, root, node, namespaceSyntax, generator))
                {
                    continue;
                }

                if (IsInsideNamespace(node, namespaceSymbol, model, cancellationToken))
                {
                    continue;
                }

                addedSymbols.Add(namespaceSymbol);
                importsToAdd.Add(namespaceSyntax);
            }

            if (nodesToSimplify.Count == 0)
            {
                return(importsToAdd.ToImmutableAndFree(), addedSymbols, null);
            }

            var annotation = new SyntaxAnnotation();

            root = root.ReplaceNodes(
                nodesToSimplify,
                (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation, annotation));

            var first = root.DescendantNodesAndSelf().First(x => x.HasAnnotation(annotation));
            var last  = root.DescendantNodesAndSelf().Last(x => x.HasAnnotation(annotation));

            return(importsToAdd.ToImmutableAndFree(), addedSymbols, first.GetCommonRoot(last));
        }
Beispiel #24
0
 public CloneMappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, IAssemblySymbol contextAssembly)
     : base(semanticModel, syntaxGenerator, contextAssembly)
 {
 }
Beispiel #25
0
        public static (string name, SyntaxNode syntax) CreateProxy(ImmutableArray <ITypeSymbol> types, SyntaxGenerator generator)
        {
            var name = GetProxyName(types);

            var(baseType, interfaceTypes) = ValidateTypes(types);
            var syntax = generator.CompilationUnit(types
                                                   .Where(x => x.ContainingNamespace != null && x.ContainingNamespace.CanBeReferencedByName)
                                                   .Select(x => x.ContainingNamespace.ToDisplayString())
                                                   .Concat(new[]
            {
                typeof(EventArgs).Namespace,
                typeof(ObservableCollection <>).Namespace,
                typeof(MethodBase).Namespace,
                typeof(IProxy).Namespace,
                typeof(CompilerGeneratedAttribute).Namespace,
            })
                                                   .Distinct()
                                                   .Select(x => generator.NamespaceImportDeclaration(x))
                                                   .Concat(new[]
            {
                generator.NamespaceDeclaration(ProxyFactory.ProxyNamespace,
                                               generator.AddAttributes(
                                                   generator.ClassDeclaration(name,
                                                                              accessibility: Accessibility.Public,
                                                                              modifiers: DeclarationModifiers.Partial,
                                                                              baseType: baseType == null ? null : generator.IdentifierName(baseType.Name),
                                                                              interfaceTypes: interfaceTypes.Select(x => generator.IdentifierName(x.Name))),
                                                   generator.Attribute("CompilerGenerated")
                                                   )
                                               )
            }));

            return(name, syntax);
        }
Beispiel #26
0
        private static async Task <Document> Fix(CodeFixContext context, SyntaxNode root, SyntaxGenerator generator, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            SyntaxNode node       = root.FindNode(context.Span);
            Diagnostic diagnostic = context.Diagnostics.First();

            switch (diagnostic.Properties[OperatorOverloadsHaveNamedAlternatesAnalyzer.DiagnosticKindText])
            {
            case OperatorOverloadsHaveNamedAlternatesAnalyzer.AddAlternateText:
                SyntaxNode       methodDeclaration      = generator.GetDeclaration(node, DeclarationKind.Operator) ?? generator.GetDeclaration(node, DeclarationKind.ConversionOperator);
                var              operatorOverloadSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken);
                INamedTypeSymbol typeSymbol             = operatorOverloadSymbol.ContainingType;

                // For C# the following `typeDeclarationSyntax` and `typeDeclaration` nodes are identical, but for VB they're different so in
                // an effort to keep this as language-agnostic as possible, the heavy-handed approach is used.
                SyntaxNode typeDeclarationSyntax = typeSymbol.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken);
                SyntaxNode typeDeclaration       = generator.GetDeclaration(typeDeclarationSyntax, DeclarationKind.Class);

                SyntaxNode addedMember;
                ImmutableArray <SyntaxNode> bodyStatements = ImmutableArray.Create(
                    generator.ThrowStatement(generator.ObjectCreationExpression(semanticModel.Compilation.GetTypeByMetadataName("System.NotImplementedException"))));
                if (OperatorOverloadsHaveNamedAlternatesAnalyzer.IsPropertyExpected(operatorOverloadSymbol.Name))
                {
                    // add a property
                    addedMember = generator.PropertyDeclaration(
                        name: OperatorOverloadsHaveNamedAlternatesAnalyzer.IsTrueText,
                        type: generator.TypeExpression(SpecialType.System_Boolean),
                        accessibility: Accessibility.Public,
                        modifiers: DeclarationModifiers.ReadOnly,
                        getAccessorStatements: bodyStatements);
                }
                else
                {
                    // add a method
                    ExpectedMethodSignature expectedSignature = GetExpectedMethodSignature(operatorOverloadSymbol, semanticModel.Compilation);
                    addedMember = generator.MethodDeclaration(
                        name: expectedSignature.Name,
                        parameters: expectedSignature.Parameters.Select(p => generator.ParameterDeclaration(p.Item1, generator.TypeExpression(p.Item2))),
                        returnType: generator.TypeExpression(expectedSignature.ReturnType),
                        accessibility: Accessibility.Public,
                        modifiers: expectedSignature.IsStatic ? DeclarationModifiers.Static : DeclarationModifiers.None,
                        statements: bodyStatements);
                }

                SyntaxNode newTypeDeclaration = generator.AddMembers(typeDeclaration, addedMember);
                return(context.Document.WithSyntaxRoot(root.ReplaceNode(typeDeclaration, newTypeDeclaration)));

            case OperatorOverloadsHaveNamedAlternatesAnalyzer.FixVisibilityText:
                SyntaxNode   badVisibilityNode   = generator.GetDeclaration(node, DeclarationKind.Method) ?? generator.GetDeclaration(node, DeclarationKind.Property);
                ISymbol      badVisibilitySymbol = semanticModel.GetDeclaredSymbol(badVisibilityNode, cancellationToken);
                SymbolEditor symbolEditor        = SymbolEditor.Create(context.Document);
                ISymbol      newSymbol           = await symbolEditor.EditOneDeclarationAsync(badVisibilitySymbol,
                                                                                              (documentEditor, syntaxNode) => documentEditor.SetAccessibility(badVisibilityNode, Accessibility.Public)).ConfigureAwait(false);

                Document   newDocument = symbolEditor.GetChangedDocuments().Single();
                SyntaxNode newRoot     = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                return(context.Document.WithSyntaxRoot(newRoot));

            default:
                return(context.Document);
            }
        }
 protected abstract Task <Document> FixIdentifierName(Document document, SyntaxGenerator syntaxFactoryService, SyntaxNode root, SyntaxNode identifier, CancellationToken cancellationToken);
            //creates the open parenthesis statement
            internal static SyntaxNode CreateOpenParen(SyntaxGenerator generator, string expressionString)
            {
                string name = "openParen";

                var expression = generator.IdentifierName(expressionString);

                var initializer = generator.MemberAccessExpression(expression, "OpenParenToken");
                SyntaxNode localDeclaration = generator.LocalDeclarationStatement(name, initializer);

                return localDeclaration;
            }
            //creates the diagnostic span statement
            internal static SyntaxNode CreateSpan(SyntaxGenerator generator, string startIdentifier, string endIdentifier)
            {
                string name = "diagnosticSpan";
                SyntaxNode memberIdentifier = generator.IdentifierName("TextSpan");
                SyntaxNode memberName = generator.IdentifierName("FromBounds");
                SyntaxNode expression = generator.MemberAccessExpression(memberIdentifier, memberName);

                SyntaxList<SyntaxNode> arguments = new SyntaxList<SyntaxNode>();

                var startSpanIdentifier = generator.IdentifierName(startIdentifier);
                var endSpanIdentifier = generator.IdentifierName(endIdentifier);

                arguments = arguments.Add(startSpanIdentifier);
                arguments = arguments.Add(endSpanIdentifier);

                SyntaxNode initializer = generator.InvocationExpression(expression, arguments);
                SyntaxNode localDeclaration = generator.LocalDeclarationStatement(name, initializer);

                return localDeclaration;
            }
        private static async Task <Document> AddConstructorsAsync(Document document, IEnumerable <Diagnostic> diagnostics, SyntaxNode root, CancellationToken cancellationToken)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            SyntaxGenerator generator = editor.Generator;
            SemanticModel   model     = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            CodeAnalysis.Text.TextSpan diagnosticSpan = diagnostics.First().Location.SourceSpan; // All the diagnostics are reported at the same location -- the name of the declared class -- so it doesn't matter which one we pick
            SyntaxNode node       = root.FindNode(diagnosticSpan);
            SyntaxNode targetNode = editor.Generator.GetDeclaration(node, DeclarationKind.Class);
            var        typeSymbol = model.GetDeclaredSymbol(targetNode) as INamedTypeSymbol;

            foreach (Diagnostic diagnostic in diagnostics)
            {
                var missingCtorSignature = (ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature)Enum.Parse(typeof(ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature), diagnostic.Properties["Signature"]);

                switch (missingCtorSignature)
                {
                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithNoParameter:
                    // Add missing CtorWithNoParameter
                    SyntaxNode newConstructorNode1 = generator.ConstructorDeclaration(typeSymbol.Name, accessibility: Accessibility.Public);
                    editor.AddMember(targetNode, newConstructorNode1);
                    break;

                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithStringParameter:
                    // Add missing CtorWithStringParameter
                    SyntaxNode newConstructorNode2 = generator.ConstructorDeclaration(
                        containingTypeName: typeSymbol.Name,
                        parameters: new[]
                    {
                        generator.ParameterDeclaration("message", generator.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_String)))
                    },
                        accessibility: Accessibility.Public,
                        baseConstructorArguments: new[]
                    {
                        generator.Argument(generator.IdentifierName("message"))
                    });
                    editor.AddMember(targetNode, newConstructorNode2);
                    break;

                case ImplementStandardExceptionConstructorsAnalyzer.MissingCtorSignature.CtorWithStringAndExceptionParameters:
                    // Add missing CtorWithStringAndExceptionParameters
                    SyntaxNode newConstructorNode3 = generator.ConstructorDeclaration(
                        containingTypeName: typeSymbol.Name,
                        parameters: new[]
                    {
                        generator.ParameterDeclaration("message", generator.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_String))),
                        generator.ParameterDeclaration("innerException", generator.TypeExpression(editor.SemanticModel.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemException)))
                    },
                        accessibility: Accessibility.Public,
                        baseConstructorArguments: new[]
                    {
                        generator.Argument(generator.IdentifierName("message")),
                        generator.Argument(generator.IdentifierName("innerException"))
                    });
                    editor.AddMember(targetNode, newConstructorNode3);
                    break;
                }
            }

            return(editor.GetChangedDocument());
        }
Beispiel #31
0
 public MappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator)
 {
     this.semanticModel   = semanticModel;
     this.syntaxGenerator = syntaxGenerator;
 }
Beispiel #32
0
        public static SyntaxNode GenerateUnderscoreNameConst(this SyntaxGenerator g, string name)
        {
            var type = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword));

            return(g.FieldDeclaration("_" + name, type, Accessibility.Friend, DeclarationModifiers.Const, g.NameOfExpression(g.IdentifierName(name))));
        }
Beispiel #33
0
        private (ImmutableArray <SyntaxNode> imports, IEnumerable <INamespaceSymbol> namespaceSymbols, SyntaxNode?context) GetImportDirectivesFromAnnotatedNodes(
            IEnumerable <SyntaxNode> syntaxNodes,
            SyntaxNode root,
            SemanticModel model,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            CancellationToken cancellationToken)
        {
            (SyntaxNode first, SyntaxNode last)? nodes = null;
            var importsToAdd = ArrayBuilder <SyntaxNode> .GetInstance();

            var annotatedNodes = syntaxNodes.Where(x => x.HasAnnotations(SymbolAnnotation.Kind));
            var addedSymbols   = new HashSet <INamespaceSymbol>();

            foreach (var annotatedNode in annotatedNodes)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (annotatedNode.GetAnnotations(DoNotAddImportsAnnotation.Kind).Any())
                {
                    continue;
                }

                var annotations = annotatedNode.GetAnnotations(SymbolAnnotation.Kind);
                foreach (var annotation in annotations)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    foreach (var namedType in SymbolAnnotation.GetSymbols(annotation, model.Compilation).OfType <INamedTypeSymbol>())
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (namedType.OriginalDefinition.IsSpecialType() || namedType.IsNullable() || namedType.IsTupleType)
                        {
                            continue;
                        }

                        var namespaceSymbol = namedType.ContainingNamespace;
                        if (namespaceSymbol is null || namespaceSymbol.IsGlobalNamespace)
                        {
                            continue;
                        }

                        nodes = (first : nodes?.first ?? annotatedNode, last : annotatedNode);

                        if (addedSymbols.Contains(namespaceSymbol))
                        {
                            continue;
                        }

                        var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);

                        if (addImportsService.HasExistingImport(model.Compilation, root, annotatedNode, namespaceSyntax, generator))
                        {
                            continue;
                        }

                        if (IsInsideNamespace(annotatedNode, namespaceSymbol, model, cancellationToken))
                        {
                            continue;
                        }

                        addedSymbols.Add(namespaceSymbol);
                        importsToAdd.Add(namespaceSyntax);
                    }
                }
            }

            // we don't add simplifier annotations here,
            // since whatever added the symbol annotation probably also added simplifier annotations,
            // and if not they probably didn't for a reason

            return(importsToAdd.ToImmutableAndFree(), addedSymbols, nodes is var(first, last) ? first.GetCommonRoot(last) : null);
        }
            internal static SyntaxNode CreateDiagnosticReport(SyntaxGenerator generator, string argumentName, string contextName)
            {
                var argumentExpression = generator.IdentifierName(argumentName);
                var argument = generator.Argument(argumentExpression);

                var identifier = generator.IdentifierName(contextName);
                var memberExpression = generator.MemberAccessExpression(identifier, "ReportDiagnostic");
                var expression = generator.InvocationExpression(memberExpression, argument);

                SyntaxNode expressionStatement = generator.ExpressionStatement(expression);
                return expressionStatement;
            }
 protected abstract Task <Document> FixEquals(Document document, SyntaxGenerator syntaxFactoryService, SyntaxNode root, SyntaxNode node, CancellationToken cancellationToken);
            internal static PropertyDeclarationSyntax CreateSupportedDiagnostics(SyntaxGenerator generator, INamedTypeSymbol notImplementedException)
            {
                var type = SyntaxFactory.ParseTypeName("ImmutableArray<DiagnosticDescriptor>");
                var modifiers = DeclarationModifiers.Override;

                SyntaxList<SyntaxNode> getAccessorStatements = new SyntaxList<SyntaxNode>();

                SyntaxNode throwStatement = generator.ThrowStatement(generator.ObjectCreationExpression(notImplementedException));
                getAccessorStatements = getAccessorStatements.Add(throwStatement);

                var propertyDeclaration = generator.PropertyDeclaration("SupportedDiagnostics", type, accessibility: Accessibility.Public, modifiers: modifiers, getAccessorStatements: getAccessorStatements) as PropertyDeclarationSyntax;
                propertyDeclaration = propertyDeclaration.RemoveNode(propertyDeclaration.AccessorList.Accessors[1], 0);

                return propertyDeclaration;
            }
 protected abstract Task <Document> FixArgument(Document document, SyntaxGenerator syntaxFactoryService, SyntaxNode root, SyntaxNode argument);
Beispiel #38
0
 internal virtual SyntaxNode WrapBuild(SyntaxGenerator generator, SyntaxNode on_false)
 => generator.IfStatement(condition.BuildInternal(generator), BuildTrue(generator), on_false);
Beispiel #39
0
        /// <inheritdoc />
        public SyntaxNode GenerateConfigureBehavior(
            ILogSink logSink,
            SyntaxGenerator syntaxGenerator,
            SemanticModel semanticModel,
            ISymbol symbol)
        {
            logSink.Debug(logSource, "Considering symbol '{0}'.", symbol);

            var propertySymbol = symbol as IPropertySymbol;
            var methodSymbol   = symbol as IMethodSymbol;

            INamedTypeSymbol returnType = null;

            if (propertySymbol != null)
            {
                if (propertySymbol.GetMethod == null)
                {
                    logSink.Debug(logSource, "Ignoring symbol '{0}' because it is a write-only property.", symbol);
                    return(null);
                }

                returnType = propertySymbol.GetMethod.ReturnType as INamedTypeSymbol;
            }
            else if (methodSymbol != null)
            {
                if (methodSymbol.AssociatedSymbol != null)
                {
                    logSink.Debug(logSource, "Ignoring symbol '{0}' because it is a method with an associated symbol.", symbol);
                    return(null);
                }

                if (methodSymbol.IsGenericMethod)
                {
                    logSink.Debug(logSource, "Ignoring symbol '{0}' because it is a generic method.", symbol);
                    return(null);
                }

                returnType = methodSymbol.ReturnType as INamedTypeSymbol;
            }
            else
            {
                logSink.Debug(logSource, "Ignoring symbol '{0}' because it is neither a property nor a method.", symbol);
                return(null);
            }

            if (returnType == null)
            {
                logSink.Warn(logSource, "Ignoring symbol '{0}' because its return type could not be determined (it's probably a generic).", symbol);
                return(null);
            }

            if (!returnType.IsGenericType)
            {
                logSink.Debug(logSource, "Ignoring symbol '{0}' because its return type is not a generic type, so it cannot be one of the supported collection types.");
                return(null);
            }

            SyntaxNode returnValueSyntax;

            if (!TryGetReturnValueSyntaxForEnumerableReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForCollectionReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForDictionaryReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForSetReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForImmutableListReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForImmutableDictionaryReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForImmutableQueueReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForImmutableSetReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax) &&
                !TryGetReturnValueSyntaxForImmutableStackReturnType(logSink, syntaxGenerator, semanticModel, returnType, out returnValueSyntax))
            {
                logSink.Debug(logSource, "Ignoring symbol '{0}' because it does not return a supported collection type.", symbol);
                return(null);
            }

            var itType = semanticModel
                         .Compilation
                         .GetTypeByMetadataName("PCLMock.It");

            if (itType == null)
            {
                logSink.Error(logSource, "Failed to resolve It class.");
                return(null);
            }

            var isAnyMethod = itType
                              .GetMembers("IsAny")
                              .Single();

            if (isAnyMethod == null)
            {
                logSink.Error(logSource, "Failed to resolve IsAny method.");
                return(null);
            }

            var lambdaParameterName = symbol.GetUniqueName();

            SyntaxNode lambdaExpression;

            if (propertySymbol != null)
            {
                if (!propertySymbol.IsIndexer)
                {
                    // GENERATED CODE:
                    //
                    //     this
                    //         .When(x => x.SymbolName)
                    //         .Return(returnValueSyntax);
                    lambdaExpression = syntaxGenerator.MemberAccessExpression(
                        syntaxGenerator.IdentifierName(lambdaParameterName),
                        propertySymbol.Name);
                }
                else
                {
                    // GENERATED CODE:
                    //
                    //     this
                    //         .When(x => x[It.IsAny<P1>(), It.IsAny<P2>() ...)
                    //         .Return(returnValueSyntax);
                    var whenArguments = propertySymbol
                                        .Parameters
                                        .Select(
                        parameter =>
                        syntaxGenerator.InvocationExpression(
                            syntaxGenerator.MemberAccessExpression(
                                syntaxGenerator.TypeExpression(itType),
                                syntaxGenerator.GenericName(
                                    "IsAny",
                                    typeArguments: new[]
                    {
                        parameter.Type
                    }))));

                    lambdaExpression = syntaxGenerator.ElementAccessExpression(
                        syntaxGenerator.IdentifierName(lambdaParameterName),
                        arguments: whenArguments);
                }
            }
            else
            {
                // GENERATED CODE:
                //
                //     this
                //         .When(x => x.SymbolName(It.IsAny<P1>(), It.IsAny<P2>() ...)
                //         .Return(returnValueSyntax);
                var whenArguments = methodSymbol
                                    .Parameters
                                    .Select(
                    parameter =>
                    syntaxGenerator.InvocationExpression(
                        syntaxGenerator.MemberAccessExpression(
                            syntaxGenerator.TypeExpression(itType),
                            syntaxGenerator.GenericName(
                                "IsAny",
                                typeArguments: new[]
                {
                    parameter.Type
                }))));

                lambdaExpression = syntaxGenerator.InvocationExpression(
                    syntaxGenerator.MemberAccessExpression(
                        syntaxGenerator.IdentifierName(lambdaParameterName),
                        methodSymbol.Name),
                    arguments: whenArguments);
            }

            var whenLambdaArgument = syntaxGenerator.ValueReturningLambdaExpression(
                lambdaParameterName,
                lambdaExpression);

            var whenInvocation = syntaxGenerator.InvocationExpression(
                syntaxGenerator.MemberAccessExpression(
                    syntaxGenerator.ThisExpression(),
                    syntaxGenerator.IdentifierName("When")),
                whenLambdaArgument);

            var result = syntaxGenerator.ExpressionStatement(
                syntaxGenerator.InvocationExpression(
                    syntaxGenerator.MemberAccessExpression(
                        whenInvocation,
                        syntaxGenerator.IdentifierName("Return")),
                    arguments: new[]
            {
                returnValueSyntax
            }));

            return(result);
        }
Beispiel #40
0
 private static RangeExpressionSyntax CreateRangeExpression(Result result, SyntaxGenerator generator)
 => result.Kind switch
 {
 protected abstract TLocalDeclarationStatementSyntax GetUpdatedLocalDeclarationStatement(SyntaxGenerator generator, TLocalDeclarationStatementSyntax localDeclarationStatement, ILocalSymbol symbol);
Beispiel #42
0
 private protected override SyntaxNode Build(SyntaxGenerator generator)
 => generator.IfStatement(condition.BuildInternal(generator), BuildTrue(generator));
            internal static SyntaxNode CreateRegister(SyntaxGenerator generator, MethodDeclarationSyntax declaration, string methodName)
            {
                SyntaxNode argument1 = generator.IdentifierName(methodName);
                SyntaxNode argument2 = generator.MemberAccessExpression(generator.IdentifierName("SyntaxKind"), "IfStatement");
                SyntaxList<SyntaxNode> arguments = new SyntaxList<SyntaxNode>().Add(argument1).Add(argument2);

                SyntaxNode expression = generator.IdentifierName(declaration.ParameterList.Parameters[0].Identifier.ValueText);
                SyntaxNode memberAccessExpression = generator.MemberAccessExpression(expression, "RegisterSyntaxNodeAction");
                SyntaxNode invocationExpression = generator.InvocationExpression(memberAccessExpression, arguments);

                return invocationExpression;
            }
Beispiel #44
0
 private SyntaxNode GenerateNamespaceImportDeclaration(INamespaceSymbol namespaceSymbol, SyntaxGenerator generator)
 {
     // We add Simplifier.Annotation so that the import can be removed if it turns out to be unnecessary.
     // This can happen for a number of reasons (we replace the type with var, inbuilt type, alias, etc.)
     return(generator
            .NamespaceImportDeclaration(namespaceSymbol.ToDisplayString(SymbolDisplayFormats.NameFormat))
            .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation));
 }
Beispiel #45
0
 internal virtual SyntaxNode BuildWithElse(SyntaxGenerator generator, IEnumerable <Statement> on_false)
 => generator.IfStatement(condition.BuildInternal(generator), BuildTrue(generator), BuildMany(generator, on_false));
Beispiel #46
0
 // C# doesn't have global imports.
 protected override ImmutableArray <SyntaxNode> GetGlobalImports(
     Compilation compilation,
     SyntaxGenerator generator
     ) => ImmutableArray <SyntaxNode> .Empty;
Beispiel #47
0
 private protected IEnumerable <SyntaxNode> BuildTrue(SyntaxGenerator generator)
 => BuildMany(generator, if_true);
Beispiel #48
0
 public static ImmutableArray <SyntaxNode> CreateArguments(
     this SyntaxGenerator factory,
     ImmutableArray <IParameterSymbol> parameters)
 {
     return(parameters.SelectAsArray(p => CreateArgument(factory, p)));
 }
        public async Task <IReadOnlyList <MappingMatch> > MatchAll(IReadOnlyCollection <IObjectField> targets, SyntaxGenerator syntaxGenerator, MappingContext mappingContext, SyntaxNode globalTargetAccessor = null)
        {
            var results = new List <MappingMatch>(targets.Count);

            foreach (var target in targets)
            {
                results.Add(new MappingMatch
                {
                    Source = await sourceFinder.FindMappingSource(target.Name, target.Type, mappingContext).ConfigureAwait(false),
                    Target = CreateTargetElement(globalTargetAccessor, target, syntaxGenerator)
                });
            }

            return(results.Where(x => x.Source != null).ToList());
        }
Beispiel #50
0
 private static SyntaxNode CreateArgument(
     this SyntaxGenerator factory,
     IParameterSymbol parameter)
 {
     return(factory.Argument(parameter.RefKind, factory.IdentifierName(parameter.Name)));
 }
            //creates an end or start span statement
            internal static SyntaxNode CreateEndOrStartSpan(SyntaxGenerator generator, string identifierString, string variableName)
            {
                SyntaxNode identifier = generator.IdentifierName(identifierString);

                SyntaxNode initializer = generator.MemberAccessExpression(identifier, "SpanStart");

                SyntaxNode localDeclaration = generator.LocalDeclarationStatement(variableName, initializer);

                return localDeclaration;
            }
 private MappingElement CreateTargetElement(SyntaxNode globalTargetAccessor, IObjectField target, SyntaxGenerator syntaxGenerator)
 {
     return(new MappingElement
     {
         Expression = (ExpressionSyntax)CreateAccessPropertyExpression(globalTargetAccessor, target, syntaxGenerator),
         ExpressionType = target.Type
     });
 }
            internal static SyntaxNode CreateDiagnostic(SyntaxGenerator generator, string locationName, string ruleName)
            {
                var identifier = generator.IdentifierName("Diagnostic");
                var expression = generator.MemberAccessExpression(identifier, "Create");

                SyntaxList<SyntaxNode> arguments = new SyntaxList<SyntaxNode>();

                var ruleExpression = generator.IdentifierName(ruleName);
                var ruleArg = generator.Argument(ruleExpression);

                var locationExpression = generator.IdentifierName(locationName);
                var locationArg = generator.Argument(locationExpression);

                arguments = arguments.Add(ruleArg);
                arguments = arguments.Add(locationArg);

                string name = "diagnostic";
                var initializer = generator.InvocationExpression(expression, arguments);
                SyntaxNode localDeclaration = generator.LocalDeclarationStatement(name, initializer);

                return localDeclaration;
            }
 private static SyntaxNode CreateAccessPropertyExpression(SyntaxNode globalTargetAccessor, IObjectField property, SyntaxGenerator generator)
 {
     if (globalTargetAccessor == null)
     {
         return(SyntaxFactory.IdentifierName(property.Name));
     }
     return(generator.MemberAccessExpression(globalTargetAccessor, property.Name));
 }
            internal static FieldDeclarationSyntax CreateEmptyRule(SyntaxGenerator generator, string idName="Change me to the name of the above constant", string titleDefault="Enter a title for this diagnostic", string messageDefault="Enter a message to be displayed with this diagnostic",
                                                                    string categoryDefault="Enter a category for this diagnostic (e.g. Formatting)", ExpressionSyntax severityDefault=null, ExpressionSyntax enabledDefault=null)
            {
                if (severityDefault == null)
                {
                    severityDefault = generator.DefaultExpression(SyntaxFactory.ParseTypeName("DiagnosticSeverity")) as ExpressionSyntax;
                }

                if (enabledDefault == null)
                {
                    enabledDefault = generator.DefaultExpression(generator.TypeExpression(SpecialType.System_Boolean)) as ExpressionSyntax;
                }

                var type = SyntaxFactory.ParseTypeName("DiagnosticDescriptor");

                var arguments = new ArgumentSyntax[6];
                var whitespace = "            ";

                var id = generator.LiteralExpression(idName);
                var idArg = generator.Argument("id", RefKind.None, id).WithLeadingTrivia(SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[0] = idArg;

                var title = generator.LiteralExpression(titleDefault);
                var titleArg = generator.Argument("title", RefKind.None, title).WithLeadingTrivia(SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[1] = titleArg;

                var message = generator.LiteralExpression(messageDefault);
                var messageArg = generator.Argument("messageFormat", RefKind.None, message).WithLeadingTrivia(SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[2] = messageArg;

                var category = generator.LiteralExpression(categoryDefault);
                var categoryArg = generator.Argument("category", RefKind.None, category).WithLeadingTrivia(SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[3] = categoryArg;

                var defaultSeverityArg = generator.Argument("defaultSeverity", RefKind.None, severityDefault).WithLeadingTrivia(SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[4] = defaultSeverityArg;

                var enabledArg = generator.Argument("isEnabledByDefault", RefKind.None, enabledDefault).WithLeadingTrivia(SyntaxFactory.Whitespace(whitespace)) as ArgumentSyntax;
                arguments[5] = enabledArg;
                
                var identifier = SyntaxFactory.ParseToken("spacingRule");

                var separators = new List<SyntaxToken>();
                var separator = SyntaxFactory.ParseToken(",").WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
                separators.Add(separator);
                separators.Add(separator);
                separators.Add(separator);
                separators.Add(separator);
                separators.Add(separator);

                var argumentsNewLines = SyntaxFactory.SeparatedList(arguments, separators);
                var argumentList = SyntaxFactory.ArgumentList(argumentsNewLines);
                var value = SyntaxFactory.ObjectCreationExpression(type, argumentList, null);
                var initializer = SyntaxFactory.EqualsValueClause(value);
                

                var variables = new SeparatedSyntaxList<VariableDeclaratorSyntax>();
                var variable = SyntaxFactory.VariableDeclarator(identifier, null, initializer);
                variables = variables.Add(variable);

                var declaration = SyntaxFactory.VariableDeclaration(type.WithTrailingTrivia(SyntaxFactory.Whitespace(" ")), variables);
                var modifiers = SyntaxFactory.TokenList(SyntaxFactory.ParseToken("internal").WithTrailingTrivia(SyntaxFactory.Whitespace(" ")), SyntaxFactory.ParseToken("static").WithTrailingTrivia(SyntaxFactory.Whitespace(" ")));
                var rule = SyntaxFactory.FieldDeclaration(new SyntaxList<AttributeListSyntax>(), modifiers, declaration);
                return rule;
            }
        protected override async Task <Document> FixIdentifierNameAsync(Document document, SyntaxGenerator generator, SyntaxNode root, SyntaxNode identifier, CancellationToken cancellationToken)
        {
            if (identifier?.Parent?.FirstAncestorOrSelf <InvocationExpressionSyntax>() is InvocationExpressionSyntax invokeParent)
            {
                SemanticModel model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                if (model.GetSymbolInfo((IdentifierNameSyntax)identifier !, cancellationToken).Symbol is IMethodSymbol methodSymbol && CanAddStringComparison(methodSymbol, model))
                {
                    // append a new StringComparison.Ordinal argument
                    SyntaxNode newArg = generator.Argument(CreateOrdinalMemberAccess(generator, model))
                                        .WithAdditionalAnnotations(Formatter.Annotation);
                    InvocationExpressionSyntax newInvoke = invokeParent.AddArgumentListArguments((ArgumentSyntax)newArg).WithAdditionalAnnotations(Formatter.Annotation);
                    SyntaxNode newRoot = root.ReplaceNode(invokeParent, newInvoke);
                    return(document.WithSyntaxRoot(newRoot));
                }
            }

            return(document);
        }
 internal static ArgumentSyntax CreateSyntaxKindIfStatement(SyntaxGenerator generator)
 {
     var syntaxKind = generator.IdentifierName("SyntaxKind");
     var expression = generator.MemberAccessExpression(syntaxKind, "IfStatement");
     var argument = generator.Argument(expression) as ArgumentSyntax;
     return argument;
 }
Beispiel #58
0
        public static TypeDeclarationSyntax ConvertToReadonly(TypeDeclarationSyntax typeDeclaration, SyntaxGenerator generator)
        {
            var propertiesToSetFrmConstructor = new List <PropertyDeclarationSyntax>();

            var newMembers = typeDeclaration.Members.Select(x =>
            {
                if (x is PropertyDeclarationSyntax propertyDeclaration && propertyDeclaration.Modifiers.Any(SyntaxKind.PublicKeyword))
                {
                    propertiesToSetFrmConstructor.Add(propertyDeclaration);
                    var accessorsWithoutSetter = propertyDeclaration.AccessorList.Accessors.Where(a => a.Kind() != SyntaxKind.SetAccessorDeclaration);
                    return(propertyDeclaration.WithAccessorList(SyntaxFactory.AccessorList(new SyntaxList <AccessorDeclarationSyntax>(accessorsWithoutSetter))));
                }
                return(x);
            }).ToList();

            var newConstructor = GenerateConstructor(typeDeclaration, generator, propertiesToSetFrmConstructor);

            newMembers.Add(newConstructor);
            return(typeDeclaration.WithMembers(newMembers));
        }
            internal static SyntaxNode CreateAnalysisMethod(SyntaxGenerator generator, string methodName, SemanticModel semanticModel)
            {
                var type = SyntaxFactory.ParseTypeName("SyntaxNodeAnalysisContext");
                var parameters = new[] { generator.ParameterDeclaration("context", type) };
                SyntaxList<SyntaxNode> statements = new SyntaxList<SyntaxNode>();
                INamedTypeSymbol notImplementedException = semanticModel.Compilation.GetTypeByMetadataName("System.NotImplementedException");
                statements = statements.Add(generator.ThrowStatement(generator.ObjectCreationExpression(notImplementedException)));

                SyntaxNode newMethodDeclaration = generator.MethodDeclaration(methodName, parameters: parameters, accessibility: Accessibility.Private, statements: statements);
                return newMethodDeclaration.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("// This method, which is the method that is registered within Initialize, performs the analysis of the Syntax Tree when an IfStatementSyntax Node is found. If the analysis finds an error, a diagnostic is reported").ElementAt(0), SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.ParseLeadingTrivia("// In this tutorial, this method will walk through the Syntax Tree seen in IfSyntaxTree.jpg and determine if the if-statement being analyzed has the correct spacing").ElementAt(0), SyntaxFactory.CarriageReturnLineFeed);
            }
Beispiel #60
0
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var(document, textSpan, cancellationToken) = context;

            // TODO: One could try to retrieve TParameterList and then filter out parameters that intersect with
            // textSpan and use that as `parameterNodes`, where `selectedParameter` would be the first one.

            var selectedParameter = await context.TryGetRelevantNodeAsync <TParameterSyntax>().ConfigureAwait(false);

            if (selectedParameter == null)
            {
                return;
            }

            var functionDeclaration = selectedParameter.FirstAncestorOrSelf <SyntaxNode>(IsFunctionDeclaration);

            if (functionDeclaration is null)
            {
                return;
            }

            var generator      = SyntaxGenerator.GetGenerator(document);
            var parameterNodes = generator.GetParameters(functionDeclaration);
            var semanticModel  = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            var parameterDefault = syntaxFacts.GetDefaultOfParameter(selectedParameter);

            // we can't just call GetDeclaredSymbol on functionDeclaration because it could an anonymous function,
            // so first we have to get the parameter symbol and then its containing method symbol
            if (!TryGetParameterSymbol(selectedParameter, semanticModel, out var parameter, cancellationToken))
            {
                return;
            }

            var methodSymbol = (IMethodSymbol)parameter.ContainingSymbol;

            if (methodSymbol.IsAbstract ||
                methodSymbol.IsExtern ||
                methodSymbol.PartialImplementationPart != null ||
                methodSymbol.ContainingType.TypeKind == TypeKind.Interface)
            {
                return;
            }

            if (CanOfferRefactoring(functionDeclaration, semanticModel, syntaxFacts, cancellationToken, out var blockStatementOpt))
            {
                // Ok.  Looks like the selected parameter could be refactored. Defer to subclass to
                // actually determine if there are any viable refactorings here.
                context.RegisterRefactorings(await GetRefactoringsForSingleParameterAsync(
                                                 document, parameter, functionDeclaration, methodSymbol, blockStatementOpt, cancellationToken).ConfigureAwait(false));
            }

            // List with parameterNodes that pass all checks
            var listOfPotentiallyValidParametersNodes = ArrayBuilder <SyntaxNode> .GetInstance();

            foreach (var parameterNode in parameterNodes)
            {
                if (!TryGetParameterSymbol(parameterNode, semanticModel, out parameter, cancellationToken))
                {
                    return;
                }

                // Update the list of valid parameter nodes
                listOfPotentiallyValidParametersNodes.Add(parameterNode);
            }

            if (listOfPotentiallyValidParametersNodes.Count > 1)
            {
                // Looks like we can offer a refactoring for more than one parameter. Defer to subclass to
                // actually determine if there are any viable refactorings here.
                context.RegisterRefactorings(await GetRefactoringsForAllParametersAsync(
                                                 document, functionDeclaration, methodSymbol, blockStatementOpt, listOfPotentiallyValidParametersNodes.ToImmutableAndFree(), selectedParameter.Span, cancellationToken).ConfigureAwait(false));
            }