public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var(document, classDeclarationSyntax) = await context.FindSyntaxForCurrentSpan <ClassDeclarationSyntax>(); if (document == null || classDeclarationSyntax == null) { return; } if (!ClassDeclarationSyntaxAnalysis.IsRecordLike(classDeclarationSyntax)) { return; } var properties = ClassDeclarationSyntaxAnalysis.GetPropertyDeclarations(classDeclarationSyntax).ToList(); if (properties.Count == 0 || properties.Any(PropertyDeclarationSyntaxExtensions.IsStatic)) { return; } context.RegisterRefactoring( new DelegateCodeAction( "Generate to string from parameters", (c) => GenerateToString(document, classDeclarationSyntax, properties, c))); return; }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var(document, argumentList) = await context.FindSyntaxForCurrentSpan <ArgumentListSyntax>().ConfigureAwait(false); if (document == null || argumentList == null || argumentList.Arguments.Count == 0) { return; } var isMultiline = argumentList.OpenParenToken.TrailingTrivia.Any(SyntaxKind.EndOfLineTrivia); if (isMultiline) { context.RegisterRefactoring(new DelegateCodeAction( "Make arguments single line", c => MakeSingleLine(document, argumentList, c))); } else { context.RegisterRefactoring(new DelegateCodeAction( "Split arguments into multiple lines", c => MakeMultiline(document, argumentList, c))); } }
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var(document, classDeclarationSyntax) = await context.FindSyntaxForCurrentSpan <ClassDeclarationSyntax>(); if (document == null || classDeclarationSyntax == null) { return; } if (!ClassDeclarationSyntaxAnalysis.IsRecordLike(classDeclarationSyntax)) { return; } var(atMostOneConstructor, nonTrivialConstructorCandidate) = ClassDeclarationSyntaxAnalysis.HasAtMostOneNoneTrivialConstructor(classDeclarationSyntax); if (!atMostOneConstructor || nonTrivialConstructorCandidate == null) { return; } var properties = ClassDeclarationSyntaxAnalysis.GetPropertyDeclarations(classDeclarationSyntax).ToList(); if (properties.Count == 0 || properties.Any(PropertyDeclarationSyntaxExtensions.IsStatic)) { return; } var cancellationToken = context.CancellationToken; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var constructorSymbol = semanticModel.GetDeclaredSymbol(nonTrivialConstructorCandidate); var propertySymbols = properties.Select(p => semanticModel.GetDeclaredSymbol(p, cancellationToken)).ToArray(); var analyser = new ConstructorPropertyRelationshipAnalyser( Array.Empty <IFieldSymbol>(), propertySymbols); var result = analyser.Analyze(semanticModel, nonTrivialConstructorCandidate); var(idxMappings, isExhaustive) = result.GetIndexMapping(propertySymbols, constructorSymbol); if (!isExhaustive) { return; } context.RegisterRefactoring( new DelegateCodeAction( "Generate with methods for parameters", (c) => GenerateWithMethods(document, classDeclarationSyntax, properties, idxMappings, c))); return; }
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var(document, methodDeclarationSyntax) = await context.FindSyntaxForCurrentSpan <ConstructorDeclarationSyntax>(); if (document == null || methodDeclarationSyntax == null) { return; } context.RegisterRefactoring( new DelegateCodeAction( "Generate test with moq", (c) => GenerateClassFromMethod(document, methodDeclarationSyntax, c))); }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var(document, classDeclarationSyntax) = await context.FindSyntaxForCurrentSpan <ClassDeclarationSyntax>(); if (document == null || classDeclarationSyntax == null) { return; } if (ClassDeclarationSyntaxAnalysis.IsPartial(classDeclarationSyntax) || ClassDeclarationSyntaxAnalysis.IsStatic(classDeclarationSyntax)) { return; } var(atMostOneNonTrivialConstructor, nonTrivialConstructorCandidate) = ClassDeclarationSyntaxAnalysis.HasAtMostOneNoneTrivialConstructor(classDeclarationSyntax); if (!atMostOneNonTrivialConstructor) { return; } var(_, propertyDeclaration) = await context.FindSyntaxForCurrentSpan <PropertyDeclarationSyntax>(); var(_, fieldDeclaration) = await context.FindSyntaxForCurrentSpan <FieldDeclarationSyntax>(); // TODO: Skip properties like string Prop => "something"; if ((fieldDeclaration == null && propertyDeclaration == null) || (fieldDeclaration != null && fieldDeclaration.IsStatic()) || (propertyDeclaration != null && propertyDeclaration.IsStatic())) { return; } var(_, fieldVariableDeclaration) = await context.FindVariableDeclaratorForCurrentSpan(); if (fieldDeclaration != null && fieldVariableDeclaration == null) { return; } switch (nonTrivialConstructorCandidate) { case ConstructorDeclarationSyntax candidate: { var cancellationToken = context.CancellationToken; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); HandleCandidate(semanticModel, candidate, propertyDeclaration, fieldDeclaration, fieldVariableDeclaration); } break; case null: { var trivialConstructor = ClassDeclarationSyntaxAnalysis.GetConstructors(classDeclarationSyntax)?.FirstOrDefault(); if (trivialConstructor != null) { var cancellationToken = context.CancellationToken; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); HandleCandidate(semanticModel, trivialConstructor, propertyDeclaration, fieldDeclaration, fieldVariableDeclaration); } else { // TODO: register add constructor refactoring } } break; } void HandleCandidate( SemanticModel model, ConstructorDeclarationSyntax candidate, PropertyDeclarationSyntax pDeclaration, FieldDeclarationSyntax fDeclaration, VariableDeclaratorSyntax variableDeclarator) { bool isProp = pDeclaration != null; var constructorSymbol = model.GetDeclaredSymbol(candidate) as IMethodSymbol; ISymbol memberSymbol = isProp ? model.GetDeclaredSymbol(pDeclaration) : model.GetDeclaredSymbol(variableDeclarator); if (constructorSymbol == null || memberSymbol == null) { return; } var analyser = new ConstructorPropertyRelationshipAnalyser( isProp ? Array.Empty <IFieldSymbol>() : new[] { memberSymbol as IFieldSymbol }, isProp ? new[] { memberSymbol as IPropertySymbol } : Array.Empty <IPropertySymbol>()); var result = analyser.Analyze(model, candidate); var assignmentResult = result.GetResult(memberSymbol); AnalysedDeclaration ad = isProp ? (AnalysedDeclaration) new PropertyDeclaration(memberSymbol as IPropertySymbol, pDeclaration) : new FieldDeclaration(memberSymbol as IFieldSymbol, fDeclaration, variableDeclarator); switch (assignmentResult) { case AssignmentExpressionAnalyserResult r: // register remove as assignment exists context.RegisterRefactoring( new DelegateCodeAction( $"Remove {ad.Identifier.ValueText}", (c) => RefactoringActions.RemoveParameter( document, classDeclarationSyntax, ad, candidate, c))); break; case EmptyAssignmentAnalyserResult _: // register add to constructor context.RegisterRefactoring( new DelegateCodeAction( $"Add {ad.Identifier.ValueText} to constructor", (c) => RefactoringActions.AddParameterToConstructor( document, classDeclarationSyntax, ad, constructorSymbol, candidate, c))); break; case MultipleAssignments _: case ParsingError _: default: // Something went wrong so it might be better to do nothing. break; } } }