Skip to content

Commit

Permalink
feat: expose legacy parser API for testing with Marko 5
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Feb 25, 2022
1 parent 186e179 commit 879d5a8
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 223 deletions.
4 changes: 1 addition & 3 deletions src/core/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Parser {
public endingMixedModeAtEOL?: boolean; // Used as a flag to record that the next EOL to exit HTML mode and go back to concise
public textPos!: number; // Used to buffer text that is found within the body of a tag
public textParseMode!: "html" | "cdata" | "parsed-text";
public value: Events.Any | undefined;
public value: Events.Any;
public events!: Events.Any[];
public eventIndex!: number;
public done!: boolean;
Expand Down Expand Up @@ -80,7 +80,6 @@ export class Parser {
this.forward = true;
this.isConcise = true;
this.isInAttrGroup = false;
this.value = undefined;
this.activeTag = undefined;
this.activeAttr = undefined;
this.beginMixedMode = false;
Expand Down Expand Up @@ -543,7 +542,6 @@ export class Parser {
const { maxPos, data } = this;

if (pos >= maxPos) {
this.value = undefined;
this.done = true;
return this;
}
Expand Down
233 changes: 233 additions & 0 deletions src/core/TempParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import {
Events,
EventTypes,
ExpressionRange,
Parser,
Range,
} from "../internal";

export class TempParser {
constructor(private _handlers: any) {
this._handlers = _handlers;
}
parse(data: string, filename: string) {
const parser = new Parser(data, filename);
let isConcise = true;
let curTagName: Events.TagName | undefined = undefined;
let curShorthandId: Events.TagShorthandId | undefined;
let curShorthandClassNames: Events.TagShorthandClass[] | undefined;
let curTagVar: Events.TagVar | undefined;
let curTagArgs: Events.TagArgs | undefined;
let curTagParams: Events.TagParams | undefined;
let curAttr:
| {
name?: Events.AttrName;
value?: Range;
argument?: ExpressionRange;
method?: boolean;
spread?: boolean;
bound?: boolean;
}
| undefined;
let curAttrs: Exclude<typeof curAttr, undefined>[] | undefined;

for (const data of parser) {
switch (data.type) {
case EventTypes.Error:
this._handlers.onError?.({
type: "error",
message: data.message,
code: data.code,
...rangeToPos(data),
});
break;
case EventTypes.Text:
this._handlers.onText?.({
type: "text",
...rangeToPos(data),
value: parser.read(data),
});
break;
case EventTypes.CDATA:
this._handlers.onCDATA?.({
type: "cdata",
...rangeToPos(data),
value: parser.read(data.value),
});
break;
case EventTypes.DocType:
this._handlers.onDocumentType?.({
type: "documentType",
...rangeToPos(data),
value: parser.read(data.value),
});
break;

case EventTypes.Declaration:
this._handlers.onDeclaration?.({
type: "declaration",
...rangeToPos(data),
value: parser.read(data.value),
});
break;
case EventTypes.Comment:
this._handlers.onComment?.({
type: "comment",
...rangeToPos(data),
value: parser.read(data),
});
break;
case EventTypes.Placeholder:
this._handlers.onPlaceholder?.({
type: "placeholder",
escape: data.escape,
...rangeToPos(data),
value: parser.read(data.value),
});
break;
case EventTypes.OpenTagStart: {
isConcise = data.start === data.end;
break;
}
case EventTypes.TagName: {
curTagName = data;
break;
}
case EventTypes.TagShorthandId:
curShorthandId = data;
break;
case EventTypes.TagShorthandClass:
curShorthandClassNames ??= [];
curShorthandClassNames.push(data);
break;
case EventTypes.TagVar:
curTagVar = data;
break;
case EventTypes.TagArgs:
curTagArgs = data;
break;
case EventTypes.TagParams:
curTagParams = data;
break;
case EventTypes.AttrName:
curAttrs ??= [];
curAttrs.push((curAttr = { name: data }));
break;
case EventTypes.AttrArgs:
curAttr!.argument = data;
break;
case EventTypes.AttrValue:
curAttr!.value = data.value;
curAttr!.bound = data.bound;
break;
case EventTypes.AttrMethod:
curAttr!.method = true;
curAttr!.argument = data.params;
curAttr!.value = data.body.value;
break;
case EventTypes.AttrSpread:
curAttr = undefined;
curAttrs ??= [];
curAttrs.push({
value: data.value,
spread: true,
});
break;
case EventTypes.OpenTagEnd:
this._handlers.onOpenTag?.({
type: "openTag",
tagName: parser.read(curTagName!),
tagNameExpression:
curTagName!.expressions.length === 1 &&
curTagName!.quasis[0].start === curTagName!.quasis[0].end &&
curTagName!.quasis[1].start === curTagName!.quasis[1].end &&
parser.read(curTagName!.expressions[0].value),
var: curTagVar && {
...rangeToPos(curTagVar),
value: parser.read(curTagVar.value),
},
argument: curTagArgs && {
...rangeToPos(curTagArgs),
value: parser.read(curTagArgs.value),
},
params: curTagParams && {
...rangeToPos(curTagParams),
value: parser.read(curTagParams.value),
},
pos: curTagName!.start - (isConcise ? 0 : 1),
endPos: data.end,
tagNameEndPos: curTagName!.end,
selfClosed: data.selfClosed,
openTagOnly: data.openTagOnly,
attributes: (curAttrs || []).map((attr) => ({
default: attr.name?.default,
name: attr.name && parser.read(attr.name),
pos: attr.name?.start ?? attr.value?.start,
endPos: attr.value?.end ?? attr.name?.end,
value: attr.value && parser.read(attr.value),
bound: attr.bound,
method: attr.method,
spread: attr.spread,
argument: attr.argument && {
...attr.argument,
value: parser.read(attr.argument.value),
},
})),
concise: isConcise,
shorthandId: curShorthandId && {
...rangeToPos(curShorthandId),
value: parser.read(curShorthandId).slice(1),
},
shorthandClassNames:
curShorthandClassNames &&
curShorthandClassNames.map((shorthandClassName) => ({
...rangeToPos(shorthandClassName),
value: parser.read(shorthandClassName).slice(1),
})),
});

curTagName = undefined;
curShorthandId = undefined;
curShorthandClassNames = undefined;
curTagVar = undefined;
curTagArgs = undefined;
curTagParams = undefined;
curAttrs = undefined;
curAttr = undefined;
break;
case EventTypes.CloseTag:
this._handlers.onCloseTag?.(
data.value
? {
type: "closeTag",
...rangeToPos(data),
tagName: parser.read(data.value),
}
: {
type: "closeTag",
pos: null,
endPos: null,
tagName: "",
}
);
break;
case EventTypes.Scriptlet:
this._handlers.onScriptlet?.({
type: "scriptlet",
block: data.block,
line: !data.block,
...rangeToPos(data),
value: parser.read(data.value),
});
break;
}
}
}
}

function rangeToPos(range: Range) {
return {
pos: range.start,
endPos: range.end,
};
}
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Parser } from "./internal";
import { Parser, TempParser } from "./internal";

export function createParser(text: string, filename: string) {
return new Parser(text, filename);
}

export function createLegacyParser(listeners: any) {
return new TempParser(listeners);
}
1 change: 1 addition & 0 deletions src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export * from "./util/constants";
export * from "./util/util";
export * as operators from "./util/operators";
export * from "./core/Parser";
export * from "./core/TempParser";
export * as STATE from "./states";
Loading

0 comments on commit 879d5a8

Please sign in to comment.