Upstream microsoft/vscode state of the touched files before 187c44cba3
This commit is contained in:
1 parent
fd90b7606a
commit
da856c50ae
2 files changed
+585
No files matched your search
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#"
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["\"", "\""],
|
||||
["'", "'"]
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["\"", "\""],
|
||||
["'", "'"]
|
||||
],
|
||||
"folding": {
|
||||
"offSide": true,
|
||||
"markers": {
|
||||
"start": "^\\s*#\\s*region\\b",
|
||||
"end": "^\\s*#\\s*endregion\\b"
|
||||
}
|
||||
},
|
||||
"indentationRules": {
|
||||
"increaseIndentPattern": "^\\s*.*(:|-) ?(&\\w+)?(\\{[^}\"']*|\\([^)\"']*)?$",
|
||||
"decreaseIndentPattern": "^\\s+\\}$"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,550 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { extname, join } from '../../../../../base/common/path.js';
|
||||
import assert from 'assert';
|
||||
import { DisposableStore, IDisposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
|
||||
import { ILanguageConfigurationService } from '../../../../../editor/common/languages/languageConfigurationRegistry.js';
|
||||
import { getReindentEditOperations } from '../../../../../editor/contrib/indentation/common/indentation.js';
|
||||
import { IRelaxedTextModelCreationOptions, createModelServices, instantiateTextModel } from '../../../../../editor/test/common/testTextModel.js';
|
||||
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
|
||||
import { ILanguageConfiguration, LanguageConfigurationFileHandler } from '../../common/languageConfigurationExtensionPoint.js';
|
||||
import { parse } from '../../../../../base/common/json.js';
|
||||
import { IRange } from '../../../../../editor/common/core/range.js';
|
||||
import { ISingleEditOperation } from '../../../../../editor/common/core/editOperation.js';
|
||||
import { trimTrailingWhitespace } from '../../../../../editor/common/commands/trimTrailingWhitespaceCommand.js';
|
||||
import { execSync } from 'child_process';
|
||||
import { ILanguageService } from '../../../../../editor/common/languages/language.js';
|
||||
import { EncodedTokenizationResult, IState, ITokenizationSupport, TokenizationRegistry } from '../../../../../editor/common/languages.js';
|
||||
import { NullState } from '../../../../../editor/common/languages/nullTokenize.js';
|
||||
import { MetadataConsts, StandardTokenType } from '../../../../../editor/common/encodedTokenAttributes.js';
|
||||
import { ITextModel } from '../../../../../editor/common/model.js';
|
||||
import { FileAccess } from '../../../../../base/common/network.js';
|
||||
|
||||
function getIRange(range: IRange): IRange {
|
||||
return {
|
||||
startLineNumber: range.startLineNumber,
|
||||
startColumn: range.startColumn,
|
||||
endLineNumber: range.endLineNumber,
|
||||
endColumn: range.endColumn
|
||||
};
|
||||
}
|
||||
|
||||
const enum LanguageId {
|
||||
TypeScript = 'ts-test'
|
||||
}
|
||||
|
||||
function forceTokenizationFromLineToLine(model: ITextModel, startLine: number, endLine: number): void {
|
||||
for (let line = startLine; line <= endLine; line++) {
|
||||
model.tokenization.forceTokenization(line);
|
||||
}
|
||||
}
|
||||
|
||||
function registerLanguage(instantiationService: TestInstantiationService, languageId: LanguageId): IDisposable {
|
||||
const disposables = new DisposableStore();
|
||||
const languageService = instantiationService.get(ILanguageService);
|
||||
disposables.add(registerLanguageConfiguration(instantiationService, languageId));
|
||||
disposables.add(languageService.registerLanguage({ id: languageId }));
|
||||
return disposables;
|
||||
}
|
||||
|
||||
function registerLanguageConfiguration(instantiationService: TestInstantiationService, languageId: LanguageId): IDisposable {
|
||||
const languageConfigurationService = instantiationService.get(ILanguageConfigurationService);
|
||||
let configPath: string;
|
||||
switch (languageId) {
|
||||
case LanguageId.TypeScript:
|
||||
configPath = FileAccess.asFileUri('vs/workbench/contrib/codeEditor/test/node/language-configuration.json').fsPath;
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown languageId');
|
||||
}
|
||||
const configContent = fs.readFileSync(configPath, { encoding: 'utf-8' });
|
||||
const parsedConfig = <ILanguageConfiguration>parse(configContent, []);
|
||||
const languageConfig = LanguageConfigurationFileHandler.extractValidConfig(languageId, parsedConfig);
|
||||
return languageConfigurationService.register(languageId, languageConfig);
|
||||
}
|
||||
|
||||
interface StandardTokenTypeData {
|
||||
startIndex: number;
|
||||
standardTokenType: StandardTokenType;
|
||||
}
|
||||
|
||||
function registerTokenizationSupport(instantiationService: TestInstantiationService, tokens: StandardTokenTypeData[][], languageId: LanguageId): IDisposable {
|
||||
let lineIndex = 0;
|
||||
const languageService = instantiationService.get(ILanguageService);
|
||||
const tokenizationSupport: ITokenizationSupport = {
|
||||
getInitialState: () => NullState,
|
||||
tokenize: undefined!,
|
||||
tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => {
|
||||
const tokensOnLine = tokens[lineIndex++];
|
||||
const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId);
|
||||
const result = new Uint32Array(2 * tokensOnLine.length);
|
||||
for (let i = 0; i < tokensOnLine.length; i++) {
|
||||
result[2 * i] = tokensOnLine[i].startIndex;
|
||||
result[2 * i + 1] =
|
||||
((encodedLanguageId << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (tokensOnLine[i].standardTokenType << MetadataConsts.TOKEN_TYPE_OFFSET));
|
||||
}
|
||||
return new EncodedTokenizationResult(result, [], state);
|
||||
}
|
||||
};
|
||||
return TokenizationRegistry.register(languageId, tokenizationSupport);
|
||||
}
|
||||
|
||||
suite('Language Configuration Parsing', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
test('Folding markers support object regex syntax with flags', () => {
|
||||
const parsed = LanguageConfigurationFileHandler.extractValidConfig('testLang', {
|
||||
folding: {
|
||||
markers: {
|
||||
start: { pattern: '^\\s*#region\\b', flags: 'i' },
|
||||
end: { pattern: '^\\s*#endregion\\b', flags: 'i' }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.ok(parsed.folding?.markers);
|
||||
assert.strictEqual(parsed.folding?.markers?.start.flags, 'i');
|
||||
assert.strictEqual(parsed.folding?.markers?.end.flags, 'i');
|
||||
assert.ok(parsed.folding?.markers?.start.test('#REGION'));
|
||||
assert.ok(parsed.folding?.markers?.end.test('#ENDREGION'));
|
||||
});
|
||||
|
||||
test('Auto-closing pairs support beforeText regex syntax with flags', () => {
|
||||
const parsed = LanguageConfigurationFileHandler.extractValidConfig('testLang', {
|
||||
autoClosingPairs: [{
|
||||
open: 'begin',
|
||||
close: 'end',
|
||||
beforeText: { pattern: '(?:^|\\s)begin$', flags: 'i' }
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(
|
||||
parsed.autoClosingPairs?.map(pair => ({
|
||||
open: pair.open,
|
||||
close: pair.close,
|
||||
beforeText: pair.beforeText ? { source: pair.beforeText.source, flags: pair.beforeText.flags } : undefined
|
||||
})),
|
||||
[{ open: 'begin', close: 'end', beforeText: { source: '(?:^|\\s)begin$', flags: 'i' } }]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Auto-Reindentation - TypeScript/JavaScript', () => {
|
||||
|
||||
const languageId = LanguageId.TypeScript;
|
||||
const options: IRelaxedTextModelCreationOptions = {};
|
||||
let disposables: DisposableStore;
|
||||
let instantiationService: TestInstantiationService;
|
||||
let languageConfigurationService: ILanguageConfigurationService;
|
||||
|
||||
setup(() => {
|
||||
disposables = new DisposableStore();
|
||||
instantiationService = createModelServices(disposables);
|
||||
languageConfigurationService = instantiationService.get(ILanguageConfigurationService);
|
||||
disposables.add(instantiationService);
|
||||
disposables.add(registerLanguage(instantiationService, languageId));
|
||||
disposables.add(registerLanguageConfiguration(instantiationService, languageId));
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
// Test which can be ran to find cases of incorrect indentation...
|
||||
test.skip('Find Cases of Incorrect Indentation with the Reindent Lines Command', () => {
|
||||
|
||||
// ./scripts/test.sh --inspect --grep='Find Cases of Incorrect Indentation with the Reindent Lines Command' --timeout=15000
|
||||
|
||||
function walkDirectoryAndReindent(directory: string, languageId: string) {
|
||||
const files = fs.readdirSync(directory, { withFileTypes: true });
|
||||
const directoriesToRecurseOn: string[] = [];
|
||||
for (const file of files) {
|
||||
if (file.isDirectory()) {
|
||||
directoriesToRecurseOn.push(join(directory, file.name));
|
||||
} else {
|
||||
const filePathName = join(directory, file.name);
|
||||
const fileExtension = extname(filePathName);
|
||||
if (fileExtension !== '.ts') {
|
||||
continue;
|
||||
}
|
||||
const fileContents = fs.readFileSync(filePathName, { encoding: 'utf-8' });
|
||||
const modelOptions: IRelaxedTextModelCreationOptions = {
|
||||
tabSize: 4,
|
||||
insertSpaces: false
|
||||
};
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, modelOptions));
|
||||
const lineCount = model.getLineCount();
|
||||
const editOperations: ISingleEditOperation[] = [];
|
||||
for (let line = 1; line <= lineCount - 1; line++) {
|
||||
/*
|
||||
NOTE: Uncomment in order to ignore incorrect JS DOC indentation
|
||||
const lineContent = model.getLineContent(line);
|
||||
const trimmedLineContent = lineContent.trim();
|
||||
if (trimmedLineContent.length === 0 || trimmedLineContent.startsWith('*') || trimmedLineContent.startsWith('/*')) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
const lineContent = model.getLineContent(line);
|
||||
const trimmedLineContent = lineContent.trim();
|
||||
if (trimmedLineContent.length === 0) {
|
||||
continue;
|
||||
}
|
||||
const editOperation = getReindentEditOperations(model, languageConfigurationService, line, line + 1);
|
||||
/*
|
||||
NOTE: Uncomment in order to see actual incorrect indentation diff
|
||||
model.applyEdits(editOperation);
|
||||
*/
|
||||
editOperations.push(...editOperation);
|
||||
}
|
||||
model.applyEdits(editOperations);
|
||||
model.applyEdits(trimTrailingWhitespace(model, [], true));
|
||||
fs.writeFileSync(filePathName, model.getValue());
|
||||
}
|
||||
}
|
||||
for (const directory of directoriesToRecurseOn) {
|
||||
walkDirectoryAndReindent(directory, languageId);
|
||||
}
|
||||
}
|
||||
|
||||
walkDirectoryAndReindent('/Users/aiday/Desktop/Test/vscode-test', 'ts-test');
|
||||
const output = execSync('cd /Users/aiday/Desktop/Test/vscode-test && git diff --shortstat', { encoding: 'utf-8' });
|
||||
console.log('\ngit diff --shortstat:\n', output);
|
||||
});
|
||||
|
||||
// Unit tests for increase and decrease indent patterns...
|
||||
|
||||
/**
|
||||
* First increase indent and decrease indent patterns:
|
||||
*
|
||||
* - decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/
|
||||
* - In (https://macromates.com/manual/en/appendix)
|
||||
* Either we have white space before the closing bracket, or we have a multi line comment ending on that line followed by whitespaces
|
||||
* This is followed by any character.
|
||||
* Textmate decrease indent pattern is as follows: /^(.*\*\/)?\s*\}[;\s]*$/
|
||||
* Presumably allowing multi line comments ending on that line implies that } is itself not part of a multi line comment
|
||||
*
|
||||
* - increaseIndentPattern: /^.*\{[^}"']*$/
|
||||
* - In (https://macromates.com/manual/en/appendix)
|
||||
* This regex means that we increase the indent when we have any characters followed by the opening brace, followed by characters
|
||||
* except for closing brace }, double quotes " or single quote '.
|
||||
* The } is checked in order to avoid the indentation in the following case `int arr[] = { 1, 2, 3 };`
|
||||
* The double quote and single quote are checked in order to avoid the indentation in the following case: str = "foo {";
|
||||
*/
|
||||
|
||||
test('Issue #25437', () => {
|
||||
// issue: https://github.com/microsoft/vscode/issues/25437
|
||||
// fix: https://github.com/microsoft/vscode/commit/8c82a6c6158574e098561c28d470711f1b484fc8
|
||||
// explanation: var foo = `{`; should not increase indentation
|
||||
|
||||
// increaseIndentPattern: /^.*\{[^}"']*$/ -> /^.*\{[^}"'`]*$/
|
||||
|
||||
const fileContents = [
|
||||
'const foo = `{`;',
|
||||
' ',
|
||||
].join('\n');
|
||||
const tokens: StandardTokenTypeData[][] = [
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 5, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 6, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 9, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 10, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 11, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 12, standardTokenType: StandardTokenType.String },
|
||||
{ startIndex: 13, standardTokenType: StandardTokenType.String },
|
||||
{ startIndex: 14, standardTokenType: StandardTokenType.String },
|
||||
{ startIndex: 15, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 16, standardTokenType: StandardTokenType.Other }
|
||||
],
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 4, standardTokenType: StandardTokenType.Other }]
|
||||
];
|
||||
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
forceTokenizationFromLineToLine(model, 1, 2);
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 1);
|
||||
const operation = editOperations[0];
|
||||
assert.deepStrictEqual(getIRange(operation.range), {
|
||||
'startLineNumber': 2,
|
||||
'startColumn': 1,
|
||||
'endLineNumber': 2,
|
||||
'endColumn': 5,
|
||||
});
|
||||
assert.deepStrictEqual(operation.text, '');
|
||||
});
|
||||
|
||||
test('Enriching the hover', () => {
|
||||
// issue: -
|
||||
// fix: https://github.com/microsoft/vscode/commit/19ae0932c45b1096443a8c1335cf1e02eb99e16d
|
||||
// explanation:
|
||||
// - decrease indent on ) and ] also
|
||||
// - increase indent on ( and [ also
|
||||
|
||||
// decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/ -> /^(.*\*\/)?\s*[\}\]\)].*$/
|
||||
// increaseIndentPattern: /^.*\{[^}"'`]*$/ -> /^.*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/
|
||||
|
||||
let fileContents = [
|
||||
'function foo(',
|
||||
' bar: string',
|
||||
' ){}',
|
||||
].join('\n');
|
||||
let model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
let editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 1);
|
||||
let operation = editOperations[0];
|
||||
assert.deepStrictEqual(getIRange(operation.range), {
|
||||
'startLineNumber': 3,
|
||||
'startColumn': 1,
|
||||
'endLineNumber': 3,
|
||||
'endColumn': 5,
|
||||
});
|
||||
assert.deepStrictEqual(operation.text, '');
|
||||
|
||||
fileContents = [
|
||||
'function foo(',
|
||||
'bar: string',
|
||||
'){}',
|
||||
].join('\n');
|
||||
model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 1);
|
||||
operation = editOperations[0];
|
||||
assert.deepStrictEqual(getIRange(operation.range), {
|
||||
'startLineNumber': 2,
|
||||
'startColumn': 1,
|
||||
'endLineNumber': 2,
|
||||
'endColumn': 1,
|
||||
});
|
||||
assert.deepStrictEqual(operation.text, ' ');
|
||||
});
|
||||
|
||||
test('Issue #86176', () => {
|
||||
// issue: https://github.com/microsoft/vscode/issues/86176
|
||||
// fix: https://github.com/microsoft/vscode/commit/d89e2e17a5d1ba37c99b1d3929eb6180a5bfc7a8
|
||||
// explanation: When quotation marks are present on the first line of an if statement or for loop, following line should not be indented
|
||||
|
||||
// increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/ -> /^((?!\/\/).)*(\{([^}"'`]*|(\t|[ ])*\/\/.*)|\([^)"'`]*|\[[^\]"'`]*)$/
|
||||
// explanation: after open brace, do not decrease indent if it is followed on the same line by "<whitespace characters> // <any characters>"
|
||||
// todo@aiday-mar: should also apply for when it follows ( and [
|
||||
|
||||
const fileContents = [
|
||||
`if () { // '`,
|
||||
`x = 4`,
|
||||
`}`
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 1);
|
||||
const operation = editOperations[0];
|
||||
assert.deepStrictEqual(getIRange(operation.range), {
|
||||
'startLineNumber': 2,
|
||||
'startColumn': 1,
|
||||
'endLineNumber': 2,
|
||||
'endColumn': 1,
|
||||
});
|
||||
assert.deepStrictEqual(operation.text, ' ');
|
||||
});
|
||||
|
||||
test('Issue #141816', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/141816
|
||||
// fix: https://github.com/microsoft/vscode/pull/141997/files
|
||||
// explanation: if (, [, {, is followed by a forward slash then assume we are in a regex pattern, and do not indent
|
||||
|
||||
// increaseIndentPattern: /^((?!\/\/).)*(\{([^}"'`]*|(\t|[ ])*\/\/.*)|\([^)"'`]*|\[[^\]"'`]*)$/ -> /^((?!\/\/).)*(\{([^}"'`/]*|(\t|[ ])*\/\/.*)|\([^)"'`/]*|\[[^\]"'`/]*)$/
|
||||
// -> Final current increase indent pattern at of writing
|
||||
|
||||
const fileContents = [
|
||||
'const r = /{/;',
|
||||
' ',
|
||||
].join('\n');
|
||||
const tokens: StandardTokenTypeData[][] = [
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 5, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 6, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 7, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 8, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 9, standardTokenType: StandardTokenType.RegEx },
|
||||
{ startIndex: 10, standardTokenType: StandardTokenType.RegEx },
|
||||
{ startIndex: 11, standardTokenType: StandardTokenType.RegEx },
|
||||
{ startIndex: 12, standardTokenType: StandardTokenType.RegEx },
|
||||
{ startIndex: 13, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 14, standardTokenType: StandardTokenType.Other }
|
||||
],
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 4, standardTokenType: StandardTokenType.Other }
|
||||
]
|
||||
];
|
||||
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
forceTokenizationFromLineToLine(model, 1, 2);
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 1);
|
||||
const operation = editOperations[0];
|
||||
assert.deepStrictEqual(getIRange(operation.range), {
|
||||
'startLineNumber': 2,
|
||||
'startColumn': 1,
|
||||
'endLineNumber': 2,
|
||||
'endColumn': 4,
|
||||
});
|
||||
assert.deepStrictEqual(operation.text, '');
|
||||
});
|
||||
|
||||
test('Issue #29886', () => {
|
||||
// issue: https://github.com/microsoft/vscode/issues/29886
|
||||
// fix: https://github.com/microsoft/vscode/commit/7910b3d7bab8a721aae98dc05af0b5e1ea9d9782
|
||||
|
||||
// decreaseIndentPattern: /^(.*\*\/)?\s*[\}\]\)].*$/ -> /^((?!.*?\/\*).*\*\/)?\s*[\}\]\)].*$/
|
||||
// -> Final current decrease indent pattern at the time of writing
|
||||
|
||||
// explanation: Positive lookahead: (?= «pattern») matches if pattern matches what comes after the current location in the input string.
|
||||
// Negative lookahead: (?! «pattern») matches if pattern does not match what comes after the current location in the input string
|
||||
// The change proposed is to not decrease the indent if there is a multi-line comment ending on the same line before the closing parentheses
|
||||
|
||||
const fileContents = [
|
||||
'function foo() {',
|
||||
' bar(/* */)',
|
||||
'};',
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
test('Issue #209859: do not do reindentation for tokens inside of a string', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/209859
|
||||
|
||||
const tokens: StandardTokenTypeData[][] = [
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.Other },
|
||||
{ startIndex: 12, standardTokenType: StandardTokenType.String },
|
||||
],
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.String },
|
||||
],
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.String },
|
||||
],
|
||||
[
|
||||
{ startIndex: 0, standardTokenType: StandardTokenType.String },
|
||||
]
|
||||
];
|
||||
disposables.add(registerTokenizationSupport(instantiationService, tokens, languageId));
|
||||
const fileContents = [
|
||||
'const foo = `some text',
|
||||
' which is strangely',
|
||||
' indented. It should',
|
||||
' not be reindented.`'
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
forceTokenizationFromLineToLine(model, 1, 4);
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
// Failing tests inferred from the current regexes...
|
||||
|
||||
test.skip('Incorrect deindentation after `*/}` string', () => {
|
||||
|
||||
// explanation: If */ was not before the }, the regex does not allow characters before the }, so there would not be an indent
|
||||
// Here since there is */ before the }, the regex allows all the characters before, hence there is a deindent
|
||||
|
||||
const fileContents = [
|
||||
`const obj = {`,
|
||||
` obj1: {`,
|
||||
` brace : '*/}'`,
|
||||
` }`,
|
||||
`}`,
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
// Failing tests from issues...
|
||||
|
||||
test.skip('Issue #56275', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/56275
|
||||
// explanation: If */ was not before the }, the regex does not allow characters before the }, so there would not be an indent
|
||||
// Here since there is */ before the }, the regex allows all the characters before, hence there is a deindent
|
||||
|
||||
let fileContents = [
|
||||
'function foo() {',
|
||||
' var bar = (/b*/);',
|
||||
'}',
|
||||
].join('\n');
|
||||
let model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
let editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
|
||||
fileContents = [
|
||||
'function foo() {',
|
||||
' var bar = "/b*/)";',
|
||||
'}',
|
||||
].join('\n');
|
||||
model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
test.skip('Issue #116843', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/116843
|
||||
// related: https://github.com/microsoft/vscode/issues/43244
|
||||
// explanation: When you have an arrow function, you don't have { or }, but you would expect indentation to still be done in that way
|
||||
|
||||
// TODO: requires exploring indent/outdent pairs instead
|
||||
|
||||
const fileContents = [
|
||||
'const add1 = (n) =>',
|
||||
' n + 1;',
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
test.skip('Issue #185252', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/185252
|
||||
// explanation: Reindenting the comment correctly
|
||||
|
||||
const fileContents = [
|
||||
'/*',
|
||||
' * This is a comment.',
|
||||
' */',
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
|
||||
test.skip('Issue 43244: incorrect indentation when signature of function call spans several lines', () => {
|
||||
|
||||
// issue: https://github.com/microsoft/vscode/issues/43244
|
||||
|
||||
const fileContents = [
|
||||
'function callSomeOtherFunction(one: number, two: number) { }',
|
||||
'function someFunction() {',
|
||||
' callSomeOtherFunction(4,',
|
||||
' 5)',
|
||||
'}',
|
||||
].join('\n');
|
||||
const model = disposables.add(instantiateTextModel(instantiationService, fileContents, languageId, options));
|
||||
const editOperations = getReindentEditOperations(model, languageConfigurationService, 1, model.getLineCount());
|
||||
assert.deepStrictEqual(editOperations.length, 0);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user