UNPKG

x-function

Version:

Extension of Function Class in JsDK

164 lines (138 loc) 5.48 kB
((metaClass,_F)=>{ metaClass.delegate=function(ctx){ var that=this; return function(){ with (ctx){ eval(that.body()) } } }; metaClass.arrowBody=function(){ const matches = this.toString().match(/^(?:\s*\(?(?:\s*\w*\s*,?\s*)*\)?\s*?=>\s*){?([\s\S]*)}?$/); if (!matches) { return null; } const firstPass = matches[1]; // Needed because the RegExp doesn't handle the last '}'. const secondPass = (firstPass.match(/{/g) || []).length === (firstPass.match(/}/g) || []).length - 1 ? firstPass.slice(0, firstPass.lastIndexOf('}')) : firstPass return secondPass; }; metaClass.classicBody=function(){ return this.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]; } metaClass.body=function(){ if(this.toString().replace(/\s+/g, '').indexOf(')=>')>=1){ return this.arrowBody(); }else{ return this.classicBody(); } } metaClass.bodyWihoutChildrenfunctions=function(){ var reducer=this.toString().reduceWhiteSpace(); // console.log(reducer) this.childrenfunctionsNames().map(function(e,i){ var posFName=reducer.indexOf('function '+e)+('function '+e).length; var from=reducer.indexOf('function '+e); var indexFeteh=reducer.indexOf('{',posFName); var indexCloser=appContext.utils.closeddiama(indexFeteh,reducer,1); //var openerArgs=reducer.indexOf('(',posFName); // var closerArgs=appContext.utils.closeddiama(openerArgs,reducer,1); // console.log(indexFeteh); //console.log(indexCloser); reducer=reducer.replaceAll(reducer.substr(from,indexCloser-from+1),'') return {from:reducer.indexOf('function '+e),to:indexCloser} //return {name:e,body:reducer.substring(indexFeteh+1,indexCloser),args:reducer.substring(openerArgs+1,closerArgs)} }); return reducer; }; /** * @depends on appContext rabeeJS * @returns {metaClass@call;childrenfunctionsNames@call;map} */ metaClass.childrenfunctionsBodies=function(){ var reducer=this.toString().reduceWhiteSpace(); // console.log(reducer) return this.childrenfunctionsNames().map(function(e,i){ var posFName=reducer.indexOf('function '+e)+('function '+e).length; var indexFeteh=reducer.indexOf('{',posFName); var indexCloser=appContext.utils.closeddiama(indexFeteh,reducer,1); var openerArgs=reducer.indexOf('(',posFName); var closerArgs=appContext.utils.closeddiama(openerArgs,reducer,1); // console.log(indexFeteh); //console.log(indexCloser); return {name:e,body:reducer.substring(indexFeteh+1,indexCloser),args:reducer.substring(openerArgs+1,closerArgs)} }); }; metaClass.childrenfunctionsNames = function(nested) { function tokenize(code) { var code = code.split(/\\./).join(''), regex = /\bfunction\b|\(|\)|\{|\}|\/\*|\*\/|\/\/|"|'|\n|\s+/mg, tokens = [], pos = 0; for (var matches; matches = regex.exec(code); pos = regex.lastIndex) { var match = matches[0], matchStart = regex.lastIndex - match.length; if (pos < matchStart) tokens.push(code.substring(pos, matchStart)); tokens.push(match); } if (pos < code.length) tokens.push(code.substring(pos)); return tokens; } var separators = { '/*': '*/', '//': '\n', '"': '"', '\'': '\'' }; function extractInnerFunctionNames(func, nested) { var names = [], tokens = tokenize(func.toString()), level = 0; for (var i = 0; i < tokens.length; ++i) { var token = tokens[i]; switch (token) { case '{': ++level; break; case '}': --level; break; case '/*': case '//': case '"': case '\'': var sep = separators[token]; while (++i < tokens.length && tokens[i] !== sep) ; break; case 'function': if (level === 1 || (nested && level)) { while (++i < tokens.length) { token = tokens[i]; if (token === '(') break; if (/^\s+$/.test(token)) continue; if (token === '/*' || token === '//') { var sep = separators[token]; while (++i < tokens.length && tokens[i] !== sep) ; continue; } names.push(token); break; } } break; } } return names; }; return extractInnerFunctionNames(this,nested); }; })(Function.prototype,Function)