Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/two-adults-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'esrap': patch
---

fix: prevent out-of-order mappings with decorators
191 changes: 121 additions & 70 deletions src/languages/ts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ export default (options = {}) => {
* @param {Context} context
*/
'ArrayExpression|ArrayPattern': (node, context) => {
if ('decorators' in node) write_parameter_decorators(context, node.decorators);
if ('decorators' in node) inline_decorators(context, node);
context.write('[');
sequence(
context,
Expand Down Expand Up @@ -629,11 +629,7 @@ export default (options = {}) => {
* @param {Context} context
*/
'ClassDeclaration|ClassExpression': (node, context) => {
if (node.decorators) {
for (const decorator of node.decorators) {
context.visit(decorator);
}
}
block_decorators(context, node);

if (node.declare) context.write('declare ');
if (node.abstract) context.write('abstract ');
Expand Down Expand Up @@ -731,11 +727,7 @@ export default (options = {}) => {
* @param {Context} context
*/
'MethodDefinition|TSAbstractMethodDefinition': (node, context) => {
if (node.decorators) {
for (const decorator of node.decorators) {
context.visit(decorator);
}
}
block_decorators(context, node);

// @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
if (node.abstract || node.type === 'TSAbstractMethodDefinition') {
Expand Down Expand Up @@ -803,11 +795,7 @@ export default (options = {}) => {
node,
context
) => {
if (node.decorators) {
for (const decorator of node.decorators) {
context.visit(decorator);
}
}
block_decorators(context, node);

if (node.declare) context.write('declare ');

Expand Down Expand Up @@ -966,8 +954,9 @@ export default (options = {}) => {
node.type in EXPRESSIONS_PRECEDENCE && !BINDINGS.has(node)
);

const start = printed_start(node);
context.location(start.line, start.column);
if (!has_preceding_decorator(node)) {
context.location(node.loc.start.line, node.loc.start.column);
}
}

visit(node);
Expand Down Expand Up @@ -1026,7 +1015,7 @@ export default (options = {}) => {
},

AssignmentPattern(node, context) {
write_parameter_decorators(context, node.decorators);
inline_decorators(context, node);
context.visit(node.left);
context.write(' = ');
context.visit(node.right);
Expand Down Expand Up @@ -1126,8 +1115,13 @@ export default (options = {}) => {
},

Decorator(node, context) {
write_decorator(context, node);
context.newline();
context.write('@');
// a decorator must be an identifier/member/call (or parenthesized); anything
// else (ternary, logical, assignment, unary, `as`, optional chain…) needs wrapping
const wrap =
/** @type {string} */ (node.expression.type) === 'ChainExpression' ||
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
maybe_wrap(context, node.expression, wrap);
},

DoWhileStatement(node, context) {
Expand Down Expand Up @@ -1160,36 +1154,52 @@ export default (options = {}) => {
},

ExportDefaultDeclaration(node, context) {
const d = node.declaration;

// ClassDeclaration/ClassExpression decorators should be printed before `export`
if ('decorators' in d) {
block_decorators(context, {
...d,
// @ts-expect-error we need to prevent a mapping being added for the end of the declaration
loc: null
});
}

token(context, 'export', node);
context.write(' default ');

context.visit(node.declaration);
if (d.loc) {
flush_comments_until(context, null, d.loc.start, true, false);
}

visit_without_decorators(context, d);

if (node.declaration.type !== 'FunctionDeclaration') {
context.write(';');
}
},

ExportNamedDeclaration(node, context) {
if (node.declaration) {
// Check if declaration has decorators (ClassDeclaration, ClassExpression can have them)
const decl = /** @type {any} */ (node.declaration);
if (decl.decorators && decl.decorators.length > 0) {
for (const decorator of decl.decorators) {
context.visit(decorator);
}
token(context, 'export', node);
context.write(' ');
// Temporarily remove decorators so ClassDeclaration doesn't print them again
const savedDecorators = decl.decorators;
decl.decorators = [];
context.visit(node.declaration);
decl.decorators = savedDecorators;
} else {
token(context, 'export', node);
context.write(' ');
context.visit(node.declaration);
const d = node.declaration;

if (d) {
// ClassDeclaration/ClassExpression decorators should be printed before `export`
if ('decorators' in d) {
block_decorators(context, {
...d,
// @ts-expect-error we need to prevent a mapping being added for the end of the declaration
loc: null
});
}

token(context, 'export', node);
context.write(' ');

if (d.loc) {
flush_comments_until(context, null, d.loc.start, true, false);
}

visit_without_decorators(context, d);
return;
}

Expand Down Expand Up @@ -1261,7 +1271,7 @@ export default (options = {}) => {
FunctionExpression: shared['FunctionDeclaration|FunctionExpression'],

Identifier(node, context) {
write_parameter_decorators(context, node.decorators);
inline_decorators(context, node);
let name = node.name;
context.write(name, node);

Expand Down Expand Up @@ -1450,7 +1460,7 @@ export default (options = {}) => {
},

ObjectPattern(node, context) {
write_parameter_decorators(context, node.decorators);
inline_decorators(context, node);
context.write('{');
sequence(context, node.properties, node.loc?.end ?? null, true);
context.write('}');
Expand Down Expand Up @@ -1938,8 +1948,11 @@ export default (options = {}) => {
// property, Acorn to its parameter. Either way they precede the modifiers
const parameter = node.parameter;
const parameter_decorators = parameter.decorators;
write_parameter_decorators(context, node.decorators);
write_parameter_decorators(context, parameter_decorators);

inline_decorators(
context,
parameter.decorators ? { ...node, decorators: parameter.decorators } : node
);

if (node.accessibility) {
context.write(node.accessibility + ' ');
Expand Down Expand Up @@ -2515,34 +2528,60 @@ function maybe_wrap(context, node, wrap) {

/**
* @param {Context} context
* @param {TSESTree.Decorator} node
* @param {TSESTree.Node & { decorators: TSESTree.Decorator[] | undefined }} node
*/
function write_decorator(context, node) {
context.write('@');
// a decorator must be an identifier/member/call (or parenthesized); anything
// else (ternary, logical, assignment, unary, `as`, optional chain…) needs wrapping
const wrap =
/** @type {string} */ (node.expression.type) === 'ChainExpression' ||
EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
maybe_wrap(context, node.expression, wrap);
function block_decorators(context, node) {
if (!node.decorators) return;

for (const decorator of node.decorators) {
context.visit(decorator);
context.newline();
}

if (node.loc && has_preceding_decorator(node)) {
context.location(node.loc.start.line, node.loc.start.column);
}
}

/**
* Parameter decorators (`@dec x`) stay on the parameter's line, unlike class
* and member decorators, which the `Decorator` visitor puts on their own line
* @param {Context} context
* @param {TSESTree.Decorator[] | undefined} decorators
* @param {TSESTree.Node & { decorators: TSESTree.Decorator[] | undefined }} node
*/
function write_parameter_decorators(context, decorators) {
if (!decorators) return;

for (const decorator of decorators) {
// not visited through the root visitor, so map the node's span here
if (decorator.loc) context.location(decorator.loc.start.line, decorator.loc.start.column);
write_decorator(context, decorator);
if (decorator.loc) context.location(decorator.loc.end.line, decorator.loc.end.column);
function inline_decorators(context, node) {
if (!node.decorators) return;

for (const decorator of node.decorators) {
context.visit(decorator);
context.write(' ');
}

if (node.loc && has_preceding_decorator(node)) {
context.location(node.loc.start.line, node.loc.start.column);
}
}

/**
* Visit an exported declaration minus its decorators, which have already been printed
* @param {Context} context
* @param {TSESTree.Node} node
*/
function visit_without_decorators(context, node) {
if ('decorators' in node && node.decorators && node.decorators.length > 0) {
const { decorators, loc } = node;

// Temporarily remove decorators so ClassDeclaration doesn't print them again
node.decorators = [];
// @ts-expect-error
node.loc = null;

context.visit(node);
node.decorators = decorators;
node.loc = loc;

if (loc) context.location(loc.end.line, loc.end.column);
} else {
context.visit(node);
}
}

/** @param {TSESTree.Node} node */
Expand Down Expand Up @@ -2722,14 +2761,26 @@ function handle_var_declarator(node, context, no_in) {
}

/**
* Where a node's printed output starts. A parameter's `loc` starts after its
* decorators (Acorn, typescript-estree), but they are printed first.
* Whether a node has a decorator whose `start` location precedes that of
* the node itself, in which case we should not emit a mapping yet
* @param {TSESTree.Node} node
*/
function printed_start(node) {
const start = /** @type {TSESTree.SourceLocation} */ (node.loc).start;
const first = 'decorators' in node ? node.decorators?.[0]?.loc?.start : undefined;
return first && before(first, start) ? first : start;
function has_preceding_decorator(node) {
let n =
((node.type === 'ExportNamedDeclaration' || node.type === 'ExportDefaultDeclaration') &&
node.declaration) ||
node;

if ('parameter' in n && 'decorators' in n.parameter) {
n = n.parameter;
}

if ('decorators' in n) {
const loc = n.decorators?.[0]?.loc;
return loc ? before(loc.start, node.loc.start) : false;
}

return false;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions test/samples/ts-decorator-export-comment/expected.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@dec
export /* c */ declare class X {}
11 changes: 11 additions & 0 deletions test/samples/ts-decorator-export-comment/expected.ts.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": 3,
"names": [],
"sources": [
"input.js"
],
"sourcesContent": [
"@dec\nexport /* c */ declare class X {}\n"
],
"mappings": "AAAA,CAAC,GAAG;MACE,uBAAuB,CAAC,CAAC,CAAC,CAAC,AACjC"
}
2 changes: 2 additions & 0 deletions test/samples/ts-decorator-export-comment/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@dec
export /* c */ declare class X {}
3 changes: 3 additions & 0 deletions test/samples/ts-decorators-class/expected.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class Category {}
@Entity('tasks', { info: true })
export class Task {}

@Entity('default', { info: true })
export default class Default {};

const u = new User();
const c = new Category();
const t = new Task();
4 changes: 2 additions & 2 deletions test/samples/ts-decorators-class/expected.ts.map
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"input.js"
],
"sourcesContent": [
"export class Entity {\n\tconstructor(\n\t\tprivate readonly name: string,\n\t\tprivate readonly info: boolean\n\t) {}\n}\n\n@Entity('users', { info: true })\nexport class User {}\n\n@Entity('categories', { info: false })\nclass Category {}\n\n@Entity('tasks', { info: true })\nexport class Task {}\n\nconst u = new User();\nconst c = new Category();\nconst t = new Task();\n"
"export class Entity {\n\tconstructor(\n\t\tprivate readonly name: string,\n\t\tprivate readonly info: boolean\n\t) {}\n}\n\n@Entity('users', { info: true })\nexport class User {}\n\n@Entity('categories', { info: false })\nclass Category {}\n\n@Entity('tasks', { info: true })\nexport class Task {}\n\n@Entity('default', { info: true })\nexport default class Default {}\n\nconst u = new User();\nconst c = new Category();\nconst t = new Task();\n"
],
"mappings": "AAAA,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC;CACpB,WAAW;EACV,iBAAiB,IAAY,AAAR,EAAE,MAAM;EAC7B,iBAAiB,IAAa,AAAT,EAAE,OAAO;GAC7B,CAAC,CAAC;AACL,CAAC;;AAGD,AADA,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,MAC1B,CADN,MACa,IAAI,CAAC,CAAC,CAAC;;AAEpB,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAAA,MAChC,QAAQ,CAAC,CAAC,CAAC;;AAGjB,AADA,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,MAC1B,CADN,MACa,IAAI,CAAC,CAAC,CAAC;;AAEpB,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;AACrB,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;AACzB,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,AACrB"
"mappings": "AAAA,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC;CACpB,WAAW;EACV,iBAAiB,IAAY,AAAR,EAAE,MAAM;EAC7B,iBAAiB,IAAa,AAAT,EAAE,OAAO;GAC7B,CAAC,CAAC;AACL,CAAC;;AAED,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;MAC1B,OAAO,IAAI,CAAC,CAAC,CAAC;;AAEpB,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;MAChC,QAAQ,CAAC,CAAC,CAAC;;AAEjB,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;MAC1B,OAAO,IAAI,CAAC,CAAC,CAAC;;AAEpB,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;MAC5B,eAAe,OAAO,CAAC,CAAC,CAAC,CAAA;;AAE/B,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;AACrB,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;AACzB,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,AACrB"
}
3 changes: 3 additions & 0 deletions test/samples/ts-decorators-class/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class Category {}
@Entity('tasks', { info: true })
export class Task {}

@Entity('default', { info: true })
export default class Default {}

const u = new User();
const c = new Category();
const t = new Task();
2 changes: 1 addition & 1 deletion test/samples/ts-decorators-expression/expected.ts.map
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"sourcesContent": [
"class Fields {\n\tstatic uuid() {\n\t\treturn function (target: any, propertyKey: string | symbol) {\n\t\t\tObject.defineProperty(target, propertyKey, { value: 'random uuid...', writable: true });\n\t\t};\n\t}\n}\n\nclass User {\n\t@Fields.uuid()\n\tid: string;\n}\n\n@(a ? b : c)\nclass Conditional {}\n\n@(a || b)\nclass Logical {}\n\n@dec\nclass Identifier {}\n\n@a.b.c\nclass Member {}\n\n@a()\nclass Call {}\n\nconst u = new User();\nconsole.log(u.id); // will print \"random uuid...\"\n"
],
"mappings": "AAAA,MAAM,MAAM,CAAC,CAAC;CACb,OAAO,IAAI,GAAG,CAAC;EACd,MAAM,CAAC,UAAU,MAAW,AAAL,EAAE,GAAG,EAAE,WAA4B,AAAjB,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;GAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;EACzF,CAAC,CAAC;CACH,CAAC;AACF,CAAC;;AAED,MAAM,IAAI,CAAC,CAAC;CACX,CAAC,MAAM,CAAC,IAAI,EAAE;CAAA,AACd,EAAE,EAAE,MAAM,CAAC;AACZ,CAAC;;AAED,CAAE,CAAA,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAAC,MACN,WAAW,CAAC,CAAC,CAAC;;AAEpB,CAAE,CAAA,CAAC,IAAI,CAAC,CAAA;AAAC,MACH,OAAO,CAAC,CAAC,CAAC;;AAEhB,CAAC,GAAG;AAAA,MACE,UAAU,CAAC,CAAC,CAAC;;AAEnB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,MACA,MAAM,CAAC,CAAC,CAAC;;AAEf,CAAC,CAAC,EAAE;AAAA,MACE,IAAI,CAAC,CAAC,CAAC;;AAEb,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;;AACrB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,+BAClB"
"mappings": "AAAA,MAAM,MAAM,CAAC,CAAC;CACb,OAAO,IAAI,GAAG,CAAC;EACd,MAAM,CAAC,UAAU,MAAW,AAAL,EAAE,GAAG,EAAE,WAA4B,AAAjB,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;GAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;EACzF,CAAC,CAAC;CACH,CAAC;AACF,CAAC;;AAED,MAAM,IAAI,CAAC,CAAC;CACX,CAAC,MAAM,CAAC,IAAI,EAAE;CACd,EAAE,EAAE,MAAM,CAAC;AACZ,CAAC;;AAED,CAAE,CAAA,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA,AAAC;MACN,WAAW,CAAC,CAAC,CAAC;;AAEpB,CAAE,CAAA,CAAC,IAAI,CAAC,CAAA,AAAC;MACH,OAAO,CAAC,CAAC,CAAC;;AAEhB,CAAC,GAAG;MACE,UAAU,CAAC,CAAC,CAAC;;AAEnB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;MACA,MAAM,CAAC,CAAC,CAAC;;AAEf,CAAC,CAAC,EAAE;MACE,IAAI,CAAC,CAAC,CAAC;;AAEb,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;;AACrB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,+BAClB"
}
2 changes: 1 addition & 1 deletion test/samples/ts-decorators/expected.ts.map
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"sourcesContent": [
"function loggedMethod(headMessage = 'LOG:') {\n\treturn function actualDecorator(originalMethod: any, context: ClassMethodDecoratorContext) {\n\t\tconst methodName = String(context.name);\n\n\t\tfunction replacementMethod(this: any, ...args: any[]) {\n\t\t\tconsole.log(`${headMessage} Entering method '${methodName}'.`);\n\t\t\tconst result = originalMethod.call(this, ...args);\n\t\t\tconsole.log(`${headMessage} Exiting method '${methodName}'.`);\n\t\t\treturn result;\n\t\t}\n\n\t\treturn replacementMethod;\n\t};\n}\n\nclass Person {\n\tname: string;\n\tconstructor(name: string) {\n\t\tthis.name = name;\n\t}\n\n\t@loggedMethod('⚠️')\n\tgreet() {\n\t\tconsole.log(`Hello, my name is ${this.name}.`);\n\t}\n}\n\nconst p = new Person('Ron');\np.greet();\n"
],
"mappings": "AAAA,SAAS,YAAY,CAAC,WAAW,GAAG,MAAM,EAAE,CAAC;CAC5C,MAAM,CAAC,SAAS,eAAe,CAAC,cAAmB,AAAL,EAAE,GAAG,EAAE,OAAoC,AAA7B,EAAE,2BAA2B,EAAE,CAAC;EAC3F,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;;EAExC,SAAS,iBAAiB,CAAC,IAAS,AAAL,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;GACtD,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,qBAAqB,UAAU,IAAI,CAAC,CAAC;;GAC/D,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;;GAClD,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,oBAAoB,UAAU,IAAI,CAAC,CAAC;;GAC9D,MAAM,CAAC,MAAM,CAAC;EACf,CAAC;;EAED,MAAM,CAAC,iBAAiB,CAAC;CAC1B,CAAC,CAAC;AACH,CAAC;;AAED,MAAM,MAAM,CAAC,CAAC;CACb,IAAI,EAAE,MAAM,CAAC;;CACb,WAAW,CAAC,IAAY,AAAR,EAAE,MAAM,EAAE,CAAC;EAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;CAClB,CAAC;;CAED,CAAC,YAAY,CAAC,IAAI,CAAC;CAAA,AACnB,KAAK,GAAG,CAAC;EACR,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;CAChD,CAAC;AACF,CAAC;;AAED,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;;AAC5B,CAAC,CAAC,KAAK,EAAE,CAAC,AACV"
"mappings": "AAAA,SAAS,YAAY,CAAC,WAAW,GAAG,MAAM,EAAE,CAAC;CAC5C,MAAM,CAAC,SAAS,eAAe,CAAC,cAAmB,AAAL,EAAE,GAAG,EAAE,OAAoC,AAA7B,EAAE,2BAA2B,EAAE,CAAC;EAC3F,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;;EAExC,SAAS,iBAAiB,CAAC,IAAS,AAAL,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;GACtD,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,qBAAqB,UAAU,IAAI,CAAC,CAAC;;GAC/D,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;;GAClD,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,oBAAoB,UAAU,IAAI,CAAC,CAAC;;GAC9D,MAAM,CAAC,MAAM,CAAC;EACf,CAAC;;EAED,MAAM,CAAC,iBAAiB,CAAC;CAC1B,CAAC,CAAC;AACH,CAAC;;AAED,MAAM,MAAM,CAAC,CAAC;CACb,IAAI,EAAE,MAAM,CAAC;;CACb,WAAW,CAAC,IAAY,AAAR,EAAE,MAAM,EAAE,CAAC;EAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;CAClB,CAAC;;CAED,CAAC,YAAY,CAAC,IAAI,CAAC;CACnB,KAAK,GAAG,CAAC;EACR,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;CAChD,CAAC;AACF,CAAC;;AAED,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;;AAC5B,CAAC,CAAC,KAAK,EAAE,CAAC,AACV"
}
2 changes: 1 addition & 1 deletion test/samples/ts-parameter-decorators/expected.ts.map
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"sourcesContent": [
"class Controller {\n\tconstructor(\n\t\t@Inject(CONFIG) private readonly config: Config,\n\t\t@Optional() @Inject(LOGGER) protected logger?: Logger,\n\t\t@Inject(CACHE) public cache = new Map(),\n\t\t@Self() service: Service\n\t) {}\n\n\tfind(@Param('id') id: string, @Query() { limit, offset }: Paging, @Body() [first]: Item[]) {}\n\n\tupdate(\n\t\t@Param('id') id: string,\n\t\t@Body(validation.pipe) body: Item,\n\t\t@(flags ?? defaults) force = false\n\t) {}\n}\n"
],
"mappings": "AAAA,MAAM,UAAU,CAAC,CAAC;CACjB,WAAW;EACM,AAAhB,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,MAAc,AAAR,EAAE,MAAM;EACnB,AAA5B,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,MAAe,CAAR,EAAE,MAAM;EACtC,AAAf,CAAC,MAAM,CAAC,KAAK,CAAC,QAAC,AAAO,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE;EACvC,CAAC,IAAI,EAAE,CAAC,OAAgB,AAAT,EAAE,OAAO;GACvB,CAAC,CAAC;;CAEJ,IAAI;EAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAU,AAAR,EAAE,MAAM;EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM;EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE;GAAE,CAAC,CAAC;;CAE7F,MAAM;EACL,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAU,AAAR,EAAE,MAAM;EACvB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAU,AAAN,EAAE,IAAI;EACjC,CAAE,CAAA,KAAK,IAAI,QAAQ,CAAA,AAAC,CAAC,KAAK,GAAG,KAAK;GACjC,CAAC,CAAC;AACL,CAAC,AACD"
"mappings": "AAAA,MAAM,UAAU,CAAC,CAAC;CACjB,WAAW;EACV,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,iBAAiB,MAAc,AAAR,EAAE,MAAM;EAC/C,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,MAAe,CAAR,EAAE,MAAM;EACrD,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAA,AAAO,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE;EACvC,CAAC,IAAI,EAAE,CAAC,OAAgB,AAAT,EAAE,OAAO;GACvB,CAAC,CAAC;;CAEJ,IAAI;EAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAU,AAAR,EAAE,MAAM;EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM;EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE;GAAE,CAAC,CAAC;;CAE7F,MAAM;EACL,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAU,AAAR,EAAE,MAAM;EACvB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAU,AAAN,EAAE,IAAI;EACjC,CAAE,CAAA,KAAK,IAAI,QAAQ,CAAA,AAAC,CAAC,KAAK,GAAG,KAAK;GACjC,CAAC,CAAC;AACL,CAAC,AACD"
}
Loading