UNPKG

@marko/compiler

Version:
218 lines (184 loc) 5.55 kB
"use strict";exports.__esModule = true;exports.parseArgs = parseArgs;exports.parseExpression = parseExpression;exports.parseParams = parseParams;exports.parseStatements = parseStatements;exports.parseTemplateLiteral = parseTemplateLiteral;exports.parseTypeArgs = parseTypeArgs;exports.parseTypeParams = parseTypeParams;exports.parseVar = parseVar;var _compiler = require("@marko/compiler"); var _babel = require("@marko/compiler/internal/babel"); var _loc = require("./loc"); function parseStatements( file, str, sourceStart, sourceEnd, sourceOffset) { return tryParse(file, false, str, sourceStart, sourceEnd, sourceOffset); } function parseExpression( file, str, sourceStart, sourceEnd, sourceOffset) { return tryParse(file, true, str, sourceStart, sourceEnd, sourceOffset); } function parseParams(file, str, sourceStart, sourceEnd) { const parsed = parseExpression( file, `(${str})=>{}`, sourceStart, sourceEnd, 1 ); if (parsed.type === "ArrowFunctionExpression") { return parsed.params; } return [ensureParseError(file, parsed, sourceStart, sourceEnd)]; } function parseArgs(file, str, sourceStart, sourceEnd) { const parsed = parseExpression(file, `_(${str})`, sourceStart, sourceEnd, 2); if (parsed.type === "CallExpression") { return parsed.arguments; } return [ensureParseError(file, parsed, sourceStart, sourceEnd)]; } function parseVar(file, str, sourceStart, sourceEnd) { const parsed = parseExpression( file, `(${str})=>{}`, sourceStart, sourceEnd, 1 ); if (parsed.type === "ArrowFunctionExpression" && parsed.params.length === 1) { return parsed.params[0]; } return ensureParseError(file, parsed, sourceStart, sourceEnd); } function parseTemplateLiteral(file, str, sourceStart, sourceEnd) { const parsed = parseExpression( file, "`" + str + "`", sourceStart, sourceEnd, 1 ); if (parsed.type === "TemplateLiteral") { return _compiler.types.templateLiteral(parsed.quasis, parsed.expressions); } return ensureParseError(file, parsed, sourceStart, sourceEnd); } function parseTypeArgs(file, str, sourceStart, sourceEnd) { const parsed = parseExpression(file, `_<${str}>`, sourceStart, sourceEnd, 2); if (parsed.type === "TSInstantiationExpression") { // typeArguments is Flow only (not TS), we need to use typeParameters return parsed.typeParameters; } return [ensureParseError(file, parsed, sourceStart, sourceEnd)]; } function parseTypeParams(file, str, sourceStart, sourceEnd) { const parsed = parseExpression( file, `<${str}>()=>{}`, sourceStart, sourceEnd, 1 ); if (parsed.type === "ArrowFunctionExpression") { return parsed.typeParameters; } return [ensureParseError(file, parsed, sourceStart, sourceEnd)]; } function tryParse( file, isExpression, code, sourceStart, sourceEnd, sourceOffset) { const { parserOpts } = file.opts; if (typeof sourceStart === "number") { const startLoc = (0, _loc.getLoc)(file, sourceStart); const startLine = startLoc.line; let startIndex = sourceStart; let startColumn = startLoc.column; if (sourceOffset) { startIndex -= sourceOffset; startColumn -= sourceOffset; } parserOpts.startLine = startLine; parserOpts.startIndex = startIndex; parserOpts.startColumn = startColumn; try { if (isExpression) { return (0, _babel.parseExpression)(code, parserOpts); } else { const { program } = (0, _babel.parse)(code, parserOpts); if (program.innerComments) { const lastNode = _compiler.types.emptyStatement(); lastNode.trailingComments = program.innerComments; program.body.push(lastNode); } return program.body; } } catch (err) { const parseError = createParseError( file, sourceStart, sourceEnd, err.message, err.loc ); if (isExpression) { return parseError; } else { return [parseError]; } } finally { parserOpts.startIndex = 0; parserOpts.startColumn = 0; parserOpts.startLine = 1; } } else { return isExpression ? _compiler.types.cloneDeepWithoutLoc((0, _babel.parseExpression)(code, parserOpts)) : (0, _babel.parse)(code, parserOpts).program.body.map((node) => _compiler.types.cloneDeepWithoutLoc(node) ); } } function ensureParseError(file, node, sourceStart, sourceEnd) { if (node.type === "MarkoParseError") return node; return createParseError( file, sourceStart, sourceEnd, `Unexpected node of type ${node.type} returned while parsing.` ); } function createParseError(file, sourceStart, sourceEnd, label, errorLoc) { file.___hasParseErrors = true; const loc = (0, _loc.getLocRange)(file, sourceStart, sourceEnd); return { type: "MarkoParseError", source: file.code.slice(sourceStart, sourceEnd), label: label.replace(/ *\(\d+:\d+\)$/, ""), errorLoc: errorLoc && getBoundedRange(loc, errorLoc), loc, start: sourceStart, end: sourceEnd }; } function getBoundedRange(range, loc) { if (loc && typeof loc.line === "number") { const { start, end } = range; // If start is out of bounds return the source. if ( loc.line < start.line || loc.line === start.line && loc.column < start.column || loc.line > end.line || loc.line === end.line && loc.column > end.column) { return range; } return { start: loc, end: loc }; } }