UNPKG

magix

Version:

view manager framewrok

271 lines (269 loc) 9.74 kB
module.exports = function(content) { var idCounter = 0; var resolveComments = function(c) { var cs = c.split(/\r\n|\r|\n/); var o = { //isa: 'OBJECT' id: 'm' + (++idCounter) }, example; var processor = function(m, value) { var name; if (value.trim().charAt(0) == '@') { value = value.trim(); var space = value.indexOf(' '); name = space >= 0 ? value.substring(1, space) : value.substring(1); value = space >= 0 ? value.substring(space + 1) : ''; } if (!name && value) { if (example) { o.example = (o.example ? o.example + '\r\n' : '') + value; } else { o.desc = (o.desc ? o.desc + '\r\n' : '') + value; } } if (name == 'name') { o.name = value.trim(); } if (name == 'example') { example = 1; o.example = (o.example ? o.example + '\r\n' : '') + value; } if (name == 'borrows') { if (!o.inherits) o.inherits = []; value.replace(/([\s\S]+) as ([\s\S]+)/, function(m, a, b) { o.inherits.push({ alias: a, as: b }); }); } if (name == 'namespace') { o.isNamespace = true; } if (name == 'constructor') { o.isa = 'CONSTRUCTOR'; o.isClass = true; } if (name == 'property') { if (!o.properties) o.properties = []; value.replace(/\{([^\}]+)\}\s+([\w\.\$]+)\s*([\S\s]*)/, function(m, type, param, desc) { o.properties.push({ type: type, desc: desc, name: param, id: 'm' + (++idCounter) }); }); } if (name == 'param') { if (!o.params) o.params = []; var nameReg = /\s*\[([^\[\]]+)\]\s*/; value.replace(/\{([^\}]+)\}\s+([\w\.\[\]]+)\s*([\S\s]*)/, function(m, type, param, desc) { var ms = param.match(nameReg); var item = { type: type, desc: desc, name: param }; if (ms) { item.isOptional = true; item.name = ms[1]; } o.params.push(item); }); } if (name == 'event') { o.isEvent = true; if (o.name.indexOf('#') == -1 && o.name.indexOf('.prototype.') == -1) o.isStatic = true; o.name = o.name.replace(/^[\w\.]+[\.#]/, ''); } if (name == 'return' || name == 'returns') { o.returns = value; } if (name == 'beta') { o.isOptional = true; } if (name == 'module') { o.needModule = value.trim(); } if (name == 'lends') { o.lends = value.trim(); } }; for (var i = 0; i < cs.length; i++) { var line = cs[i]; line.replace(/\s*\*?([\s\S]*)/, processor); } if (o.example) o.example = o.example.trim(); return o; }; var block = function(str) { var flags = []; var index = 0; var blocks = []; var next = function() { return str.charAt(index + 1); }; var last = function() { var i = 1; while (!str.charAt(index - i).trim()) i++; return str.charAt(index - i); }; var skipUntil = function(a, whole) { while (true) { if (whole) { var s = str.substring(index, index + a.length); if (s == a) { index += a.length; break; } index++; } else { if (a.indexOf(str.charAt(++index)) >= 0 && last() != '\\') break; } } }; while (index < str.length) { var c = str.charAt(index); if (c == '{') { flags.push({ start: index }); } else if (c == '}') { var o = flags.pop(); if (o) { var s = str.substring(o.start, index + 1); if (s.indexOf('/**') > -1) { blocks.push(s); } } } if (c == '/') { //注释与正则相关 if (next() == '/') skipUntil('\r\n'); //单行注释 else if (next() == '*') skipUntil('*/', true); //多行注释 else if (last() == '=') { var lastIndex = index; skipUntil('/'); //上一个字符是=号,则是正则 index++; console.log('skip regex', str.substring(lastIndex, index)); } } index++; } blocks.pop(); //弹出最外层的define return blocks; }; var remain = function(blocks) { var remain = content; for (var i = blocks.length - 1; i >= 0; i--) { remain = remain.replace(blocks[i], ''); } return remain; }; var lends = function(o, name, block) { var reg = /\/\*\*([\s\S]+?)\*\/([^*\/]+?)[=:]/g; var isStatic = !/(?:#|\.prorotype)$/.test(name); var sname = name.replace(/(?:#|\.prototype)$/, ''); block.replace(reg, function(m, c, n) { if (!o.methods) o.methods = []; c = resolveComments(c); c.memberOf = sname; c.name = n.replace(/\s|(?:[\s\S]*?\.)/g, ''); if (isStatic && o.isa == 'CONSTRUCTOR') c.isStatic = true; o.methods.push(c); }); }; var root = function(remain) { var o = {}; var reg = /\/\*\*([\s\S]+?)\*\//g; var ls = []; remain.replace(reg, function(m, c) { c = resolveComments(c); // if (c.name) { o[c.name] = c; } if (c.lends) { //简单修正最外层的 var idx = remain.indexOf(m); var equal = remain.indexOf('*/', idx) + 2; equal = remain.indexOf('=', equal) + 1; ls.push({ name: c.lends, sname: c.lends.replace(/(?:#|\.prototype)$/, ''), block: remain.substring(idx, equal) }); } }); for (var i = 0, l; i < ls.length; i++) { l = ls[i]; if (o[l.sname]) { lends(o[l.sname], l.name, l.block); } } return o; }; var attach = function(root, blocks) { for (var i = 0; i < blocks.length; i++) { var block = blocks[i]; var m = block.match(/@lends\s+([\w#]+)/); var name = m && m[1]; if (name) { var sname = name.replace(/(?:#|\.prototype)$/, ''); block = block.replace(/\/\*[\s\S]*?@lends[\s\S]*?\*\//, ''); var o = root[sname]; block = block.replace(/\/\*\*([\s\S]+?)\*\//g, function(m, c) { c = resolveComments(c); c.memberOf = sname; if (c.isEvent) { if (!o.events) o.events = []; o.events.push(c); delete c.isEvent; return ''; } return m; }); lends(o, name, block); } } }; var cloneMethod = function(o) { var r = {}; for (var p in o) { r[p] = o[p]; } return r; }; var borrows = function(root) { for (var p in root) { var one = root[p]; if (one.inherits) { for (var i = 0; i < one.inherits.length; i++) { var ih = one.inherits[i]; var ts = ih.alias.split('.'); var name = ts[0]; var m = ts[1]; var target = root[name]; if (target) { var mds = target.methods; for (var j = mds.length - 1; j >= 0; j--) { var md = mds[j]; if (md.name == m) { md = cloneMethod(md); md.id = 'm' + (++idCounter); if (ih.as.indexOf('#') !== 0) md.isStatic = true; if (!one.methods) one.methods = []; one.methods.push(md); } } } } } } }; var bs = block(content); //根据大括号分区块 var rm = remain(bs); //分块后遗留的代码,主入口 var main = root(rm); //全局根对象或类 attach(main, bs); //处理借给 borrows(main); //处理借到 return main; };