import { HiddenCloseLocation } from './errors.js';
export declare enum TokenType {
TEXT = "TEXT",
EXPRESSION_START = "EXPRESSION_START",// <%=
EXPRESSION_UNESCAPED = "EXPRESSION_UNESCAPED",// <%!=
EXPRESSION_BR = "EXPRESSION_BR",// <%br= (escaped + newlines to
)
CODE_START = "CODE_START",// <%
TAG_END = "TAG_END",// %>
COMMENT = "COMMENT",// <%-- comment --%>
DEFINE_START = "DEFINE_START",// - value is the expression text
SELF_CLOSING = "SELF_CLOSING",// />
ATTR_NAME = "ATTR_NAME",// $property or regular
ATTR_VALUE = "ATTR_VALUE",
COLON = "COLON",
SEMICOLON = "SEMICOLON",
GT = "GT",// >
LT = "LT",// <
SLASH = "SLASH",// /
EQUALS = "EQUALS",// =
QUOTE = "QUOTE",// " or '
EOF = "EOF",
NEWLINE = "NEWLINE",
WHITESPACE = "WHITESPACE",
JAVASCRIPT = "JAVASCRIPT"
}
export interface SourceLocation {
start: {
line: number;
column: number;
offset: number;
};
end: {
line: number;
column: number;
offset: number;
};
}
export interface Token {
type: TokenType;
value: string;
line: number;
column: number;
start: number;
end: number;
loc?: SourceLocation;
/**
* Set on the literal text parts of an interpolated attribute value
* (title="a <%= x %> b"): they are text, never a value to classify as an
* identifier or expression.
*/
interpolation_text?: boolean;
}
export declare class Lexer {
private input;
private filename?;
private position;
private line;
private column;
private tokens;
private line_starts;
readonly hidden_closes: HiddenCloseLocation[];
private in_attribute_value;
private savedPosition;
constructor(input: string, filename?: string);
/** 1-based line and column of an input offset. */
private position_at;
/**
* Save current position for later token creation
*/
private savePosition;
/**
* Get saved position or current position
*/
private getSavedPosition;
/**
* Replace <%-- comment --%> with equivalent number of newlines
* This ensures line mapping stays accurate while removing comment content
*/
private preprocessComments;
/**
* Replace HTML comments () that appear OUTSIDE of tags
* This strips documentation comments before component definitions
* HTML comments INSIDE tags are preserved in the output
*/
private preprocessHTMLComments;
/**
* Preprocess code blocks: mark empty lines with a comment placeholder.
*
* Expressions (<%= %>, <%!= %>, <%br= %>) are left exactly as written - a
* multi-line expression is joined onto one generated line by the parser, so no
* newline is moved out of it into the template text. Lines that start inside a
* string, template literal or block comment are part of that literal or comment
* and are never touched (shared JS scanner).
*/
private preprocessCodeBlocks;
/**
* Record the suspicious %> hidden in // comments of the code region starting at
* `start` of `text`. Line comments are blanked once a code block is preprocessed,
* so code blocks are recorded there and expressions (and an unclosed code block)
* when scanned; no region is seen with its comments twice.
*/
private record_hidden_closes;
tokenize(): Token[];
/**
* A template is compiled into JavaScript, and that JavaScript may be inlined in an
* HTML element,
* text, an attribute value, a <% %> block or an HTML comment. <%-- --%> comments are
* never emitted and are blanked out of this.input already.
*/
private reject_script_text;
private scan_next;
private scan_text;
private scan_code_block;
private scan_html_comment;
private scan_expression;
private scan_javascript;
private scan_component_name;
private scan_slot_name;
private match_sequence;
private peek_sequence;
private peek_sequence_at;
private skip_whitespace;
private current_char;
private peek_ahead;
private advance;
/**
* Record a token spanning input offsets [start, end). Its line/column (and
* loc.start) are those of `start` - the token's first character - and loc.end is
* the position of `end`, whatever the scanner has consumed by the time it calls.
*/
private add_token;
private is_tag_name_char;
private is_tag_start_at;
private is_tag_name_continue_char;
private scan_opening_tag;
/**
* <{expression} attrs...> or {expression}>: a component whose name is
* computed at render time. The expression runs from the { after < to its
* matching }, honouring nested braces and string literals, so a > inside it
* (<{a > b ? 'X' : 'Y'}>) never terminates the tag - the tag name ends at
* the brace, not at >. Emits TAG_OPEN/TAG_CLOSE then DYNAMIC_TAG_NAME
* carrying the raw expression text; attributes scan as for any tag.
*/
private scan_dynamic_tag;
private last_token_type;
/**
* Scan the body of a raw-text element as literal text, stopping at its closing tag.
*
* Markup inside is emitted as TEXT rather than tags, so ..
* round-trips exactly as written. JQHTML delimiters are still honoured, so
* <%= %> interpolation keeps working; the search for the closing tag skips those
* regions, so an expression may contain the literal string "".
*
* NEWLINE tokens are emitted as usual: codegen is line-based, and swallowing them
* here would desynchronise every downstream line number, including sourcemaps.
*/
private scan_raw_text_element;
private scan_closing_tag;
private scan_attributes;
private is_attribute_start_char;
/**
* Characters HTML does not allow in an attribute name: whitespace, quotes, `<`,
* `/`, and control characters (`=` and `>` end the name before this is asked).
* An attribute name is emitted into the compiled module as an object key, so a
* quote in one is not just invalid HTML - it is the end of a JS string literal.
* Everything templates legitimately use stays allowed: `:` `.` `-` `_` `@` `$`
* and digits (x-on:click, :class, @click.prevent, aria-label, data-foo.bar).
*/
private static is_forbidden_attribute_name_char;
private throw_invalid_attribute_name;
private scan_attribute;
private scan_attribute_value;
private validate_unquoted_value;
/** The rule for plain attributes: a value must be quoted, on every tag, included.
* Only @ attributes (unquoted) and $ attributes (either) take a JavaScript value. */
private throw_unquoted_regular_attribute;
private get_current_attribute_context;
private value_contains_interpolation;
private scan_interpolated_attribute_value;
private attribute_nl2br_error;
private attribute_multiline_expression_error;
private attribute_unknown_tag_error;
private attribute_code_block_error;
}
//# sourceMappingURL=lexer.d.ts.map