Skip to content

Commit 432349e

Browse files
authored
Merge pull request #142077 from microsoft/dbaeumer/stripComments
Move strip comments into own module and write tests
2 parents 23731b5 + 6132f8a commit 432349e

File tree

5 files changed

+202
-28
lines changed

5 files changed

+202
-28
lines changed

build/gulpfile.vscode.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const vscodeResources = [
6060
'!out-build/vs/code/browser/**/*.html',
6161
'!out-build/vs/editor/standalone/**/*.svg',
6262
'out-build/vs/base/common/performance.js',
63+
'out-build/vs/base/common/stripComments.js',
6364
'out-build/vs/base/node/languagePacks.js',
6465
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
6566
'out-build/vs/base/browser/ui/codicons/codicon/**',

src/main.js

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const os = require('os');
2121
const bootstrap = require('./bootstrap');
2222
const bootstrapNode = require('./bootstrap-node');
2323
const { getUserDataPath } = require('./vs/platform/environment/node/userDataPath');
24+
const { stripComments } = require('./vs/base/common/stripComments');
2425
/** @type {Partial<IProductConfiguration>} */
2526
const product = require('../product.json');
2627
const { app, protocol, crashReporter } = require('electron');
@@ -583,34 +584,6 @@ async function resolveNlsConfiguration() {
583584
return nlsConfiguration;
584585
}
585586

586-
/**
587-
* @param {string} content
588-
* @returns {string}
589-
*/
590-
function stripComments(content) {
591-
const regexp = /("(?:[^\\"]*(?:\\.)?)*")|('(?:[^\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
592-
593-
return content.replace(regexp, function (match, m1, m2, m3, m4) {
594-
// Only one of m1, m2, m3, m4 matches
595-
if (m3) {
596-
// A block comment. Replace with nothing
597-
return '';
598-
} else if (m4) {
599-
// A line comment. If it ends in \r?\n then keep it.
600-
const length_1 = m4.length;
601-
if (length_1 > 2 && m4[length_1 - 1] === '\n') {
602-
return m4[length_1 - 2] === '\r' ? '\r\n' : '\n';
603-
}
604-
else {
605-
return '';
606-
}
607-
} else {
608-
// We match a string
609-
return match;
610-
}
611-
});
612-
}
613-
614587
/**
615588
* Language tags are case insensitive however an amd loader is case sensitive
616589
* To make this work on case preserving & insensitive FS we do the following:

src/vs/base/common/stripComments.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
/**
7+
* Strips single and multi line JavaScript comments from JSON
8+
* content. Ignores characters in strings BUT doesn't support
9+
* string continuation across multiple lines since it is not
10+
* supported in JSON.
11+
* @param content the content to strip comments from
12+
* @returns the content without comments
13+
*/
14+
export function stripComments(content: string): string;

src/vs/base/common/stripComments.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
//@ts-check
9+
10+
(function () {
11+
function factory(path, os, productName, cwd) {
12+
// First group matches a double quoted string
13+
// Second group matches a single quoted string
14+
// Third group matches a multi line comment
15+
// Forth group matches a single line comment
16+
const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
17+
18+
/**
19+
*
20+
* @param {string} content
21+
* @returns {string}
22+
*/
23+
function stripComments(content) {
24+
console.log(`Stripping comments`);
25+
return content.replace(regexp, function (match, _m1, _m2, m3, m4) {
26+
// Only one of m1, m2, m3, m4 matches
27+
if (m3) {
28+
// A block comment. Replace with nothing
29+
return '';
30+
} else if (m4) {
31+
// Since m4 is a single line comment is is at least of length 2 (e.g. //)
32+
// If it ends in \r?\n then keep it.
33+
const length = m4.length;
34+
if (m4[length - 1] === '\n') {
35+
return m4[length - 2] === '\r' ? '\r\n' : '\n';
36+
}
37+
else {
38+
return '';
39+
}
40+
} else {
41+
// We match a string
42+
return match;
43+
}
44+
});
45+
}
46+
return {
47+
stripComments
48+
};
49+
}
50+
51+
52+
if (typeof define === 'function') {
53+
// amd
54+
define([], function () { return factory(); });
55+
} else if (typeof module === 'object' && typeof module.exports === 'object') {
56+
// commonjs
57+
module.exports = factory();
58+
} else {
59+
console.trace('strip comments defined in UNKNOWN context (neither requirejs or commonjs)');
60+
}
61+
})();
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import * as assert from 'assert';
6+
7+
import { stripComments } from 'vs/base/common/stripComments';
8+
9+
// We use this regular expression quite often to strip comments in JSON files.
10+
11+
suite('Strip Comments', () => {
12+
test('Line comment', () => {
13+
const content: string = [
14+
"{",
15+
" \"prop\": 10 // a comment",
16+
"}",
17+
].join('\n');
18+
const expected = [
19+
"{",
20+
" \"prop\": 10 ",
21+
"}",
22+
].join('\n');
23+
assert.strictEqual(stripComments(content), expected);
24+
});
25+
test('Line comment - EOF', () => {
26+
const content: string = [
27+
"{",
28+
"}",
29+
"// a comment"
30+
].join('\n');
31+
const expected = [
32+
"{",
33+
"}",
34+
""
35+
].join('\n');
36+
assert.strictEqual(stripComments(content), expected);
37+
});
38+
test('Line comment - \\r\\n', () => {
39+
const content: string = [
40+
"{",
41+
" \"prop\": 10 // a comment",
42+
"}",
43+
].join('\r\n');
44+
const expected = [
45+
"{",
46+
" \"prop\": 10 ",
47+
"}",
48+
].join('\r\n');
49+
assert.strictEqual(stripComments(content), expected);
50+
});
51+
test('Line comment - EOF - \\r\\n', () => {
52+
const content: string = [
53+
"{",
54+
"}",
55+
"// a comment"
56+
].join('\r\n');
57+
const expected = [
58+
"{",
59+
"}",
60+
""
61+
].join('\r\n');
62+
assert.strictEqual(stripComments(content), expected);
63+
});
64+
test('Block comment - single line', () => {
65+
const content: string = [
66+
"{",
67+
" /* before */\"prop\": 10/* after */",
68+
"}",
69+
].join('\n');
70+
const expected = [
71+
"{",
72+
" \"prop\": 10",
73+
"}",
74+
].join('\n');
75+
assert.strictEqual(stripComments(content), expected);
76+
});
77+
test('Block comment - multi line', () => {
78+
const content: string = [
79+
"{",
80+
" /**",
81+
" * Some comment",
82+
" */",
83+
" \"prop\": 10",
84+
"}",
85+
].join('\n');
86+
const expected = [
87+
"{",
88+
" ",
89+
" \"prop\": 10",
90+
"}",
91+
].join('\n');
92+
assert.strictEqual(stripComments(content), expected);
93+
});
94+
test('Block comment - shortest match', () => {
95+
const content = "/* abc */ */";
96+
const expected = " */";
97+
assert.strictEqual(stripComments(content), expected);
98+
});
99+
test('No strings - double quote', () => {
100+
const content: string = [
101+
"{",
102+
" \"/* */\": 10",
103+
"}"
104+
].join('\n');
105+
const expected: string = [
106+
"{",
107+
" \"/* */\": 10",
108+
"}"
109+
].join('\n');
110+
assert.strictEqual(stripComments(content), expected);
111+
});
112+
test('No strings - single quote', () => {
113+
const content: string = [
114+
"{",
115+
" '/* */': 10",
116+
"}"
117+
].join('\n');
118+
const expected: string = [
119+
"{",
120+
" '/* */': 10",
121+
"}"
122+
].join('\n');
123+
assert.strictEqual(stripComments(content), expected);
124+
});
125+
});

0 commit comments

Comments
 (0)