OLD | NEW |
| (Empty) |
1 /* | |
2 * @license | |
3 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | |
4 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | |
5 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | |
6 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | |
7 * Code distributed by Google as part of the polymer project is also | |
8 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | |
9 */ | |
10 | |
11 (function(scope) { | |
12 | |
13 var ContextFreeParser = { | |
14 parse: function(text) { | |
15 var top = {}; | |
16 var entities = []; | |
17 var current = top; | |
18 var subCurrent = {}; | |
19 | |
20 var scriptDocCommentClause = '\\/\\*\\*([\\s\\S]*?)\\*\\/'; | |
21 var htmlDocCommentClause = '<!--([\\s\\S]*?)-->'; | |
22 | |
23 // matches text between /** and */ inclusive and <!-- and --> inclusive | |
24 var docCommentRegex = new RegExp(scriptDocCommentClause + '|' + htmlDocCom
mentClause, 'g'); | |
25 | |
26 // acquire all script doc comments | |
27 var docComments = text.match(docCommentRegex) || []; | |
28 | |
29 // each match represents a single block of doc comments | |
30 docComments.forEach(function(m) { | |
31 // unify line ends, remove all comment characters, split into individual
lines | |
32 var lines = m.replace(/\r\n/g, '\n').replace(/^\s*\/\*\*|^\s*\*\/|^\s*\*
?|^\s*\<\!-\-|^s*\-\-\>/gm, '').split('\n'); | |
33 | |
34 // pragmas (@-rules) must occur on a line by themselves | |
35 var pragmas = []; | |
36 // filter lines whose first non-whitespace character is @ into the pragm
a list | |
37 // (and out of the `lines` array) | |
38 lines = lines.filter(function(l) { | |
39 var m = l.match(/\s*@([\w-]*) (.*)/); | |
40 if (!m) { | |
41 return true; | |
42 } | |
43 pragmas.push(m); | |
44 }); | |
45 | |
46 // collect all other text into a single block | |
47 var code = lines.join('\n'); | |
48 | |
49 // process pragmas | |
50 pragmas.forEach(function(m) { | |
51 var pragma = m[1], content = m[2]; | |
52 switch (pragma) { | |
53 | |
54 // currently all entities are either @class or @element | |
55 case 'class': | |
56 case 'element': | |
57 current = { | |
58 name: content, | |
59 description: code | |
60 }; | |
61 entities.push(current); | |
62 break; | |
63 | |
64 // an entity may have these describable sub-features | |
65 case 'attribute': | |
66 case 'property': | |
67 case 'method': | |
68 case 'event': | |
69 subCurrent = { | |
70 name: content, | |
71 description: code | |
72 }; | |
73 var label = pragma == 'property' ? 'properties' : pragma + 's'; | |
74 makePragma(current, label, subCurrent); | |
75 break; | |
76 | |
77 // sub-feature pragmas | |
78 case 'default': | |
79 case 'type': | |
80 subCurrent[pragma] = content; | |
81 break; | |
82 | |
83 case 'param': | |
84 var eventParmsRe = /\{(.+)\}\s+(\w+[.\w+]+)\s+(.*)$/; | |
85 | |
86 var params = content.match(eventParmsRe); | |
87 if (params) { | |
88 var subEventObj = { | |
89 type: params[1], | |
90 name: params[2], | |
91 description: params[3] | |
92 }; | |
93 makePragma(subCurrent, pragma + 's', subEventObj); | |
94 } | |
95 | |
96 break; | |
97 | |
98 // everything else | |
99 default: | |
100 current[pragma] = content; | |
101 break; | |
102 } | |
103 }); | |
104 | |
105 // utility function, yay hoisting | |
106 function makePragma(object, pragma, content) { | |
107 var p$ = object; | |
108 var p = p$[pragma]; | |
109 if (!p) { | |
110 p$[pragma] = p = []; | |
111 } | |
112 p.push(content); | |
113 } | |
114 | |
115 }); | |
116 | |
117 if (entities.length === 0) { | |
118 entities.push({name: 'Entity', description: '**Undocumented**'}); | |
119 } | |
120 return entities; | |
121 } | |
122 }; | |
123 | |
124 if (typeof module !== 'undefined' && module.exports) { | |
125 module.exports = ContextFreeParser; | |
126 } else { | |
127 scope.ContextFreeParser = ContextFreeParser; | |
128 } | |
129 | |
130 })(this); | |
OLD | NEW |