forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdef.js
More file actions
1 lines (1 loc) · 17.6 KB
/
Copy pathdef.js
File metadata and controls
1 lines (1 loc) · 17.6 KB
1
!function(mod){"object"==typeof exports&&"object"==typeof module?exports.init=mod:"function"==typeof define&&define.amd?define({init:mod}):tern.def={init:mod}}(function(exports,infer){"use strict";function hop(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}var TypeParser=exports.TypeParser=function(spec,start,base,forceNew){this.pos=start||0,this.spec=spec,this.base=base,this.forceNew=forceNew};function unwrapType(type,self,args){return type.call?type(self,args):type}function extractProp(type,prop){if("!ret"==prop){if(type.retval)return type.retval;var rv=new infer.AVal;return type.propagate(new infer.IsCallee(infer.ANull,[],null,rv)),rv}return type.getProp(prop)}function computedFunc(name,args,retType,generator){return function(self,cArgs){for(var realArgs=[],i=0;i<args.length;i++)realArgs.push(unwrapType(args[i],self,cArgs));return new infer.Fn(name,infer.ANull,realArgs,unwrapType(retType,self,cArgs),generator)}}function computedUnion(types){return function(self,args){for(var union=new infer.AVal,i=0;i<types.length;i++)unwrapType(types[i],self,args).propagate(union);return union.maxWeight=1e5,union}}function computedArray(inner){return function(self,args){return new infer.Arr(inner(self,args))}}function computedTuple(types){return function(self,args){return new infer.Arr(types.map(function(tp){return unwrapType(tp,self,args)}))}}function computedObject(names,types){return function(self,args){var obj=new infer.Obj;return names.forEach(function(prop,i){obj.defProp(prop).addType(unwrapType(types[i],self,args))}),obj}}function addArgCallEffects(type){if(type instanceof infer.Fn&&type.args)for(var i=0;i<type.args.length;++i){var arg=type.args[i];arg instanceof infer.Fn&&arg.args&&arg.args.length&&addArgCallEffect(type,i)}}function addArgCallEffect(type,argNum){addEffect(type,function(_self,args){args[argNum]&&args[argNum].propagate(new infer.IsCallee(infer.cx().topScope,type.args[argNum].args,null,infer.ANull))})}function parseType(spec,name,base,forceNew){var type=new TypeParser(spec,null,base,forceNew).parseType(!1,name,!0);return type instanceof infer.AVal?type.types.forEach(addArgCallEffects):addArgCallEffects(type),type}function addEffect(fn,handler,replaceRet){var oldCmp=fn.computeRet,rv=fn.retval;fn.computeRet=function(self,args,argNodes){var handled=handler(self,args,argNodes),old=oldCmp?oldCmp(self,args,argNodes):rv;return replaceRet?handled:old}}TypeParser.prototype={eat:function(str){if(1==str.length?this.spec.charAt(this.pos)==str:this.spec.indexOf(str,this.pos)==this.pos)return this.pos+=str.length,!0},word:function(re){for(var word="",ch,re=re||/[\w$]/;(ch=this.spec.charAt(this.pos))&&re.test(ch);)word+=ch,++this.pos;return word},error:function(){throw new Error("Unrecognized type spec: "+this.spec+" (at "+this.pos+")")},parseFnType:function(comp,name,top,generator){var args=[],names=[],computed=!1,retType,computeRet,computeRetStart,fn;if(!this.eat(")"))for(var i=0;;++i){var colon=this.spec.indexOf(": ",this.pos),argname;-1!=colon&&(argname=this.spec.slice(this.pos,colon),/^(\.\.\.)?[$\w?]+$/.test(argname)?this.pos=colon+2:argname=null),names.push(argname);var argType=this.parseType(comp);if(argType.call&&(computed=!0),args.push(argType),!this.eat(", ")){this.eat(")")||this.error();break}}if(this.eat(" -> ")){var retStart=this.pos;(retType=this.parseType(!0)).call&&!computed&&(computeRet=retType,retType=infer.ANull,computeRetStart=retStart)}else retType=infer.ANull;return computed?computedFunc(name,args,retType,generator):(top&&(fn=this.base)?infer.Fn.call(this.base,name,infer.ANull,args,names,retType,generator):fn=new infer.Fn(name,infer.ANull,args,names,retType,generator),computeRet&&(fn.computeRet=computeRet),null!=computeRetStart&&(fn.computeRetSource=this.spec.slice(computeRetStart,this.pos)),fn)},parseType:function(comp,name,top){var main=this.parseTypeMaybeProp(comp,name,top);if(!this.eat("|"))return main;for(var types=[main],computed=main.call;;){var next=this.parseTypeMaybeProp(comp,name,top);if(types.push(next),next.call&&(computed=!0),!this.eat("|"))break}if(computed)return computedUnion(types);for(var union=new infer.AVal,i=0;i<types.length;i++)types[i].propagate(union);return union.maxWeight=1e5,union},parseTypeMaybeProp:function(comp,name,top){for(var result=this.parseTypeInner(comp,name,top);comp&&this.eat(".");)result=this.extendWithProp(result);return result},extendWithProp:function(base){var propName=this.word(/[\w<>$!:]/)||this.error();return base.apply?function(self,args){return extractProp(base(self,args),propName)}:extractProp(base,propName)},parseTypeInner:function(comp,name,top){var gen;if(this.eat("fn(")||(gen=this.eat("fn*(")))return this.parseFnType(comp,name,top,gen);if(this.eat("[")){for(var inner=this.parseType(comp),types,computed=inner.call;this.eat(", ");){types||(types=[inner]);var next=this.parseType(comp);types.push(next),computed=computed||next.call}return this.eat("]")||this.error(),computed?types?computedTuple(types):computedArray(inner):top&&this.base?(infer.Arr.call(this.base,types||inner),this.base):new infer.Arr(types||inner)}if(this.eat("{")){var types=[],names=[],computed=!1;if(!this.eat("}"))for(var i=0;;++i){var colon=this.spec.indexOf(": ",this.pos),propName;-1!=colon&&(propName=this.spec.slice(this.pos,colon),/^[$\w?]+$/.test(propName)?this.pos=colon+2:propName=null);var propType=this.parseType(comp);if(propType.call&&(computed=!0),names.push(propName),types.push(propType),!this.eat(", ")){this.eat("}")||this.error();break}}if(computed)return computedObject(names,types);var obj=new infer.Obj;return names.forEach(function(prop,i){obj.defProp(prop).addType(types[i])}),obj}if(this.eat("+")){var path=this.word(/[\w$<>\.:!]/),base,name;if(!(base=infer.cx().localDefs[path+".prototype"])){var base;if(!((base=parsePath(path))instanceof infer.Obj))return base;var proto=descendProps(base,["prototype"]);proto&&(proto=proto.getObjType())&&(base=proto)}return comp&&this.eat("[")?this.parsePoly(base):top&&this.base?(this.base.proto=base,(name=base.hasCtor&&base.hasCtor.name||base.name)&&(this.base.name=name),this.base):top&&this.forceNew?new infer.Obj(base):infer.getInstance(base)}if(this.eat(":")){var name=this.word(/[\w$\.]/);return infer.getSymbol(name)}if(comp&&this.eat("!")){var arg=this.word(/\d/);if(arg)return arg=Number(arg),function(_self,args){return args[arg]||infer.ANull};if(this.eat("this"))return function(self){return self};if(this.eat("custom:")){var fname=this.word(/[\w$]/);return customFunctions[fname]||function(){return infer.ANull}}return this.fromWord("!"+this.word(/[\w$<>\.!:]/))}return this.eat("?")?infer.ANull:this.fromWord(this.word(/[\w$<>\.!:`]/))},fromWord:function(spec){var cx=infer.cx();switch(spec){case"number":return cx.num;case"string":return cx.str;case"bool":return cx.bool;case"<top>":return cx.topScope}return cx.localDefs&&spec in cx.localDefs?cx.localDefs[spec]:parsePath(spec)},parsePoly:function(base){var propName="<i>",match;(match=this.spec.slice(this.pos).match(/^\s*([\w$:]+)\s*=\s*/))&&(propName=match[1],this.pos+=match[0].length);var value=this.parseType(!0);if(this.eat("]")||this.error(),value.call)return function(self,args){var instance=new infer.Obj(base);return value(self,args).propagate(instance.defProp(propName)),instance};var instance=new infer.Obj(base);return value.propagate(instance.defProp(propName)),instance}};var parseEffect=exports.parseEffect=function(effect,fn){var m;if(0==effect.indexOf("propagate ")){var p,origin=(p=new TypeParser(effect,10)).parseType(!0);p.eat(" ")||p.error();var target=p.parseType(!0);addEffect(fn,function(self,args){unwrapType(origin,self,args).propagate(unwrapType(target,self,args))})}else if(0==effect.indexOf("call ")){var andRet=5==effect.indexOf("and return ",5),p,getCallee=(p=new TypeParser(effect,andRet?16:5)).parseType(!0),getSelf=null,getArgs=[];for(p.eat(" this=")&&(getSelf=p.parseType(!0));p.eat(" ");)getArgs.push(p.parseType(!0));addEffect(fn,function(self,args){for(var callee=unwrapType(getCallee,self,args),slf=getSelf?unwrapType(getSelf,self,args):infer.ANull,as=[],i=0;i<getArgs.length;++i)as.push(unwrapType(getArgs[i],self,args));var result=andRet?new infer.AVal:infer.ANull;return callee.propagate(new infer.IsCallee(slf,as,null,result)),result},andRet)}else if(m=effect.match(/^custom (\S+)\s*(.*)/)){var customFunc=customFunctions[m[1]];customFunc&&addEffect(fn,m[2]?customFunc(m[2]):customFunc)}else{if(0!=effect.indexOf("copy "))throw new Error("Unknown effect type: "+effect);var p,getFrom=(p=new TypeParser(effect,5)).parseType(!0);p.eat(" ");var getTo=p.parseType(!0);addEffect(fn,function(self,args){var from=unwrapType(getFrom,self,args),to=unwrapType(getTo,self,args);from.forAllProps(function(prop,val,local){local&&"<i>"!=prop&&to.propagate(new infer.DefProp(prop,val))})})}},currentTopScope,parsePath=exports.parsePath=function(path,scope){var cx=infer.cx(),cached=cx.paths[path],origPath=path;if(null!=cached)return cached;cx.paths[path]=infer.ANull;var base=scope||currentTopScope||cx.topScope;if(cx.localDefs)for(var name in cx.localDefs)if(0==path.indexOf(name)){if(path==name)return cx.paths[path]=cx.localDefs[path];if("."==path.charAt(name.length)){base=cx.localDefs[name],path=path.slice(name.length+1);break}}var result=descendProps(base,path.split("."));return cx.paths[origPath]=result==infer.ANull?null:result,result};function descendProps(base,parts){for(var i=0;i<parts.length&&base!=infer.ANull;++i){var prop=parts[i];if("!"==prop.charAt(0))if("!proto"==prop)base=base instanceof infer.Obj&&base.proto||infer.ANull;else{var fn=base.getFunctionType();if(fn)if("!ret"==prop)base=fn.retval&&fn.retval.getType(!1)||infer.ANull;else{var arg=fn.args&&fn.args[Number(prop.slice(1))];base=arg&&arg.getType(!1)||infer.ANull}else base=infer.ANull}else if(base instanceof infer.Obj&&("prototype"==prop&&base instanceof infer.Fn||base.hasProp(prop))){var propVal=base.getProp(prop);base=!propVal||propVal.isEmpty()?infer.ANull:propVal.types[0]}else base=infer.ANull}return base}function emptyObj(ctor){var empty=Object.create(ctor.prototype);return empty.props=Object.create(null),empty.isShell=!0,empty}function isSimpleAnnotation(spec){if(!spec["!type"]||/^(fn\(|\[|\+)/.test(spec["!type"]))return!1;for(var prop in spec)if("!type"!=prop&&"!doc"!=prop&&"!url"!=prop&&"!span"!=prop&&"!data"!=prop)return!1;return!0}function passOne(base,spec,path){if(!base){var tp=spec["!type"];if(tp)if(/^fn\(/.test(tp))base=emptyObj(infer.Fn);else if("["==tp.charAt(0))base=emptyObj(infer.Arr);else{if("+"!=tp.charAt(0))throw new Error("Invalid !type spec: "+tp);base=emptyObj(infer.Obj)}else base=spec["!stdProto"]?infer.cx().protos[spec["!stdProto"]]:emptyObj(infer.Obj);base.name=path}for(var name in spec)if(hop(spec,name)&&33!=name.charCodeAt(0)){var inner=spec[name];if("string"==typeof inner||isSimpleAnnotation(inner))continue;var prop=base.defProp(name);passOne(prop.getObjType(),inner,path?path+"."+name:name).propagate(prop)}return base}function passTwo(base,spec,path){if(base.isShell){delete base.isShell;var tp=spec["!type"];if(tp)parseType(tp,path,base);else{var proto=spec["!proto"]&&parseType(spec["!proto"]);infer.Obj.call(base,!(proto instanceof infer.Obj)||proto,path)}}var effects=spec["!effects"];if(effects&&base instanceof infer.Fn)for(var i=0;i<effects.length;++i)parseEffect(effects[i],base);for(var name in copyInfo(spec,base),spec)if(hop(spec,name)&&33!=name.charCodeAt(0)){var inner=spec[name],known=base.defProp(name),innerPath=path?path+"."+name:name;if("string"==typeof inner)known.isEmpty()&&parseType(inner,innerPath).propagate(known);else{if(isSimpleAnnotation(inner)){if(!known.isEmpty())continue;parseType(inner["!type"],innerPath,null,!0).propagate(known)}else passTwo(known.getObjType(),inner,innerPath);inner["!doc"]&&(known.doc=inner["!doc"]),inner["!url"]&&(known.url=inner["!url"]),inner["!span"]&&(known.span=inner["!span"])}}return base}function copyInfo(spec,type){spec["!doc"]&&(type.doc=spec["!doc"]),spec["!url"]&&(type.url=spec["!url"]),spec["!span"]&&(type.span=spec["!span"]),spec["!data"]&&(type.metaData=spec["!data"])}function doLoadEnvironment(data,scope){var cx=infer.cx(),server=cx.parent;infer.addOrigin(cx.curOrigin=data["!name"]||"env#"+cx.origins.length),cx.localDefs=cx.definitions[cx.curOrigin]=Object.create(null),server&&server.signal("preLoadDef",data),passOne(scope,data);var def=data["!define"];if(def){for(var name in def){var spec=def[name];cx.localDefs[name]="string"==typeof spec?parsePath(spec):passOne(null,spec,name)}for(var name in def){var spec;"string"!=typeof(spec=def[name])&&passTwo(cx.localDefs[name],def[name],name)}}passTwo(scope,data),server&&server.signal("postLoadDef",data),cx.curOrigin=cx.localDefs=null}exports.load=function(data,scope){scope||(scope=infer.cx().topScope);var oldScope=currentTopScope;currentTopScope=scope;try{doLoadEnvironment(data,scope)}finally{currentTopScope=oldScope}},exports.parse=function(data,origin,path){var cx=infer.cx();origin&&(cx.origin=origin,cx.localDefs=cx.definitions[origin]);try{return"string"==typeof data?parseType(data,path):passTwo(passOne(null,data,path),data,path)}finally{origin&&(cx.origin=cx.localDefs=null)}};var customFunctions=Object.create(null);infer.registerFunction=function(name,f){customFunctions[name]=f};var IsCreated=infer.constraint({construct:function(created,target,spec){this.created=created,this.target=target,this.spec=spec},addType:function(tp){if(tp instanceof infer.Obj&&this.created++<5){var derived=new infer.Obj(tp),spec=this.spec;if(spec instanceof infer.AVal&&(spec=spec.getObjType(!1)),spec instanceof infer.Obj)for(var prop in spec.props){var cur=spec.props[prop].types[0],p=derived.defProp(prop);if(cur&&cur instanceof infer.Obj&&cur.props.value){var vtp=cur.props.value.getType(!1);vtp&&p.addType(vtp)}}this.target.addType(derived)}}});infer.registerFunction("Object_create",function(_self,args,argNodes){if(argNodes&&argNodes.length&&"Literal"==argNodes[0].type&&null==argNodes[0].value)return new infer.Obj;var result=new infer.AVal;return args[0]&&args[0].propagate(new IsCreated(0,result,args[1])),result});var PropSpec=infer.constraint({construct:function(target){this.target=target},addType:function(tp){tp instanceof infer.Obj&&(tp.hasProp("value")?tp.getProp("value").propagate(this.target):tp.hasProp("get")&&tp.getProp("get").propagate(new infer.IsCallee(infer.ANull,[],null,this.target)))}});infer.registerFunction("Object_defineProperty",function(_self,args,argNodes){if(argNodes&&argNodes.length>=3&&"Literal"==argNodes[1].type&&"string"==typeof argNodes[1].value){var obj=args[0],connect=new infer.AVal;obj.propagate(new infer.DefProp(argNodes[1].value,connect,argNodes[1])),args[2].propagate(new PropSpec(connect))}return infer.ANull}),infer.registerFunction("Object_defineProperties",function(_self,args,argNodes){if(args.length>=2){var obj=args[0];args[1].forAllProps(function(prop,val,local){if(local){var connect=new infer.AVal;obj.propagate(new infer.DefProp(prop,connect,argNodes&&argNodes[1])),val.propagate(new PropSpec(connect))}})}return infer.ANull});var IsBound=infer.constraint({construct:function(self,args,target){this.self=self,this.args=args,this.target=target},addType:function(tp){if(tp instanceof infer.Fn){this.target.addType(new infer.Fn(tp.name,infer.ANull,tp.args.slice(this.args.length),tp.argNames.slice(this.args.length),tp.retval,tp.generator)),this.self.propagate(tp.self);for(var i=0;i<Math.min(tp.args.length,this.args.length);++i)this.args[i].propagate(tp.args[i])}}});function makePromise(){var defs=infer.cx().definitions.ecmascript;return defs&&new infer.Obj(defs["Promise.prototype"])}infer.registerFunction("Function_bind",function(self,args){if(!args.length)return infer.ANull;var result=new infer.AVal;return self.propagate(new IsBound(args[0],args.slice(1),result)),result}),infer.registerFunction("Array_ctor",function(_self,args){var arr=new infer.Arr;if(1!=args.length||!args[0].hasType(infer.cx().num))for(var content=arr.getProp("<i>"),i=0;i<args.length;++i)args[i].propagate(content);return arr}),infer.registerFunction("Promise_ctor",function(_self,args,argNodes){var self=makePromise();if(!self||args.length<1)return infer.ANull;var valProp=self.defProp(":t",argNodes&&argNodes[0]),valArg=new infer.AVal;valArg.propagate(valProp);var exec=new infer.Fn("execute",infer.ANull,[valArg],["value"],infer.ANull),reject=infer.cx().definitions.ecmascript.Promise_reject;return args[0].propagate(new infer.IsCallee(infer.ANull,[exec,reject],null,infer.ANull)),self}),infer.registerFunction("Promise_resolve",function(_self,args,argNodes){var self=makePromise();if(!self)return infer.ANull;if(args.length){var valProp=self.defProp(":t",argNodes&&argNodes[0]),valArg=new infer.AVal;valArg.propagate(valProp),args[0].propagate(new PromiseResolvesTo(valArg))}return self});var PromiseResolvesTo=infer.constraint({construct:function(output){this.output=output},addType:function(tp){tp.constructor==infer.Obj&&"Promise"==tp.name&&tp.hasProp(":t")?tp.getProp(":t").propagate(this.output):tp.propagate(this.output)}}),WG_PROMISE_KEEP_VALUE=50;return infer.registerFunction("Promise_then",function(self,args,argNodes){var fn=args.length&&args[0].getFunctionType(),defs=infer.cx().definitions.ecmascript;if(!fn||!defs)return self;var result=new infer.Obj(defs["Promise.prototype"]),value=result.defProp(":t",argNodes&&argNodes[0]),ty;return fn.retval.isEmpty()&&(ty=self.getType())instanceof infer.Obj&&ty.hasProp(":t")&&ty.getProp(":t").propagate(value,50),fn.retval.propagate(new PromiseResolvesTo(value)),result}),infer.registerFunction("getOwnPropertySymbols",function(_self,args){if(!args.length)return infer.ANull;var result=new infer.AVal;return args[0].forAllProps(function(prop,_val,local){local&&":"==prop.charAt(0)&&result.addType(infer.getSymbol(prop.slice(1)))}),result}),infer.registerFunction("getSymbol",function(_self,_args,argNodes){return argNodes&&argNodes.length&&"Literal"==argNodes[0].type&&"string"==typeof argNodes[0].value?infer.getSymbol(argNodes[0].value):infer.ANull}),exports});