var recordLastSourceRange = function () { if (lastRange && lastRangeStartNode && lastRangeEndNode) { if (lastRangeStartNode == lastRangeEndNode) { ts.setSourceMapRange(lastRangeEndNode, lastRange); } else { ts.setSourceMapRange(lastRangeStartNode, lastRange); // Only emit the pos for the first node emitted in the range. ts.setEmitFlags(lastRangeStartNode, ts.EmitFlags.NoTrailingSourceMap); ts.setSourceMapRange(lastRangeEndNode, lastRange); // Only emit emit end for the last node emitted in the range. ts.setEmitFlags(lastRangeEndNode, ts.EmitFlags.NoLeadingSourceMap); } } };
function resetTextRange(node) { if (!(node.flags & ts.NodeFlags.Synthesized)) { // need to clone as we don't want to modify source nodes, // as the parsed SourceFiles could be cached! node = ts.getMutableClone(node); } var textRange = { pos: node.pos, end: node.end }; ts.setSourceMapRange(node, textRange); ts.setTextRange(node, { pos: -1, end: -1 }); return node; }
function visitor(node) { if (ts.isIdentifier(node) && node.text === 'a') { var newNode = ts.createIdentifier('b'); ts.setSourceMapRange(newNode, { pos: 16, end: 16, source: ts.createSourceMapSource('test.html', 'abc\ndef\nghi\njkl\nmno\npqr') }); return newNode; } return ts.visitEachChild(node, visitor, context); }
function visitNode(node) { if (node.kind === ts.SyntaxKind.Identifier) { var parent1 = fileContext.syntheticNodeParents.get(node); var parent2 = parent1 && fileContext.syntheticNodeParents.get(parent1); var parent3 = parent2 && fileContext.syntheticNodeParents.get(parent2); if (parent1 && parent1.kind === ts.SyntaxKind.PropertyDeclaration) { // TypeScript ignores synthetic comments on (static) property declarations // with initializers. // find the parent ExpressionStatement like MyClass.foo = ... var expressionStmt = lastNodeWith(nodePath, function (node) { return node.kind === ts.SyntaxKind.ExpressionStatement; }); if (expressionStmt) { ts.setSyntheticLeadingComments(expressionStmt, ts.getSyntheticLeadingComments(parent1) || []); } } else if (parent3 && parent3.kind === ts.SyntaxKind.VariableStatement && tsickle.hasModifierFlag(parent3, ts.ModifierFlags.Export)) { // TypeScript ignores synthetic comments on exported variables. // find the parent ExpressionStatement like exports.foo = ... var expressionStmt = lastNodeWith(nodePath, function (node) { return node.kind === ts.SyntaxKind.ExpressionStatement; }); if (expressionStmt) { ts.setSyntheticLeadingComments(expressionStmt, ts.getSyntheticLeadingComments(parent3) || []); } } } // TypeScript ignores synthetic comments on reexport / import statements. var moduleName = extractModuleNameFromRequireVariableStatement(node); if (moduleName && fileContext.importOrReexportDeclarations) { // Locate the original import/export declaration via the // text range. var importOrReexportDeclaration = fileContext.importOrReexportDeclarations.find(function (ied) { return ied.pos === node.pos; }); if (importOrReexportDeclaration) { ts.setSyntheticLeadingComments(node, ts.getSyntheticLeadingComments(importOrReexportDeclaration) || []); } // Need to clear the textRange for ImportDeclaration / ExportDeclaration as // otherwise TypeScript would emit the original comments even if we set the // ts.EmitFlag.NoComments. (see also resetNodeTextRangeToPreventDuplicateComments below) ts.setSourceMapRange(node, { pos: node.pos, end: node.end }); ts.setTextRange(node, { pos: -1, end: -1 }); } nodePath.push(node); node.forEachChild(visitNode); nodePath.pop(); }