function setFileOverviewComment(sf, fileoverview) {
     var comments = fileoverview.comments, host = fileoverview.host, trailing = fileoverview.trailing;
     // If host statement is no longer the first one, it means that extra statements were added at the
     // very beginning, so we need to relocate @fileoverview comment and cleanup the original statement
     // that hosted it.
     if (sf.statements.length > 0 && host !== sf.statements[0]) {
         if (trailing) {
             ts.setSyntheticTrailingComments(host, undefined);
         }
         else {
             ts.setSyntheticLeadingComments(host, undefined);
         }
         ts.setSyntheticLeadingComments(sf.statements[0], comments);
     }
 }
Exemple #2
0
 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();
 }
Exemple #3
0
/**
 * Reads in the leading comment text ranges of the given node,
 * converts them into `ts.SyntheticComment`s and stores them on the node.
 *
 * Note: This would be greatly simplified with https://github.com/Microsoft/TypeScript/issues/17615.
 *
 * @param lastCommentEnd The end of the last comment
 * @return The end of the last found comment, -1 if no comment was found.
 */
function synthesizeLeadingComments(sourceFile, node, lastCommentEnd) {
    var parent = node.parent;
    var sharesStartWithParent = parent && parent.kind !== ts.SyntaxKind.Block &&
        parent.kind !== ts.SyntaxKind.SourceFile && parent.getFullStart() === node.getFullStart();
    if (sharesStartWithParent || lastCommentEnd >= node.getStart()) {
        return -1;
    }
    var adjustedNodeFullStart = Math.max(lastCommentEnd, node.getFullStart());
    var leadingComments = getAllLeadingCommentRanges(sourceFile, adjustedNodeFullStart, node.getStart());
    if (leadingComments && leadingComments.length) {
        ts.setSyntheticLeadingComments(node, synthesizeCommentRanges(sourceFile, leadingComments));
        return node.getStart();
    }
    return -1;
}
Exemple #4
0
/**
 * Convert trailing detached comment ranges of statement arrays
 * (e.g. the statements of a ts.SourceFile or ts.Block) into a
 * `ts.NonEmittedStatement` with `ts.SynthesizedComment`s.
 *
 * A Detached trailing comment are all comments after the first newline
 * the follows the last statement in a SourceFile / Block.
 *
 * Note: This would be greatly simplified with https://github.com/Microsoft/TypeScript/issues/17615.
 */
function synthesizeDetachedTrailingComments(sourceFile, node, statements) {
    var trailingCommentStart = statements.end;
    if (statements.length) {
        var lastStmt = statements[statements.length - 1];
        var lastStmtTrailingComments = ts.getTrailingCommentRanges(sourceFile.text, lastStmt.end);
        if (lastStmtTrailingComments && lastStmtTrailingComments.length) {
            trailingCommentStart = lastStmtTrailingComments[lastStmtTrailingComments.length - 1].end;
        }
    }
    var detachedComments = getAllLeadingCommentRanges(sourceFile, trailingCommentStart, node.end);
    if (!detachedComments || !detachedComments.length) {
        return { commentStmt: null, lastCommentEnd: -1 };
    }
    var lastCommentEnd = detachedComments[detachedComments.length - 1].end;
    var commentStmt = createNotEmittedStatement(sourceFile);
    ts.setEmitFlags(commentStmt, ts.EmitFlags.CustomPrologue);
    ts.setSyntheticLeadingComments(commentStmt, synthesizeCommentRanges(sourceFile, detachedComments));
    return { commentStmt: commentStmt, lastCommentEnd: lastCommentEnd };
}
 TypeScriptNodeEmitter.prototype.updateSourceFile = function (sourceFile, stmts, preamble) {
     var converter = new _NodeEmitterVisitor();
     // [].concat flattens the result so that each `visit...` method can also return an array of
     // stmts.
     var statements = [].concat.apply([], stmts.map(function (stmt) { return stmt.visitStatement(converter, null); }).filter(function (stmt) { return stmt != null; }));
     var preambleStmts = [];
     if (preamble) {
         if (preamble.startsWith('/*') && preamble.endsWith('*/')) {
             preamble = preamble.substr(2, preamble.length - 4);
         }
         var commentStmt = ts.createNotEmittedStatement(sourceFile);
         ts.setSyntheticLeadingComments(commentStmt, [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: preamble, pos: -1, end: -1 }]);
         ts.setEmitFlags(commentStmt, ts.EmitFlags.CustomPrologue);
         preambleStmts.push(commentStmt);
     }
     var sourceStatments = preambleStmts.concat(converter.getReexports(), converter.getImports(), statements);
     converter.updateSourceMap(sourceStatments);
     var newSourceFile = ts.updateSourceFileNode(sourceFile, sourceStatments);
     return [newSourceFile, converter.getNodeMap()];
 };