Output lints by location in file

Sort lints by their location within the file.

Fix: 134781118
Test: Visual
Change-Id: I5beed3a37e19cd03cffcf3f0f42848ec56ff7b04
diff --git a/Location.cpp b/Location.cpp
index 2d834fb..0bff1b2 100644
--- a/Location.cpp
+++ b/Location.cpp
@@ -17,6 +17,7 @@
 #include "Location.h"
 
 #include <android-base/logging.h>
+#include <tuple>
 
 namespace android {
 
@@ -40,11 +41,7 @@
 }
 
 bool Position::operator<(const Position& pos) const {
-    CHECK(inSameFile(*this, pos)) << "Cannot compare positions in different files";
-    if (mLine == pos.mLine) {
-        return mColumn < pos.mColumn;
-    }
-    return mLine < pos.mLine;
+    return std::tie(mFilename, mLine, mColumn) < std::tie(pos.mFilename, pos.mLine, pos.mColumn);
 }
 
 std::ostream& operator<<(std::ostream& ostr, const Position& pos) {
@@ -91,9 +88,7 @@
 }
 
 bool Location::operator<(const Location& loc) const {
-    CHECK(inSameFile(*this, loc)) << "Cannot compare locations in different files";
-    CHECK(!intersect(*this, loc));
-    return mEnd < loc.mBegin;
+    return std::tie(mBegin, mEnd) < std::tie(loc.mBegin, loc.mEnd);
 }
 
 std::ostream& operator<<(std::ostream& ostr, const Location& loc) {
diff --git a/Location.h b/Location.h
index 2e99ab8..7407b60 100644
--- a/Location.h
+++ b/Location.h
@@ -35,7 +35,6 @@
 
     static bool inSameFile(const Position& lhs, const Position& rhs);
 
-    // Precondition: inSameFile()
     bool operator<(const Position& pos) const;
 
    private:
@@ -64,7 +63,6 @@
     static bool inSameFile(const Location& lhs, const Location& rhs);
     static bool intersect(const Location& lhs, const Location& rhs);
 
-    // Precondition: inSameFile() && !intersect()
     bool operator<(const Location& loc) const;
 
    private:
diff --git a/lint/Lint.cpp b/lint/Lint.cpp
index 20a4e24..ad5a619 100644
--- a/lint/Lint.cpp
+++ b/lint/Lint.cpp
@@ -18,6 +18,7 @@
 
 #include <android-base/logging.h>
 #include <iostream>
+#include <tuple>
 
 #include "Location.h"
 
@@ -37,6 +38,11 @@
     return mMessage;
 }
 
+bool Lint::operator<(const Lint& other) const {
+    return std::tie(mLocation, mLevel, mMessage) <
+           std::tie(other.mLocation, other.mLevel, other.mMessage);
+}
+
 Lint&& Lint::operator<<(const std::string& in) {
     mMessage += in;
 
diff --git a/lint/Lint.h b/lint/Lint.h
index 53a057c..90040a7 100644
--- a/lint/Lint.h
+++ b/lint/Lint.h
@@ -41,6 +41,8 @@
     const Location& getLocation() const;
     const std::string& getMessage() const;
 
+    bool operator<(const Lint& other) const;
+
   private:
     LintLevel mLevel;
     Location mLocation;
diff --git a/lint/main.cpp b/lint/main.cpp
index a112a9c..4fbedc9 100644
--- a/lint/main.cpp
+++ b/lint/main.cpp
@@ -16,6 +16,7 @@
 
 #include <hidl-util/FQName.h>
 
+#include <algorithm>
 #include <iostream>
 #include <vector>
 
@@ -23,6 +24,7 @@
 #include "Coordinator.h"
 #include "Lint.h"
 #include "LintRegistry.h"
+#include "Location.h"
 
 using namespace android;
 
@@ -111,6 +113,8 @@
 
         if (!errors.empty())
             std::cerr << "Lints for: " << fqName.string() << std::endl << std::endl;
+
+        std::sort(errors.begin(), errors.end());
         for (const Lint& error : errors) {
             std::cerr << error;
         }