Skip to content

Commit cb7261f

Browse files
author
Benjamin Pasero
committed
paths - adopt extname()
1 parent 8b4fd37 commit cb7261f

16 files changed

Lines changed: 71 additions & 71 deletions

File tree

src/vs/base/common/glob.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
import * as arrays from 'vs/base/common/arrays';
77
import * as strings from 'vs/base/common/strings';
8-
import * as paths from 'vs/base/common/paths';
9-
import { sep, posix } from 'vs/base/common/paths.node';
8+
import * as extpath from 'vs/base/common/paths';
9+
import * as paths from 'vs/base/common/paths.node';
1010
import { LRUCache } from 'vs/base/common/map';
1111
import { CharCode } from 'vs/base/common/charCode';
1212
import { isThenable } from 'vs/base/common/async';
@@ -332,7 +332,7 @@ function wrapRelativePattern(parsedPattern: ParsedStringPattern, arg2: string |
332332
}
333333

334334
return function (path, basename) {
335-
if (!paths.isEqualOrParent(path, arg2.base)) {
335+
if (!extpath.isEqualOrParent(path, arg2.base)) {
336336
return null;
337337
}
338338

@@ -397,8 +397,8 @@ function trivia3(pattern: string, options: IGlobOptions): ParsedStringPattern {
397397

398398
// common patterns: **/something/else just need endsWith check, something/else just needs and equals check
399399
function trivia4and5(path: string, pattern: string, matchPathEnds: boolean): ParsedStringPattern {
400-
const nativePath = sep !== posix.sep ? path.replace(ALL_FORWARD_SLASHES, sep) : path;
401-
const nativePathEnd = sep + nativePath;
400+
const nativePath = paths.sep !== paths.posix.sep ? path.replace(ALL_FORWARD_SLASHES, paths.sep) : path;
401+
const nativePathEnd = paths.sep + nativePath;
402402
const parsedPattern: ParsedStringPattern = matchPathEnds ? function (path, basename) {
403403
return typeof path === 'string' && (path === nativePath || strings.endsWith(path, nativePathEnd)) ? pattern : null;
404404
} : function (path, basename) {

src/vs/base/common/paths.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ export function basename(path: string): string {
2626
}
2727
}
2828

29-
/**
30-
* @returns `.far` from `boo.far` or the empty string.
31-
*/
32-
export function extname(path: string): string {
33-
path = basename(path);
34-
const idx = ~path.lastIndexOf('.');
35-
return idx ? path.substring(~idx) : '';
36-
}
37-
3829
const _posixBadPath = /(\/\.\.?\/)|(\/\.\.?)$|^(\.\.?\/)|(\/\/+)|(\\)/;
3930
const _winBadPath = /(\\\.\.?\\)|(\\\.\.?)$|^(\.\.?\\)|(\\\\+)|(\/)/;
4031

src/vs/base/common/resources.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as paths from 'vs/base/common/paths';
7-
import { isAbsolute, posix, dirname as pathDirname } from 'vs/base/common/paths.node';
6+
import * as extpath from 'vs/base/common/paths';
7+
import * as paths from 'vs/base/common/paths.node';
88
import { URI } from 'vs/base/common/uri';
99
import { equalsIgnoreCase } from 'vs/base/common/strings';
1010
import { Schemas } from 'vs/base/common/network';
@@ -33,10 +33,10 @@ export function basenameOrAuthority(resource: URI): string {
3333
export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase = hasToIgnoreCase(base)): boolean {
3434
if (base.scheme === parentCandidate.scheme) {
3535
if (base.scheme === Schemas.file) {
36-
return paths.isEqualOrParent(fsPath(base), fsPath(parentCandidate), ignoreCase);
36+
return extpath.isEqualOrParent(fsPath(base), fsPath(parentCandidate), ignoreCase);
3737
}
3838
if (isEqualAuthority(base.authority, parentCandidate.authority, ignoreCase)) {
39-
return paths.isEqualOrParent(base.path, parentCandidate.path, ignoreCase, '/');
39+
return extpath.isEqualOrParent(base.path, parentCandidate.path, ignoreCase, '/');
4040
}
4141
}
4242
return false;
@@ -82,9 +82,9 @@ export function dirname(resource: URI): URI | null {
8282
return resource;
8383
}
8484
if (resource.scheme === Schemas.file) {
85-
return URI.file(pathDirname(fsPath(resource)));
85+
return URI.file(paths.dirname(fsPath(resource)));
8686
}
87-
let dirname = posix.dirname(resource.path);
87+
let dirname = paths.posix.dirname(resource.path);
8888
if (resource.authority && dirname.length && dirname.charCodeAt(0) !== CharCode.Slash) {
8989
return null; // If a URI contains an authority component, then the path component must either be empty or begin with a CharCode.Slash ("/") character
9090
}
@@ -146,7 +146,7 @@ export function fsPath(uri: URI): string {
146146
} else if (
147147
isWindows
148148
&& uriPath.charCodeAt(0) === CharCode.Slash
149-
&& paths.isWindowsDriveLetter(uriPath.charCodeAt(1))
149+
&& extpath.isWindowsDriveLetter(uriPath.charCodeAt(1))
150150
&& uriPath.charCodeAt(2) === CharCode.Colon
151151
) {
152152
value = uriPath.substr(1);
@@ -164,7 +164,7 @@ export function fsPath(uri: URI): string {
164164
* Returns true if the URI path is absolute.
165165
*/
166166
export function isAbsolutePath(resource: URI): boolean {
167-
return isAbsolute(resource.path);
167+
return paths.isAbsolute(resource.path);
168168
}
169169

170170
export function distinctParents<T>(items: T[], resourceAccessor: (item: T) => URI): T[] {

src/vs/base/test/common/paths.node.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,13 @@ suite('Paths (Node Implementation)', () => {
354354
assert.strictEqual(path.posix.extname('file\\\\'), '');
355355
assert.strictEqual(path.posix.extname('file.\\'), '.\\');
356356
assert.strictEqual(path.posix.extname('file.\\\\'), '.\\\\');
357+
358+
// Tests from VSCode
359+
assert.equal(path.extname('far.boo'), '.boo');
360+
assert.equal(path.extname('far.b'), '.b');
361+
assert.equal(path.extname('far.'), '.');
362+
assert.equal(path.extname('far.boo/boo.far'), '.far');
363+
assert.equal(path.extname('far.boo/boo'), '');
357364
});
358365

359366
test('resolve', () => {
@@ -496,6 +503,27 @@ suite('Paths (Node Implementation)', () => {
496503
const controlCharFilename = `Icon${String.fromCharCode(13)}`;
497504
assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`),
498505
controlCharFilename);
506+
507+
// Tests from VSCode
508+
assert.equal(path.basename('foo/bar'), 'bar');
509+
assert.equal(path.posix.basename('foo\\bar'), 'foo\\bar');
510+
assert.equal(path.win32.basename('foo\\bar'), 'bar');
511+
assert.equal(path.basename('/foo/bar'), 'bar');
512+
assert.equal(path.posix.basename('\\foo\\bar'), '\\foo\\bar');
513+
assert.equal(path.win32.basename('\\foo\\bar'), 'bar');
514+
assert.equal(path.basename('./bar'), 'bar');
515+
assert.equal(path.posix.basename('.\\bar'), '.\\bar');
516+
assert.equal(path.win32.basename('.\\bar'), 'bar');
517+
assert.equal(path.basename('/bar'), 'bar');
518+
assert.equal(path.posix.basename('\\bar'), '\\bar');
519+
assert.equal(path.win32.basename('\\bar'), 'bar');
520+
assert.equal(path.basename('bar/'), 'bar');
521+
assert.equal(path.posix.basename('bar\\'), 'bar\\');
522+
assert.equal(path.win32.basename('bar\\'), 'bar');
523+
assert.equal(path.basename('bar'), 'bar');
524+
assert.equal(path.basename('////////'), '');
525+
assert.equal(path.posix.basename('\\\\\\\\'), '\\\\\\\\');
526+
assert.equal(path.win32.basename('\\\\\\\\'), '');
499527
});
500528

501529
test('relative', () => {

src/vs/base/test/common/paths.test.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,6 @@ suite('Paths', () => {
7171

7272
});
7373

74-
test('basename', () => {
75-
assert.equal(paths.basename('foo/bar'), 'bar');
76-
assert.equal(paths.basename('foo\\bar'), 'bar');
77-
assert.equal(paths.basename('/foo/bar'), 'bar');
78-
assert.equal(paths.basename('\\foo\\bar'), 'bar');
79-
assert.equal(paths.basename('./bar'), 'bar');
80-
assert.equal(paths.basename('.\\bar'), 'bar');
81-
assert.equal(paths.basename('/bar'), 'bar');
82-
assert.equal(paths.basename('\\bar'), 'bar');
83-
assert.equal(paths.basename('bar/'), 'bar');
84-
assert.equal(paths.basename('bar\\'), 'bar');
85-
assert.equal(paths.basename('bar'), 'bar');
86-
assert.equal(paths.basename('////////'), '');
87-
assert.equal(paths.basename('\\\\\\\\'), '');
88-
});
89-
9074
test('join', () => {
9175
assert.equal(paths.join('.', 'bar'), 'bar');
9276
assert.equal(paths.join('../../foo/bar', '../../foo'), '../../foo');
@@ -114,14 +98,6 @@ suite('Paths', () => {
11498
assert.equal(paths.join('http://localhost/test', 'test'), 'http://localhost/test/test');
11599
});
116100

117-
test('extname', () => {
118-
assert.equal(paths.extname('far.boo'), '.boo');
119-
assert.equal(paths.extname('far.b'), '.b');
120-
assert.equal(paths.extname('far.'), '.');
121-
assert.equal(paths.extname('far.boo/boo.far'), '.far');
122-
assert.equal(paths.extname('far.boo/boo'), '');
123-
});
124-
125101
test('isUNC', () => {
126102
if (platform.isWindows) {
127103
assert.ok(!paths.isUNC('foo'));

src/vs/base/test/node/glob.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,10 @@ suite('Glob', () => {
722722
assert.strictEqual(glob.match(expr, 'bar', hasSibling), '**/bar');
723723
assert.strictEqual(glob.match(expr, 'foo', hasSibling), null);
724724
assert.strictEqual(glob.match(expr, 'foo/bar', hasSibling), '**/bar');
725-
assert.strictEqual(glob.match(expr, 'foo\\bar', hasSibling), '**/bar');
725+
if (isWindows) {
726+
// backslash is a valid file name character on posix
727+
assert.strictEqual(glob.match(expr, 'foo\\bar', hasSibling), '**/bar');
728+
}
726729
assert.strictEqual(glob.match(expr, 'foo/foo', hasSibling), null);
727730
assert.strictEqual(glob.match(expr, 'foo.js', hasSibling), '**/*.js');
728731
assert.strictEqual(glob.match(expr, 'bar.js', hasSibling), null);

src/vs/platform/telemetry/common/telemetryUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { IDisposable } from 'vs/base/common/lifecycle';
77
import { guessMimeTypes } from 'vs/base/common/mime';
8-
import * as paths from 'vs/base/common/paths';
8+
import { extname } from 'vs/base/common/paths.node';
99
import { URI } from 'vs/base/common/uri';
1010
import { IConfigurationService, ConfigurationTarget, ConfigurationTargetToString } from 'vs/platform/configuration/common/configuration';
1111
import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/common/keybinding';
@@ -79,7 +79,7 @@ export interface URIDescriptor {
7979

8080
export function telemetryURIDescriptor(uri: URI, hashPath: (path: string) => string): URIDescriptor {
8181
const fsPath = uri && uri.fsPath;
82-
return fsPath ? { mimeType: guessMimeTypes(fsPath).join(', '), scheme: uri.scheme, ext: paths.extname(fsPath), path: hashPath(fsPath) } : {};
82+
return fsPath ? { mimeType: guessMimeTypes(fsPath).join(', '), scheme: uri.scheme, ext: extname(fsPath), path: hashPath(fsPath) } : {};
8383
}
8484

8585
/**

src/vs/platform/workspaces/common/workspaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
88
import { Event } from 'vs/base/common/event';
99
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
1010
import { URI, UriComponents } from 'vs/base/common/uri';
11-
import { extname } from 'vs/base/common/paths';
11+
import { extname } from 'vs/base/common/paths.node';
1212

1313
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
1414
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');

src/vs/workbench/browser/parts/editor/editorStatus.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'vs/css!./media/editorstatus';
77
import * as nls from 'vs/nls';
88
import { $, append, runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
99
import * as strings from 'vs/base/common/strings';
10-
import * as paths from 'vs/base/common/paths';
10+
import { extname, basename } from 'vs/base/common/resources';
1111
import * as types from 'vs/base/common/types';
1212
import { URI as uri } from 'vs/base/common/uri';
1313
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
@@ -911,7 +911,7 @@ export class ChangeModeAction extends Action {
911911
let configureModeSettings: IQuickPickItem;
912912
let galleryAction: Action;
913913
if (hasLanguageSupport) {
914-
const ext = paths.extname(resource.fsPath) || paths.basename(resource.fsPath);
914+
const ext = extname(resource) || basename(resource);
915915

916916
galleryAction = this.instantiationService.createInstance(ShowLanguageExtensionsAction, ext);
917917
if (galleryAction.enabled) {
@@ -992,9 +992,9 @@ export class ChangeModeAction extends Action {
992992
}
993993

994994
private configureFileAssociation(resource: uri): void {
995-
const extension = paths.extname(resource.fsPath);
996-
const basename = paths.basename(resource.fsPath);
997-
const currentAssociation = this.modeService.getModeIdByFilepathOrFirstLine(basename);
995+
const extension = extname(resource);
996+
const base = basename(resource);
997+
const currentAssociation = this.modeService.getModeIdByFilepathOrFirstLine(base);
998998

999999
const languages = this.modeService.getRegisteredLanguageNames();
10001000
const picks: IQuickPickItem[] = languages.sort().map((lang, index) => {
@@ -1008,15 +1008,15 @@ export class ChangeModeAction extends Action {
10081008
});
10091009

10101010
setTimeout(() => {
1011-
this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguageToConfigure', "Select Language Mode to Associate with '{0}'", extension || basename) }).then(language => {
1011+
this.quickInputService.pick(picks, { placeHolder: nls.localize('pickLanguageToConfigure', "Select Language Mode to Associate with '{0}'", extension || base) }).then(language => {
10121012
if (language) {
10131013
const fileAssociationsConfig = this.configurationService.inspect(FILES_ASSOCIATIONS_CONFIG);
10141014

10151015
let associationKey: string;
1016-
if (extension && basename[0] !== '.') {
1016+
if (extension && base[0] !== '.') {
10171017
associationKey = `*${extension}`; // only use "*.ext" if the file path is in the form of <name>.<ext>
10181018
} else {
1019-
associationKey = basename; // otherwise use the basename (e.g. .gitignore, Dockerfile)
1019+
associationKey = base; // otherwise use the basename (e.g. .gitignore, Dockerfile)
10201020
}
10211021

10221022
// If the association is already being made in the workspace, make sure to target workspace settings

src/vs/workbench/common/resources.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as paths from 'vs/base/common/paths';
88
import * as objects from 'vs/base/common/objects';
99
import { Event, Emitter } from 'vs/base/common/event';
1010
import { relative } from 'vs/base/common/paths.node';
11+
import { basename, extname } from 'vs/base/common/resources';
1112
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
1213
import { IModeService } from 'vs/editor/common/services/modeService';
1314
import { IFileService } from 'vs/platform/files/common/files';
@@ -64,9 +65,9 @@ export class ResourceContextKey extends Disposable implements IContextKey<URI> {
6465
if (!ResourceContextKey._uriEquals(this._resourceKey.get(), value)) {
6566
this._resourceKey.set(value);
6667
this._schemeKey.set(value && value.scheme);
67-
this._filenameKey.set(value && paths.basename(value.fsPath));
68+
this._filenameKey.set(value && basename(value));
6869
this._langIdKey.set(value ? this._modeService.getModeIdByFilepathOrFirstLine(value.fsPath) : null);
69-
this._extensionKey.set(value && paths.extname(value.fsPath));
70+
this._extensionKey.set(value && extname(value));
7071
this._hasResource.set(!!value);
7172
this._isFileSystemResource.set(value && this._fileService.canHandleResource(value));
7273
}

0 commit comments

Comments
 (0)