blob: ab9b9432d094ebab59e5d036cd1310a2f2095d96 [file] [log] [blame]
Cary Clark8032b982017-07-28 11:04:54 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Cary Clark1a8d7622018-03-05 13:26:16 -05008#include "SkOSPath.h"
Cary Clark8032b982017-07-28 11:04:54 -04009
Cary Clark2da9fb82018-11-01 09:29:36 -040010#include "bmhParser.h"
11#include "fiddleParser.h"
12#include "mdOut.h"
13#include "includeWriter.h"
14#include "selfCheck.h"
Cary Clark09d80c02018-10-31 12:14:03 -040015
Cary Clark2f466242017-12-11 16:03:17 -050016DEFINE_string2(status, a, "", "File containing status of documentation. (Use in place of -b -i)");
Cary Clarkbc5697d2017-10-04 14:31:33 -040017DEFINE_string2(bmh, b, "", "Path to a *.bmh file or a directory.");
Cary Clarkbef063a2017-10-31 15:44:45 -040018DEFINE_bool2(catalog, c, false, "Write example catalog.htm. (Requires -b -f -r)");
Cary Clarkbc5697d2017-10-04 14:31:33 -040019DEFINE_string2(examples, e, "", "File of fiddlecli input, usually fiddle.json (For now, disables -r -f -s)");
Cary Clark3bdaa462018-10-31 16:16:54 -040020DEFINE_bool2(extract, E, false, "Extract examples into fiddle.json");
Cary Clarkbc5697d2017-10-04 14:31:33 -040021DEFINE_string2(fiddle, f, "", "File of fiddlecli output, usually fiddleout.json.");
Cary Clark5081eed2018-01-22 07:55:48 -050022DEFINE_bool2(hack, H, false, "Do a find/replace hack to update all *.bmh files. (Requires -b)");
23// h is reserved for help
Cary Clarkbc5697d2017-10-04 14:31:33 -040024DEFINE_string2(include, i, "", "Path to a *.h file or a directory.");
Cary Clarkac47b882018-01-11 10:35:44 -050025DEFINE_bool2(selfcheck, k, false, "Check bmh against itself. (Requires -b)");
Cary Clarkbc5697d2017-10-04 14:31:33 -040026DEFINE_bool2(stdout, o, false, "Write file out to standard out.");
27DEFINE_bool2(populate, p, false, "Populate include from bmh. (Requires -b -i)");
Cary Clark5081eed2018-01-22 07:55:48 -050028// q is reserved for quiet
Cary Clark7cfcbca2018-01-04 16:11:51 -050029DEFINE_string2(ref, r, "", "Resolve refs and write *.md files to path. (Requires -b -f)");
Cary Clarkbc5697d2017-10-04 14:31:33 -040030DEFINE_string2(spellcheck, s, "", "Spell-check [once, all, mispelling]. (Requires -b)");
Cary Clarka560c472017-11-27 10:44:06 -050031DEFINE_bool2(tokens, t, false, "Write bmh from include. (Requires -b -i)");
Cary Clarkbc5697d2017-10-04 14:31:33 -040032DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)");
Cary Clark5081eed2018-01-22 07:55:48 -050033// v is reserved for verbose
Cary Clark682c58d2018-05-16 07:07:07 -040034DEFINE_bool2(validate, V, false, "Validate that all anchor references have definitions. (Requires -r)");
Cary Clark884dd7d2017-10-11 10:37:52 -040035DEFINE_bool2(skip, z, false, "Skip degenerate missed in legacy preprocessor.");
Cary Clark8032b982017-07-28 11:04:54 -040036
Cary Clark09d80c02018-10-31 12:14:03 -040037// -b docs -i include/core/SkRect.h -f fiddleout.json -r site/user/api
38// -b docs/SkIRect_Reference.bmh -H
Cary Clark682c58d2018-05-16 07:07:07 -040039/* todos:
Cary Clark8032b982017-07-28 11:04:54 -040040
Cary Clarka90ea222018-10-16 10:30:28 -040041if #Subtopic contains #SeeAlso or #Example generate horizontal rule at end
42constexpr populated with filter inside subtopic does not have definition body
43
Cary Clark8032b982017-07-28 11:04:54 -040044#List needs '# content ##', formatting
Cary Clark186d08f2018-04-03 08:43:27 -040045rewrap text to fit in some number of columns
46#Literal is inflexible, making the entire #Code block link-less (see $Literal in SkImageInfo)
Cary Clark80247e52018-07-11 16:18:41 -040047 would rather keep links for body above #Literal, and/or make it a block and not a one-liner
Cary Clark682c58d2018-05-16 07:07:07 -040048add check to require #Const to contain #Code block if defining const or constexpr (enum consts have
Cary Clark80247e52018-07-11 16:18:41 -040049 #Code blocks inside the #Enum def)
Cary Clarkd2ca79c2018-08-10 13:09:13 -040050subclasses (e.g. Iter in SkPath) need to check for #Line and generate overview
51 subclass methods should also disallow #In
Cary Clark682c58d2018-05-16 07:07:07 -040052
Cary Clark682c58d2018-05-16 07:07:07 -040053It's awkward that phrase param is a child of the phrase def. Since phrase refs may also be children,
54there is special case code to skip phrase def when looking for additional substitutions in the
55phrase def. Could put it in the token list instead I guess, or make a definition subclass used
56by phrase def with an additional slot...
57
Cary Clark682c58d2018-05-16 07:07:07 -040058rearrange const out for md so that const / value / short description comes first in a table,
59followed by more elaborate descriptions, examples, seealso. In md.cpp, look to see if #Subtopic
60has #Const children. If so, generate a summary table first.
61Or, only allow #Line and moderate text description in #Const. Put more verbose text, example,
62seealso, in subsequent #SubTopic. Alpha_Type does this and it looks good.
63
Cary Clark61313f32018-10-08 14:57:48 -040064IPoint is awkward. SkPoint and SkIPoint are named things; Point is a topic, which
65refers to float points or integer points. There needn't be an IPoint topic.
66One way to resolve this would be to combine SkPoint_Reference and SkIPoint_Reference into
67Point_Reference that then contains both structs (or just move SKIPoint into SkPoint_Reference).
68Most Point references would be replaced with SkPoint / SkIPoint (if that's what they mean),
69or remain Point if the text indicates the concept rather one of the C structs.
70
Cary Clarkac47b882018-01-11 10:35:44 -050071see head of selfCheck.cpp for additional todos
Cary Clark80247e52018-07-11 16:18:41 -040072see head of spellCheck.cpp for additional todos
Cary Clark8032b982017-07-28 11:04:54 -040073 */
74
Ben Wagner63fd7602017-10-09 15:45:33 -040075/*
Cary Clark8032b982017-07-28 11:04:54 -040076 class contains named struct, enum, enum-member, method, topic, subtopic
77 everything contained by class is uniquely named
78 contained names may be reused by other classes
79 method contains named parameters
80 parameters may be reused in other methods
81 */
82
Cary Clark8032b982017-07-28 11:04:54 -040083
84// pass one: parse text, collect definitions
85// pass two: lookup references
86
Cary Clark8032b982017-07-28 11:04:54 -040087static int count_children(const Definition& def, MarkType markType) {
88 int count = 0;
89 if (markType == def.fMarkType) {
90 ++count;
91 }
92 for (auto& child : def.fChildren ) {
93 count += count_children(*child, markType);
94 }
95 return count;
96}
97
98int main(int argc, char** const argv) {
Cary Clarka560c472017-11-27 10:44:06 -050099 BmhParser bmhParser(FLAGS_skip);
Cary Clark8032b982017-07-28 11:04:54 -0400100 bmhParser.validate();
101
102 SkCommandLineFlags::SetUsage(
Cary Clarka560c472017-11-27 10:44:06 -0500103 "Common Usage: bookmaker -b path/to/bmh_files -i path/to/include.h -t\n"
Cary Clark8032b982017-07-28 11:04:54 -0400104 " bookmaker -b path/to/bmh_files -e fiddle.json\n"
105 " ~/go/bin/fiddlecli --input fiddle.json --output fiddleout.json\n"
106 " bookmaker -b path/to/bmh_files -f fiddleout.json -r path/to/md_files\n"
Cary Clark2f466242017-12-11 16:03:17 -0500107 " bookmaker -a path/to/status.json -x\n"
108 " bookmaker -a path/to/status.json -p\n");
Cary Clark8032b982017-07-28 11:04:54 -0400109 bool help = false;
110 for (int i = 1; i < argc; i++) {
111 if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i])) {
112 help = true;
113 for (int j = i + 1; j < argc; j++) {
114 if (SkStrStartsWith(argv[j], '-')) {
115 break;
116 }
117 help = false;
118 }
119 break;
120 }
121 }
122 if (!help) {
123 SkCommandLineFlags::Parse(argc, argv);
124 } else {
125 SkCommandLineFlags::PrintUsage();
Cary Clarkac47b882018-01-11 10:35:44 -0500126 const char* const commands[] = { "", "-h", "bmh", "-h", "examples", "-h", "include",
127 "-h", "fiddle", "-h", "ref", "-h", "status", "-h", "tokens",
Cary Clark8032b982017-07-28 11:04:54 -0400128 "-h", "crosscheck", "-h", "populate", "-h", "spellcheck" };
Cary Clark7265ea32017-09-14 12:12:32 -0400129 SkCommandLineFlags::Parse(SK_ARRAY_COUNT(commands), commands);
Cary Clark8032b982017-07-28 11:04:54 -0400130 return 0;
131 }
Cary Clark3bdaa462018-10-31 16:16:54 -0400132 bool runAll = false;
Cary Clark2f466242017-12-11 16:03:17 -0500133 if (FLAGS_bmh.isEmpty() && FLAGS_include.isEmpty() && FLAGS_status.isEmpty()) {
Cary Clark3bdaa462018-10-31 16:16:54 -0400134 FLAGS_status.set(0, "docs/status.json");
135 if (FLAGS_extract) {
136 FLAGS_examples.set(0, "fiddle.json");
137 } else {
138 FLAGS_fiddle.set(0, "fiddleout.json");
139 FLAGS_ref.set(0, "site/user/api");
140 runAll = true;
141 }
Cary Clark8032b982017-07-28 11:04:54 -0400142 }
Cary Clark2f466242017-12-11 16:03:17 -0500143 if (!FLAGS_bmh.isEmpty() && !FLAGS_status.isEmpty()) {
144 SkDebugf("requires -b or -a but not both\n");
Cary Clarkbef063a2017-10-31 15:44:45 -0400145 SkCommandLineFlags::PrintUsage();
146 return 1;
147 }
Cary Clark2f466242017-12-11 16:03:17 -0500148 if (!FLAGS_include.isEmpty() && !FLAGS_status.isEmpty()) {
149 SkDebugf("requires -i or -a but not both\n");
150 SkCommandLineFlags::PrintUsage();
151 return 1;
152 }
153 if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && FLAGS_catalog) {
154 SkDebugf("-c requires -b or -a\n");
155 SkCommandLineFlags::PrintUsage();
156 return 1;
157 }
158 if ((FLAGS_fiddle.isEmpty() || FLAGS_ref.isEmpty()) && FLAGS_catalog) {
159 SkDebugf("-c requires -f -r\n");
160 SkCommandLineFlags::PrintUsage();
161 return 1;
162 }
163 if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_examples.isEmpty()) {
164 SkDebugf("-e requires -b or -a\n");
Cary Clark8032b982017-07-28 11:04:54 -0400165 SkCommandLineFlags::PrintUsage();
166 return 1;
167 }
Cary Clark2f466242017-12-11 16:03:17 -0500168 if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_status.isEmpty() &&
169 FLAGS_populate) {
170 SkDebugf("-p requires -b -i or -a\n");
Cary Clark8032b982017-07-28 11:04:54 -0400171 SkCommandLineFlags::PrintUsage();
172 return 1;
173 }
Cary Clark2f466242017-12-11 16:03:17 -0500174 if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_ref.isEmpty()) {
175 SkDebugf("-r requires -b or -a\n");
Cary Clark8032b982017-07-28 11:04:54 -0400176 SkCommandLineFlags::PrintUsage();
177 return 1;
178 }
Cary Clark2f466242017-12-11 16:03:17 -0500179 if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty() && !FLAGS_spellcheck.isEmpty()) {
180 SkDebugf("-s requires -b or -a\n");
Cary Clark8032b982017-07-28 11:04:54 -0400181 SkCommandLineFlags::PrintUsage();
182 return 1;
183 }
Cary Clarka560c472017-11-27 10:44:06 -0500184 if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_tokens) {
185 SkDebugf("-t requires -b -i\n");
Cary Clark8032b982017-07-28 11:04:54 -0400186 SkCommandLineFlags::PrintUsage();
187 return 1;
188 }
Cary Clark2f466242017-12-11 16:03:17 -0500189 if ((FLAGS_include.isEmpty() || FLAGS_bmh.isEmpty()) && FLAGS_status.isEmpty() &&
190 FLAGS_crosscheck) {
191 SkDebugf("-x requires -b -i or -a\n");
Cary Clark8032b982017-07-28 11:04:54 -0400192 SkCommandLineFlags::PrintUsage();
193 return 1;
194 }
Cary Clarkac47b882018-01-11 10:35:44 -0500195 bmhParser.reset();
Cary Clark8032b982017-07-28 11:04:54 -0400196 if (!FLAGS_bmh.isEmpty()) {
Cary Clark2dc84ad2018-01-26 12:56:22 -0500197 if (FLAGS_tokens) {
198 IncludeParser::RemoveFile(FLAGS_bmh[0], FLAGS_include[0]);
199 }
Cary Clark186d08f2018-04-03 08:43:27 -0400200 if (!bmhParser.parseFile(FLAGS_bmh[0], ".bmh", ParserCommon::OneFile::kNo)) {
Cary Clark8032b982017-07-28 11:04:54 -0400201 return -1;
202 }
Cary Clark2f466242017-12-11 16:03:17 -0500203 } else if (!FLAGS_status.isEmpty()) {
Cary Clark2f466242017-12-11 16:03:17 -0500204 if (!bmhParser.parseStatus(FLAGS_status[0], ".bmh", StatusFilter::kInProgress)) {
205 return -1;
206 }
Cary Clark8032b982017-07-28 11:04:54 -0400207 }
Cary Clarkab2621d2018-01-30 10:08:57 -0500208 if (FLAGS_hack) {
Cary Clark09d80c02018-10-31 12:14:03 -0400209 if (FLAGS_bmh.isEmpty() && FLAGS_status.isEmpty()) {
210 SkDebugf("-H or --hack requires -a or -b\n");
Cary Clarkab2621d2018-01-30 10:08:57 -0500211 SkCommandLineFlags::PrintUsage();
212 return 1;
213 }
214 HackParser hacker(bmhParser);
Cary Clark09d80c02018-10-31 12:14:03 -0400215 hacker.fDebugOut = FLAGS_stdout;
216 if (!FLAGS_status.isEmpty() && !hacker.parseStatus(FLAGS_status[0], ".bmh",
217 StatusFilter::kInProgress)) {
218 SkDebugf("hack failed\n");
219 return -1;
220 }
221 if (!FLAGS_bmh.isEmpty() && !hacker.parseFile(FLAGS_bmh[0], ".bmh",
222 ParserCommon::OneFile::kNo)) {
Cary Clarkab2621d2018-01-30 10:08:57 -0500223 SkDebugf("hack failed\n");
224 return -1;
225 }
226 return 0;
227 }
Cary Clarkac47b882018-01-11 10:35:44 -0500228 if (FLAGS_selfcheck && !SelfCheck(bmhParser)) {
229 return -1;
230 }
Cary Clark3bdaa462018-10-31 16:16:54 -0400231 if (!FLAGS_fiddle.isEmpty() && FLAGS_examples.isEmpty()) {
Cary Clarkbef063a2017-10-31 15:44:45 -0400232 FiddleParser fparser(&bmhParser);
Cary Clarkd7895502018-07-18 15:10:08 -0400233 if (!fparser.parseFromFile(FLAGS_fiddle[0])) {
Cary Clark8032b982017-07-28 11:04:54 -0400234 return -1;
235 }
236 }
Cary Clark3bdaa462018-10-31 16:16:54 -0400237 if (runAll || (!FLAGS_catalog && !FLAGS_ref.isEmpty())) {
Cary Clark186d08f2018-04-03 08:43:27 -0400238 IncludeParser includeParser;
239 includeParser.validate();
Cary Clark61313f32018-10-08 14:57:48 -0400240 if (!FLAGS_status.isEmpty() && !includeParser.parseStatus(FLAGS_status[0], ".h",
241 StatusFilter::kCompleted)) {
242 return -1;
243 }
Cary Clark186d08f2018-04-03 08:43:27 -0400244 if (!FLAGS_include.isEmpty() && !includeParser.parseFile(FLAGS_include[0], ".h",
245 ParserCommon::OneFile::kYes)) {
246 return -1;
247 }
Cary Clarka90ea222018-10-16 10:30:28 -0400248 includeParser.writeCodeBlock();
Cary Clark61313f32018-10-08 14:57:48 -0400249 MdOut mdOut(bmhParser, includeParser);
Cary Clark9174bda2017-09-19 17:39:32 -0400250 mdOut.fDebugOut = FLAGS_stdout;
Cary Clark682c58d2018-05-16 07:07:07 -0400251 mdOut.fValidate = FLAGS_validate;
Cary Clark61313f32018-10-08 14:57:48 -0400252 if (!FLAGS_bmh.isEmpty() && mdOut.buildReferences(FLAGS_bmh[0], FLAGS_ref[0])) {
Cary Clark2f466242017-12-11 16:03:17 -0500253 bmhParser.fWroteOut = true;
254 }
255 if (!FLAGS_status.isEmpty() && mdOut.buildStatus(FLAGS_status[0], FLAGS_ref[0])) {
Cary Clarkd0530ba2017-09-14 11:25:39 -0400256 bmhParser.fWroteOut = true;
257 }
Cary Clark682c58d2018-05-16 07:07:07 -0400258 if (FLAGS_validate) {
259 mdOut.checkAnchors();
260 }
Cary Clark8032b982017-07-28 11:04:54 -0400261 }
Cary Clark2da9fb82018-11-01 09:29:36 -0400262 if (runAll || (FLAGS_catalog && !FLAGS_ref.isEmpty())) {
Cary Clark3bdaa462018-10-31 16:16:54 -0400263 Catalog cparser(&bmhParser);
264 cparser.fDebugOut = FLAGS_stdout;
265 if (!FLAGS_bmh.isEmpty() && !cparser.openCatalog(FLAGS_bmh[0])) {
266 return -1;
267 }
268 if (!FLAGS_status.isEmpty() && !cparser.openStatus(FLAGS_status[0])) {
269 return -1;
270 }
271 if (!cparser.parseFile(FLAGS_fiddle[0], ".txt", ParserCommon::OneFile::kNo)) {
272 return -1;
273 }
274 if (!cparser.closeCatalog(FLAGS_ref[0])) {
275 return -1;
276 }
277 bmhParser.fWroteOut = true;
278 }
279 if (FLAGS_tokens) {
280 IncludeParser includeParser;
281 includeParser.validate();
282 if (!includeParser.parseFile(FLAGS_include[0], ".h", ParserCommon::OneFile::kNo)) {
283 return -1;
284 }
285 includeParser.fDebugOut = FLAGS_stdout;
286 if (includeParser.dumpTokens()) {
287 bmhParser.fWroteOut = true;
288 }
289 }
290 if (runAll || FLAGS_crosscheck) {
291 IncludeParser includeParser;
292 includeParser.validate();
293 if (!FLAGS_include.isEmpty() &&
294 !includeParser.parseFile(FLAGS_include[0], ".h", ParserCommon::OneFile::kNo)) {
295 return -1;
296 }
297 if (!FLAGS_status.isEmpty() && !includeParser.parseStatus(FLAGS_status[0], ".h",
298 StatusFilter::kCompleted)) {
299 return -1;
300 }
301 if (!includeParser.crossCheck(bmhParser)) {
302 return -1;
303 }
304 }
305 if (runAll || FLAGS_populate) {
306 IncludeWriter includeWriter;
307 includeWriter.validate();
308 if (!FLAGS_include.isEmpty() &&
309 !includeWriter.parseFile(FLAGS_include[0], ".h", ParserCommon::OneFile::kNo)) {
310 return -1;
311 }
312 if (!FLAGS_status.isEmpty() && !includeWriter.parseStatus(FLAGS_status[0], ".h",
313 StatusFilter::kCompleted)) {
314 return -1;
315 }
316 includeWriter.fDebugOut = FLAGS_stdout;
317 if (!includeWriter.populate(bmhParser)) {
318 return -1;
319 }
320 bmhParser.fWroteOut = true;
321 }
322 if (!FLAGS_spellcheck.isEmpty()) {
Cary Clark2f466242017-12-11 16:03:17 -0500323 if (!FLAGS_bmh.isEmpty()) {
324 bmhParser.spellCheck(FLAGS_bmh[0], FLAGS_spellcheck);
325 }
326 if (!FLAGS_status.isEmpty()) {
327 bmhParser.spellStatus(FLAGS_status[0], FLAGS_spellcheck);
328 }
Cary Clark154beea2017-10-26 07:58:48 -0400329 bmhParser.fWroteOut = true;
Cary Clark8032b982017-07-28 11:04:54 -0400330 }
Cary Clark3bdaa462018-10-31 16:16:54 -0400331 if (!FLAGS_examples.isEmpty()) {
Cary Clark73fa9722017-08-29 17:36:51 -0400332 // check to see if examples have duplicate names
333 if (!bmhParser.checkExamples()) {
Cary Clark8032b982017-07-28 11:04:54 -0400334 return -1;
335 }
Cary Clark9174bda2017-09-19 17:39:32 -0400336 bmhParser.fDebugOut = FLAGS_stdout;
Cary Clark73fa9722017-08-29 17:36:51 -0400337 if (!bmhParser.dumpExamples(FLAGS_examples[0])) {
338 return -1;
Cary Clark8032b982017-07-28 11:04:54 -0400339 }
Cary Clarkd0530ba2017-09-14 11:25:39 -0400340 return 0;
Cary Clark8032b982017-07-28 11:04:54 -0400341 }
Cary Clarkd0530ba2017-09-14 11:25:39 -0400342 if (!bmhParser.fWroteOut) {
Cary Clark3bdaa462018-10-31 16:16:54 -0400343 int examples = 0;
344 int methods = 0;
345 int topics = 0;
Cary Clarkd0530ba2017-09-14 11:25:39 -0400346 for (const auto& topic : bmhParser.fTopicMap) {
347 if (topic.second->fParent) {
348 continue;
349 }
350 examples += count_children(*topic.second, MarkType::kExample);
351 methods += count_children(*topic.second, MarkType::kMethod);
352 topics += count_children(*topic.second, MarkType::kSubtopic);
353 topics += count_children(*topic.second, MarkType::kTopic);
Cary Clark8032b982017-07-28 11:04:54 -0400354 }
Ben Wagner63fd7602017-10-09 15:45:33 -0400355 SkDebugf("topics=%d classes=%d methods=%d examples=%d\n",
Cary Clarkd0530ba2017-09-14 11:25:39 -0400356 bmhParser.fTopicMap.size(), bmhParser.fClassMap.size(),
357 methods, examples);
Cary Clark8032b982017-07-28 11:04:54 -0400358 }
Cary Clark8032b982017-07-28 11:04:54 -0400359 return 0;
360}
Cary Clark09d80c02018-10-31 12:14:03 -0400361
362void NameMap::copyToParent(NameMap* parent) const {
363 size_t colons = fName.rfind("::");
364 string topName = string::npos == colons ? fName : fName.substr(colons + 2);
365 for (auto& entry : fRefMap) {
366 string scoped = topName + "::" + entry.first;
367 SkASSERT(parent->fRefMap.end() == parent->fRefMap.find(scoped));
368 parent->fRefMap[scoped] = entry.second;
369 auto scopedLinkIter = fLinkMap.find(entry.first);
370 if (fLinkMap.end() != scopedLinkIter) {
371 SkASSERT(parent->fLinkMap.end() == parent->fLinkMap.find(scoped));
372 parent->fLinkMap[scoped] = scopedLinkIter->second;
373 }
374 }
375}
Cary Clark77b3f3a2018-11-07 14:59:03 -0500376
377void NameMap::setParams(Definition* bmhDef, Definition* iMethod) {
378 Definition* pParent = bmhDef->csParent();
379 string parentName;
380 if (pParent) {
381 parentName = pParent->fName + "::";
382 fParent = &pParent->asRoot()->fNames;
383 }
384 fName = parentName + iMethod->fName;
385 TextParser methParams(iMethod);
386 for (auto& param : iMethod->fTokens) {
387 if (MarkType::kComment != param.fMarkType) {
388 continue;
389 }
390 TextParser paramParser(&param);
391 if (!paramParser.skipExact("@param ")) { // write parameters, if any
392 continue;
393 }
394 paramParser.skipSpace();
395 const char* start = paramParser.fChar;
396 paramParser.skipToSpace();
397 string paramName(start, paramParser.fChar - start);
398 #ifdef SK_DEBUG
399 for (char c : paramName) {
400 SkASSERT(isalnum(c) || '_' == c);
401 }
402 #endif
403 if (!methParams.containsWord(paramName.c_str(), methParams.fEnd, nullptr)) {
404 param.reportError<void>("mismatched param name");
405 }
406 fRefMap[paramName] = &param;
407 fLinkMap[paramName] = '#' + bmhDef->fFiddle + '_' + paramName;
408 }
409}
410