From 65d1079f8f10ae2b070fe5a54b942f8afc045ee5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:15:59 -0700 Subject: [PATCH 1/9] Replace services' jsdoc parser with parsers' Also modify scanner's definition of leading vs trailing comments, with associated changes to emitter and emit baselines (the last is in a separate commit). --- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 3 +- src/compiler/emitter.ts | 82 ++- src/compiler/parser.ts | 411 ++++++++++----- src/compiler/scanner.ts | 67 ++- src/compiler/types.ts | 12 +- src/compiler/utilities.ts | 158 ++++-- src/harness/unittests/jsDocParsing.ts | 726 +++++++++++++++++--------- src/services/services.ts | 402 ++------------ src/services/utilities.ts | 10 +- 10 files changed, 1049 insertions(+), 828 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d8017d601adb0..d28df13655f15 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -262,7 +262,7 @@ namespace ts { Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType); let functionType = node.parent; let index = indexOf(functionType.parameters, node); - return "p" + index; + return "arg" + index; case SyntaxKind.JSDocTypedefTag: const parentNode = node.parent && node.parent.parent; let nameFromParentNode: string; @@ -517,9 +517,7 @@ namespace ts { // because the scope of JsDocComment should not be affected by whether the current node is a // container or not. if (isInJavaScriptFile(node) && node.jsDocComments) { - for (const jsDocComment of node.jsDocComments) { - bind(jsDocComment); - } + forEach(node.jsDocComments, bind); } if (checkUnreachable(node)) { forEachChild(node, bind); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 863c9e7c37aab..b620904326207 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5629,12 +5629,13 @@ namespace ts { case SyntaxKind.JSDocThisType: case SyntaxKind.JSDocOptionalType: return getTypeFromTypeNode((node).type); + case SyntaxKind.JSDocRecordType: + return getTypeFromTypeNode((node as JSDocRecordType).literal); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.TypeLiteral: case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocFunctionType: - case SyntaxKind.JSDocRecordType: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node, aliasSymbol, aliasTypeArguments); // This function assumes that an identifier or qualified name is a type expression // Callers should first ensure this by calling isTypeNode diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f02cf2667444b..ce8d8e44d394b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -851,7 +851,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean) { + function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean, commentsBeforePunctuation: boolean) { Debug.assert(nodes.length > 0); increaseIndent(); @@ -877,6 +877,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(nodes[i]); + if (commentsBeforePunctuation) { + emitLeadingCommentsAtEnd(nodes[i]); + } } if (nodes.hasTrailingComma && allowTrailingComma) { @@ -895,7 +898,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, emitNode?: (node: TNode) => void): number { + function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, commentsBeforePunctuation?: boolean, emitNode?: (node: TNode) => void): number { if (!emitNode) { emitNode = emit; } @@ -913,13 +916,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } const node = nodes[start + i]; - // This emitting is to make sure we emit following comment properly - // ...(x, /*comment1*/ y)... - // ^ => node.pos - // "comment1" is not considered leading comment for "y" but rather - // considered as trailing comment of the previous node. - emitTrailingCommentsOfPosition(node.pos); emitNode(node); + if (commentsBeforePunctuation) { + emitLeadingCommentsAtEnd(nodes[i]); + } leadingComma = true; } if (trailingComma) { @@ -1897,7 +1897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) { write("["); - emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false); + emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false, /*commentsBeforePunctuation*/ true); write("]"); } else { @@ -1921,7 +1921,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // then try to preserve the original shape of the object literal. // Otherwise just try to preserve the formatting. if (numElements === properties.length) { - emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true); + emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true, /*commentsBeforePunctuation*/ true); } else { const multiLine = node.multiLine; @@ -2166,14 +2166,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitPropertyAssignment(node: PropertyDeclaration) { emit(node.name); write(": "); - // This is to ensure that we emit comment in the following case: - // For example: - // obj = { - // id: /*comment1*/ ()=>void - // } - // "comment1" is not considered to be leading comment for node.initializer - // but rather a trailing comment on the previous node. - emitTrailingCommentsOfPosition(node.initializer.pos); emit(node.initializer); } @@ -2285,6 +2277,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(node.expression); + emitLeadingCommentsAtEnd(node.expression); const dotRangeStart = nodeIsSynthesized(node.expression) ? -1 : node.expression.end; const dotRangeEnd = nodeIsSynthesized(node.expression) ? -1 : skipTrivia(currentText, node.expression.end) + 1; const dotToken = { pos: dotRangeStart, end: dotRangeEnd }; @@ -2501,13 +2494,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitThis(expression); if (node.arguments.length) { write(", "); + emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); + emitLeadingCommentsAtEnd(node.arguments); } write(")"); } else { write("("); + emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); + emitLeadingCommentsAtEnd(node.arguments); write(")"); } } @@ -2608,6 +2605,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write("("); emit(node.expression); + emitLeadingCommentsAtEnd(node.expression); write(")"); } @@ -2886,6 +2884,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else { emit(node.left); + emitLeadingCommentsAtEnd(node.left); // Add indentation before emit the operator if the operator is on different line // For example: // 3 @@ -3898,6 +3897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emitNodeWithCommentsAndWithoutSourcemap(node.name); emitEnd(node.name); + emitLeadingCommentsAtEnd(node.name); } function createVoidZero(): Expression { @@ -4040,6 +4040,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emit(name); } + emitLeadingCommentsAtEnd(name); write(" = "); emit(value); }); @@ -4591,6 +4592,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitStart(restParam); write("var "); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); + emitLeadingCommentsAtEnd(restParam.name); write(" = [];"); emitEnd(restParam); emitTrailingComments(restParam); @@ -4612,6 +4614,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge writeLine(); emitStart(restParam); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); + emitLeadingCommentsAtEnd(restParam.name); write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];"); emitEnd(restParam); decreaseIndent(); @@ -4633,6 +4636,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitDeclarationName(node: Declaration) { if (node.name) { emitNodeWithCommentsAndWithoutSourcemap(node.name); + emitLeadingCommentsAtEnd(node.name); } else { write(getGeneratedNameForNode(node)); @@ -4660,6 +4664,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const { kind, parent } = node; if (kind !== SyntaxKind.MethodDeclaration && kind !== SyntaxKind.MethodSignature && + kind !== SyntaxKind.ArrowFunction && parent && parent.kind !== SyntaxKind.PropertyAssignment && parent.kind !== SyntaxKind.CallExpression && @@ -4734,7 +4739,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const parameters = node.parameters; const skipCount = node.parameters.length && (node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0; const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0; - emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false); + emitTrailingCommentsOfPosition(node.parameters.pos); + emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ false, /*commentsBeforePunctuation*/ true); + if ((parameters.length - omitCount - skipCount) <= 0) { + emitLeadingCommentsAtEnd(node.parameters); + } } write(")"); decreaseIndent(); @@ -5791,7 +5800,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => emit(decorator.expression)); if (firstParameterDecorator) { argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0); @@ -5891,7 +5900,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => emit(decorator.expression)); if (firstParameterDecorator) { @@ -5933,7 +5942,7 @@ const _super = (function (geti, seti) { for (const parameter of node.parameters) { if (nodeIsDecorated(parameter)) { const decorators = parameter.decorators; - argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, decorator => { + argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => { write(`__param(${parameterIndex}, `); emit(decorator.expression); write(")"); @@ -6347,6 +6356,7 @@ const _super = (function (geti, seti) { emitExpressionForPropertyName(node.name); emitEnd(node); write(";"); + emitLeadingCommentsAtEnd(node.name); } function writeEnumMemberDeclarationValue(member: EnumMember) { @@ -8288,7 +8298,11 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); + // However, a leading mid-line comment of the end of file token is emitted with spaces before, + // as if it were a trailing comment of the previous token + const commentStartsInMidLine = leadingComments && leadingComments.length && leadingComments[0].pos - 1 > 0 && currentText.charCodeAt(leadingComments[0].pos - 1) !== 10; + const isEndOfFile = node.kind === SyntaxKind.EndOfFileToken && commentStartsInMidLine; + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ !isEndOfFile, newLine, writeComment); } function emitTrailingComments(node: Node) { @@ -8305,8 +8319,11 @@ const _super = (function (geti, seti) { /** * Emit trailing comments at the position. The term trailing comment is used here to describe following comment: - * x, /comment1/ y - * ^ => pos; the function will emit "comment1" in the emitJS + * x, /*comment1* / // comment2 + * ^ => pos; the function will emit "comment1" and "comment2" in the emitJS + * However, + * x /*comment1* /, y + * 'comment1' is actually a leading comment of ',' and needs to be emitted using emitLeadingCommentsAtEnd */ function emitTrailingCommentsOfPosition(pos: number) { if (compilerOptions.removeComments) { @@ -8319,7 +8336,18 @@ const _super = (function (geti, seti) { emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment); } - function emitLeadingCommentsOfPositionWorker(pos: number) { + /** + * Emit leading comments for the token after the current token. + * This is only needed for punctuation tokens. For example, in + * x /*comment1* /, y + * 'comment1' is a leading comment of ',' but needs to be emitted + * from x because there is no token for ','. + */ + function emitLeadingCommentsAtEnd(node: Node | NodeArray) { + emitLeadingCommentsOfPositionWorker(node.end, /*trailingSeparator*/ false); + } + + function emitLeadingCommentsOfPositionWorker(pos: number, trailingSeparator = true) { if (compilerOptions.removeComments) { return; } @@ -8337,7 +8365,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, trailingSeparator, newLine, writeComment); } function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b28f13e438f74..342b711a5a6a7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -378,7 +378,7 @@ namespace ts { case SyntaxKind.JSDocNullableType: return visitNode(cbNode, (node).type); case SyntaxKind.JSDocRecordType: - return visitNodes(cbNodes, (node).members); + return visitNode(cbNode, (node).literal); case SyntaxKind.JSDocTypeReference: return visitNode(cbNode, (node).name) || visitNodes(cbNodes, (node).typeArguments); @@ -397,7 +397,7 @@ namespace ts { return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).type); case SyntaxKind.JSDocComment: - return visitNodes(cbNodes, (node).tags); + return visitNodes(cbNodes, (node).tags); case SyntaxKind.JSDocParameterTag: return visitNode(cbNode, (node).preParameterName) || visitNode(cbNode, (node).typeExpression) || @@ -450,10 +450,10 @@ namespace ts { /* @internal */ export function parseIsolatedJSDocComment(content: string, start?: number, length?: number) { const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); - if (result && result.jsDocComment) { + if (result && result.jsDoc) { // because the jsDocComment was parsed out of the source file, it might // not be covered by the fixupParentReferences. - Parser.fixupParentReferences(result.jsDocComment); + Parser.fixupParentReferences(result.jsDoc); } return result; @@ -652,20 +652,18 @@ namespace ts { function addJSDocComment(node: T): T { - if (contextFlags & NodeFlags.JavaScriptFile) { - const comments = getLeadingCommentRangesOfNode(node, sourceFile); - if (comments) { - for (const comment of comments) { - const jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (!jsDocComment) { - continue; - } + const comments = getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (const comment of comments) { + const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (!jsDoc) { + continue; + } - if (!node.jsDocComments) { - node.jsDocComments = []; - } - node.jsDocComments.push(jsDocComment); + if (!node.jsDocComments) { + node.jsDocComments = []; } + node.jsDocComments.push(jsDoc); } } @@ -2201,7 +2199,7 @@ namespace ts { } fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node); parseTypeMemberSemicolon(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function isIndexSignature(): boolean { @@ -2291,7 +2289,7 @@ namespace ts { // [Yield] nor [Await] fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, method); parseTypeMemberSemicolon(); - return finishNode(method); + return addJSDocComment(finishNode(method)); } else { const property = createNode(SyntaxKind.PropertySignature, fullStart); @@ -2308,7 +2306,7 @@ namespace ts { } parseTypeMemberSemicolon(); - return finishNode(property); + return addJSDocComment(finishNode(property)); } } @@ -2897,7 +2895,7 @@ namespace ts { node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>"); node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function tryParseParenthesizedArrowFunctionExpression(): Expression { @@ -2930,7 +2928,7 @@ namespace ts { ? parseArrowFunctionExpressionBody(isAsync) : parseIdentifier(); - return finishNode(arrowFunction); + return addJSDocComment(finishNode(arrowFunction)); } // True -> We definitely expect a parenthesized arrow function here. @@ -4114,7 +4112,7 @@ namespace ts { function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): AccessorDeclaration { if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return addJSDocComment(parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers)); + return parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers); } else if (parseContextualModifier(SyntaxKind.SetKeyword)) { return parseAccessorDeclaration(SyntaxKind.SetAccessor, fullStart, decorators, modifiers); @@ -4993,7 +4991,7 @@ namespace ts { : doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseNonParameterInitializer); parseSemicolon(); - return finishNode(property); + return addJSDocComment(finishNode(property)); } function parsePropertyOrMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ClassElement { @@ -5022,7 +5020,7 @@ namespace ts { node.name = parsePropertyName(); fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node); node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function isClassMemberModifier(idToken: SyntaxKind) { @@ -5265,7 +5263,7 @@ namespace ts { node.members = createMissingList(); } - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseNameOfClassDeclarationOrExpression(): Identifier { @@ -5333,7 +5331,7 @@ namespace ts { node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false); node.members = parseObjectTypeMembers(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseTypeAliasDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): TypeAliasDeclaration { @@ -5357,7 +5355,7 @@ namespace ts { const node = createNode(SyntaxKind.EnumMember, scanner.getStartPos()); node.name = parsePropertyName(); node.initializer = allowInAnd(parseNonParameterInitializer); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseEnumDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): EnumDeclaration { @@ -5373,7 +5371,7 @@ namespace ts { else { node.members = createMissingList(); } - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseModuleBlock(): ModuleBlock { @@ -5400,7 +5398,7 @@ namespace ts { node.body = parseOptional(SyntaxKind.DotToken) ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.Export | namespaceFlag) : parseModuleBlock(); - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseAmbientExternalModuleDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ModuleDeclaration { @@ -5489,7 +5487,7 @@ namespace ts { parseExpected(SyntaxKind.EqualsToken); importEqualsDeclaration.moduleReference = parseModuleReference(); parseSemicolon(); - return finishNode(importEqualsDeclaration); + return addJSDocComment(finishNode(importEqualsDeclaration)); } } @@ -5810,6 +5808,7 @@ namespace ts { export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) { initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); + sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS); scanner.setText(content, start, length); currentToken = scanner.scan(); const jsDocTypeExpression = parseJSDocTypeExpression(); @@ -6028,22 +6027,7 @@ namespace ts { function parseJSDocRecordType(): JSDocRecordType { const result = createNode(SyntaxKind.JSDocRecordType); - nextToken(); - result.members = parseDelimitedList(ParsingContext.JSDocRecordMembers, parseJSDocRecordMember); - checkForTrailingComma(result.members); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(result); - } - - function parseJSDocRecordMember(): JSDocRecordMember { - const result = createNode(SyntaxKind.JSDocRecordMember); - result.name = parseSimplePropertyName(); - - if (token() === SyntaxKind.ColonToken) { - nextToken(); - result.type = parseJSDocType(); - } - + result.literal = parseTypeLiteral(); return finishNode(result); } @@ -6143,14 +6127,14 @@ namespace ts { export function parseIsolatedJSDocComment(content: string, start: number, length: number) { initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; - const jsDocComment = parseJSDocCommentWorker(start, length); + const jsDoc = parseJSDocCommentWorker(start, length); const diagnostics = parseDiagnostics; clearState(); - return jsDocComment ? { jsDocComment, diagnostics } : undefined; + return jsDoc ? { jsDoc, diagnostics } : undefined; } - export function parseJSDocComment(parent: Node, start: number, length: number): JSDocComment { + export function parseJSDocComment(parent: Node, start: number, length: number): JSDoc { const saveToken = currentToken; const saveParseDiagnosticsLength = parseDiagnostics.length; const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; @@ -6167,7 +6151,7 @@ namespace ts { return comment; } - export function parseJSDocCommentWorker(start: number, length: number): JSDocComment { + export function parseJSDocCommentWorker(start: number, length: number): JSDoc { const content = sourceText; start = start || 0; const end = length === undefined ? content.length : start + length; @@ -6178,76 +6162,145 @@ namespace ts { Debug.assert(end <= content.length); let tags: NodeArray; - let result: JSDocComment; + const comments: string[] = []; + let result: JSDoc; // Check for /** (JSDoc opening part) - if (content.charCodeAt(start) === CharacterCodes.slash && - content.charCodeAt(start + 1) === CharacterCodes.asterisk && - content.charCodeAt(start + 2) === CharacterCodes.asterisk && - content.charCodeAt(start + 3) !== CharacterCodes.asterisk) { - + if (!isJsDocStart(content, start)) { + return result; + } - // + 3 for leading /**, - 5 in total for /** */ - scanner.scanRange(start + 3, length - 5, () => { - // Initially we can parse out a tag. We also have seen a starting asterisk. - // This is so that /** * @type */ doesn't parse. - let canParseTag = true; - let seenAsterisk = true; + // + 3 for leading /**, - 5 in total for /** */ + scanner.scanRange(start + 3, length - 5, () => { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + let canParseTag = true; + let seenAsterisk = true; + let advanceToken = true; + let margin: number | undefined = undefined; + let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; + let text: string; + nextJSDocToken(); + while (token() === SyntaxKind.WhitespaceTrivia) { nextJSDocToken(); - while (token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { - case SyntaxKind.AtToken: - if (canParseTag) { - parseTag(); - } - // This will take us to the end of the line, so it's OK to parse a tag on the next pass through the loop - seenAsterisk = false; - break; - - case SyntaxKind.NewLineTrivia: - // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet - canParseTag = true; + } + if (token() === SyntaxKind.NewLineTrivia) { + canParseTag = true; + seenAsterisk = false; + nextJSDocToken(); + } + while (token() !== SyntaxKind.EndOfFileToken) { + switch (token()) { + case SyntaxKind.AtToken: + if (canParseTag) { + removeTrailingNewlines(comments); + parseTag(indent); + // This will take us past the end of the line, so it's OK to parse a tag on the next pass through the loop + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. But real-world comments may break this rule. seenAsterisk = false; - break; - - case SyntaxKind.AsteriskToken: - if (seenAsterisk) { - // If we've already seen an asterisk, then we can no longer parse a tag on this line - canParseTag = false; + advanceToken = false; + margin = undefined; + } + else { + comments.push(scanner.getTokenText()); + } + indent++; + break; + + case SyntaxKind.NewLineTrivia: + // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet + comments.push(scanner.getTokenText()); + canParseTag = true; + seenAsterisk = false; + indent = 0; + break; + + case SyntaxKind.AsteriskToken: + text = scanner.getTokenText(); + if (seenAsterisk) { + // If we've already seen an asterisk, then we can no longer parse a tag on this line + canParseTag = false; + comments.push(text); + if (!margin) { + margin = indent; } - // Ignore the first asterisk on a line - seenAsterisk = true; - break; + } + // Ignore the first asterisk on a line + seenAsterisk = true; + indent += text.length; + break; + + case SyntaxKind.Identifier: + // Anything else is doc comment text. We just save it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + text = scanner.getTokenText(); + comments.push(text); + if (!margin) { + margin = indent; + } + canParseTag = false; + indent += text.length; + break; - case SyntaxKind.Identifier: - // Anything else is doc comment text. We can't do anything with it. Because it - // wasn't a tag, we can no longer parse a tag on this line until we hit the next - // line break. - canParseTag = false; - break; - case SyntaxKind.EndOfFileToken: - break; - } + case SyntaxKind.WhitespaceTrivia: + // only collect whitespace if we *know* that we're just looking at comments, not a possible jsdoc tag + text = scanner.getTokenText(); + if (!canParseTag || margin !== undefined && indent + text.length > margin) { + comments.push(text.slice(margin - indent - 1)); + } + indent += text.length; + break; + case SyntaxKind.EndOfFileToken: + break; + + default: + text = scanner.getTokenText(); + comments.push(text); + indent += text.length; + break; + } + if (advanceToken) { nextJSDocToken(); } + else { + advanceToken = true; + } + } + removeLeadingNewlines(comments); + removeTrailingNewlines(comments); + result = createJSDocComment(); - result = createJSDocComment(); - - }); - } + }); return result; - function createJSDocComment(): JSDocComment { - if (!tags) { - return undefined; + function removeLeadingNewlines(comments: string[]) { + while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { + comments.shift(); + } + } + + function removeTrailingNewlines(comments: string[]) { + while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) { + comments.pop(); } + } - const result = createNode(SyntaxKind.JSDocComment, start); + function isJsDocStart(content: string, start: number) { + return content.charCodeAt(start) === CharacterCodes.slash && + content.charCodeAt(start + 1) === CharacterCodes.asterisk && + content.charCodeAt(start + 2) === CharacterCodes.asterisk && + content.charCodeAt(start + 3) !== CharacterCodes.asterisk; + } + + function createJSDocComment(): JSDoc { + const result = createNode(SyntaxKind.JSDocComment, start); result.tags = tags; + result.comment = comments.length ? comments.join("") : undefined; return finishNode(result, end); } @@ -6257,78 +6310,158 @@ namespace ts { } } - function parseTag(): void { + function parseTag(indent: number) { Debug.assert(token() === SyntaxKind.AtToken); const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos()); atToken.end = scanner.getTextPos(); nextJSDocToken(); const tagName = parseJSDocIdentifierName(); + skipWhitespace(); if (!tagName) { return; } - const tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); - addTag(tag); - } - - function handleTag(atToken: Node, tagName: Identifier): JSDocTag { + let tag: JSDocTag; if (tagName) { switch (tagName.text) { case "param": - return handleParamTag(atToken, tagName); + tag = parseParamTag(atToken, tagName); + break; case "return": case "returns": - return handleReturnTag(atToken, tagName); + tag = parseReturnTag(atToken, tagName); + break; case "template": - return handleTemplateTag(atToken, tagName); + tag = parseTemplateTag(atToken, tagName); + break; case "type": - return handleTypeTag(atToken, tagName); + tag = parseTypeTag(atToken, tagName); + break; case "typedef": - return handleTypedefTag(atToken, tagName); + tag = parseTypedefTag(atToken, tagName); + break; + default: + tag = parseUnknownTag(atToken, tagName); + break; } } + else { + tag = parseUnknownTag(atToken, tagName); + } - return undefined; + if (!tag) { + // a badly malformed tag should not be added to the list of tags + return; + } + addTag(tag, parseTagComments(indent + tag.end - tag.pos)); + } + + function parseTagComments(indent: number) { + const comments: string[] = []; + let savingComments = false; + let seenAsterisk = true; + let done = false; + let margin: number | undefined; + let text: string; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } + while (!done && token() !== SyntaxKind.EndOfFileToken) { + text = scanner.getTokenText(); + switch (token()) { + case SyntaxKind.NewLineTrivia: + if (seenAsterisk) { + savingComments = false; + seenAsterisk = false; + comments.push(text); + } + indent = 0; + break; + case SyntaxKind.AtToken: + done = true; + break; + case SyntaxKind.WhitespaceTrivia: + if (savingComments && seenAsterisk) { + pushComment(text); + } + else { + // if the whitespace crosses the margin, take only the whitespace that passes the margin + if (margin !== undefined && indent + text.length > margin) { + comments.push(text.slice(margin - indent - 1)); + } + indent += text.length; + } + break; + case SyntaxKind.AsteriskToken: + if (!seenAsterisk) { + // leading asterisks start recording on the *next* (non-whitespace) token + savingComments = false; + indent += text.length; + } + // FALLTHROUGH to gather comments + default: + if (seenAsterisk) { + savingComments = true; // leading identifiers start recording as well + pushComment(text); + } + seenAsterisk = true; + break; + } + if (!done) { + nextJSDocToken(); + } + } + + removeLeadingNewlines(comments); + removeTrailingNewlines(comments); + return comments; } - function handleUnknownTag(atToken: Node, tagName: Identifier) { + function parseUnknownTag(atToken: Node, tagName: Identifier) { const result = createNode(SyntaxKind.JSDocTag, atToken.pos); result.atToken = atToken; result.tagName = tagName; return finishNode(result); } - function addTag(tag: JSDocTag): void { - if (tag) { - if (!tags) { - tags = >[]; - tags.pos = tag.pos; - } + function addTag(tag: JSDocTag, comments: string[]): void { + tag.comment = comments.join(""); - tags.push(tag); - tags.end = tag.end; + if (!tags) { + tags = >[]; + tags.pos = tag.pos; } + + tags.push(tag); + tags.end = tag.end; } function tryParseTypeExpression(): JSDocTypeExpression { - if (token() !== SyntaxKind.OpenBraceToken) { - return undefined; - } + return tryParse(() => { + skipWhitespace(); + if (token() !== SyntaxKind.OpenBraceToken) { + return undefined; + } - const typeExpression = parseJSDocTypeExpression(); - return typeExpression; + return parseJSDocTypeExpression(); + }); } - function handleParamTag(atToken: Node, tagName: Identifier) { + function parseParamTag(atToken: Node, tagName: Identifier) { let typeExpression = tryParseTypeExpression(); - skipWhitespace(); + let name: Identifier; let isBracketed: boolean; // Looking for something like '[foo]' or 'foo' if (parseOptionalToken(SyntaxKind.OpenBracketToken)) { name = parseJSDocIdentifierName(); + skipWhitespace(); isBracketed = true; // May have an optional default, e.g. '[foo = 42]' @@ -6365,11 +6498,12 @@ namespace ts { result.preParameterName = preName; result.typeExpression = typeExpression; result.postParameterName = postName; + result.parameterName = postName || preName; result.isBracketed = isBracketed; return finishNode(result); } - function handleReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag { + function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6381,7 +6515,7 @@ namespace ts { return finishNode(result); } - function handleTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag { + function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6393,10 +6527,11 @@ namespace ts { return finishNode(result); } - function handlePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { + function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); const name = parseJSDocIdentifierName(); + skipWhitespace(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), /*length*/ 0, Diagnostics.Identifier_expected); return undefined; @@ -6410,7 +6545,7 @@ namespace ts { return finishNode(result); } - function handleTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { + function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); @@ -6419,6 +6554,7 @@ namespace ts { typedefTag.tagName = tagName; typedefTag.name = parseJSDocIdentifierName(); typedefTag.typeExpression = typeExpression; + skipWhitespace(); if (typeExpression) { if (typeExpression.type.kind === SyntaxKind.JSDocTypeReference) { @@ -6488,6 +6624,7 @@ namespace ts { nextJSDocToken(); const tagName = parseJSDocIdentifierName(); + skipWhitespace(); if (!tagName) { return false; } @@ -6498,21 +6635,21 @@ namespace ts { // already has a @type tag, terminate the parent tag now. return false; } - parentTag.jsDocTypeTag = handleTypeTag(atToken, tagName); + parentTag.jsDocTypeTag = parseTypeTag(atToken, tagName); return true; case "prop": case "property": if (!parentTag.jsDocPropertyTags) { parentTag.jsDocPropertyTags = >[]; } - const propertyTag = handlePropertyTag(atToken, tagName); + const propertyTag = parsePropertyTag(atToken, tagName); parentTag.jsDocPropertyTags.push(propertyTag); return true; } return false; } - function handleTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { + function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6523,6 +6660,7 @@ namespace ts { while (true) { const name = parseJSDocIdentifierName(); + skipWhitespace(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); return undefined; @@ -6536,6 +6674,7 @@ namespace ts { if (token() === SyntaxKind.CommaToken) { nextJSDocToken(); + skipWhitespace(); } else { break; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c1431ca23ed50..d8cfc39db87ba 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -599,10 +599,11 @@ namespace ts { * If false, whitespace is skipped until the first line break and comments between that location * and the next token are returned. * If true, comments occurring between the given position and the next line break are returned. + * If there is no line break, then no comments are returned. */ function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] { let result: CommentRange[]; - let collecting = trailing || pos === 0; + let needToSkipTrailingComment = pos > 0; while (pos < text.length) { const ch = text.charCodeAt(pos); switch (ch) { @@ -615,7 +616,11 @@ namespace ts { if (trailing) { return result; } - collecting = true; + else if (needToSkipTrailingComment) { + // skip the first line if not trailing (it'll be part of the trailing comment). + needToSkipTrailingComment = false; + result = undefined; + } if (result && result.length) { lastOrUndefined(result).hasTrailingNewLine = true; } @@ -651,11 +656,13 @@ namespace ts { pos++; } } - if (collecting) { + + // if we are at the end of the file, don't add trailing comments. + // end-of-file comments are added as leading comment of the end-of-file token. + if (pos < text.length || !trailing) { if (!result) { result = []; } - result.push({ pos: startPos, end: pos, hasTrailingNewLine, kind }); } continue; @@ -671,10 +678,10 @@ namespace ts { } break; } - return result; + return !trailing ? result : undefined; } - return result; + return !trailing ? result : undefined; } export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] { @@ -1689,40 +1696,46 @@ namespace ts { } startPos = pos; - - // Eat leading whitespace - let ch = text.charCodeAt(pos); - while (pos < end) { - ch = text.charCodeAt(pos); - if (isWhiteSpaceSingleLine(ch)) { - pos++; - } - else { - break; - } - } tokenPos = pos; + const ch = text.charCodeAt(pos); switch (ch) { + case CharacterCodes.tab: + case CharacterCodes.verticalTab: + case CharacterCodes.formFeed: + case CharacterCodes.space: + while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { + pos++; + } + return token = SyntaxKind.WhitespaceTrivia; case CharacterCodes.at: - return pos += 1, token = SyntaxKind.AtToken; + pos++; + return token = SyntaxKind.AtToken; case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: - return pos += 1, token = SyntaxKind.NewLineTrivia; + pos++; + return token = SyntaxKind.NewLineTrivia; case CharacterCodes.asterisk: - return pos += 1, token = SyntaxKind.AsteriskToken; + pos++; + return token = SyntaxKind.AsteriskToken; case CharacterCodes.openBrace: - return pos += 1, token = SyntaxKind.OpenBraceToken; + pos++; + return token = SyntaxKind.OpenBraceToken; case CharacterCodes.closeBrace: - return pos += 1, token = SyntaxKind.CloseBraceToken; + pos++; + return token = SyntaxKind.CloseBraceToken; case CharacterCodes.openBracket: - return pos += 1, token = SyntaxKind.OpenBracketToken; + pos++; + return token = SyntaxKind.OpenBracketToken; case CharacterCodes.closeBracket: - return pos += 1, token = SyntaxKind.CloseBracketToken; + pos++; + return token = SyntaxKind.CloseBracketToken; case CharacterCodes.equals: - return pos += 1, token = SyntaxKind.EqualsToken; + pos++; + return token = SyntaxKind.EqualsToken; case CharacterCodes.comma: - return pos += 1, token = SyntaxKind.CommaToken; + pos++; + return token = SyntaxKind.CommaToken; } if (isIdentifierStart(ch, ScriptTarget.Latest)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 50beef52bf812..2ee28d501a959 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -464,7 +464,7 @@ namespace ts { modifiers?: ModifiersArray; // Array of modifiers /* @internal */ id?: number; // Unique id (used to look up NodeLinks) parent?: Node; // Parent node (initialized by binding - /* @internal */ jsDocComments?: JSDocComment[]; // JSDoc for the node, if it has any. Only for .js files. + /* @internal */ jsDocComments?: JSDoc[]; // JSDoc for the node, if it has any. Only for .js files. /* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding) /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) /* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding) @@ -1471,7 +1471,7 @@ namespace ts { // @kind(SyntaxKind.JSDocRecordType) export interface JSDocRecordType extends JSDocType, TypeLiteralNode { - members: NodeArray; + literal: TypeLiteralNode; } // @kind(SyntaxKind.JSDocTypeReference) @@ -1519,14 +1519,16 @@ namespace ts { } // @kind(SyntaxKind.JSDocComment) - export interface JSDocComment extends Node { + export interface JSDoc extends Node { tags: NodeArray; + comment: string | undefined; } // @kind(SyntaxKind.JSDocTag) export interface JSDocTag extends Node { atToken: Node; tagName: Identifier; + comment: string | undefined; } // @kind(SyntaxKind.JSDocTemplateTag) @@ -1565,9 +1567,13 @@ namespace ts { // @kind(SyntaxKind.JSDocParameterTag) export interface JSDocParameterTag extends JSDocTag { + /** the parameter name, if provided *before* the type (TypeScript-style) */ preParameterName?: Identifier; typeExpression?: JSDocTypeExpression; + /** the parameter name, if provided *after* the type (JSDoc-standard) */ postParameterName?: Identifier; + /** the parameter name, regardless of the location it was provided */ + parameterName: Identifier; isBracketed: boolean; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0c026fc6b6d45..52683f0e74bf8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -596,13 +596,7 @@ namespace ts { } export function getJsDocCommentsFromText(node: Node, text: string) { - const commentRanges = (node.kind === SyntaxKind.Parameter || - node.kind === SyntaxKind.TypeParameter || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.ArrowFunction) ? - concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : - getLeadingCommentRangesOfNodeFromText(node, text); - return filter(commentRanges, isJsDocComment); + return filter(getLeadingCommentRanges(text, node.pos), isJsDocComment); function isJsDocComment(comment: CommentRange) { // True if the comment starts with '/**' but not if it is '/**/' @@ -1356,39 +1350,75 @@ namespace ts { return undefined; } - const jsDocComments = getJSDocComments(node, checkParentVariableStatement); - if (!jsDocComments) { + const jsDocTags = getJSDocTags(node, checkParentVariableStatement); + if (!jsDocTags) { return undefined; } - for (const jsDocComment of jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.kind === kind) { - return tag; - } + for (const tag of jsDocTags) { + if (tag.kind === kind) { + return tag; } } } - function getJSDocComments(node: Node, checkParentVariableStatement: boolean): JSDocComment[] { - if (node.jsDocComments) { - return node.jsDocComments; - } - // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. - // /** - // * @param {number} name - // * @returns {number} - // */ - // var x = function(name) { return name.length; } + function append(previous: T[] | undefined, additional: T[] | undefined): T[] | undefined { + if (additional) { + if (!previous) { + previous = []; + } + for (const x of additional) { + previous.push(x); + } + } + return previous; + } + + export function getJSDocComments(node: Node, checkParentVariableStatement: boolean): string[] { + return getJSDocs(node, checkParentVariableStatement, docs => map(docs, doc => doc.comment), tags => map(tags, tag => tag.comment)); + } + + function getJSDocTags(node: Node, checkParentVariableStatement: boolean): JSDocTag[] { + return getJSDocs(node, checkParentVariableStatement, docs => { + let result: JSDocTag[] = []; + for (const doc of docs) { + if (doc.tags) { + result.push(...doc.tags); + } + } + return result; + }, tags => tags); + } + + function getJSDocs(node: Node, checkParentVariableStatement: boolean, getDocs: (docs: JSDoc[]) => T[], getTags: (tags: JSDocTag[]) => T[]): T[] { + // TODO: Get rid of getJsDocComments and friends (note the lowercase 's' in Js) + // TODO: A lot of this work should be cached, maybe. I guess it's only used in services right now... + let result: T[] = undefined; + // prepend documentation from parent sources if (checkParentVariableStatement) { + // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. + // /** + // * @param {number} name + // * @returns {number} + // */ + // var x = function(name) { return name.length; } const isInitializerOfVariableDeclarationInStatement = - node.parent.kind === SyntaxKind.VariableDeclaration && - (node.parent).initializer === node && + isVariableLike(node.parent) && + (node.parent).initializer === node && node.parent.parent.parent.kind === SyntaxKind.VariableStatement; + const isVariableOfVariableDeclarationStatement = isVariableLike(node) && + node.parent.parent.kind === SyntaxKind.VariableStatement; - const variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined; + const variableStatementNode = + isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : + isVariableOfVariableDeclarationStatement ? node.parent.parent : + undefined; if (variableStatementNode) { - return variableStatementNode.jsDocComments; + result = append(result, getJSDocs(variableStatementNode, checkParentVariableStatement, getDocs, getTags)); + } + if (node.kind === SyntaxKind.ModuleDeclaration && + node.parent && node.parent.kind === SyntaxKind.ModuleDeclaration) { + result = append(result, getJSDocs(node.parent, checkParentVariableStatement, getDocs, getTags)); } // Also recognize when the node is the RHS of an assignment expression @@ -1399,16 +1429,62 @@ namespace ts { (parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && parent.parent.kind === SyntaxKind.ExpressionStatement; if (isSourceOfAssignmentExpressionStatement) { - return parent.parent.jsDocComments; + result = append(result, getJSDocs(parent.parent, checkParentVariableStatement, getDocs, getTags)); } const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment; if (isPropertyAssignmentExpression) { - return parent.jsDocComments; + result = append(result, getJSDocs(parent, checkParentVariableStatement, getDocs, getTags)); + } + + // Pull parameter comments from declaring function as well + if (node.kind === SyntaxKind.Parameter) { + const paramTags = getJSDocParameterTag(node as ParameterDeclaration, checkParentVariableStatement); + if (paramTags) { + result = append(result, getTags(paramTags)); + } } } - return undefined; + if (isVariableLike(node) && node.initializer) { + result = append(result, getJSDocs(node.initializer, /*checkParentVariableStatement*/ false, getDocs, getTags)); + } + + if (node.jsDocComments) { + if (result) { + result = append(result, getDocs(node.jsDocComments)); + } + else { + return getDocs(node.jsDocComments); + } + } + + return result; + } + + function getJSDocParameterTag(param: ParameterDeclaration, checkParentVariableStatement: boolean): JSDocTag[] { + const func = param.parent as FunctionLikeDeclaration; + const tags = getJSDocTags(func, checkParentVariableStatement); + if (!param.name) { + // this is an anonymous jsdoc param from a `function(type1, type2): type3` specification + const i = func.parameters.indexOf(param); + const paramTags = filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag); + if (paramTags && 0 <= i && i < paramTags.length) { + return [paramTags[i]]; + } + } + else if (param.name.kind === SyntaxKind.Identifier) { + const name = (param.name as Identifier).text; + const paramTags = filter(tags, tag => tag.kind === SyntaxKind.JSDocParameterTag && (tag as JSDocParameterTag).parameterName.text === name); + if (paramTags) { + return paramTags; + } + } + else { + // TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines + // But multi-line object types aren't supported yet either + return undefined; + } } export function getJSDocTypeTag(node: Node): JSDocTypeTag { @@ -1429,17 +1505,15 @@ namespace ts { // annotation. const parameterName = (parameter.name).text; - const jsDocComments = getJSDocComments(parameter.parent, /*checkParentVariableStatement*/ true); - if (jsDocComments) { - for (const jsDocComment of jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.kind === SyntaxKind.JSDocParameterTag) { - const parameterTag = tag; - const name = parameterTag.preParameterName || parameterTag.postParameterName; - if (name.text === parameterName) { - return parameterTag; - } - } + const jsDocTags = getJSDocTags(parameter.parent, /*checkParentVariableStatement*/ true); + if (!jsDocTags) { + return undefined; + } + for (const tag of jsDocTags) { + if (tag.kind === SyntaxKind.JSDocParameterTag) { + const parameterTag = tag; + if (parameterTag.parameterName.text === parameterName) { + return parameterTag; } } } diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index a9987ef3176e6..e688dc2075001 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -6,11 +6,11 @@ namespace ts { describe("TypeExpressions", () => { function parsesCorrectly(content: string, expected: string) { const typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content); - assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0); + assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued"); const result = Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type); - assert.equal(result, expected); + assert.equal(result, expected, "result === expected"); } function parsesIncorrectly(content: string) { @@ -99,10 +99,15 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 3, - "members": { - "length": 0, - "pos": 2, - "end": 2 + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 3, + "members": { + "length": 0, + "pos": 2, + "end": 2 + } } }`); }); @@ -113,21 +118,26 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 6, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 6, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, "end": 5, - "text": "foo" - } - }, - "length": 1, - "pos": 2, - "end": 5 + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } + }, + "length": 1, + "pos": 2, + "end": 5 + } } }`); }); @@ -138,26 +148,31 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 14, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 14, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 13, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "length": 1, - "pos": 2, - "end": 13 + "length": 1, + "pos": 2, + "end": 13 + } } }`); }); @@ -168,32 +183,37 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 11, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 11, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 6, - "end": 10, - "name": { - "kind": "Identifier", + "end": 6, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } + }, + "1": { + "kind": "PropertySignature", "pos": 6, "end": 10, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 10 + "name": { + "kind": "Identifier", + "pos": 6, + "end": 10, + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 10 + } } }`); }); @@ -204,37 +224,42 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 19, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 19, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 14, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 14, - "end": 18, - "name": { - "kind": "Identifier", + "1": { + "kind": "PropertySignature", "pos": 14, "end": 18, - "text": "bar" - } - }, - "length": 2, - "pos": 2, - "end": 18 + "name": { + "kind": "Identifier", + "pos": 14, + "end": 18, + "text": "bar" + } + }, + "length": 2, + "pos": 2, + "end": 18 + } } }`); }); @@ -245,37 +270,42 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 19, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 5, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 19, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 6, - "end": 18, - "name": { - "kind": "Identifier", + "end": 6, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + } + }, + "1": { + "kind": "PropertySignature", "pos": 6, - "end": 10, - "text": "bar" + "end": 18, + "name": { + "kind": "Identifier", + "pos": 6, + "end": 10, + "text": "bar" + }, + "type": { + "kind": "NumberKeyword", + "pos": 11, + "end": 18 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 11, - "end": 18 - } - }, - "length": 2, - "pos": 2, - "end": 18 + "length": 2, + "pos": 2, + "end": 18 + } } }`); }); @@ -286,42 +316,47 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 27, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 13, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 27, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, - "end": 5, - "text": "foo" + "end": 14, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "type": { + "kind": "NumberKeyword", + "pos": 6, + "end": 13 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 6, - "end": 13 - } - }, - "1": { - "kind": "JSDocRecordMember", - "pos": 14, - "end": 26, - "name": { - "kind": "Identifier", + "1": { + "kind": "PropertySignature", "pos": 14, - "end": 18, - "text": "bar" + "end": 26, + "name": { + "kind": "Identifier", + "pos": 14, + "end": 18, + "text": "bar" + }, + "type": { + "kind": "NumberKeyword", + "pos": 19, + "end": 26 + } }, - "type": { - "kind": "NumberKeyword", - "pos": 19, - "end": 26 - } - }, - "length": 2, - "pos": 2, - "end": 26 + "length": 2, + "pos": 2, + "end": 26 + } } }`); }); @@ -332,22 +367,128 @@ namespace ts { "kind": "JSDocRecordType", "pos": 1, "end": 11, - "members": { - "0": { - "kind": "JSDocRecordMember", - "pos": 2, - "end": 10, - "name": { - "kind": "Identifier", + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 11, + "members": { + "0": { + "kind": "PropertySignature", "pos": 2, "end": 10, - "originalKeywordKind": "FunctionKeyword", - "text": "function" - } - }, - "length": 1, - "pos": 2, - "end": 10 + "name": { + "kind": "Identifier", + "pos": 2, + "end": 10, + "originalKeywordKind": "FunctionKeyword", + "text": "function" + } + }, + "length": 1, + "pos": 2, + "end": 10 + } + } +}`); + }); + + it("trailingCommaInRecordType", () => { + parsesCorrectly("{{a,}}", `{ + "kind": "JSDocRecordType", + "pos": 1, + "end": 5, + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 5, + "members": { + "0": { + "kind": "PropertySignature", + "pos": 2, + "end": 4, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 3, + "text": "a" + } + }, + "length": 1, + "pos": 2, + "end": 4 + } + } +}`); + }); + + it("callSignatureInRecordType", () => { + parsesCorrectly("{{(): number}}", `{ + "kind": "JSDocRecordType", + "pos": 1, + "end": 13, + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 13, + "members": { + "0": { + "kind": "CallSignature", + "pos": 2, + "end": 12, + "parameters": { + "length": 0, + "pos": 3, + "end": 3 + }, + "type": { + "kind": "NumberKeyword", + "pos": 5, + "end": 12 + } + }, + "length": 1, + "pos": 2, + "end": 12 + } + } +}`); + }); + + it("methodInRecordType", () => { + parsesCorrectly("{{foo(): number}}", `{ + "kind": "JSDocRecordType", + "pos": 1, + "end": 16, + "literal": { + "kind": "TypeLiteral", + "pos": 1, + "end": 16, + "members": { + "0": { + "kind": "MethodSignature", + "pos": 2, + "end": 15, + "name": { + "kind": "Identifier", + "pos": 2, + "end": 5, + "text": "foo" + }, + "parameters": { + "length": 0, + "pos": 6, + "end": 6 + }, + "type": { + "kind": "NumberKeyword", + "pos": 8, + "end": 15 + } + }, + "length": 1, + "pos": 2, + "end": 15 + } } }`); }); @@ -872,17 +1013,14 @@ namespace ts { } }`); }); - }); + + }); describe("parsesIncorrectly", () => { it("emptyType", () => { parsesIncorrectly("{}"); }); - it("trailingCommaInRecordType", () => { - parsesIncorrectly("{{a,}}"); - }); - it("unionTypeWithTrailingBar", () => { parsesIncorrectly("{(a|)}"); }); @@ -947,14 +1085,6 @@ namespace ts { parsesIncorrectly("{function(a: number)}"); }); - it("callSignatureInRecordType", () => { - parsesIncorrectly("{{(): number}}"); - }); - - it("methodInRecordType", () => { - parsesIncorrectly("{{foo(): number}}"); - }); - it("tupleTypeWithComma", () => { parsesIncorrectly( "{[,]}"); }); @@ -979,7 +1109,7 @@ namespace ts { Debug.fail("Comment has at least one diagnostic: " + comment.diagnostics[0].messageText); } - const result = toJsonString(comment.jsDocComment); + const result = toJsonString(comment.jsDoc); const expectedString = typeof expected === "string" ? expected @@ -990,7 +1120,7 @@ namespace ts { const chai = require("chai"); chai.config.showDiff = true; // Use deep equal to compare key value data instead of the two objects - chai.expect(JSON.parse(result)).deep.equal(JSON.parse(expectedString)); + chai.expect(JSON.parse(expectedString)).deep.equal(JSON.parse(result)); } else { assert.equal(result, expectedString); @@ -1028,10 +1158,6 @@ namespace ts { parsesIncorrectly("/*** */"); }); - it("asteriskAfterPreamble", () => { - parsesIncorrectly("/** * @type {number} */"); - }); - it("multipleTypes", () => { parsesIncorrectly( `/** @@ -1091,6 +1217,7 @@ namespace ts { "0": { "kind": "JSDocTypeTag", "pos": 8, + "comment": "", "end": 22, "atToken": { "kind": "AtToken", @@ -1112,7 +1239,8 @@ namespace ts { "pos": 15, "end": 21 } - } + }, + "comment": "" }, "length": 1, "pos": 8, @@ -1121,6 +1249,15 @@ namespace ts { }`); }); + it("asteriskAfterPreamble", () => { + parsesCorrectly("/** * @type {number} */", `{ + "comment": "* @type {number} ", + "end": 23, + "kind": "JSDocComment", + "pos": 0 +}`); + }); + it("noType", () => { parsesCorrectly( `/** @@ -1133,8 +1270,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, - "end": 13, + "end": 14, "atToken": { "kind": "AtToken", "pos": 8, @@ -1149,7 +1287,7 @@ namespace ts { }, "length": 1, "pos": 8, - "end": 13 + "end": 14 } }`); }); @@ -1166,8 +1304,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, - "end": 15, + "end": 16, "atToken": { "kind": "AtToken", "pos": 8, @@ -1182,7 +1321,7 @@ namespace ts { }, "length": 1, "pos": 8, - "end": 15 + "end": 16 } }`); }); @@ -1199,6 +1338,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, "end": 22, "atToken": { @@ -1242,6 +1382,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocTypeTag", + "comment": "", "pos": 8, "end": 22, "atToken": { @@ -1285,6 +1426,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, "end": 24, "atToken": { @@ -1328,6 +1470,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "Description text follows", "pos": 8, "end": 24, "atToken": { @@ -1371,6 +1514,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocReturnTag", + "comment": "", "pos": 8, "end": 25, "atToken": { @@ -1414,6 +1558,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1442,6 +1587,12 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "length": 1, @@ -1464,6 +1615,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1492,10 +1644,17 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "1": { "kind": "JSDocParameterTag", + "comment": "", "pos": 34, "end": 55, "atToken": { @@ -1524,6 +1683,12 @@ namespace ts { "pos": 50, "end": 55, "text": "name2" + }, + "parameterName": { + "kind": "Identifier", + "pos": 50, + "end": 55, + "text": "name2" } }, "length": 2, @@ -1545,6 +1710,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 29, "atToken": { @@ -1573,6 +1739,12 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, "length": 1, @@ -1594,6 +1766,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 31, "atToken": { @@ -1623,6 +1796,12 @@ namespace ts { "end": 30, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 25, + "end": 30, + "text": "name1" + }, "isBracketed": true }, "length": 1, @@ -1644,6 +1823,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description text follows", "pos": 8, "end": 36, "atToken": { @@ -1673,6 +1853,12 @@ namespace ts { "end": 31, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 26, + "end": 31, + "text": "name1" + }, "isBracketed": true }, "length": 1, @@ -1694,6 +1880,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1722,11 +1909,56 @@ namespace ts { "pos": 24, "end": 29, "text": "name1" + }, + "parameterName": { + "kind": "Identifier", + "pos": 24, + "end": 29, + "text": "name1" } }, - "length": 1, - "pos": 8, - "end": 29 + "1": { + "atToken": { + "end": 31, + "kind": "AtToken", + "pos": 30 + }, + "comment": "", + "end": 51, + "kind": "JSDocParameterTag", + "parameterName": { + "end": 51, + "kind": "Identifier", + "pos": 46, + "text": "name2" + }, + "pos": 30, + "postParameterName": { + "end": 51, + "kind": "Identifier", + "pos": 46, + "text": "name2" + }, + "tagName": { + "end": 36, + "kind": "Identifier", + "pos": 31, + "text": "param" + }, + "typeExpression": { + "end": 45, + "kind": "JSDocTypeExpression", + "pos": 37, + "type": { + "end": 44, + "kind": "NumberKeyword", + "pos": 38 + } + } + }, + "end": 51, + "length": 2, + "pos": 8 } }`); }); @@ -1743,6 +1975,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 29, "atToken": { @@ -1762,6 +1995,12 @@ namespace ts { "end": 20, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 20, + "text": "name1" + }, "typeExpression": { "kind": "JSDocTypeExpression", "pos": 21, @@ -1792,6 +2031,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "Description", "pos": 8, "end": 29, "atToken": { @@ -1811,6 +2051,12 @@ namespace ts { "end": 20, "text": "name1" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 20, + "text": "name1" + }, "typeExpression": { "kind": "JSDocTypeExpression", "pos": 21, @@ -1841,8 +2087,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 19, + "end": 20, "atToken": { "kind": "AtToken", "pos": 8, @@ -1858,7 +2105,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -1867,13 +2114,13 @@ namespace ts { } }, "length": 1, - "pos": 17, - "end": 19 + "pos": 18, + "end": 20 } }, "length": 1, "pos": 8, - "end": 19 + "end": 20 } }`); }); @@ -1890,8 +2137,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 21, + "end": 22, "atToken": { "kind": "AtToken", "pos": 8, @@ -1918,7 +2166,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 20, - "end": 21, + "end": 22, "name": { "kind": "Identifier", "pos": 20, @@ -1927,13 +2175,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 21 + "pos": 18, + "end": 22 } }, "length": 1, "pos": 8, - "end": 21 + "end": 22 } }`); }); @@ -1950,8 +2198,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 22, + "end": 23, "atToken": { "kind": "AtToken", "pos": 8, @@ -1967,7 +2216,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -1978,7 +2227,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 21, - "end": 22, + "end": 23, "name": { "kind": "Identifier", "pos": 21, @@ -1987,13 +2236,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 22 + "pos": 18, + "end": 23 } }, "length": 1, "pos": 8, - "end": 22 + "end": 23 } }`); }); @@ -2010,8 +2259,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 22, + "end": 23, "atToken": { "kind": "AtToken", "pos": 8, @@ -2038,7 +2288,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 21, - "end": 22, + "end": 23, "name": { "kind": "Identifier", "pos": 21, @@ -2047,13 +2297,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 22 + "pos": 18, + "end": 23 } }, "length": 1, "pos": 8, - "end": 22 + "end": 23 } }`); }); @@ -2070,8 +2320,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "", "pos": 8, - "end": 23, + "end": 24, "atToken": { "kind": "AtToken", "pos": 8, @@ -2087,7 +2338,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -2098,7 +2349,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 22, - "end": 23, + "end": 24, "name": { "kind": "Identifier", "pos": 22, @@ -2107,13 +2358,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 23 + "pos": 18, + "end": 24 } }, "length": 1, "pos": 8, - "end": 23 + "end": 24 } }`); }); @@ -2130,8 +2381,9 @@ namespace ts { "tags": { "0": { "kind": "JSDocTemplateTag", + "comment": "Description of type parameters.", "pos": 8, - "end": 23, + "end": 24, "atToken": { "kind": "AtToken", "pos": 8, @@ -2147,7 +2399,7 @@ namespace ts { "0": { "kind": "TypeParameter", "pos": 18, - "end": 19, + "end": 20, "name": { "kind": "Identifier", "pos": 18, @@ -2158,7 +2410,7 @@ namespace ts { "1": { "kind": "TypeParameter", "pos": 22, - "end": 23, + "end": 24, "name": { "kind": "Identifier", "pos": 22, @@ -2167,13 +2419,13 @@ namespace ts { } }, "length": 2, - "pos": 17, - "end": 23 + "pos": 18, + "end": 24 } }, "length": 1, "pos": 8, - "end": 23 + "end": 24 } }`); }); @@ -2190,6 +2442,7 @@ namespace ts { "tags": { "0": { "kind": "JSDocParameterTag", + "comment": "", "pos": 8, "end": 18, "atToken": { @@ -2203,6 +2456,12 @@ namespace ts { "end": 14, "text": "param" }, + "parameterName": { + "kind": "Identifier", + "pos": 15, + "end": 18, + "text": "foo" + }, "preParameterName": { "kind": "Identifier", "pos": 15, @@ -2236,17 +2495,18 @@ namespace ts { "kind": "AtToken", "pos": 8 }, - "end": 97, + "comment": "", + "end": 98, "jsDocTypeLiteral": { - "end": 97, + "end": 98, "jsDocPropertyTags": [ { "atToken": { "end": 48, "kind": "AtToken", - "pos": 46 + "pos": 47 }, - "end": 69, + "end": 72, "kind": "JSDocPropertyTag", "name": { "end": 69, @@ -2254,7 +2514,7 @@ namespace ts { "pos": 66, "text": "age" }, - "pos": 46, + "pos": 47, "tagName": { "end": 56, "kind": "Identifier", @@ -2276,9 +2536,9 @@ namespace ts { "atToken": { "end": 75, "kind": "AtToken", - "pos": 73 + "pos": 74 }, - "end": 97, + "end": 98, "kind": "JSDocPropertyTag", "name": { "end": 97, @@ -2286,7 +2546,7 @@ namespace ts { "pos": 93, "text": "name" }, - "pos": 73, + "pos": 74, "tagName": { "end": 83, "kind": "Identifier", @@ -2309,11 +2569,11 @@ namespace ts { "atToken": { "end": 29, "kind": "AtToken", - "pos": 27 + "pos": 28 }, "end": 42, "kind": "JSDocTypeTag", - "pos": 27, + "pos": 28, "tagName": { "end": 33, "kind": "Identifier", @@ -2338,7 +2598,7 @@ namespace ts { } }, "kind": "JSDocTypeLiteral", - "pos": 23 + "pos": 26 }, "kind": "JSDocTypedefTag", "name": { @@ -2355,7 +2615,7 @@ namespace ts { "text": "typedef" } }, - "end": 97, + "end": 98, "length": 1, "pos": 8 } diff --git a/src/services/services.ts b/src/services/services.ts index c19eb487d756f..812ae0643d83e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -194,7 +194,7 @@ namespace ts { public end: number; public flags: NodeFlags; public parent: Node; - public jsDocComments: JSDocComment[]; + public jsDocComments: JSDoc[]; private _children: Node[]; constructor(kind: SyntaxKind, pos: number, end: number) { @@ -355,7 +355,7 @@ namespace ts { public end: number; public flags: NodeFlags; public parent: Node; - public jsDocComments: JSDocComment[]; + public jsDocComments: JSDoc[]; public __tokenTag: any; constructor(pos: number, end: number) { @@ -474,349 +474,48 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { + // Only collect doc comments from duplicate declarations once: + // In case of a union property there might be same declaration multiple times + // which only varies in type parameter + // Eg. const a: Array | Array; a.length + // The property length will have two declarations of property length coming + // from Array - Array and Array const documentationComment = []; - const docComments = getJsDocCommentsSeparatedByNewLines(); - ts.forEach(docComments, docComment => { - if (documentationComment.length) { - documentationComment.push(lineBreakPart()); - } - documentationComment.push(docComment); - }); - - return documentationComment; - - function getJsDocCommentsSeparatedByNewLines() { - const paramTag = "@param"; - const jsDocCommentParts: SymbolDisplayPart[] = []; - - ts.forEach(declarations, (declaration, indexOfDeclaration) => { - // Make sure we are collecting doc comment from declaration once, - // In case of union property there might be same declaration multiple times - // which only varies in type parameter - // Eg. const a: Array | Array; a.length - // The property length will have two declarations of property length coming - // from Array - Array and Array - if (indexOf(declarations, declaration) === indexOfDeclaration) { - const sourceFileOfDeclaration = getSourceFileOfNode(declaration); - // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments - if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { - if ((declaration.parent.kind === SyntaxKind.FunctionExpression || declaration.parent.kind === SyntaxKind.ArrowFunction) && - declaration.parent.parent.kind === SyntaxKind.VariableDeclaration) { - addCommentParts(declaration.parent.parent.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment); - } - addCommentParts(declaration.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment); - } - - // If this is left side of dotted module declaration, there is no doc comments associated with this node - if (declaration.kind === SyntaxKind.ModuleDeclaration && (declaration).body && (declaration).body.kind === SyntaxKind.ModuleDeclaration) { - return; - } - - if ((declaration.kind === SyntaxKind.FunctionExpression || declaration.kind === SyntaxKind.ArrowFunction) && - declaration.parent.kind === SyntaxKind.VariableDeclaration) { - addCommentParts(declaration.parent.parent, sourceFileOfDeclaration, getCleanedJsDocComment); - } - - // If this is dotted module name, get the doc comments from the parent - while (declaration.kind === SyntaxKind.ModuleDeclaration && declaration.parent.kind === SyntaxKind.ModuleDeclaration) { - declaration = declaration.parent; - } - addCommentParts(declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, - sourceFileOfDeclaration, - getCleanedJsDocComment); - - if (declaration.kind === SyntaxKind.VariableDeclaration) { - const init = (declaration as VariableDeclaration).initializer; - if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - // Get the cleaned js doc comment text from the initializer - addCommentParts(init, sourceFileOfDeclaration, getCleanedJsDocComment); - } - } - } - }); - - return jsDocCommentParts; - - function addCommentParts(commented: Node, - sourceFileOfDeclaration: SourceFile, - getCommentPart: (pos: number, end: number, file: SourceFile) => SymbolDisplayPart[]): void { - const ranges = getJsDocCommentTextRange(commented, sourceFileOfDeclaration); - // Get the cleaned js doc comment text from the declaration - ts.forEach(ranges, jsDocCommentTextRange => { - const cleanedComment = getCommentPart(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); - if (cleanedComment) { - addRange(jsDocCommentParts, cleanedComment); - } - }); - } - - function getJsDocCommentTextRange(node: Node, sourceFile: SourceFile): TextRange[] { - return ts.map(getJsDocComments(node, sourceFile), - jsDocComment => { - return { - pos: jsDocComment.pos + "/*".length, // Consume /* from the comment - end: jsDocComment.end - "*/".length // Trim off comment end indicator - }; - }); - } - - function consumeWhiteSpacesOnTheLine(pos: number, end: number, sourceFile: SourceFile, maxSpacesToRemove?: number) { - if (maxSpacesToRemove !== undefined) { - end = Math.min(end, pos + maxSpacesToRemove); - } - - for (; pos < end; pos++) { - const ch = sourceFile.text.charCodeAt(pos); - if (!isWhiteSpaceSingleLine(ch)) { - return pos; - } - } - - return end; - } - - function consumeLineBreaks(pos: number, end: number, sourceFile: SourceFile) { - while (pos < end && isLineBreak(sourceFile.text.charCodeAt(pos))) { - pos++; - } - - return pos; - } - - function isName(pos: number, end: number, sourceFile: SourceFile, name: string) { - return pos + name.length < end && - sourceFile.text.substr(pos, name.length) === name && - isWhiteSpace(sourceFile.text.charCodeAt(pos + name.length)); - } - - function isParamTag(pos: number, end: number, sourceFile: SourceFile) { - // If it is @param tag - return isName(pos, end, sourceFile, paramTag); - } - - function pushDocCommentLineText(docComments: SymbolDisplayPart[], text: string, blankLineCount: number) { - // Add the empty lines in between texts - while (blankLineCount) { - blankLineCount--; - docComments.push(textPart("")); - } - - docComments.push(textPart(text)); + forEachUnique(declarations, declaration => { + const comments = getJSDocComments(declaration, /*checkParentVariableStatement*/ true); + if (!comments) { + return; } - - function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - let spacesToRemoveAfterAsterisk: number; - const docComments: SymbolDisplayPart[] = []; - let blankLineCount = 0; - let isInParamTag = false; - - while (pos < end) { - let docCommentTextOfLine = ""; - // First consume leading white space - pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile); - - // If the comment starts with '*' consume the spaces on this line - if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - const lineStartPos = pos + 1; - pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); - - // Set the spaces to remove after asterisk as margin if not already set - if (spacesToRemoveAfterAsterisk === undefined && pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - spacesToRemoveAfterAsterisk = pos - lineStartPos; - } - } - else if (spacesToRemoveAfterAsterisk === undefined) { - spacesToRemoveAfterAsterisk = 0; - } - - // Analyze text on this line - while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - const ch = sourceFile.text.charAt(pos); - if (ch === "@") { - // If it is @param tag - if (isParamTag(pos, end, sourceFile)) { - isInParamTag = true; - pos += paramTag.length; - continue; - } - else { - isInParamTag = false; - } - } - - // Add the ch to doc text if we arent in param tag - if (!isInParamTag) { - docCommentTextOfLine += ch; - } - - // Scan next character - pos++; - } - - // Continue with next line - pos = consumeLineBreaks(pos, end, sourceFile); - if (docCommentTextOfLine) { - pushDocCommentLineText(docComments, docCommentTextOfLine, blankLineCount); - blankLineCount = 0; - } - else if (!isInParamTag && docComments.length) { - // This is blank line when there is text already parsed - blankLineCount++; + for (const comment of comments) { + if (comment) { + if (documentationComment.length) { + documentationComment.push(lineBreakPart()); } + documentationComment.push(textPart(comment)); } - - return docComments; } + }); - function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - let paramHelpStringMargin: number; - const paramDocComments: SymbolDisplayPart[] = []; - while (pos < end) { - if (isParamTag(pos, end, sourceFile)) { - let blankLineCount = 0; - let recordedParamTag = false; - // Consume leading spaces - pos = consumeWhiteSpaces(pos + paramTag.length); - if (pos >= end) { - break; - } - - // Ignore type expression - if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { - pos++; - for (let curlies = 1; pos < end; pos++) { - const charCode = sourceFile.text.charCodeAt(pos); - - // { character means we need to find another } to match the found one - if (charCode === CharacterCodes.openBrace) { - curlies++; - continue; - } - - // } char - if (charCode === CharacterCodes.closeBrace) { - curlies--; - if (curlies === 0) { - // We do not have any more } to match the type expression is ignored completely - pos++; - break; - } - else { - // there are more { to be matched with } - continue; - } - } - - // Found start of another tag - if (charCode === CharacterCodes.at) { - break; - } - } - - // Consume white spaces - pos = consumeWhiteSpaces(pos); - if (pos >= end) { - break; - } - } - - // Parameter name - if (isName(pos, end, sourceFile, name)) { - // Found the parameter we are looking for consume white spaces - pos = consumeWhiteSpaces(pos + name.length); - if (pos >= end) { - break; - } - - let paramHelpString = ""; - const firstLineParamHelpStringPos = pos; - while (pos < end) { - const ch = sourceFile.text.charCodeAt(pos); - - // at line break, set this comment line text and go to next line - if (isLineBreak(ch)) { - if (paramHelpString) { - pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount); - paramHelpString = ""; - blankLineCount = 0; - recordedParamTag = true; - } - else if (recordedParamTag) { - blankLineCount++; - } - - // Get the pos after cleaning start of the line - setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos); - continue; - } - - // Done scanning param help string - next tag found - if (ch === CharacterCodes.at) { - break; - } - - paramHelpString += sourceFile.text.charAt(pos); - - // Go to next character - pos++; - } - - // If there is param help text, add it top the doc comments - if (paramHelpString) { - pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount); - } - paramHelpStringMargin = undefined; - } - - // If this is the start of another tag, continue with the loop in search of param tag with symbol name - if (sourceFile.text.charCodeAt(pos) === CharacterCodes.at) { - continue; - } - } - - // Next character - pos++; - } - - return paramDocComments; - - function consumeWhiteSpaces(pos: number) { - while (pos < end && isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) { - pos++; - } - - return pos; - } - - function setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos: number) { - // Get the pos after consuming line breaks - pos = consumeLineBreaks(pos, end, sourceFile); - if (pos >= end) { - return; - } - - if (paramHelpStringMargin === undefined) { - paramHelpStringMargin = sourceFile.getLineAndCharacterOfPosition(firstLineParamHelpStringPos).character; - } - - // Now consume white spaces max - const startOfLinePos = pos; - pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); - if (pos >= end) { - return; - } + return documentationComment; + } - const consumedSpaces = pos - startOfLinePos; - if (consumedSpaces < paramHelpStringMargin) { - const ch = sourceFile.text.charCodeAt(pos); - if (ch === CharacterCodes.asterisk) { - // Consume more spaces after asterisk - pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); - } + /** + * Iterates through 'array' by index and performs the callback on each element of array until the callback + * returns a truthy value, then returns that value. + * If no such value is found, the callback is applied to each element of array and undefined is returned. + */ + export function forEachUnique(array: T[], callback: (element: T, index: number) => U): U { + if (array) { + for (let i = 0, len = array.length; i < len; i++) { + if (indexOf(array, array[i]) === i) { + const result = callback(array[i], i); + if (result) { + return result; } } } } + return undefined; } class TypeObject implements Type { @@ -7498,9 +7197,9 @@ namespace ts { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); - if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { - docCommentAndDiagnostics.jsDocComment.parent = token; - classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) { + docCommentAndDiagnostics.jsDoc.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDoc); return; } } @@ -7513,22 +7212,22 @@ namespace ts { pushClassification(start, width, ClassificationType.comment); } - function classifyJSDocComment(docComment: JSDocComment) { + function classifyJSDocComment(docComment: JSDoc) { let pos = docComment.pos; + if (docComment.tags) { + for (const tag of docComment.tags) { + // As we walk through each tag, classify the portion of text from the end of + // the last tag (or the start of the entire doc comment) as 'comment'. + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } - for (const tag of docComment.tags) { - // As we walk through each tag, classify the portion of text from the end of - // the last tag (or the start of the entire doc comment) as 'comment'. - if (tag.pos !== pos) { - pushCommentRange(pos, tag.pos - pos); - } - - pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); - pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); - pos = tag.tagName.end; + pos = tag.tagName.end; - switch (tag.kind) { + switch (tag.kind) { case SyntaxKind.JSDocParameterTag: processJSDocParameterTag(tag); break; @@ -7541,9 +7240,10 @@ namespace ts { case SyntaxKind.JSDocReturnTag: processElement((tag).typeExpression); break; - } + } - pos = tag.end; + pos = tag.end; + } } if (pos !== docComment.end) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9b3469643ba77..4ceecb4bf50db 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -569,9 +569,11 @@ namespace ts { if (node) { if (node.jsDocComments) { for (const jsDocComment of node.jsDocComments) { - for (const tag of jsDocComment.tags) { - if (tag.pos <= position && position <= tag.end) { - return tag; + if (jsDocComment.tags) { + for (const tag of jsDocComment.tags) { + if (tag.pos <= position && position <= tag.end) { + return tag; + } } } } @@ -946,4 +948,4 @@ namespace ts { } return { configJsonObject, diagnostics }; } -} \ No newline at end of file +} From b14d7c7ebb1aeee3074fa0c9ee2d42b0d964232e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:25:49 -0700 Subject: [PATCH 2/9] Add more jsdoc tests --- tests/cases/conformance/jsdoc/returns.ts | 9 ++++++++ .../fourslash/jsDocFunctionSignatures10.ts | 15 +++++++++++++ .../fourslash/jsDocFunctionSignatures11.ts | 9 ++++++++ .../fourslash/jsDocFunctionSignatures12.ts | 13 +++++++++++ .../fourslash/jsDocFunctionSignatures2.ts | 2 +- .../fourslash/jsDocFunctionSignatures5.ts | 18 +++++++++++++++ .../fourslash/jsDocFunctionSignatures6.ts | 19 ++++++++++++++++ .../fourslash/jsDocFunctionSignatures7.ts | 16 ++++++++++++++ .../fourslash/jsDocFunctionSignatures8.ts | 16 ++++++++++++++ .../fourslash/jsDocFunctionSignatures9.ts | 22 +++++++++++++++++++ tests/cases/fourslash/jsdocReturnsTag.ts | 17 ++++++++++++++ 11 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tests/cases/conformance/jsdoc/returns.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures10.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures11.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures12.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures5.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures6.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures7.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures8.ts create mode 100644 tests/cases/fourslash/jsDocFunctionSignatures9.ts create mode 100644 tests/cases/fourslash/jsdocReturnsTag.ts diff --git a/tests/cases/conformance/jsdoc/returns.ts b/tests/cases/conformance/jsdoc/returns.ts new file mode 100644 index 0000000000000..72cb4a6cb679b --- /dev/null +++ b/tests/cases/conformance/jsdoc/returns.ts @@ -0,0 +1,9 @@ +// @allowJs: true +// @filename: returns.js +// @out: dummy.js +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} diff --git a/tests/cases/fourslash/jsDocFunctionSignatures10.ts b/tests/cases/fourslash/jsDocFunctionSignatures10.ts new file mode 100644 index 0000000000000..60810c46e70dc --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures10.ts @@ -0,0 +1,15 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * Do some foo things +//// * @template T A Foolish template +//// * @param {T} x a parameter +//// */ +////function foo(x) { +////} +//// +////fo/**/o() + +goTo.marker(); +verify.quickInfoIs("function foo(x: T): void", "Do some foo things"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures11.ts b/tests/cases/fourslash/jsDocFunctionSignatures11.ts new file mode 100644 index 0000000000000..26b2cda6d2aa9 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures11.ts @@ -0,0 +1,9 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @type {{ [name: string]: string; }} variables +//// */ +////const vari/**/ables = {}; +goTo.marker(); +verify.quickInfoIs("const variables: {\n [name: string]: string;\n}"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures12.ts b/tests/cases/fourslash/jsDocFunctionSignatures12.ts new file mode 100644 index 0000000000000..29a8ac4caeb9c --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures12.ts @@ -0,0 +1,13 @@ + +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {{ stringProp: string, +//// * numProp: number }} o +//// */ +////function f1(o) { +//// o/**/; +////} +goTo.marker(); +verify.quickInfoIs("(parameter) o: any"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures2.ts b/tests/cases/fourslash/jsDocFunctionSignatures2.ts index 174ea7d6560a0..e6430cba5bd7d 100644 --- a/tests/cases/fourslash/jsDocFunctionSignatures2.ts +++ b/tests/cases/fourslash/jsDocFunctionSignatures2.ts @@ -9,4 +9,4 @@ //// f6('', /**/false) goTo.marker(); -verify.currentSignatureHelpIs('f6(p0: string, p1?: boolean): number') +verify.currentSignatureHelpIs('f6(arg0: string, arg1?: boolean): number') diff --git a/tests/cases/fourslash/jsDocFunctionSignatures5.ts b/tests/cases/fourslash/jsDocFunctionSignatures5.ts new file mode 100644 index 0000000000000..08d0da990bcc6 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures5.ts @@ -0,0 +1,18 @@ +/// +// @allowJs: true +// @Filename: Foo.js + +/////** +//// * Filters a path based on a regexp or glob pattern. +//// * @param {String} basePath The base path where the search will be performed. +//// * @param {String} pattern A string defining a regexp of a glob pattern. +//// * @param {String} type The search pattern type, can be a regexp or a glob. +//// * @param {Object} options A object containing options to the search. +//// * @return {Array} A list containing the filtered paths. +//// */ +////function pathFilter(basePath, pattern, type, options){ +//////... +////} +////pathFilter(/**/'foo', 'bar', 'baz', {}); +goTo.marker(); +verify.currentSignatureHelpDocCommentIs("Filters a path based on a regexp or glob pattern."); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures6.ts b/tests/cases/fourslash/jsDocFunctionSignatures6.ts new file mode 100644 index 0000000000000..10b290d6d02a2 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures6.ts @@ -0,0 +1,19 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {string} p1 - A string param +//// * @param {string?} p2 - An optional param +//// * @param {string} [p3] - Another optional param +//// * @param {string} [p4="test"] - An optional param with a default value +//// */ +////function f1(p1, p2, p3, p4){} +////f1(/*1*/'foo', /*2*/'bar', /*3*/'baz', /*4*/'qux'); +goTo.marker('1'); +verify.currentParameterHelpArgumentDocCommentIs("- A string param"); +goTo.marker('2'); +verify.currentParameterHelpArgumentDocCommentIs("- An optional param "); +goTo.marker('3'); +verify.currentParameterHelpArgumentDocCommentIs("- Another optional param"); +goTo.marker('4'); +verify.currentParameterHelpArgumentDocCommentIs("- An optional param with a default value"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures7.ts b/tests/cases/fourslash/jsDocFunctionSignatures7.ts new file mode 100644 index 0000000000000..6bbb8a34dccc2 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures7.ts @@ -0,0 +1,16 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * @param {string} p0 +//// * @param {string} [p1] +//// */ +////function Test(p0, p1) { +//// this.P0 = p0; +//// this.P1 = p1; +////} +//// +//// +////var /**/test = new Test(""); +goTo.marker(); +verify.quickInfoIs('var test: {\n P0: string;\n P1: string;\n}'); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures8.ts b/tests/cases/fourslash/jsDocFunctionSignatures8.ts new file mode 100644 index 0000000000000..3dbe38e34df1b --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures8.ts @@ -0,0 +1,16 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** +//// * Represents a person +//// * @constructor +//// * @param {string} name The name of the person +//// * @param {number} age The age of the person +//// */ +////function Person(name, age) { +//// this.name = name; +//// this.age = age; +////} +////var p = new Pers/**/on(); +goTo.marker(); +verify.quickInfoIs("function Person(name: string, age: number): void", "Represents a person"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures9.ts b/tests/cases/fourslash/jsDocFunctionSignatures9.ts new file mode 100644 index 0000000000000..26361bfe10615 --- /dev/null +++ b/tests/cases/fourslash/jsDocFunctionSignatures9.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: Foo.js +/////** first line of the comment +//// +////third line */ +////function foo() {} +////foo/**/(); +goTo.marker(); +verify.verifyQuickInfoDisplayParts('function', + '', + { start: 63, length: 3 }, + [{"text": "function", "kind": "keyword"}, + {"text": " ", "kind": "space"}, + {"text": "foo", "kind": "functionName"}, + {"text": "(", "kind": "punctuation"}, + {"text": ")", "kind": "punctuation"}, + {"text": ":", "kind": "punctuation"}, + {"text": " ", "kind": "space"}, + {"text": "void", "kind": "keyword"} + ], + [{"text": "first line of the comment\n\nthird line ", "kind": "text"}]); diff --git a/tests/cases/fourslash/jsdocReturnsTag.ts b/tests/cases/fourslash/jsdocReturnsTag.ts new file mode 100644 index 0000000000000..9203bd9e03698 --- /dev/null +++ b/tests/cases/fourslash/jsdocReturnsTag.ts @@ -0,0 +1,17 @@ +/// +// @allowJs: true +// @Filename: dummy.js +/////** +//// * Find an item +//// * @template T +//// * @param {T[]} l +//// * @param {T} x +//// * @returns {?T} The names of the found item(s). +//// */ +////function find(l, x) { +////} +////find(''/**/); + +goTo.marker(); +verify.currentSignatureHelpIs("find(l: T[], x: T): T") +// There currently isn't a way to display the return tag comment From 2b9624672df3027af28f96741025ec3c3906d82c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 09:26:44 -0700 Subject: [PATCH 3/9] Update/add baselines for jsdoc/emitter changes --- .../reference/arrowFunctionErrorSpan.js | 4 +- .../reference/augmentExportEquals1.js | 4 +- .../reference/augmentExportEquals1_1.js | 4 +- .../reference/augmentExportEquals2.js | 4 +- .../reference/augmentExportEquals2_1.js | 4 +- .../augmentedTypesExternalModule1.js | 2 +- ...ScopedFunctionDeclarationInStrictModule.js | 2 +- tests/baselines/reference/callOverloads1.js | 2 +- tests/baselines/reference/callOverloads2.js | 2 +- tests/baselines/reference/callOverloads3.js | 2 +- tests/baselines/reference/callOverloads4.js | 2 +- tests/baselines/reference/callOverloads5.js | 2 +- .../reference/collisionArgumentsFunction.js | 1 + .../collisionRestParameterFunction.js | 1 + .../collisionThisExpressionAndParameter.js | 1 + .../reference/commentInEmptyParameterList1.js | 2 +- ...mentOnParenthesizedExpressionOpenParen1.js | 2 +- .../commentsArgumentsOfCallExpression2.js | 2 +- tests/baselines/reference/commentsFunction.js | 4 +- tests/baselines/reference/commentsVarDecl.js | 6 +- .../reference/computedPropertyNames48_ES5.js | 4 +- .../reference/constructorOverloads1.js | 4 +- .../reference/constructorOverloads2.js | 4 +- .../reference/constructorOverloads3.js | 2 +- .../contextuallyTypingRestParameters.js | 4 +- .../declFileObjectLiteralWithAccessors.js | 4 +- .../declFileObjectLiteralWithOnlyGetter.js | 4 +- .../declFileObjectLiteralWithOnlySetter.js | 4 +- tests/baselines/reference/errorSupression1.js | 2 +- .../es6ImportDefaultBindingWithExport.js | 2 +- .../reference/es6ImportNameSpaceImportDts.js | 1 + .../es6ImportNameSpaceImportNoNamedExports.js | 1 + .../es6ImportNamedImportIdentifiersParsing.js | 1 + .../reference/es6modulekindWithES5Target10.js | 1 + ...rtSpecifierReferencingOuterDeclaration4.js | 1 + .../baselines/reference/genericConstraint3.js | 1 + ...ersAndIndexSignaturesFromDifferentBases.js | 1 + ...rsAndIndexSignaturesFromDifferentBases2.js | 1 + ...tedStringIndexersFromDifferentBaseTypes.js | 1 + ...edStringIndexersFromDifferentBaseTypes2.js | 1 + .../reference/jsxInvalidEsprimaTestSuite.js | 4 +- .../nonConflictingRecursiveBaseTypeMembers.js | 1 + .../objectTypesWithOptionalProperties2.js | 3 +- ...parseRegularExpressionMixedWithComments.js | 6 +- .../parserGreaterThanTokenAmbiguity10.js | 1 + .../parserGreaterThanTokenAmbiguity13.js | 2 +- .../parserGreaterThanTokenAmbiguity15.js | 1 + .../parserGreaterThanTokenAmbiguity18.js | 2 +- .../parserGreaterThanTokenAmbiguity20.js | 1 + .../parserGreaterThanTokenAmbiguity3.js | 2 +- .../parserGreaterThanTokenAmbiguity5.js | 1 + .../parserGreaterThanTokenAmbiguity8.js | 2 +- .../reference/parserSkippedTokens5.js | 2 +- .../reference/parserSkippedTokens7.js | 1 + .../reference/parserSkippedTokens8.js | 2 +- .../reference/parserSkippedTokens9.js | 1 + ...siveExportAssignmentAndFindAliasedType1.js | 2 +- ...siveExportAssignmentAndFindAliasedType2.js | 2 +- ...siveExportAssignmentAndFindAliasedType3.js | 2 +- ...siveExportAssignmentAndFindAliasedType4.js | 2 +- ...siveExportAssignmentAndFindAliasedType5.js | 2 +- ...siveExportAssignmentAndFindAliasedType6.js | 2 +- ...siveExportAssignmentAndFindAliasedType7.js | 2 +- tests/baselines/reference/returns.js | 16 ++++ tests/baselines/reference/returns.symbols | 10 +++ tests/baselines/reference/returns.types | 11 +++ .../thisInInvalidContextsExternalModule.js | 2 +- tests/baselines/reference/tsxParseTests2.js | 2 +- .../typeAliasDoesntMakeModuleInstantiated.js | 1 + tests/cases/fourslash/commentsClassMembers.ts | 89 +++++++++---------- .../cases/fourslash/commentsCommentParsing.ts | 54 +++++------ .../fourslash/commentsFunctionExpression.ts | 12 +-- .../fourslash/commentsLinePreservation.ts | 10 +-- tests/cases/fourslash/commentsModules.ts | 26 +++--- .../fourslash/getJavaScriptQuickInfo1.ts | 2 +- .../fourslash/getJavaScriptQuickInfo7.ts | 2 +- 76 files changed, 219 insertions(+), 161 deletions(-) create mode 100644 tests/baselines/reference/returns.js create mode 100644 tests/baselines/reference/returns.symbols create mode 100644 tests/baselines/reference/returns.types diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.js b/tests/baselines/reference/arrowFunctionErrorSpan.js index 2557113e89bd4..3ead7ed3b311e 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.js +++ b/tests/baselines/reference/arrowFunctionErrorSpan.js @@ -83,7 +83,9 @@ f(// comment 1 // comment 2 function () { // comment 4 -}); +} + // comment 5 +); // body is not a block f(function (_) { return 1 + 2; }); diff --git a/tests/baselines/reference/augmentExportEquals1.js b/tests/baselines/reference/augmentExportEquals1.js index 98322c01a34c9..6f7aab9269228 100644 --- a/tests/baselines/reference/augmentExportEquals1.js +++ b/tests/baselines/reference/augmentExportEquals1.js @@ -32,5 +32,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals1_1.js b/tests/baselines/reference/augmentExportEquals1_1.js index 08f032ff33f1c..7023966344141 100644 --- a/tests/baselines/reference/augmentExportEquals1_1.js +++ b/tests/baselines/reference/augmentExportEquals1_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals2.js b/tests/baselines/reference/augmentExportEquals2.js index fc373173e3c44..b444c16b6fcd4 100644 --- a/tests/baselines/reference/augmentExportEquals2.js +++ b/tests/baselines/reference/augmentExportEquals2.js @@ -31,5 +31,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentExportEquals2_1.js b/tests/baselines/reference/augmentExportEquals2_1.js index 9046157bb2626..afa78d1d981f5 100644 --- a/tests/baselines/reference/augmentExportEquals2_1.js +++ b/tests/baselines/reference/augmentExportEquals2_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; // should not work -}); + var a; +}); // should not work diff --git a/tests/baselines/reference/augmentedTypesExternalModule1.js b/tests/baselines/reference/augmentedTypesExternalModule1.js index 65525e8187eea..01358a9e4af73 100644 --- a/tests/baselines/reference/augmentedTypesExternalModule1.js +++ b/tests/baselines/reference/augmentedTypesExternalModule1.js @@ -13,4 +13,4 @@ define(["require", "exports"], function (require, exports) { c5.prototype.foo = function () { }; return c5; }()); -}); +}); // should be ok everywhere diff --git a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js index d1a8091871c2e..6d46015847881 100644 --- a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js +++ b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js @@ -14,4 +14,4 @@ define(["require", "exports"], function (require, exports) { foo(); // ok } return foo; -}); +}); // not ok diff --git a/tests/baselines/reference/callOverloads1.js b/tests/baselines/reference/callOverloads1.js index 756a9099e4452..d441deb41d7d5 100644 --- a/tests/baselines/reference/callOverloads1.js +++ b/tests/baselines/reference/callOverloads1.js @@ -22,7 +22,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); function F1(a) { return a; } diff --git a/tests/baselines/reference/callOverloads2.js b/tests/baselines/reference/callOverloads2.js index b890ee8bde967..8db26c3b77143 100644 --- a/tests/baselines/reference/callOverloads2.js +++ b/tests/baselines/reference/callOverloads2.js @@ -30,7 +30,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); function F1(s) { return s; } // error diff --git a/tests/baselines/reference/callOverloads3.js b/tests/baselines/reference/callOverloads3.js index e5d678543c647..ee49f4b329735 100644 --- a/tests/baselines/reference/callOverloads3.js +++ b/tests/baselines/reference/callOverloads3.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/callOverloads4.js b/tests/baselines/reference/callOverloads4.js index dfb274dfb6e35..fa7a51ae8d10f 100644 --- a/tests/baselines/reference/callOverloads4.js +++ b/tests/baselines/reference/callOverloads4.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/callOverloads5.js b/tests/baselines/reference/callOverloads5.js index cf159d309b0f2..d95485f85d7f5 100644 --- a/tests/baselines/reference/callOverloads5.js +++ b/tests/baselines/reference/callOverloads5.js @@ -24,7 +24,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function (a) { }; + Foo.prototype.bar1 = function (a) { /*WScript.Echo(a);*/ }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index 9ce4a5ab0e20b..d59efc116ee2c 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -90,3 +90,4 @@ function f42(i) { function f4NoError(arguments) { var arguments; // No error } + // no codegen no error diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index 8660e8f5db0ea..a9e3f510fa17d 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -63,3 +63,4 @@ function f4(_i) { } function f4NoError(_i) { } + // no codegen no error diff --git a/tests/baselines/reference/collisionThisExpressionAndParameter.js b/tests/baselines/reference/collisionThisExpressionAndParameter.js index bc15e4b56b50a..a445c35295b4d 100644 --- a/tests/baselines/reference/collisionThisExpressionAndParameter.js +++ b/tests/baselines/reference/collisionThisExpressionAndParameter.js @@ -167,3 +167,4 @@ function f3(_this) { var _this = this; (function (x) { console.log(_this.x); }); } + // no code gen - no error diff --git a/tests/baselines/reference/commentInEmptyParameterList1.js b/tests/baselines/reference/commentInEmptyParameterList1.js index 8f4e13d82d69d..09b34f93536a4 100644 --- a/tests/baselines/reference/commentInEmptyParameterList1.js +++ b/tests/baselines/reference/commentInEmptyParameterList1.js @@ -3,5 +3,5 @@ function foo(/** nothing */) { } //// [commentInEmptyParameterList1.js] -function foo() { +function foo( /** nothing */) { } diff --git a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js index d014043dfe0a3..7a7c25a9b4c0a 100644 --- a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js +++ b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js @@ -7,4 +7,4 @@ var f: () => any; //// [commentOnParenthesizedExpressionOpenParen1.js] var j; var f; -(j = f()); +(/* Preserve */ j = f()); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index a7065410ff4fe..f89e67ef3d8b3 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -14,7 +14,7 @@ foo( function foo(/*c1*/ x, /*d1*/ y, /*e1*/ w) { } var a, b; foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); -foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + b); +foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( /*c4*/ function () { }, diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index 0ffb271410879..86978d7bdf7ee 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -74,8 +74,8 @@ var fooFunc = function FooFunctionValue(/** fooFunctionValue param */ b) { return b; }; /// lamdaFoo var comment -var lambdaFoo = function (/**param a*/ a, /**param b*/ b) { return a + b; }; -var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * b; }; +var lambdaFoo = /** this is lambda comment*/ function (/**param a*/ a, /**param b*/ b) { return a + b; }; +var lambddaNoVarComment = /** this is lambda multiplication*/ function (/**param a*/ a, /**param b*/ b) { return a * b; }; lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment diff --git a/tests/baselines/reference/commentsVarDecl.js b/tests/baselines/reference/commentsVarDecl.js index 5ff2a3c1c6a85..e9b6776a6d902 100644 --- a/tests/baselines/reference/commentsVarDecl.js +++ b/tests/baselines/reference/commentsVarDecl.js @@ -64,13 +64,13 @@ x = myVariable; /** jsdocstyle comment - only this comment should be in .d.ts file*/ var n = 30; /** var deckaration with comment on type as well*/ -var y = 20; +var y = /** value comment */ 20; /// var deckaration with comment on type as well var yy = /// value comment 20; /** comment2 */ -var z = function (x, y) { return x + y; }; +var z = /** lambda comment */ function (x, y) { return x + y; }; var z2; var x2 = z2; var n4; @@ -98,6 +98,6 @@ declare var y: number; declare var yy: number; /** comment2 */ declare var z: (x: number, y: number) => number; -declare var z2: (x: number) => string; +declare var z2: /** type comment*/ (x: number) => string; declare var x2: (x: number) => string; declare var n4: (x: number) => string; diff --git a/tests/baselines/reference/computedPropertyNames48_ES5.js b/tests/baselines/reference/computedPropertyNames48_ES5.js index 15123a98f302b..f2610b7272a78 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES5.js +++ b/tests/baselines/reference/computedPropertyNames48_ES5.js @@ -34,5 +34,5 @@ extractIndexer((_b = {}, extractIndexer((_c = {}, _c["" || 0] = "", _c -)); // Should return any (widened form of undefined) -var _a, _b, _c; +)); +var _a, _b, _c; // Should return any (widened form of undefined) diff --git a/tests/baselines/reference/constructorOverloads1.js b/tests/baselines/reference/constructorOverloads1.js index 47906974f6ea5..d62cb9530c505 100644 --- a/tests/baselines/reference/constructorOverloads1.js +++ b/tests/baselines/reference/constructorOverloads1.js @@ -25,8 +25,8 @@ f1.bar2(); var Foo = (function () { function Foo(x) { } - Foo.prototype.bar1 = function () { }; - Foo.prototype.bar2 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar2 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads2.js b/tests/baselines/reference/constructorOverloads2.js index 76481ec1bc691..e8d11af405621 100644 --- a/tests/baselines/reference/constructorOverloads2.js +++ b/tests/baselines/reference/constructorOverloads2.js @@ -34,7 +34,7 @@ var __extends = (this && this.__extends) || function (d, b) { var FooBase = (function () { function FooBase(x) { } - FooBase.prototype.bar1 = function () { }; + FooBase.prototype.bar1 = function () { /*WScript.Echo("base bar1");*/ }; return FooBase; }()); var Foo = (function (_super) { @@ -42,7 +42,7 @@ var Foo = (function (_super) { function Foo(x, y) { _super.call(this, x); } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads3.js b/tests/baselines/reference/constructorOverloads3.js index 61f0d50db03af..7cc27fd5b42e1 100644 --- a/tests/baselines/reference/constructorOverloads3.js +++ b/tests/baselines/reference/constructorOverloads3.js @@ -32,7 +32,7 @@ var Foo = (function (_super) { __extends(Foo, _super); function Foo(x, y) { } - Foo.prototype.bar1 = function () { }; + Foo.prototype.bar1 = function () { /*WScript.Echo("Yo");*/ }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index 17561f5d7fccb..48589ade40865 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -9,9 +9,9 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { - var y = []; + var /*3*/ y = []; for (var _i = 0; _i < arguments.length; _i++) { - y[_i - 0] = arguments[_i]; + /*3*/ y[_i - 0] = arguments[_i]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js index 7886736f7e452..adc185e269f88 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js @@ -12,7 +12,7 @@ var /*2*/x = point.x; point./*3*/x = 30; //// [declFileObjectLiteralWithAccessors.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { b: 10, get x() { return x; }, @@ -22,7 +22,7 @@ function makePoint(x) { ; var /*4*/ point = makePoint(2); var /*2*/ x = point.x; -point.x = 30; +point./*3*/ x = 30; //// [declFileObjectLiteralWithAccessors.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js index eb440c028d582..96b4de87bef53 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js @@ -10,14 +10,14 @@ var /*2*/x = point./*3*/x; //// [declFileObjectLiteralWithOnlyGetter.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { get x() { return x; }, }; } ; var /*4*/ point = makePoint(2); -var /*2*/ x = point.x; +var /*2*/ x = point./*3*/ x; //// [declFileObjectLiteralWithOnlyGetter.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js index f7a48fe810c45..44b28a9bdb2df 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js @@ -10,7 +10,7 @@ var /*3*/point = makePoint(2); point./*2*/x = 30; //// [declFileObjectLiteralWithOnlySetter.js] -function makePoint(x) { +function /*1*/ makePoint(x) { return { b: 10, set x(a) { this.b = a; } @@ -18,7 +18,7 @@ function makePoint(x) { } ; var /*3*/ point = makePoint(2); -point.x = 30; +point./*2*/ x = 30; //// [declFileObjectLiteralWithOnlySetter.d.ts] diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 77545131ce344..285aa525b5fb0 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -18,4 +18,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); -// So we don't want an error on 'concat'. + // So we don't want an error on 'concat'. diff --git a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js index cc90d28091478..1e6f49e241448 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js @@ -21,7 +21,7 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; exports.x = server_1.default; -}); +}); // non referenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportDts.js b/tests/baselines/reference/es6ImportNameSpaceImportDts.js index cf66c08331e3a..0b522776c4b24 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportDts.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportDts.js @@ -22,6 +22,7 @@ exports.c = c; "use strict"; var nameSpaceBinding = require("./server"); exports.x = new nameSpaceBinding.c(); + // unreferenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js index 8ece816fd3b6c..79c588dc27701 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js @@ -14,3 +14,4 @@ var a = 10; module.exports = a; //// [es6ImportNameSpaceImportNoNamedExports_1.js] "use strict"; + // error diff --git a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js index 8db7fcd6f9c57..a9a843f3cc9c0 100644 --- a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js +++ b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js @@ -7,3 +7,4 @@ import { default as yield } from "somemodule"; // no error import { default as default } from "somemodule"; // default as is ok, error of default binding name //// [es6ImportNamedImportIdentifiersParsing.js] + // default as is ok, error of default binding name diff --git a/tests/baselines/reference/es6modulekindWithES5Target10.js b/tests/baselines/reference/es6modulekindWithES5Target10.js index b8a66241780ef..015a64c3bc012 100644 --- a/tests/baselines/reference/es6modulekindWithES5Target10.js +++ b/tests/baselines/reference/es6modulekindWithES5Target10.js @@ -8,3 +8,4 @@ namespace N { export = N; // Error //// [es6modulekindWithES5Target10.js] + // Error diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js index 1badf46999668..1b8e4dd5c4b5c 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js @@ -12,3 +12,4 @@ export declare function bar(): X.bar; // error //// [exportSpecifierReferencingOuterDeclaration2_A.js] //// [exportSpecifierReferencingOuterDeclaration2_B.js] "use strict"; + // error diff --git a/tests/baselines/reference/genericConstraint3.js b/tests/baselines/reference/genericConstraint3.js index 59548c4f4d70e..657600ba41a99 100644 --- a/tests/baselines/reference/genericConstraint3.js +++ b/tests/baselines/reference/genericConstraint3.js @@ -4,3 +4,4 @@ interface A> { x: U; } interface B extends A<{}, { x: {} }> { } // Should not produce an error //// [genericConstraint3.js] + // Should not produce an error diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js index f4ea5f07eb9b4..26ef7ca775920 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js @@ -28,3 +28,4 @@ interface G extends A, B, C, E { } // should only report one error interface H extends A, F { } // Should report no error at all because error is internal to F //// [inheritedMembersAndIndexSignaturesFromDifferentBases.js] + // Should report no error at all because error is internal to F diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js index 8a3b2f8d0328e..9291ab53c1c3a 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js @@ -10,3 +10,4 @@ interface B { interface C extends B, A { } // Should succeed //// [inheritedMembersAndIndexSignaturesFromDifferentBases2.js] + // Should succeed diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js index 1645dd10a552a..c7a008f01fb0c 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js @@ -29,3 +29,4 @@ interface D2 { interface E2 extends A2, D2 { } // error //// [inheritedStringIndexersFromDifferentBaseTypes.js] + // error diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js index aa837b5cf2e6a..0580b145901b5 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js @@ -25,3 +25,4 @@ interface F extends A, D { } // ok because we overrode D's number index signature //// [inheritedStringIndexersFromDifferentBaseTypes2.js] + // ok because we overrode D's number index signature diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js index 7f01666bd7821..85d0d3687be19 100644 --- a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js @@ -62,7 +62,7 @@ a['foo'] > ; ; ; var x =
one
two
;; -var x =
one
/* intervening comment */ /* intervening comment */
two
;; +var x =
one
/* intervening comment */ /* intervening comment */
two
;;
{"str"}}; id="b" />;
>; @@ -76,4 +76,4 @@ var x =
one
/* intervening comment */ /* intervening comment */
; ; }; - /*hai*//*hai*/asdf/>;; +/*hai*/ /*hai*/asdf/>;; diff --git a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js index 6e77029fa94f5..9663da873b843 100644 --- a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js +++ b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js @@ -10,3 +10,4 @@ interface B { interface C extends A, B { } // Should not be an error //// [nonConflictingRecursiveBaseTypeMembers.js] + // Should not be an error diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties2.js b/tests/baselines/reference/objectTypesWithOptionalProperties2.js index eabb1a153a6e6..28470e049830b 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties2.js +++ b/tests/baselines/reference/objectTypesWithOptionalProperties2.js @@ -42,6 +42,5 @@ var C2 = (function () { return C2; }()); var b = { - x: function () { }, 1: // error - // error + x: function () { }, 1: // error }; diff --git a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js index 78752a77f75c5..0ef42cf2ce1b4 100644 --- a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js +++ b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js @@ -8,7 +8,7 @@ var regex5 = /**// asdf/**/ /; //// [parseRegularExpressionMixedWithComments.js] var regex1 = / asdf /; -var regex2 = / asdf /; +var regex2 = /**/ / asdf /; var regex3 = 1; -var regex4 = Math.pow(/ /, /asdf /); -var regex5 = Math.pow(/ asdf/, / /); +var regex4 = /**/ Math.pow(/ /, /asdf /); +var regex5 = /**/ Math.pow(/ asdf/, / /); diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js index 862722b1a73c4..eb76d7e0d7cc3 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity10.js] 1 + // before >>> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js index 49130a9dd136b..5be4da1c04e81 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js @@ -2,5 +2,5 @@ 1 >>/**/= 2; //// [parserGreaterThanTokenAmbiguity13.js] -1 >> ; /**/ +1 >> /**/ ; 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js index b6f905e12e77a..8fadea77fdcd4 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity15.js] 1 + // before >>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js index 71527689b2cda..4cf227f27488d 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js @@ -2,5 +2,5 @@ 1 >>>/**/= 2; //// [parserGreaterThanTokenAmbiguity18.js] -1 >>> ; /**/ +1 >>> /**/ ; 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js index 01d1d6401f2a6..ab86deeb0d21a 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity20.js] 1 + // Before >>>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js index 79f8c139260d1..f692d1a6324c2 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js @@ -2,4 +2,4 @@ 1 >/**/> 2; //// [parserGreaterThanTokenAmbiguity3.js] -1 > /**/ > 2; +1 > /**/ /**/ > 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js index c65b76f504a0b..24aa9e5316a35 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js @@ -6,5 +6,6 @@ //// [parserGreaterThanTokenAmbiguity5.js] 1 + // before >> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js index 0006c03219a39..d8ea6134a5813 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js @@ -2,4 +2,4 @@ 1 >>/**/> 2; //// [parserGreaterThanTokenAmbiguity8.js] -1 >> /**/ > 2; +1 >> /**/ /**/ > 2; diff --git a/tests/baselines/reference/parserSkippedTokens5.js b/tests/baselines/reference/parserSkippedTokens5.js index 359a98a5969e5..665db1ef70d99 100644 --- a/tests/baselines/reference/parserSkippedTokens5.js +++ b/tests/baselines/reference/parserSkippedTokens5.js @@ -2,4 +2,4 @@ \ /*foo*/ ; //// [parserSkippedTokens5.js] -; +/*foo*/ ; diff --git a/tests/baselines/reference/parserSkippedTokens7.js b/tests/baselines/reference/parserSkippedTokens7.js index 2115614ea1f3e..b3aa40d905707 100644 --- a/tests/baselines/reference/parserSkippedTokens7.js +++ b/tests/baselines/reference/parserSkippedTokens7.js @@ -2,3 +2,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens7.js] + /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens8.js b/tests/baselines/reference/parserSkippedTokens8.js index c9f00f4b85bae..d8433bbd34cd3 100644 --- a/tests/baselines/reference/parserSkippedTokens8.js +++ b/tests/baselines/reference/parserSkippedTokens8.js @@ -3,4 +3,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens8.js] -; +; /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens9.js b/tests/baselines/reference/parserSkippedTokens9.js index d693b99b2eabc..cabf3a48e5631 100644 --- a/tests/baselines/reference/parserSkippedTokens9.js +++ b/tests/baselines/reference/parserSkippedTokens9.js @@ -4,3 +4,4 @@ //// [parserSkippedTokens9.js] ; // existing trivia + /*bar*/ diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js index d759bc2f296a7..96fff1f8f3346 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js @@ -29,4 +29,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType1_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js index 7704b38f68ddb..e8262c86b4f50 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js @@ -33,4 +33,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType2_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js index a46be3bdafc94..39303b463bad6 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js @@ -37,4 +37,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType3_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js index 8ccd6ecf5603c..80a4408b10d2b 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js @@ -31,4 +31,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType4_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js index 4602ed554e59d..69f6ff07bd89b 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js @@ -40,4 +40,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType5_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js index d3487519218f7..277a8a168da0b 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js @@ -49,4 +49,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType6_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js index 9a29c2bf9498c..fcab82802b207 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js @@ -51,4 +51,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType7_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); +}); // This should result in type ClassB diff --git a/tests/baselines/reference/returns.js b/tests/baselines/reference/returns.js new file mode 100644 index 0000000000000..67390dea72a2e --- /dev/null +++ b/tests/baselines/reference/returns.js @@ -0,0 +1,16 @@ +//// [returns.js] +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} + + +//// [dummy.js] +/** + * @returns {string} This comment is not currently exposed + */ +function f() { + return ""; +} diff --git a/tests/baselines/reference/returns.symbols b/tests/baselines/reference/returns.symbols new file mode 100644 index 0000000000000..e0f0d4dac963a --- /dev/null +++ b/tests/baselines/reference/returns.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/returns.js === +/** + * @returns {string} This comment is not currently exposed + */ +function f() { +>f : Symbol(f, Decl(returns.js, 0, 0)) + + return ""; +} + diff --git a/tests/baselines/reference/returns.types b/tests/baselines/reference/returns.types new file mode 100644 index 0000000000000..c1bb1637c450a --- /dev/null +++ b/tests/baselines/reference/returns.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/jsdoc/returns.js === +/** + * @returns {string} This comment is not currently exposed + */ +function f() { +>f : () => string + + return ""; +>"" : string +} + diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index 2e7e6d8b47cca..00553a3fbbaf9 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -107,4 +107,4 @@ var SomeEnum; SomeEnum[SomeEnum["A"] = this] = "A"; SomeEnum[SomeEnum["B"] = this.spaaaace] = "B"; // Also should not be allowed })(SomeEnum || (SomeEnum = {})); -module.exports = this; +module.exports = this; // Should be an error diff --git a/tests/baselines/reference/tsxParseTests2.js b/tests/baselines/reference/tsxParseTests2.js index b0cf54f8d1f02..c09e9d2c3cb0c 100644 --- a/tests/baselines/reference/tsxParseTests2.js +++ b/tests/baselines/reference/tsxParseTests2.js @@ -8,4 +8,4 @@ var x =
; //// [file.jsx] -var x =
; +var x =
; diff --git a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js index 861e20cb0d145..af2287ef27f38 100644 --- a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js +++ b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js @@ -11,3 +11,4 @@ declare module m { declare var m: m.IStatic; // Should be ok to have var 'm' as module is non instantiated //// [typeAliasDoesntMakeModuleInstantiated.js] + // Should be ok to have var 'm' as module is non instantiated diff --git a/tests/cases/fourslash/commentsClassMembers.ts b/tests/cases/fourslash/commentsClassMembers.ts index d719253a57b47..481baee28af94 100644 --- a/tests/cases/fourslash/commentsClassMembers.ts +++ b/tests/cases/fourslash/commentsClassMembers.ts @@ -8,11 +8,11 @@ //// public p/*3*/2(/** number to add*/b: number) { //// return this./*4*/p1 + /*5*/b; //// } -//// /** getter property*/ +//// /** getter property 1*/ //// public get p/*6*/3() { //// return this./*7*/p/*8q*/2(/*8*/this./*9*/p1); //// } -//// /** setter property*/ +//// /** setter property 1*/ //// public set p/*10*/3(/** this is value*/value: number) { //// this./*11*/p1 = this./*12*/p/*13q*/2(/*13*/value); //// } @@ -22,11 +22,11 @@ //// private p/*15*/p2(/** number to add*/b: number) { //// return this./*16*/p1 + /*17*/b; //// } -//// /** getter property*/ +//// /** getter property 2*/ //// private get p/*18*/p3() { //// return this./*19*/p/*20q*/p2(/*20*/this./*21*/pp1); //// } -//// /** setter property*/ +//// /** setter property 2*/ //// private set p/*22*/p3( /** this is value*/value: number) { //// this./*23*/pp1 = this./*24*/p/*25q*/p2(/*25*/value); //// } @@ -43,7 +43,7 @@ //// static get s/*32*/3() { //// return /*33*/c1./*34*/s/*35q*/2(/*35*/c1./*36*/s1); //// } -//// /** setter property*/ +//// /** setter property 3*/ //// static set s/*37*/3( /** this is value*/value: number) { //// /*38*/c1./*39*/s1 = /*40*/c1./*41*/s/*42q*/2(/*42*/value); //// } @@ -131,7 +131,6 @@ //// th/*116*/is./*114*/a = /*115*/a + 2 + bb/*117*/bb; //// } ////} - goTo.marker('1'); verify.quickInfoIs("class c1", "This is comment for c1"); @@ -144,10 +143,10 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('4'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -159,15 +158,15 @@ goTo.marker('5'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('6'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('7'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -184,10 +183,10 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('9'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -196,15 +195,15 @@ verify.memberListContains("nc_pp2", "(method) c1.nc_pp2(b: number): number", "") verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('10'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('11'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -215,10 +214,10 @@ verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('12'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -242,10 +241,10 @@ verify.quickInfoIs("(method) c1.pp2(b: number): number", "sum with property"); goTo.marker('16'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -257,15 +256,15 @@ goTo.marker('17'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('18'); -verify.quickInfoIs("(property) c1.pp3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.pp3: number", "getter property 2\nsetter property 2"); goTo.marker('19'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -282,10 +281,10 @@ verify.quickInfoIs("(method) c1.pp2(b: number): number", "sum with property"); goTo.marker('21'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -294,15 +293,15 @@ verify.memberListContains("nc_pp2", "(method) c1.nc_pp2(b: number): number", "") verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('22'); -verify.quickInfoIs("(property) c1.pp3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.pp3: number", "getter property 2\nsetter property 2"); goTo.marker('23'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -313,10 +312,10 @@ verify.memberListContains("nc_pp3", "(property) c1.nc_pp3: number", ""); goTo.marker('24'); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("pp1", "(property) c1.pp1: number", "pp1 is property of c1"); verify.memberListContains("pp2", "(method) c1.pp2(b: number): number", "sum with property"); -verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property\nsetter property"); +verify.memberListContains("pp3", "(property) c1.pp3: number", "getter property 2\nsetter property 2"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -346,7 +345,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('30'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -355,7 +354,7 @@ goTo.marker('31'); verify.completionListContains("b", "(parameter) b: number", "number to add"); goTo.marker('32'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('33'); verify.completionListContains("c1", "class c1", "This is comment for c1"); @@ -363,7 +362,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('34'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -378,13 +377,13 @@ verify.quickInfoIs("(method) c1.s2(b: number): number", "static sum with propert goTo.marker('36'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); goTo.marker('37'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('38'); verify.completionListContains("c1", "class c1", "This is comment for c1"); @@ -392,7 +391,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('39'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -403,7 +402,7 @@ verify.completionListContains("c1", "class c1", "This is comment for c1"); goTo.marker('41'); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -514,7 +513,7 @@ goTo.marker('67'); verify.quickInfoIs("(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p1", "(property) c1.p1: number", "p1 is property of c1"); verify.memberListContains("p2", "(method) c1.p2(b: number): number", "sum with property"); -verify.memberListContains("p3", "(property) c1.p3: number", "getter property\nsetter property"); +verify.memberListContains("p3", "(property) c1.p3: number", "getter property 1\nsetter property 1"); verify.memberListContains("nc_p1", "(property) c1.nc_p1: number", ""); verify.memberListContains("nc_p2", "(method) c1.nc_p2(b: number): number", ""); verify.memberListContains("nc_p3", "(property) c1.nc_p3: number", ""); @@ -537,9 +536,9 @@ verify.quickInfoIs("(method) c1.p2(b: number): number", "sum with property"); goTo.marker('72'); verify.quickInfoIs("var i1_prop: number", ""); goTo.marker('73'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('74'); -verify.quickInfoIs("(property) c1.p3: number", "getter property\nsetter property"); +verify.quickInfoIs("(property) c1.p3: number", "getter property 1\nsetter property 1"); goTo.marker('75'); verify.quickInfoIs("var i1_prop: number", ""); @@ -584,7 +583,7 @@ goTo.marker('88'); verify.quickInfoIs("(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s1", "(property) c1.s1: number", "s1 is static property of c1"); verify.memberListContains("s2", "(method) c1.s2(b: number): number", "static sum with property"); -verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property"); +verify.memberListContains("s3", "(property) c1.s3: number", "static getter property\nsetter property 3"); verify.memberListContains("nc_s1", "(property) c1.nc_s1: number", ""); verify.memberListContains("nc_s2", "(method) c1.nc_s2(b: number): number", ""); verify.memberListContains("nc_s3", "(property) c1.nc_s3: number", ""); @@ -607,9 +606,9 @@ verify.quickInfoIs("(method) c1.s2(b: number): number", "static sum with propert goTo.marker('93'); verify.quickInfoIs("var i1_s_prop: number", ""); goTo.marker('94'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('95'); -verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property"); +verify.quickInfoIs("(property) c1.s3: number", "static getter property\nsetter property 3"); goTo.marker('96'); verify.quickInfoIs("var i1_s_prop: number", ""); @@ -686,8 +685,8 @@ goTo.marker('113'); verify.quickInfoIs("(property) cProperties.nc_p1: number", ""); goTo.marker('114'); -verify.memberListContains("a", "(property) cWithConstructorProperty.a: number", "more info about a"); -verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "more info about a"); +verify.memberListContains("a", "(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); +verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); goTo.marker('115'); verify.completionListContains("a", "(parameter) a: number", "this is first parameter a\nmore info about a"); diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index f209f573e2fd9..a0a86cbc75cf6 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -48,7 +48,7 @@ ////} ////jsDocMi/*7q*/xedComments2(/*7*/); //// -/////** jsdoc comment */ /*** another jsDocComment*/ +/////** jsdoc comment */ /*** malformed jsDocComment*/ /////// Triple slash comment ////function jsDocMixedComments3() { ////} @@ -238,9 +238,9 @@ goTo.marker('7q'); verify.quickInfoIs("function jsDocMixedComments2(): void", "jsdoc comment \nanother jsDocComment"); goTo.marker('8'); -verify.currentSignatureHelpDocCommentIs("jsdoc comment \n* another jsDocComment"); +verify.currentSignatureHelpDocCommentIs("jsdoc comment "); goTo.marker('8q'); -verify.quickInfoIs("function jsDocMixedComments3(): void", "jsdoc comment \n* another jsDocComment"); +verify.quickInfoIs("function jsDocMixedComments3(): void", "jsdoc comment "); goTo.marker('9'); verify.currentSignatureHelpDocCommentIs("jsdoc comment \nanother jsDocComment"); @@ -295,33 +295,33 @@ verify.completionListContains("a", "(parameter) a: number", "first number"); verify.completionListContains("b", "(parameter) b: number", "second number"); goTo.marker('19'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs("first number"); goTo.marker('19q'); -verify.quickInfoIs("function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function\n@anotherTag\n@anotherTag"); +verify.quickInfoIs("function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function"); goTo.marker('19aq'); verify.quickInfoIs("(parameter) a: number", "first number"); goTo.marker('20'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('20aq'); verify.quickInfoIs("(parameter) b: number", ""); goTo.marker('21'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); -verify.currentParameterHelpArgumentDocCommentIs("{"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); +verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('21aq'); -verify.quickInfoIs("(parameter) c: number", "{"); +verify.quickInfoIs("(parameter) c: number", ""); goTo.marker('22'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('22aq'); verify.quickInfoIs("(parameter) d: any", ""); goTo.marker('23'); -verify.currentSignatureHelpDocCommentIs("This is multiplication function\n@anotherTag\n@anotherTag"); +verify.currentSignatureHelpDocCommentIs("This is multiplication function"); verify.currentParameterHelpArgumentDocCommentIs("LastParam "); goTo.marker('23aq'); verify.quickInfoIs("(parameter) e: any", "LastParam "); @@ -347,65 +347,65 @@ goTo.marker('26aq'); verify.quickInfoIs("(parameter) b: string", ""); goTo.marker('27'); -verify.completionListContains("multiply", "function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function\n@anotherTag\n@anotherTag"); +verify.completionListContains("multiply", "function multiply(a: number, b: number, c?: number, d?: any, e?: any): void", "This is multiplication function"); verify.completionListContains("f1", "function f1(a: number): any (+1 overload)", "fn f1 with number"); goTo.marker('28'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('28q'); -verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function"); +verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{()=>string; } } f this is optional param f"); goTo.marker('28aq'); verify.quickInfoIs("(parameter) a: number", ""); goTo.marker('29'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is about b"); goTo.marker('29aq'); verify.quickInfoIs("(parameter) b: number", "this is about b"); goTo.marker('30'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param c"); goTo.marker('30aq'); verify.quickInfoIs("(parameter) c: () => string", "this is optional param c"); goTo.marker('31'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); -verify.currentParameterHelpArgumentDocCommentIs(""); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentParameterHelpArgumentDocCommentIs("this is optional param d"); goTo.marker('31aq'); -verify.quickInfoIs("(parameter) d: () => string", ""); +verify.quickInfoIs("(parameter) d: () => string", "this is optional param d"); goTo.marker('32'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param e"); goTo.marker('32aq'); verify.quickInfoIs("(parameter) e: () => string", "this is optional param e"); goTo.marker('33'); -verify.currentSignatureHelpDocCommentIs("This is subtract function"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('33aq'); verify.quickInfoIs("(parameter) f: () => string", ""); goTo.marker('34'); -verify.currentSignatureHelpDocCommentIs("this is square function\n@paramTag { number } a this is input number of paramTag\n@returnType { number } it is return type"); +verify.currentSignatureHelpDocCommentIs("this is square function"); verify.currentParameterHelpArgumentDocCommentIs("this is input number"); goTo.marker('34q'); -verify.quickInfoIs("function square(a: number): number", "this is square function\n@paramTag { number } a this is input number of paramTag\n@returnType { number } it is return type"); +verify.quickInfoIs("function square(a: number): number", "this is square function"); goTo.marker('34aq'); verify.quickInfoIs("(parameter) a: number", "this is input number"); goTo.marker('35'); -verify.currentSignatureHelpDocCommentIs("this is divide function\n@paramTag { number } g this is optional param g"); +verify.currentSignatureHelpDocCommentIs("this is divide function"); verify.currentParameterHelpArgumentDocCommentIs("this is a"); goTo.marker('35q'); -verify.quickInfoIs("function divide(a: number, b: number): void", "this is divide function\n@paramTag { number } g this is optional param g"); +verify.quickInfoIs("function divide(a: number, b: number): void", "this is divide function"); goTo.marker('35aq'); verify.quickInfoIs("(parameter) a: number", "this is a"); goTo.marker('36'); -verify.currentSignatureHelpDocCommentIs("this is divide function\n@paramTag { number } g this is optional param g"); +verify.currentSignatureHelpDocCommentIs("this is divide function"); verify.currentParameterHelpArgumentDocCommentIs("this is b"); goTo.marker('36aq'); verify.quickInfoIs("(parameter) b: number", "this is b"); @@ -492,4 +492,4 @@ goTo.marker('49aq'); verify.quickInfoIs("(parameter) c: any", "this is info about b\nnot aligned text about parameter will eat only one space"); goTo.marker('50'); -verify.quickInfoIs("class NoQuickInfoClass", ""); \ No newline at end of file +verify.quickInfoIs("class NoQuickInfoClass", ""); diff --git a/tests/cases/fourslash/commentsFunctionExpression.ts b/tests/cases/fourslash/commentsFunctionExpression.ts index 048efa3c9c186..f22c49764ddee 100644 --- a/tests/cases/fourslash/commentsFunctionExpression.ts +++ b/tests/cases/fourslash/commentsFunctionExpression.ts @@ -64,25 +64,25 @@ verify.quickInfoIs('function anotherFunc(a: number): string', ''); goTo.marker('8'); verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', 'documentation\ninner docs '); goTo.marker('9'); -verify.quickInfoIs('(parameter) b: string', '{string} inner parameter '); +verify.quickInfoIs('(parameter) b: string', 'inner parameter '); goTo.marker('10'); verify.quickInfoIs('(local var) localVar: string', ''); goTo.marker('11'); verify.quickInfoIs('(local var) localVar: string', ''); goTo.marker('12'); -verify.quickInfoIs('(parameter) b: string', '{string} inner parameter '); +verify.quickInfoIs('(parameter) b: string', 'inner parameter '); goTo.marker('13'); verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', 'documentation\ninner docs '); goTo.marker('14'); -verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.quickInfoIs("var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('15'); verify.completionListContains('s', '(parameter) s: string', "the first parameter!\nparam on expression\nOn parameter "); goTo.marker('16'); -verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.quickInfoIs("var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('17'); -verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\nSummary on expression"); goTo.marker('18'); -verify.currentSignatureHelpDocCommentIs("On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression"); +verify.currentSignatureHelpDocCommentIs("On variable\nSummary on expression"); verify.currentParameterHelpArgumentDocCommentIs("the first parameter!\nparam on expression\nOn parameter "); diff --git a/tests/cases/fourslash/commentsLinePreservation.ts b/tests/cases/fourslash/commentsLinePreservation.ts index 012272d7544a9..a1b574ea33bbc 100644 --- a/tests/cases/fourslash/commentsLinePreservation.ts +++ b/tests/cases/fourslash/commentsLinePreservation.ts @@ -116,7 +116,7 @@ goTo.marker('c'); verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n\nThis is fourth Line"); goTo.marker('d'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('1'); verify.quickInfoIs(undefined, ""); @@ -126,17 +126,17 @@ goTo.marker('2'); verify.quickInfoIs(undefined, ""); goTo.marker('f'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('3'); verify.quickInfoIs(undefined, "first line of param\n\nparam information third line"); goTo.marker('g'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('4'); verify.quickInfoIs(undefined, "param information first line"); goTo.marker('h'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@random tag This should be third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('5'); verify.quickInfoIs(undefined, "param information first line\n\nparam information third line"); @@ -151,7 +151,7 @@ goTo.marker('7'); verify.quickInfoIs(undefined, "param information first line\n\nparam information third line"); goTo.marker('k'); -verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line\n@randomtag \n\n random information first line\n\n random information third line"); +verify.quickInfoIs(undefined, "This is firstLine\nThis is second Line"); goTo.marker('8'); verify.quickInfoIs(undefined, "hello "); diff --git a/tests/cases/fourslash/commentsModules.ts b/tests/cases/fourslash/commentsModules.ts index 9415c1bc85e7d..a501e561606fa 100644 --- a/tests/cases/fourslash/commentsModules.ts +++ b/tests/cases/fourslash/commentsModules.ts @@ -129,8 +129,8 @@ verify.memberListContains("c", "constructor m1.m2.c(): m1.m2.c", ""); verify.memberListContains("i", "var m1.m2.i: m1.m2.c", "i"); goTo.marker('9'); -verify.completionListContains("m2", "namespace m2", ""); -verify.quickInfoIs("namespace m2", ""); +verify.completionListContains("m2", "namespace m2", "namespace comment of m2.m3"); +verify.quickInfoIs("namespace m2", "namespace comment of m2.m3"); goTo.marker('10'); verify.memberListContains("m3", "namespace m2.m3"); @@ -141,12 +141,12 @@ verify.quickInfoIs("constructor m2.m3.c(): m2.m3.c", ""); verify.memberListContains("c", "constructor m2.m3.c(): m2.m3.c", ""); goTo.marker('12'); -verify.completionListContains("m3", "namespace m3", ""); -verify.quickInfoIs("namespace m3", ""); +verify.completionListContains("m3", "namespace m3", "namespace comment of m3.m4.m5"); +verify.quickInfoIs("namespace m3", "namespace comment of m3.m4.m5"); goTo.marker('13'); -verify.memberListContains("m4", "namespace m3.m4", ""); -verify.quickInfoIs("namespace m3.m4", ""); +verify.memberListContains("m4", "namespace m3.m4", "namespace comment of m3.m4.m5"); +verify.quickInfoIs("namespace m3.m4", "namespace comment of m3.m4.m5"); goTo.marker('14'); verify.memberListContains("m5", "namespace m3.m4.m5"); @@ -157,12 +157,12 @@ verify.quickInfoIs("constructor m3.m4.m5.c(): m3.m4.m5.c", ""); verify.memberListContains("c", "constructor m3.m4.m5.c(): m3.m4.m5.c", ""); goTo.marker('16'); -verify.completionListContains("m4", "namespace m4", ""); -verify.quickInfoIs("namespace m4", ""); +verify.completionListContains("m4", "namespace m4", "namespace comment of m4.m5.m6"); +verify.quickInfoIs("namespace m4", "namespace comment of m4.m5.m6"); goTo.marker('17'); -verify.memberListContains("m5", "namespace m4.m5", ""); -verify.quickInfoIs("namespace m4.m5", ""); +verify.memberListContains("m5", "namespace m4.m5", "namespace comment of m4.m5.m6"); +verify.quickInfoIs("namespace m4.m5", "namespace comment of m4.m5.m6"); goTo.marker('18'); verify.memberListContains("m6", "namespace m4.m5.m6"); @@ -178,11 +178,11 @@ verify.quickInfoIs("constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c", ""); goTo.marker('21'); verify.completionListContains("m5", "namespace m5"); -verify.quickInfoIs("namespace m5", ""); +verify.quickInfoIs("namespace m5", "namespace comment of m5.m6.m7"); goTo.marker('22'); verify.memberListContains("m6", "namespace m5.m6"); -verify.quickInfoIs("namespace m5.m6", ""); +verify.quickInfoIs("namespace m5.m6", "namespace comment of m5.m6.m7"); goTo.marker('23'); verify.memberListContains("m7", "namespace m5.m6.m7"); @@ -248,4 +248,4 @@ goTo.marker('39'); verify.quickInfoIs("(method) complexM.m2.c.foo2(): complexM.m1.c", ""); goTo.marker('40'); -verify.quickInfoIs("(method) complexM.m1.c.foo(): number", ""); \ No newline at end of file +verify.quickInfoIs("(method) complexM.m1.c.foo(): number", ""); diff --git a/tests/cases/fourslash/getJavaScriptQuickInfo1.ts b/tests/cases/fourslash/getJavaScriptQuickInfo1.ts index 71072f1699aa2..f10068eb61219 100644 --- a/tests/cases/fourslash/getJavaScriptQuickInfo1.ts +++ b/tests/cases/fourslash/getJavaScriptQuickInfo1.ts @@ -6,4 +6,4 @@ ////var /**/v; goTo.marker(); -verify.quickInfoIs('var v: new (p1: number) => string'); \ No newline at end of file +verify.quickInfoIs('var v: new (arg1: number) => string'); diff --git a/tests/cases/fourslash/getJavaScriptQuickInfo7.ts b/tests/cases/fourslash/getJavaScriptQuickInfo7.ts index 7b8d967d19070..d9f66a97eb885 100644 --- a/tests/cases/fourslash/getJavaScriptQuickInfo7.ts +++ b/tests/cases/fourslash/getJavaScriptQuickInfo7.ts @@ -19,4 +19,4 @@ goTo.marker(); verify.quickInfoExists(); verify.quickInfoIs('function a1(p: any): number', - 'This is a very cool function that is very nice.\n@returns something'); + 'This is a very cool function that is very nice.'); From 275a4bd4f3df74441b9cd56ac212fd37fb35f3b6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 10:05:56 -0700 Subject: [PATCH 4/9] Use enum for parser state instead of 2 booleans Plus cleanup some lint --- src/compiler/parser.ts | 30 ++++++++++++++++-------------- src/compiler/utilities.ts | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 342b711a5a6a7..445af2243df13 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6151,6 +6151,12 @@ namespace ts { return comment; } + const enum TagState { + BeginningOfLine, + SawAsterisk, + SavingComments + } + export function parseJSDocCommentWorker(start: number, length: number): JSDoc { const content = sourceText; start = start || 0; @@ -6359,8 +6365,7 @@ namespace ts { function parseTagComments(indent: number) { const comments: string[] = []; - let savingComments = false; - let seenAsterisk = true; + let state = TagState.SawAsterisk; let done = false; let margin: number | undefined; let text: string; @@ -6375,9 +6380,8 @@ namespace ts { text = scanner.getTokenText(); switch (token()) { case SyntaxKind.NewLineTrivia: - if (seenAsterisk) { - savingComments = false; - seenAsterisk = false; + if (state >= TagState.SawAsterisk) { + state = TagState.BeginningOfLine; comments.push(text); } indent = 0; @@ -6386,7 +6390,7 @@ namespace ts { done = true; break; case SyntaxKind.WhitespaceTrivia: - if (savingComments && seenAsterisk) { + if (state === TagState.SavingComments) { pushComment(text); } else { @@ -6398,18 +6402,16 @@ namespace ts { } break; case SyntaxKind.AsteriskToken: - if (!seenAsterisk) { + if (state === TagState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token - savingComments = false; + state = TagState.SawAsterisk; indent += text.length; + break; } - // FALLTHROUGH to gather comments + // FALLTHROUGH otherwise to record the * as a comment default: - if (seenAsterisk) { - savingComments = true; // leading identifiers start recording as well - pushComment(text); - } - seenAsterisk = true; + state = TagState.SavingComments; // leading identifiers start recording as well + pushComment(text); break; } if (!done) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 52683f0e74bf8..5e55627886678 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1380,7 +1380,7 @@ namespace ts { function getJSDocTags(node: Node, checkParentVariableStatement: boolean): JSDocTag[] { return getJSDocs(node, checkParentVariableStatement, docs => { - let result: JSDocTag[] = []; + const result: JSDocTag[] = []; for (const doc of docs) { if (doc.tags) { result.push(...doc.tags); From 21439a470ddd7e6a467777c76f26cde82da79578 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 18:41:03 -0700 Subject: [PATCH 5/9] Rebaseline tests to old emitter --- tests/baselines/reference/arrowFunctionErrorSpan.js | 4 +--- tests/baselines/reference/augmentExportEquals1.js | 4 ++-- tests/baselines/reference/augmentExportEquals1_1.js | 4 ++-- tests/baselines/reference/augmentExportEquals2.js | 4 ++-- tests/baselines/reference/augmentExportEquals2_1.js | 4 ++-- tests/baselines/reference/augmentedTypesExternalModule1.js | 2 +- .../blockScopedFunctionDeclarationInStrictModule.js | 2 +- tests/baselines/reference/callOverloads1.js | 2 +- tests/baselines/reference/callOverloads2.js | 2 +- tests/baselines/reference/callOverloads3.js | 2 +- tests/baselines/reference/callOverloads4.js | 2 +- tests/baselines/reference/callOverloads5.js | 2 +- tests/baselines/reference/collisionArgumentsFunction.js | 1 - tests/baselines/reference/collisionRestParameterFunction.js | 1 - .../reference/collisionThisExpressionAndParameter.js | 1 - tests/baselines/reference/commentInEmptyParameterList1.js | 2 +- .../reference/commentOnParenthesizedExpressionOpenParen1.js | 2 +- .../reference/commentsArgumentsOfCallExpression2.js | 2 +- tests/baselines/reference/commentsFunction.js | 4 ++-- tests/baselines/reference/commentsVarDecl.js | 6 +++--- tests/baselines/reference/computedPropertyNames48_ES5.js | 4 ++-- tests/baselines/reference/constructorOverloads1.js | 4 ++-- tests/baselines/reference/constructorOverloads2.js | 4 ++-- tests/baselines/reference/constructorOverloads3.js | 2 +- .../baselines/reference/contextuallyTypingRestParameters.js | 4 ++-- .../reference/declFileObjectLiteralWithAccessors.js | 4 ++-- .../reference/declFileObjectLiteralWithOnlyGetter.js | 4 ++-- .../reference/declFileObjectLiteralWithOnlySetter.js | 4 ++-- .../reference/es6ImportDefaultBindingWithExport.js | 2 +- tests/baselines/reference/es6ImportNameSpaceImportDts.js | 1 - .../reference/es6ImportNameSpaceImportNoNamedExports.js | 1 - .../reference/es6ImportNamedImportIdentifiersParsing.js | 1 - tests/baselines/reference/es6modulekindWithES5Target10.js | 1 - .../exportSpecifierReferencingOuterDeclaration4.js | 1 - tests/baselines/reference/genericConstraint3.js | 1 - .../inheritedMembersAndIndexSignaturesFromDifferentBases.js | 1 - ...inheritedMembersAndIndexSignaturesFromDifferentBases2.js | 1 - .../inheritedStringIndexersFromDifferentBaseTypes.js | 1 - .../inheritedStringIndexersFromDifferentBaseTypes2.js | 1 - tests/baselines/reference/jsxInvalidEsprimaTestSuite.js | 4 ++-- .../reference/nonConflictingRecursiveBaseTypeMembers.js | 1 - .../reference/objectTypesWithOptionalProperties2.js | 3 ++- .../reference/parseRegularExpressionMixedWithComments.js | 6 +++--- .../reference/parserGreaterThanTokenAmbiguity10.js | 1 - .../reference/parserGreaterThanTokenAmbiguity13.js | 2 +- .../reference/parserGreaterThanTokenAmbiguity15.js | 1 - .../reference/parserGreaterThanTokenAmbiguity18.js | 2 +- .../reference/parserGreaterThanTokenAmbiguity20.js | 1 - .../baselines/reference/parserGreaterThanTokenAmbiguity3.js | 2 +- .../baselines/reference/parserGreaterThanTokenAmbiguity5.js | 1 - .../baselines/reference/parserGreaterThanTokenAmbiguity8.js | 2 +- tests/baselines/reference/parserSkippedTokens5.js | 2 +- tests/baselines/reference/parserSkippedTokens7.js | 1 - tests/baselines/reference/parserSkippedTokens8.js | 2 +- tests/baselines/reference/parserSkippedTokens9.js | 1 - .../recursiveExportAssignmentAndFindAliasedType1.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType2.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType3.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType4.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType5.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType6.js | 2 +- .../recursiveExportAssignmentAndFindAliasedType7.js | 2 +- .../reference/thisInInvalidContextsExternalModule.js | 2 +- tests/baselines/reference/tsxParseTests2.js | 2 +- .../reference/typeAliasDoesntMakeModuleInstantiated.js | 1 - 65 files changed, 62 insertions(+), 84 deletions(-) diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.js b/tests/baselines/reference/arrowFunctionErrorSpan.js index 3ead7ed3b311e..2557113e89bd4 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.js +++ b/tests/baselines/reference/arrowFunctionErrorSpan.js @@ -83,9 +83,7 @@ f(// comment 1 // comment 2 function () { // comment 4 -} - // comment 5 -); +}); // body is not a block f(function (_) { return 1 + 2; }); diff --git a/tests/baselines/reference/augmentExportEquals1.js b/tests/baselines/reference/augmentExportEquals1.js index 6f7aab9269228..98322c01a34c9 100644 --- a/tests/baselines/reference/augmentExportEquals1.js +++ b/tests/baselines/reference/augmentExportEquals1.js @@ -32,5 +32,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals1_1.js b/tests/baselines/reference/augmentExportEquals1_1.js index 7023966344141..08f032ff33f1c 100644 --- a/tests/baselines/reference/augmentExportEquals1_1.js +++ b/tests/baselines/reference/augmentExportEquals1_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals2.js b/tests/baselines/reference/augmentExportEquals2.js index b444c16b6fcd4..fc373173e3c44 100644 --- a/tests/baselines/reference/augmentExportEquals2.js +++ b/tests/baselines/reference/augmentExportEquals2.js @@ -31,5 +31,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "./file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentExportEquals2_1.js b/tests/baselines/reference/augmentExportEquals2_1.js index afa78d1d981f5..9046157bb2626 100644 --- a/tests/baselines/reference/augmentExportEquals2_1.js +++ b/tests/baselines/reference/augmentExportEquals2_1.js @@ -29,5 +29,5 @@ define(["require", "exports"], function (require, exports) { //// [file3.js] define(["require", "exports", "file2"], function (require, exports) { "use strict"; - var a; -}); // should not work + var a; // should not work +}); diff --git a/tests/baselines/reference/augmentedTypesExternalModule1.js b/tests/baselines/reference/augmentedTypesExternalModule1.js index 01358a9e4af73..65525e8187eea 100644 --- a/tests/baselines/reference/augmentedTypesExternalModule1.js +++ b/tests/baselines/reference/augmentedTypesExternalModule1.js @@ -13,4 +13,4 @@ define(["require", "exports"], function (require, exports) { c5.prototype.foo = function () { }; return c5; }()); -}); // should be ok everywhere +}); diff --git a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js index 6d46015847881..d1a8091871c2e 100644 --- a/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js +++ b/tests/baselines/reference/blockScopedFunctionDeclarationInStrictModule.js @@ -14,4 +14,4 @@ define(["require", "exports"], function (require, exports) { foo(); // ok } return foo; -}); // not ok +}); diff --git a/tests/baselines/reference/callOverloads1.js b/tests/baselines/reference/callOverloads1.js index d441deb41d7d5..756a9099e4452 100644 --- a/tests/baselines/reference/callOverloads1.js +++ b/tests/baselines/reference/callOverloads1.js @@ -22,7 +22,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); function F1(a) { return a; } diff --git a/tests/baselines/reference/callOverloads2.js b/tests/baselines/reference/callOverloads2.js index 8db26c3b77143..b890ee8bde967 100644 --- a/tests/baselines/reference/callOverloads2.js +++ b/tests/baselines/reference/callOverloads2.js @@ -30,7 +30,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); function F1(s) { return s; } // error diff --git a/tests/baselines/reference/callOverloads3.js b/tests/baselines/reference/callOverloads3.js index ee49f4b329735..e5d678543c647 100644 --- a/tests/baselines/reference/callOverloads3.js +++ b/tests/baselines/reference/callOverloads3.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/callOverloads4.js b/tests/baselines/reference/callOverloads4.js index fa7a51ae8d10f..dfb274dfb6e35 100644 --- a/tests/baselines/reference/callOverloads4.js +++ b/tests/baselines/reference/callOverloads4.js @@ -23,7 +23,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/callOverloads5.js b/tests/baselines/reference/callOverloads5.js index d95485f85d7f5..cf159d309b0f2 100644 --- a/tests/baselines/reference/callOverloads5.js +++ b/tests/baselines/reference/callOverloads5.js @@ -24,7 +24,7 @@ var Foo = (function () { function Foo(x) { // WScript.Echo("Constructor function has executed"); } - Foo.prototype.bar1 = function (a) { /*WScript.Echo(a);*/ }; + Foo.prototype.bar1 = function (a) { }; return Foo; }()); //class Foo(s: String); diff --git a/tests/baselines/reference/collisionArgumentsFunction.js b/tests/baselines/reference/collisionArgumentsFunction.js index d59efc116ee2c..9ce4a5ab0e20b 100644 --- a/tests/baselines/reference/collisionArgumentsFunction.js +++ b/tests/baselines/reference/collisionArgumentsFunction.js @@ -90,4 +90,3 @@ function f42(i) { function f4NoError(arguments) { var arguments; // No error } - // no codegen no error diff --git a/tests/baselines/reference/collisionRestParameterFunction.js b/tests/baselines/reference/collisionRestParameterFunction.js index a9e3f510fa17d..8660e8f5db0ea 100644 --- a/tests/baselines/reference/collisionRestParameterFunction.js +++ b/tests/baselines/reference/collisionRestParameterFunction.js @@ -63,4 +63,3 @@ function f4(_i) { } function f4NoError(_i) { } - // no codegen no error diff --git a/tests/baselines/reference/collisionThisExpressionAndParameter.js b/tests/baselines/reference/collisionThisExpressionAndParameter.js index a445c35295b4d..bc15e4b56b50a 100644 --- a/tests/baselines/reference/collisionThisExpressionAndParameter.js +++ b/tests/baselines/reference/collisionThisExpressionAndParameter.js @@ -167,4 +167,3 @@ function f3(_this) { var _this = this; (function (x) { console.log(_this.x); }); } - // no code gen - no error diff --git a/tests/baselines/reference/commentInEmptyParameterList1.js b/tests/baselines/reference/commentInEmptyParameterList1.js index 09b34f93536a4..8f4e13d82d69d 100644 --- a/tests/baselines/reference/commentInEmptyParameterList1.js +++ b/tests/baselines/reference/commentInEmptyParameterList1.js @@ -3,5 +3,5 @@ function foo(/** nothing */) { } //// [commentInEmptyParameterList1.js] -function foo( /** nothing */) { +function foo() { } diff --git a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js index 7a7c25a9b4c0a..d014043dfe0a3 100644 --- a/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js +++ b/tests/baselines/reference/commentOnParenthesizedExpressionOpenParen1.js @@ -7,4 +7,4 @@ var f: () => any; //// [commentOnParenthesizedExpressionOpenParen1.js] var j; var f; -(/* Preserve */ j = f()); +(j = f()); diff --git a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js index f89e67ef3d8b3..a7065410ff4fe 100644 --- a/tests/baselines/reference/commentsArgumentsOfCallExpression2.js +++ b/tests/baselines/reference/commentsArgumentsOfCallExpression2.js @@ -14,7 +14,7 @@ foo( function foo(/*c1*/ x, /*d1*/ y, /*e1*/ w) { } var a, b; foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b); -foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + /*e3*/ b); +foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + b); foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b)); foo( /*c4*/ function () { }, diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index 86978d7bdf7ee..0ffb271410879 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -74,8 +74,8 @@ var fooFunc = function FooFunctionValue(/** fooFunctionValue param */ b) { return b; }; /// lamdaFoo var comment -var lambdaFoo = /** this is lambda comment*/ function (/**param a*/ a, /**param b*/ b) { return a + b; }; -var lambddaNoVarComment = /** this is lambda multiplication*/ function (/**param a*/ a, /**param b*/ b) { return a * b; }; +var lambdaFoo = function (/**param a*/ a, /**param b*/ b) { return a + b; }; +var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * b; }; lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment diff --git a/tests/baselines/reference/commentsVarDecl.js b/tests/baselines/reference/commentsVarDecl.js index e9b6776a6d902..5ff2a3c1c6a85 100644 --- a/tests/baselines/reference/commentsVarDecl.js +++ b/tests/baselines/reference/commentsVarDecl.js @@ -64,13 +64,13 @@ x = myVariable; /** jsdocstyle comment - only this comment should be in .d.ts file*/ var n = 30; /** var deckaration with comment on type as well*/ -var y = /** value comment */ 20; +var y = 20; /// var deckaration with comment on type as well var yy = /// value comment 20; /** comment2 */ -var z = /** lambda comment */ function (x, y) { return x + y; }; +var z = function (x, y) { return x + y; }; var z2; var x2 = z2; var n4; @@ -98,6 +98,6 @@ declare var y: number; declare var yy: number; /** comment2 */ declare var z: (x: number, y: number) => number; -declare var z2: /** type comment*/ (x: number) => string; +declare var z2: (x: number) => string; declare var x2: (x: number) => string; declare var n4: (x: number) => string; diff --git a/tests/baselines/reference/computedPropertyNames48_ES5.js b/tests/baselines/reference/computedPropertyNames48_ES5.js index f2610b7272a78..15123a98f302b 100644 --- a/tests/baselines/reference/computedPropertyNames48_ES5.js +++ b/tests/baselines/reference/computedPropertyNames48_ES5.js @@ -34,5 +34,5 @@ extractIndexer((_b = {}, extractIndexer((_c = {}, _c["" || 0] = "", _c -)); -var _a, _b, _c; // Should return any (widened form of undefined) +)); // Should return any (widened form of undefined) +var _a, _b, _c; diff --git a/tests/baselines/reference/constructorOverloads1.js b/tests/baselines/reference/constructorOverloads1.js index d62cb9530c505..47906974f6ea5 100644 --- a/tests/baselines/reference/constructorOverloads1.js +++ b/tests/baselines/reference/constructorOverloads1.js @@ -25,8 +25,8 @@ f1.bar2(); var Foo = (function () { function Foo(x) { } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; - Foo.prototype.bar2 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; + Foo.prototype.bar2 = function () { }; return Foo; }()); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads2.js b/tests/baselines/reference/constructorOverloads2.js index e8d11af405621..76481ec1bc691 100644 --- a/tests/baselines/reference/constructorOverloads2.js +++ b/tests/baselines/reference/constructorOverloads2.js @@ -34,7 +34,7 @@ var __extends = (this && this.__extends) || function (d, b) { var FooBase = (function () { function FooBase(x) { } - FooBase.prototype.bar1 = function () { /*WScript.Echo("base bar1");*/ }; + FooBase.prototype.bar1 = function () { }; return FooBase; }()); var Foo = (function (_super) { @@ -42,7 +42,7 @@ var Foo = (function (_super) { function Foo(x, y) { _super.call(this, x); } - Foo.prototype.bar1 = function () { /*WScript.Echo("bar1");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/constructorOverloads3.js b/tests/baselines/reference/constructorOverloads3.js index 7cc27fd5b42e1..61f0d50db03af 100644 --- a/tests/baselines/reference/constructorOverloads3.js +++ b/tests/baselines/reference/constructorOverloads3.js @@ -32,7 +32,7 @@ var Foo = (function (_super) { __extends(Foo, _super); function Foo(x, y) { } - Foo.prototype.bar1 = function () { /*WScript.Echo("Yo");*/ }; + Foo.prototype.bar1 = function () { }; return Foo; }(FooBase)); var f1 = new Foo("hey"); diff --git a/tests/baselines/reference/contextuallyTypingRestParameters.js b/tests/baselines/reference/contextuallyTypingRestParameters.js index 48589ade40865..17561f5d7fccb 100644 --- a/tests/baselines/reference/contextuallyTypingRestParameters.js +++ b/tests/baselines/reference/contextuallyTypingRestParameters.js @@ -9,9 +9,9 @@ var x: (...y: string[]) => void = function (.../*3*/y) { //// [contextuallyTypingRestParameters.js] var x = function () { - var /*3*/ y = []; + var y = []; for (var _i = 0; _i < arguments.length; _i++) { - /*3*/ y[_i - 0] = arguments[_i]; + y[_i - 0] = arguments[_i]; } var t = y; var x2 = t; // This should be error diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js index adc185e269f88..7886736f7e452 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.js +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.js @@ -12,7 +12,7 @@ var /*2*/x = point.x; point./*3*/x = 30; //// [declFileObjectLiteralWithAccessors.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { b: 10, get x() { return x; }, @@ -22,7 +22,7 @@ function /*1*/ makePoint(x) { ; var /*4*/ point = makePoint(2); var /*2*/ x = point.x; -point./*3*/ x = 30; +point.x = 30; //// [declFileObjectLiteralWithAccessors.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js index 96b4de87bef53..eb440c028d582 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlyGetter.js @@ -10,14 +10,14 @@ var /*2*/x = point./*3*/x; //// [declFileObjectLiteralWithOnlyGetter.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { get x() { return x; }, }; } ; var /*4*/ point = makePoint(2); -var /*2*/ x = point./*3*/ x; +var /*2*/ x = point.x; //// [declFileObjectLiteralWithOnlyGetter.d.ts] diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js index 44b28a9bdb2df..f7a48fe810c45 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.js @@ -10,7 +10,7 @@ var /*3*/point = makePoint(2); point./*2*/x = 30; //// [declFileObjectLiteralWithOnlySetter.js] -function /*1*/ makePoint(x) { +function makePoint(x) { return { b: 10, set x(a) { this.b = a; } @@ -18,7 +18,7 @@ function /*1*/ makePoint(x) { } ; var /*3*/ point = makePoint(2); -point./*2*/ x = 30; +point.x = 30; //// [declFileObjectLiteralWithOnlySetter.d.ts] diff --git a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js index 1e6f49e241448..cc90d28091478 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingWithExport.js @@ -21,7 +21,7 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; exports.x = server_1.default; -}); // non referenced +}); //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportDts.js b/tests/baselines/reference/es6ImportNameSpaceImportDts.js index 0b522776c4b24..cf66c08331e3a 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportDts.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportDts.js @@ -22,7 +22,6 @@ exports.c = c; "use strict"; var nameSpaceBinding = require("./server"); exports.x = new nameSpaceBinding.c(); - // unreferenced //// [server.d.ts] diff --git a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js index 79c588dc27701..8ece816fd3b6c 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportNoNamedExports.js @@ -14,4 +14,3 @@ var a = 10; module.exports = a; //// [es6ImportNameSpaceImportNoNamedExports_1.js] "use strict"; - // error diff --git a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js index a9a843f3cc9c0..8db7fcd6f9c57 100644 --- a/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js +++ b/tests/baselines/reference/es6ImportNamedImportIdentifiersParsing.js @@ -7,4 +7,3 @@ import { default as yield } from "somemodule"; // no error import { default as default } from "somemodule"; // default as is ok, error of default binding name //// [es6ImportNamedImportIdentifiersParsing.js] - // default as is ok, error of default binding name diff --git a/tests/baselines/reference/es6modulekindWithES5Target10.js b/tests/baselines/reference/es6modulekindWithES5Target10.js index 015a64c3bc012..b8a66241780ef 100644 --- a/tests/baselines/reference/es6modulekindWithES5Target10.js +++ b/tests/baselines/reference/es6modulekindWithES5Target10.js @@ -8,4 +8,3 @@ namespace N { export = N; // Error //// [es6modulekindWithES5Target10.js] - // Error diff --git a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js index 1b8e4dd5c4b5c..1badf46999668 100644 --- a/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js +++ b/tests/baselines/reference/exportSpecifierReferencingOuterDeclaration4.js @@ -12,4 +12,3 @@ export declare function bar(): X.bar; // error //// [exportSpecifierReferencingOuterDeclaration2_A.js] //// [exportSpecifierReferencingOuterDeclaration2_B.js] "use strict"; - // error diff --git a/tests/baselines/reference/genericConstraint3.js b/tests/baselines/reference/genericConstraint3.js index 657600ba41a99..59548c4f4d70e 100644 --- a/tests/baselines/reference/genericConstraint3.js +++ b/tests/baselines/reference/genericConstraint3.js @@ -4,4 +4,3 @@ interface A> { x: U; } interface B extends A<{}, { x: {} }> { } // Should not produce an error //// [genericConstraint3.js] - // Should not produce an error diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js index 26ef7ca775920..f4ea5f07eb9b4 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.js @@ -28,4 +28,3 @@ interface G extends A, B, C, E { } // should only report one error interface H extends A, F { } // Should report no error at all because error is internal to F //// [inheritedMembersAndIndexSignaturesFromDifferentBases.js] - // Should report no error at all because error is internal to F diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js index 9291ab53c1c3a..8a3b2f8d0328e 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases2.js @@ -10,4 +10,3 @@ interface B { interface C extends B, A { } // Should succeed //// [inheritedMembersAndIndexSignaturesFromDifferentBases2.js] - // Should succeed diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js index c7a008f01fb0c..1645dd10a552a 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.js @@ -29,4 +29,3 @@ interface D2 { interface E2 extends A2, D2 { } // error //// [inheritedStringIndexersFromDifferentBaseTypes.js] - // error diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js index 0580b145901b5..aa837b5cf2e6a 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.js @@ -25,4 +25,3 @@ interface F extends A, D { } // ok because we overrode D's number index signature //// [inheritedStringIndexersFromDifferentBaseTypes2.js] - // ok because we overrode D's number index signature diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js index 85d0d3687be19..7f01666bd7821 100644 --- a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js @@ -62,7 +62,7 @@ a['foo'] > ; ; ; var x =
one
two
;; -var x =
one
/* intervening comment */ /* intervening comment */
two
;; +var x =
one
/* intervening comment */ /* intervening comment */
two
;;
{"str"}}; id="b" />;
>; @@ -76,4 +76,4 @@ var x =
one
/* intervening comment */ /* intervening comment */
; ; }; -/*hai*/ /*hai*/asdf/>;; + /*hai*//*hai*/asdf/>;; diff --git a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js index 9663da873b843..6e77029fa94f5 100644 --- a/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js +++ b/tests/baselines/reference/nonConflictingRecursiveBaseTypeMembers.js @@ -10,4 +10,3 @@ interface B { interface C extends A, B { } // Should not be an error //// [nonConflictingRecursiveBaseTypeMembers.js] - // Should not be an error diff --git a/tests/baselines/reference/objectTypesWithOptionalProperties2.js b/tests/baselines/reference/objectTypesWithOptionalProperties2.js index 28470e049830b..eabb1a153a6e6 100644 --- a/tests/baselines/reference/objectTypesWithOptionalProperties2.js +++ b/tests/baselines/reference/objectTypesWithOptionalProperties2.js @@ -42,5 +42,6 @@ var C2 = (function () { return C2; }()); var b = { - x: function () { }, 1: // error + x: function () { }, 1: // error + // error }; diff --git a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js index 0ef42cf2ce1b4..78752a77f75c5 100644 --- a/tests/baselines/reference/parseRegularExpressionMixedWithComments.js +++ b/tests/baselines/reference/parseRegularExpressionMixedWithComments.js @@ -8,7 +8,7 @@ var regex5 = /**// asdf/**/ /; //// [parseRegularExpressionMixedWithComments.js] var regex1 = / asdf /; -var regex2 = /**/ / asdf /; +var regex2 = / asdf /; var regex3 = 1; -var regex4 = /**/ Math.pow(/ /, /asdf /); -var regex5 = /**/ Math.pow(/ asdf/, / /); +var regex4 = Math.pow(/ /, /asdf /); +var regex5 = Math.pow(/ asdf/, / /); diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js index eb76d7e0d7cc3..862722b1a73c4 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity10.js] 1 - // before >>> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js index 5be4da1c04e81..49130a9dd136b 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity13.js @@ -2,5 +2,5 @@ 1 >>/**/= 2; //// [parserGreaterThanTokenAmbiguity13.js] -1 >> /**/ ; +1 >> ; /**/ 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js index 8fadea77fdcd4..b6f905e12e77a 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity15.js] 1 - // before >>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js index 4cf227f27488d..71527689b2cda 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity18.js @@ -2,5 +2,5 @@ 1 >>>/**/= 2; //// [parserGreaterThanTokenAmbiguity18.js] -1 >>> /**/ ; +1 >>> ; /**/ 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js index ab86deeb0d21a..01d1d6401f2a6 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity20.js] 1 - // Before >>>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js index f692d1a6324c2..79f8c139260d1 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity3.js @@ -2,4 +2,4 @@ 1 >/**/> 2; //// [parserGreaterThanTokenAmbiguity3.js] -1 > /**/ /**/ > 2; +1 > /**/ > 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js index 24aa9e5316a35..c65b76f504a0b 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js @@ -6,6 +6,5 @@ //// [parserGreaterThanTokenAmbiguity5.js] 1 - // before >> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js index d8ea6134a5813..0006c03219a39 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity8.js @@ -2,4 +2,4 @@ 1 >>/**/> 2; //// [parserGreaterThanTokenAmbiguity8.js] -1 >> /**/ /**/ > 2; +1 >> /**/ > 2; diff --git a/tests/baselines/reference/parserSkippedTokens5.js b/tests/baselines/reference/parserSkippedTokens5.js index 665db1ef70d99..359a98a5969e5 100644 --- a/tests/baselines/reference/parserSkippedTokens5.js +++ b/tests/baselines/reference/parserSkippedTokens5.js @@ -2,4 +2,4 @@ \ /*foo*/ ; //// [parserSkippedTokens5.js] -/*foo*/ ; +; diff --git a/tests/baselines/reference/parserSkippedTokens7.js b/tests/baselines/reference/parserSkippedTokens7.js index b3aa40d905707..2115614ea1f3e 100644 --- a/tests/baselines/reference/parserSkippedTokens7.js +++ b/tests/baselines/reference/parserSkippedTokens7.js @@ -2,4 +2,3 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens7.js] - /*bar*/ diff --git a/tests/baselines/reference/parserSkippedTokens8.js b/tests/baselines/reference/parserSkippedTokens8.js index d8433bbd34cd3..c9f00f4b85bae 100644 --- a/tests/baselines/reference/parserSkippedTokens8.js +++ b/tests/baselines/reference/parserSkippedTokens8.js @@ -3,4 +3,4 @@ /*foo*/ \ /*bar*/ //// [parserSkippedTokens8.js] -; /*bar*/ +; diff --git a/tests/baselines/reference/parserSkippedTokens9.js b/tests/baselines/reference/parserSkippedTokens9.js index cabf3a48e5631..d693b99b2eabc 100644 --- a/tests/baselines/reference/parserSkippedTokens9.js +++ b/tests/baselines/reference/parserSkippedTokens9.js @@ -4,4 +4,3 @@ //// [parserSkippedTokens9.js] ; // existing trivia - /*bar*/ diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js index 96fff1f8f3346..d759bc2f296a7 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType1.js @@ -29,4 +29,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType1_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js index e8262c86b4f50..7704b38f68ddb 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType2.js @@ -33,4 +33,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType2_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js index 39303b463bad6..a46be3bdafc94 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType3.js @@ -37,4 +37,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType3_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js index 80a4408b10d2b..8ccd6ecf5603c 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType4.js @@ -31,4 +31,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType4_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js index 69f6ff07bd89b..4602ed554e59d 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType5.js @@ -40,4 +40,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType5_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js index 277a8a168da0b..d3487519218f7 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType6.js @@ -49,4 +49,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType6_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js index fcab82802b207..9a29c2bf9498c 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.js @@ -51,4 +51,4 @@ define(["require", "exports"], function (require, exports) { //// [recursiveExportAssignmentAndFindAliasedType7_moduleA.js] define(["require", "exports"], function (require, exports) { "use strict"; -}); // This should result in type ClassB +}); diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index 00553a3fbbaf9..2e7e6d8b47cca 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -107,4 +107,4 @@ var SomeEnum; SomeEnum[SomeEnum["A"] = this] = "A"; SomeEnum[SomeEnum["B"] = this.spaaaace] = "B"; // Also should not be allowed })(SomeEnum || (SomeEnum = {})); -module.exports = this; // Should be an error +module.exports = this; diff --git a/tests/baselines/reference/tsxParseTests2.js b/tests/baselines/reference/tsxParseTests2.js index c09e9d2c3cb0c..b0cf54f8d1f02 100644 --- a/tests/baselines/reference/tsxParseTests2.js +++ b/tests/baselines/reference/tsxParseTests2.js @@ -8,4 +8,4 @@ var x =
; //// [file.jsx] -var x =
; +var x =
; diff --git a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js index af2287ef27f38..861e20cb0d145 100644 --- a/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js +++ b/tests/baselines/reference/typeAliasDoesntMakeModuleInstantiated.js @@ -11,4 +11,3 @@ declare module m { declare var m: m.IStatic; // Should be ok to have var 'm' as module is non instantiated //// [typeAliasDoesntMakeModuleInstantiated.js] - // Should be ok to have var 'm' as module is non instantiated From ff9ccc9b059bd122e8ea88dd7bc08e4f2bf1bf7f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 18:41:29 -0700 Subject: [PATCH 6/9] Undo scanner/emitter changes --- src/compiler/emitter.ts | 74 +++++++++++++-------------------------- src/compiler/scanner.ts | 19 ++++------ src/compiler/utilities.ts | 8 ++++- 3 files changed, 38 insertions(+), 63 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ce8d8e44d394b..574c496d747ee 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -851,7 +851,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean, commentsBeforePunctuation: boolean) { + function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean) { Debug.assert(nodes.length > 0); increaseIndent(); @@ -877,9 +877,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(nodes[i]); - if (commentsBeforePunctuation) { - emitLeadingCommentsAtEnd(nodes[i]); - } } if (nodes.hasTrailingComma && allowTrailingComma) { @@ -898,7 +895,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } - function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, commentsBeforePunctuation?: boolean, emitNode?: (node: TNode) => void): number { + function emitList(nodes: TNode[], start: number, count: number, multiLine: boolean, trailingComma: boolean, leadingComma?: boolean, noTrailingNewLine?: boolean, emitNode?: (node: TNode) => void): number { if (!emitNode) { emitNode = emit; } @@ -916,10 +913,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } } const node = nodes[start + i]; + // This emitting is to make sure we emit following comment properly + // ...(x, /*comment1*/ y)... + // ^ => node.pos + // "comment1" is not considered leading comment for "y" but rather + // considered as trailing comment of the previous node. + emitTrailingCommentsOfPosition(node.pos); emitNode(node); - if (commentsBeforePunctuation) { - emitLeadingCommentsAtEnd(nodes[i]); - } leadingComma = true; } if (trailingComma) { @@ -1897,7 +1897,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else if (languageVersion >= ScriptTarget.ES6 || !forEach(elements, isSpreadElementExpression)) { write("["); - emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false, /*commentsBeforePunctuation*/ true); + emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false); write("]"); } else { @@ -1921,7 +1921,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // then try to preserve the original shape of the object literal. // Otherwise just try to preserve the formatting. if (numElements === properties.length) { - emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true, /*commentsBeforePunctuation*/ true); + emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces*/ true); } else { const multiLine = node.multiLine; @@ -2166,6 +2166,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitPropertyAssignment(node: PropertyDeclaration) { emit(node.name); write(": "); + // This is to ensure that we emit comment in the following case: + // For example: + // obj = { + // id: /*comment1*/ ()=>void + // } + // "comment1" is not considered to be leading comment for node.initializer + // but rather a trailing comment on the previous node. + emitTrailingCommentsOfPosition(node.initializer.pos); emit(node.initializer); } @@ -2277,7 +2285,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(node.expression); - emitLeadingCommentsAtEnd(node.expression); const dotRangeStart = nodeIsSynthesized(node.expression) ? -1 : node.expression.end; const dotRangeEnd = nodeIsSynthesized(node.expression) ? -1 : skipTrivia(currentText, node.expression.end) + 1; const dotToken = { pos: dotRangeStart, end: dotRangeEnd }; @@ -2494,17 +2501,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitThis(expression); if (node.arguments.length) { write(", "); - emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); - emitLeadingCommentsAtEnd(node.arguments); } write(")"); } else { write("("); - emitTrailingCommentsOfPosition(node.arguments.pos); emitCommaList(node.arguments); - emitLeadingCommentsAtEnd(node.arguments); write(")"); } } @@ -2605,7 +2608,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write("("); emit(node.expression); - emitLeadingCommentsAtEnd(node.expression); write(")"); } @@ -2884,7 +2886,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else { emit(node.left); - emitLeadingCommentsAtEnd(node.left); // Add indentation before emit the operator if the operator is on different line // For example: // 3 @@ -3897,7 +3898,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emitNodeWithCommentsAndWithoutSourcemap(node.name); emitEnd(node.name); - emitLeadingCommentsAtEnd(node.name); } function createVoidZero(): Expression { @@ -4040,7 +4040,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emit(name); } - emitLeadingCommentsAtEnd(name); write(" = "); emit(value); }); @@ -4592,7 +4591,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge emitStart(restParam); write("var "); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); - emitLeadingCommentsAtEnd(restParam.name); write(" = [];"); emitEnd(restParam); emitTrailingComments(restParam); @@ -4614,7 +4612,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge writeLine(); emitStart(restParam); emitNodeWithCommentsAndWithoutSourcemap(restParam.name); - emitLeadingCommentsAtEnd(restParam.name); write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];"); emitEnd(restParam); decreaseIndent(); @@ -4636,7 +4633,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function emitDeclarationName(node: Declaration) { if (node.name) { emitNodeWithCommentsAndWithoutSourcemap(node.name); - emitLeadingCommentsAtEnd(node.name); } else { write(getGeneratedNameForNode(node)); @@ -4664,7 +4660,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const { kind, parent } = node; if (kind !== SyntaxKind.MethodDeclaration && kind !== SyntaxKind.MethodSignature && - kind !== SyntaxKind.ArrowFunction && parent && parent.kind !== SyntaxKind.PropertyAssignment && parent.kind !== SyntaxKind.CallExpression && @@ -4739,11 +4734,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const parameters = node.parameters; const skipCount = node.parameters.length && (node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0; const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0; - emitTrailingCommentsOfPosition(node.parameters.pos); - emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ false, /*commentsBeforePunctuation*/ true); - if ((parameters.length - omitCount - skipCount) <= 0) { - emitLeadingCommentsAtEnd(node.parameters); - } + emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false); } write(")"); decreaseIndent(); @@ -5800,7 +5791,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => emit(decorator.expression)); if (firstParameterDecorator) { argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0); @@ -5900,7 +5891,7 @@ const _super = (function (geti, seti) { writeLine(); const decoratorCount = decorators ? decorators.length : 0; - let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, + let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => emit(decorator.expression)); if (firstParameterDecorator) { @@ -5942,7 +5933,7 @@ const _super = (function (geti, seti) { for (const parameter of node.parameters) { if (nodeIsDecorated(parameter)) { const decorators = parameter.decorators; - argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, /*commentsBeforePunctuation*/ false, decorator => { + argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, decorator => { write(`__param(${parameterIndex}, `); emit(decorator.expression); write(")"); @@ -6356,7 +6347,6 @@ const _super = (function (geti, seti) { emitExpressionForPropertyName(node.name); emitEnd(node); write(";"); - emitLeadingCommentsAtEnd(node.name); } function writeEnumMemberDeclarationValue(member: EnumMember) { @@ -8319,11 +8309,8 @@ const _super = (function (geti, seti) { /** * Emit trailing comments at the position. The term trailing comment is used here to describe following comment: - * x, /*comment1* / // comment2 - * ^ => pos; the function will emit "comment1" and "comment2" in the emitJS - * However, * x /*comment1* /, y - * 'comment1' is actually a leading comment of ',' and needs to be emitted using emitLeadingCommentsAtEnd + * ^ => pos; the function will emit "comment1" */ function emitTrailingCommentsOfPosition(pos: number) { if (compilerOptions.removeComments) { @@ -8336,18 +8323,7 @@ const _super = (function (geti, seti) { emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment); } - /** - * Emit leading comments for the token after the current token. - * This is only needed for punctuation tokens. For example, in - * x /*comment1* /, y - * 'comment1' is a leading comment of ',' but needs to be emitted - * from x because there is no token for ','. - */ - function emitLeadingCommentsAtEnd(node: Node | NodeArray) { - emitLeadingCommentsOfPositionWorker(node.end, /*trailingSeparator*/ false); - } - - function emitLeadingCommentsOfPositionWorker(pos: number, trailingSeparator = true) { + function emitLeadingCommentsOfPositionWorker(pos: number) { if (compilerOptions.removeComments) { return; } @@ -8365,7 +8341,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - emitComments(currentText, currentLineMap, writer, leadingComments, trailingSeparator, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); } function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index d8cfc39db87ba..a714320639f39 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -599,11 +599,10 @@ namespace ts { * If false, whitespace is skipped until the first line break and comments between that location * and the next token are returned. * If true, comments occurring between the given position and the next line break are returned. - * If there is no line break, then no comments are returned. */ function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] { let result: CommentRange[]; - let needToSkipTrailingComment = pos > 0; + let collecting = trailing || pos === 0; while (pos < text.length) { const ch = text.charCodeAt(pos); switch (ch) { @@ -616,11 +615,7 @@ namespace ts { if (trailing) { return result; } - else if (needToSkipTrailingComment) { - // skip the first line if not trailing (it'll be part of the trailing comment). - needToSkipTrailingComment = false; - result = undefined; - } + collecting = true; if (result && result.length) { lastOrUndefined(result).hasTrailingNewLine = true; } @@ -656,13 +651,11 @@ namespace ts { pos++; } } - - // if we are at the end of the file, don't add trailing comments. - // end-of-file comments are added as leading comment of the end-of-file token. - if (pos < text.length || !trailing) { + if (collecting) { if (!result) { result = []; } + result.push({ pos: startPos, end: pos, hasTrailingNewLine, kind }); } continue; @@ -678,10 +671,10 @@ namespace ts { } break; } - return !trailing ? result : undefined; + return result; } - return !trailing ? result : undefined; + return result; } export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5e55627886678..f6f8b1f66b207 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -596,7 +596,13 @@ namespace ts { } export function getJsDocCommentsFromText(node: Node, text: string) { - return filter(getLeadingCommentRanges(text, node.pos), isJsDocComment); + const commentRanges = (node.kind === SyntaxKind.Parameter || + node.kind === SyntaxKind.TypeParameter || + node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.ArrowFunction) ? + concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : + getLeadingCommentRangesOfNodeFromText(node, text); + return filter(commentRanges, isJsDocComment); function isJsDocComment(comment: CommentRange) { // True if the comment starts with '/**' but not if it is '/**/' From 643cf302c63fcd107d336c8f8ddd99d81cb8bf78 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 1 Sep 2016 21:39:24 -0700 Subject: [PATCH 7/9] Use getJsDocFromText to get trailing comments Also update a couple of missed spots in the previous undo commits --- src/compiler/emitter.ts | 6 +----- src/compiler/parser.ts | 2 +- tests/baselines/reference/errorSupression1.js | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 574c496d747ee..1821acd0a1f7f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -8288,11 +8288,7 @@ const _super = (function (geti, seti) { emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments); // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space - // However, a leading mid-line comment of the end of file token is emitted with spaces before, - // as if it were a trailing comment of the previous token - const commentStartsInMidLine = leadingComments && leadingComments.length && leadingComments[0].pos - 1 > 0 && currentText.charCodeAt(leadingComments[0].pos - 1) !== 10; - const isEndOfFile = node.kind === SyntaxKind.EndOfFileToken && commentStartsInMidLine; - emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ !isEndOfFile, newLine, writeComment); + emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment); } function emitTrailingComments(node: Node) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 445af2243df13..59fc1ef004b22 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -652,7 +652,7 @@ namespace ts { function addJSDocComment(node: T): T { - const comments = getLeadingCommentRangesOfNode(node, sourceFile); + const comments = getJsDocCommentsFromText(node, sourceFile.text); if (comments) { for (const comment of comments) { const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 285aa525b5fb0..77545131ce344 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -18,4 +18,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); - // So we don't want an error on 'concat'. +// So we don't want an error on 'concat'. From f8e192afb032bc5e1309e939d764d8a0df073e74 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 2 Sep 2016 09:09:02 -0700 Subject: [PATCH 8/9] Use a state enum to parse top-level jsdoc comments Also use a `pushComments` function, which fixes a spacing bug. --- src/compiler/parser.ts | 126 ++++++++---------- .../cases/fourslash/commentsCommentParsing.ts | 14 +- 2 files changed, 64 insertions(+), 76 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59fc1ef004b22..fdc1ccefcd7f6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6151,10 +6151,10 @@ namespace ts { return comment; } - const enum TagState { + const enum JSDocState { BeginningOfLine, SawAsterisk, - SavingComments + SavingComments, } export function parseJSDocCommentWorker(start: number, length: number): JSDoc { @@ -6180,93 +6180,81 @@ namespace ts { scanner.scanRange(start + 3, length - 5, () => { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. - let canParseTag = true; - let seenAsterisk = true; let advanceToken = true; + let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; - let text: string; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } nextJSDocToken(); while (token() === SyntaxKind.WhitespaceTrivia) { nextJSDocToken(); } if (token() === SyntaxKind.NewLineTrivia) { - canParseTag = true; - seenAsterisk = false; + state = JSDocState.BeginningOfLine; nextJSDocToken(); } while (token() !== SyntaxKind.EndOfFileToken) { switch (token()) { case SyntaxKind.AtToken: - if (canParseTag) { + if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingNewlines(comments); parseTag(indent); - // This will take us past the end of the line, so it's OK to parse a tag on the next pass through the loop - // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. But real-world comments may break this rule. - seenAsterisk = false; + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. + // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning + // for malformed examples like `/** @param {string} x @returns {number} the length */` + state = JSDocState.BeginningOfLine; advanceToken = false; margin = undefined; + indent++; } else { - comments.push(scanner.getTokenText()); + pushComment(scanner.getTokenText()); } - indent++; break; - case SyntaxKind.NewLineTrivia: - // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet comments.push(scanner.getTokenText()); - canParseTag = true; - seenAsterisk = false; + state = JSDocState.BeginningOfLine; indent = 0; break; - case SyntaxKind.AsteriskToken: - text = scanner.getTokenText(); - if (seenAsterisk) { + const asterisk = scanner.getTokenText(); + if (state === JSDocState.SawAsterisk) { // If we've already seen an asterisk, then we can no longer parse a tag on this line - canParseTag = false; - comments.push(text); - if (!margin) { - margin = indent; - } + state = JSDocState.SavingComments; + pushComment(asterisk); + } + else { + // Ignore the first asterisk on a line + state = JSDocState.SawAsterisk; + indent += asterisk.length; } - // Ignore the first asterisk on a line - seenAsterisk = true; - indent += text.length; break; - case SyntaxKind.Identifier: // Anything else is doc comment text. We just save it. Because it // wasn't a tag, we can no longer parse a tag on this line until we hit the next // line break. - text = scanner.getTokenText(); - comments.push(text); - if (!margin) { - margin = indent; - } - canParseTag = false; - indent += text.length; + pushComment(scanner.getTokenText()); + state = JSDocState.SavingComments; break; - - case SyntaxKind.WhitespaceTrivia: - // only collect whitespace if we *know* that we're just looking at comments, not a possible jsdoc tag - text = scanner.getTokenText(); - if (!canParseTag || margin !== undefined && indent + text.length > margin) { - comments.push(text.slice(margin - indent - 1)); + // only collect whitespace if we're already saving comments or have just crossed the comment indent margin + const whitespace = scanner.getTokenText(); + if (state === JSDocState.SavingComments || margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent - 1)); } - indent += text.length; + indent += whitespace.length; break; - case SyntaxKind.EndOfFileToken: break; - default: - text = scanner.getTokenText(); - comments.push(text); - indent += text.length; + pushComment(scanner.getTokenText()); break; } if (advanceToken) { @@ -6365,10 +6353,8 @@ namespace ts { function parseTagComments(indent: number) { const comments: string[] = []; - let state = TagState.SawAsterisk; - let done = false; + let state = JSDocState.SawAsterisk; let margin: number | undefined; - let text: string; function pushComment(text: string) { if (!margin) { margin = indent; @@ -6376,47 +6362,49 @@ namespace ts { comments.push(text); indent += text.length; } - while (!done && token() !== SyntaxKind.EndOfFileToken) { - text = scanner.getTokenText(); + while (token() !== SyntaxKind.AtToken && token() !== SyntaxKind.EndOfFileToken) { switch (token()) { case SyntaxKind.NewLineTrivia: - if (state >= TagState.SawAsterisk) { - state = TagState.BeginningOfLine; - comments.push(text); + if (state >= JSDocState.SawAsterisk) { + state = JSDocState.BeginningOfLine; + comments.push(scanner.getTokenText()); } indent = 0; break; case SyntaxKind.AtToken: - done = true; + // Done break; case SyntaxKind.WhitespaceTrivia: - if (state === TagState.SavingComments) { - pushComment(text); + if (state === JSDocState.SavingComments) { + pushComment(scanner.getTokenText()); } else { + const whitespace = scanner.getTokenText(); // if the whitespace crosses the margin, take only the whitespace that passes the margin - if (margin !== undefined && indent + text.length > margin) { - comments.push(text.slice(margin - indent - 1)); + if (margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent - 1)); } - indent += text.length; + indent += whitespace.length; } break; case SyntaxKind.AsteriskToken: - if (state === TagState.BeginningOfLine) { + if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token - state = TagState.SawAsterisk; - indent += text.length; + state = JSDocState.SawAsterisk; + indent += scanner.getTokenText().length; break; } // FALLTHROUGH otherwise to record the * as a comment default: - state = TagState.SavingComments; // leading identifiers start recording as well - pushComment(text); + state = JSDocState.SavingComments; // leading identifiers start recording as well + pushComment(scanner.getTokenText()); break; } - if (!done) { - nextJSDocToken(); + if (token() === SyntaxKind.AtToken) { + // Done + break; } + nextJSDocToken(); } removeLeadingNewlines(comments); diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index a0a86cbc75cf6..53c459c9fc168 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -351,39 +351,39 @@ verify.completionListContains("multiply", "function multiply(a: number, b: numbe verify.completionListContains("f1", "function f1(a: number): any (+1 overload)", "fn f1 with number"); goTo.marker('28'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('28q'); -verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{()=>string; } } f this is optional param f"); +verify.quickInfoIs("function subtract(a: number, b: number, c?: () => string, d?: () => string, e?: () => string, f?: () => string): void", "This is subtract function{ () => string; } } f this is optional param f"); goTo.marker('28aq'); verify.quickInfoIs("(parameter) a: number", ""); goTo.marker('29'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is about b"); goTo.marker('29aq'); verify.quickInfoIs("(parameter) b: number", "this is about b"); goTo.marker('30'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param c"); goTo.marker('30aq'); verify.quickInfoIs("(parameter) c: () => string", "this is optional param c"); goTo.marker('31'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param d"); goTo.marker('31aq'); verify.quickInfoIs("(parameter) d: () => string", "this is optional param d"); goTo.marker('32'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs("this is optional param e"); goTo.marker('32aq'); verify.quickInfoIs("(parameter) e: () => string", "this is optional param e"); goTo.marker('33'); -verify.currentSignatureHelpDocCommentIs("This is subtract function{()=>string; } } f this is optional param f"); +verify.currentSignatureHelpDocCommentIs("This is subtract function{ () => string; } } f this is optional param f"); verify.currentParameterHelpArgumentDocCommentIs(""); goTo.marker('33aq'); verify.quickInfoIs("(parameter) f: () => string", ""); From e2ff42f4536c33085b216965b654a04ddce6d7a3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 14 Sep 2016 16:25:17 -0700 Subject: [PATCH 9/9] Add comment explaining a magic constant in parser --- src/compiler/parser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fdc1ccefcd7f6..5037256d59f4b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6183,6 +6183,7 @@ namespace ts { let advanceToken = true; let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; + // + 4 for leading '/** ' let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; function pushComment(text: string) { if (!margin) {