Sort "deps" and "public_deps" when running the "gn format" command.

The "deps" and "public_deps" are sorted using the following order:
  1. litteral strings
    a. local targets, e.g. ":a",
    b. relative targets, e.g. "a" or "../a",
    c. absolute targets, e.g. "//a",
  2. other values, e.g. variable reference.

In each group, values are sorted alphabetically.

BUG=554928

Review URL: https://codereview.chromium.org/1496653002

Cr-Original-Commit-Position: refs/heads/master@{#362943}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: b502732dcdb76fae1e8c2f8ddc63a019e9a9ecdd
diff --git a/tools/gn/format_test_data/063.gn b/tools/gn/format_test_data/063.gn
index a933f4b..9fd8211 100644
--- a/tools/gn/format_test_data/063.gn
+++ b/tools/gn/format_test_data/063.gn
@@ -1,18 +1,36 @@
 source_set("test") {
+  a = "a"
+  b = "b"
   deps = [
-    "//c",
     "//a",
+    "//a/a",
+    "//a/b",
+    "//a:a",
+    "//a:b",
+    "//b",
+    ":a",
     ":b",
-    "../d",
+    "a",
+    "a/a",
+    "a/b",
+    "a:a",
+    "a:b",
+    "b",
+    a,
+    b,
   ]
 
   public_deps = []
   if (condition) {
     public_deps += [
-      "//y",
-      "//w",
-      ":x",
-      "../z",
+      "//a",
+      "//a/a",
+      "//a:a",
+      ":a",
+      "a",
+      "a/a",
+      "a:a",
+      a,
     ]
   }
 }
diff --git a/tools/gn/format_test_data/063.golden b/tools/gn/format_test_data/063.golden
index acf2843..3dc4bed 100644
--- a/tools/gn/format_test_data/063.golden
+++ b/tools/gn/format_test_data/063.golden
@@ -1,18 +1,36 @@
 source_set("test") {
+  a = "a"
+  b = "b"
   deps = [
+    ":a",
     ":b",
-    "../d",
+    "a",
+    "a:a",
+    "a:b",
+    "a/a",
+    "a/b",
+    "b",
     "//a",
-    "//c",
+    "//a:a",
+    "//a:b",
+    "//a/a",
+    "//a/b",
+    "//b",
+    a,
+    b,
   ]
 
   public_deps = []
   if (condition) {
     public_deps += [
-      ":x",
-      "../z",
-      "//w",
-      "//y",
+      ":a",
+      "a",
+      "a:a",
+      "a/a",
+      "//a",
+      "//a:a",
+      "//a/a",
+      a,
     ]
   }
 }
diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc
index d22adca..38133dd 100644
--- a/tools/gn/parse_tree.cc
+++ b/tools/gn/parse_tree.cc
@@ -16,6 +16,26 @@
 
 namespace {
 
+enum DepsCategory {
+  DEPS_CATEGORY_LOCAL,
+  DEPS_CATEGORY_RELATIVE,
+  DEPS_CATEGORY_ABSOLUTE,
+  DEPS_CATEGORY_OTHER,
+};
+
+DepsCategory GetDepsCategory(base::StringPiece deps) {
+  if (deps.length() < 2 || deps[0] != '"' || deps[deps.size() - 1] != '"')
+    return DEPS_CATEGORY_OTHER;
+
+  if (deps[1] == ':')
+    return DEPS_CATEGORY_LOCAL;
+
+  if (deps[1] == '/')
+    return DEPS_CATEGORY_ABSOLUTE;
+
+  return DEPS_CATEGORY_RELATIVE;
+}
+
 std::tuple<base::StringPiece, base::StringPiece> SplitAtFirst(
     base::StringPiece str,
     char c) {
@@ -590,7 +610,8 @@
   SortList([](const ParseNode* a, const ParseNode* b) {
     base::StringPiece astr = GetStringRepresentation(a);
     base::StringPiece bstr = GetStringRepresentation(b);
-    return SplitAtFirst(astr, ':') < SplitAtFirst(bstr, ':');
+    return std::make_pair(GetDepsCategory(astr), SplitAtFirst(astr, ':')) <
+           std::make_pair(GetDepsCategory(bstr), SplitAtFirst(bstr, ':'));
   });
 }