@tslite/analysis 0.1.8 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var core=require('@tslite/core');var I=new Set,T=(...e)=>new Set(e),m={atoms:new Set,vars:new Set},M=(...e)=>({atoms:new Set(e),vars:new Set}),C=e=>({atoms:new Set,vars:new Set([e])}),R=e=>{let t=new Set,o=new Set;for(let n of e){for(let r of n.atoms)t.add(r);for(let r of n.vars)o.add(r);}return {atoms:t,vars:o}},Y=(e,t)=>{let o=new Set(e.atoms),n=new Set;for(let r of e.vars){let i=t.get(r);if(i){for(let s of i.atoms)o.add(s);for(let s of i.vars)n.add(s);}else n.add(r);}return {atoms:o,vars:n}},U={params:[],latent:m},V=(e,t)=>{let o=new Map;return e.params.forEach((n,r)=>{let i=t[r];n&&i&&o.set(n,i);}),Y(e.latent,o)},O=e=>new Set(e.atoms),ae=e=>{let t=new Set;for(let o of e)for(let n of o)t.add(n);return t},fe=(e,t)=>{for(let o of e)if(!t.has(o))return false;return true},j=(e,t)=>[...e].filter(o=>!t.has(o));var de=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]=new Set(n);return t},pe=(e,t,o=[])=>{let n=new Array(t).fill(null),r="\u03B5";return n[e]=r,{params:n,latent:{atoms:new Set(o),vars:new Set([r])}}},L={nodeEffects:{ForStatement:"loops",ForInStatement:"loops",ForOfStatement:"loops",WhileStatement:"loops",DoWhileStatement:"loops",AssignmentExpression:"mutates",UpdateExpression:"mutates"}},ye=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),h=e=>ye.has(e.type),p=e=>e,ue=e=>p(e).body,me=e=>p(e).params??[],S=e=>e&&e.type==="Identifier"?p(e).name:void 0,Ee=e=>{let t=p(e).object,o=p(e).property,n=S(t);if(!n)return null;let r=p(e).computed?void 0:S(o);return {path:r?`${n}.${r}`:n,root:n}},ge=e=>typeof e=="object"&&e!==null&&"latent"in e,$=(e,t)=>ge(e)?V(e,t):{atoms:new Set(e),vars:new Set},J=(e,t)=>{let o=0;return {rules:e,env:t,schemeOf:new Map,active:new Set,fresh:()=>`\u03B5${o++}`}},Q=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]={kind:"capability",decl:n};return core.rootScope(t)};function x(e,t,o){let n=o.schemeOf.get(e);if(n)return n;if(o.active.has(e))return U;o.active.add(e);let r=me(e),i=r.map(v=>v.type==="Identifier"?o.fresh():null),s={};r.forEach((v,D)=>{let K=S(v);K&&i[D]&&(s[K]={kind:"param",var:i[D]});});let a=core.childScope(t,s),f=ue(e),u=f?E(f,a,o):m,d={params:i,latent:u};return o.active.delete(e),o.schemeOf.set(e,d),d}function _(e,t,o){x(e,t,o);}function E(e,t,o){let n=o.rules.nodeEffects[e.type],r=n?M(n):m;if(h(e))return _(e,t,o),r;if(e.type==="CallExpression"||e.type==="NewExpression")return R([r,we(e,t,o)]);if(e.type==="BlockStatement"||e.type==="Program"){let s=p(e).body??[];return R([r,ve(s,t,o)])}let i=[r];return core.forEachChild(e,s=>i.push(E(s,t,o))),R(i)}function ve(e,t,o){let n=t,r={};for(let s of e)if(s.type==="FunctionDeclaration"){let a=S(p(s).id);a&&(r[a]={kind:"fn",node:s,scope:n});}Object.keys(r).length&&(n=core.childScope(n,r));for(let s in r)r[s].kind==="fn"&&(r[s].scope=n);for(let s in r){let a=r[s];a.kind==="fn"&&_(a.node,n,o);}let i=[];for(let s of e)if(s.type!=="FunctionDeclaration"){if(s.type==="VariableDeclaration"){let a=p(s).declarations??[];for(let f of a){let u=p(f).id,d=p(f).init,v=S(u);if(v&&d&&h(d)){let D=core.childScope(n,{[v]:{kind:"fn",node:d,scope:n}});_(d,D,o),n=D;}else d&&i.push(E(d,n,o)),v&&(n=core.childScope(n,{[v]:{kind:"value"}}));}continue}i.push(E(s,n,o));}return R(i)}function we(e,t,o){let n=p(e).callee,r=p(e).arguments??[],i=r.map(f=>h(f)?m:E(f,t,o)),s=r.map(f=>Re(f,t,o)),a=Se(n,s,t,o);return R([a,...i])}function Re(e,t,o){if(h(e))return x(e,t,o).latent;if(e.type==="Identifier"){let n=core.lookup(t,S(e));if(!n)return null;if(n.kind==="fn")return x(n.node,n.scope,o).latent;if(n.kind==="param")return C(n.var);if(n.kind==="capability")return $(n.decl,[])}return null}function Se(e,t,o,n){if(!e)return m;if(e.type==="Identifier"){let r=core.lookup(o,S(e));if(!r)return m;switch(r.kind){case "capability":return $(r.decl,t);case "fn":return V(x(r.node,r.scope,n),t);case "param":return C(r.var);case "value":return m}}if(h(e))return V(x(e,o,n),t);if(e.type==="MemberExpression"){let r=Ee(e),i=r&&(n.env[r.path]??n.env[r.root]);if(i)return $(i,t)}return E(e,o,n)}function W(e,t={}){let o=t.env??{},n=J(t.rules??L,o),r=Q(o);if(t.root&&t.root!==e){E(t.root,r,n);let i=n.schemeOf.get(e);if(i)return O(i.latent)}return h(e)?O(x(e,r,n).latent):O(E(e,r,n))}function z(e,t={}){let o=t.env??{},n=J(t.rules??L,o);E(e,Q(o),n);let r=new Map;for(let[i,s]of n.schemeOf)r.set(i,O(s.latent));return r}var X=e=>e.size?`{ ${[...e].sort().join(", ")} }`:"pure";function G(e,t,o){let n=W(e,o),r=j(n,t);return r.length===0?[]:[{node:e,declared:t,inferred:n,excess:r,message:`Effect contract violated: declared ${X(t)} but infers ${X(n)} \u2014 not allowed: ${r.join(", ")}.`}]}function Z(e){switch(e){case "pure":return I;case "io":return T("io");case "any":return null}}function Be(e,t,o){let n=Z(t);return n===null?[]:G(e,n,o)}var b=e=>e,B=e=>e&&e.type==="Identifier"?b(e).name:void 0,N=(e,t)=>b(e)[t],Ne=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),F=e=>Ne.has(e.type);function Oe(e){if(!e)return null;if(e.type==="Identifier"){let t=B(e);return {path:t,root:t}}if(e.type==="MemberExpression"){let t=b(e).object,o=b(e).property,n=b(e).computed,r=B(t);if(!r)return null;let i=n?void 0:B(o);return {path:i?`${r}.${i}`:r,root:r}}return null}function te(e){let{categories:t,matrix:o}=e,n=o.defaultPolicy??"allow",r=s=>t[s.path]??t[s.root],i=(s,a)=>o.rules[s]?.[a]??n;return (s,a)=>{if(!a)return null;let f=t[a];if(f===void 0)return null;let u=Oe(N(s,"callee"));if(!u)return null;let d=r(u);return d===void 0||i(f,d)!=="deny"?null:{call:s,from:a,to:u.path,fromCategory:f,toCategory:d,message:`Policy violated: ${f} '${a}' must not call ${d} '${u.path}' (${f} \u2192 ${d} is deny).`}}}var oe=e=>e.type==="CallExpression"||e.type==="NewExpression";function xe(e,t){let o=te(t),n=[],r=(i,s)=>{if(oe(i)){let a=o(i,s);a&&n.push(a);}if(i.type==="VariableDeclaration"){for(let a of b(i).declarations??[]){let f=N(a,"init");if(!f)continue;let u=F(f)?B(N(a,"id"))??s:s;r(f,u);}return}if(i.type==="FunctionDeclaration"){let a=B(N(i,"id"))??s;core.forEachChild(i,f=>r(f,a));return}core.forEachChild(i,a=>r(a,s));};return r(e,null),n}function ne(e){let t=te(e),o=new Map,n=[],r=()=>n.length?n[n.length-1]:null,i=null;return {enter(s){if(s.type==="VariableDeclarator"){let a=N(s,"init"),f=B(N(s,"id"));a&&F(a)&&f&&(i={name:f,fn:a});}if(F(s)){let a=i&&i.fn===s?i.name:s.type==="FunctionDeclaration"?B(N(s,"id"))??r():r();n.push(a),i=null;}if(oe(s)){let a=t(s,r());a&&o.set(s,a);}},exit(s){F(s)&&n.pop();},result:()=>o}}var w=e=>e,be=e=>e&&e.type==="Identifier"?w(e).name:void 0,c=(e,t)=>w(e)[t],g=(e,t)=>w(e)[t]??[];function y(e,t){if(e)switch(e.type){case "Identifier":t.add(w(e).name);return;case "AssignmentPattern":y(c(e,"left"),t);return;case "RestElement":y(c(e,"argument"),t);return;case "ArrayPattern":for(let o of g(e,"elements"))y(o,t);return;case "ObjectPattern":for(let o of g(e,"properties"))o.type==="RestElement"?y(c(o,"argument"),t):y(c(o,"value"),t);return}}function ke(e){let t=new Set;for(let o of e)if(o.type==="VariableDeclaration")for(let n of g(o,"declarations"))y(c(n,"id"),t);else if(o.type==="FunctionDeclaration"){let n=be(c(o,"id"));n&&t.add(n);}return t}var l=(e,t)=>{for(let o of t)e.add(o);},k=(e,t)=>{for(let o of t)e.delete(o);},De=new Set,re=e=>new Set(e);function H(e,t){let o=new Set;switch(e.type){case "Identifier":o.add(w(e).name);break;case "MemberExpression":{l(o,t(c(e,"object"))),w(e).computed&&l(o,t(c(e,"property")));break}case "Property":{w(e).computed&&l(o,t(c(e,"key"))),l(o,t(c(e,"value")));break}case "ArrowFunctionExpression":case "FunctionExpression":case "FunctionDeclaration":{let n=g(e,"params"),r=new Set;for(let i of n)y(i,r),i.type==="AssignmentPattern"&&l(o,t(c(i,"right")));l(o,t(c(e,"body"))),k(o,r);break}case "BlockStatement":case "Program":{let n=g(e,"body");for(let r of n)l(o,t(r));k(o,ke(n));break}case "VariableDeclarator":{l(o,t(c(e,"init")));let n=c(e,"id");n&&n.type!=="Identifier"&&A(n,o,t);break}case "CatchClause":{let n=new Set;y(c(e,"param"),n),l(o,t(c(e,"body"))),k(o,n);break}case "LabeledStatement":l(o,t(c(e,"body")));break;case "BreakStatement":case "ContinueStatement":break;case "ForInStatement":case "ForOfStatement":{let n=c(e,"left");l(o,t(c(e,"right")));let r=new Set;if(n.type==="VariableDeclaration")for(let s of g(n,"declarations"))y(c(s,"id"),r);else y(n,r);let i=re(t(c(e,"body")));k(i,r),l(o,i);break}case "ForStatement":{let n=c(e,"init"),r=new Set;if(n){if(n.type==="VariableDeclaration")for(let i of g(n,"declarations"))y(c(i,"id"),r);l(o,t(n));}for(let i of ["test","update","body"]){let s=re(t(c(e,i)));k(s,r),l(o,s);}break}default:core.forEachChild(e,n=>l(o,t(n)));break}return o}function se(e,t={}){let o=new Map,n=new Set(t.globals??[]),r=i=>{if(!i)return De;let s=H(i,r);return k(s,n),o.set(i,s),s};return r(e),o}function A(e,t,o){if(e.type==="AssignmentPattern")l(t,o(c(e,"right"))),A(c(e,"left"),t,o);else if(e.type==="ArrayPattern")for(let n of g(e,"elements"))n&&A(n,t,o);else if(e.type==="ObjectPattern")for(let n of g(e,"properties")){w(n).computed&&l(t,o(c(n,"key")));let r=c(n,"value")??c(n,"argument");r&&A(r,t,o);}}function Ve(e,t){return se(e,t).get(e)??new Set}function Pe(e,t){return {root:e,diagnostics:t.diagnostics,typeOf:o=>t.overlay.get(o)?.type,scopeOf:o=>t.overlay.get(o)?.scope}}function Fe(e,t){let o=new Map,n={tree:e,read:s=>o.get(s.name)},r=t.filter(s=>!!s.visitor),i=t.filter(s=>!s.visitor&&s.run);if(r.length){let s=a=>{for(let f of r)f.visitor.enter?.(a,n);core.forEachChild(a,s);for(let f=r.length-1;f>=0;f--)r[f].visitor.exit?.(a,n);};s(e.root);for(let a of r)o.set(a.name,a.visitor.result());}for(let s of i)o.set(s.name,s.run(n));return o}var ie=new Set,Ae=(e,t)=>({name:"effects",run:o=>z(o.tree.root,{env:e,rules:t})}),Ie=e=>({name:"deps",visitor:(()=>{let t=new Set(e?.globals??[]),o=new Map;return {exit(n){let r=H(n,i=>i?o.get(i)??ie:ie);for(let i of t)r.delete(i);o.set(n,r);},result:()=>o}})()}),Te=e=>({name:"policies",visitor:ne(e)});exports.DEFAULT_RULES=L;exports.PURE=I;exports.PURE_ROW=m;exports.PURE_SCHEME=U;exports.analyze=Fe;exports.checkEffectPolicy=Be;exports.checkEffects=G;exports.checkPolicies=xe;exports.deps=se;exports.depsOverlay=Ie;exports.effect=T;exports.effectCeiling=Z;exports.effectEnv=de;exports.effectsOverlay=Ae;exports.effectsOverlayOf=z;exports.excess=j;exports.forwardEffect=pe;exports.freeVars=Ve;exports.groundRow=O;exports.inferEffects=W;exports.instantiateScheme=V;exports.join=ae;exports.joinRows=R;exports.policiesOverlay=Te;exports.rowOf=M;exports.rowOfVar=C;exports.substituteRow=Y;exports.typedTreeOf=Pe;exports.within=fe;
|
|
1
|
+
'use strict';var core=require('@tslite/core');var T=new Set,I=(...e)=>new Set(e),E={atoms:new Set,vars:new Set},U=(...e)=>({atoms:new Set(e),vars:new Set}),C=e=>({atoms:new Set,vars:new Set([e])}),R=e=>{let t=new Set,o=new Set;for(let n of e){for(let r of n.atoms)t.add(r);for(let r of n.vars)o.add(r);}return {atoms:t,vars:o}},X=(e,t)=>{let o=new Set(e.atoms),n=new Set;for(let r of e.vars){let i=t.get(r);if(i){for(let s of i.atoms)o.add(s);for(let s of i.vars)n.add(s);}else n.add(r);}return {atoms:o,vars:n}},j={params:[],latent:E},V=(e,t)=>{let o=new Map;return e.params.forEach((n,r)=>{let i=t[r];n&&i&&o.set(n,i);}),X(e.latent,o)},N=e=>new Set(e.atoms),pe=e=>{let t=new Set;for(let o of e)for(let n of o)t.add(n);return t},ye=(e,t)=>{for(let o of e)if(!t.has(o))return false;return true},W=(e,t)=>[...e].filter(o=>!t.has(o));var Ee=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]=new Set(n);return t},ge=(e,t,o=[])=>{let n=new Array(t).fill(null),r="\u03B5";return n[e]=r,{params:n,latent:{atoms:new Set(o),vars:new Set([r])}}},M={nodeEffects:{ForStatement:"loops",ForInStatement:"loops",ForOfStatement:"loops",WhileStatement:"loops",DoWhileStatement:"loops",AssignmentExpression:"mutates",UpdateExpression:"mutates"}},ve=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),h=e=>ve.has(e.type),p=e=>e,we=e=>p(e).body,Re=e=>p(e).params??[],B=e=>e&&e.type==="Identifier"?p(e).name:void 0,Ne=e=>{let t=p(e).object,o=p(e).property,n=B(t);if(!n)return null;let r=p(e).computed?void 0:B(o);return {path:r?`${n}.${r}`:n,root:n}},Be=e=>typeof e=="object"&&e!==null&&"latent"in e,$=(e,t)=>Be(e)?V(e,t):{atoms:new Set(e),vars:new Set},L=(e,t)=>{let o=0;return {rules:e,env:t,schemeOf:new Map,nodeEff:new Map,active:new Set,fresh:()=>`\u03B5${o++}`}},z=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]={kind:"capability",decl:n};return core.rootScope(t)};function O(e,t,o){let n=o.schemeOf.get(e);if(n)return n;if(o.active.has(e))return j;o.active.add(e);let r=Re(e),i=r.map(v=>v.type==="Identifier"?o.fresh():null),s={};r.forEach((v,D)=>{let Q=B(v);Q&&i[D]&&(s[Q]={kind:"param",var:i[D]});});let a=core.childScope(t,s),c=we(e),u=c?m(c,a,o):E,l={params:i,latent:u};return o.active.delete(e),o.schemeOf.set(e,l),l}function _(e,t,o){O(e,t,o);}function m(e,t,o){let n=Se(e,t,o);return o.nodeEff.set(e,n),n}function Se(e,t,o){let n=o.rules.nodeEffects[e.type],r=n?U(n):E;if(h(e))return _(e,t,o),r;if(e.type==="CallExpression"||e.type==="NewExpression")return R([r,Oe(e,t,o)]);if(e.type==="BlockStatement"||e.type==="Program"){let s=p(e).body??[];return R([r,xe(s,t,o)])}let i=[r];return core.forEachChild(e,s=>i.push(m(s,t,o))),R(i)}function xe(e,t,o){let n=t,r={};for(let s of e)if(s.type==="FunctionDeclaration"){let a=B(p(s).id);a&&(r[a]={kind:"fn",node:s,scope:n});}Object.keys(r).length&&(n=core.childScope(n,r));for(let s in r)r[s].kind==="fn"&&(r[s].scope=n);for(let s in r){let a=r[s];a.kind==="fn"&&_(a.node,n,o);}let i=[];for(let s of e)if(s.type!=="FunctionDeclaration"){if(s.type==="VariableDeclaration"){let a=p(s).declarations??[];for(let c of a){let u=p(c).id,l=p(c).init,v=B(u);if(v&&l&&h(l)){let D=core.childScope(n,{[v]:{kind:"fn",node:l,scope:n}});_(l,D,o),n=D;}else l&&i.push(m(l,n,o)),v&&(n=core.childScope(n,{[v]:{kind:"value"}}));}continue}i.push(m(s,n,o));}return R(i)}function Oe(e,t,o){let n=p(e).callee,r=p(e).arguments??[],i=r.map(c=>h(c)?E:m(c,t,o)),s=r.map(c=>he(c,t,o)),a=be(n,s,t,o);return R([a,...i])}function he(e,t,o){if(h(e))return O(e,t,o).latent;if(e.type==="Identifier"){let n=core.lookup(t,B(e));if(!n)return null;if(n.kind==="fn")return O(n.node,n.scope,o).latent;if(n.kind==="param")return C(n.var);if(n.kind==="capability")return $(n.decl,[])}return null}function be(e,t,o,n){if(!e)return E;if(e.type==="Identifier"){let r=core.lookup(o,B(e));if(!r)return E;switch(r.kind){case "capability":return $(r.decl,t);case "fn":return V(O(r.node,r.scope,n),t);case "param":return C(r.var);case "value":return E}}if(h(e))return V(O(e,o,n),t);if(e.type==="MemberExpression"){let r=Ne(e),i=r&&(n.env[r.path]??n.env[r.root]);if(i)return $(i,t)}return m(e,o,n)}function G(e,t={}){let o=t.env??{},n=L(t.rules??M,o),r=z(o);if(t.root&&t.root!==e){m(t.root,r,n);let i=n.schemeOf.get(e);if(i)return N(i.latent)}return h(e)?N(O(e,r,n).latent):N(m(e,r,n))}function H(e,t={}){let o=t.env??{},n=L(t.rules??M,o);m(e,z(o),n);let r=new Map;for(let[i,s]of n.schemeOf)r.set(i,N(s.latent));return r}function K(e,t={}){let o=t.env??{},n=L(t.rules??M,o);m(e,z(o),n);let r=new Map;for(let[i,s]of n.nodeEff)r.set(i,N(s));return r}var ee=e=>e.size?`{ ${[...e].sort().join(", ")} }`:"pure";function Y(e,t,o){let n=G(e,o),r=W(n,t);return r.length===0?[]:[{node:e,declared:t,inferred:n,excess:r,message:`Effect contract violated: declared ${ee(t)} but infers ${ee(n)} \u2014 not allowed: ${r.join(", ")}.`}]}function te(e){switch(e){case "pure":return T;case "io":return I("io");case "any":return null}}function ke(e,t,o){let n=te(t);return n===null?[]:Y(e,n,o)}var b=e=>e,S=e=>e&&e.type==="Identifier"?b(e).name:void 0,x=(e,t)=>b(e)[t],De=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),F=e=>De.has(e.type);function Ve(e){if(!e)return null;if(e.type==="Identifier"){let t=S(e);return {path:t,root:t}}if(e.type==="MemberExpression"){let t=b(e).object,o=b(e).property,n=b(e).computed,r=S(t);if(!r)return null;let i=n?void 0:S(o);return {path:i?`${r}.${i}`:r,root:r}}return null}function ne(e){let{categories:t,matrix:o}=e,n=o.defaultPolicy??"allow",r=s=>t[s.path]??t[s.root],i=(s,a)=>o.rules[s]?.[a]??n;return (s,a)=>{if(!a)return null;let c=t[a];if(c===void 0)return null;let u=Ve(x(s,"callee"));if(!u)return null;let l=r(u);return l===void 0||i(c,l)!=="deny"?null:{call:s,from:a,to:u.path,fromCategory:c,toCategory:l,message:`Policy violated: ${c} '${a}' must not call ${l} '${u.path}' (${c} \u2192 ${l} is deny).`}}}var re=e=>e.type==="CallExpression"||e.type==="NewExpression";function Ce(e,t){let o=ne(t),n=[],r=(i,s)=>{if(re(i)){let a=o(i,s);a&&n.push(a);}if(i.type==="VariableDeclaration"){for(let a of b(i).declarations??[]){let c=x(a,"init");if(!c)continue;let u=F(c)?S(x(a,"id"))??s:s;r(c,u);}return}if(i.type==="FunctionDeclaration"){let a=S(x(i,"id"))??s;core.forEachChild(i,c=>r(c,a));return}core.forEachChild(i,a=>r(a,s));};return r(e,null),n}function se(e){let t=ne(e),o=new Map,n=[],r=()=>n.length?n[n.length-1]:null,i=null;return {enter(s){if(s.type==="VariableDeclarator"){let a=x(s,"init"),c=S(x(s,"id"));a&&F(a)&&c&&(i={name:c,fn:a});}if(F(s)){let a=i&&i.fn===s?i.name:s.type==="FunctionDeclaration"?S(x(s,"id"))??r():r();n.push(a),i=null;}if(re(s)){let a=t(s,r());a&&o.set(s,a);}},exit(s){F(s)&&n.pop();},result:()=>o}}var w=e=>e,Pe=e=>e&&e.type==="Identifier"?w(e).name:void 0,f=(e,t)=>w(e)[t],g=(e,t)=>w(e)[t]??[];function y(e,t){if(e)switch(e.type){case "Identifier":t.add(w(e).name);return;case "AssignmentPattern":y(f(e,"left"),t);return;case "RestElement":y(f(e,"argument"),t);return;case "ArrayPattern":for(let o of g(e,"elements"))y(o,t);return;case "ObjectPattern":for(let o of g(e,"properties"))o.type==="RestElement"?y(f(o,"argument"),t):y(f(o,"value"),t);return}}function Me(e){let t=new Set;for(let o of e)if(o.type==="VariableDeclaration")for(let n of g(o,"declarations"))y(f(n,"id"),t);else if(o.type==="FunctionDeclaration"){let n=Pe(f(o,"id"));n&&t.add(n);}return t}var d=(e,t)=>{for(let o of t)e.add(o);},k=(e,t)=>{for(let o of t)e.delete(o);},fe=new Set,ie=e=>new Set(e);function J(e,t){let o=new Set;switch(e.type){case "Identifier":o.add(w(e).name);break;case "MemberExpression":{d(o,t(f(e,"object"))),w(e).computed&&d(o,t(f(e,"property")));break}case "Property":{w(e).computed&&d(o,t(f(e,"key"))),d(o,t(f(e,"value")));break}case "ArrowFunctionExpression":case "FunctionExpression":case "FunctionDeclaration":{let n=g(e,"params"),r=new Set;for(let i of n)y(i,r),i.type==="AssignmentPattern"&&d(o,t(f(i,"right")));d(o,t(f(e,"body"))),k(o,r);break}case "BlockStatement":case "Program":{let n=g(e,"body");for(let r of n)d(o,t(r));k(o,Me(n));break}case "VariableDeclarator":{d(o,t(f(e,"init")));let n=f(e,"id");n&&n.type!=="Identifier"&&A(n,o,t);break}case "CatchClause":{let n=new Set;y(f(e,"param"),n),d(o,t(f(e,"body"))),k(o,n);break}case "LabeledStatement":d(o,t(f(e,"body")));break;case "BreakStatement":case "ContinueStatement":break;case "ForInStatement":case "ForOfStatement":{let n=f(e,"left");d(o,t(f(e,"right")));let r=new Set;if(n.type==="VariableDeclaration")for(let s of g(n,"declarations"))y(f(s,"id"),r);else y(n,r);let i=ie(t(f(e,"body")));k(i,r),d(o,i);break}case "ForStatement":{let n=f(e,"init"),r=new Set;if(n){if(n.type==="VariableDeclaration")for(let i of g(n,"declarations"))y(f(i,"id"),r);d(o,t(n));}for(let i of ["test","update","body"]){let s=ie(t(f(e,i)));k(s,r),d(o,s);}break}default:core.forEachChild(e,n=>d(o,t(n)));break}return o}function ce(e,t={}){let o=new Map,n=new Set(t.globals??[]),r=i=>{if(!i)return fe;let s=J(i,r);return k(s,n),o.set(i,s),s};return r(e),o}function A(e,t,o){if(e.type==="AssignmentPattern")d(t,o(f(e,"right"))),A(f(e,"left"),t,o);else if(e.type==="ArrayPattern")for(let n of g(e,"elements"))n&&A(n,t,o);else if(e.type==="ObjectPattern")for(let n of g(e,"properties")){w(n).computed&&d(t,o(f(n,"key")));let r=f(n,"value")??f(n,"argument");r&&A(r,t,o);}}function Fe(e,t){return ce(e,t).get(e)??new Set}function q(e,t){if(e){if(e.type==="MemberExpression"){q(f(e,"object"),t);return}y(e,t);}}function de(e){let t=new Map,o=n=>{if(!n)return fe;let r=new Set;return n.type==="AssignmentExpression"?q(f(n,"left"),r):n.type==="UpdateExpression"&&q(f(n,"argument"),r),core.forEachChild(n,i=>d(r,o(i))),t.set(n,r),r};return o(e),t}function Ae(e){return de(e).get(e)??new Set}function Ie(e,t){return {root:e,diagnostics:t.diagnostics,typeOf:o=>t.overlay.get(o)?.type,scopeOf:o=>t.overlay.get(o)?.scope}}function Ue(e,t){let o=new Map,n={tree:e,read:s=>o.get(s.name)},r=t.filter(s=>!!s.visitor),i=t.filter(s=>!s.visitor&&s.run);if(r.length){let s=a=>{for(let c of r)c.visitor.enter?.(a,n);core.forEachChild(a,s);for(let c=r.length-1;c>=0;c--)r[c].visitor.exit?.(a,n);};s(e.root);for(let a of r)o.set(a.name,a.visitor.result());}for(let s of i)o.set(s.name,s.run(n));return o}var le=new Set,je=(e,t)=>({name:"effects",run:o=>H(o.tree.root,{env:e,rules:t})}),We=(e,t)=>({name:"nodeEffects",run:o=>K(o.tree.root,{env:e,rules:t})}),$e=e=>({name:"deps",visitor:(()=>{let t=new Set(e?.globals??[]),o=new Map;return {exit(n){let r=J(n,i=>i?o.get(i)??le:le);for(let i of t)r.delete(i);o.set(n,r);},result:()=>o}})()}),_e=e=>({name:"policies",visitor:se(e)});exports.DEFAULT_RULES=M;exports.PURE=T;exports.PURE_ROW=E;exports.PURE_SCHEME=j;exports.analyze=Ue;exports.checkEffectPolicy=ke;exports.checkEffects=Y;exports.checkPolicies=Ce;exports.deps=ce;exports.depsOverlay=$e;exports.effect=I;exports.effectCeiling=te;exports.effectEnv=Ee;exports.effectsByNode=K;exports.effectsOverlay=je;exports.effectsOverlayOf=H;exports.excess=W;exports.forwardEffect=ge;exports.freeVars=Fe;exports.groundRow=N;exports.inferEffects=G;exports.instantiateScheme=V;exports.join=pe;exports.joinRows=R;exports.nodeEffectsOverlay=We;exports.policiesOverlay=_e;exports.rowOf=U;exports.rowOfVar=C;exports.substituteRow=X;exports.typedTreeOf=Ie;exports.within=ye;exports.writeTargets=Ae;exports.writes=de;
|
package/dist/index.d.cts
CHANGED
|
@@ -109,6 +109,17 @@ declare function effectsOverlayOf(root: BaseNode, opts?: {
|
|
|
109
109
|
readonly env?: EffectEnv;
|
|
110
110
|
readonly rules?: EffectRules;
|
|
111
111
|
}): Map<BaseNode, Effect>;
|
|
112
|
+
/**
|
|
113
|
+
* O efeito de CADA nó (não só função): `Map<nó, Effect>` aterrado. Espelha o
|
|
114
|
+
* `effectsOverlayOf`, mas percorre o `ctx.nodeEff` — o efeito que `execNode`
|
|
115
|
+
* computa por nó (calls propagam o do callee; def de função é pura; `for`/`await`
|
|
116
|
+
* carregam seu átomo via `rules.nodeEffects`). É a base do `describeExpr` do
|
|
117
|
+
* `@tslite/nocode` ("o que ESTA expressão faz?"). Reads (free vars) vêm do `deps`.
|
|
118
|
+
*/
|
|
119
|
+
declare function effectsByNode(root: BaseNode, opts?: {
|
|
120
|
+
readonly env?: EffectEnv;
|
|
121
|
+
readonly rules?: EffectRules;
|
|
122
|
+
}): Map<BaseNode, Effect>;
|
|
112
123
|
|
|
113
124
|
/** Uma violação de contrato de efeito (erro como dado). */
|
|
114
125
|
interface EffectViolation {
|
|
@@ -245,12 +256,30 @@ interface DepsOptions {
|
|
|
245
256
|
declare function deps(node: BaseNode, opts?: DepsOptions): DepsOverlay;
|
|
246
257
|
/** Conveniência: as variáveis livres (deps) da raiz `node`. */
|
|
247
258
|
declare function freeVars(node: BaseNode, opts?: DepsOptions): ReadonlySet<Dep>;
|
|
259
|
+
/** Um nome ESCRITO (alvo de `=`/`+=`/`++`) — o lado def do use-def. */
|
|
260
|
+
type Write = string;
|
|
261
|
+
/** O overlay: para cada nó, o conjunto de nomes que sua subárvore escreve. */
|
|
262
|
+
type WritesOverlay = Map<BaseNode, ReadonlySet<Write>>;
|
|
263
|
+
/**
|
|
264
|
+
* O overlay de WRITES de `node`: para cada subárvore, os nomes que ela escreve.
|
|
265
|
+
* Simétrico ao {@link deps} (ver A16). O nó de atribuição contribui seu alvo; a
|
|
266
|
+
* subárvore propaga a união (um write aninhado no RHS, `x = (y = 1)`, conta `y`).
|
|
267
|
+
*/
|
|
268
|
+
declare function writes(node: BaseNode): WritesOverlay;
|
|
269
|
+
/** Conveniência: os nomes que a raiz `node` escreve. */
|
|
270
|
+
declare function writeTargets(node: BaseNode): ReadonlySet<Write>;
|
|
248
271
|
|
|
249
272
|
/**
|
|
250
273
|
* `effects` como overlay: o efeito concreto de **cada função** (`Map<fn, Effect>`).
|
|
251
274
|
* Faz a própria travessia (grafo lazy de schemes) — forma `run`.
|
|
252
275
|
*/
|
|
253
276
|
declare const effectsOverlay: (env: EffectEnv, rules?: EffectRules) => Overlay<Effect>;
|
|
277
|
+
/**
|
|
278
|
+
* `nodeEffects` como overlay: o efeito de **cada nó** (`Map<nó, Effect>`) — não só
|
|
279
|
+
* função. É o que o `describeExpr` do `@tslite/nocode` lê ("o que ESTA expressão
|
|
280
|
+
* faz?"). Reads (free vars) vêm do `depsOverlay`, em paralelo.
|
|
281
|
+
*/
|
|
282
|
+
declare const nodeEffectsOverlay: (env: EffectEnv, rules?: EffectRules) => Overlay<Effect>;
|
|
254
283
|
/**
|
|
255
284
|
* `deps` como overlay-**visitor**: as variáveis livres de cada subárvore. Em
|
|
256
285
|
* pós-ordem (`exit`), combina os filhos (já no map) — partilha o walk do runner.
|
|
@@ -262,4 +291,4 @@ declare const depsOverlay: (opts?: DepsOptions) => Overlay<ReadonlySet<Dep>>;
|
|
|
262
291
|
*/
|
|
263
292
|
declare const policiesOverlay: (opts: PolicyOptions) => Overlay<PolicyViolation>;
|
|
264
293
|
|
|
265
|
-
export { type Analysis, type Category, DEFAULT_RULES, type Decision, type Dep, type DepsOptions, type DepsOverlay, type Effect, type EffectAtom, type EffectDecl, type EffectEnv, type EffectRow, type EffectRules, type EffectScheme, type EffectVar, type EffectViolation, type InferOptions, type Overlay, type OverlayCtx, type OverlayResult, type OverlayVisitor, PURE, PURE_ROW, PURE_SCHEME, type PolicyMatrix, type PolicyOptions, type PolicyViolation, type TypedTree, analyze, checkEffectPolicy, checkEffects, checkPolicies, deps, depsOverlay, effect, effectCeiling, effectEnv, effectsOverlay, effectsOverlayOf, excess, forwardEffect, freeVars, groundRow, inferEffects, instantiateScheme, join, joinRows, policiesOverlay, rowOf, rowOfVar, substituteRow, typedTreeOf, within };
|
|
294
|
+
export { type Analysis, type Category, DEFAULT_RULES, type Decision, type Dep, type DepsOptions, type DepsOverlay, type Effect, type EffectAtom, type EffectDecl, type EffectEnv, type EffectRow, type EffectRules, type EffectScheme, type EffectVar, type EffectViolation, type InferOptions, type Overlay, type OverlayCtx, type OverlayResult, type OverlayVisitor, PURE, PURE_ROW, PURE_SCHEME, type PolicyMatrix, type PolicyOptions, type PolicyViolation, type TypedTree, type Write, type WritesOverlay, analyze, checkEffectPolicy, checkEffects, checkPolicies, deps, depsOverlay, effect, effectCeiling, effectEnv, effectsByNode, effectsOverlay, effectsOverlayOf, excess, forwardEffect, freeVars, groundRow, inferEffects, instantiateScheme, join, joinRows, nodeEffectsOverlay, policiesOverlay, rowOf, rowOfVar, substituteRow, typedTreeOf, within, writeTargets, writes };
|
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,17 @@ declare function effectsOverlayOf(root: BaseNode, opts?: {
|
|
|
109
109
|
readonly env?: EffectEnv;
|
|
110
110
|
readonly rules?: EffectRules;
|
|
111
111
|
}): Map<BaseNode, Effect>;
|
|
112
|
+
/**
|
|
113
|
+
* O efeito de CADA nó (não só função): `Map<nó, Effect>` aterrado. Espelha o
|
|
114
|
+
* `effectsOverlayOf`, mas percorre o `ctx.nodeEff` — o efeito que `execNode`
|
|
115
|
+
* computa por nó (calls propagam o do callee; def de função é pura; `for`/`await`
|
|
116
|
+
* carregam seu átomo via `rules.nodeEffects`). É a base do `describeExpr` do
|
|
117
|
+
* `@tslite/nocode` ("o que ESTA expressão faz?"). Reads (free vars) vêm do `deps`.
|
|
118
|
+
*/
|
|
119
|
+
declare function effectsByNode(root: BaseNode, opts?: {
|
|
120
|
+
readonly env?: EffectEnv;
|
|
121
|
+
readonly rules?: EffectRules;
|
|
122
|
+
}): Map<BaseNode, Effect>;
|
|
112
123
|
|
|
113
124
|
/** Uma violação de contrato de efeito (erro como dado). */
|
|
114
125
|
interface EffectViolation {
|
|
@@ -245,12 +256,30 @@ interface DepsOptions {
|
|
|
245
256
|
declare function deps(node: BaseNode, opts?: DepsOptions): DepsOverlay;
|
|
246
257
|
/** Conveniência: as variáveis livres (deps) da raiz `node`. */
|
|
247
258
|
declare function freeVars(node: BaseNode, opts?: DepsOptions): ReadonlySet<Dep>;
|
|
259
|
+
/** Um nome ESCRITO (alvo de `=`/`+=`/`++`) — o lado def do use-def. */
|
|
260
|
+
type Write = string;
|
|
261
|
+
/** O overlay: para cada nó, o conjunto de nomes que sua subárvore escreve. */
|
|
262
|
+
type WritesOverlay = Map<BaseNode, ReadonlySet<Write>>;
|
|
263
|
+
/**
|
|
264
|
+
* O overlay de WRITES de `node`: para cada subárvore, os nomes que ela escreve.
|
|
265
|
+
* Simétrico ao {@link deps} (ver A16). O nó de atribuição contribui seu alvo; a
|
|
266
|
+
* subárvore propaga a união (um write aninhado no RHS, `x = (y = 1)`, conta `y`).
|
|
267
|
+
*/
|
|
268
|
+
declare function writes(node: BaseNode): WritesOverlay;
|
|
269
|
+
/** Conveniência: os nomes que a raiz `node` escreve. */
|
|
270
|
+
declare function writeTargets(node: BaseNode): ReadonlySet<Write>;
|
|
248
271
|
|
|
249
272
|
/**
|
|
250
273
|
* `effects` como overlay: o efeito concreto de **cada função** (`Map<fn, Effect>`).
|
|
251
274
|
* Faz a própria travessia (grafo lazy de schemes) — forma `run`.
|
|
252
275
|
*/
|
|
253
276
|
declare const effectsOverlay: (env: EffectEnv, rules?: EffectRules) => Overlay<Effect>;
|
|
277
|
+
/**
|
|
278
|
+
* `nodeEffects` como overlay: o efeito de **cada nó** (`Map<nó, Effect>`) — não só
|
|
279
|
+
* função. É o que o `describeExpr` do `@tslite/nocode` lê ("o que ESTA expressão
|
|
280
|
+
* faz?"). Reads (free vars) vêm do `depsOverlay`, em paralelo.
|
|
281
|
+
*/
|
|
282
|
+
declare const nodeEffectsOverlay: (env: EffectEnv, rules?: EffectRules) => Overlay<Effect>;
|
|
254
283
|
/**
|
|
255
284
|
* `deps` como overlay-**visitor**: as variáveis livres de cada subárvore. Em
|
|
256
285
|
* pós-ordem (`exit`), combina os filhos (já no map) — partilha o walk do runner.
|
|
@@ -262,4 +291,4 @@ declare const depsOverlay: (opts?: DepsOptions) => Overlay<ReadonlySet<Dep>>;
|
|
|
262
291
|
*/
|
|
263
292
|
declare const policiesOverlay: (opts: PolicyOptions) => Overlay<PolicyViolation>;
|
|
264
293
|
|
|
265
|
-
export { type Analysis, type Category, DEFAULT_RULES, type Decision, type Dep, type DepsOptions, type DepsOverlay, type Effect, type EffectAtom, type EffectDecl, type EffectEnv, type EffectRow, type EffectRules, type EffectScheme, type EffectVar, type EffectViolation, type InferOptions, type Overlay, type OverlayCtx, type OverlayResult, type OverlayVisitor, PURE, PURE_ROW, PURE_SCHEME, type PolicyMatrix, type PolicyOptions, type PolicyViolation, type TypedTree, analyze, checkEffectPolicy, checkEffects, checkPolicies, deps, depsOverlay, effect, effectCeiling, effectEnv, effectsOverlay, effectsOverlayOf, excess, forwardEffect, freeVars, groundRow, inferEffects, instantiateScheme, join, joinRows, policiesOverlay, rowOf, rowOfVar, substituteRow, typedTreeOf, within };
|
|
294
|
+
export { type Analysis, type Category, DEFAULT_RULES, type Decision, type Dep, type DepsOptions, type DepsOverlay, type Effect, type EffectAtom, type EffectDecl, type EffectEnv, type EffectRow, type EffectRules, type EffectScheme, type EffectVar, type EffectViolation, type InferOptions, type Overlay, type OverlayCtx, type OverlayResult, type OverlayVisitor, PURE, PURE_ROW, PURE_SCHEME, type PolicyMatrix, type PolicyOptions, type PolicyViolation, type TypedTree, type Write, type WritesOverlay, analyze, checkEffectPolicy, checkEffects, checkPolicies, deps, depsOverlay, effect, effectCeiling, effectEnv, effectsByNode, effectsOverlay, effectsOverlayOf, excess, forwardEffect, freeVars, groundRow, inferEffects, instantiateScheme, join, joinRows, nodeEffectsOverlay, policiesOverlay, rowOf, rowOfVar, substituteRow, typedTreeOf, within, writeTargets, writes };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {forEachChild,rootScope,childScope,lookup}from'@tslite/core';var I=new Set,T=(...e)=>new Set(e),m={atoms:new Set,vars:new Set},M=(...e)=>({atoms:new Set(e),vars:new Set}),C=e=>({atoms:new Set,vars:new Set([e])}),R=e=>{let t=new Set,o=new Set;for(let n of e){for(let r of n.atoms)t.add(r);for(let r of n.vars)o.add(r);}return {atoms:t,vars:o}},Y=(e,t)=>{let o=new Set(e.atoms),n=new Set;for(let r of e.vars){let i=t.get(r);if(i){for(let s of i.atoms)o.add(s);for(let s of i.vars)n.add(s);}else n.add(r);}return {atoms:o,vars:n}},U={params:[],latent:m},V=(e,t)=>{let o=new Map;return e.params.forEach((n,r)=>{let i=t[r];n&&i&&o.set(n,i);}),Y(e.latent,o)},O=e=>new Set(e.atoms),ae=e=>{let t=new Set;for(let o of e)for(let n of o)t.add(n);return t},fe=(e,t)=>{for(let o of e)if(!t.has(o))return false;return true},j=(e,t)=>[...e].filter(o=>!t.has(o));var de=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]=new Set(n);return t},pe=(e,t,o=[])=>{let n=new Array(t).fill(null),r="\u03B5";return n[e]=r,{params:n,latent:{atoms:new Set(o),vars:new Set([r])}}},L={nodeEffects:{ForStatement:"loops",ForInStatement:"loops",ForOfStatement:"loops",WhileStatement:"loops",DoWhileStatement:"loops",AssignmentExpression:"mutates",UpdateExpression:"mutates"}},ye=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),h=e=>ye.has(e.type),p=e=>e,ue=e=>p(e).body,me=e=>p(e).params??[],S=e=>e&&e.type==="Identifier"?p(e).name:void 0,Ee=e=>{let t=p(e).object,o=p(e).property,n=S(t);if(!n)return null;let r=p(e).computed?void 0:S(o);return {path:r?`${n}.${r}`:n,root:n}},ge=e=>typeof e=="object"&&e!==null&&"latent"in e,$=(e,t)=>ge(e)?V(e,t):{atoms:new Set(e),vars:new Set},J=(e,t)=>{let o=0;return {rules:e,env:t,schemeOf:new Map,active:new Set,fresh:()=>`\u03B5${o++}`}},Q=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]={kind:"capability",decl:n};return rootScope(t)};function x(e,t,o){let n=o.schemeOf.get(e);if(n)return n;if(o.active.has(e))return U;o.active.add(e);let r=me(e),i=r.map(v=>v.type==="Identifier"?o.fresh():null),s={};r.forEach((v,D)=>{let K=S(v);K&&i[D]&&(s[K]={kind:"param",var:i[D]});});let a=childScope(t,s),f=ue(e),u=f?E(f,a,o):m,d={params:i,latent:u};return o.active.delete(e),o.schemeOf.set(e,d),d}function _(e,t,o){x(e,t,o);}function E(e,t,o){let n=o.rules.nodeEffects[e.type],r=n?M(n):m;if(h(e))return _(e,t,o),r;if(e.type==="CallExpression"||e.type==="NewExpression")return R([r,we(e,t,o)]);if(e.type==="BlockStatement"||e.type==="Program"){let s=p(e).body??[];return R([r,ve(s,t,o)])}let i=[r];return forEachChild(e,s=>i.push(E(s,t,o))),R(i)}function ve(e,t,o){let n=t,r={};for(let s of e)if(s.type==="FunctionDeclaration"){let a=S(p(s).id);a&&(r[a]={kind:"fn",node:s,scope:n});}Object.keys(r).length&&(n=childScope(n,r));for(let s in r)r[s].kind==="fn"&&(r[s].scope=n);for(let s in r){let a=r[s];a.kind==="fn"&&_(a.node,n,o);}let i=[];for(let s of e)if(s.type!=="FunctionDeclaration"){if(s.type==="VariableDeclaration"){let a=p(s).declarations??[];for(let f of a){let u=p(f).id,d=p(f).init,v=S(u);if(v&&d&&h(d)){let D=childScope(n,{[v]:{kind:"fn",node:d,scope:n}});_(d,D,o),n=D;}else d&&i.push(E(d,n,o)),v&&(n=childScope(n,{[v]:{kind:"value"}}));}continue}i.push(E(s,n,o));}return R(i)}function we(e,t,o){let n=p(e).callee,r=p(e).arguments??[],i=r.map(f=>h(f)?m:E(f,t,o)),s=r.map(f=>Re(f,t,o)),a=Se(n,s,t,o);return R([a,...i])}function Re(e,t,o){if(h(e))return x(e,t,o).latent;if(e.type==="Identifier"){let n=lookup(t,S(e));if(!n)return null;if(n.kind==="fn")return x(n.node,n.scope,o).latent;if(n.kind==="param")return C(n.var);if(n.kind==="capability")return $(n.decl,[])}return null}function Se(e,t,o,n){if(!e)return m;if(e.type==="Identifier"){let r=lookup(o,S(e));if(!r)return m;switch(r.kind){case "capability":return $(r.decl,t);case "fn":return V(x(r.node,r.scope,n),t);case "param":return C(r.var);case "value":return m}}if(h(e))return V(x(e,o,n),t);if(e.type==="MemberExpression"){let r=Ee(e),i=r&&(n.env[r.path]??n.env[r.root]);if(i)return $(i,t)}return E(e,o,n)}function W(e,t={}){let o=t.env??{},n=J(t.rules??L,o),r=Q(o);if(t.root&&t.root!==e){E(t.root,r,n);let i=n.schemeOf.get(e);if(i)return O(i.latent)}return h(e)?O(x(e,r,n).latent):O(E(e,r,n))}function z(e,t={}){let o=t.env??{},n=J(t.rules??L,o);E(e,Q(o),n);let r=new Map;for(let[i,s]of n.schemeOf)r.set(i,O(s.latent));return r}var X=e=>e.size?`{ ${[...e].sort().join(", ")} }`:"pure";function G(e,t,o){let n=W(e,o),r=j(n,t);return r.length===0?[]:[{node:e,declared:t,inferred:n,excess:r,message:`Effect contract violated: declared ${X(t)} but infers ${X(n)} \u2014 not allowed: ${r.join(", ")}.`}]}function Z(e){switch(e){case "pure":return I;case "io":return T("io");case "any":return null}}function Be(e,t,o){let n=Z(t);return n===null?[]:G(e,n,o)}var b=e=>e,B=e=>e&&e.type==="Identifier"?b(e).name:void 0,N=(e,t)=>b(e)[t],Ne=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),F=e=>Ne.has(e.type);function Oe(e){if(!e)return null;if(e.type==="Identifier"){let t=B(e);return {path:t,root:t}}if(e.type==="MemberExpression"){let t=b(e).object,o=b(e).property,n=b(e).computed,r=B(t);if(!r)return null;let i=n?void 0:B(o);return {path:i?`${r}.${i}`:r,root:r}}return null}function te(e){let{categories:t,matrix:o}=e,n=o.defaultPolicy??"allow",r=s=>t[s.path]??t[s.root],i=(s,a)=>o.rules[s]?.[a]??n;return (s,a)=>{if(!a)return null;let f=t[a];if(f===void 0)return null;let u=Oe(N(s,"callee"));if(!u)return null;let d=r(u);return d===void 0||i(f,d)!=="deny"?null:{call:s,from:a,to:u.path,fromCategory:f,toCategory:d,message:`Policy violated: ${f} '${a}' must not call ${d} '${u.path}' (${f} \u2192 ${d} is deny).`}}}var oe=e=>e.type==="CallExpression"||e.type==="NewExpression";function xe(e,t){let o=te(t),n=[],r=(i,s)=>{if(oe(i)){let a=o(i,s);a&&n.push(a);}if(i.type==="VariableDeclaration"){for(let a of b(i).declarations??[]){let f=N(a,"init");if(!f)continue;let u=F(f)?B(N(a,"id"))??s:s;r(f,u);}return}if(i.type==="FunctionDeclaration"){let a=B(N(i,"id"))??s;forEachChild(i,f=>r(f,a));return}forEachChild(i,a=>r(a,s));};return r(e,null),n}function ne(e){let t=te(e),o=new Map,n=[],r=()=>n.length?n[n.length-1]:null,i=null;return {enter(s){if(s.type==="VariableDeclarator"){let a=N(s,"init"),f=B(N(s,"id"));a&&F(a)&&f&&(i={name:f,fn:a});}if(F(s)){let a=i&&i.fn===s?i.name:s.type==="FunctionDeclaration"?B(N(s,"id"))??r():r();n.push(a),i=null;}if(oe(s)){let a=t(s,r());a&&o.set(s,a);}},exit(s){F(s)&&n.pop();},result:()=>o}}var w=e=>e,be=e=>e&&e.type==="Identifier"?w(e).name:void 0,c=(e,t)=>w(e)[t],g=(e,t)=>w(e)[t]??[];function y(e,t){if(e)switch(e.type){case "Identifier":t.add(w(e).name);return;case "AssignmentPattern":y(c(e,"left"),t);return;case "RestElement":y(c(e,"argument"),t);return;case "ArrayPattern":for(let o of g(e,"elements"))y(o,t);return;case "ObjectPattern":for(let o of g(e,"properties"))o.type==="RestElement"?y(c(o,"argument"),t):y(c(o,"value"),t);return}}function ke(e){let t=new Set;for(let o of e)if(o.type==="VariableDeclaration")for(let n of g(o,"declarations"))y(c(n,"id"),t);else if(o.type==="FunctionDeclaration"){let n=be(c(o,"id"));n&&t.add(n);}return t}var l=(e,t)=>{for(let o of t)e.add(o);},k=(e,t)=>{for(let o of t)e.delete(o);},De=new Set,re=e=>new Set(e);function H(e,t){let o=new Set;switch(e.type){case "Identifier":o.add(w(e).name);break;case "MemberExpression":{l(o,t(c(e,"object"))),w(e).computed&&l(o,t(c(e,"property")));break}case "Property":{w(e).computed&&l(o,t(c(e,"key"))),l(o,t(c(e,"value")));break}case "ArrowFunctionExpression":case "FunctionExpression":case "FunctionDeclaration":{let n=g(e,"params"),r=new Set;for(let i of n)y(i,r),i.type==="AssignmentPattern"&&l(o,t(c(i,"right")));l(o,t(c(e,"body"))),k(o,r);break}case "BlockStatement":case "Program":{let n=g(e,"body");for(let r of n)l(o,t(r));k(o,ke(n));break}case "VariableDeclarator":{l(o,t(c(e,"init")));let n=c(e,"id");n&&n.type!=="Identifier"&&A(n,o,t);break}case "CatchClause":{let n=new Set;y(c(e,"param"),n),l(o,t(c(e,"body"))),k(o,n);break}case "LabeledStatement":l(o,t(c(e,"body")));break;case "BreakStatement":case "ContinueStatement":break;case "ForInStatement":case "ForOfStatement":{let n=c(e,"left");l(o,t(c(e,"right")));let r=new Set;if(n.type==="VariableDeclaration")for(let s of g(n,"declarations"))y(c(s,"id"),r);else y(n,r);let i=re(t(c(e,"body")));k(i,r),l(o,i);break}case "ForStatement":{let n=c(e,"init"),r=new Set;if(n){if(n.type==="VariableDeclaration")for(let i of g(n,"declarations"))y(c(i,"id"),r);l(o,t(n));}for(let i of ["test","update","body"]){let s=re(t(c(e,i)));k(s,r),l(o,s);}break}default:forEachChild(e,n=>l(o,t(n)));break}return o}function se(e,t={}){let o=new Map,n=new Set(t.globals??[]),r=i=>{if(!i)return De;let s=H(i,r);return k(s,n),o.set(i,s),s};return r(e),o}function A(e,t,o){if(e.type==="AssignmentPattern")l(t,o(c(e,"right"))),A(c(e,"left"),t,o);else if(e.type==="ArrayPattern")for(let n of g(e,"elements"))n&&A(n,t,o);else if(e.type==="ObjectPattern")for(let n of g(e,"properties")){w(n).computed&&l(t,o(c(n,"key")));let r=c(n,"value")??c(n,"argument");r&&A(r,t,o);}}function Ve(e,t){return se(e,t).get(e)??new Set}function Pe(e,t){return {root:e,diagnostics:t.diagnostics,typeOf:o=>t.overlay.get(o)?.type,scopeOf:o=>t.overlay.get(o)?.scope}}function Fe(e,t){let o=new Map,n={tree:e,read:s=>o.get(s.name)},r=t.filter(s=>!!s.visitor),i=t.filter(s=>!s.visitor&&s.run);if(r.length){let s=a=>{for(let f of r)f.visitor.enter?.(a,n);forEachChild(a,s);for(let f=r.length-1;f>=0;f--)r[f].visitor.exit?.(a,n);};s(e.root);for(let a of r)o.set(a.name,a.visitor.result());}for(let s of i)o.set(s.name,s.run(n));return o}var ie=new Set,Ae=(e,t)=>({name:"effects",run:o=>z(o.tree.root,{env:e,rules:t})}),Ie=e=>({name:"deps",visitor:(()=>{let t=new Set(e?.globals??[]),o=new Map;return {exit(n){let r=H(n,i=>i?o.get(i)??ie:ie);for(let i of t)r.delete(i);o.set(n,r);},result:()=>o}})()}),Te=e=>({name:"policies",visitor:ne(e)});export{L as DEFAULT_RULES,I as PURE,m as PURE_ROW,U as PURE_SCHEME,Fe as analyze,Be as checkEffectPolicy,G as checkEffects,xe as checkPolicies,se as deps,Ie as depsOverlay,T as effect,Z as effectCeiling,de as effectEnv,Ae as effectsOverlay,z as effectsOverlayOf,j as excess,pe as forwardEffect,Ve as freeVars,O as groundRow,W as inferEffects,V as instantiateScheme,ae as join,R as joinRows,Te as policiesOverlay,M as rowOf,C as rowOfVar,Y as substituteRow,Pe as typedTreeOf,fe as within};
|
|
1
|
+
import {forEachChild,rootScope,childScope,lookup}from'@tslite/core';var T=new Set,I=(...e)=>new Set(e),E={atoms:new Set,vars:new Set},U=(...e)=>({atoms:new Set(e),vars:new Set}),C=e=>({atoms:new Set,vars:new Set([e])}),R=e=>{let t=new Set,o=new Set;for(let n of e){for(let r of n.atoms)t.add(r);for(let r of n.vars)o.add(r);}return {atoms:t,vars:o}},X=(e,t)=>{let o=new Set(e.atoms),n=new Set;for(let r of e.vars){let i=t.get(r);if(i){for(let s of i.atoms)o.add(s);for(let s of i.vars)n.add(s);}else n.add(r);}return {atoms:o,vars:n}},j={params:[],latent:E},V=(e,t)=>{let o=new Map;return e.params.forEach((n,r)=>{let i=t[r];n&&i&&o.set(n,i);}),X(e.latent,o)},N=e=>new Set(e.atoms),pe=e=>{let t=new Set;for(let o of e)for(let n of o)t.add(n);return t},ye=(e,t)=>{for(let o of e)if(!t.has(o))return false;return true},W=(e,t)=>[...e].filter(o=>!t.has(o));var Ee=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]=new Set(n);return t},ge=(e,t,o=[])=>{let n=new Array(t).fill(null),r="\u03B5";return n[e]=r,{params:n,latent:{atoms:new Set(o),vars:new Set([r])}}},M={nodeEffects:{ForStatement:"loops",ForInStatement:"loops",ForOfStatement:"loops",WhileStatement:"loops",DoWhileStatement:"loops",AssignmentExpression:"mutates",UpdateExpression:"mutates"}},ve=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),h=e=>ve.has(e.type),p=e=>e,we=e=>p(e).body,Re=e=>p(e).params??[],B=e=>e&&e.type==="Identifier"?p(e).name:void 0,Ne=e=>{let t=p(e).object,o=p(e).property,n=B(t);if(!n)return null;let r=p(e).computed?void 0:B(o);return {path:r?`${n}.${r}`:n,root:n}},Be=e=>typeof e=="object"&&e!==null&&"latent"in e,$=(e,t)=>Be(e)?V(e,t):{atoms:new Set(e),vars:new Set},L=(e,t)=>{let o=0;return {rules:e,env:t,schemeOf:new Map,nodeEff:new Map,active:new Set,fresh:()=>`\u03B5${o++}`}},z=e=>{let t={};for(let[o,n]of Object.entries(e))t[o]={kind:"capability",decl:n};return rootScope(t)};function O(e,t,o){let n=o.schemeOf.get(e);if(n)return n;if(o.active.has(e))return j;o.active.add(e);let r=Re(e),i=r.map(v=>v.type==="Identifier"?o.fresh():null),s={};r.forEach((v,D)=>{let Q=B(v);Q&&i[D]&&(s[Q]={kind:"param",var:i[D]});});let a=childScope(t,s),c=we(e),u=c?m(c,a,o):E,l={params:i,latent:u};return o.active.delete(e),o.schemeOf.set(e,l),l}function _(e,t,o){O(e,t,o);}function m(e,t,o){let n=Se(e,t,o);return o.nodeEff.set(e,n),n}function Se(e,t,o){let n=o.rules.nodeEffects[e.type],r=n?U(n):E;if(h(e))return _(e,t,o),r;if(e.type==="CallExpression"||e.type==="NewExpression")return R([r,Oe(e,t,o)]);if(e.type==="BlockStatement"||e.type==="Program"){let s=p(e).body??[];return R([r,xe(s,t,o)])}let i=[r];return forEachChild(e,s=>i.push(m(s,t,o))),R(i)}function xe(e,t,o){let n=t,r={};for(let s of e)if(s.type==="FunctionDeclaration"){let a=B(p(s).id);a&&(r[a]={kind:"fn",node:s,scope:n});}Object.keys(r).length&&(n=childScope(n,r));for(let s in r)r[s].kind==="fn"&&(r[s].scope=n);for(let s in r){let a=r[s];a.kind==="fn"&&_(a.node,n,o);}let i=[];for(let s of e)if(s.type!=="FunctionDeclaration"){if(s.type==="VariableDeclaration"){let a=p(s).declarations??[];for(let c of a){let u=p(c).id,l=p(c).init,v=B(u);if(v&&l&&h(l)){let D=childScope(n,{[v]:{kind:"fn",node:l,scope:n}});_(l,D,o),n=D;}else l&&i.push(m(l,n,o)),v&&(n=childScope(n,{[v]:{kind:"value"}}));}continue}i.push(m(s,n,o));}return R(i)}function Oe(e,t,o){let n=p(e).callee,r=p(e).arguments??[],i=r.map(c=>h(c)?E:m(c,t,o)),s=r.map(c=>he(c,t,o)),a=be(n,s,t,o);return R([a,...i])}function he(e,t,o){if(h(e))return O(e,t,o).latent;if(e.type==="Identifier"){let n=lookup(t,B(e));if(!n)return null;if(n.kind==="fn")return O(n.node,n.scope,o).latent;if(n.kind==="param")return C(n.var);if(n.kind==="capability")return $(n.decl,[])}return null}function be(e,t,o,n){if(!e)return E;if(e.type==="Identifier"){let r=lookup(o,B(e));if(!r)return E;switch(r.kind){case "capability":return $(r.decl,t);case "fn":return V(O(r.node,r.scope,n),t);case "param":return C(r.var);case "value":return E}}if(h(e))return V(O(e,o,n),t);if(e.type==="MemberExpression"){let r=Ne(e),i=r&&(n.env[r.path]??n.env[r.root]);if(i)return $(i,t)}return m(e,o,n)}function G(e,t={}){let o=t.env??{},n=L(t.rules??M,o),r=z(o);if(t.root&&t.root!==e){m(t.root,r,n);let i=n.schemeOf.get(e);if(i)return N(i.latent)}return h(e)?N(O(e,r,n).latent):N(m(e,r,n))}function H(e,t={}){let o=t.env??{},n=L(t.rules??M,o);m(e,z(o),n);let r=new Map;for(let[i,s]of n.schemeOf)r.set(i,N(s.latent));return r}function K(e,t={}){let o=t.env??{},n=L(t.rules??M,o);m(e,z(o),n);let r=new Map;for(let[i,s]of n.nodeEff)r.set(i,N(s));return r}var ee=e=>e.size?`{ ${[...e].sort().join(", ")} }`:"pure";function Y(e,t,o){let n=G(e,o),r=W(n,t);return r.length===0?[]:[{node:e,declared:t,inferred:n,excess:r,message:`Effect contract violated: declared ${ee(t)} but infers ${ee(n)} \u2014 not allowed: ${r.join(", ")}.`}]}function te(e){switch(e){case "pure":return T;case "io":return I("io");case "any":return null}}function ke(e,t,o){let n=te(t);return n===null?[]:Y(e,n,o)}var b=e=>e,S=e=>e&&e.type==="Identifier"?b(e).name:void 0,x=(e,t)=>b(e)[t],De=new Set(["ArrowFunctionExpression","FunctionExpression","FunctionDeclaration"]),F=e=>De.has(e.type);function Ve(e){if(!e)return null;if(e.type==="Identifier"){let t=S(e);return {path:t,root:t}}if(e.type==="MemberExpression"){let t=b(e).object,o=b(e).property,n=b(e).computed,r=S(t);if(!r)return null;let i=n?void 0:S(o);return {path:i?`${r}.${i}`:r,root:r}}return null}function ne(e){let{categories:t,matrix:o}=e,n=o.defaultPolicy??"allow",r=s=>t[s.path]??t[s.root],i=(s,a)=>o.rules[s]?.[a]??n;return (s,a)=>{if(!a)return null;let c=t[a];if(c===void 0)return null;let u=Ve(x(s,"callee"));if(!u)return null;let l=r(u);return l===void 0||i(c,l)!=="deny"?null:{call:s,from:a,to:u.path,fromCategory:c,toCategory:l,message:`Policy violated: ${c} '${a}' must not call ${l} '${u.path}' (${c} \u2192 ${l} is deny).`}}}var re=e=>e.type==="CallExpression"||e.type==="NewExpression";function Ce(e,t){let o=ne(t),n=[],r=(i,s)=>{if(re(i)){let a=o(i,s);a&&n.push(a);}if(i.type==="VariableDeclaration"){for(let a of b(i).declarations??[]){let c=x(a,"init");if(!c)continue;let u=F(c)?S(x(a,"id"))??s:s;r(c,u);}return}if(i.type==="FunctionDeclaration"){let a=S(x(i,"id"))??s;forEachChild(i,c=>r(c,a));return}forEachChild(i,a=>r(a,s));};return r(e,null),n}function se(e){let t=ne(e),o=new Map,n=[],r=()=>n.length?n[n.length-1]:null,i=null;return {enter(s){if(s.type==="VariableDeclarator"){let a=x(s,"init"),c=S(x(s,"id"));a&&F(a)&&c&&(i={name:c,fn:a});}if(F(s)){let a=i&&i.fn===s?i.name:s.type==="FunctionDeclaration"?S(x(s,"id"))??r():r();n.push(a),i=null;}if(re(s)){let a=t(s,r());a&&o.set(s,a);}},exit(s){F(s)&&n.pop();},result:()=>o}}var w=e=>e,Pe=e=>e&&e.type==="Identifier"?w(e).name:void 0,f=(e,t)=>w(e)[t],g=(e,t)=>w(e)[t]??[];function y(e,t){if(e)switch(e.type){case "Identifier":t.add(w(e).name);return;case "AssignmentPattern":y(f(e,"left"),t);return;case "RestElement":y(f(e,"argument"),t);return;case "ArrayPattern":for(let o of g(e,"elements"))y(o,t);return;case "ObjectPattern":for(let o of g(e,"properties"))o.type==="RestElement"?y(f(o,"argument"),t):y(f(o,"value"),t);return}}function Me(e){let t=new Set;for(let o of e)if(o.type==="VariableDeclaration")for(let n of g(o,"declarations"))y(f(n,"id"),t);else if(o.type==="FunctionDeclaration"){let n=Pe(f(o,"id"));n&&t.add(n);}return t}var d=(e,t)=>{for(let o of t)e.add(o);},k=(e,t)=>{for(let o of t)e.delete(o);},fe=new Set,ie=e=>new Set(e);function J(e,t){let o=new Set;switch(e.type){case "Identifier":o.add(w(e).name);break;case "MemberExpression":{d(o,t(f(e,"object"))),w(e).computed&&d(o,t(f(e,"property")));break}case "Property":{w(e).computed&&d(o,t(f(e,"key"))),d(o,t(f(e,"value")));break}case "ArrowFunctionExpression":case "FunctionExpression":case "FunctionDeclaration":{let n=g(e,"params"),r=new Set;for(let i of n)y(i,r),i.type==="AssignmentPattern"&&d(o,t(f(i,"right")));d(o,t(f(e,"body"))),k(o,r);break}case "BlockStatement":case "Program":{let n=g(e,"body");for(let r of n)d(o,t(r));k(o,Me(n));break}case "VariableDeclarator":{d(o,t(f(e,"init")));let n=f(e,"id");n&&n.type!=="Identifier"&&A(n,o,t);break}case "CatchClause":{let n=new Set;y(f(e,"param"),n),d(o,t(f(e,"body"))),k(o,n);break}case "LabeledStatement":d(o,t(f(e,"body")));break;case "BreakStatement":case "ContinueStatement":break;case "ForInStatement":case "ForOfStatement":{let n=f(e,"left");d(o,t(f(e,"right")));let r=new Set;if(n.type==="VariableDeclaration")for(let s of g(n,"declarations"))y(f(s,"id"),r);else y(n,r);let i=ie(t(f(e,"body")));k(i,r),d(o,i);break}case "ForStatement":{let n=f(e,"init"),r=new Set;if(n){if(n.type==="VariableDeclaration")for(let i of g(n,"declarations"))y(f(i,"id"),r);d(o,t(n));}for(let i of ["test","update","body"]){let s=ie(t(f(e,i)));k(s,r),d(o,s);}break}default:forEachChild(e,n=>d(o,t(n)));break}return o}function ce(e,t={}){let o=new Map,n=new Set(t.globals??[]),r=i=>{if(!i)return fe;let s=J(i,r);return k(s,n),o.set(i,s),s};return r(e),o}function A(e,t,o){if(e.type==="AssignmentPattern")d(t,o(f(e,"right"))),A(f(e,"left"),t,o);else if(e.type==="ArrayPattern")for(let n of g(e,"elements"))n&&A(n,t,o);else if(e.type==="ObjectPattern")for(let n of g(e,"properties")){w(n).computed&&d(t,o(f(n,"key")));let r=f(n,"value")??f(n,"argument");r&&A(r,t,o);}}function Fe(e,t){return ce(e,t).get(e)??new Set}function q(e,t){if(e){if(e.type==="MemberExpression"){q(f(e,"object"),t);return}y(e,t);}}function de(e){let t=new Map,o=n=>{if(!n)return fe;let r=new Set;return n.type==="AssignmentExpression"?q(f(n,"left"),r):n.type==="UpdateExpression"&&q(f(n,"argument"),r),forEachChild(n,i=>d(r,o(i))),t.set(n,r),r};return o(e),t}function Ae(e){return de(e).get(e)??new Set}function Ie(e,t){return {root:e,diagnostics:t.diagnostics,typeOf:o=>t.overlay.get(o)?.type,scopeOf:o=>t.overlay.get(o)?.scope}}function Ue(e,t){let o=new Map,n={tree:e,read:s=>o.get(s.name)},r=t.filter(s=>!!s.visitor),i=t.filter(s=>!s.visitor&&s.run);if(r.length){let s=a=>{for(let c of r)c.visitor.enter?.(a,n);forEachChild(a,s);for(let c=r.length-1;c>=0;c--)r[c].visitor.exit?.(a,n);};s(e.root);for(let a of r)o.set(a.name,a.visitor.result());}for(let s of i)o.set(s.name,s.run(n));return o}var le=new Set,je=(e,t)=>({name:"effects",run:o=>H(o.tree.root,{env:e,rules:t})}),We=(e,t)=>({name:"nodeEffects",run:o=>K(o.tree.root,{env:e,rules:t})}),$e=e=>({name:"deps",visitor:(()=>{let t=new Set(e?.globals??[]),o=new Map;return {exit(n){let r=J(n,i=>i?o.get(i)??le:le);for(let i of t)r.delete(i);o.set(n,r);},result:()=>o}})()}),_e=e=>({name:"policies",visitor:se(e)});export{M as DEFAULT_RULES,T as PURE,E as PURE_ROW,j as PURE_SCHEME,Ue as analyze,ke as checkEffectPolicy,Y as checkEffects,Ce as checkPolicies,ce as deps,$e as depsOverlay,I as effect,te as effectCeiling,Ee as effectEnv,K as effectsByNode,je as effectsOverlay,H as effectsOverlayOf,W as excess,ge as forwardEffect,Fe as freeVars,N as groundRow,G as inferEffects,V as instantiateScheme,pe as join,R as joinRows,We as nodeEffectsOverlay,_e as policiesOverlay,U as rowOf,C as rowOfVar,X as substituteRow,Ie as typedTreeOf,ye as within,Ae as writeTargets,de as writes};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tslite/analysis",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "TSLite analysis — behavior/effect overlays over the AST (effect inference + propagation + contracts)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@tslite/core": "0.
|
|
43
|
-
"@tslite/checker": "0.
|
|
42
|
+
"@tslite/core": "0.6.0",
|
|
43
|
+
"@tslite/checker": "0.7.0",
|
|
44
44
|
"@tslite/capability": "0.2.0"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|