public async Task <ExtractMethodResult> ExtractMethodAsync( Document document, TextSpan textSpan, bool localFunction, ExtractMethodGenerationOptions options, CancellationToken cancellationToken) { var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); var validator = CreateSelectionValidator(semanticDocument, textSpan, options.ExtractOptions, localFunction); var selectionResult = await validator.GetValidSelectionAsync(cancellationToken).ConfigureAwait(false); if (!selectionResult.ContainsValidContext) { return(new FailedExtractMethodResult(selectionResult.Status)); } cancellationToken.ThrowIfCancellationRequested(); // extract method var extractor = CreateMethodExtractor((TResult)selectionResult, options, localFunction); return(await extractor.ExtractMethodAsync(cancellationToken).ConfigureAwait(false)); }
public MethodExtractor( SelectionResult selectionResult, ExtractMethodGenerationOptions options, bool localFunction) { Contract.ThrowIfNull(selectionResult); OriginalSelectionResult = selectionResult; Options = options; LocalFunction = localFunction; }
protected static async Task <SyntaxNode> ExtractMethodAsync( TestWorkspace workspace, TestHostDocument testDocument, bool succeed = true, bool dontPutOutOrRefOnStruct = true, bool allowBestEffort = false) { var document = workspace.CurrentSolution.GetDocument(testDocument.Id); Assert.NotNull(document); var options = new ExtractMethodGenerationOptions( ExtractOptions: new ExtractMethodOptions(dontPutOutOrRefOnStruct), CodeGenerationOptions: CodeGenerationOptions.GetDefault(document.Project.LanguageServices), AddImportOptions: AddImportPlacementOptions.Default, NamingPreferences: _ => NamingStylePreferences.Default); var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None); var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options.ExtractOptions, localFunction: false); var selectedCode = await validator.GetValidSelectionAsync(CancellationToken.None); if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion()) { return(null); } Assert.True(selectedCode.ContainsValidContext); // extract method var extractor = new CSharpMethodExtractor((CSharpSelectionResult)selectedCode, options, localFunction: false); var result = await extractor.ExtractMethodAsync(CancellationToken.None); Assert.NotNull(result); Assert.Equal(succeed, result.Succeeded || result.SucceededWithSuggestion || (allowBestEffort && result.Status.HasBestEffort())); var(doc, _) = await result.GetFormattedDocumentAsync(CodeCleanupOptions.GetDefault(document.Project.LanguageServices), CancellationToken.None); return(doc == null ? null : await doc.GetSyntaxRootAsync()); }
private static async Task <ImmutableArray <CodeAction> > GetCodeActionsAsync( Document document, TextSpan textSpan, ExtractMethodGenerationOptions extractOptions, CodeCleanupOptions cleanupOptions, CancellationToken cancellationToken) { using var _ = ArrayBuilder <CodeAction> .GetInstance(out var actions); var methodAction = await ExtractMethodAsync(document, textSpan, extractOptions, cleanupOptions, cancellationToken).ConfigureAwait(false); actions.AddIfNotNull(methodAction); var localFunctionAction = await ExtractLocalFunctionAsync(document, textSpan, extractOptions, cleanupOptions, cancellationToken).ConfigureAwait(false); actions.AddIfNotNull(localFunctionAction); return(actions.ToImmutable()); }
public static async ValueTask <ExtractMethodGenerationOptions> GetExtractMethodGenerationOptionsAsync(this Document document, ExtractMethodGenerationOptions?fallbackOptions, CancellationToken cancellationToken) { fallbackOptions ??= ExtractMethodGenerationOptions.GetDefault(document.Project.LanguageServices); var extractOptions = fallbackOptions.Value.ExtractOptions; var codeGenerationOptions = await document.GetCodeGenerationOptionsAsync(fallbackOptions.Value.CodeGenerationOptions, cancellationToken).ConfigureAwait(false); var addImportOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions.Value.AddImportOptions, cancellationToken).ConfigureAwait(false); var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var namingPreferences = documentOptions.GetOption(NamingStyleOptions.NamingPreferences, document.Project.Language); var namingPreferencesProvider = new NamingStylePreferencesProvider(language => namingPreferences); return(new ExtractMethodGenerationOptions( extractOptions, codeGenerationOptions, addImportOptions, namingPreferencesProvider)); }
private static async Task <ExtractMethodResult?> TryWithoutMakingValueTypesRefAsync( Document document, TextSpan span, ExtractMethodResult result, ExtractMethodGenerationOptions options, CancellationToken cancellationToken) { if (options.ExtractOptions.DontPutOutOrRefOnStruct || !result.Reasons.IsSingle()) { return(null); } var reason = result.Reasons.FirstOrDefault(); var length = FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.IndexOf(':'); if (reason != null && length > 0 && reason.IndexOf(FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.Substring(0, length), 0, length, StringComparison.Ordinal) >= 0) { var newResult = await ExtractMethodService.ExtractMethodAsync( document, span, localFunction : false, options with { ExtractOptions = options.ExtractOptions with { DontPutOutOrRefOnStruct = true } },
public void OptionsAreMessagePackSerializable(string language) { var messagePackOptions = MessagePackSerializerOptions.Standard.WithResolver(MessagePackFormatters.DefaultResolver); using var workspace = new AdhocWorkspace(); var languageServices = workspace.Services.GetLanguageServices(language); var options = new object[] { SimplifierOptions.GetDefault(languageServices), SyntaxFormattingOptions.GetDefault(languageServices), CodeCleanupOptions.GetDefault(languageServices), CodeGenerationOptions.GetDefault(languageServices), IdeCodeStyleOptions.GetDefault(languageServices), CodeActionOptions.GetDefault(languageServices), IndentationOptions.GetDefault(languageServices), ExtractMethodGenerationOptions.GetDefault(languageServices), // some non-default values: new VisualBasicIdeCodeStyleOptions( new IdeCodeStyleOptions.CommonOptions() { AllowStatementImmediatelyAfterBlock = new CodeStyleOption2 <bool>(false, NotificationOption2.Error) }, PreferredModifierOrder: new CodeStyleOption2 <string>("Public Private", NotificationOption2.Error)) }; foreach (var original in options) { using var stream = new MemoryStream(); MessagePackSerializer.Serialize(stream, original, messagePackOptions); stream.Position = 0; var deserialized = MessagePackSerializer.Deserialize(original.GetType(), stream, messagePackOptions); Assert.Equal(original, deserialized); } }
protected abstract TExtractor CreateMethodExtractor(TResult selectionResult, ExtractMethodGenerationOptions options, bool localFunction);
private static async Task <CodeAction> ExtractMethodAsync(Document document, TextSpan textSpan, ExtractMethodGenerationOptions extractOptions, CodeCleanupOptions cleanupOptions, CancellationToken cancellationToken) { var result = await ExtractMethodService.ExtractMethodAsync( document, textSpan, localFunction : false, extractOptions, cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(result); if (!result.Succeeded && !result.SucceededWithSuggestion) { return(null); } return(CodeAction.Create( FeaturesResources.Extract_method, async c => { var(document, invocationNameToken) = await result.GetFormattedDocumentAsync(cleanupOptions, c).ConfigureAwait(false); return await AddRenameAnnotationAsync(document, invocationNameToken, c).ConfigureAwait(false); }, nameof(FeaturesResources.Extract_method))); }
private static async Task <CodeAction> ExtractLocalFunctionAsync(Document document, TextSpan textSpan, ExtractMethodGenerationOptions extractOptions, CodeCleanupOptions cleanupOptions, CancellationToken cancellationToken) { var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); if (!syntaxFacts.SupportsLocalFunctionDeclaration(syntaxTree.Options)) { return(null); } var localFunctionResult = await ExtractMethodService.ExtractMethodAsync( document, textSpan, localFunction : true, extractOptions, cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(localFunctionResult); if (localFunctionResult.Succeeded || localFunctionResult.SucceededWithSuggestion) { var codeAction = CodeAction.Create( FeaturesResources.Extract_local_function, async c => { var(document, invocationNameToken) = await localFunctionResult.GetFormattedDocumentAsync(cleanupOptions, c).ConfigureAwait(false); return(await AddRenameAnnotationAsync(document, invocationNameToken, c).ConfigureAwait(false)); }, nameof(FeaturesResources.Extract_local_function)); return(codeAction); } return(null); }
public CSharpMethodExtractor(CSharpSelectionResult result, ExtractMethodGenerationOptions options, bool localFunction) : base(result, options, localFunction) { }
public static Task <ExtractMethodResult> ExtractMethodAsync(Document document, TextSpan textSpan, bool localFunction, ExtractMethodGenerationOptions options, CancellationToken cancellationToken) => document.GetRequiredLanguageService <IExtractMethodService>().ExtractMethodAsync(document, textSpan, localFunction, options, cancellationToken);