Skip to content

Commit 7dcd5a4

Browse files
authored
Remove use of editorconfig module to avoid dependency on one-ini wasm file. (#12579)
1 parent a0f863c commit 7dcd5a4

File tree

9 files changed

+290
-288
lines changed

9 files changed

+290
-288
lines changed

Extension/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6505,7 +6505,6 @@
65056505
"@vscode/test-electron": "^2.3.10",
65066506
"async-child-process": "^1.1.1",
65076507
"await-notify": "^1.0.1",
6508-
"copy-webpack-plugin": "^12.0.2",
65096508
"eslint": "^8.45.0",
65106509
"eslint-plugin-header": "^3.1.1",
65116510
"eslint-plugin-import": "^2.29.1",
@@ -6534,7 +6533,6 @@
65346533
"@vscode/extension-telemetry": "^0.9.6",
65356534
"chokidar": "^3.6.0",
65366535
"comment-json": "^4.2.3",
6537-
"editorconfig": "^2.0.0",
65386536
"escape-string-regexp": "^2.0.0",
65396537
"glob": "^7.2.3",
65406538
"minimatch": "^3.0.5",

Extension/src/LanguageServer/Providers/documentFormattingEditProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import * as vscode from 'vscode';
66
import { ResponseError } from 'vscode-languageclient';
77
import { DefaultClient, FormatDocumentRequest, FormatParams, FormatResult } from '../client';
8+
import { getEditorConfigSettings } from '../editorConfig';
89
import { RequestCancelled, ServerCancelled } from '../protocolFilter';
9-
import { CppSettings, OtherSettings, getEditorConfigSettings } from '../settings';
10+
import { CppSettings, OtherSettings } from '../settings';
1011
import { makeVscodeTextEdits } from '../utils';
1112

1213
export class DocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider {

Extension/src/LanguageServer/Providers/documentRangeFormattingEditProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import * as vscode from 'vscode';
66
import { ResponseError } from 'vscode-languageclient';
77
import { DefaultClient, FormatParams, FormatRangeRequest, FormatResult } from '../client';
8+
import { getEditorConfigSettings } from '../editorConfig';
89
import { RequestCancelled, ServerCancelled } from '../protocolFilter';
9-
import { CppSettings, getEditorConfigSettings } from '../settings';
10+
import { CppSettings } from '../settings';
1011
import { makeVscodeTextEdits } from '../utils';
1112

1213
export class DocumentRangeFormattingEditProvider implements vscode.DocumentRangeFormattingEditProvider {

Extension/src/LanguageServer/Providers/onTypeFormattingEditProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import * as vscode from 'vscode';
66
import { ResponseError } from 'vscode-languageclient';
77
import { DefaultClient, FormatOnTypeRequest, FormatParams, FormatResult } from '../client';
8+
import { getEditorConfigSettings } from '../editorConfig';
89
import { RequestCancelled, ServerCancelled } from '../protocolFilter';
9-
import { CppSettings, getEditorConfigSettings } from '../settings';
10+
import { CppSettings } from '../settings';
1011
import { makeVscodeTextEdits } from '../utils';
1112

1213
export class OnTypeFormattingEditProvider implements vscode.OnTypeFormattingEditProvider {

Extension/src/LanguageServer/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ import {
5353
import { Location, TextEdit, WorkspaceEdit } from './commonTypes';
5454
import * as configs from './configurations';
5555
import { DataBinding } from './dataBinding';
56+
import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig';
5657
import { CppSourceStr, clients, configPrefix, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
5758
import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization';
5859
import { PersistentFolderState, PersistentWorkspaceState } from './persistentState';
5960
import { createProtocolFilter } from './protocolFilter';
6061
import * as refs from './references';
61-
import { CppSettings, OtherSettings, SettingsParams, WorkspaceFolderSettingsParams, getEditorConfigSettings } from './settings';
62+
import { CppSettings, OtherSettings, SettingsParams, WorkspaceFolderSettingsParams } from './settings';
6263
import { SettingsTracker } from './settingsTracker';
6364
import { ConfigurationType, LanguageStatusUI, getUI } from './ui';
6465
import { handleChangedFromCppToC, makeLspRange, makeVscodeLocation, makeVscodeRange } from './utils';
@@ -102,7 +103,6 @@ let workspaceHash: string = "";
102103
let workspaceDisposables: vscode.Disposable[] = [];
103104
export let workspaceReferences: refs.ReferencesManager;
104105
export const openFileVersions: Map<string, number> = new Map<string, number>();
105-
export const cachedEditorConfigSettings: Map<string, any> = new Map<string, any>();
106106
export const cachedEditorConfigLookups: Map<string, boolean> = new Map<string, boolean>();
107107
export let semanticTokensLegend: vscode.SemanticTokensLegend | undefined;
108108

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
* See 'LICENSE' in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
'use strict';
6+
7+
import * as fs from 'fs';
8+
import * as path from 'path';
9+
10+
export const cachedEditorConfigSettings: Map<string, any> = new Map<string, any>();
11+
12+
export function mapIndentationReferenceToEditorConfig(value: string | undefined): string {
13+
if (value !== undefined) {
14+
// Will never actually be undefined, as these settings have default values.
15+
if (value === "statementBegin") {
16+
return "statement_begin";
17+
}
18+
if (value === "outermostParenthesis") {
19+
return "outermost_parenthesis";
20+
}
21+
}
22+
return "innermost_parenthesis";
23+
}
24+
25+
export function mapIndentToEditorConfig(value: string | undefined): string {
26+
if (value !== undefined) {
27+
// Will never actually be undefined, as these settings have default values.
28+
if (value === "leftmostColumn") {
29+
return "leftmost_column";
30+
}
31+
if (value === "oneLeft") {
32+
return "one_left";
33+
}
34+
}
35+
return "none";
36+
}
37+
38+
export function mapNewOrSameLineToEditorConfig(value: string | undefined): string {
39+
if (value !== undefined) {
40+
// Will never actually be undefined, as these settings have default values.
41+
if (value === "newLine") {
42+
return "new_line";
43+
}
44+
if (value === "sameLine") {
45+
return "same_line";
46+
}
47+
}
48+
return "ignore";
49+
}
50+
51+
export function mapWrapToEditorConfig(value: string | undefined): string {
52+
if (value !== undefined) {
53+
// Will never actually be undefined, as these settings have default values.
54+
if (value === "allOneLineScopes") {
55+
return "all_one_line_scopes";
56+
}
57+
if (value === "oneLiners") {
58+
return "one_liners";
59+
}
60+
}
61+
return "never";
62+
}
63+
64+
function matchesSection(filePath: string, section: string): boolean {
65+
const fileName: string = path.basename(filePath);
66+
// Escape all regex special characters except '*' and '?'.
67+
// Convert wildcards '*' to '.*' and '?' to '.'.
68+
const sectionPattern = section.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.');
69+
const regex: RegExp = new RegExp(`^${sectionPattern}$`);
70+
return regex.test(fileName);
71+
}
72+
73+
function parseEditorConfigContent(content: string): Record<string, any> {
74+
const lines = content.split(/\r?\n/);
75+
const config: Record<string, any> = {};
76+
let currentSection: string | null = '*'; // Use '*' for sectionless (global) settings.
77+
78+
lines.forEach(line => {
79+
line = line.trim();
80+
81+
if (!line || line.startsWith('#') || line.startsWith(';')) {
82+
// Skip empty lines and comments.
83+
return;
84+
}
85+
86+
if (line.startsWith('[') && line.endsWith(']')) {
87+
// New section (e.g., [*.js])
88+
currentSection = line.slice(1, -1).trim();
89+
config[currentSection] = config[currentSection] || {};
90+
} else {
91+
// Key-value pair (e.g., indent_style = space).
92+
const [key, ...values] = line.split('=');
93+
if (key && values.length > 0) {
94+
const trimmedKey = key.trim();
95+
const value = values.join('=').trim();
96+
if (currentSection) {
97+
// Ensure the current section is initialized.
98+
if (!config[currentSection]) {
99+
config[currentSection] = {};
100+
}
101+
config[currentSection][trimmedKey] = value;
102+
}
103+
}
104+
}
105+
});
106+
107+
return config;
108+
}
109+
110+
function getEditorConfig(filePath: string): any {
111+
let combinedConfig: any = {};
112+
let globalConfig: any = {};
113+
let currentDir: string = path.dirname(filePath);
114+
const rootDir: string = path.parse(currentDir).root;
115+
116+
// Traverse from the file's directory to the root directory.
117+
for (;;) {
118+
const editorConfigPath: string = path.join(currentDir, '.editorconfig');
119+
if (fs.existsSync(editorConfigPath)) {
120+
const configFileContent: string = fs.readFileSync(editorConfigPath, 'utf-8');
121+
const configData = parseEditorConfigContent(configFileContent);
122+
123+
// Extract global (sectionless) entries.
124+
if (configData['*']) {
125+
globalConfig = {
126+
...globalConfig,
127+
...configData['*']
128+
};
129+
}
130+
131+
// Match sections and combine configurations.
132+
Object.keys(configData).forEach((section: string) => {
133+
if (section !== '*' && matchesSection(filePath, section)) {
134+
combinedConfig = {
135+
...combinedConfig,
136+
...configData[section]
137+
};
138+
}
139+
});
140+
141+
// Check if the current .editorconfig is the root.
142+
if (configData['*']?.root?.toLowerCase() === 'true') {
143+
break; // Stop searching after processing the root = true file.
144+
}
145+
}
146+
if (currentDir === rootDir) {
147+
break; // Stop the loop after checking the root directory.
148+
}
149+
currentDir = path.dirname(currentDir);
150+
}
151+
152+
// Merge global config with section-based config.
153+
return {
154+
...globalConfig,
155+
...combinedConfig
156+
};
157+
}
158+
159+
// Look up the appropriate .editorconfig settings for the specified file.
160+
// This is intentionally not async to avoid races due to multiple entrancy.
161+
export function getEditorConfigSettings(fsPath: string): Promise<any> {
162+
let editorConfigSettings: any = cachedEditorConfigSettings.get(fsPath);
163+
if (!editorConfigSettings) {
164+
editorConfigSettings = getEditorConfig(fsPath);
165+
cachedEditorConfigSettings.set(fsPath, editorConfigSettings);
166+
}
167+
return editorConfigSettings;
168+
}

Extension/src/LanguageServer/settings.ts

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
'use strict';
66

77
import { execSync } from 'child_process';
8-
import * as editorConfig from 'editorconfig';
98
import * as fs from 'fs';
109
import * as os from 'os';
1110
import * as path from 'path';
@@ -17,7 +16,8 @@ import * as which from 'which';
1716
import { getCachedClangFormatPath, getCachedClangTidyPath, getExtensionFilePath, getRawSetting, isArray, isArrayOfString, isBoolean, isNumber, isObject, isString, isValidMapping, setCachedClangFormatPath, setCachedClangTidyPath } from '../common';
1817
import { isWindows } from '../constants';
1918
import * as telemetry from '../telemetry';
20-
import { DefaultClient, cachedEditorConfigLookups, cachedEditorConfigSettings, hasTrustedCompilerPaths } from './client';
19+
import { cachedEditorConfigLookups, DefaultClient, hasTrustedCompilerPaths } from './client';
20+
import { getEditorConfigSettings, mapIndentationReferenceToEditorConfig, mapIndentToEditorConfig, mapNewOrSameLineToEditorConfig, mapWrapToEditorConfig } from './editorConfig';
2121
import { clients } from './extension';
2222
import { CommentPattern } from './languageConfig';
2323
import { PersistentState } from './persistentState';
@@ -1076,66 +1076,3 @@ export class OtherSettings {
10761076
public get searchExclude(): Excludes { return this.getAsExcludes("search", "exclude", this.defaultSearchExcludes, this.resource); }
10771077
public get workbenchSettingsEditor(): string { return this.getAsString("workbench.settings", "editor", this.resource, "ui"); }
10781078
}
1079-
1080-
function mapIndentationReferenceToEditorConfig(value: string | undefined): string {
1081-
if (value !== undefined) {
1082-
// Will never actually be undefined, as these settings have default values.
1083-
if (value === "statementBegin") {
1084-
return "statement_begin";
1085-
}
1086-
if (value === "outermostParenthesis") {
1087-
return "outermost_parenthesis";
1088-
}
1089-
}
1090-
return "innermost_parenthesis";
1091-
}
1092-
1093-
function mapIndentToEditorConfig(value: string | undefined): string {
1094-
if (value !== undefined) {
1095-
// Will never actually be undefined, as these settings have default values.
1096-
if (value === "leftmostColumn") {
1097-
return "leftmost_column";
1098-
}
1099-
if (value === "oneLeft") {
1100-
return "one_left";
1101-
}
1102-
}
1103-
return "none";
1104-
}
1105-
1106-
function mapNewOrSameLineToEditorConfig(value: string | undefined): string {
1107-
if (value !== undefined) {
1108-
// Will never actually be undefined, as these settings have default values.
1109-
if (value === "newLine") {
1110-
return "new_line";
1111-
}
1112-
if (value === "sameLine") {
1113-
return "same_line";
1114-
}
1115-
}
1116-
return "ignore";
1117-
}
1118-
1119-
function mapWrapToEditorConfig(value: string | undefined): string {
1120-
if (value !== undefined) {
1121-
// Will never actually be undefined, as these settings have default values.
1122-
if (value === "allOneLineScopes") {
1123-
return "all_one_line_scopes";
1124-
}
1125-
if (value === "oneLiners") {
1126-
return "one_liners";
1127-
}
1128-
}
1129-
return "never";
1130-
}
1131-
1132-
// Look up the appropriate .editorconfig settings for the specified file.
1133-
// This is intentionally not async to avoid races due to multiple entrancy.
1134-
export function getEditorConfigSettings(fsPath: string): Promise<any> {
1135-
let editorConfigSettings: any = cachedEditorConfigSettings.get(fsPath);
1136-
if (!editorConfigSettings) {
1137-
editorConfigSettings = editorConfig.parseSync(fsPath);
1138-
cachedEditorConfigSettings.set(fsPath, editorConfigSettings);
1139-
}
1140-
return editorConfigSettings;
1141-
}

Extension/webpack.config.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
'use strict';
99

1010
const path = require('path');
11-
const copyPlugin = require('copy-webpack-plugin');
1211

1312
/**@type {import('webpack').Configuration}*/
1413
const config = {
@@ -32,16 +31,6 @@ const config = {
3231
extensions: ['.js', '.ts',],
3332
mainFields: ['main', 'module'],
3433
},
35-
plugins: [
36-
new copyPlugin({
37-
patterns: [
38-
{
39-
from: path.resolve(__dirname, 'node_modules', "@one-ini", "wasm", "one_ini_bg.wasm"),
40-
to: path.resolve(__dirname, 'dist', 'src')
41-
}
42-
]
43-
})
44-
],
4534
module: {
4635
rules: [{
4736
test: /\.ts$/,

0 commit comments

Comments
 (0)