@jqhtml/parser 2.2.222
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/LICENSE +21 -0
- package/README.md +30 -0
- package/bin/jqhtml-compile +218 -0
- package/dist/ast.d.ts +102 -0
- package/dist/ast.d.ts.map +1 -0
- package/dist/ast.js +30 -0
- package/dist/ast.js.map +1 -0
- package/dist/codegen.d.ts +108 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +1377 -0
- package/dist/codegen.js.map +1 -0
- package/dist/compiler.d.ts +25 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +273 -0
- package/dist/compiler.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +155 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.d.ts +3 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +47 -0
- package/dist/integration.js.map +1 -0
- package/dist/lexer.d.ts +123 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +1446 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser.d.ts +56 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +845 -0
- package/dist/parser.js.map +1 -0
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +106 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 JQHTML Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @jqhtml/parser
|
|
2
|
+
|
|
3
|
+
Compiles `.jqhtml` templates into JavaScript for the JQHTML component framework.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx jqhtml-compile compile components/*.jqhtml -o bundle.js --sourcemap
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Templates look like HTML with embedded JavaScript:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<Define:Product_Card class="card">
|
|
13
|
+
<h3><%= this.data.name %></h3>
|
|
14
|
+
<% if (this.data.on_sale) { %>
|
|
15
|
+
<span class="badge">Sale!</span>
|
|
16
|
+
<% } %>
|
|
17
|
+
</Define:Product_Card>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The parser handles the template syntax - `<Define:>` blocks, `<%= %>` expressions, control flow, slots, event bindings. Output is JavaScript that the `@jqhtml/core` runtime understands.
|
|
21
|
+
|
|
22
|
+
## Status
|
|
23
|
+
|
|
24
|
+
Alpha release. Works well enough that I use it daily, but documentation is sparse and you might hit edge cases. Webpack loader and proper docs coming soon.
|
|
25
|
+
|
|
26
|
+
Found a bug or built something cool? Drop me a line.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
**hansonxyz** · [hanson.xyz](https://hanson.xyz/) · [github](https://github.com/hansonxyz)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JQHTML Official CLI Compiler
|
|
5
|
+
*
|
|
6
|
+
* Compiles .jqhtml templates to JavaScript with multiple output formats
|
|
7
|
+
* Uses unified compiler module for single source of truth
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import { compileTemplate } from '../dist/index.js';
|
|
14
|
+
import { readFileSync } from 'fs';
|
|
15
|
+
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
18
|
+
|
|
19
|
+
// Get package version
|
|
20
|
+
const packagePath = path.join(path.dirname(__dirname), 'package.json');
|
|
21
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
22
|
+
const VERSION = packageJson.version;
|
|
23
|
+
|
|
24
|
+
// Parse command line arguments
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
const args = {
|
|
27
|
+
input: null,
|
|
28
|
+
output: null,
|
|
29
|
+
format: 'iife',
|
|
30
|
+
sourcemap: false,
|
|
31
|
+
statusJson: false,
|
|
32
|
+
help: false,
|
|
33
|
+
version: false
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
for (let i = 2; i < argv.length; i++) {
|
|
37
|
+
const arg = argv[i];
|
|
38
|
+
|
|
39
|
+
if (arg === '--help' || arg === '-h') {
|
|
40
|
+
args.help = true;
|
|
41
|
+
} else if (arg === '--version' || arg === '-v') {
|
|
42
|
+
args.version = true;
|
|
43
|
+
} else if (arg === '--output' || arg === '-o') {
|
|
44
|
+
args.output = argv[++i];
|
|
45
|
+
if (!args.output) {
|
|
46
|
+
throw new Error('--output requires a file path');
|
|
47
|
+
}
|
|
48
|
+
} else if (arg === '--format') {
|
|
49
|
+
args.format = argv[++i];
|
|
50
|
+
if (!['iife', 'esm', 'cjs', 'umd'].includes(args.format)) {
|
|
51
|
+
throw new Error(`Invalid format: ${args.format}. Must be one of: iife, esm, cjs, umd`);
|
|
52
|
+
}
|
|
53
|
+
} else if (arg === '--sourcemap') {
|
|
54
|
+
args.sourcemap = true;
|
|
55
|
+
} else if (arg === '--status-json') {
|
|
56
|
+
args.statusJson = true;
|
|
57
|
+
} else if (!arg.startsWith('-')) {
|
|
58
|
+
args.input = arg;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return args;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Show help message
|
|
66
|
+
function showHelp() {
|
|
67
|
+
console.log(`
|
|
68
|
+
JQHTML CLI Compiler v${VERSION}
|
|
69
|
+
|
|
70
|
+
Usage: jqhtml-compile <input.jqhtml> [options]
|
|
71
|
+
|
|
72
|
+
Options:
|
|
73
|
+
--output, -o <file> Write output to file instead of stdout
|
|
74
|
+
--format <format> Output format: iife|esm|cjs|umd (default: iife)
|
|
75
|
+
--sourcemap Include inline sourcemap
|
|
76
|
+
--status-json Output errors as JSON for programmatic parsing
|
|
77
|
+
--version, -v Show version number
|
|
78
|
+
--help, -h Show this help message
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
jqhtml compile component.jqhtml
|
|
82
|
+
jqhtml compile component.jqhtml --output component.js
|
|
83
|
+
jqhtml compile component.jqhtml --format esm --sourcemap
|
|
84
|
+
jqhtml compile component.jqhtml -o dist/component.js --format umd
|
|
85
|
+
|
|
86
|
+
Output formats:
|
|
87
|
+
iife - Self-executing function that registers with window.jqhtml
|
|
88
|
+
esm - ES module export
|
|
89
|
+
cjs - CommonJS module.exports
|
|
90
|
+
umd - Universal module (works as AMD, CommonJS, or global)
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// Main compilation function
|
|
96
|
+
async function compile(inputFile, options) {
|
|
97
|
+
try {
|
|
98
|
+
// Read input file
|
|
99
|
+
const inputPath = path.resolve(inputFile);
|
|
100
|
+
if (!fs.existsSync(inputPath)) {
|
|
101
|
+
throw new Error(`Input file not found: ${inputPath}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const source = fs.readFileSync(inputPath, 'utf-8');
|
|
105
|
+
const filename = path.basename(inputPath);
|
|
106
|
+
|
|
107
|
+
// Use unified compiler
|
|
108
|
+
const compiled = compileTemplate(source, filename, {
|
|
109
|
+
format: options.format,
|
|
110
|
+
sourcemap: options.sourcemap,
|
|
111
|
+
version: VERSION
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const formattedCode = compiled.code;
|
|
115
|
+
|
|
116
|
+
if (options.statusJson) {
|
|
117
|
+
// Output as JSON for programmatic consumption
|
|
118
|
+
const result = {
|
|
119
|
+
status: 'success',
|
|
120
|
+
result: formattedCode
|
|
121
|
+
};
|
|
122
|
+
if (options.output) {
|
|
123
|
+
result.outputFile = options.output;
|
|
124
|
+
}
|
|
125
|
+
console.log(JSON.stringify(result));
|
|
126
|
+
} else if (options.output) {
|
|
127
|
+
// Write to output file
|
|
128
|
+
const outputPath = path.resolve(options.output);
|
|
129
|
+
const outputDir = path.dirname(outputPath);
|
|
130
|
+
|
|
131
|
+
// Create output directory if it doesn't exist
|
|
132
|
+
if (!fs.existsSync(outputDir)) {
|
|
133
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fs.writeFileSync(outputPath, formattedCode, 'utf-8');
|
|
137
|
+
console.log(`✓ Compiled ${inputFile} → ${options.output}`);
|
|
138
|
+
} else {
|
|
139
|
+
// Output the compiled code to stdout without trailing newline
|
|
140
|
+
process.stdout.write(formattedCode);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return 0; // Success
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (options.statusJson) {
|
|
146
|
+
// Output error as JSON
|
|
147
|
+
const errorObj = {
|
|
148
|
+
status: 'error',
|
|
149
|
+
error: {
|
|
150
|
+
type: error.constructor.name,
|
|
151
|
+
message: error.message,
|
|
152
|
+
file: error.filename || null,
|
|
153
|
+
line: error.line || null,
|
|
154
|
+
column: error.column || null,
|
|
155
|
+
context: error.context || null,
|
|
156
|
+
suggestion: error.suggestion || null
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
console.log(JSON.stringify(errorObj));
|
|
160
|
+
} else {
|
|
161
|
+
// Output error to stderr
|
|
162
|
+
console.error(`Error: ${error.message}`);
|
|
163
|
+
if (error.line) {
|
|
164
|
+
console.error(` at line ${error.line}, column ${error.column || 0}`);
|
|
165
|
+
}
|
|
166
|
+
if (error.context) {
|
|
167
|
+
console.error(` context: ${error.context}`);
|
|
168
|
+
}
|
|
169
|
+
if (error.suggestion) {
|
|
170
|
+
console.error(` suggestion: ${error.suggestion}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return 1; // Error
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Main entry point
|
|
178
|
+
async function main() {
|
|
179
|
+
try {
|
|
180
|
+
const args = parseArgs(process.argv);
|
|
181
|
+
|
|
182
|
+
if (args.help) {
|
|
183
|
+
showHelp();
|
|
184
|
+
process.exit(0);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (args.version) {
|
|
188
|
+
console.log(`v${VERSION}`);
|
|
189
|
+
process.exit(0);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!args.input) {
|
|
193
|
+
if (args.statusJson) {
|
|
194
|
+
console.log(JSON.stringify({
|
|
195
|
+
status: 'error',
|
|
196
|
+
error: {
|
|
197
|
+
type: 'ArgumentError',
|
|
198
|
+
message: 'No input file specified'
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
} else {
|
|
202
|
+
console.error('Error: No input file specified');
|
|
203
|
+
console.error('Usage: jqhtml compile <input.jqhtml> [options]');
|
|
204
|
+
console.error('Use --help for more information');
|
|
205
|
+
}
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const exitCode = await compile(args.input, args);
|
|
210
|
+
process.exit(exitCode);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Fatal error:', error.message);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Run the CLI
|
|
218
|
+
main();
|
package/dist/ast.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { SourceLocation } from './lexer.js';
|
|
2
|
+
export declare enum NodeType {
|
|
3
|
+
PROGRAM = "Program",
|
|
4
|
+
COMPONENT_DEFINITION = "ComponentDefinition",
|
|
5
|
+
COMPONENT_INVOCATION = "ComponentInvocation",
|
|
6
|
+
HTML_TAG = "HtmlTag",
|
|
7
|
+
TEXT = "Text",
|
|
8
|
+
EXPRESSION = "Expression",
|
|
9
|
+
IF_STATEMENT = "IfStatement",
|
|
10
|
+
FOR_STATEMENT = "ForStatement",
|
|
11
|
+
CODE_BLOCK = "CodeBlock",
|
|
12
|
+
FRAGMENT = "Fragment",
|
|
13
|
+
SLOT = "Slot",// v2 slot syntax
|
|
14
|
+
CONDITIONAL_ATTRIBUTE = "ConditionalAttribute"
|
|
15
|
+
}
|
|
16
|
+
export interface BaseNode {
|
|
17
|
+
type: NodeType;
|
|
18
|
+
start: number;
|
|
19
|
+
end: number;
|
|
20
|
+
line: number;
|
|
21
|
+
column: number;
|
|
22
|
+
loc?: SourceLocation;
|
|
23
|
+
range?: [number, number];
|
|
24
|
+
}
|
|
25
|
+
export interface ProgramNode extends BaseNode {
|
|
26
|
+
type: NodeType.PROGRAM;
|
|
27
|
+
body: ASTNode[];
|
|
28
|
+
}
|
|
29
|
+
export interface ComponentDefinitionNode extends BaseNode {
|
|
30
|
+
type: NodeType.COMPONENT_DEFINITION;
|
|
31
|
+
name: string;
|
|
32
|
+
body: ASTNode[];
|
|
33
|
+
attributes: Record<string, any>;
|
|
34
|
+
extends?: string;
|
|
35
|
+
defineArgs?: Record<string, any>;
|
|
36
|
+
isSlotOnly?: boolean;
|
|
37
|
+
slotNames?: string[];
|
|
38
|
+
}
|
|
39
|
+
export interface TextNode extends BaseNode {
|
|
40
|
+
type: NodeType.TEXT;
|
|
41
|
+
content: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ExpressionNode extends BaseNode {
|
|
44
|
+
type: NodeType.EXPRESSION;
|
|
45
|
+
code: string;
|
|
46
|
+
escaped: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface IfStatementNode extends BaseNode {
|
|
49
|
+
type: NodeType.IF_STATEMENT;
|
|
50
|
+
condition: string;
|
|
51
|
+
consequent: ASTNode[];
|
|
52
|
+
alternate: ASTNode[] | null;
|
|
53
|
+
}
|
|
54
|
+
export interface ForStatementNode extends BaseNode {
|
|
55
|
+
type: NodeType.FOR_STATEMENT;
|
|
56
|
+
iterator: string;
|
|
57
|
+
body: ASTNode[];
|
|
58
|
+
}
|
|
59
|
+
export interface CodeBlockNode extends BaseNode {
|
|
60
|
+
type: NodeType.CODE_BLOCK;
|
|
61
|
+
tokens?: Array<{
|
|
62
|
+
type: string;
|
|
63
|
+
value: string;
|
|
64
|
+
}>;
|
|
65
|
+
code?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface ConditionalAttributeNode extends BaseNode {
|
|
68
|
+
type: NodeType.CONDITIONAL_ATTRIBUTE;
|
|
69
|
+
condition: string;
|
|
70
|
+
attributes: Record<string, any>;
|
|
71
|
+
}
|
|
72
|
+
export interface FragmentNode extends BaseNode {
|
|
73
|
+
type: NodeType.FRAGMENT;
|
|
74
|
+
children: ASTNode[];
|
|
75
|
+
}
|
|
76
|
+
export interface SlotNode extends BaseNode {
|
|
77
|
+
type: NodeType.SLOT;
|
|
78
|
+
name: string;
|
|
79
|
+
attributes?: Record<string, any>;
|
|
80
|
+
children: ASTNode[];
|
|
81
|
+
selfClosing: boolean;
|
|
82
|
+
}
|
|
83
|
+
export interface ComponentInvocationNode extends BaseNode {
|
|
84
|
+
type: NodeType.COMPONENT_INVOCATION;
|
|
85
|
+
name: string;
|
|
86
|
+
attributes: Record<string, any>;
|
|
87
|
+
conditionalAttributes?: ConditionalAttributeNode[];
|
|
88
|
+
children: ASTNode[];
|
|
89
|
+
selfClosing: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface HtmlTagNode extends BaseNode {
|
|
92
|
+
type: NodeType.HTML_TAG;
|
|
93
|
+
name: string;
|
|
94
|
+
attributes: Record<string, any>;
|
|
95
|
+
conditionalAttributes?: ConditionalAttributeNode[];
|
|
96
|
+
children: ASTNode[];
|
|
97
|
+
selfClosing: boolean;
|
|
98
|
+
preserveWhitespace?: boolean;
|
|
99
|
+
}
|
|
100
|
+
export type ASTNode = ProgramNode | ComponentDefinitionNode | ComponentInvocationNode | HtmlTagNode | TextNode | ExpressionNode | IfStatementNode | ForStatementNode | CodeBlockNode | FragmentNode | SlotNode | ConditionalAttributeNode;
|
|
101
|
+
export declare function createNode<T extends ASTNode>(type: T['type'], props: Omit<T, 'type' | keyof BaseNode>, start: number, end: number, line: number, column: number, loc?: SourceLocation): T;
|
|
102
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|
package/dist/ast.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// AST Node Types for JQHTML Templates
|
|
2
|
+
// Simple, clear node structures for the syntax tree
|
|
3
|
+
export var NodeType;
|
|
4
|
+
(function (NodeType) {
|
|
5
|
+
NodeType["PROGRAM"] = "Program";
|
|
6
|
+
NodeType["COMPONENT_DEFINITION"] = "ComponentDefinition";
|
|
7
|
+
NodeType["COMPONENT_INVOCATION"] = "ComponentInvocation";
|
|
8
|
+
NodeType["HTML_TAG"] = "HtmlTag";
|
|
9
|
+
NodeType["TEXT"] = "Text";
|
|
10
|
+
NodeType["EXPRESSION"] = "Expression";
|
|
11
|
+
NodeType["IF_STATEMENT"] = "IfStatement";
|
|
12
|
+
NodeType["FOR_STATEMENT"] = "ForStatement";
|
|
13
|
+
NodeType["CODE_BLOCK"] = "CodeBlock";
|
|
14
|
+
NodeType["FRAGMENT"] = "Fragment";
|
|
15
|
+
NodeType["SLOT"] = "Slot";
|
|
16
|
+
NodeType["CONDITIONAL_ATTRIBUTE"] = "ConditionalAttribute"; // Conditional attribute: <% if (cond) { %>attr="val"<% } %>
|
|
17
|
+
})(NodeType || (NodeType = {}));
|
|
18
|
+
// Helper to create nodes with common properties
|
|
19
|
+
export function createNode(type, props, start, end, line, column, loc) {
|
|
20
|
+
return {
|
|
21
|
+
type,
|
|
22
|
+
start,
|
|
23
|
+
end,
|
|
24
|
+
line,
|
|
25
|
+
column,
|
|
26
|
+
loc,
|
|
27
|
+
...props
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ast.js.map
|
package/dist/ast.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,oDAAoD;AAIpD,MAAM,CAAN,IAAY,QAaX;AAbD,WAAY,QAAQ;IAClB,+BAAmB,CAAA;IACnB,wDAA4C,CAAA;IAC5C,wDAA4C,CAAA;IAC5C,gCAAoB,CAAA;IACpB,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,wCAA4B,CAAA;IAC5B,0CAA8B,CAAA;IAC9B,oCAAwB,CAAA;IACxB,iCAAqB,CAAA;IACrB,yBAAa,CAAA;IACb,0DAA8C,CAAA,CAAE,4DAA4D;AAC9G,CAAC,EAbW,QAAQ,KAAR,QAAQ,QAanB;AA4HD,gDAAgD;AAChD,MAAM,UAAU,UAAU,CACxB,IAAe,EACf,KAAuC,EACvC,KAAa,EACb,GAAW,EACX,IAAY,EACZ,MAAc,EACd,GAAoB;IAEpB,OAAO;QACL,IAAI;QACJ,KAAK;QACL,GAAG;QACH,IAAI;QACJ,MAAM;QACN,GAAG;QACH,GAAG,KAAK;KACJ,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ProgramNode } from './ast.js';
|
|
2
|
+
export interface GeneratedCode {
|
|
3
|
+
code: string;
|
|
4
|
+
source_map?: string;
|
|
5
|
+
source_map_data_uri?: string;
|
|
6
|
+
components: Map<string, ComponentCode>;
|
|
7
|
+
}
|
|
8
|
+
export interface ComponentCode {
|
|
9
|
+
name: string;
|
|
10
|
+
render_function: string;
|
|
11
|
+
dependencies: string[];
|
|
12
|
+
tagName: string;
|
|
13
|
+
defaultAttributes: Record<string, any>;
|
|
14
|
+
defineArgs?: Record<string, any>;
|
|
15
|
+
extends?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class CodeGenerator {
|
|
18
|
+
private indent_level;
|
|
19
|
+
private components;
|
|
20
|
+
private current_component;
|
|
21
|
+
private in_slot;
|
|
22
|
+
private tag_depth;
|
|
23
|
+
private lastOutput;
|
|
24
|
+
private outputLine;
|
|
25
|
+
private outputColumn;
|
|
26
|
+
private sourceMapGenerator?;
|
|
27
|
+
private sourceContent?;
|
|
28
|
+
private sourceFile?;
|
|
29
|
+
private outputBuffer;
|
|
30
|
+
private enablePositionTracking;
|
|
31
|
+
private positionLog;
|
|
32
|
+
private currentOutputLine;
|
|
33
|
+
private preserveLines;
|
|
34
|
+
private outputLines;
|
|
35
|
+
private sourceLines;
|
|
36
|
+
generate(ast: ProgramNode, sourceFile?: string, sourceContent?: string): GeneratedCode;
|
|
37
|
+
/**
|
|
38
|
+
* Generate code with source maps using 1:1 line mapping + SourceMapGenerator
|
|
39
|
+
*/
|
|
40
|
+
generateWithSourceMap(ast: ProgramNode, sourceFile: string, sourceContent: string): GeneratedCode;
|
|
41
|
+
private generate_component_with_mappings_TESTING;
|
|
42
|
+
private generate_component;
|
|
43
|
+
private generate_function_body;
|
|
44
|
+
/**
|
|
45
|
+
* Generate function body with true 1:1 line mapping
|
|
46
|
+
* Each line in the source produces exactly one line in the output
|
|
47
|
+
*/
|
|
48
|
+
private generate_function_body_1to1;
|
|
49
|
+
private generate_node;
|
|
50
|
+
/**
|
|
51
|
+
* Padded trim: Collapse internal whitespace but preserve leading/trailing space
|
|
52
|
+
* Examples:
|
|
53
|
+
* " hello " → " hello "
|
|
54
|
+
* "hello" → "hello"
|
|
55
|
+
* " " → " "
|
|
56
|
+
* "\n\n \n" → " "
|
|
57
|
+
*/
|
|
58
|
+
private padded_trim;
|
|
59
|
+
private generate_text;
|
|
60
|
+
private generate_expression;
|
|
61
|
+
private generate_if;
|
|
62
|
+
private generate_for;
|
|
63
|
+
private generate_code_block;
|
|
64
|
+
private generate_tag_open;
|
|
65
|
+
private generate_html_tag;
|
|
66
|
+
private generate_component_invocation;
|
|
67
|
+
private parse_attributes;
|
|
68
|
+
private generate_attributes_with_conditionals;
|
|
69
|
+
private generate_attributes_object;
|
|
70
|
+
private is_self_closing_tag;
|
|
71
|
+
private compile_interpolated_value;
|
|
72
|
+
private escape_string;
|
|
73
|
+
private indent;
|
|
74
|
+
private extract_slots_from_children;
|
|
75
|
+
/**
|
|
76
|
+
* Emit text and track position for source maps
|
|
77
|
+
*/
|
|
78
|
+
private emit;
|
|
79
|
+
/**
|
|
80
|
+
* Emit a line of text (adds newline)
|
|
81
|
+
*/
|
|
82
|
+
private emitLine;
|
|
83
|
+
/**
|
|
84
|
+
* Reset position tracking
|
|
85
|
+
*/
|
|
86
|
+
private resetPositionTracking;
|
|
87
|
+
/**
|
|
88
|
+
* Get position tracking log for debugging
|
|
89
|
+
*/
|
|
90
|
+
getPositionLog(): Array<{
|
|
91
|
+
line: number;
|
|
92
|
+
column: number;
|
|
93
|
+
text: string;
|
|
94
|
+
node?: string;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Enable/disable position tracking
|
|
98
|
+
*/
|
|
99
|
+
setPositionTracking(enabled: boolean): void;
|
|
100
|
+
/**
|
|
101
|
+
* Serialize attribute object with proper handling of identifiers and expressions
|
|
102
|
+
* Quoted values become strings, identifiers/expressions become raw JavaScript
|
|
103
|
+
*/
|
|
104
|
+
private serializeAttributeObject;
|
|
105
|
+
private build_module_code;
|
|
106
|
+
}
|
|
107
|
+
export declare function generate(ast: ProgramNode, sourceFile?: string, sourceContent?: string): GeneratedCode;
|
|
108
|
+
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
|