Merge pull request #4978 from Microsoft/expandDocTemplateCoverage

Expand JSDoc template generation locations (to 'master')
This commit is contained in:
Daniel Rosenwasser
2015-09-25 15:28:28 -07:00
12 changed files with 500 additions and 13 deletions
+1 -1
View File
@@ -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:
+8 -1
View File
@@ -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
View File
@@ -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, `
/**
*
*/`);
}