blob: 26ab468c69d2b729323b7877e2776ae796977c41 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fidl/findings_json.h"
namespace fidl {
void FindingsJson::Generate(const Finding& finding) {
GenerateObject([&]() {
GenerateObjectMember("category", "fidl-lint/" + finding.subcategory(), Position::kFirst);
GenerateObjectMember("message", finding.message());
// TODO(fxbug.dev/7990) Add "url" to related FIDL documentation, per Tricium spec
Generate(finding.span());
std::vector<SuggestionWithReplacementSpan> suggestions;
if (finding.suggestion().has_value()) {
suggestions.emplace_back(
SuggestionWithReplacementSpan{finding.span(), finding.suggestion().value()});
}
GenerateObjectMember("suggestions", suggestions);
});
}
void FindingsJson::Generate(const SuggestionWithReplacementSpan& suggestion_with_span) {
auto& suggestion = suggestion_with_span.suggestion;
auto& span = suggestion_with_span.span;
GenerateObject([&]() {
GenerateObjectMember("description", suggestion.description(), Position::kFirst);
std::vector<Replacement> replacements;
if (suggestion.replacement().has_value()) {
replacements.emplace_back(Replacement{span, suggestion.replacement().value()});
}
GenerateObjectMember("replacements", replacements);
});
}
void FindingsJson::Generate(const Replacement& replacement) {
GenerateObject([&]() {
GenerateObjectMember("replacement", replacement.replacement, Position::kFirst);
Generate(replacement.span);
});
}
void FindingsJson::Generate(const SourceSpan& span) {
GenerateObjectMember("path", span.source_file().filename());
auto start = span.data();
auto end = span.data();
end.remove_prefix(start.size());
// Gracefully handle a span indicating the end of the file.
//
// If the span starts at the end of the file, `end_span` should be the same as
// `span`, or calling SourceSpan::position() will attempt to read past the end
// of the source file.
SourceSpan end_span;
auto end_of_file = span.source_file().data().data() + span.source_file().data().size();
if (start.data() == end_of_file) {
end_span = span;
} else {
end_span = SourceSpan(end, span.source_file());
}
SourceFile::Position start_position = span.position();
SourceFile::Position end_position = end_span.position();
GenerateObjectMember("start_line", static_cast<uint32_t>(start_position.line));
GenerateObjectMember("start_char", static_cast<uint32_t>(start_position.column - 1));
GenerateObjectMember("end_line", static_cast<uint32_t>(end_position.line));
GenerateObjectMember("end_char", static_cast<uint32_t>(end_position.column - 1));
}
std::ostringstream FindingsJson::Produce() {
ResetIndentLevel();
GenerateArray(findings_);
return std::move(json_file_);
}
} // namespace fidl