1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_LABEL_H_ 6 #define TOOLS_GN_LABEL_H_ 7 8 #include <string_view> 9 #include <tuple> 10 11 #include <stddef.h> 12 13 #include "gn/source_dir.h" 14 #include "gn/string_atom.h" 15 16 class Err; 17 class Value; 18 19 // A label represents the name of a target or some other named thing in 20 // the source path. The label is always absolute and always includes a name 21 // part, so it starts with a slash, and has one colon. 22 class Label { 23 public: 24 Label(); 25 26 // Makes a label given an already-separated out path and name. 27 // See also Resolve(). 28 Label(const SourceDir& dir, 29 std::string_view name, 30 const SourceDir& toolchain_dir, 31 std::string_view toolchain_name); 32 33 // Makes a label with an empty toolchain. 34 Label(const SourceDir& dir, std::string_view name); 35 36 // Resolves a string from a build file that may be relative to the 37 // current directory into a fully qualified label. On failure returns an 38 // is_null() label and sets the error. 39 static Label Resolve(const SourceDir& current_dir, 40 std::string_view source_root, 41 const Label& current_toolchain, 42 const Value& input, 43 Err* err); 44 is_null()45 bool is_null() const { return dir_.is_null(); } 46 dir()47 const SourceDir& dir() const { return dir_; } name()48 const std::string& name() const { return name_.str(); } name_atom()49 StringAtom name_atom() const { return name_; } 50 toolchain_dir()51 const SourceDir& toolchain_dir() const { return toolchain_dir_; } toolchain_name()52 const std::string& toolchain_name() const { return toolchain_name_.str(); } toolchain_name_atom()53 StringAtom toolchain_name_atom() const { return toolchain_name_; } 54 55 // Returns the current label's toolchain as its own Label. 56 Label GetToolchainLabel() const; 57 58 // Returns a copy of this label but with an empty toolchain. 59 Label GetWithNoToolchain() const; 60 61 // Formats this label in a way that we can present to the user or expose to 62 // other parts of the system. SourceDirs end in slashes, but the user 63 // expects names like "//chrome/renderer:renderer_config" when printed. The 64 // toolchain is optionally included. 65 std::string GetUserVisibleName(bool include_toolchain) const; 66 67 // Like the above version, but automatically includes the toolchain if it's 68 // not the default one. Normally the user only cares about the toolchain for 69 // non-default ones, so this can make certain output more clear. 70 std::string GetUserVisibleName(const Label& default_toolchain) const; 71 72 bool operator==(const Label& other) const { 73 return hash_ == other.hash_ && name_.SameAs(other.name_) && 74 dir_ == other.dir_ && toolchain_dir_ == other.toolchain_dir_ && 75 toolchain_name_.SameAs(other.toolchain_name_); 76 } 77 bool operator!=(const Label& other) const { return !operator==(other); } 78 bool operator<(const Label& other) const { 79 // This custom comparison function uses the fact that SourceDir and 80 // StringAtom values have very fast equality comparison to avoid 81 // un-necessary string comparisons when components are equal. 82 if (dir_ != other.dir_) 83 return dir_ < other.dir_; 84 85 if (!name_.SameAs(other.name_)) 86 return name_ < other.name_; 87 88 if (toolchain_dir_ != other.toolchain_dir_) 89 return toolchain_dir_ < other.toolchain_dir_; 90 91 return toolchain_name_ < other.toolchain_name_; 92 } 93 94 // Returns true if the toolchain dir/name of this object matches some 95 // other object. ToolchainsEqual(const Label & other)96 bool ToolchainsEqual(const Label& other) const { 97 return toolchain_dir_ == other.toolchain_dir_ && 98 toolchain_name_.SameAs(other.toolchain_name_); 99 } 100 hash()101 size_t hash() const { return hash_; } 102 103 private: Label(SourceDir dir,StringAtom name)104 Label(SourceDir dir, StringAtom name) 105 : dir_(dir), name_(name), hash_(ComputeHash()) {} 106 Label(SourceDir dir,StringAtom name,SourceDir toolchain_dir,StringAtom toolchain_name)107 Label(SourceDir dir, 108 StringAtom name, 109 SourceDir toolchain_dir, 110 StringAtom toolchain_name) 111 : dir_(dir), 112 name_(name), 113 toolchain_dir_(toolchain_dir), 114 toolchain_name_(toolchain_name), 115 hash_(ComputeHash()) {} 116 ComputeHash()117 size_t ComputeHash() const { 118 size_t h0 = dir_.hash(); 119 size_t h1 = name_.ptr_hash(); 120 size_t h2 = toolchain_dir_.hash(); 121 size_t h3 = toolchain_name_.ptr_hash(); 122 return ((h3 * 131 + h2) * 131 + h1) * 131 + h0; 123 } 124 125 SourceDir dir_; 126 StringAtom name_; 127 128 SourceDir toolchain_dir_; 129 StringAtom toolchain_name_; 130 131 size_t hash_; 132 // NOTE: Must be initialized by constructors with ComputeHash() value. 133 }; 134 135 namespace std { 136 137 template <> 138 struct hash<Label> { 139 std::size_t operator()(const Label& v) const { return v.hash(); } 140 }; 141 142 } // namespace std 143 144 extern const char kLabels_Help[]; 145 146 #endif // TOOLS_GN_LABEL_H_ 147