Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diviner/atom/DivinerAtom.php
12256 views
1
<?php
2
3
final class DivinerAtom extends Phobject {
4
5
const TYPE_ARTICLE = 'article';
6
const TYPE_CLASS = 'class';
7
const TYPE_FILE = 'file';
8
const TYPE_FUNCTION = 'function';
9
const TYPE_INTERFACE = 'interface';
10
const TYPE_METHOD = 'method';
11
12
private $type;
13
private $name;
14
private $file;
15
private $line;
16
private $hash;
17
private $contentRaw;
18
private $length;
19
private $language;
20
private $docblockRaw;
21
private $docblockText;
22
private $docblockMeta;
23
private $warnings = array();
24
private $parent;
25
private $parentHash;
26
private $children = array();
27
private $childHashes = array();
28
private $context;
29
private $extends = array();
30
private $links = array();
31
private $book;
32
private $properties = array();
33
34
/**
35
* Returns a sorting key which imposes an unambiguous, stable order on atoms.
36
*/
37
public function getSortKey() {
38
return implode(
39
"\0",
40
array(
41
$this->getBook(),
42
$this->getType(),
43
$this->getContext(),
44
$this->getName(),
45
$this->getFile(),
46
sprintf('%08d', $this->getLine()),
47
));
48
}
49
50
public function setBook($book) {
51
$this->book = $book;
52
return $this;
53
}
54
55
public function getBook() {
56
return $this->book;
57
}
58
59
public function setContext($context) {
60
$this->context = $context;
61
return $this;
62
}
63
64
public function getContext() {
65
return $this->context;
66
}
67
68
public static function getAtomSerializationVersion() {
69
return 2;
70
}
71
72
public function addWarning($warning) {
73
$this->warnings[] = $warning;
74
return $this;
75
}
76
77
public function getWarnings() {
78
return $this->warnings;
79
}
80
81
public function setDocblockRaw($docblock_raw) {
82
$this->docblockRaw = $docblock_raw;
83
84
if ($docblock_raw !== null) {
85
$parser = new PhutilDocblockParser();
86
list($text, $meta) = $parser->parse($docblock_raw);
87
$this->docblockText = $text;
88
$this->docblockMeta = $meta;
89
} else {
90
$this->docblockText = null;
91
$this->docblockMeta = null;
92
}
93
94
return $this;
95
}
96
97
public function getDocblockRaw() {
98
return $this->docblockRaw;
99
}
100
101
public function getDocblockText() {
102
if ($this->docblockText === null) {
103
throw new PhutilInvalidStateException('setDocblockRaw');
104
}
105
return $this->docblockText;
106
}
107
108
public function getDocblockMeta() {
109
if ($this->docblockMeta === null) {
110
throw new PhutilInvalidStateException('setDocblockRaw');
111
}
112
return $this->docblockMeta;
113
}
114
115
public function getDocblockMetaValue($key, $default = null) {
116
$meta = $this->getDocblockMeta();
117
return idx($meta, $key, $default);
118
}
119
120
public function setDocblockMetaValue($key, $value) {
121
$meta = $this->getDocblockMeta();
122
$meta[$key] = $value;
123
$this->docblockMeta = $meta;
124
return $this;
125
}
126
127
public function setType($type) {
128
$this->type = $type;
129
return $this;
130
}
131
132
public function getType() {
133
return $this->type;
134
}
135
136
public function setName($name) {
137
$this->name = $name;
138
return $this;
139
}
140
141
public function getName() {
142
return $this->name;
143
}
144
145
public function setFile($file) {
146
$this->file = $file;
147
return $this;
148
}
149
150
public function getFile() {
151
return $this->file;
152
}
153
154
public function setLine($line) {
155
$this->line = $line;
156
return $this;
157
}
158
159
public function getLine() {
160
return $this->line;
161
}
162
163
public function setContentRaw($content_raw) {
164
$this->contentRaw = $content_raw;
165
return $this;
166
}
167
168
public function getContentRaw() {
169
return $this->contentRaw;
170
}
171
172
public function setHash($hash) {
173
$this->hash = $hash;
174
return $this;
175
}
176
177
public function addLink(DivinerAtomRef $ref) {
178
$this->links[] = $ref;
179
return $this;
180
}
181
182
public function addExtends(DivinerAtomRef $ref) {
183
$this->extends[] = $ref;
184
return $this;
185
}
186
187
public function getLinkDictionaries() {
188
return mpull($this->links, 'toDictionary');
189
}
190
191
public function getExtendsDictionaries() {
192
return mpull($this->extends, 'toDictionary');
193
}
194
195
public function getExtends() {
196
return $this->extends;
197
}
198
199
public function getHash() {
200
if ($this->hash) {
201
return $this->hash;
202
}
203
204
$parts = array(
205
$this->getBook(),
206
$this->getType(),
207
$this->getName(),
208
$this->getFile(),
209
$this->getLine(),
210
$this->getLength(),
211
$this->getLanguage(),
212
$this->getContentRaw(),
213
$this->getDocblockRaw(),
214
$this->getProperties(),
215
$this->getChildHashes(),
216
mpull($this->extends, 'toHash'),
217
mpull($this->links, 'toHash'),
218
);
219
220
$this->hash = md5(serialize($parts)).'N';
221
return $this->hash;
222
}
223
224
public function setLength($length) {
225
$this->length = $length;
226
return $this;
227
}
228
229
public function getLength() {
230
return $this->length;
231
}
232
233
public function setLanguage($language) {
234
$this->language = $language;
235
return $this;
236
}
237
238
public function getLanguage() {
239
return $this->language;
240
}
241
242
public function addChildHash($child_hash) {
243
$this->childHashes[] = $child_hash;
244
return $this;
245
}
246
247
public function getChildHashes() {
248
if (!$this->childHashes && $this->children) {
249
$this->childHashes = mpull($this->children, 'getHash');
250
}
251
return $this->childHashes;
252
}
253
254
public function setParentHash($parent_hash) {
255
if ($this->parentHash) {
256
throw new Exception(pht('Atom already has a parent!'));
257
}
258
$this->parentHash = $parent_hash;
259
return $this;
260
}
261
262
public function hasParent() {
263
return $this->parent || $this->parentHash;
264
}
265
266
public function setParent(DivinerAtom $atom) {
267
if ($this->parentHash) {
268
throw new Exception(pht('Parent hash has already been computed!'));
269
}
270
$this->parent = $atom;
271
return $this;
272
}
273
274
public function getParentHash() {
275
if ($this->parent && !$this->parentHash) {
276
$this->parentHash = $this->parent->getHash();
277
}
278
return $this->parentHash;
279
}
280
281
public function addChild(DivinerAtom $atom) {
282
if ($this->childHashes) {
283
throw new Exception(pht('Child hashes have already been computed!'));
284
}
285
286
$atom->setParent($this);
287
$this->children[] = $atom;
288
return $this;
289
}
290
291
public function getURI() {
292
$parts = array();
293
$parts[] = phutil_escape_uri_path_component($this->getType());
294
if ($this->getContext()) {
295
$parts[] = phutil_escape_uri_path_component($this->getContext());
296
}
297
$parts[] = phutil_escape_uri_path_component($this->getName());
298
$parts[] = null;
299
return implode('/', $parts);
300
}
301
302
public function toDictionary() {
303
// NOTE: If you change this format, bump the format version in
304
// @{method:getAtomSerializationVersion}.
305
return array(
306
'book' => $this->getBook(),
307
'type' => $this->getType(),
308
'name' => $this->getName(),
309
'file' => $this->getFile(),
310
'line' => $this->getLine(),
311
'hash' => $this->getHash(),
312
'uri' => $this->getURI(),
313
'length' => $this->getLength(),
314
'context' => $this->getContext(),
315
'language' => $this->getLanguage(),
316
'docblockRaw' => $this->getDocblockRaw(),
317
'warnings' => $this->getWarnings(),
318
'parentHash' => $this->getParentHash(),
319
'childHashes' => $this->getChildHashes(),
320
'extends' => $this->getExtendsDictionaries(),
321
'links' => $this->getLinkDictionaries(),
322
'ref' => $this->getRef()->toDictionary(),
323
'properties' => $this->getProperties(),
324
);
325
}
326
327
public function getRef() {
328
$title = null;
329
if ($this->docblockMeta) {
330
$title = $this->getDocblockMetaValue('title');
331
}
332
333
return id(new DivinerAtomRef())
334
->setBook($this->getBook())
335
->setContext($this->getContext())
336
->setType($this->getType())
337
->setName($this->getName())
338
->setTitle($title)
339
->setGroup($this->getProperty('group'));
340
}
341
342
public static function newFromDictionary(array $dictionary) {
343
$atom = id(new DivinerAtom())
344
->setBook(idx($dictionary, 'book'))
345
->setType(idx($dictionary, 'type'))
346
->setName(idx($dictionary, 'name'))
347
->setFile(idx($dictionary, 'file'))
348
->setLine(idx($dictionary, 'line'))
349
->setHash(idx($dictionary, 'hash'))
350
->setLength(idx($dictionary, 'length'))
351
->setContext(idx($dictionary, 'context'))
352
->setLanguage(idx($dictionary, 'language'))
353
->setParentHash(idx($dictionary, 'parentHash'))
354
->setDocblockRaw(idx($dictionary, 'docblockRaw'))
355
->setProperties(idx($dictionary, 'properties'));
356
357
foreach (idx($dictionary, 'warnings', array()) as $warning) {
358
$atom->addWarning($warning);
359
}
360
361
foreach (idx($dictionary, 'childHashes', array()) as $child) {
362
$atom->addChildHash($child);
363
}
364
365
foreach (idx($dictionary, 'extends', array()) as $extends) {
366
$atom->addExtends(DivinerAtomRef::newFromDictionary($extends));
367
}
368
369
return $atom;
370
}
371
372
public function getProperty($key, $default = null) {
373
return idx($this->properties, $key, $default);
374
}
375
376
public function setProperty($key, $value) {
377
$this->properties[$key] = $value;
378
return $this;
379
}
380
381
public function getProperties() {
382
return $this->properties;
383
}
384
385
public function setProperties(array $properties) {
386
$this->properties = $properties;
387
return $this;
388
}
389
390
public static function getThisAtomIsNotDocumentedString($type) {
391
switch ($type) {
392
case self::TYPE_ARTICLE:
393
return pht('This article is not documented.');
394
case self::TYPE_CLASS:
395
return pht('This class is not documented.');
396
case self::TYPE_FILE:
397
return pht('This file is not documented.');
398
case self::TYPE_FUNCTION:
399
return pht('This function is not documented.');
400
case self::TYPE_INTERFACE:
401
return pht('This interface is not documented.');
402
case self::TYPE_METHOD:
403
return pht('This method is not documented.');
404
default:
405
phlog(pht("Need translation for '%s'.", $type));
406
return pht('This %s is not documented.', $type);
407
}
408
}
409
410
public static function getAllTypes() {
411
return array(
412
self::TYPE_ARTICLE,
413
self::TYPE_CLASS,
414
self::TYPE_FILE,
415
self::TYPE_FUNCTION,
416
self::TYPE_INTERFACE,
417
self::TYPE_METHOD,
418
);
419
}
420
421
public static function getAtomTypeNameString($type) {
422
switch ($type) {
423
case self::TYPE_ARTICLE:
424
return pht('Article');
425
case self::TYPE_CLASS:
426
return pht('Class');
427
case self::TYPE_FILE:
428
return pht('File');
429
case self::TYPE_FUNCTION:
430
return pht('Function');
431
case self::TYPE_INTERFACE:
432
return pht('Interface');
433
case self::TYPE_METHOD:
434
return pht('Method');
435
default:
436
phlog(pht("Need translation for '%s'.", $type));
437
return ucwords($type);
438
}
439
}
440
441
}
442
443