1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Lint.h"
18
19 #include <android-base/logging.h>
20 #include <json/json.h>
21 #include <iostream>
22 #include <tuple>
23
24 #include "Location.h"
25
26 namespace android {
Lint(LintLevel level,const Location & location,const std::string & message)27 Lint::Lint(LintLevel level, const Location& location, const std::string& message)
28 : mLevel(level), mLocation(location), mMessage(message) {}
29
getLevel() const30 LintLevel Lint::getLevel() const {
31 return mLevel;
32 }
33
getLevelString() const34 std::string Lint::getLevelString() const {
35 switch (mLevel) {
36 case WARNING:
37 return "WARNING";
38 case ERROR:
39 return "ERROR";
40 default:
41 LOG(FATAL) << "LintLevel must be warning or error";
42 }
43 }
44
getLocation() const45 const Location& Lint::getLocation() const {
46 return mLocation;
47 }
48
getMessage() const49 const std::string& Lint::getMessage() const {
50 return mMessage;
51 }
52
operator <(const Lint & other) const53 bool Lint::operator<(const Lint& other) const {
54 return std::tie(mLocation, mLevel, mMessage) <
55 std::tie(other.mLocation, other.mLevel, other.mMessage);
56 }
57
operator <<(const std::string & in)58 Lint&& Lint::operator<<(const std::string& in) {
59 mMessage += in;
60
61 return std::move(*this);
62 }
63
asJson() const64 Json::Value Lint::asJson() const {
65 Json::Value lint;
66
67 lint["message"] = mMessage;
68 lint["level"] = getLevelString();
69
70 // Begin and end should be in the same file
71 lint["filename"] = mLocation.begin().filename();
72 lint["begin"]["line"] = Json::UInt(mLocation.begin().line());
73 lint["begin"]["column"] = Json::UInt(mLocation.begin().column());
74 lint["end"]["line"] = Json::UInt(mLocation.end().line());
75 lint["end"]["column"] = Json::UInt(mLocation.end().column());
76
77 return lint;
78 }
79
80 enum Color { DEFAULT = 0, RED = 31, YELLOW = 33 };
81
setColor(Color color,bool bold=false)82 static std::string setColor(Color color, bool bold = false) {
83 std::string ret;
84 ret += "\033[";
85 if (bold) ret += "1";
86 if (bold && color != DEFAULT) ret += ";";
87 if (color != DEFAULT) ret += std::to_string(color);
88 ret += "m";
89
90 return ret;
91 }
92
operator <<(std::ostream & os,const Lint & lint)93 std::ostream& operator<<(std::ostream& os, const Lint& lint) {
94 if (lint.getLevel() == WARNING) {
95 os << setColor(YELLOW, true) << lint.getLevelString() << ": " << setColor(DEFAULT);
96 } else {
97 CHECK(lint.getLevel() == ERROR);
98 os << setColor(RED, true) << lint.getLevelString() << ": " << setColor(DEFAULT);
99 }
100
101 return os << setColor(DEFAULT, true) << lint.getLocation() << setColor(DEFAULT) << ": "
102 << lint.getMessage() << std::endl;
103 }
104 } // namespace android