1 // Copyright 2014 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 #include <regex>
6 #include "gn/err.h"
7 #include "gn/filesystem_utils.h"
8 #include "gn/functions.h"
9 #include "gn/label.h"
10 #include "gn/parse_tree.h"
11 #include "gn/value.h"
12 #include "ohos_components.h"
13
14 namespace functions {
15
16 const char kGetLabelInfo[] = "get_label_info";
17 const char kGetLabelInfo_HelpShort[] =
18 "get_label_info: Get an attribute from a target's label.";
19 const char kGetLabelInfo_Help[] =
20 R"*(get_label_info: Get an attribute from a target's label.
21
22 get_label_info(target_label, what)
23
24 Given the label of a target, returns some attribute of that target. The
25 target need not have been previously defined in the same file, since none of
26 the attributes depend on the actual target definition, only the label itself.
27
28 See also "gn help get_target_outputs".
29
30 Possible values for the "what" parameter
31
32 "name"
33 The short name of the target. This will match the value of the
34 "target_name" variable inside that target's declaration. For the label
35 "//foo/bar:baz" this will return "baz".
36
37 "dir"
38 The directory containing the target's definition, with no slash at the
39 end. For the label "//foo/bar:baz" this will return "//foo/bar".
40
41 "target_gen_dir"
42 The generated file directory for the target. This will match the value of
43 the "target_gen_dir" variable when inside that target's declaration.
44
45 "root_gen_dir"
46 The root of the generated file tree for the target. This will match the
47 value of the "root_gen_dir" variable when inside that target's
48 declaration.
49
50 "target_out_dir
51 The output directory for the target. This will match the value of the
52 "target_out_dir" variable when inside that target's declaration.
53
54 "root_out_dir"
55 The root of the output file tree for the target. This will match the
56 value of the "root_out_dir" variable when inside that target's
57 declaration.
58
59 "label_no_toolchain"
60 The fully qualified version of this label, not including the toolchain.
61 For the input ":bar" it might return "//foo:bar".
62
63 "label_with_toolchain"
64 The fully qualified version of this label, including the toolchain. For
65 the input ":bar" it might return "//foo:bar(//toolchain:x64)".
66
67 "toolchain"
68 The label of the toolchain. This will match the value of the
69 "current_toolchain" variable when inside that target's declaration.
70
71 Examples
72
73 get_label_info(":foo", "name")
74 # Returns string "foo".
75
76 get_label_info("//foo/bar:baz", "target_gen_dir")
77 # Returns string "//out/Debug/gen/foo/bar".
78 )*";
79
getComponentLabel(const std::string & target_label,const BuildSettings * settings)80 std::string getComponentLabel(const std::string& target_label,
81 const BuildSettings* settings) {
82 std::string pattern = R"(^[a-zA-Z0-9_]+:[a-zA-Z0-9_.-]+(?:\([\\\$\{\}a-zA-Z0-9._/:-]+\))?$)";
83 std::regex regexPattern(pattern);
84 if (std::regex_match(target_label, regexPattern)) {
85 size_t pos = target_label.find(':');
86 std::string component_str = target_label.substr(0, pos);
87 std::string innner_api_str = target_label.substr(pos + 1);
88 size_t toolchain_pos = innner_api_str.find("(");
89 const OhosComponent* component =
90 settings->GetOhosComponentByName(component_str);
91 if (component) {
92 if(toolchain_pos != std::string::npos){
93 std::string innner_api = innner_api_str.substr(0, toolchain_pos);
94 std::string toolchain_suffix = innner_api_str.substr(toolchain_pos);
95 std::string parsed_target = component->getInnerApi(innner_api);
96 std::string parsed_innerapi = parsed_target + toolchain_suffix;
97 return parsed_innerapi;
98 } else{
99 std::string parsed_innerapi = component->getInnerApi(innner_api_str);
100 return parsed_innerapi;
101 }
102 }
103 }
104 return {};
105 }
106
RunGetLabelInfo(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)107 Value RunGetLabelInfo(Scope* scope,
108 const FunctionCallNode* function,
109 const std::vector<Value>& args,
110 Err* err) {
111 if (args.size() != 2) {
112 *err = Err(function, "Expected two arguments.");
113 return Value();
114 }
115
116 // Resolve the requested label.
117 const BuildSettings* buildSettings = scope->settings()->build_settings();
118 Label label;
119 std::string target = args[0].string_value();
120 bool resolved = false;
121 // [OHOS] Resolve component info first
122 if (!target.empty()) {
123 const std::string& label_str = getComponentLabel(target, buildSettings);
124 if (!label_str.empty()) {
125 const Value& value = Value(args[0].origin(), label_str);
126 label =
127 Label::Resolve(scope->GetSourceDir(), buildSettings->root_path_utf8(),
128 ToolchainLabelForScope(scope), value, err);
129 resolved = true;
130 }
131 }
132 if (!resolved) {
133 label =
134 Label::Resolve(scope->GetSourceDir(), buildSettings->root_path_utf8(),
135 ToolchainLabelForScope(scope), args[0], err);
136 }
137 if (label.is_null())
138 return Value();
139
140 // Extract the "what" parameter.
141 if (!args[1].VerifyTypeIs(Value::STRING, err))
142 return Value();
143 const std::string& what = args[1].string_value();
144
145 Value result(function, Value::STRING);
146 if (what == "name") {
147 result.string_value() = label.name();
148
149 } else if (what == "dir") {
150 result.string_value() = DirectoryWithNoLastSlash(label.dir());
151
152 } else if (what == "target_gen_dir") {
153 result.string_value() = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir(
154 BuildDirContext(scope, label.GetToolchainLabel()), label.dir(),
155 BuildDirType::GEN));
156
157 } else if (what == "root_gen_dir") {
158 result.string_value() = DirectoryWithNoLastSlash(GetBuildDirAsSourceDir(
159 BuildDirContext(scope, label.GetToolchainLabel()), BuildDirType::GEN));
160
161 } else if (what == "target_out_dir") {
162 result.string_value() = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir(
163 BuildDirContext(scope, label.GetToolchainLabel()), label.dir(),
164 BuildDirType::OBJ));
165
166 } else if (what == "root_out_dir") {
167 result.string_value() = DirectoryWithNoLastSlash(GetBuildDirAsSourceDir(
168 BuildDirContext(scope, label.GetToolchainLabel()),
169 BuildDirType::TOOLCHAIN_ROOT));
170
171 } else if (what == "toolchain") {
172 result.string_value() = label.GetToolchainLabel().GetUserVisibleName(false);
173
174 } else if (what == "label_no_toolchain") {
175 result.string_value() =
176 label.GetWithNoToolchain().GetUserVisibleName(false);
177
178 } else if (what == "label_with_toolchain") {
179 result.string_value() = label.GetUserVisibleName(true);
180
181 } else {
182 *err = Err(args[1], "Unknown value for \"what\" parameter.");
183 return Value();
184 }
185
186 return result;
187 }
188
189 } // namespace functions
190