Skip to content

Commit 01d945b

Browse files
committed
Merge pull request #2612 from ahmad-farid/OCNoTest2
Adding outlining for comments to allow collapsing in VS #698
2 parents 6493980 + 35d848f commit 01d945b

File tree

7 files changed

+254
-19
lines changed

7 files changed

+254
-19
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Your pull request should:
2525
* Tests should include reasonable permutations of the target fix/change
2626
* Include baseline changes with your change
2727
* All changed code must have 100% code coverage
28-
* Follow the code conventions descriped in [Coding guidlines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidlines)
28+
* Follow the code conventions descriped in [Coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines)
2929
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
3030

3131
## Running the Tests

src/compiler/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5299,7 +5299,7 @@ module ts {
52995299
break;
53005300
}
53015301

5302-
let range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos() };
5302+
let range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
53035303

53045304
let comment = sourceText.substring(range.pos, range.end);
53055305
let referencePathMatchResult = getFileReferenceFromReferencePath(comment, range);

src/compiler/scanner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ module ts {
523523
let nextChar = text.charCodeAt(pos + 1);
524524
let hasTrailingNewLine = false;
525525
if (nextChar === CharacterCodes.slash || nextChar === CharacterCodes.asterisk) {
526+
let kind = nextChar === CharacterCodes.slash ? SyntaxKind.SingleLineCommentTrivia : SyntaxKind.MultiLineCommentTrivia;
526527
let startPos = pos;
527528
pos += 2;
528529
if (nextChar === CharacterCodes.slash) {
@@ -548,7 +549,7 @@ module ts {
548549
result = [];
549550
}
550551

551-
result.push({ pos: startPos, end: pos, hasTrailingNewLine: hasTrailingNewLine });
552+
result.push({ pos: startPos, end: pos, hasTrailingNewLine, kind });
552553
}
553554
continue;
554555
}

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ module ts {
985985

986986
export interface CommentRange extends TextRange {
987987
hasTrailingNewLine?: boolean;
988+
kind: SyntaxKind;
988989
}
989990

990991
// Source files are declarations when they are external modules.

src/services/outliningElementsCollector.ts

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
//
2-
// Copyright (c) Microsoft Corporation. All rights reserved.
3-
//
4-
// Licensed under the Apache License, Version 2.0 (the "License");
5-
// you may not use this file except in compliance with the License.
6-
// You may obtain a copy of the License at
7-
// http://www.apache.org/licenses/LICENSE-2.0
8-
//
9-
// Unless required by applicable law or agreed to in writing, software
10-
// distributed under the License is distributed on an "AS IS" BASIS,
11-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
// See the License for the specific language governing permissions and
13-
// limitations under the License.
14-
//
15-
161
module ts {
172
export module OutliningElementsCollector {
183
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
@@ -31,6 +16,66 @@ module ts {
3116
}
3217
}
3318

19+
function addOutliningSpanComments(commentSpan: CommentRange, autoCollapse: boolean) {
20+
if (commentSpan) {
21+
let span: OutliningSpan = {
22+
textSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
23+
hintSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
24+
bannerText: collapseText,
25+
autoCollapse: autoCollapse
26+
};
27+
elements.push(span);
28+
}
29+
}
30+
31+
function addOutliningForLeadingCommentsForNode(n: Node) {
32+
let comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
33+
34+
if (comments) {
35+
let firstSingleLineCommentStart = -1;
36+
let lastSingleLineCommentEnd = -1;
37+
let isFirstSingleLineComment = true;
38+
let singleLineCommentCount = 0;
39+
40+
for (let currentComment of comments) {
41+
42+
// For single line comments, combine consecutive ones (2 or more) into
43+
// a single span from the start of the first till the end of the last
44+
if (currentComment.kind === SyntaxKind.SingleLineCommentTrivia) {
45+
if (isFirstSingleLineComment) {
46+
firstSingleLineCommentStart = currentComment.pos;
47+
}
48+
isFirstSingleLineComment = false;
49+
lastSingleLineCommentEnd = currentComment.end;
50+
singleLineCommentCount++;
51+
}
52+
else if (currentComment.kind === SyntaxKind.MultiLineCommentTrivia) {
53+
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
54+
addOutliningSpanComments(currentComment, /*autoCollapse*/ false);
55+
56+
singleLineCommentCount = 0;
57+
lastSingleLineCommentEnd = -1;
58+
isFirstSingleLineComment = true;
59+
}
60+
}
61+
62+
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
63+
}
64+
}
65+
66+
function combineAndAddMultipleSingleLineComments(count: number, start: number, end: number) {
67+
// Only outline spans of two or more consecutive single line comments
68+
if (count > 1) {
69+
let multipleSingleLineComments = {
70+
pos: start,
71+
end: end,
72+
kind: SyntaxKind.SingleLineCommentTrivia
73+
}
74+
75+
addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
76+
}
77+
}
78+
3479
function autoCollapse(node: Node) {
3580
return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction;
3681
}
@@ -41,6 +86,11 @@ module ts {
4186
if (depth > maxDepth) {
4287
return;
4388
}
89+
90+
if (isDeclaration(n)) {
91+
addOutliningForLeadingCommentsForNode(n);
92+
}
93+
4494
switch (n.kind) {
4595
case SyntaxKind.Block:
4696
if (!isFunctionBlock(n)) {
@@ -93,7 +143,7 @@ module ts {
93143
});
94144
break;
95145
}
96-
// Fallthrough.
146+
// Fallthrough.
97147

98148
case SyntaxKind.ModuleBlock: {
99149
let openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////[|/*
4+
//// Block comment at the beginning of the file before module:
5+
//// line one of the comment
6+
//// line two of the comment
7+
//// line three
8+
//// line four
9+
//// line five
10+
////*/|]
11+
////module Sayings[| {
12+
//// [|/*
13+
//// Comment before class:
14+
//// line one of the comment
15+
//// line two of the comment
16+
//// line three
17+
//// line four
18+
//// line five
19+
//// */|]
20+
//// export class Greeter[| {
21+
//// [|/*
22+
//// Comment before a string identifier
23+
//// line two of the comment
24+
//// */|]
25+
//// greeting: string;
26+
//// [|/*
27+
//// constructor
28+
//// parameter message as a string
29+
//// */|]
30+
////
31+
//// [|/*
32+
//// Multiple comments should be collapsed individually
33+
//// */|]
34+
//// constructor(message: string /* do not collapse this */)[| {
35+
//// this.greeting = message;
36+
//// }|]
37+
//// [|/*
38+
//// method of a class
39+
//// */|]
40+
//// greet()[| {
41+
//// return "Hello, " + this.greeting;
42+
//// }|]
43+
//// }|]
44+
////}|]
45+
////
46+
////[|/*
47+
//// Block comment for interface. The ending can be on the same line as the declaration.
48+
////*/|]interface IFoo[| {
49+
//// [|/*
50+
//// Multiple block comments
51+
//// */|]
52+
////
53+
//// [|/*
54+
//// should be collapsed
55+
//// */|]
56+
////
57+
//// [|/*
58+
//// individually
59+
//// */|]
60+
////
61+
//// [|/*
62+
//// this comment has trailing space before /* and after *-/ signs
63+
//// */|]
64+
////
65+
//// [|/**
66+
//// *
67+
//// *
68+
//// *
69+
//// */|]
70+
////
71+
//// [|/*
72+
//// */|]
73+
////
74+
//// [|/*
75+
//// */|]
76+
//// // single line comments in the middle should not have an effect
77+
//// [|/*
78+
//// */|]
79+
////
80+
//// [|/*
81+
//// */|]
82+
////
83+
//// [|/*
84+
//// this block comment ends
85+
//// on the same line */|] [|/* where the following comment starts
86+
//// should be collapsed separately
87+
//// */|]
88+
////
89+
//// getDist(): number;
90+
////}|]
91+
////
92+
////var x =[|{
93+
//// a:1,
94+
//// b: 2,
95+
//// [|/*
96+
//// Over a function in an object literal
97+
//// */|]
98+
//// get foo()[| {
99+
//// return 1;
100+
//// }|]
101+
////}|]
102+
103+
verify.outliningSpansInCurrentFile(test.ranges());
104+
105+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////[|// Single line comments at the start of the file
4+
////// line 2
5+
////// line 3
6+
////// line 4|]
7+
////module Sayings[| {
8+
////
9+
//// [|/*
10+
//// */|]
11+
//// [|// A sequence of
12+
//// // single line|]
13+
//// [|/*
14+
//// and block
15+
//// */|]
16+
//// [|// comments
17+
//// //|]
18+
//// export class Sample[| {
19+
//// }|]
20+
////}|]
21+
////
22+
////interface IFoo[| {
23+
//// [|// all consecutive single line comments should be in one block regardless of their number or empty lines/spaces inbetween
24+
////
25+
//// // comment 2
26+
//// // comment 3
27+
////
28+
//// //comment 4
29+
//// /// comment 5
30+
//// ///// comment 6
31+
////
32+
//// //comment 7
33+
//// ///comment 8
34+
//// // comment 9
35+
//// // //comment 10
36+
////
37+
////
38+
////
39+
////
40+
////
41+
////
42+
////
43+
////
44+
////
45+
////
46+
////
47+
////
48+
////
49+
////
50+
////
51+
////
52+
////
53+
////
54+
////
55+
////
56+
//// // // //comment 11
57+
//// // comment 12
58+
//// // comment 13
59+
//// // comment 14
60+
//// // comment 15
61+
////
62+
//// // comment 16
63+
//// // comment 17
64+
//// // comment 18
65+
//// // comment 19
66+
//// // comment 20
67+
//// // comment 21|]
68+
////
69+
//// getDist(): number; // One single line comment should not be collapsed
70+
////}|]
71+
////
72+
////// One single line comment should not be collapsed
73+
////class WithOneSingleLineComment[| {
74+
////}|]
75+
76+
verify.outliningSpansInCurrentFile(test.ranges());
77+
78+

0 commit comments

Comments
 (0)