• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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