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); }
/// <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>(); }
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; }
public static ImmutableArray <SyntaxNode> CreateThrowNotImplementedStatementBlock( this SyntaxGenerator codeDefinitionFactory, Compilation compilation) => ImmutableArray.Create(CreateThrowNotImplementedStatement(codeDefinitionFactory, compilation));
private protected override SyntaxNode Build(SyntaxGenerator generator) => generator.ArrayTypeExpression(Type.BuildInternal(generator));
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)); }
public CloneMappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, IAssemblySymbol contextAssembly) : base(semanticModel, syntaxGenerator, contextAssembly) { }
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); }
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()); }
public MappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator) { this.semanticModel = semanticModel; this.syntaxGenerator = syntaxGenerator; }
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)))); }
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);
internal virtual SyntaxNode WrapBuild(SyntaxGenerator generator, SyntaxNode on_false) => generator.IfStatement(condition.BuildInternal(generator), BuildTrue(generator), on_false);
/// <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); }
private static RangeExpressionSyntax CreateRangeExpression(Result result, SyntaxGenerator generator) => result.Kind switch {
protected abstract TLocalDeclarationStatementSyntax GetUpdatedLocalDeclarationStatement(SyntaxGenerator generator, TLocalDeclarationStatementSyntax localDeclarationStatement, ILocalSymbol symbol);
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; }
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)); }
internal virtual SyntaxNode BuildWithElse(SyntaxGenerator generator, IEnumerable <Statement> on_false) => generator.IfStatement(condition.BuildInternal(generator), BuildTrue(generator), BuildMany(generator, on_false));
// C# doesn't have global imports. protected override ImmutableArray <SyntaxNode> GetGlobalImports( Compilation compilation, SyntaxGenerator generator ) => ImmutableArray <SyntaxNode> .Empty;
private protected IEnumerable <SyntaxNode> BuildTrue(SyntaxGenerator generator) => BuildMany(generator, if_true);
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()); }
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; }
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); }
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)); }