10b57cec5SDimitry Andric //===--- ASTSelectionRequirements.cpp - Clang refactoring library ---------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h" 10480093f4SDimitry Andric #include "clang/AST/Attr.h" 11*bdd1243dSDimitry Andric #include <optional> 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric using namespace clang; 140b57cec5SDimitry Andric using namespace tooling; 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric Expected<SelectedASTNode> evaluate(RefactoringRuleContext & Context) const170b57cec5SDimitry AndricASTSelectionRequirement::evaluate(RefactoringRuleContext &Context) const { 180b57cec5SDimitry Andric // FIXME: Memoize so that selection is evaluated only once. 190b57cec5SDimitry Andric Expected<SourceRange> Range = 200b57cec5SDimitry Andric SourceRangeSelectionRequirement::evaluate(Context); 210b57cec5SDimitry Andric if (!Range) 220b57cec5SDimitry Andric return Range.takeError(); 230b57cec5SDimitry Andric 24*bdd1243dSDimitry Andric std::optional<SelectedASTNode> Selection = 250b57cec5SDimitry Andric findSelectedASTNodes(Context.getASTContext(), *Range); 260b57cec5SDimitry Andric if (!Selection) 270b57cec5SDimitry Andric return Context.createDiagnosticError( 280b57cec5SDimitry Andric Range->getBegin(), diag::err_refactor_selection_invalid_ast); 290b57cec5SDimitry Andric return std::move(*Selection); 300b57cec5SDimitry Andric } 310b57cec5SDimitry Andric evaluate(RefactoringRuleContext & Context) const320b57cec5SDimitry AndricExpected<CodeRangeASTSelection> CodeRangeASTSelectionRequirement::evaluate( 330b57cec5SDimitry Andric RefactoringRuleContext &Context) const { 340b57cec5SDimitry Andric // FIXME: Memoize so that selection is evaluated only once. 350b57cec5SDimitry Andric Expected<SelectedASTNode> ASTSelection = 360b57cec5SDimitry Andric ASTSelectionRequirement::evaluate(Context); 370b57cec5SDimitry Andric if (!ASTSelection) 380b57cec5SDimitry Andric return ASTSelection.takeError(); 390b57cec5SDimitry Andric std::unique_ptr<SelectedASTNode> StoredSelection = 40a7dea167SDimitry Andric std::make_unique<SelectedASTNode>(std::move(*ASTSelection)); 41*bdd1243dSDimitry Andric std::optional<CodeRangeASTSelection> CodeRange = 42*bdd1243dSDimitry Andric CodeRangeASTSelection::create(Context.getSelectionRange(), 43*bdd1243dSDimitry Andric *StoredSelection); 440b57cec5SDimitry Andric if (!CodeRange) 450b57cec5SDimitry Andric return Context.createDiagnosticError( 460b57cec5SDimitry Andric Context.getSelectionRange().getBegin(), 470b57cec5SDimitry Andric diag::err_refactor_selection_invalid_ast); 480b57cec5SDimitry Andric Context.setASTSelection(std::move(StoredSelection)); 490b57cec5SDimitry Andric return std::move(*CodeRange); 500b57cec5SDimitry Andric } 51