ymandel updated this revision to Diff 197146. ymandel added a comment. Updated comment to more explicity describe motivation for new signature.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D61015/new/ https://reviews.llvm.org/D61015 Files: clang/include/clang/Tooling/Refactoring/Transformer.h clang/lib/Tooling/Refactoring/Transformer.cpp Index: clang/lib/Tooling/Refactoring/Transformer.cpp =================================================================== --- clang/lib/Tooling/Refactoring/Transformer.cpp +++ clang/lib/Tooling/Refactoring/Transformer.cpp @@ -157,12 +157,16 @@ Edit.Target, It->second, Edit.Kind, Edit.Part, *Result.Context); if (auto Err = RangeOrErr.takeError()) return std::move(Err); - Transformation T; - T.Range = *RangeOrErr; - if (T.Range.isInvalid() || - isOriginMacroBody(*Result.SourceManager, T.Range.getBegin())) + auto &Range = *RangeOrErr; + if (Range.isInvalid() || + isOriginMacroBody(*Result.SourceManager, Range.getBegin())) return SmallVector<Transformation, 0>(); - T.Replacement = Edit.Replacement(Result); + auto ReplacementOrErr = Edit.Replacement(Result); + if (auto Err = ReplacementOrErr.takeError()) + return std::move(Err); + Transformation T; + T.Range = Range; + T.Replacement = std::move(*ReplacementOrErr); Transformations.push_back(std::move(T)); } return Transformations; Index: clang/include/clang/Tooling/Refactoring/Transformer.h =================================================================== --- clang/include/clang/Tooling/Refactoring/Transformer.h +++ clang/include/clang/Tooling/Refactoring/Transformer.h @@ -44,12 +44,21 @@ Name, }; -using TextGenerator = - std::function<std::string(const ast_matchers::MatchFinder::MatchResult &)>; +// \c TextGenerator may fail, because it processes dynamically-bound match +// results. For example, a typo in the name of a bound node or a mismatch in +// the node's type can lead to a failure in the string generation code. We +// allow the generator to return \c Expected, rather than assert on such +// failures, so that the Transformer client can choose how to handle the error. +// For example, if used in a UI (for example, clang-query or a web app), in +// which the user specifies the rewrite rule, the backend might choose to return +// a diagnostic error, rather than crash. +using TextGenerator = std::function<Expected<std::string>( + const ast_matchers::MatchFinder::MatchResult &)>; -/// Wraps a string as a TextGenerator. +/// Wraps a string as a (trivially successful) TextGenerator. inline TextGenerator text(std::string M) { - return [M](const ast_matchers::MatchFinder::MatchResult &) { return M; }; + return [M](const ast_matchers::MatchFinder::MatchResult &) + -> Expected<std::string> { return M; }; } // Description of a source-code edit, expressed in terms of an AST node.
Index: clang/lib/Tooling/Refactoring/Transformer.cpp =================================================================== --- clang/lib/Tooling/Refactoring/Transformer.cpp +++ clang/lib/Tooling/Refactoring/Transformer.cpp @@ -157,12 +157,16 @@ Edit.Target, It->second, Edit.Kind, Edit.Part, *Result.Context); if (auto Err = RangeOrErr.takeError()) return std::move(Err); - Transformation T; - T.Range = *RangeOrErr; - if (T.Range.isInvalid() || - isOriginMacroBody(*Result.SourceManager, T.Range.getBegin())) + auto &Range = *RangeOrErr; + if (Range.isInvalid() || + isOriginMacroBody(*Result.SourceManager, Range.getBegin())) return SmallVector<Transformation, 0>(); - T.Replacement = Edit.Replacement(Result); + auto ReplacementOrErr = Edit.Replacement(Result); + if (auto Err = ReplacementOrErr.takeError()) + return std::move(Err); + Transformation T; + T.Range = Range; + T.Replacement = std::move(*ReplacementOrErr); Transformations.push_back(std::move(T)); } return Transformations; Index: clang/include/clang/Tooling/Refactoring/Transformer.h =================================================================== --- clang/include/clang/Tooling/Refactoring/Transformer.h +++ clang/include/clang/Tooling/Refactoring/Transformer.h @@ -44,12 +44,21 @@ Name, }; -using TextGenerator = - std::function<std::string(const ast_matchers::MatchFinder::MatchResult &)>; +// \c TextGenerator may fail, because it processes dynamically-bound match +// results. For example, a typo in the name of a bound node or a mismatch in +// the node's type can lead to a failure in the string generation code. We +// allow the generator to return \c Expected, rather than assert on such +// failures, so that the Transformer client can choose how to handle the error. +// For example, if used in a UI (for example, clang-query or a web app), in +// which the user specifies the rewrite rule, the backend might choose to return +// a diagnostic error, rather than crash. +using TextGenerator = std::function<Expected<std::string>( + const ast_matchers::MatchFinder::MatchResult &)>; -/// Wraps a string as a TextGenerator. +/// Wraps a string as a (trivially successful) TextGenerator. inline TextGenerator text(std::string M) { - return [M](const ast_matchers::MatchFinder::MatchResult &) { return M; }; + return [M](const ast_matchers::MatchFinder::MatchResult &) + -> Expected<std::string> { return M; }; } // Description of a source-code edit, expressed in terms of an AST node.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits