mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #4978 from Microsoft/expandDocTemplateCoverage
Expand JSDoc template generation locations (to 'master')
This commit is contained in:
@@ -621,7 +621,7 @@ namespace ts {
|
||||
return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression);
|
||||
}
|
||||
|
||||
export function isFunctionLike(node: Node): boolean {
|
||||
export function isFunctionLike(node: Node): node is FunctionLikeDeclaration {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
|
||||
@@ -1908,7 +1908,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
if (actual.newText !== expected.newText) {
|
||||
this.raiseError(name + ' failed - expected insertion:\n' + expected.newText + '\nactual insertion:\n' + actual.newText);
|
||||
this.raiseError(name + ' failed - expected insertion:\n' + this.clarifyNewlines(expected.newText) + '\nactual insertion:\n' + this.clarifyNewlines(actual.newText));
|
||||
}
|
||||
|
||||
if (actual.caretOffset !== expected.caretOffset) {
|
||||
@@ -1917,6 +1917,13 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private clarifyNewlines(str: string) {
|
||||
return str.replace(/\r?\n/g, lineEnding => {
|
||||
const representation = lineEnding === "\r\n" ? "CRLF" : "LF";
|
||||
return "# - " + representation + lineEnding;
|
||||
});
|
||||
}
|
||||
|
||||
public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) {
|
||||
this.taoInvalidReason = "verifyMatchingBracePosition NYI";
|
||||
|
||||
|
||||
+42
-11
@@ -6997,8 +6997,12 @@ namespace ts {
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
* Valid positions are
|
||||
* - outside of comments, statements, and expressions, and
|
||||
* - preceding a function declaration.
|
||||
* - outside of comments, statements, and expressions, and
|
||||
* - preceding a:
|
||||
* - function/constructor/method declaration
|
||||
* - class declarations
|
||||
* - variable statements
|
||||
* - namespace declarations
|
||||
*
|
||||
* Hosts should ideally check that:
|
||||
* - The line is all whitespace up to 'position' before performing the insertion.
|
||||
@@ -7025,16 +7029,37 @@ namespace ts {
|
||||
}
|
||||
|
||||
// TODO: add support for:
|
||||
// - methods
|
||||
// - constructors
|
||||
// - class decls
|
||||
let containingFunction = <FunctionDeclaration>getAncestor(tokenAtPos, SyntaxKind.FunctionDeclaration);
|
||||
// - enums/enum members
|
||||
// - interfaces
|
||||
// - property declarations
|
||||
// - potentially property assignments
|
||||
let commentOwner: Node;
|
||||
findOwner: for (commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
|
||||
switch (commentOwner.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.VariableStatement:
|
||||
break findOwner;
|
||||
case SyntaxKind.SourceFile:
|
||||
return undefined;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// If in walking up the tree, we hit a a nested namespace declaration,
|
||||
// then we must be somewhere within a dotted namespace name; however we don't
|
||||
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
|
||||
if (commentOwner.parent.kind === SyntaxKind.ModuleDeclaration) {
|
||||
return undefined;
|
||||
}
|
||||
break findOwner;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containingFunction || containingFunction.getStart() < position) {
|
||||
if (!commentOwner || commentOwner.getStart() < position) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let parameters = containingFunction.parameters;
|
||||
let parameters = isFunctionLike(commentOwner) ? commentOwner.parameters : emptyArray;
|
||||
let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
|
||||
let lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
|
||||
|
||||
@@ -7043,9 +7068,15 @@ namespace ts {
|
||||
// TODO: call a helper method instead once PR #4133 gets merged in.
|
||||
const newLine = host.getNewLine ? host.getNewLine() : "\r\n";
|
||||
|
||||
let docParams = parameters.reduce((prev, cur, index) =>
|
||||
prev +
|
||||
indentationStr + " * @param " + (cur.name.kind === SyntaxKind.Identifier ? (<Identifier>cur.name).text : "param" + index) + newLine, "");
|
||||
let docParams = "";
|
||||
for (let i = 0, numParams = parameters.length; i < numParams; i++) {
|
||||
const currentName = parameters[i].name;
|
||||
const paramName = currentName.kind === SyntaxKind.Identifier ?
|
||||
(<Identifier>currentName).text :
|
||||
"param" + i;
|
||||
|
||||
docParams += `${indentationStr} * @param ${paramName}${newLine}`;
|
||||
}
|
||||
|
||||
// A doc comment consists of the following
|
||||
// * The opening comment line
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, newTextOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, newTextOffset);
|
||||
}
|
||||
|
||||
/////*decl*/class C {
|
||||
//// private p;
|
||||
//// constructor(a, b, c, d);
|
||||
//// constructor(public a, private b, protected c, d, e?) {
|
||||
//// }
|
||||
////
|
||||
//// foo();
|
||||
//// foo(a?, b?, ...args) {
|
||||
//// }
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("decl", /*newTextOffset*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/
|
||||
`);
|
||||
@@ -0,0 +1,79 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, indentation: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, indentation);
|
||||
}
|
||||
|
||||
const enum Indentation {
|
||||
Standard = 8,
|
||||
Indented = 12,
|
||||
}
|
||||
|
||||
|
||||
////class C {
|
||||
/////*0*/ /*1*/
|
||||
//// foo();
|
||||
//// /*2*/foo(a);
|
||||
//// /*3*/foo(a, b);
|
||||
//// /*4*/ foo(a, {x: string}, [c]);
|
||||
//// /*5*/foo(a?, b?, ...args) {
|
||||
//// }
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("0", Indentation.Standard, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
|
||||
confirmNormalizedJsDoc("1", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
|
||||
confirmNormalizedJsDoc("2", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
*/
|
||||
`);
|
||||
|
||||
confirmNormalizedJsDoc("3", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
`);
|
||||
|
||||
confirmNormalizedJsDoc("4", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
* @param param1
|
||||
* @param param2
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("5", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
* @param args
|
||||
*/
|
||||
`);
|
||||
@@ -0,0 +1,46 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, indentation: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, indentation);
|
||||
}
|
||||
|
||||
const enum Indentation {
|
||||
Indented = 12,
|
||||
}
|
||||
|
||||
|
||||
////class C {
|
||||
//// /*0*/
|
||||
//// [Symbol.iterator]() {
|
||||
//// return undefined;
|
||||
//// }
|
||||
//// /*1*/
|
||||
//// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { }
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("0", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("1", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/`);
|
||||
@@ -0,0 +1,52 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, newTextOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, newTextOffset);
|
||||
}
|
||||
|
||||
////class C {
|
||||
//// private p;
|
||||
//// /*0*/
|
||||
//// constructor(a, b, c, d);
|
||||
//// /*1*/
|
||||
//// constructor(public a, private b, protected c, d, e?) {
|
||||
//// }
|
||||
////
|
||||
//// foo();
|
||||
//// foo(a?, b?, ...args) {
|
||||
//// }
|
||||
////}
|
||||
|
||||
const newTextOffset = 12;
|
||||
confirmNormalizedJsDoc("0", /*newTextOffset*/ newTextOffset,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
* @param c
|
||||
* @param d
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("1", /*newTextOffset*/ newTextOffset,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
* @param c
|
||||
* @param d
|
||||
* @param e
|
||||
*/`);
|
||||
@@ -0,0 +1,46 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, charOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, charOffset);
|
||||
}
|
||||
|
||||
/////*namespaceN*/
|
||||
////namespace n {
|
||||
////}
|
||||
////
|
||||
/////*namespaceM*/
|
||||
////module m {
|
||||
////}
|
||||
////
|
||||
/////*ambientModule*/
|
||||
////module "ambientModule" {
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("namespaceN", /*indentation*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("namespaceM", /*indentation*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("namespaceM", /*indentation*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
@@ -0,0 +1,36 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, charOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, charOffset);
|
||||
}
|
||||
|
||||
/////*top*/
|
||||
////namespace n1.
|
||||
//// /*n2*/ n2.
|
||||
//// /*n3*/ n3 {
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("top", /*indentation*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
goTo.marker("n2");
|
||||
verify.noDocCommentTemplate();
|
||||
|
||||
goTo.marker("n3");
|
||||
verify.noDocCommentTemplate();
|
||||
@@ -0,0 +1,46 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, indentation: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, indentation);
|
||||
}
|
||||
|
||||
const enum Indentation {
|
||||
Indented = 12,
|
||||
}
|
||||
|
||||
|
||||
////var x = {
|
||||
//// /*0*/
|
||||
//// foo() {
|
||||
//// return undefined;
|
||||
//// }
|
||||
//// /*1*/
|
||||
//// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { }
|
||||
////}
|
||||
|
||||
confirmNormalizedJsDoc("0", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
*/`);
|
||||
|
||||
confirmNormalizedJsDoc("1", Indentation.Indented,
|
||||
`/**
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/`);
|
||||
@@ -0,0 +1,54 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, newTextOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, newTextOffset);
|
||||
}
|
||||
|
||||
/////*a*/
|
||||
////var a = 10;
|
||||
////
|
||||
/////*b*/
|
||||
////let b = "";
|
||||
////
|
||||
/////*c*/
|
||||
////const c = 30;
|
||||
////
|
||||
/////*d*/
|
||||
////let d = function d(x, y, z) {
|
||||
//// return +(x + y + z);
|
||||
////};
|
||||
////
|
||||
/////*e*/
|
||||
////let e = class E {
|
||||
//// constructor(a, b, c) {
|
||||
//// this.a = a;
|
||||
//// this.b = b || (this.c = c);
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
/////*f*/
|
||||
////let f = {
|
||||
//// foo: 10,
|
||||
//// bar: "20"
|
||||
////};
|
||||
|
||||
for (const varName of "abcdef".split("")) {
|
||||
confirmNormalizedJsDoc(varName, /*newTextOffset*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const CRLF = "\r\n";
|
||||
/**
|
||||
* @returns the given value with '\n' normalized to '\r\n' and with no leading newline
|
||||
*/
|
||||
function useCRLFAndStripLeadingNewline(str: string): string {
|
||||
str = str.replace(/\r?\n/g, CRLF);
|
||||
if (str.indexOf(CRLF) === 0) {
|
||||
str = str.slice(CRLF.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function confirmNormalizedJsDoc(markerName: string, newTextOffset: number, template: string): void {
|
||||
goTo.marker(markerName);
|
||||
const normalized = useCRLFAndStripLeadingNewline(template);
|
||||
verify.DocCommentTemplate(normalized, newTextOffset);
|
||||
}
|
||||
|
||||
/////*a*/
|
||||
////var a1 = 10, a2 = 20;
|
||||
////
|
||||
/////*b*/
|
||||
////let b1 = "", b2 = true;
|
||||
////
|
||||
/////*c*/
|
||||
////const c1 = 30, c2 = 40;
|
||||
////
|
||||
/////*d*/
|
||||
////let d1 = function d(x, y, z) {
|
||||
//// return +(x + y + z);
|
||||
////}, d2 = 50;
|
||||
////
|
||||
/////*e*/
|
||||
////let e1 = class E {
|
||||
//// constructor(a, b, c) {
|
||||
//// this.a = a;
|
||||
//// this.b = b || (this.c = c);
|
||||
//// }
|
||||
////}, e2 = () => 100;
|
||||
////
|
||||
/////*f*/
|
||||
////let f1 = {
|
||||
//// foo: 10,
|
||||
//// bar: "20"
|
||||
////}, f2 = null;
|
||||
|
||||
for (const varName of "abcdef".split("")) {
|
||||
confirmNormalizedJsDoc(varName, /*newTextOffset*/ 8, `
|
||||
/**
|
||||
*
|
||||
*/`);
|
||||
}
|
||||
Reference in New Issue
Block a user