private List <AssignmentExpression> CreateVirtualMemberRefs(List <AssignmentExpression> variables, TupleElementSyntax typeElement, int initializerNumber, List <Expression> initValues, TextSpan textSpan) { for (int i = 0; i < variables.Count; i++) { var variable = variables[i]; var tupleTypeElementMemRef = new MemberReferenceExpression { Target = new IdToken(((IdToken)variable.Left).Id, variable.Left.TextSpan), Name = ConvertId(typeElement.Identifier) }; var right = variable?.Right as TupleCreateExpression; if (right == null) { continue; } right.Initializers.Add(new AssignmentExpression { Left = tupleTypeElementMemRef, Right = initValues[i], TextSpan = textSpan }); } return(variables); }
/// <summary> /// When a name is absent, deconstruct a given tuple, otherwise create virtual member references /// </summary> private Ust HandleTupleStatement(VariableDeclarationSyntax node) { List <AssignmentExpression> variables = node.Variables.Select(v => (AssignmentExpression)VisitAndReturnNullIfError(v)).ToList(); var typeNode = (TupleTypeSyntax)node.Type; var textSpan = node.GetTextSpan(); for (int i = 0; i < typeNode.Elements.Count; i++) { TupleElementSyntax typeElement = typeNode.Elements[i]; if (typeElement.Identifier == null) { continue; } var initValues = node.Variables.Select(v => { var tuple = v.Initializer?.Value as TupleExpressionSyntax; if (tuple == null) { return(null); } return((Expression)base.Visit(tuple.Arguments.ElementAtOrDefault(i))); }).ToList(); variables = CreateVirtualMemberRefs(variables, typeElement, i, initValues, typeNode.Elements[i].GetTextSpan()); } var declaration = new VariableDeclarationExpression(null, variables, textSpan); return(new ExpressionStatement(declaration)); }
private static Task <Document> RenameTupleElementAsync( Document document, MethodDeclarationSyntax methodDeclaration, TupleElementSyntax tupleElement, IFieldSymbol fieldSymbol, string newName, SemanticModel semanticModel, CancellationToken cancellationToken) { MethodDeclarationSyntax newNode = methodDeclaration; var returnType = (TupleTypeSyntax)methodDeclaration.ReturnType; SyntaxToken newIdentifier = SyntaxFactory.Identifier(newName).WithTriviaFrom(tupleElement.Identifier); SeparatedSyntaxList <TupleElementSyntax> newElements = returnType.Elements.Replace(tupleElement, tupleElement.WithIdentifier(newIdentifier)); newNode = methodDeclaration.WithReturnType(returnType.WithElements(newElements)); var rewriter = new RenameRewriter(fieldSymbol, newName, semanticModel, cancellationToken); if (methodDeclaration.Body is BlockSyntax body) { newNode = newNode.WithBody((BlockSyntax)rewriter.VisitBlock(body)); } else if (methodDeclaration.ExpressionBody is ArrowExpressionClauseSyntax expressionBody) { newNode = newNode.WithExpressionBody((ArrowExpressionClauseSyntax)rewriter.VisitArrowExpressionClause(expressionBody)); } return(document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken)); }
private static void GetName(SemanticModel semanticModel, TupleElementSyntax element, out string typeName, out string name) { typeName = element.Type.ToString(); name = element.Identifier.ToString(); if (!string.IsNullOrWhiteSpace(name)) { return; } var typeSymbol = semanticModel.GetTypeInfo(element.Type).Type; switch (typeSymbol.SpecialType) { case SpecialType.System_Object: name = "Object"; break; case SpecialType.System_Boolean: name = "Bool"; break; case SpecialType.System_Char: name = "Char"; break; case SpecialType.System_SByte: name = "SByte"; break; case SpecialType.System_Byte: name = "Byte"; break; case SpecialType.System_Int16: name = "Short"; break; case SpecialType.System_Int32: name = "Int"; break; case SpecialType.System_Int64: name = "Long"; break; case SpecialType.System_UInt16: name = "UShort"; break; case SpecialType.System_UInt32: name = "UInt"; break; case SpecialType.System_UInt64: name = "ULong"; break; case SpecialType.System_Decimal: name = "Decimal"; break; case SpecialType.System_Single: name = "Float"; break; case SpecialType.System_Double: name = "Double"; break; case SpecialType.System_String: name = "String"; break; case SpecialType.System_IntPtr: name = "IntPtr"; break; case SpecialType.System_UIntPtr: name = "UIntPtr"; break; default: name = typeName.Replace("[]", "Array") .Replace("?", "_Nullable") .Replace('<', '_') .Replace(">", "") .Replace(", ", "_") .Replace(',', '_') .Replace(' ', '_'); break; } }
private static Task <Document> RenameTupleElementAsync( Document document, PropertyDeclarationSyntax propertyDeclaration, TupleElementSyntax tupleElement, IFieldSymbol fieldSymbol, string newName, SemanticModel semanticModel, CancellationToken cancellationToken) { PropertyDeclarationSyntax newNode = propertyDeclaration; var type = (TupleTypeSyntax)propertyDeclaration.Type; SyntaxToken newIdentifier = SyntaxFactory.Identifier(newName).WithTriviaFrom(tupleElement.Identifier); SeparatedSyntaxList <TupleElementSyntax> newElements = type.Elements.Replace(tupleElement, tupleElement.WithIdentifier(newIdentifier)); newNode = propertyDeclaration.WithType(type.WithElements(newElements)); var rewriter = new RenameRewriter(fieldSymbol, newName, semanticModel, cancellationToken); var newAccessorList = (AccessorListSyntax)rewriter.VisitAccessorList(propertyDeclaration.AccessorList); newNode = newNode.WithAccessorList(newAccessorList); return(document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken)); }
private Doc PrintTupleElementSyntax(TupleElementSyntax node) { return(Concat( this.Print(node.Type), node.Identifier.RawKind != 0 ? Concat(" ", this.PrintSyntaxToken(node.Identifier)) : Doc.Null )); }
public static Doc Print(TupleElementSyntax node) { return(Doc.Concat( Node.Print(node.Type), node.Identifier.RawKind != 0 ? Doc.Concat(" ", Token.Print(node.Identifier)) : Doc.Null )); }
public override void VisitTupleElement(TupleElementSyntax node) { if (!PreVisit(node)) { return; } node.Type?.Accept(this); base.VisitTupleElement(node); PostVisit(node); }
public override void VisitTupleElement(TupleElementSyntax node) { Log(node, "Unsupported Syntax !"); }
// // Summary: // Called when the visitor visits a TupleElementSyntax node. public virtual void VisitTupleElement(TupleElementSyntax node);
public override Evaluation VisitTupleElement(TupleElementSyntax node) { node.Type?.Accept <Evaluation>(this); return(base.VisitTupleElement(node)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddDocumentationComment) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeMethodReturnType) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.MemberTypeMustMatchOverriddenMemberType) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddPartialModifier) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.MakeContainingClassAbstract) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveParametersFromStaticConstructor) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveMemberDeclaration) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RenameDestructorToMatchClassName) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RenameTupleElement)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.MissingXmlCommentForPubliclyVisibleTypeOrMember: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddDocumentationComment)) { break; } CodeAction codeAction = CodeAction.Create( "Add documentation comment", cancellationToken => AddDocumentationCommentRefactoring.RefactorAsync(context.Document, memberDeclaration, false, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); CodeAction codeAction2 = CodeAction.Create( "Add documentation comment (copy from base if available)", cancellationToken => AddDocumentationCommentRefactoring.RefactorAsync(context.Document, memberDeclaration, true, cancellationToken), GetEquivalenceKey(diagnostic, "CopyFromBaseIfAvailable")); context.RegisterCodeFix(codeAction2, diagnostic); break; } case CompilerDiagnosticIdentifiers.MethodReturnTypeMustMatchOverriddenMethodReturnType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeMethodReturnType)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); ITypeSymbol typeSymbol = methodSymbol.OverriddenMethod.ReturnType; CodeFixRegistrator.ChangeMemberDeclarationType(context, diagnostic, memberDeclaration, typeSymbol, semanticModel); break; } case CompilerDiagnosticIdentifiers.PartialMethodsMustHaveVoidReturnType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeMethodReturnType)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodDeclaration = (MethodDeclarationSyntax)memberDeclaration; MethodDeclarationSyntax otherPart = semanticModel.GetOtherPart(methodDeclaration, context.CancellationToken); if (otherPart == null) { break; } CodeAction codeAction = CodeAction.Create( "Change return type to 'void'", cancellationToken => { return(context.Document.Solution().ReplaceNodesAsync( new MethodDeclarationSyntax[] { methodDeclaration, otherPart }, (node, _) => node.WithReturnType(CSharpFactory.VoidType().WithTriviaFrom(node.ReturnType)), cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.MemberTypeMustMatchOverriddenMemberType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.MemberTypeMustMatchOverriddenMemberType)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = null; switch (memberDeclaration.Kind()) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.IndexerDeclaration: { var propertySymbol = (IPropertySymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); typeSymbol = propertySymbol.OverriddenProperty.Type; break; } case SyntaxKind.EventDeclaration: { var eventSymbol = (IEventSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); typeSymbol = eventSymbol.OverriddenEvent.Type; break; } case SyntaxKind.EventFieldDeclaration: { VariableDeclaratorSyntax declarator = ((EventFieldDeclarationSyntax)memberDeclaration).Declaration.Variables.First(); var eventSymbol = (IEventSymbol)semanticModel.GetDeclaredSymbol(declarator, context.CancellationToken); typeSymbol = eventSymbol.OverriddenEvent.Type; break; } } CodeFixRegistrator.ChangeMemberDeclarationType(context, diagnostic, memberDeclaration, typeSymbol, semanticModel); break; } case CompilerDiagnosticIdentifiers.MissingPartialModifier: case CompilerDiagnosticIdentifiers.PartialMethodMustBeDeclaredInPartialClassOrPartialStruct: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddPartialModifier)) { break; } SyntaxNode node = null; switch (memberDeclaration.Kind()) { case SyntaxKind.MethodDeclaration: { if (memberDeclaration.IsParentKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration)) { node = memberDeclaration.Parent; } break; } case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.InterfaceDeclaration: { node = memberDeclaration; break; } } Debug.Assert(node != null, memberDeclaration.ToString()); if (node == null) { break; } ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.PartialKeyword); break; } case CompilerDiagnosticIdentifiers.MemberIsAbstractButItIsContainedInNonAbstractClass: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.MakeContainingClassAbstract)) { break; } if (!memberDeclaration.IsParentKind(SyntaxKind.ClassDeclaration)) { break; } ModifiersCodeFixRegistrator.AddModifier( context, diagnostic, memberDeclaration.Parent, SyntaxKind.AbstractKeyword, title: "Make containing class abstract"); break; } case CompilerDiagnosticIdentifiers.StaticConstructorMustBeParameterless: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveParametersFromStaticConstructor)) { break; } var constructorDeclaration = (ConstructorDeclarationSyntax)memberDeclaration; CodeAction codeAction = CodeAction.Create( "Remove parameters", cancellationToken => { ParameterListSyntax parameterList = constructorDeclaration.ParameterList; ParameterListSyntax newParameterList = parameterList .WithParameters(default(SeparatedSyntaxList <ParameterSyntax>)) .WithOpenParenToken(parameterList.OpenParenToken.WithoutTrailingTrivia()) .WithCloseParenToken(parameterList.CloseParenToken.WithoutLeadingTrivia()); ConstructorDeclarationSyntax newNode = constructorDeclaration.WithParameterList(newParameterList); return(context.Document.ReplaceNodeAsync(constructorDeclaration, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.ExplicitInterfaceDeclarationCanOnlyBeDeclaredInClassOrStruct: case CompilerDiagnosticIdentifiers.InterfacesCannotContainFields: case CompilerDiagnosticIdentifiers.InterfacesCannotContainOperators: case CompilerDiagnosticIdentifiers.InterfacesCannotDeclareTypes: case CompilerDiagnosticIdentifiers.OnlyClassTypesCanContainDestructors: case CompilerDiagnosticIdentifiers.StructsCannotContainExplicitParameterlessConstructors: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveMemberDeclaration)) { break; } CodeFixRegistrator.RemoveMember(context, diagnostic, memberDeclaration); break; } case CompilerDiagnosticIdentifiers.NameOfDestructorMustMatchNameOfClass: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RenameDestructorToMatchClassName)) { break; } if (!(memberDeclaration is DestructorDeclarationSyntax destructorDeclaration)) { break; } if (!(memberDeclaration.Parent is ClassDeclarationSyntax classDeclaration)) { break; } if (classDeclaration.Identifier.ValueText.Length == 0) { break; } CodeAction codeAction = CodeAction.Create( "Rename destructor to match class name", cancellationToken => { DestructorDeclarationSyntax newNode = destructorDeclaration.WithIdentifier(classDeclaration.Identifier.WithTriviaFrom(destructorDeclaration.Identifier)); return(context.Document.ReplaceNodeAsync(destructorDeclaration, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CannotChangeTupleElementNameWhenOverridingInheritedMember: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RenameTupleElement)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (memberDeclaration is MethodDeclarationSyntax methodDeclaration) { IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (!(methodSymbol.ReturnType is INamedTypeSymbol tupleType)) { break; } if (!tupleType.IsTupleType) { break; } if (!(methodSymbol.OverriddenMethod?.ReturnType is INamedTypeSymbol baseTupleType)) { break; } if (!baseTupleType.IsTupleType) { break; } ImmutableArray <IFieldSymbol> elements = tupleType.TupleElements; ImmutableArray <IFieldSymbol> baseElements = baseTupleType.TupleElements; if (elements.Length != baseElements.Length) { break; } int i = 0; while (i < elements.Length) { if (elements[i].Name != baseElements[i].Name) { break; } i++; } if (i == elements.Length) { break; } TupleElementSyntax tupleElement = ((TupleTypeSyntax)methodDeclaration.ReturnType).Elements[i]; CodeAction codeAction = CodeAction.Create( $"Rename '{elements[i].Name}' to '{baseElements[i].Name}'", ct => RenameTupleElementAsync(context.Document, methodDeclaration, tupleElement, elements[i], baseElements[i].Name, semanticModel, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } else if (memberDeclaration is PropertyDeclarationSyntax propertyDeclaration) { IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken); if (!(propertySymbol.Type is INamedTypeSymbol tupleType)) { break; } if (!tupleType.IsTupleType) { break; } if (!(propertySymbol.OverriddenProperty?.Type is INamedTypeSymbol baseTupleType)) { break; } if (!baseTupleType.IsTupleType) { break; } ImmutableArray <IFieldSymbol> elements = tupleType.TupleElements; ImmutableArray <IFieldSymbol> baseElements = baseTupleType.TupleElements; if (elements.Length != baseElements.Length) { break; } int i = 0; while (i < elements.Length) { if (elements[i].Name != baseElements[i].Name) { break; } i++; } if (i == elements.Length) { break; } TupleElementSyntax tupleElement = ((TupleTypeSyntax)propertyDeclaration.Type).Elements[i]; CodeAction codeAction = CodeAction.Create( $"Rename '{elements[i].Name}' to '{baseElements[i].Name}'", ct => RenameTupleElementAsync(context.Document, propertyDeclaration, tupleElement, elements[i], baseElements[i].Name, semanticModel, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } } } }
//public override void VisitStructDeclaration(StructDeclarationSyntax node) //{ // base.VisitStructDeclaration(node); //} //public override void VisitSwitchSection(SwitchSectionSyntax node) //{ // base.VisitSwitchSection(node); //} //public override void VisitSwitchStatement(SwitchStatementSyntax node) //{ // base.VisitSwitchStatement(node); //} //public override void VisitThisExpression(ThisExpressionSyntax node) //{ // base.VisitThisExpression(node); //} //public override void VisitThrowExpression(ThrowExpressionSyntax node) //{ // base.VisitThrowExpression(node); //} //public override void VisitThrowStatement(ThrowStatementSyntax node) //{ // base.VisitThrowStatement(node); //} //public override void VisitTryStatement(TryStatementSyntax node) //{ // base.VisitTryStatement(node); //} public override void VisitTupleElement(TupleElementSyntax node) { VisitType(node.Type); //base.VisitTupleElement(node); }
public override void VisitTupleElement(TupleElementSyntax node) { }
/// <summary> /// Given a tuple element syntax, get the corresponding symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a tuple element.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> public ISymbol GetDeclaredSymbol(TupleElementSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { CheckSyntaxNode(declarationSyntax); var tupleTypeSyntax = declarationSyntax.Parent as TupleTypeSyntax; if (tupleTypeSyntax != null) { return (GetSymbolInfo(tupleTypeSyntax).Symbol as TupleTypeSymbol)?.TupleElements.ElementAtOrDefault(tupleTypeSyntax.Elements.IndexOf(declarationSyntax)); } return null; }
private static async Task <Solution> MakeElementNamePascalCaseAsync(Document document, TupleElementSyntax tupleElement, CancellationToken cancellationToken) { SyntaxNode?root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); if (root is null) { return(document.Project.Solution); } string elementName = tupleElement.Identifier.ValueText; if (RGDiagnosticAnalyzer.IsInCamelCase(elementName) && tupleElement.Ancestors().OfType <TupleTypeSyntax>().FirstOrDefault() is TupleTypeSyntax tupleTypeSyntax) { string pascalCase = RGDiagnosticAnalyzer.ToPascalCase(elementName); SemanticModel?semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (semanticModel is null) { return(document.Project.Solution); } if (semanticModel.GetSymbolInfo(tupleTypeSyntax, cancellationToken).Symbol is not INamedTypeSymbol tupleSymbol) { return(document.Project.Solution); } IFieldSymbol?fieldSymbol = tupleSymbol.TupleElements.FirstOrDefault(element => element.Name == elementName); if (fieldSymbol is null) { return(document.Project.Solution); } Solution solution = document.Project.Solution; return(await Renamer.RenameSymbolAsync(solution, fieldSymbol, pascalCase, solution.Workspace.Options, cancellationToken).ConfigureAwait(false)); } else { return(document.Project.Solution); } }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CS1591_MissingXmlCommentForPubliclyVisibleTypeOrMember: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddDocumentationComment, context.Document, root.SyntaxTree)) { break; } CodeAction codeAction = CodeAction.Create( "Add documentation comment", ct => AddDocumentationCommentRefactoring.RefactorAsync(context.Document, memberDeclaration, false, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); CodeAction codeAction2 = CodeAction.Create( "Add documentation comment (copy from base if available)", ct => AddDocumentationCommentRefactoring.RefactorAsync(context.Document, memberDeclaration, true, ct), GetEquivalenceKey(diagnostic, "CopyFromBaseIfAvailable")); context.RegisterCodeFix(codeAction2, diagnostic); break; } case CompilerDiagnosticIdentifiers.CS0508_MethodReturnTypeMustMatchOverriddenMethodReturnType: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMethodReturnType, context.Document, root.SyntaxTree)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodSymbol = (IMethodSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); ITypeSymbol typeSymbol = methodSymbol.OverriddenMethod.ReturnType; CodeFixRegistrator.ChangeTypeOrReturnType(context, diagnostic, memberDeclaration, typeSymbol, semanticModel); break; } case CompilerDiagnosticIdentifiers.CS0766_PartialMethodsMustHaveVoidReturnType: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeMethodReturnType, context.Document, root.SyntaxTree)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodDeclaration = (MethodDeclarationSyntax)memberDeclaration; MethodDeclarationSyntax otherPart = semanticModel.GetOtherPart(methodDeclaration, context.CancellationToken); if (otherPart == null) { break; } CodeAction codeAction = CodeAction.Create( "Change return type to 'void'", ct => { return(context.Document.Solution().ReplaceNodesAsync( new MethodDeclarationSyntax[] { methodDeclaration, otherPart }, (node, _) => node.WithReturnType(CSharpFactory.VoidType().WithTriviaFrom(node.ReturnType)), ct)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CS1715_MemberTypeMustMatchOverriddenMemberType: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MemberTypeMustMatchOverriddenMemberType, context.Document, root.SyntaxTree)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = null; switch (memberDeclaration.Kind()) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.IndexerDeclaration: { var propertySymbol = (IPropertySymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); typeSymbol = propertySymbol.OverriddenProperty.Type; break; } case SyntaxKind.EventDeclaration: { var eventSymbol = (IEventSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken); typeSymbol = eventSymbol.OverriddenEvent.Type; break; } case SyntaxKind.EventFieldDeclaration: { VariableDeclaratorSyntax declarator = ((EventFieldDeclarationSyntax)memberDeclaration).Declaration.Variables[0]; var eventSymbol = (IEventSymbol)semanticModel.GetDeclaredSymbol(declarator, context.CancellationToken); typeSymbol = eventSymbol.OverriddenEvent.Type; break; } } CodeFixRegistrator.ChangeTypeOrReturnType(context, diagnostic, memberDeclaration, typeSymbol, semanticModel); break; } case CompilerDiagnosticIdentifiers.CS0260_MissingPartialModifier: case CompilerDiagnosticIdentifiers.CS0751_PartialMethodMustBeDeclaredInPartialClassOrPartialStruct: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddPartialModifier, context.Document, root.SyntaxTree)) { break; } SyntaxNode node = null; switch (memberDeclaration.Kind()) { case SyntaxKind.MethodDeclaration: { if (memberDeclaration.IsParentKind( SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.RecordDeclaration, SyntaxKind.RecordStructDeclaration)) { node = memberDeclaration.Parent; } break; } case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.RecordStructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.RecordDeclaration: { node = memberDeclaration; break; } } SyntaxDebug.Assert(node != null, memberDeclaration); if (node == null) { break; } ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.PartialKeyword, title: $"Make {CSharpFacts.GetTitle(node)} partial"); break; } case CompilerDiagnosticIdentifiers.CS0513_MemberIsAbstractButItIsContainedInNonAbstractClass: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassAbstract, context.Document, root.SyntaxTree)) { break; } if (!memberDeclaration.IsParentKind(SyntaxKind.ClassDeclaration)) { break; } ModifiersCodeFixRegistrator.AddModifier( context, diagnostic, memberDeclaration.Parent, SyntaxKind.AbstractKeyword, title: "Make containing class abstract"); break; } case CompilerDiagnosticIdentifiers.CS0132_StaticConstructorMustBeParameterless: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveParametersFromStaticConstructor, context.Document, root.SyntaxTree)) { break; } var constructorDeclaration = (ConstructorDeclarationSyntax)memberDeclaration; CodeAction codeAction = CodeAction.Create( "Remove parameters", ct => { ParameterListSyntax parameterList = constructorDeclaration.ParameterList; ParameterListSyntax newParameterList = parameterList .WithParameters(default(SeparatedSyntaxList <ParameterSyntax>)) .WithOpenParenToken(parameterList.OpenParenToken.WithoutTrailingTrivia()) .WithCloseParenToken(parameterList.CloseParenToken.WithoutLeadingTrivia()); ConstructorDeclarationSyntax newNode = constructorDeclaration.WithParameterList(newParameterList); return(context.Document.ReplaceNodeAsync(constructorDeclaration, newNode, ct)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CS0541_ExplicitInterfaceDeclarationCanOnlyBeDeclaredInClassOrStruct: case CompilerDiagnosticIdentifiers.CS0525_InterfacesCannotContainFields: case CompilerDiagnosticIdentifiers.CS0567_InterfacesCannotContainOperators: case CompilerDiagnosticIdentifiers.CS0524_InterfacesCannotDeclareTypes: case CompilerDiagnosticIdentifiers.CS0575_OnlyClassTypesCanContainDestructors: case CompilerDiagnosticIdentifiers.CS0568_StructsCannotContainExplicitParameterlessConstructors: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveMemberDeclaration, context.Document, root.SyntaxTree)) { break; } CodeFixRegistrator.RemoveMemberDeclaration(context, diagnostic, memberDeclaration); break; } case CompilerDiagnosticIdentifiers.CS0574_NameOfDestructorMustMatchNameOfClass: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RenameDestructorToMatchClassName, context.Document, root.SyntaxTree)) { break; } if (memberDeclaration is not DestructorDeclarationSyntax destructorDeclaration) { break; } if (memberDeclaration.Parent is not ClassDeclarationSyntax classDeclaration) { break; } if (classDeclaration.Identifier.ValueText.Length == 0) { break; } CodeAction codeAction = CodeAction.Create( "Rename destructor to match class name", ct => { DestructorDeclarationSyntax newNode = destructorDeclaration.WithIdentifier(classDeclaration.Identifier.WithTriviaFrom(destructorDeclaration.Identifier)); return(context.Document.ReplaceNodeAsync(destructorDeclaration, newNode, ct)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CS8139_CannotChangeTupleElementNameWhenOverridingInheritedMember: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RenameTupleElement, context.Document, root.SyntaxTree)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (memberDeclaration is MethodDeclarationSyntax methodDeclaration) { IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (methodSymbol.ReturnType is not INamedTypeSymbol tupleType) { break; } if (!tupleType.IsTupleType) { break; } if (methodSymbol.OverriddenMethod?.ReturnType is not INamedTypeSymbol baseTupleType) { break; } if (!baseTupleType.IsTupleType) { break; } ImmutableArray <IFieldSymbol> elements = tupleType.TupleElements; ImmutableArray <IFieldSymbol> baseElements = baseTupleType.TupleElements; if (elements.Length != baseElements.Length) { break; } int i = 0; while (i < elements.Length) { if (elements[i].Name != baseElements[i].Name) { break; } i++; } if (i == elements.Length) { break; } TupleElementSyntax tupleElement = ((TupleTypeSyntax)methodDeclaration.ReturnType).Elements[i]; CodeAction codeAction = CodeAction.Create( $"Rename '{elements[i].Name}' to '{baseElements[i].Name}'", ct => RenameTupleElementAsync(context.Document, methodDeclaration, tupleElement, elements[i], baseElements[i].Name, semanticModel, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } else if (memberDeclaration is PropertyDeclarationSyntax propertyDeclaration) { IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken); if (propertySymbol.Type is not INamedTypeSymbol tupleType) { break; } if (!tupleType.IsTupleType) { break; } if (propertySymbol.OverriddenProperty?.Type is not INamedTypeSymbol baseTupleType) { break; } if (!baseTupleType.IsTupleType) { break; } ImmutableArray <IFieldSymbol> elements = tupleType.TupleElements; ImmutableArray <IFieldSymbol> baseElements = baseTupleType.TupleElements; if (elements.Length != baseElements.Length) { break; } int i = 0; while (i < elements.Length) { if (elements[i].Name != baseElements[i].Name) { break; } i++; } if (i == elements.Length) { break; } TupleElementSyntax tupleElement = ((TupleTypeSyntax)propertyDeclaration.Type).Elements[i]; CodeAction codeAction = CodeAction.Create( $"Rename '{elements[i].Name}' to '{baseElements[i].Name}'", ct => RenameTupleElementAsync(context.Document, propertyDeclaration, tupleElement, elements[i], baseElements[i].Name, semanticModel, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } case CompilerDiagnosticIdentifiers.CS3000_MethodsWithVariableArgumentsAreNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3001_ArgumentTypeIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3002_ReturnTypeIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3003_TypeOfVariableIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3005_IdentifierDifferingOnlyInCaseIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3006_OverloadedMethodDifferingOnlyInRefOrOutOrInArrayRankIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3007_OverloadedMethodDifferingOnlyByUnnamedArrayTypesIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3008_IdentifierIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3009_BaseTypeIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3016_ArraysAsAttributeArgumentsIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3024_ConstraintTypeIsNotCLSCompliant: case CompilerDiagnosticIdentifiers.CS3027_TypeIsNotCLSCompliantBecauseBaseInterfaceIsNotCLSCompliant: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MarkDeclarationAsNonCLSCompliant, context.Document, root.SyntaxTree)) { break; } CodeAction codeAction = CodeAction.Create( $"Mark {CSharpFacts.GetTitle(memberDeclaration)} as non-CLS-compliant", ct => MarkDeclarationAsNonCLSCompliantAsync(context.Document, memberDeclaration, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CS0539_ExplicitInterfaceDeclarationIsNotMemberOfInterface: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddParameterToExplicitlyImplementedInterfaceMember, context.Document, root.SyntaxTree)) { break; } var context2 = new CommonFixContext( context.Document, GetEquivalenceKey(diagnostic), await context.GetSemanticModelAsync().ConfigureAwait(false), context.CancellationToken); CodeAction codeAction = AddParameterToInterfaceMemberRefactoring.ComputeRefactoringForExplicitImplementation(context2, memberDeclaration); if (codeAction != null) { context.RegisterCodeFix(codeAction, diagnostic); } break; } } } }
public override void VisitTupleElement(TupleElementSyntax node) { throw new NotImplementedException(); }
public TameTupleElementSyntax(TupleElementSyntax node) { Node = node; AddChildren(); }
public override void VisitTupleElement(TupleElementSyntax node) { node.Type?.Accept(this); base.VisitTupleElement(node); }
//public override void VisitSwitchSection(SwitchSectionSyntax node) //{ // base.VisitSwitchSection(node); //} //public override void VisitSwitchStatement(SwitchStatementSyntax node) //{ // base.VisitSwitchStatement(node); //} //public override void VisitThisExpression(ThisExpressionSyntax node) //{ // base.VisitThisExpression(node); //} //public override void VisitThrowExpression(ThrowExpressionSyntax node) //{ // base.VisitThrowExpression(node); //} //public override void VisitThrowStatement(ThrowStatementSyntax node) //{ // base.VisitThrowStatement(node); //} //public override void VisitTryStatement(TryStatementSyntax node) //{ // base.VisitTryStatement(node); //} public override void VisitTupleElement(TupleElementSyntax node) { //base.VisitTupleElement(node); }