SCAST MCP Server
by davidkingzyb
Verified
- SCAST
- lib
var SCASTPY=function(){var types={num:false,kw:false,id:false,str:false,punc:false,sp:false,op:false,t:false,Comment:false,ClassDefine:true,MethodDefine:true,PropertyDefine:true,Variable:true,CallExpression:true,FunctionDefine:true,LoopStatement:true,IfStatement:true,BlockStatement:true,Expression:false,Condition:false,Arguments:false,Arg:false,ArrayExpression:true,ObjectExpression:true,TupleExpression:true,WithStatement:true,MemberExpression:true,TryStatement:true,ExceptStatement:true,FinallyStatement:true,Lambda:true};function TokenStream(input){var current=null;var pykeywords=["False","None","True","and","as","assert","async","await","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","nonlocal","not","or","pass","raise","return","try","while","with","yield"];return{next:next,peek:peek,eof:eof,croak:input.croak};function is_keyword(x){return pykeywords.indexOf(x)>=0}function is_digit(ch){return/[0-9]/i.test(ch)}function is_id_start(ch){return/[a-zA-Z$_@]/i.test(ch)}function is_id(ch){return is_id_start(ch)||"0123456789".indexOf(ch)>=0}function is_op_char(ch){return"+-*/%=&|<>!^\\".indexOf(ch)>=0}function is_punc(ch){return"(){}[]".indexOf(ch)>=0}function is_whitespace(ch){return" \t".indexOf(ch)>=0}function is_split(ch){return",;.:?".indexOf(ch)>=0}function read_while(predicate){var str="";while(!input.eof()&&predicate(input.peek()))str+=input.next();return str}function read_number(){var has_dot=false;var number=read_while(function(ch){if(ch=="."){if(has_dot)return false;has_dot=true;return true}return is_digit(ch)});return{type:"num",value:parseFloat(number),poi:{line:start.line,start:start.column,end:input.poi().column}}}function read_ident(){var id=read_while(is_id);return{type:is_keyword(id)?"kw":"id",value:id,poi:{line:start.line,start:start.column,end:input.poi().column}}}function read_escaped(end){var escaped=false,str="";input.next();while(!input.eof()){var ch=input.next();if(escaped){str+=ch;escaped=false}else if(ch=="\\"){escaped=true}else if(ch==end){break}else{str+=ch}}return str}function read_string(ch){return{type:"str",value:read_escaped(ch),poi:{line:start.line,start:start.column,end:input.poi().column}}}function read_indentation(predicate){var str="";input.next();while(!input.eof()&&predicate(input.peek())){str+=input.next()}return{type:"t",value:str,poi:{line:start.line,start:start.column,end:input.poi().column}}}function skip_comment(){read_while(function(ch){return ch!="\n"});input.next()}var start;function read_next(){read_while(is_whitespace);if(input.eof())return null;var ch=input.peek();start=input.poi();if(ch=="\n")return read_indentation(is_whitespace);if(ch=="#"||ch=="/"&&input.peek(1)=="/"){return{type:"Comment",value:read_while(function(ch){return ch!="\n"}),poi:{line:start.line,start:start.column,end:input.poi().column}}}if(ch=='"')return read_string('"');if(ch=="'")return read_string("'");if(is_digit(ch))return read_number();if(is_id_start(ch))return read_ident();if(is_punc(ch))return{type:"punc",value:input.next(),poi:{line:start.line,start:start.column,end:input.poi().column}};if(is_split(ch))return{type:"sp",value:input.next(),poi:{line:start.line,start:start.column,end:input.poi().column}};if(is_op_char(ch))return{type:"op",value:read_while(is_op_char),poi:{line:start.line,start:start.column,end:input.poi().column}};input.croak(`Can't handle character :${ch}(${ch.charCodeAt(0)})`)}function peek(){return current||(current=read_next())}function next(){var tok=current;current=null;return tok||read_next()}function eof(){return peek()==null}}function InputStream(input){var pos=0,line=1,col=0;return{next:next,peek:peek,eof:eof,croak:croak,poi:poi};function next(){var ch=input.charAt(pos++);if(ch=="\n")line++,col=0;else col++;return ch}function peek(i=0){return input.charAt(pos+i)}function poi(){return{line:line,column:col,pos:pos}}function eof(){return peek()==""}function croak(msg){throw new Error(msg+" ("+line+":"+col+")")}}function parse(input){var isclass=false;return parse_toplevel();function is_kw(kw){var tok=input.peek();return tok&&tok.type=="kw"&&(!kw||tok.value==kw)&&tok}function is_punc(ch){var tok=input.peek();return tok&&tok.type=="punc"&&(!ch||tok.value==ch)&&tok}function is_sp(ch){var tok=input.peek();return tok&&tok.type=="sp"&&(!ch||tok.value==ch)&&tok}function is_kw(kw){var tok=input.peek();return tok&&tok.type=="kw"&&(!kw||tok.value==kw)&&tok}function is_op(op){var tok=input.peek();return tok&&tok.type=="op"&&(!op||tok.value==op)&&tok}function is_id(){var tok=input.peek();return tok.type=="id"}function is_num(){var tok=input.peek();return tok.type=="num"}function is_str(){var tok=input.peek();return tok.type=="str"}function skip_punc(ch){if(is_punc(ch))input.next();else input.croak('Expecting punctuation: "'+ch+'"')}function skip_split(ch){if(is_sp(ch))input.next();else input.croak('Expecting punctuation: "'+ch+'"')}function parse_next(){var n=input.next();return n}function parse_toplevel(){var prog=[];while(!input.eof()){prog.push(parse_statement())}return{type:"top",body:prog}}function parse_id(iscls){var n=input.next();if(is_punc("(")){var r={type:"CallExpression",value:n.value,poi:{line:n.poi.line,start:n.poi.start},body:[parse_arguments()]};return r}else if(is_op("=")||is_op("+=")||is_op("-=")||is_op("*=")||is_op("/=")||is_op("%=")||is_op("**=")||is_op("//=")){input.next();var r={type:"Variable",value:n.value,poi:{line:n.poi.line,start:n.poi.start},body:[parse_expression()]};if(iscls)r.type="PropertyDefine";return r}else if(is_sp(".")){input.next();let nn=input.peek();var r={type:"MemberExpression",value:n.value,poi:{line:nn.poi.line,start:nn.poi.start},body:[parse_expression()]};return r}else{return n}}function parse_arg(){if(is_sp(","))return skip_split(",");let n=null;if(is_id()){n=input.next();if(is_punc("(")){return{type:"CallExpression",value:n.value,poi:{line:n.poi.line,start:n.poi.start},body:[parse_arguments()]}}}else if(is_kw("lambda")){return parse_lambda()}else{n=input.next()}return{type:"Arg",value:n.value,node:n,poi:n.poi}}function parse_arguments(){var r={type:"Arguments",body:[],poi:{line:input.peek().poi.line,start:input.peek().poi.start},value:""};skip_punc("(");while(!is_punc(")")){var sts=parse_arg();if(sts){r.value+=sts.value+" ";r.body.push(sts)}}skip_punc(")");return r}function parse_block(iscls){var poi={line:input.peek().poi.line,start:input.peek().poi.start};var body=[];input.next();var indentation=input.peek();while(indentation.type!="t"||indentation.value.length===0){indentation=input.next()}while(input.peek()&&(input.peek().type!="t"||input.peek().type=="t"&&input.peek().value==indentation.value)){var sts=parse_statement(iscls);sts&&body.push(sts)}return{type:"BlockStatement",body:body,poi:poi,indentation:indentation}}function parse_function(){input.next();var r={type:"FunctionDefine",value:input.peek().value,poi:{start:input.peek().poi.start,line:input.peek().poi.line}};input.next();if(is_punc("("))r.arguments=parse_arguments();if(is_op("->")){input.next();r.return=input.peek();while(!is_sp(":"))input.next()}if(is_sp(":"))r.body=parse_block().body;for(let arg of r.arguments.body){if(arg.value=="self"&&isclass){r.type="MethodDefine";break}}return r}function parse_class(){input.next();var r={type:"ClassDefine",value:input.peek().value,poi:{start:input.peek().poi.start,line:input.peek().poi.line},extends:[]};input.next();if(is_punc("(")){while(!is_punc(")")){let p=input.next();if(is_id()){r.extends.push(input.peek())}}skip_punc(")")}isclass=true;if(is_sp(":"))r.body=parse_block(true).body;console.log("class",r,isclass);isclass=false;return r}function parse_condition(){var r={type:"Condition",poi:{line:input.peek().poi.line,start:input.peek().poi.start},value:"",body:[]};while(!is_sp(":")){let n=null;if(is_id()){r.value+=input.peek().value+" ";n=input.next();if(is_punc("(")){r.body.push({type:"CallExpression",value:n.value,poi:{line:n.poi.line,start:n.poi.start},body:[parse_arguments()]})}continue}else{n=input.next()}r.value+=n.value+" ";r.body.push(n)}return r}function parse_if(){var n=input.next();var r={type:"IfStatement",poi:{line:n.poi.line,start:n.poi.start},value:n.value};if(is_sp(":")){r.body=parse_block().body}else{r.condition=parse_condition();if(is_sp(":")){r.body=parse_block().body}return r}return r}function parse_try(){var n=input.next();var r={type:"TryStatement",poi:{line:n.poi.line,start:n.poi.start},value:n.value,body:parse_block().body};return r}function parse_finally(){var n=input.next();var r={type:"FinallyStatement",poi:{line:n.poi.line,start:n.poi.start},value:n.value,body:parse_block().body};return r}function parse_except(){var n=input.next();var r={type:"ExceptStatement",poi:{line:n.poi.line,start:n.poi.start},value:n.value};r.condition=parse_condition();if(is_sp(":")){r.body=parse_block().body}return r}function parse_loop(){var n=input.next();var r={type:"LoopStatement",value:n.value,poi:{line:n.poi.line,start:n.poi.start},condition:parse_condition()};if(is_sp(":"))r.body=parse_block().body;return r}function parse_list(){var n=input.next();var end="]";var body=[];var poi={line:n.poi.line,start:n.poi.start};var str="";while(input.peek().value!=end){let nn=input.next();if(is_punc("["))body.push(parse_list());if(is_punc("("))body.push(parse_tuple());if(is_punc("{"))body.push(parse_object());str+=nn.value;body.push(nn)}input.next();return{type:"ArrayExpression",value:str,body:body,poi:poi}}function parse_tuple(){var n=input.next();var end=")";var body=[];var poi={line:n.poi.line,start:n.poi.start};var str="";while(input.peek().value!=end){let nn=input.next();if(is_punc("["))body.push(parse_list());if(is_punc("("))body.push(parse_tuple());if(is_punc("{"))body.push(parse_object());str+=nn.value;body.push(nn)}input.next();return{type:"TupleExpression",value:str,body:body,poi:poi}}function parse_object(){var n=input.next();var end="}";var body=[];var poi={line:n.poi.line,start:n.poi.start};var str="";while(input.peek().value!=end){let nn=input.next();if(is_punc("["))body.push(parse_list());if(is_punc("("))body.push(parse_tuple());if(is_punc("{"))body.push(parse_object());str+=nn.value;body.push(nn)}input.next();return{type:"ObjectExpression",value:str,body:body,poi:poi}}function parse_with(){var n=input.next();var r={type:"WithStatement",value:n.value,poi:{line:n.poi.line,start:n.poi.start},condition:parse_condition()};if(is_sp(":"))r.body=parse_block().body;return r}function parse_keyword(){var n=input.peek();var r={type:"Expression",value:n.value,poi:{line:n.poi.line,start:n.poi.start}};input.next();var nn=input.peek();if(nn){r.body=[parse_expression()]}return r}function parse_lambda(){var n=input.peek();var r={type:"Lambda",value:n.value,poi:{line:n.poi.line,start:n.poi.start},body:[]};input.next();var argument={type:"Arguments",body:[],poi:{line:input.peek().poi.line,start:input.peek().poi.start},value:""};while(!is_sp(":")){let arg=input.next();argument.body.push(arg);argument.value+=arg.value}r.arguments=argument;while(!is_sp(",")&&!is_punc()&&input.peek().type!="t"){let b=input.next();r.body.push(b)}return r}function parse_expression(iscls){if(is_id())return parse_id(iscls);if(is_punc("["))return parse_list();if(is_punc("("))return parse_tuple();if(is_punc("{"))return parse_object();if(is_kw("lambda"))return parse_lambda();if(is_kw())return parse_keyword();return parse_next()}function parse_statement(iscls){try{if(is_kw("def"))return parse_function();else if(is_kw("if")||is_kw("elif")||is_kw("else"))return parse_if();else if(is_kw("for")||is_kw("while"))return parse_loop();else if(is_kw("with"))return parse_with();else if(is_kw("try"))return parse_try();else if(is_kw("except"))return parse_except();else if(is_kw("finally"))return parse_finally();else if(is_kw("class"))return parse_class();return parse_expression(iscls)}catch(err){var p=input.peek();console.warn(`parse statement ${p.type} ${p.value} at ${p.poi.line}:${p.poi.start}:${p.poi.end}`,err)}}}function getAst(code){var inputSteam=InputStream(code);var tokenSteam=TokenStream(inputSteam);return parse(tokenSteam)}function traverseAst(node,callback){var isreturn=callback(node);if(isreturn===true)return;if(node.body&&node.body.length>0){for(let n of node.body){traverseAst(n,callback)}}}function analysisMermaid(node,file,r){switch(node.type){case"FunctionDefine":traverseFunction(node,{},file);return true;case"ClassDefine":if(!r.showMethod)break;traverseClass(node,file);return true;case"Variable":for(let n of node.body){if(n.type=="CallExpression"){r.FlowVarNew[node.value]=n.value}}}function traverseClass(node,file){node._file=file;node._flow_id=node.value;if(r.FlowFilter[node.value]===false)return;r.FlowNode[node._flow_id]=node;if(r.FlowOne[node._flow_id]){if(r.FlowOne[node._flow_id].indexOf(node.value)<0){r.FlowOne[node._flow_id].unshift(node.value)}}else{r.FlowOne[node._flow_id]=[node.value]}r.Flow+=` ${node.value}[${node.value}]\nclick ${node.value} "javascript:void(onFlowClick('${node.value}','${file}'))"\n`;r.FDPNode[node._flow_id]={id:node.value,w:node.value.length*gD3fontSize/1.6+gD3fontSize*2,text:`[${node.value}]`};r.UMLClass[node.value]={};r.UML+=` class ${node.value}{\n`;for(let member of node.body){switch(member.type){case"MethodDefine":member._flow_id=member.value;traverseFunction(member,node,file,true);break;case"PropertyDefine":traverseProperty(member,node,file,r);break;case"FunctionDefine":member._flow_id=member.value;traverseFunction(member,node,file,true);break}}r.UML+=" }\n";for(let fnode of node.extends){let f=fnode.value;if(r.FDPNode[f]===undefined){r.FDPNode[f]={id:f,w:f.length*gD3fontSize/1.6+gD3fontSize*2,text:`[${f}]`}}r.UML+=` ${f} <|-- ${node.value}\n`;r.FlowLink+=`${f} ==o ${node.value}\n`;r.FDPLinks.push({source:f,target:node.value,value:6,dist:200,dash:"2,2"})}}function traverseProperty(member,cls,file,r){member._flow_id=member.value;member._flow_prop=`|${member.value.replaceAll("|","|").replaceAll("[","").replaceAll("]","")}|`;r.UML+=` ${member.value}\n`;if(!r.showCall)return true;for(let n of member.body){if(n.type=="CallExpression"){n._file=file;n._flow_id=n.value+"_"+member._flow_id;n._flow_from=cls._flow_id;n._flow_prop=member._flow_prop;r.FlowNode[n._flow_id]=n;r.FlowVarNew[member.value]=n.value;if(!r.FlowFilter[n._flow_id])return true;n._flow_str=` ${n._flow_id}([${n.value}])\nclick ${n._flow_id} "javascript:void(onFlowClick('${n._flow_id}','${file}'))"\n`;r.FDPNode[n._flow_id]={id:n._flow_id,w:n.value.length*gD3fontSize/1.6+gD3fontSize*2,text:n.value+"()"};r.Flow+=n._flow_str;return true}}}function traverseFunction(member,cls,file,symbol){var method=cls.value?member.value+"_"+cls.value:member.value;if(r.FlowOne[member.value]){if(r.FlowOne[member.value].indexOf(method)<0){r.FlowOne[member.value].unshift(method)}}else{r.FlowOne[member.value]=[method]}member._flow_id=method;member._flow_from=cls.value;member._file=file;if(r.FlowFilter[member._flow_id]===false)return;r.FlowNode[member._flow_id]=member;r.FDPNode[member._flow_id]={id:member._flow_id,w:member.value.length*gD3fontSize/1.6+gD3fontSize*3,text:`${member.value}()`};if(symbol)r.UML+=` ${member.value}()\n`;r.Flow+=` ${member._flow_id}([${member.value}])\nclick ${member._flow_id} "javascript:void(onFlowClick('${member._flow_id}','${file}'))"\n`;if(cls._flow_id){r.FlowLink+=`${cls._flow_id} --o ${member._flow_id}\n`;r.FDPLinks.push({source:cls._flow_id,target:member._flow_id,value:2})}if(r.showCall&&member.body){for(let n of member.body){doBlock(n,member,method)}}}function doBlock(n,node,method){if(!n)return;n._file=file;n._flow_id=n.value+"_"+node._flow_id;n._flow_from=r.showIf?node._flow_id:method;if(n.type=="FunctionDefine"||n.type=="MethodDefine"){r.FlowNode[n._flow_id]=n;traverseFunction(n,node,file)}else if(n.type=="LoopStatement"){r.FlowNode[n._flow_id]=n;if(r.showIf){r.Flow+=` ${n._flow_id}((${n.value}))\nclick ${n._flow_id} "javascript:void(onFlowClick('${n._flow_id}','${file}'))"\n`;r.FDPNode[n._flow_id]={id:n._flow_id,w:0,text:"🔵"}}if(n.condition&&n.condition.value)n._flow_condition="|"+n.condition.value.replaceAll("|","|").replaceAll("[","⌈").replaceAll("]","⌋")+"|";if(n.body){for(let nn of n.body){doBlock(nn,n,method)}}}else if(n.type=="IfStatement"){r.FlowNode[n._flow_id]=n;if(r.showIf){r.Flow+=` ${n._flow_id}{${n.value}}\nclick ${n._flow_id} "javascript:void(onFlowClick('${n._flow_id}','${file}'))"\n`;r.FDPNode[n._flow_id]={id:n._flow_id,w:0,text:"🔷"}}if(n.condition&&n.condition.value)n._flow_condition="|"+n.condition.value.replaceAll("|","|").replaceAll("[","⌈").replaceAll("]","⌋")+"|";if(n.body){for(let nn of n.body){doBlock(nn,n,method)}}}else if(n.type=="CallExpression"){if(node.type=="Variable"){r.FlowVarNew[node.value]=n.value}n._flow_callee=node.type=="FunctionDefine"||node.type=="MethodDefine"?n.value:node.value;if(r.FlowNode[n._flow_id])n._flow_id=n._flow_callee+n._flow_id;r.FlowNode[n._flow_id]=n;if(!r.FlowFilter[n._flow_id])return true;n._flow_str=` ${n._flow_id}([${n.value}])\nclick ${n._flow_id} "javascript:void(onFlowClick('${n._flow_id}','${file}'))"\n`;r.FDPNode[n._flow_id]={id:n._flow_id,w:n.value.length*gD3fontSize/1.6+gD3fontSize*2,text:n.value+"()"};r.Flow+=n._flow_str}else if(n.type=="Variable"||n.type=="Expression"||n.type=="WithStatement"||n.type=="TryStatement"||n.type=="ExceptStatement"||n.type=="FinallyStatement"||n.type=="MemberExpression"){r.FlowNode[n._flow_id]=n;n._flow_id=node._flow_id;if(n.body){for(let nn of n.body){doBlock(nn,n,method)}}}}}function analysisD3(node,file){node.children=[];if(node.body&&node.body.length>0){for(let b of node.body){if(d3config.scastops[b.type]||d3config.scastops.all){node.children.push(b)}}}switch(node.type){case"top":node.name=file;node.value=file;break;case"ClassDefine":node.name=`[ ${node.value} ]`;break;case"MethodDefine":node.name=`${node.value}()`;break;case"FunctionDefine":node.name=`${node.value}()`;break;case"PropertyDefine":node.name=`${node.value}`;break;case"CallExpression":node.name=node.value+"()";break;default:node.name=node.value}}var d3config={scastops:types,fontsize:14};function setD3Config(conf){d3config=conf}function loc2poi(node){return node.poi}function setCode(){}return{getAst:getAst,traverseAst:traverseAst,analysisMermaid:analysisMermaid,analysisD3:analysisD3,setD3Config:setD3Config,types:types,loc2poi:loc2poi,setCode:setCode}}();ESTREEPY=SCASTPY;