@xaendar/compiler 0.7.41 → 0.8.0

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.
Files changed (2) hide show
  1. package/dist/compiler.js +1 -1
  2. package/package.json +3 -3
package/dist/compiler.js CHANGED
@@ -11,6 +11,6 @@ ${n}(${i.args?.join(", ")}) {`,...P(["const context = new Context(this, parentCo
11
11
  Found character ${e.currentChar.value} at ${e.formattedPosition}`)}let s=i?39:34;for(;r;)e.peek()===s?(e.advance(),r=!1,n={state:"text",tokens:[{type:22,parts:[o]}]}):(e.advance(),o=`${o}${e.currentChar.value}`);return n}function Ke(e,t){let r=!0,o="",n={state:"import-path",tokens:[]};if(e.skipSpaces(),e.advance(),e.currentChar.code!==123)throw new Error(`Expected { after @import at ${e.formattedPosition}`);for(;r;)switch(e.peek()){case 32:e.skipSpaces(),o&&e.peek()!==44&&e.peek()!==125&&(o=`${o} `);break;case 44:He(n,e,o),o="";break;case 125:He(n,e,o),r=!1;break;default:e.advance(),o=`${o}${e.currentChar.value}`}return n}function He(e,t,r){t.advance(),e.tokens.push({type:21,parts:[r]})}function We(e,t){let r=!0,o="",n=1,i;for(;r;)switch(e.peek()){case 123:n++,o=fe(e,o);break;case 125:if(n--,n===0){e.advance(),o=o.trimEnd();let s=t.history.pop(),a;switch(s){case"attribute":if(e.peek()!==34)throw new Error(`Interpolation must end with double quotes '"' Found ${String.fromCharCode(e.peek())} at ${e.formattedPosition}`);e.advance(),a="tag-body";break;case"text":a="text"}i={state:a,tokens:[{type:10,parts:[o]}],popState:!0},r=!1}else o=fe(e,o);break;default:o=fe(e,o)}return i}function fe(e,t){return e.advance(1),`${t}${e.currentChar.value}`}function Xe(e,t){let r=!0,o="`",n;for(e.advance();r;)switch(e.peek()){case 96:if(o=qe(e,o),e.peek()===125){e.advance();let i=t.history.pop(),s;switch(i){case"attribute":if(e.peek()!==34)throw new Error(`Attribute interpolation expression must end with double quotes at ${e.formattedPosition}`);e.advance(),s="tag-body";break;case"text":s="text"}n={state:s,tokens:[{type:9,parts:[o]}],popState:!0},r=!1}else o=`${o}${e.currentChar.value}`;break;default:o=qe(e,o)}return n}function qe(e,t){return e.advance(),`${t}${e.currentChar.value}`}function ze(e,t){return e.advance(),e.skipSpaces(),e.peek()===96?{state:"interpolation-literal"}:{state:"interpolation-expression"}}function Qe(e,t){let r=!0,o;for(;r;)switch(e.peek()){case 64:o={state:"event"},r=!1;break;case 32:e.skipSpaces();break;case 62:case 47:o={state:"tag-open-end"},r=!1;break;default:o={state:"attribute"},r=!1}return o}function je(e,t){let r=!0,o="",n;for(e.advance(2),e.skipSpaces();r;)switch(e.peek()){case 62:e.advance(),n={state:"text",tokens:[{type:4,parts:[o]}]},r=!1;break;case 32:throw new Error("Tag Close Name cannot contains spaces");default:e.advance(),o=`${o}${e.currentChar.value}`}return n}function Ye(e,t){let r;if(e.peek()===62)e.advance(),r={state:"text",tokens:[{type:3,parts:[]}]};else{e.advance();let o=e.peek();if(o===62)e.advance(),r={state:"text",tokens:[{type:2,parts:[]}]};else throw new Error(`Unexpected character ${o} for closing tag.
12
12
  Expected />
13
13
  Read of /${String.fromCharCode(o)} at ${e.formattedPosition}`)}return r}function Ze(e,t){let r=!0,o="",n;for(e.advance(),e.skipSpaces();r;)switch(e.peek()){case 32:case 47:case 62:n={state:"tag-body",tokens:[{type:1,parts:[o]}]},r=!1;break;default:e.advance(),o=`${o}${e.currentChar.value}`}return n}function Je(e){return/\S/.test(e)}function et(e,t){let r=!0,o="",n;for(;r;)switch(e.peek()){case 60:n={state:e.peek(1,{offset:1})===47?"tag-close":"tag-open-name"},r=!1;break;case 123:n={state:"interpolation",pushState:!0},r=!1;break;case 64:n={state:"flow-control"},r=!1;break;case 125:t.history[t.history.length-1]==="flow-control-block"?(e.advance(),n={state:"text",tokens:[{type:20}],popState:!0},r=!1):(e.advance(),o=`${o}${e.currentChar.value}`);break;case 10:case 13:e.advance();break;default:e.advance(),o=`${o}${e.currentChar.value}`}return n.tokens??=Je(o)?[{type:0,parts:[o]}]:void 0,n}var re=class{constructor(t){this.input=t}input;_currentChar={code:0,index:-1,value:""};get currentChar(){return this._currentChar}_peekCache=new Map;_position={row:0,column:0};get position(){return this._position}get formattedPosition(){return`[Ln ${this._position.row}, Col ${this._position.column}]`}advance(t=1){if(t<1)throw new Error(`${t} is not a valid value. Please enter a number equal or greater than 1`);let r=this._currentChar.index+t;r>=this.input.length?(this._currentChar.code=0,this._currentChar.index=-1,this._currentChar.value="",this.throwEOFError()):([10,13].includes(this._currentChar.code)?(this._position.row++,this._position.column=0):this._position.column++,this._currentChar.index=r,this._currentChar.value=this.input[r],this._currentChar.code=this.input.charCodeAt(r))}peekMatch(t,r){if(typeof t=="string"){let i=this.peek(t.length);for(let s=0;s<t.length;s++)if(i[s]!==t.charCodeAt(s))return!1;return!0}let o=this._currentChar.index+1,n=this.input.slice(o,o+r);return t.test(n)}peek(t,r){let o=this._peekCache,n=typeof t=="number"?t:1,i=(typeof t=="object"?t:r)?.offset??0;return n===1?this.peekOneChar(this._currentChar.index+i+1,o):this.peekMany(n+i,o)}skipSpaces(){for(;this.peek()===32||this.peek()===10||this.peek()===13;)this.advance()}peekMany(t,r){let o=new Array,n=this._currentChar.index+1;for(let i=n;i<n+t;i++)o.push(this.peekOneChar(i,r));return o}peekOneChar(t,r){if(r.has(t))return r.get(t);t>=this.input.length&&this.throwEOFError();let o=this.input.charCodeAt(t);return r.set(t,o),o}throwEOFError(){throw new Error("",{cause:0})}};var oe=class{constructor(t){this.input=t;this._cursor=new re(this.input)}input;_cursor;_state="text";_stack=new Mt;_tokens=new Array;_states={text:et,"tag-open-name":Ze,"tag-body":Qe,"tag-open-end":Ye,"tag-close":je,attribute:Pe,"attribute-value":be,event:De,parameter:Be,"flow-control":Ge,"flow-control-condition":Me,"case-flow-control-condition":$e,"flow-control-block":Ve,interpolation:ze,"interpolation-expression":We,"interpolation-literal":Xe,import:Ke,"import-path":Ue};tokenize(){let t=!1;for(;!t;)try{let r=this._states[this._state],{state:o,tokens:n,popState:i,pushState:s}=r(this._cursor,{history:this._stack.values,tokens:[...this._tokens]});n?.length&&this._tokens.push(...n),s&&this._stack.push(this._state),i&&this._stack.pop(),this._state=o}catch(r){if(r.cause===0)t=!0;else throw console.log(`Something went wrong while computing state ${this._state} at ${this._cursor.formattedPosition}`),r}return this._tokens}};var ne=class{constructor(t){this._tokens=t}_tokens;_currentToken={value:{type:23},index:-1};getCurrentToken(){return this._currentToken}advance(t=1){if(t<1)throw new Error(`${t} is not a valid value. Please enter a number equal or greater than 1`);let r=this._currentToken.index+t;r>=this._tokens.length?(this._currentToken.value={type:23},this._currentToken.index=-1):(this._currentToken.index=r,this._currentToken.value=this._tokens[r])}peek(t,r){let o=typeof t=="number"?t:1,n=(typeof t=="object"?t:r)?.offset??0;return o===1?this.peekOneToken(this._currentToken.index+n+1):this.peekMany(o+n)}peekMany(t){let r=new Array,o=this._currentToken.index+1;for(let n=o;n<o+t;n++)r.push(this.peekOneToken(n));return r}peekOneToken(t){return t<this._tokens.length?this._tokens[t]:{type:23}}};import{ScriptTarget as Bt,SyntaxKind as p,createSourceFile as Dt,forEachChild as Gt}from"typescript";function y(e){let t="const x = ",n=Dt("expression.ts",`${t}${e}`,Bt.ESNext,!0).statements[0].declarationList.declarations[0].initializer,i=new Array;if(tt(n,t.length,i),i.length)throw new Error(i.reduce((s,a)=>`${s}${a.message}
14
- `,""));return{node:n}}function tt(e,t,r){if(!Vt(e))throw new Error(Ut(e));if(Gt(e,o=>tt(o,t,r)),r.length)throw new Error(r[0].message)}function Vt(e){switch(e.kind){case p.StringLiteral:case p.NumericLiteral:case p.BigIntLiteral:case p.TrueKeyword:case p.FalseKeyword:case p.NullKeyword:case p.UndefinedKeyword:case p.Identifier:case p.PropertyAccessExpression:case p.ElementAccessExpression:case p.CallExpression:case p.BinaryExpression:case p.EqualsEqualsToken:case p.EqualsEqualsEqualsToken:case p.ExclamationEqualsToken:case p.ExclamationEqualsEqualsToken:case p.LessThanToken:case p.LessThanEqualsToken:case p.GreaterThanToken:case p.GreaterThanEqualsToken:case p.PlusToken:case p.MinusToken:case p.AsteriskToken:case p.SlashToken:case p.PercentToken:case p.AsteriskAsteriskToken:case p.AmpersandAmpersandToken:case p.BarBarToken:case p.QuestionQuestionToken:case p.QuestionDotToken:case p.QuestionToken:case p.ColonToken:case p.AmpersandToken:case p.BarToken:case p.CaretToken:case p.LessThanLessThanToken:case p.GreaterThanGreaterThanToken:case p.GreaterThanGreaterThanGreaterThanToken:case p.InstanceOfKeyword:case p.InKeyword:case p.PrefixUnaryExpression:case p.PostfixUnaryExpression:case p.TypeOfExpression:case p.VoidExpression:case p.ConditionalExpression:case p.ParenthesizedExpression:case p.TemplateExpression:case p.NoSubstitutionTemplateLiteral:case p.TemplateHead:case p.TemplateMiddle:case p.TemplateTail:case p.TemplateSpan:case p.ArrayLiteralExpression:case p.ObjectLiteralExpression:case p.PropertyAssignment:case p.ShorthandPropertyAssignment:case p.SpreadAssignment:case p.SpreadElement:case p.TaggedTemplateExpression:case p.SyntaxList:return!0;default:return!1}}function Ut(e){switch(e.kind){case p.AwaitExpression:return"'await' is not allowed inside template expressions.";case p.YieldExpression:return"'yield' is not allowed inside template expressions.";case p.NewExpression:return"'new' is not allowed inside template expressions.";case p.ArrowFunction:case p.FunctionExpression:return"Function expressions are not allowed inside template expressions.";case p.BinaryExpression:return Ht(e.operatorToken.kind)?"Assignments are not allowed inside template expressions. Use @const to declare local template variables instead.":`'${p[e.kind]}' is not allowed inside template expressions.`;default:return`'${p[e.kind]}' is not allowed inside template expressions.`}}function Ht(e){return e>=p.FirstAssignment&&e<=p.LastAssignment}function K(e,t,r){return e.advance(),{type:2,expression:y(r.parts[0]).node}}function rt(e,t,r){e.advance();let o=r.parts[0],n=e.peek();if(n.type===5||n.type===4||n.type===7)return{name:o,value:"true"};if(n.type===10||n.type===9)return{name:o,value:K(e,t,n)};if(n.type!==6)throw new Error(`[Parser] Attribute value missing for ${o} in: ${o}`);return e.advance(),{name:o,value:n.parts[0]}}function ot(e,t,r){e.advance();let o=r.parts[0],[n,i]=o.split("=");if(!n||!i)throw new Error(`[Parser] Invalid event format: ${o}`);let s=new Array;for(;e.peek().type===8;)e.advance(),s.push(y(e.getCurrentToken().value.parts[0]).node);return{name:n,handler:i.replace(/^[""]|[""]$/g,""),parameters:s}}function nt(e,t,r){e.advance();let o=r.parts[0],n=new Array,i=new Array,s=!0;for(;s;){let c=e.peek();switch(c.type){case 5:n.push(rt(e,t,c));break;case 7:i.push(ot(e,t,c));break;default:s=!1}}if(e.peek().type===3&&e.advance(),e.peek().type===2)return e.advance(),{type:0,tagName:o,attributes:n,events:i,children:[]};let a=new Array;for(;!Kt(e,o);){let c=t();c&&a.push(c)}return e.advance(),{type:0,tagName:o,attributes:n,events:i,children:a}}function Kt(e,t){let r=e.peek();return r.type===4&&r.parts[0]===t}import{createSourceFile as Wt,isExpressionStatement as qt,isIdentifier as Xt,ScriptTarget as zt}from"typescript";function w(e,t){let r=new Array;for(;e.peek().type!==20;){let o=t();o&&r.push(o)}return e.advance(),r}function it(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after FOR, got ${u[o.type]}`);let n=Qt(o.parts[0],0);e.advance(2);let i=w(e,t);return{type:6,...n,children:i}}function Qt(e,t){let r=Yt(e);if(r.length<2)throw new Error('[Parser] @for requires at least "item of iterable; track expr".');let o=r[0].trim(),n=o.indexOf(" of ");if(n===-1)throw new Error('[Parser] @for expression must be in the form "item of iterable".');let i=o.slice(0,n).trim(),s=o.slice(n+4).trim();if(!st(i))throw new Error(`[Parser] '${i}' is not a valid item alias.`);let a=y(s),c=r[1].trim();if(!c.startsWith("track "))throw new Error('[Parser] Second section of @for must start with "track".');let m=c.slice(6).trim(),l=y(m),h=new Map;if(r.length>=3&&r[2]!==void 0){let k=r[2].trim(),I=t+e.indexOf(r[2]);jt(k,I,h)}return{itemAlias:i,iterableExpression:a.node,iterableSource:s,trackExpression:l.node,trackSource:m,implicitAliases:h}}function jt(e,t,r){let o=e.split(","),n=0,i=new Set(["$index","$last","$first","$even","$odd"]);for(let s of o){let a=s.trim(),c=a.indexOf("=");if(c===-1)throw new Error(`[Parser] Invalid alias declaration '${a}'. Expected '$implicit = alias'.`);n+=s.length+1;let m=a.slice(0,c).trim(),l=a.slice(c+1).trim();if(!(k=>i.has(k))(l))throw new Error(`[Parser] '${l}' is not a known implicit variable. Known variables: ${[...i].join(", ")}.`);if(n+=s.length+1,!st(m))throw new Error(`[Parser] '${m}' is not a valid alias identifier.`);if(n+=s.length+1,r.has(l))throw new Error(`[Parser] '${l}' is already aliased in this @for expression.`);r.set(l,m),n+=s.length+1}}function Yt(e){let t=new Array,r="",o=0,n;for(let i=0;i<e.length;i++){let s=e[i];if(!(!r&&s===" ")){if(n){r+=s,s===n&&e[i-1]!=="\\"&&(n=null);continue}if(s==='"'||s==="'"||s==="`"){n=s,r+=s;continue}if(s==="("||s==="["||s==="{"){o++,r+=s;continue}if(s===")"||s==="]"||s==="}"){o--,r+=s;continue}if(s===";"&&o===0){t.push(r),r="";continue}r+=s}}return r.trim().length&&t.push(r),t}function st(e){if(!e.length)return!1;let r=Wt("__id.ts",e,zt.ESNext,!1).statements[0];return!!r&&qt(r)&&Xt(r.expression)&&r.expression.text===e}function at(e,t,r){return pt(e,t,r)}function Zt(e,t,r){switch(r.type){case 14:return pt(e,t,r);case 13:e.advance(2);let o=w(e,t);return{type:4,children:o}}}function pt(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after ${u[r.type]}, got ${u[o.type]}`);e.advance(2);let n=o.parts[0],i=y(n),s=w(e,t);return{type:r.type===11?3:5,condition:n,conditionNode:i.node,children:s,alternate:Zt(e,t,e.peek())}}function ct(e,t,r){let o=new Array;for(;e.peek().type===21;){e.advance();let n=e.getCurrentToken().value.parts[0],i=Jt(n);o.push(i)}return e.advance(),{type:9,specifiers:o,path:e.getCurrentToken().value.parts[0]}}function Jt(e){let t=e.trim(),r=t.match(/^\*\s+as\s+([A-Za-z_$][\w$]*)$/);if(r)return{imported:"*",local:r[1]};let o=t.match(/^default\s+as\s+([A-Za-z_$][\w$]*)$/);if(o)return{imported:"default",local:o[1]};let n=t.match(/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);if(n)return{imported:n[1],local:n[2]??n[1]};throw new Error(`[Parser] Invalid import specifier "${e}".`)}function mt(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after SWITCH, got ${u[o.type]}`);let n=y(o.parts[0]).node;e.advance(2);let i=new Array;for(;e.peek().type!==20;)switch(e.peek().type){case 16:let a=new Array;do{e.advance();let c=e.peek();if(c.type!==18)throw new Error("[Parser] Expected CONDITION after CASE");a.push(c.parts[0]),e.advance()}while(e.peek().type!==19);e.advance(),i.push({type:8,condition:a,children:w(e,t)});break;case 17:e.advance(2),i.push({type:8,condition:null,children:w(e,t)});break}return e.advance(),{type:7,expression:n,children:i}}function lt(e,t,r){return e.advance(),{type:1,value:r.parts[0]}}var ie=class{_cursor;_states={0:lt,10:K,9:K,1:nt,11:at,12:it,15:mt,21:ct};constructor(t){this._cursor=new ne(t)}parse(){let t=new Array;for(;this._cursor.peek().type!==23;){let r=this.parseNode();r&&t.push(r)}return t}parseNode(){let t=this._cursor.peek();if(t.type===23)return;let r=this._states[t.type];if(!r)throw new Error(`[Parser] No transition function for token type ${u[t.type]}`);return r(this._cursor,this.parseNode.bind(this),t)}};import{indent as Ar}from"@xaendar/common";var D=class extends x{_imports=new Array;addImport(t){this._imports.push(t)}getImportBySelector(t){return this._imports.find(r=>r.type==="component"&&r.selectors.includes(t))}};import{indent as Te}from"@xaendar/common";function ft(e,t,r){let o=new Array;if(nr(e.tagName)){let n=r.getImportBySelector(e.tagName);if(!n)throw new Error(`[Type Checker] ${e.tagName} selector is not associated to any WebComponent imported in the template`);o.push(...er(e,n,r))}else o.push(...or(e,r));return e.children.forEach(n=>o.push(...t(n,r))),o}function er(e,t,r){let o=new Array,n=new Set(t.properties.filter(i=>i.required).map(i=>i.alias??i.name));if(e.attributes.forEach(({name:i,value:s})=>{let a=tr(t,i);if(a){n.delete(a.alias??a.name);let c=typeof s=="object"?d(s.expression,r,{resolver:"root"}):"let x!: string";o.push("{",Te(`(${c}) satisfies ${a.type};`),"}")}}),n.size)throw new Error(`[Type Checker] ${e.tagName} is missing the following required properties: ${Array.from(n.values()).join(`
14
+ `,""));return{node:n}}function tt(e,t,r){if(!Vt(e))throw new Error(Ut(e));if(Gt(e,o=>tt(o,t,r)),r.length)throw new Error(r[0].message)}function Vt(e){switch(e.kind){case p.StringLiteral:case p.NumericLiteral:case p.BigIntLiteral:case p.TrueKeyword:case p.FalseKeyword:case p.NullKeyword:case p.UndefinedKeyword:case p.Identifier:case p.PropertyAccessExpression:case p.ElementAccessExpression:case p.CallExpression:case p.BinaryExpression:case p.EqualsEqualsToken:case p.EqualsEqualsEqualsToken:case p.ExclamationEqualsToken:case p.ExclamationEqualsEqualsToken:case p.LessThanToken:case p.LessThanEqualsToken:case p.GreaterThanToken:case p.GreaterThanEqualsToken:case p.PlusToken:case p.MinusToken:case p.AsteriskToken:case p.SlashToken:case p.PercentToken:case p.AsteriskAsteriskToken:case p.AmpersandAmpersandToken:case p.BarBarToken:case p.QuestionQuestionToken:case p.QuestionDotToken:case p.QuestionToken:case p.ColonToken:case p.AmpersandToken:case p.BarToken:case p.CaretToken:case p.LessThanLessThanToken:case p.GreaterThanGreaterThanToken:case p.GreaterThanGreaterThanGreaterThanToken:case p.InstanceOfKeyword:case p.InKeyword:case p.PrefixUnaryExpression:case p.PostfixUnaryExpression:case p.TypeOfExpression:case p.VoidExpression:case p.ConditionalExpression:case p.ParenthesizedExpression:case p.TemplateExpression:case p.NoSubstitutionTemplateLiteral:case p.TemplateHead:case p.TemplateMiddle:case p.TemplateTail:case p.TemplateSpan:case p.ArrayLiteralExpression:case p.ObjectLiteralExpression:case p.PropertyAssignment:case p.ShorthandPropertyAssignment:case p.SpreadAssignment:case p.SpreadElement:case p.TaggedTemplateExpression:case p.SyntaxList:return!0;default:return!1}}function Ut(e){switch(e.kind){case p.AwaitExpression:return"'await' is not allowed inside template expressions.";case p.YieldExpression:return"'yield' is not allowed inside template expressions.";case p.NewExpression:return"'new' is not allowed inside template expressions.";case p.ArrowFunction:case p.FunctionExpression:return"Function expressions are not allowed inside template expressions.";case p.BinaryExpression:return Ht(e.operatorToken.kind)?"Assignments are not allowed inside template expressions. Use @const to declare local template variables instead.":`'${p[e.kind]}' is not allowed inside template expressions.`;default:return`'${p[e.kind]}' is not allowed inside template expressions.`}}function Ht(e){return e>=p.FirstAssignment&&e<=p.LastAssignment}function K(e,t,r){return e.advance(),{type:2,expression:y(r.parts[0]).node}}function rt(e,t,r){e.advance();let o=r.parts[0],n=e.peek();if(n.type===5||n.type===4||n.type===7)return{name:o,value:"true"};if(n.type===10||n.type===9)return{name:o,value:K(e,t,n)};if(n.type!==6)throw new Error(`[Parser] Attribute value missing for ${o} in: ${o}`);return e.advance(),{name:o,value:n.parts[0]}}function ot(e,t,r){e.advance();let o=r.parts[0],[n,i]=o.split("=");if(!n||!i)throw new Error(`[Parser] Invalid event format: ${o}`);let s=new Array;for(;e.peek().type===8;)e.advance(),s.push(y(e.getCurrentToken().value.parts[0]).node);return{name:n,handler:i.replace(/^[""]|[""]$/g,""),parameters:s}}function nt(e,t,r){e.advance();let o=r.parts[0],n=new Array,i=new Array,s=!0;for(;s;){let c=e.peek();switch(c.type){case 5:n.push(rt(e,t,c));break;case 7:i.push(ot(e,t,c));break;default:s=!1}}if(e.peek().type===3&&e.advance(),e.peek().type===2)return e.advance(),{type:0,tagName:o,attributes:n,events:i,children:[]};let a=new Array;for(;!Kt(e,o);){let c=t();c&&a.push(c)}return e.advance(),{type:0,tagName:o,attributes:n,events:i,children:a}}function Kt(e,t){let r=e.peek();return r.type===4&&r.parts[0]===t}import{createSourceFile as Wt,isExpressionStatement as qt,isIdentifier as Xt,ScriptTarget as zt}from"typescript";function w(e,t){let r=new Array;for(;e.peek().type!==20;){let o=t();o&&r.push(o)}return e.advance(),r}function it(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after FOR, got ${u[o.type]}`);let n=Qt(o.parts[0],0);e.advance(2);let i=w(e,t);return{type:6,...n,children:i}}function Qt(e,t){let r=Yt(e);if(r.length<2)throw new Error('[Parser] @for requires at least "item of iterable; track expr".');let o=r[0].trim(),n=o.indexOf(" of ");if(n===-1)throw new Error('[Parser] @for expression must be in the form "item of iterable".');let i=o.slice(0,n).trim(),s=o.slice(n+4).trim();if(!st(i))throw new Error(`[Parser] '${i}' is not a valid item alias.`);let a=y(s),c=r[1].trim();if(!c.startsWith("track "))throw new Error('[Parser] Second section of @for must start with "track".');let m=c.slice(6).trim(),l=y(m),h=new Map;if(r.length>=3&&r[2]!==void 0){let k=r[2].trim(),I=t+e.indexOf(r[2]);jt(k,I,h)}return{itemAlias:i,iterableExpression:a.node,iterableSource:s,trackExpression:l.node,trackSource:m,implicitAliases:h}}function jt(e,t,r){let o=e.split(","),n=0,i=new Set(["$index","$last","$first","$even","$odd"]);for(let s of o){let a=s.trim(),c=a.indexOf("=");if(c===-1)throw new Error(`[Parser] Invalid alias declaration '${a}'. Expected '$implicit = alias'.`);n+=s.length+1;let m=a.slice(0,c).trim(),l=a.slice(c+1).trim();if(!(k=>i.has(k))(l))throw new Error(`[Parser] '${l}' is not a known implicit variable. Known variables: ${[...i].join(", ")}.`);if(n+=s.length+1,!st(m))throw new Error(`[Parser] '${m}' is not a valid alias identifier.`);if(n+=s.length+1,r.has(l))throw new Error(`[Parser] '${l}' is already aliased in this @for expression.`);r.set(l,m),n+=s.length+1}}function Yt(e){let t=new Array,r="",o=0,n;for(let i=0;i<e.length;i++){let s=e[i];if(!(!r&&s===" ")){if(n){r+=s,s===n&&e[i-1]!=="\\"&&(n=null);continue}if(s==='"'||s==="'"||s==="`"){n=s,r+=s;continue}if(s==="("||s==="["||s==="{"){o++,r+=s;continue}if(s===")"||s==="]"||s==="}"){o--,r+=s;continue}if(s===";"&&o===0){t.push(r),r="";continue}r+=s}}return r.trim().length&&t.push(r),t}function st(e){if(!e.length)return!1;let r=Wt("__id.ts",e,zt.ESNext,!1).statements[0];return!!r&&qt(r)&&Xt(r.expression)&&r.expression.text===e}function at(e,t,r){return pt(e,t,r)}function Zt(e,t,r){switch(r.type){case 14:return pt(e,t,r);case 13:e.advance(2);let o=w(e,t);return{type:4,children:o}}}function pt(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after ${u[r.type]}, got ${u[o.type]}`);e.advance(2);let n=o.parts[0],i=y(n),s=w(e,t);return{type:r.type===11?3:5,condition:n,conditionNode:i.node,children:s,alternate:Zt(e,t,e.peek())}}function ct(e,t,r){let o=new Array;for(;e.peek().type===21;){e.advance();let n=e.getCurrentToken().value.parts[0],i=Jt(n);o.push(i)}return e.advance(),{type:9,specifiers:o,path:e.getCurrentToken().value.parts[0]}}function Jt(e){let t=e.trim(),r=t.match(/^\*\s+as\s+([A-Za-z_$][\w$]*)$/);if(r)return{imported:"*",local:r[1]};let o=t.match(/^default\s+as\s+([A-Za-z_$][\w$]*)$/);if(o)return{imported:"default",local:o[1]};let n=t.match(/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);if(n)return{imported:n[1],local:n[2]??n[1]};throw new Error(`[Parser] Invalid import specifier "${e}".`)}function mt(e,t,r){e.advance();let o=e.peek();if(o.type!==18)throw new Error(`[Parser] Expected CONDITION after SWITCH, got ${u[o.type]}`);let n=y(o.parts[0]).node;e.advance(2);let i=new Array;for(;e.peek().type!==20;)switch(e.peek().type){case 16:let a=new Array;do{e.advance();let c=e.peek();if(c.type!==18)throw new Error("[Parser] Expected CONDITION after CASE");a.push(c.parts[0]),e.advance()}while(e.peek().type!==19);e.advance(),i.push({type:8,condition:a,children:w(e,t)});break;case 17:e.advance(2),i.push({type:8,condition:null,children:w(e,t)});break}return e.advance(),{type:7,expression:n,children:i}}function lt(e,t,r){return e.advance(),{type:1,value:r.parts[0]}}var ie=class{_cursor;_states={0:lt,10:K,9:K,1:nt,11:at,12:it,15:mt,21:ct};constructor(t){this._cursor=new ne(t)}parse(){let t=new Array;for(;this._cursor.peek().type!==23;){let r=this.parseNode();r&&t.push(r)}return t}parseNode(){let t=this._cursor.peek();if(t.type===23)return;let r=this._states[t.type];if(!r)throw new Error(`[Parser] No transition function for token type ${u[t.type]}`);return r(this._cursor,this.parseNode.bind(this),t)}};import{indent as Ar}from"@xaendar/common";var D=class extends x{_imports=new Array;addImport(t){this._imports.push(t)}getImportBySelector(t){return this._imports.find(r=>r.type==="component"&&r.selectors.includes(t))}};import{indent as Te}from"@xaendar/common";function ft(e,t,r){let o=new Array;if(nr(e.tagName)){let n=r.getImportBySelector(e.tagName);if(!n)throw new Error(`[Type Checker] ${e.tagName} selector is not associated to any WebComponent imported in the template`);o.push(...er(e,n,r))}else o.push(...or(e,r));return e.children.forEach(n=>o.push(...t(n,r))),o}function er(e,t,r){let o=new Array,n=new Set(t.properties.filter(i=>i.required).map(i=>i.alias??i.name));if(e.attributes.forEach(({name:i,value:s})=>{let a=tr(t,i);a&&(n.delete(a.alias??a.name),o.push("{",...Te(typeof s=="object"?[`(${d(s.expression,r,{resolver:"root"})}) satisfies ${a.type};`]:["let x!: string",`x satisfies ${a.type};`]),"}"))}),n.size)throw new Error(`[Type Checker] ${e.tagName} is missing the following required properties: ${Array.from(n.values()).join(`
15
15
  `)}`);return e.events.forEach(({name:i,handler:s,parameters:a})=>{let c=rr(t,i);if(!c)throw new Error(`[Type Checker] Unknown event "${i}" on <${e.tagName}> (${t.className} has no @Event with this name).`);let m=new x([],r);m.addUnresolvableIdentifier("$event");let l=a.map(h=>d(h,m,{resolver:"root"})).join(", ");o.push("{"),c.type!=="void"&&o.push(Te(`let $event!: CustomEvent<${c.type}>;`)),o.push(Te(`root.${s}(${l});`),"}")}),o}function tr(e,t){return e.properties.find(r=>(r.alias??r.name)===t)}function rr(e,t){return e.events.find(r=>r.name===t)}function or(e,t){let r=new Array;return e.attributes.forEach(({value:o})=>{typeof o!="string"&&r.push(`${d(o.expression,t,{resolver:"root"})};`)}),e.events.forEach(({handler:o,parameters:n})=>{let i=new x([],t);i.addUnresolvableIdentifier("$event");let s=n.map(a=>d(a,i,{resolver:"root"})).join(", ");r.push(`root.${o}(${s});`)}),r}function nr(e){return/^[a-z][a-z0-9._\-]*-[a-z0-9._\-]*$/.test(e)}import{indent as ir}from"@xaendar/common";function ut(e,t,r){let o=new D([],r),n=W(e,"$index"),i=W(e,"$first"),s=W(e,"$last"),a=W(e,"$even"),c=W(e,"$odd");[n,i,s,a,c,e.itemAlias].forEach(l=>o.addUnresolvableIdentifier(l));let m=new Array;return m.push(`for (const ${e.itemAlias} of root.${e.iterableSource}) {`),m.push(...ir([`let ${n}!: number;`,`let ${i}!: boolean;`,`let ${s}!: boolean;`,`let ${a}!: boolean;`,`let ${c}!: boolean;`,`${d(e.trackExpression,r,{skipResolution:!0})};`,...e.children.flatMap(l=>t(l,o))])),m.push("}"),m}function W(e,t){return e.implicitAliases.get(t)??t}import{indent as xe}from"@xaendar/common";function dt(e,t,r){let o=new Array,n=d(e.conditionNode,r,{resolver:"root"});o.push(`if (${n}) {`),o.push(...xe(e.children.flatMap(s=>t(s,r)))),o.push("}");let i=e.alternate;for(;i?.type===5;){let s=d(i.conditionNode,r,{resolver:"root"});o.push(`else if (${s}) {`),o.push(...xe(i.children.flatMap(a=>t(a,r)))),o.push("}"),i=i.alternate}return i&&(o.push("else {"),o.push(...xe(i.children.flatMap(s=>t(s,r)))),o.push("}")),o}function xt(e,t,r){let o=e.path,n=Tt(o),i=new Array;for(let s of e.specifiers){let{imported:a,local:c}=s;switch(a){case"*":i.push(`let ${c}!: typeof import('${n}');`);break;case"default":i.push(`let ${c}!: typeof import('${n}')['default'];`);break;default:let m=Tt(a);i.push(`let ${c}!: typeof import('${n}')['${m}'];`);break}}return i}function Tt(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}import{indent as ht}from"@xaendar/common";function Et(e,t,r){let n=[`switch (${d(e.expression,r,{resolver:"root"})}) {`];return e.children.forEach(i=>{i.condition?.length?i.condition.forEach(s=>n.push(` case ${s}:`)):n.push(" default:"),n.push(...ht(ht([...i.children.flatMap(s=>t(s,r)),"break;"])))}),n.push("}"),n}function he(e,t,r){return e.type===2?[`${d(e.expression,r,{resolver:"root"})};`]:[]}import{existsSync as Ee}from"fs";import{readFile as sr}from"fs/promises";import{resolve as ar}from"path";import{createSourceFile as pr,forEachChild as cr,getNameOfDeclaration as Ct,isArrayLiteralExpression as mr,isCallExpression as q,isClassDeclaration as lr,isDecorator as fr,isIdentifier as F,isObjectLiteralExpression as kt,isPropertyAccessExpression as ur,isPropertyAssignment as Nt,isPropertyDeclaration as ke,isStringLiteral as Ce,isTypeReferenceNode as dr,ScriptTarget as Tr,SyntaxKind as It}from"typescript";async function gt(e,t,r=process.cwd()){try{let o=xr(e,r);if(!o)return;let n=await sr(o,"utf8"),i=pr(o,n,Tr.Latest,!0),s;return cr(i,a=>{if(!s&&lr(a)){let c=a.name?.text;if(c!==t)return;let m=a.modifiers??[],l=Array.from(m).find(g=>hr(g));if(!l)return;let h=kr(l);if(!h?.length)return;let k=new Array,I=new Array;a.members.forEach(g=>{if(!ke(g))return;let O=g.modifiers??[],X=!1,z=Array.from(O).find(A=>{let S=Er(A);return X=!!S.required,S.decorator});if(z){let A=Ct(g),S=A&&F(A)?A.text:void 0;if(S){let G=Ir(S,z,X);G&&k.push(G)}return}let Ne=Array.from(O).find(A=>Cr(A));if(Ne){let A=Ct(g),S=A&&F(A)?A.text:void 0;if(S){let G=gr(S,Ne);G&&I.push(G)}}}),s={type:"component",className:c,selectors:h,properties:k,events:I}}}),s}catch(o){console.error(`Failed to extract component metadata from ${e}:`,o);return}}function xr(e,t){if(e.startsWith(".")){let r=ar(t,e);if(Ee(`${r}.ts`))return r+".ts";if(Ee(`${r}/index.ts`))return`${r}/index.ts`;if(Ee(r))return r}}function hr(e){if(e.kind!==It.Decorator)return!1;let t=q(e.expression)?e.expression.expression:e.expression;return F(t)&&t.text==="WebComponent"}function Er(e){if(!fr(e))return{decorator:!1};let t=e.expression;if(!q(t))return{decorator:!1};let r=t.expression;return F(r)&&r.text==="Property"?{decorator:!0}:ur(r)&&F(r.expression)&&r.expression.text==="Property"&&r.name.text==="required"?{decorator:!0,required:!0}:{decorator:!1}}function Cr(e){if(e.kind!==It.Decorator)return!1;let t=q(e.expression)?e.expression.expression:e.expression;return F(t)&&t.text==="Event"}function kr(e){try{let t=e.expression;if(!q(t))return[];let r=t.arguments;if(r.length===0)return[];let o=r[0];if(!o||!kt(o))return[];let n=Array.from(o.properties).find(i=>Nt(i)&&F(i.name)&&i.name.text==="selector");return Nr(n.initializer)}catch{return[]}}function Nr(e){return Ce(e)?[e.text]:mr(e)?e.elements?.filter(t=>Ce(t)).map(t=>t.text):[]}function Ir(e,t,r){let o=t.expression,n={name:e,required:r,type:ke(t.parent)?At(t.parent.type):"any"};if(q(o)){let i=o.arguments,a=(i.length?i.find(c=>kt(c)):void 0)?.properties?.find(c=>Nt(c)&&F(c.name)&&c.name.text==="alias");a&&Ce(a.initializer)&&(n.alias=a.initializer.text)}return n}function gr(e,t){let r={name:e,type:"void"};return ke(t.parent)&&(r.type=At(t.parent.type,!0)),r}function At(e,t=!1){let r=t?"void":"any";if(!e||!dr(e))return r;let o=e.typeArguments;return!o||o.length===0?r:o[0].getText()}var se=class{constructor(t){this._ast=t}_ast;_context=new D;_states={1:he,2:he,0:ft,3:dt,6:ut,7:Et,9:xt};async populateImportMetadata(t){let r=this._ast.filter(o=>o.type===9);await Promise.all(r.flatMap(o=>o.specifiers.filter(({imported:n})=>n!=="*").map(async({imported:n,local:i})=>{let s=n==="default"?i:n,a=await gt(o.path,s,t);a&&this._context.addImport(a)})))}async generate(t){await this.populateImportMetadata(t);let r=this._ast.flatMap(o=>this._processNode(o,this._context));return["function typeCheck() {",...Ar(r),"}"].join(`
16
16
  `)}_processNode=(t,r)=>{let o=this._states[t.type];if(!o)throw new Error(`[Type Checker] No transition function for token type ${E[t.type]}`);return o(t,this._processNode,r)}};async function ea(e,t,r){let o=new oe(e).tokenize(),n=new ie(o).parse();return{javascript:new Q(n).generate(r),typescript:await new se(n).generate(t)}}export{ea as compile};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.7.41",
3
+ "version": "0.8.0",
4
4
  "description": "A library for transpiling Xaendar Templates into JavaScript code",
5
5
  "author": "Kaitenjo",
6
6
  "license": "MIT",
@@ -13,8 +13,8 @@
13
13
  },
14
14
  "main": "./dist/compiler.js",
15
15
  "dependencies": {
16
- "@xaendar/common": "0.7.41",
17
- "@xaendar/types": "0.7.41",
16
+ "@xaendar/common": "0.8.0",
17
+ "@xaendar/types": "0.8.0",
18
18
  "typescript": "^6.0.3"
19
19
  }
20
20
  }