123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.transformSpan = exports.transform = void 0;
- const utils_1 = require("./utils");
- const transform = (node, context, isInParentParens = false) => {
- const type = utils_1.getNgType(node);
- switch (type) {
- case 'Unary': {
- // @ts-ignore: there is no `Unary` in `@angular/compiler@<10.1.0`
- const { operator, expr } = node;
- const tArgument = _t(expr);
- return _c('UnaryExpression', {
- prefix: true,
- argument: tArgument,
- operator: operator,
- }, node.span, { hasParentParens: isInParentParens });
- }
- case 'Binary': {
- const { left, operation, right } = node;
- const isPrefixAdd = right.span.start === right.span.end; // +1 === 1 - 0
- const isPrefixMinus = left.span.start === left.span.end; // -1 === 0 - 1
- // `@angular/compiler` changed this to `Unary` since `v10.1.0`
- // istanbul ignore next
- if (isPrefixAdd || isPrefixMinus) {
- const tArgument = left.span.start === left.span.end
- ? _t(right)
- : _t(left);
- return _c('UnaryExpression', {
- prefix: true,
- argument: tArgument,
- operator: isPrefixAdd ? '+' : '-',
- }, {
- start: node.span.start,
- end: _getOuterEnd(tArgument),
- }, { hasParentParens: isInParentParens });
- }
- const tLeft = _t(left);
- const tRight = _t(right);
- return _c(operation === '&&' || operation === '||'
- ? 'LogicalExpression'
- : 'BinaryExpression', {
- left: tLeft,
- right: tRight,
- // @ts-ignore
- operator: operation,
- }, { start: _getOuterStart(tLeft), end: _getOuterEnd(tRight) }, { hasParentParens: isInParentParens });
- }
- case 'BindingPipe': {
- const { exp, name, args } = node;
- const tExp = _t(exp);
- const nameStart = _findBackChar(/\S/, _findBackChar(/\|/, _getOuterEnd(tExp)) + 1);
- const tName = _c('Identifier', { name }, { start: nameStart, end: nameStart + name.length });
- const tArgs = args.map(_t);
- return _c('NGPipeExpression', {
- left: tExp,
- right: tName,
- arguments: tArgs,
- }, {
- start: _getOuterStart(tExp),
- end: _getOuterEnd(tArgs.length === 0 ? tName : utils_1.getLast(tArgs)),
- }, { hasParentParens: isInParentParens });
- }
- case 'Chain': {
- const { expressions } = node;
- return _c('NGChainedExpression', { expressions: expressions.map(_t) }, node.span, { hasParentParens: isInParentParens });
- }
- case 'Comment': {
- const { value } = node;
- return _c('CommentLine', { value }, node.span, {
- processSpan: false,
- });
- }
- case 'Conditional': {
- const { condition, trueExp, falseExp } = node;
- const tCondition = _t(condition);
- const tTrueExp = _t(trueExp);
- const tFalseExp = _t(falseExp);
- return _c('ConditionalExpression', {
- test: tCondition,
- consequent: tTrueExp,
- alternate: tFalseExp,
- }, { start: _getOuterStart(tCondition), end: _getOuterEnd(tFalseExp) }, { hasParentParens: isInParentParens });
- }
- case 'EmptyExpr':
- return _c('NGEmptyExpression', {}, node.span, {
- hasParentParens: isInParentParens,
- });
- case 'FunctionCall': {
- const { target, args } = node;
- const tArgs = args.length === 1
- ? [_transformHasParentParens(args[0])]
- : args.map(_t);
- const tTarget = _t(target);
- return _c('CallExpression', {
- callee: tTarget,
- arguments: tArgs,
- }, {
- start: _getOuterStart(tTarget),
- end: node.span.end,
- }, { hasParentParens: isInParentParens });
- }
- case 'ImplicitReceiver': {
- return _c('ThisExpression', {}, node.span, {
- hasParentParens: isInParentParens,
- });
- }
- case 'KeyedRead': {
- const { obj, key } = node;
- const tKey = _t(key);
- return _transformReceiverAndName(obj, tKey, {
- computed: true,
- optional: false,
- }, {
- end: node.span.end,
- hasParentParens: isInParentParens,
- });
- }
- case 'LiteralArray': {
- const { expressions } = node;
- return _c('ArrayExpression', { elements: expressions.map(_t) }, node.span, { hasParentParens: isInParentParens });
- }
- case 'LiteralMap': {
- const { keys, values } = node;
- const tValues = values.map(value => _t(value));
- const tProperties = keys.map(({ key, quoted }, index) => {
- const tValue = tValues[index];
- const keyStart = _findBackChar(/\S/, index === 0
- ? node.span.start + 1 // {
- : _findBackChar(/,/, _getOuterEnd(tValues[index - 1])) + 1);
- const keyEnd = _findFrontChar(/\S/, _findFrontChar(/:/, _getOuterStart(tValue) - 1) - 1) + 1;
- const keySpan = { start: keyStart, end: keyEnd };
- const tKey = quoted
- ? _c('StringLiteral', { value: key }, keySpan)
- : _c('Identifier', { name: key }, keySpan);
- return _c('ObjectProperty', {
- key: tKey,
- value: tValue,
- method: false,
- shorthand: false,
- computed: false,
- }, { start: _getOuterStart(tKey), end: _getOuterEnd(tValue) });
- });
- return _c('ObjectExpression', { properties: tProperties }, node.span, { hasParentParens: isInParentParens });
- }
- case 'LiteralPrimitive': {
- const { value } = node;
- switch (typeof value) {
- case 'boolean':
- return _c('BooleanLiteral', { value }, node.span, {
- hasParentParens: isInParentParens,
- });
- case 'number':
- return _c('NumericLiteral', { value }, node.span, {
- hasParentParens: isInParentParens,
- });
- case 'object':
- return _c('NullLiteral', {}, node.span, {
- hasParentParens: isInParentParens,
- });
- case 'string':
- return _c('StringLiteral', { value }, node.span, {
- hasParentParens: isInParentParens,
- });
- case 'undefined':
- return _c('Identifier', { name: 'undefined' }, node.span, { hasParentParens: isInParentParens });
- // istanbul ignore next
- default:
- throw new Error(`Unexpected LiteralPrimitive value type ${typeof value}`);
- }
- }
- case 'MethodCall':
- case 'SafeMethodCall': {
- const isOptionalType = type === 'SafeMethodCall';
- const { receiver, name, args } = node;
- const tArgs = args.length === 1
- ? [_transformHasParentParens(args[0])]
- : args.map(_t);
- const nameEnd = _findFrontChar(/\S/, _findFrontChar(/\(/, (tArgs.length === 0
- ? _findFrontChar(/\)/, node.span.end - 1)
- : _getOuterStart(tArgs[0])) - 1) - 1) + 1;
- const tName = _c('Identifier', { name }, { start: nameEnd - name.length, end: nameEnd });
- const tReceiverAndName = _transformReceiverAndName(receiver, tName, {
- computed: false,
- optional: isOptionalType,
- });
- const isOptionalReceiver = _isOptionalReceiver(tReceiverAndName);
- return _c(isOptionalType || isOptionalReceiver
- ? 'OptionalCallExpression'
- : 'CallExpression', {
- callee: tReceiverAndName,
- arguments: tArgs,
- }, {
- start: _getOuterStart(tReceiverAndName),
- end: node.span.end,
- }, { hasParentParens: isInParentParens });
- }
- case 'NonNullAssert': {
- const { expression } = node;
- const tExpression = _t(expression);
- return _c('TSNonNullExpression', { expression: tExpression }, {
- start: _getOuterStart(tExpression),
- end: node.span.end,
- }, { hasParentParens: isInParentParens });
- }
- case 'PrefixNot': {
- const { expression } = node;
- const tExpression = _t(expression);
- return _c('UnaryExpression', {
- prefix: true,
- operator: '!',
- argument: tExpression,
- }, {
- start: node.span.start,
- end: _getOuterEnd(tExpression),
- }, { hasParentParens: isInParentParens });
- }
- case 'PropertyRead':
- case 'SafePropertyRead': {
- const isOptionalType = type === 'SafePropertyRead';
- const { receiver, name } = node;
- const nameEnd = _findFrontChar(/\S/, node.span.end - 1) + 1;
- const tName = _c('Identifier', { name }, { start: nameEnd - name.length, end: nameEnd }, _isImplicitThis(receiver) ? { hasParentParens: isInParentParens } : {});
- return _transformReceiverAndName(receiver, tName, {
- computed: false,
- optional: isOptionalType,
- }, { hasParentParens: isInParentParens });
- }
- case 'KeyedWrite': {
- const { obj, key, value } = node;
- const tKey = _t(key);
- const tValue = _t(value);
- const tReceiverAndName = _transformReceiverAndName(obj, tKey, {
- computed: true,
- optional: false,
- }, { end: _findBackChar(/\]/, _getOuterEnd(tKey)) + 1 });
- return _c('AssignmentExpression', {
- left: tReceiverAndName,
- operator: '=',
- right: tValue,
- }, { start: _getOuterStart(tReceiverAndName), end: _getOuterEnd(tValue) }, { hasParentParens: isInParentParens });
- }
- case 'PropertyWrite': {
- const { receiver, name, value } = node;
- const tValue = _t(value);
- const nameEnd = _findFrontChar(/\S/, _findFrontChar(/=/, _getOuterStart(tValue) - 1) - 1) + 1;
- const tName = _c('Identifier', { name }, { start: nameEnd - name.length, end: nameEnd });
- const tReceiverAndName = _transformReceiverAndName(receiver, tName, {
- computed: false,
- optional: false,
- });
- return _c('AssignmentExpression', {
- left: tReceiverAndName,
- operator: '=',
- right: tValue,
- }, { start: _getOuterStart(tReceiverAndName), end: _getOuterEnd(tValue) }, { hasParentParens: isInParentParens });
- }
- case 'Quote': {
- const { prefix, uninterpretedExpression } = node;
- return _c('NGQuotedExpression', {
- prefix,
- value: uninterpretedExpression,
- }, node.span, { hasParentParens: isInParentParens });
- }
- // istanbul ignore next
- default:
- throw new Error(`Unexpected node ${type}`);
- }
- function _t(n) {
- return exports.transform(n, context);
- }
- function _transformHasParentParens(n) {
- return exports.transform(n, context, true);
- }
- function _c(t, n, span, { processSpan = true, hasParentParens = false } = {}) {
- const newNode = Object.assign(Object.assign({ type: t }, transformSpan(span, context, processSpan, hasParentParens)), n);
- switch (t) {
- case 'Identifier': {
- const identifier = newNode;
- identifier.loc.identifierName = identifier.name;
- break;
- }
- case 'NumericLiteral': {
- const numericLiteral = newNode;
- numericLiteral.extra = Object.assign(Object.assign({}, numericLiteral.extra), { raw: context.text.slice(numericLiteral.start, numericLiteral.end), rawValue: numericLiteral.value });
- break;
- }
- case 'StringLiteral': {
- const stringLiteral = newNode;
- stringLiteral.extra = Object.assign(Object.assign({}, stringLiteral.extra), { raw: context.text.slice(stringLiteral.start, stringLiteral.end), rawValue: stringLiteral.value });
- break;
- }
- }
- return newNode;
- }
- function _transformReceiverAndName(receiver, tName, props, { end = _getOuterEnd(tName), hasParentParens = false } = {}) {
- if (_isImplicitThis(receiver)) {
- return tName;
- }
- const tReceiver = _t(receiver);
- const isOptionalReceiver = _isOptionalReceiver(tReceiver);
- return _c(props.optional || isOptionalReceiver
- ? 'OptionalMemberExpression'
- : 'MemberExpression', Object.assign({ object: tReceiver, property: tName, computed: props.computed }, (props.optional
- ? { optional: true }
- : isOptionalReceiver
- ? { optional: false }
- : null)), { start: _getOuterStart(tReceiver), end }, { hasParentParens });
- }
- function _findFrontChar(regex, index) {
- return utils_1.findFrontChar(regex, index, context.text);
- }
- function _findBackChar(regex, index) {
- return utils_1.findBackChar(regex, index, context.text);
- }
- function _isImplicitThis(n) {
- return (n.span.start >= n.span.end ||
- /^\s+$/.test(context.text.slice(n.span.start, n.span.end)));
- }
- function _isOptionalReceiver(n) {
- return ((n.type === 'OptionalCallExpression' ||
- n.type === 'OptionalMemberExpression') &&
- !_isParenthesized(n));
- }
- function _isParenthesized(n) {
- // @ts-ignore
- return n.extra && n.extra.parenthesized;
- }
- function _getOuterStart(n) {
- // @ts-ignore
- return _isParenthesized(n) ? n.extra.parenStart : n.start;
- }
- function _getOuterEnd(n) {
- // @ts-ignore
- return _isParenthesized(n) ? n.extra.parenEnd : n.end;
- }
- };
- exports.transform = transform;
- function transformSpan(span, context, processSpan = false, hasParentParens = false) {
- if (!processSpan) {
- const { start, end } = span;
- return {
- start,
- end,
- loc: {
- start: context.locator.locationForIndex(start),
- end: context.locator.locationForIndex(end),
- },
- };
- }
- const { outerSpan, innerSpan, hasParens } = utils_1.fitSpans(span, context.text, hasParentParens);
- return Object.assign({ start: innerSpan.start, end: innerSpan.end, loc: {
- start: context.locator.locationForIndex(innerSpan.start),
- end: context.locator.locationForIndex(innerSpan.end),
- } }, (hasParens && {
- extra: {
- parenthesized: true,
- parenStart: outerSpan.start,
- parenEnd: outerSpan.end,
- },
- }));
- }
- exports.transformSpan = transformSpan;
|