Merge branch 'master' into joh/splash

This commit is contained in:
Johannes Rieken 2018-07-24 09:35:15 +02:00
commit 7348d2f74b
280 changed files with 8049 additions and 4031 deletions

View file

@ -21,5 +21,9 @@
'2018-05-15 12:00, US/Pacific': 'development',
'2018-05-28 18:00, US/Pacific': 'endgame',
# 'release' not needed anymore, return to 'development' after releasing.
'2018-06-06 12:00, US/Pacific': 'development',
'2018-06-06 12:00, US/Pacific': 'development', # 1.24.0 released
'2018-06-25 18:00, US/Pacific': 'endgame',
'2018-07-05 12:00, US/Pacific': 'development', # 1.25.0 released
'2018-07-30 18:00, US/Pacific': 'endgame',
# '2018-08-08 12:00, US/Pacific': 'development', # 1.26.0 released
}

2
.gitignore vendored
View file

@ -6,6 +6,8 @@ node_modules/
out/
out-build/
out-editor/
out-editor-src/
out-editor-build/
out-editor-esm/
out-editor-min/
out-monaco-editor-core/

View file

@ -1,12 +1,12 @@
[
{
"name": "ms-vscode.node-debug",
"version": "1.26.4",
"version": "1.26.5",
"repo": "https://github.com/Microsoft/vscode-node-debug"
},
{
"name": "ms-vscode.node-debug2",
"version": "1.26.3",
"version": "1.26.5",
"repo": "https://github.com/Microsoft/vscode-node-debug2"
}
]

View file

@ -12,6 +12,9 @@ const File = require('vinyl');
const i18n = require('./lib/i18n');
const standalone = require('./lib/standalone');
const cp = require('child_process');
const compilation = require('./lib/compilation');
const monacoapi = require('./monaco/api');
const fs = require('fs');
var root = path.dirname(__dirname);
var sha1 = util.getVersion(root);
@ -58,29 +61,56 @@ var BUNDLED_FILE_HEADER = [
''
].join('\n');
function editorLoaderConfig() {
var result = common.loaderConfig();
// never ship octicons in editor
result.paths['vs/base/browser/ui/octiconLabel/octiconLabel'] = 'out-build/vs/base/browser/ui/octiconLabel/octiconLabel.mock';
// force css inlining to use base64 -- see https://github.com/Microsoft/monaco-editor/issues/148
result['vs/css'] = {
inlineResources: 'base64',
inlineResourcesLimit: 3000 // see https://github.com/Microsoft/monaco-editor/issues/336
};
return result;
}
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
gulp.task('clean-editor-src', util.rimraf('out-editor-src'));
gulp.task('extract-editor-src', ['clean-editor-src'], function () {
console.log(`If the build fails, consider tweaking shakeLevel below to a lower value.`);
const apiusages = monacoapi.execute().usageContent;
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
standalone.extractEditor({
sourcesRoot: path.join(root, 'src'),
entryPoints: [
'vs/editor/editor.main',
'vs/editor/editor.worker',
'vs/base/worker/workerMain',
],
inlineEntryPoints: [
apiusages,
extrausages
],
libs: [
`lib.d.ts`,
`lib.es2015.collection.d.ts`
],
redirects: {
'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock',
},
compilerOptions: {
module: 2, // ModuleKind.AMD
},
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
importIgnorePattern: /^vs\/css!/,
destRoot: path.join(root, 'out-editor-src')
});
});
// Full compile, including nls and inline sources in sourcemaps, for build
gulp.task('clean-editor-build', util.rimraf('out-editor-build'));
gulp.task('compile-editor-build', ['clean-editor-build', 'extract-editor-src'], compilation.compileTask('out-editor-src', 'out-editor-build', true));
gulp.task('clean-optimized-editor', util.rimraf('out-editor'));
gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-client-build'], common.optimizeTask({
gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-editor-build'], common.optimizeTask({
src: 'out-editor-build',
entryPoints: editorEntryPoints,
otherSources: editorOtherSources,
resources: editorResources,
loaderConfig: editorLoaderConfig(),
loaderConfig: {
paths: {
'vs': 'out-editor-build/vs',
'vscode': 'empty:'
}
},
bundleLoader: false,
header: BUNDLED_FILE_HEADER,
bundleInfo: true,
@ -229,7 +259,7 @@ gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify
});
gulp.task('analyze-editor-distro', function () {
// @ts-ignore
// @ts-ignore
var bundleInfo = require('../out-editor/bundleInfo.json');
var graph = bundleInfo.graph;
var bundles = bundleInfo.bundles;

View file

@ -95,6 +95,7 @@ const BUNDLED_FILE_HEADER = [
gulp.task('clean-optimized-vscode', util.rimraf('out-vscode'));
gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compile-extensions-build'], common.optimizeTask({
src: 'out-build',
entryPoints: vscodeEntryPoints,
otherSources: [],
resources: vscodeResources,

View file

@ -18,18 +18,21 @@ var _ = require("underscore");
var monacodts = require("../monaco/api");
var fs = require("fs");
var reporter = reporter_1.createReporter();
var rootDir = path.join(__dirname, '../../src');
var options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
function getTypeScriptCompilerOptions(src) {
var rootDir = path.join(__dirname, "../../" + src);
var options = require("../../" + src + "/tsconfig.json").compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
return options;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
function createCompile(build, emitError) {
var opts = _.clone(options);
function createCompile(src, build, emitError) {
var opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
var ts = tsb.create(opts, null, null, function (err) { return reporter(err.toString()); });
@ -51,31 +54,31 @@ function createCompile(build, emitError) {
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: options.sourceRoot
sourceRoot: opts.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
return es.duplex(input, output);
};
}
function compileTask(out, build) {
function compileTask(src, out, build) {
return function () {
var compile = createCompile(build, true);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
var compile = createCompile(src, build, true);
var srcPipe = es.merge(gulp.src(src + "/**", { base: "" + src }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
// Do not write .d.ts files to disk, as they are not needed there.
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
return src
return srcPipe
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, false));
.pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
};
}
exports.compileTask = compileTask;
function watchTask(out, build) {
return function () {
var compile = createCompile(build);
var compile = createCompile('src', build);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
var watchSrc = watch('src/**', { base: 'src' });
// Do not write .d.ts files to disk, as they are not needed there.
@ -122,6 +125,7 @@ function monacodtsTask(out, isWatch) {
fs.writeFileSync(result.filePath, result.content);
}
else {
fs.writeFileSync(result.filePath, result.content);
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
}

View file

@ -21,19 +21,22 @@ import * as fs from 'fs';
const reporter = createReporter();
const rootDir = path.join(__dirname, '../../src');
const options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
function getTypeScriptCompilerOptions(src: string) {
const rootDir = path.join(__dirname, `../../${src}`);
const options = require(`../../${src}/tsconfig.json`).compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
return options;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
function createCompile(build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
const opts = _.clone(options);
function createCompile(src: string, build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
const opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
@ -59,7 +62,7 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: options.sourceRoot
sourceRoot: opts.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
@ -68,32 +71,32 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
};
}
export function compileTask(out: string, build: boolean): () => NodeJS.ReadWriteStream {
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
return function () {
const compile = createCompile(build, true);
const compile = createCompile(src, build, true);
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
const srcPipe = es.merge(
gulp.src(`${src}/**`, { base: `${src}` }),
gulp.src('node_modules/typescript/lib/lib.d.ts'),
);
// Do not write .d.ts files to disk, as they are not needed there.
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
return src
return srcPipe
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, false));
.pipe(src !== 'src' ? es.through() : monacodtsTask(out, false));
};
}
export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteStream {
return function () {
const compile = createCompile(build);
const compile = createCompile('src', build);
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
@ -150,6 +153,7 @@ function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
} else {
fs.writeFileSync(result.filePath, result.content);
resultStream.emit('error', 'monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.');
}
}

View file

@ -37,19 +37,19 @@ function loaderConfig(emptyPaths) {
}
exports.loaderConfig = loaderConfig;
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
function loader(bundledFileHeader, bundleLoader) {
function loader(src, bundledFileHeader, bundleLoader) {
var sources = [
'out-build/vs/loader.js'
src + "/vs/loader.js"
];
if (bundleLoader) {
sources = sources.concat([
'out-build/vs/css.js',
'out-build/vs/nls.js'
src + "/vs/css.js",
src + "/vs/nls.js"
]);
}
var isFirst = true;
return (gulp
.src(sources, { base: 'out-build' })
.src(sources, { base: "" + src })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
@ -71,7 +71,7 @@ function loader(bundledFileHeader, bundleLoader) {
return f;
})));
}
function toConcatStream(bundledFileHeader, sources, dest) {
function toConcatStream(src, bundledFileHeader, sources, dest) {
var useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
// If a bundle ends up including in any of the sources our copyright, then
// insert a fake source at the beginning of each bundle with our copyright
@ -91,7 +91,7 @@ function toConcatStream(bundledFileHeader, sources, dest) {
}
var treatedSources = sources.map(function (source) {
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
var base = source.path ? root + '/out-build' : '';
var base = source.path ? root + ("/" + src) : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
base: base,
@ -102,12 +102,13 @@ function toConcatStream(bundledFileHeader, sources, dest) {
.pipe(useSourcemaps ? util.loadSourcemaps() : es.through())
.pipe(concat(dest));
}
function toBundleStream(bundledFileHeader, bundles) {
function toBundleStream(src, bundledFileHeader, bundles) {
return es.merge(bundles.map(function (bundle) {
return toConcatStream(bundledFileHeader, bundle.sources, bundle.dest);
return toConcatStream(src, bundledFileHeader, bundle.sources, bundle.dest);
}));
}
function optimizeTask(opts) {
var src = opts.src;
var entryPoints = opts.entryPoints;
var otherSources = opts.otherSources;
var resources = opts.resources;
@ -123,7 +124,7 @@ function optimizeTask(opts) {
if (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
toBundleStream(bundledFileHeader, result.files).pipe(bundlesStream);
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
var filteredResources = resources.slice();
result.cssInlinedResources.forEach(function (resource) {
@ -132,7 +133,7 @@ function optimizeTask(opts) {
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: 'out-build' }).pipe(resourcesStream);
gulp.src(filteredResources, { base: "" + src }).pipe(resourcesStream);
var bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
@ -145,9 +146,9 @@ function optimizeTask(opts) {
});
var otherSourcesStream = es.through();
var otherSourcesStreamArr = [];
gulp.src(otherSources, { base: 'out-build' })
gulp.src(otherSources, { base: "" + src })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(bundledFileHeader, [data], data.relative));
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
@ -156,7 +157,7 @@ function optimizeTask(opts) {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
var result = es.merge(loader(bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
var result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: null,

View file

@ -50,21 +50,21 @@ declare class FileSourceMap extends VinylFile {
public sourceMap: sm.RawSourceMap;
}
function loader(bundledFileHeader: string, bundleLoader: boolean): NodeJS.ReadWriteStream {
function loader(src: string, bundledFileHeader: string, bundleLoader: boolean): NodeJS.ReadWriteStream {
let sources = [
'out-build/vs/loader.js'
`${src}/vs/loader.js`
];
if (bundleLoader) {
sources = sources.concat([
'out-build/vs/css.js',
'out-build/vs/nls.js'
`${src}/vs/css.js`,
`${src}/vs/nls.js`
]);
}
let isFirst = true;
return (
gulp
.src(sources, { base: 'out-build' })
.src(sources, { base: `${src}` })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
@ -87,7 +87,7 @@ function loader(bundledFileHeader: string, bundleLoader: boolean): NodeJS.ReadWr
);
}
function toConcatStream(bundledFileHeader: string, sources: bundle.IFile[], dest: string): NodeJS.ReadWriteStream {
function toConcatStream(src: string, bundledFileHeader: string, sources: bundle.IFile[], dest: string): NodeJS.ReadWriteStream {
const useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
// If a bundle ends up including in any of the sources our copyright, then
@ -110,7 +110,7 @@ function toConcatStream(bundledFileHeader: string, sources: bundle.IFile[], dest
const treatedSources = sources.map(function (source) {
const root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
const base = source.path ? root + '/out-build' : '';
const base = source.path ? root + `/${src}` : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
@ -124,13 +124,17 @@ function toConcatStream(bundledFileHeader: string, sources: bundle.IFile[], dest
.pipe(concat(dest));
}
function toBundleStream(bundledFileHeader: string, bundles: bundle.IConcatFile[]): NodeJS.ReadWriteStream {
function toBundleStream(src:string, bundledFileHeader: string, bundles: bundle.IConcatFile[]): NodeJS.ReadWriteStream {
return es.merge(bundles.map(function (bundle) {
return toConcatStream(bundledFileHeader, bundle.sources, bundle.dest);
return toConcatStream(src, bundledFileHeader, bundle.sources, bundle.dest);
}));
}
export interface IOptimizeTaskOpts {
/**
* The folder to read files from.
*/
src: string;
/**
* (for AMD files, will get bundled and get Copyright treatment)
*/
@ -167,6 +171,7 @@ export interface IOptimizeTaskOpts {
}
export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream {
const src = opts.src;
const entryPoints = opts.entryPoints;
const otherSources = opts.otherSources;
const resources = opts.resources;
@ -183,7 +188,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err) { return bundlesStream.emit('error', JSON.stringify(err)); }
toBundleStream(bundledFileHeader, result.files).pipe(bundlesStream);
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
const filteredResources = resources.slice();
@ -193,7 +198,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: 'out-build' }).pipe(resourcesStream);
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
const bundleInfoArray: VinylFile[] = [];
if (opts.bundleInfo) {
@ -209,9 +214,9 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
const otherSourcesStream = es.through();
const otherSourcesStreamArr: NodeJS.ReadWriteStream[] = [];
gulp.src(otherSources, { base: 'out-build' })
gulp.src(otherSources, { base: `${src}` })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(bundledFileHeader, [data], data.relative));
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
@ -221,7 +226,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
}));
const result = es.merge(
loader(bundledFileHeader, bundleLoader),
loader(src, bundledFileHeader, bundleLoader),
bundlesStream,
otherSourcesStream,
resourcesStream,

View file

@ -7,9 +7,93 @@ Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var fs = require("fs");
var path = require("path");
var tss = require("./treeshaking");
var REPO_ROOT = path.join(__dirname, '../../');
var SRC_DIR = path.join(REPO_ROOT, 'src');
var OUT_EDITOR = path.join(REPO_ROOT, 'out-editor');
var dirCache = {};
function writeFile(filePath, contents) {
function ensureDirs(dirPath) {
if (dirCache[dirPath]) {
return;
}
dirCache[dirPath] = true;
ensureDirs(path.dirname(dirPath));
if (fs.existsSync(dirPath)) {
return;
}
fs.mkdirSync(dirPath);
}
ensureDirs(path.dirname(filePath));
fs.writeFileSync(filePath, contents);
}
function extractEditor(options) {
var result = tss.shake(options);
for (var fileName in result) {
if (result.hasOwnProperty(fileName)) {
writeFile(path.join(options.destRoot, fileName), result[fileName]);
}
}
var copied = {};
var copyFile = function (fileName) {
if (copied[fileName]) {
return;
}
copied[fileName] = true;
var srcPath = path.join(options.sourcesRoot, fileName);
var dstPath = path.join(options.destRoot, fileName);
writeFile(dstPath, fs.readFileSync(srcPath));
};
var writeOutputFile = function (fileName, contents) {
writeFile(path.join(options.destRoot, fileName), contents);
};
for (var fileName in result) {
if (result.hasOwnProperty(fileName)) {
var fileContents = result[fileName];
var info = ts.preProcessFile(fileContents);
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
var importedFileName = info.importedFiles[i].fileName;
var importedFilePath = void 0;
if (/^vs\/css!/.test(importedFileName)) {
importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
}
else {
importedFilePath = importedFileName;
}
if (/(^\.\/)|(^\.\.\/)/.test(importedFilePath)) {
importedFilePath = path.join(path.dirname(fileName), importedFilePath);
}
if (/\.css$/.test(importedFilePath)) {
transportCSS(importedFilePath, copyFile, writeOutputFile);
}
else {
if (fs.existsSync(path.join(options.sourcesRoot, importedFilePath + '.js'))) {
copyFile(importedFilePath + '.js');
}
}
}
}
}
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
'vs/css.build.js',
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
exports.extractEditor = extractEditor;
function createESMSourcesAndResources(options) {
var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
@ -94,7 +178,7 @@ function createESMSourcesAndResources(options) {
options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); });
while (queue.length > 0) {
var module_1 = queue.shift();
if (transportCSS(options, module_1, enqueue, write)) {
if (transportCSS(module_1, enqueue, write)) {
continue;
}
if (transportResource(options, module_1, enqueue, write)) {
@ -171,7 +255,7 @@ function createESMSourcesAndResources(options) {
fs.writeFileSync(path.join(OUT_FOLDER, 'vs/monaco.d.ts'), monacodts);
}
exports.createESMSourcesAndResources = createESMSourcesAndResources;
function transportCSS(options, module, enqueue, write) {
function transportCSS(module, enqueue, write) {
if (!/\.css/.test(module)) {
return false;
}
@ -179,10 +263,10 @@ function transportCSS(options, module, enqueue, write) {
var fileContents = fs.readFileSync(filename).toString();
var inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148
var inlineResourcesLimit = 300000; //3000; // see https://github.com/Microsoft/monaco-editor/issues/336
var newContents = _rewriteOrInlineUrls(filename, fileContents, inlineResources === 'base64', inlineResourcesLimit);
var newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64', inlineResourcesLimit);
write(module, newContents);
return true;
function _rewriteOrInlineUrls(originalFileFSPath, contents, forceBase64, inlineByteLimit) {
function _rewriteOrInlineUrls(contents, forceBase64, inlineByteLimit) {
return _replaceURL(contents, function (url) {
var imagePath = path.join(path.dirname(module), url);
var fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath));

View file

@ -6,11 +6,101 @@
import * as ts from 'typescript';
import * as fs from 'fs';
import * as path from 'path';
import * as tss from './treeshaking';
const REPO_ROOT = path.join(__dirname, '../../');
const SRC_DIR = path.join(REPO_ROOT, 'src');
const OUT_EDITOR = path.join(REPO_ROOT, 'out-editor');
let dirCache: { [dir: string]: boolean; } = {};
function writeFile(filePath: string, contents: Buffer | string): void {
function ensureDirs(dirPath: string): void {
if (dirCache[dirPath]) {
return;
}
dirCache[dirPath] = true;
ensureDirs(path.dirname(dirPath));
if (fs.existsSync(dirPath)) {
return;
}
fs.mkdirSync(dirPath);
}
ensureDirs(path.dirname(filePath));
fs.writeFileSync(filePath, contents);
}
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
writeFile(path.join(options.destRoot, fileName), result[fileName]);
}
}
let copied: { [fileName:string]: boolean; } = {};
const copyFile = (fileName: string) => {
if (copied[fileName]) {
return;
}
copied[fileName] = true;
const srcPath = path.join(options.sourcesRoot, fileName);
const dstPath = path.join(options.destRoot, fileName);
writeFile(dstPath, fs.readFileSync(srcPath));
};
const writeOutputFile = (fileName: string, contents: string) => {
writeFile(path.join(options.destRoot, fileName), contents);
};
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
const fileContents = result[fileName];
const info = ts.preProcessFile(fileContents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFileName = info.importedFiles[i].fileName;
let importedFilePath: string;
if (/^vs\/css!/.test(importedFileName)) {
importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
} else {
importedFilePath = importedFileName;
}
if (/(^\.\/)|(^\.\.\/)/.test(importedFilePath)) {
importedFilePath = path.join(path.dirname(fileName), importedFilePath);
}
if (/\.css$/.test(importedFilePath)) {
transportCSS(importedFilePath, copyFile, writeOutputFile);
} else {
if (fs.existsSync(path.join(options.sourcesRoot, importedFilePath + '.js'))) {
copyFile(importedFilePath + '.js');
}
}
}
}
}
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
'vs/css.build.js',
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
export interface IOptions {
entryPoints: string[];
outFolder: string;
@ -111,7 +201,7 @@ export function createESMSourcesAndResources(options: IOptions): void {
while (queue.length > 0) {
const module = queue.shift();
if (transportCSS(options, module, enqueue, write)) {
if (transportCSS(module, enqueue, write)) {
continue;
}
if (transportResource(options, module, enqueue, write)) {
@ -198,7 +288,7 @@ export function createESMSourcesAndResources(options: IOptions): void {
}
function transportCSS(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean {
function transportCSS(module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean {
if (!/\.css/.test(module)) {
return false;
@ -209,11 +299,11 @@ function transportCSS(options: IOptions, module: string, enqueue: (module: strin
const inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148
const inlineResourcesLimit = 300000;//3000; // see https://github.com/Microsoft/monaco-editor/issues/336
const newContents = _rewriteOrInlineUrls(filename, fileContents, inlineResources === 'base64', inlineResourcesLimit);
const newContents = _rewriteOrInlineUrls(fileContents, inlineResources === 'base64', inlineResourcesLimit);
write(module, newContents);
return true;
function _rewriteOrInlineUrls(originalFileFSPath: string, contents: string, forceBase64: boolean, inlineByteLimit: number): string {
function _rewriteOrInlineUrls(contents: string, forceBase64: boolean, inlineByteLimit: number): string {
return _replaceURL(contents, (url) => {
let imagePath = path.join(path.dirname(module), url);
let fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath));

682
build/lib/treeshaking.js Normal file
View file

@ -0,0 +1,682 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var ts = require("typescript");
var TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
var ShakeLevel;
(function (ShakeLevel) {
ShakeLevel[ShakeLevel["Files"] = 0] = "Files";
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function shake(options) {
var languageService = createTypeScriptLanguageService(options);
markNodes(languageService, options);
return generateResult(languageService, options.shakeLevel);
}
exports.shake = shake;
//#region Discovery, LanguageService & Setup
function createTypeScriptLanguageService(options) {
// Discover referenced files
var FILES = discoverAndReadFiles(options);
// Add fake usage files
options.inlineEntryPoints.forEach(function (inlineEntryPoint, index) {
FILES["inlineEntryPoint:" + index + ".ts"] = inlineEntryPoint;
});
// Resolve libs
var RESOLVED_LIBS = {};
options.libs.forEach(function (filename) {
var filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS["defaultLib:" + filename] = fs.readFileSync(filepath).toString();
});
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
return ts.createLanguageService(host);
}
/**
* Read imports and follow them until all files have been handled
*/
function discoverAndReadFiles(options) {
var FILES = {};
var in_queue = Object.create(null);
var queue = [];
var enqueue = function (moduleId) {
if (in_queue[moduleId]) {
return;
}
in_queue[moduleId] = true;
queue.push(moduleId);
};
options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); });
while (queue.length > 0) {
var moduleId = queue.shift();
var dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
var dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
continue;
}
var ts_filename = void 0;
if (options.redirects[moduleId]) {
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
}
else {
ts_filename = path.join(options.sourcesRoot, moduleId + '.ts');
}
var ts_filecontents = fs.readFileSync(ts_filename).toString();
var info = ts.preProcessFile(ts_filecontents);
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
var importedFileName = info.importedFiles[i].fileName;
if (options.importIgnorePattern.test(importedFileName)) {
// Ignore vs/css! imports
continue;
}
var importedModuleId = importedFileName;
if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) {
importedModuleId = path.join(path.dirname(moduleId), importedModuleId);
}
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
}
return FILES;
}
/**
* A TypeScript language service host
*/
var TypeScriptLanguageServiceHost = /** @class */ (function () {
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
else if (this._libs.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
}
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (options) {
return 'defaultLib:lib.d.ts';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
};
return TypeScriptLanguageServiceHost;
}());
//#endregion
//#region Tree Shaking
var NodeColor;
(function (NodeColor) {
NodeColor[NodeColor["White"] = 0] = "White";
NodeColor[NodeColor["Gray"] = 1] = "Gray";
NodeColor[NodeColor["Black"] = 2] = "Black";
})(NodeColor || (NodeColor = {}));
function getColor(node) {
return node.$$$color || 0 /* White */;
}
function setColor(node, color) {
node.$$$color = color;
}
function nodeOrParentIsBlack(node) {
while (node) {
var color = getColor(node);
if (color === 2 /* Black */) {
return true;
}
node = node.parent;
}
return false;
}
function nodeOrChildIsBlack(node) {
if (getColor(node) === 2 /* Black */) {
return true;
}
for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
var child = _a[_i];
if (nodeOrChildIsBlack(child)) {
return true;
}
}
return false;
}
function markNodes(languageService, options) {
var program = languageService.getProgram();
if (options.shakeLevel === 0 /* Files */) {
// Mark all source files Black
program.getSourceFiles().forEach(function (sourceFile) {
setColor(sourceFile, 2 /* Black */);
});
return;
}
var black_queue = [];
var gray_queue = [];
var sourceFilesLoaded = {};
function enqueueTopLevelModuleStatements(sourceFile) {
sourceFile.forEachChild(function (node) {
if (ts.isImportDeclaration(node)) {
if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, 2 /* Black */);
enqueueImport(node, node.moduleSpecifier.text);
}
return;
}
if (ts.isExportDeclaration(node)) {
if (ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, 2 /* Black */);
enqueueImport(node, node.moduleSpecifier.text);
}
return;
}
if (ts.isExpressionStatement(node)
|| ts.isIfStatement(node)
|| ts.isIterationStatement(node, true)
|| ts.isExportAssignment(node)) {
enqueue_black(node);
}
if (ts.isImportEqualsDeclaration(node)) {
if (/export/.test(node.getFullText(sourceFile))) {
// e.g. "export import Severity = BaseSeverity;"
enqueue_black(node);
}
}
});
}
function enqueue_gray(node) {
if (nodeOrParentIsBlack(node) || getColor(node) === 1 /* Gray */) {
return;
}
setColor(node, 1 /* Gray */);
gray_queue.push(node);
}
function enqueue_black(node) {
var previousColor = getColor(node);
if (previousColor === 2 /* Black */) {
return;
}
if (previousColor === 1 /* Gray */) {
// remove from gray queue
gray_queue.splice(gray_queue.indexOf(node), 1);
setColor(node, 0 /* White */);
// add to black queue
enqueue_black(node);
// // move from one queue to the other
// black_queue.push(node);
// setColor(node, NodeColor.Black);
return;
}
if (nodeOrParentIsBlack(node)) {
return;
}
var fileName = node.getSourceFile().fileName;
if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) {
setColor(node, 2 /* Black */);
return;
}
var sourceFile = node.getSourceFile();
if (!sourceFilesLoaded[sourceFile.fileName]) {
sourceFilesLoaded[sourceFile.fileName] = true;
enqueueTopLevelModuleStatements(sourceFile);
}
if (ts.isSourceFile(node)) {
return;
}
setColor(node, 2 /* Black */);
black_queue.push(node);
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) {
var references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
if (references) {
for (var i = 0, len = references.length; i < len; i++) {
var reference = references[i];
var referenceSourceFile = program.getSourceFile(reference.fileName);
var referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
if (ts.isMethodDeclaration(referenceNode.parent)
|| ts.isPropertyDeclaration(referenceNode.parent)
|| ts.isGetAccessor(referenceNode.parent)
|| ts.isSetAccessor(referenceNode.parent)) {
enqueue_gray(referenceNode.parent);
}
}
}
}
}
function enqueueFile(filename) {
var sourceFile = program.getSourceFile(filename);
if (!sourceFile) {
console.warn("Cannot find source file " + filename);
return;
}
enqueue_black(sourceFile);
}
function enqueueImport(node, importText) {
if (options.importIgnorePattern.test(importText)) {
// this import should be ignored
return;
}
var nodeSourceFile = node.getSourceFile();
var fullPath;
if (/(^\.\/)|(^\.\.\/)/.test(importText)) {
fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts';
}
else {
fullPath = importText + '.ts';
}
enqueueFile(fullPath);
}
options.entryPoints.forEach(function (moduleId) { return enqueueFile(moduleId + '.ts'); });
// Add fake usage files
options.inlineEntryPoints.forEach(function (_, index) { return enqueueFile("inlineEntryPoint:" + index + ".ts"); });
var step = 0;
var checker = program.getTypeChecker();
var _loop_1 = function () {
++step;
var node = void 0;
if (step % 100 === 0) {
console.log(step + "/" + (step + black_queue.length + gray_queue.length) + " (" + black_queue.length + ", " + gray_queue.length + ")");
}
if (black_queue.length === 0) {
for (var i = 0; i < gray_queue.length; i++) {
var node_1 = gray_queue[i];
var nodeParent = node_1.parent;
if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) {
gray_queue.splice(i, 1);
black_queue.push(node_1);
setColor(node_1, 2 /* Black */);
i--;
}
}
}
if (black_queue.length > 0) {
node = black_queue.shift();
}
else {
return "break";
}
var nodeSourceFile = node.getSourceFile();
var loop = function (node) {
var _a = getRealNodeSymbol(checker, node), symbol = _a[0], symbolImportNode = _a[1];
if (symbolImportNode) {
setColor(symbolImportNode, 2 /* Black */);
}
if (symbol && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
var declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
}
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) {
enqueue_black(declaration.name);
for (var j = 0; j < declaration.members.length; j++) {
var member = declaration.members[j];
var memberName = member.name ? member.name.getText() : null;
if (ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
) {
enqueue_black(member);
}
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (var _i = 0, _b = declaration.heritageClauses; _i < _b.length; _i++) {
var heritageClause = _b[_i];
enqueue_black(heritageClause);
}
}
}
else {
enqueue_black(declaration);
}
}
}
node.forEachChild(loop);
};
node.forEachChild(loop);
};
while (black_queue.length > 0 || gray_queue.length > 0) {
var state_1 = _loop_1();
if (state_1 === "break")
break;
}
}
function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
var declaration = symbol.declarations[i];
var declarationSourceFile = declaration.getSourceFile();
if (nodeSourceFile === declarationSourceFile) {
if (declaration.pos <= node.pos && node.end <= declaration.end) {
return true;
}
}
}
return false;
}
function generateResult(languageService, shakeLevel) {
var program = languageService.getProgram();
var result = {};
var writeFile = function (filePath, contents) {
result[filePath] = contents;
};
program.getSourceFiles().forEach(function (sourceFile) {
var fileName = sourceFile.fileName;
if (/^defaultLib:/.test(fileName)) {
return;
}
var destination = fileName;
if (/\.d\.ts$/.test(fileName)) {
if (nodeOrChildIsBlack(sourceFile)) {
writeFile(destination, sourceFile.text);
}
return;
}
var text = sourceFile.text;
var result = '';
function keep(node) {
result += text.substring(node.pos, node.end);
}
function write(data) {
result += data;
}
function writeMarkedNodes(node) {
if (getColor(node) === 2 /* Black */) {
return keep(node);
}
// Always keep certain top-level statements
if (ts.isSourceFile(node.parent)) {
if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && node.expression.text === 'use strict') {
return keep(node);
}
if (ts.isVariableStatement(node) && nodeOrChildIsBlack(node)) {
return keep(node);
}
}
// Keep the entire import in import * as X cases
if (ts.isImportDeclaration(node)) {
if (node.importClause && node.importClause.namedBindings) {
if (ts.isNamespaceImport(node.importClause.namedBindings)) {
if (getColor(node.importClause.namedBindings) === 2 /* Black */) {
return keep(node);
}
}
else {
var survivingImports = [];
for (var i = 0; i < node.importClause.namedBindings.elements.length; i++) {
var importNode = node.importClause.namedBindings.elements[i];
if (getColor(importNode) === 2 /* Black */) {
survivingImports.push(importNode.getFullText(sourceFile));
}
}
var leadingTriviaWidth = node.getLeadingTriviaWidth();
var leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
if (survivingImports.length > 0) {
if (node.importClause && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + ", {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
}
return write(leadingTrivia + "import {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
}
else {
if (node.importClause && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + " from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
}
}
}
}
else {
if (node.importClause && getColor(node.importClause) === 2 /* Black */) {
return keep(node);
}
}
}
if (shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) {
var toWrite = node.getFullText();
for (var i = node.members.length - 1; i >= 0; i--) {
var member = node.members[i];
if (getColor(member) === 2 /* Black */) {
// keep method
continue;
}
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
var pos = member.pos - node.pos;
var end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
}
return write(toWrite);
}
if (ts.isFunctionDeclaration(node)) {
// Do not go inside functions if they haven't been marked
return;
}
node.forEachChild(writeMarkedNodes);
}
if (getColor(sourceFile) !== 2 /* Black */) {
if (!nodeOrChildIsBlack(sourceFile)) {
// none of the elements are reachable => don't write this file at all!
return;
}
sourceFile.forEachChild(writeMarkedNodes);
result += sourceFile.endOfFileToken.getFullText(sourceFile);
}
else {
result = text;
}
writeFile(destination, result);
});
return result;
}
//#endregion
//#region Utils
/**
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker, node) {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node) {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getPropertySymbolsFromType(type, propName) {
function getTextOfPropertyName(name) {
function isStringOrNumericLiteral(node) {
var kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
}
}
var name = getTextOfPropertyName(propName);
if (name && type) {
var result = [];
var symbol_1 = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
var t = _a[_i];
var symbol_2 = t.getProperty(name);
if (symbol_2) {
result.push(symbol_2);
}
}
return result;
}
if (symbol_1) {
result.push(symbol_1);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker, node) {
var objectLiteral = node.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
return getPropertySymbolsFromType(contextualType, node.name);
}
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
// (2) when the aliased symbol is originating from an import.
//
function shouldSkipAlias(node, declaration) {
if (node.kind !== ts.SyntaxKind.Identifier) {
return false;
}
if (node.parent === declaration) {
return true;
}
switch (declaration.kind) {
case ts.SyntaxKind.ImportClause:
case ts.SyntaxKind.ImportEqualsDeclaration:
return true;
case ts.SyntaxKind.ImportSpecifier:
return declaration.parent.kind === ts.SyntaxKind.NamedImports;
default:
return false;
}
}
if (!ts.isShorthandPropertyAssignment(node)) {
if (node.getChildCount() !== 0) {
return [null, null];
}
}
var symbol = checker.getSymbolAtLocation(node);
var importNode = null;
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
var aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
// We should mark the import as visited
importNode = symbol.declarations[0];
symbol = aliased;
}
}
if (symbol) {
// Because name in short-hand property assignment has two different meanings: property name and property value,
// using go-to-definition at such position should go to the variable declaration of the property value rather than
// go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
// is performed at the location of property access, we would like to go to definition of the property in the short-hand
// assignment. This case and others are handled by the following code.
if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
symbol = checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
}
// If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
// declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
// and return the property declaration for the referenced property.
// For example:
// import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
//
// function bar<T>(onfulfilled: (value: T) => void) { //....}
// interface Test {
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
var type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
var propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
}
}
}
// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
// object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
// For example
// interface Props{
// /*first*/prop1: number
// prop2: boolean
// }
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
var element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent)) {
var propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
if (symbol && symbol.declarations) {
return [symbol, importNode];
}
return [null, null];
}
/** Get the token whose text contains the position */
function getTokenAtPosition(sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
var current = sourceFile;
outer: while (true) {
// find the child that contains 'position'
for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) {
var child = _a[_i];
var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
if (start > position) {
// If this child begins after position, then all subsequent children will as well.
break;
}
var end = child.getEnd();
if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) {
current = child;
continue outer;
}
}
return current;
}
}

817
build/lib/treeshaking.ts Normal file
View file

@ -0,0 +1,817 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
export const enum ShakeLevel {
Files = 0,
InnerFile = 1,
ClassMembers = 2
}
export interface ITreeShakingOptions {
/**
* The full path to the root where sources are.
*/
sourcesRoot: string;
/**
* Module ids.
* e.g. `vs/editor/editor.main` or `index`
*/
entryPoints: string[];
/**
* Inline usages.
*/
inlineEntryPoints: string[];
/**
* TypeScript libs.
* e.g. `lib.d.ts`, `lib.es2015.collection.d.ts`
*/
libs: string[];
/**
* TypeScript compiler options.
*/
compilerOptions: ts.CompilerOptions;
/**
* The shake level to perform.
*/
shakeLevel: ShakeLevel;
/**
* regex pattern to ignore certain imports e.g. `vs/css!` imports
*/
importIgnorePattern: RegExp;
redirects: { [module: string]: string; };
}
export interface ITreeShakingResult {
[file: string]: string;
}
export function shake(options: ITreeShakingOptions): ITreeShakingResult {
const languageService = createTypeScriptLanguageService(options);
markNodes(languageService, options);
return generateResult(languageService, options.shakeLevel);
}
//#region Discovery, LanguageService & Setup
function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.LanguageService {
// Discover referenced files
const FILES = discoverAndReadFiles(options);
// Add fake usage files
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
});
// Resolve libs
const RESOLVED_LIBS: ILibMap = {};
options.libs.forEach((filename) => {
const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
return ts.createLanguageService(host);
}
/**
* Read imports and follow them until all files have been handled
*/
function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
const FILES: IFileMap = {};
const in_queue: { [module: string]: boolean; } = Object.create(null);
const queue: string[] = [];
const enqueue = (moduleId: string) => {
if (in_queue[moduleId]) {
return;
}
in_queue[moduleId] = true;
queue.push(moduleId);
};
options.entryPoints.forEach((entryPoint) => enqueue(entryPoint));
while (queue.length > 0) {
const moduleId = queue.shift();
const dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
const dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
continue;
}
let ts_filename: string;
if (options.redirects[moduleId]) {
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
} else {
ts_filename = path.join(options.sourcesRoot, moduleId + '.ts');
}
const ts_filecontents = fs.readFileSync(ts_filename).toString();
const info = ts.preProcessFile(ts_filecontents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFileName = info.importedFiles[i].fileName;
if (options.importIgnorePattern.test(importedFileName)) {
// Ignore vs/css! imports
continue;
}
let importedModuleId = importedFileName;
if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) {
importedModuleId = path.join(path.dirname(moduleId), importedModuleId);
}
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
}
return FILES;
}
interface ILibMap { [libName: string]: string; }
interface IFileMap { [fileName: string]: string; }
/**
* A TypeScript language service host
*/
class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
private readonly _libs: ILibMap;
private readonly _files: IFileMap;
private readonly _compilerOptions: ts.CompilerOptions;
constructor(libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
getCompilationSettings(): ts.CompilerOptions {
return this._compilerOptions;
}
getScriptFileNames(): string[] {
return (
[]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files))
);
}
getScriptVersion(fileName: string): string {
return '1';
}
getProjectVersion(): string {
return '1';
}
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
} else if (this._libs.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
} else {
return ts.ScriptSnapshot.fromString('');
}
}
getScriptKind(fileName: string): ts.ScriptKind {
return ts.ScriptKind.TS;
}
getCurrentDirectory(): string {
return '';
}
getDefaultLibFileName(options: ts.CompilerOptions): string {
return 'defaultLib:lib.d.ts';
}
isDefaultLibFileName(fileName: string): boolean {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
}
}
//#endregion
//#region Tree Shaking
const enum NodeColor {
White = 0,
Gray = 1,
Black = 2
}
function getColor(node: ts.Node): NodeColor {
return (<any>node).$$$color || NodeColor.White;
}
function setColor(node: ts.Node, color: NodeColor): void {
(<any>node).$$$color = color;
}
function nodeOrParentIsBlack(node: ts.Node): boolean {
while (node) {
const color = getColor(node);
if (color === NodeColor.Black) {
return true;
}
node = node.parent;
}
return false;
}
function nodeOrChildIsBlack(node: ts.Node): boolean {
if (getColor(node) === NodeColor.Black) {
return true;
}
for (const child of node.getChildren()) {
if (nodeOrChildIsBlack(child)) {
return true;
}
}
return false;
}
function markNodes(languageService: ts.LanguageService, options: ITreeShakingOptions) {
const program = languageService.getProgram();
if (options.shakeLevel === ShakeLevel.Files) {
// Mark all source files Black
program.getSourceFiles().forEach((sourceFile) => {
setColor(sourceFile, NodeColor.Black);
});
return;
}
const black_queue: ts.Node[] = [];
const gray_queue: ts.Node[] = [];
const sourceFilesLoaded: { [fileName: string]: boolean } = {};
function enqueueTopLevelModuleStatements(sourceFile: ts.SourceFile): void {
sourceFile.forEachChild((node: ts.Node) => {
if (ts.isImportDeclaration(node)) {
if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, NodeColor.Black);
enqueueImport(node, node.moduleSpecifier.text);
}
return;
}
if (ts.isExportDeclaration(node)) {
if (ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, NodeColor.Black);
enqueueImport(node, node.moduleSpecifier.text);
}
return;
}
if (
ts.isExpressionStatement(node)
|| ts.isIfStatement(node)
|| ts.isIterationStatement(node, true)
|| ts.isExportAssignment(node)
) {
enqueue_black(node);
}
if (ts.isImportEqualsDeclaration(node)) {
if (/export/.test(node.getFullText(sourceFile))) {
// e.g. "export import Severity = BaseSeverity;"
enqueue_black(node);
}
}
});
}
function enqueue_gray(node: ts.Node): void {
if (nodeOrParentIsBlack(node) || getColor(node) === NodeColor.Gray) {
return;
}
setColor(node, NodeColor.Gray);
gray_queue.push(node);
}
function enqueue_black(node: ts.Node): void {
const previousColor = getColor(node);
if (previousColor === NodeColor.Black) {
return;
}
if (previousColor === NodeColor.Gray) {
// remove from gray queue
gray_queue.splice(gray_queue.indexOf(node), 1);
setColor(node, NodeColor.White);
// add to black queue
enqueue_black(node);
// // move from one queue to the other
// black_queue.push(node);
// setColor(node, NodeColor.Black);
return;
}
if (nodeOrParentIsBlack(node)) {
return;
}
const fileName = node.getSourceFile().fileName;
if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) {
setColor(node, NodeColor.Black);
return;
}
const sourceFile = node.getSourceFile();
if (!sourceFilesLoaded[sourceFile.fileName]) {
sourceFilesLoaded[sourceFile.fileName] = true;
enqueueTopLevelModuleStatements(sourceFile);
}
if (ts.isSourceFile(node)) {
return;
}
setColor(node, NodeColor.Black);
black_queue.push(node);
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) {
const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
if (references) {
for (let i = 0, len = references.length; i < len; i++) {
const reference = references[i];
const referenceSourceFile = program.getSourceFile(reference.fileName);
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
if (
ts.isMethodDeclaration(referenceNode.parent)
|| ts.isPropertyDeclaration(referenceNode.parent)
|| ts.isGetAccessor(referenceNode.parent)
|| ts.isSetAccessor(referenceNode.parent)
) {
enqueue_gray(referenceNode.parent);
}
}
}
}
}
function enqueueFile(filename: string): void {
const sourceFile = program.getSourceFile(filename);
if (!sourceFile) {
console.warn(`Cannot find source file ${filename}`);
return;
}
enqueue_black(sourceFile);
}
function enqueueImport(node: ts.Node, importText: string): void {
if (options.importIgnorePattern.test(importText)) {
// this import should be ignored
return;
}
const nodeSourceFile = node.getSourceFile();
let fullPath: string;
if (/(^\.\/)|(^\.\.\/)/.test(importText)) {
fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts';
} else {
fullPath = importText + '.ts';
}
enqueueFile(fullPath);
}
options.entryPoints.forEach(moduleId => enqueueFile(moduleId + '.ts'));
// Add fake usage files
options.inlineEntryPoints.forEach((_, index) => enqueueFile(`inlineEntryPoint:${index}.ts`));
let step = 0;
const checker = program.getTypeChecker();
while (black_queue.length > 0 || gray_queue.length > 0) {
++step;
let node: ts.Node;
if (step % 100 === 0) {
console.log(`${step}/${step+black_queue.length+gray_queue.length} (${black_queue.length}, ${gray_queue.length})`);
}
if (black_queue.length === 0) {
for (let i = 0; i < gray_queue.length; i++) {
const node = gray_queue[i];
const nodeParent = node.parent;
if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) {
gray_queue.splice(i, 1);
black_queue.push(node);
setColor(node, NodeColor.Black);
i--;
}
}
}
if (black_queue.length > 0) {
node = black_queue.shift();
} else {
// only gray nodes remaining...
break;
}
const nodeSourceFile = node.getSourceFile();
const loop = (node: ts.Node) => {
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
if (symbolImportNode) {
setColor(symbolImportNode, NodeColor.Black);
}
if (symbol && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
}
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) {
enqueue_black(declaration.name);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (
ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose'// TODO: keeping all `dispose` methods
) {
enqueue_black(member);
}
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (let heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
}
} else {
enqueue_black(declaration);
}
}
}
node.forEachChild(loop);
};
node.forEachChild(loop);
}
}
function nodeIsInItsOwnDeclaration(nodeSourceFile: ts.SourceFile, node: ts.Node, symbol: ts.Symbol): boolean {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
const declarationSourceFile = declaration.getSourceFile();
if (nodeSourceFile === declarationSourceFile) {
if (declaration.pos <= node.pos && node.end <= declaration.end) {
return true;
}
}
}
return false;
}
function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult {
const program = languageService.getProgram();
let result: ITreeShakingResult = {};
const writeFile = (filePath: string, contents: string): void => {
result[filePath] = contents;
};
program.getSourceFiles().forEach((sourceFile) => {
const fileName = sourceFile.fileName;
if (/^defaultLib:/.test(fileName)) {
return;
}
const destination = fileName;
if (/\.d\.ts$/.test(fileName)) {
if (nodeOrChildIsBlack(sourceFile)) {
writeFile(destination, sourceFile.text);
}
return;
}
let text = sourceFile.text;
let result = '';
function keep(node: ts.Node): void {
result += text.substring(node.pos, node.end);
}
function write(data: string): void {
result += data;
}
function writeMarkedNodes(node: ts.Node): void {
if (getColor(node) === NodeColor.Black) {
return keep(node);
}
// Always keep certain top-level statements
if (ts.isSourceFile(node.parent)) {
if (ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression) && node.expression.text === 'use strict') {
return keep(node);
}
if (ts.isVariableStatement(node) && nodeOrChildIsBlack(node)) {
return keep(node);
}
}
// Keep the entire import in import * as X cases
if (ts.isImportDeclaration(node)) {
if (node.importClause && node.importClause.namedBindings) {
if (ts.isNamespaceImport(node.importClause.namedBindings)) {
if (getColor(node.importClause.namedBindings) === NodeColor.Black) {
return keep(node);
}
} else {
let survivingImports: string[] = [];
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
const importNode = node.importClause.namedBindings.elements[i];
if (getColor(importNode) === NodeColor.Black) {
survivingImports.push(importNode.getFullText(sourceFile));
}
}
const leadingTriviaWidth = node.getLeadingTriviaWidth();
const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
if (survivingImports.length > 0) {
if (node.importClause && getColor(node.importClause) === NodeColor.Black) {
return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
} else {
if (node.importClause && getColor(node.importClause) === NodeColor.Black) {
return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
}
}
} else {
if (node.importClause && getColor(node.importClause) === NodeColor.Black) {
return keep(node);
}
}
}
if (shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) {
let toWrite = node.getFullText();
for (let i = node.members.length - 1; i >= 0; i--) {
const member = node.members[i];
if (getColor(member) === NodeColor.Black) {
// keep method
continue;
}
if (/^_(.*)Brand$/.test(member.name.getText())) {
// TODO: keep all members ending with `Brand`...
continue;
}
let pos = member.pos - node.pos;
let end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
}
return write(toWrite);
}
if (ts.isFunctionDeclaration(node)) {
// Do not go inside functions if they haven't been marked
return;
}
node.forEachChild(writeMarkedNodes);
}
if (getColor(sourceFile) !== NodeColor.Black) {
if (!nodeOrChildIsBlack(sourceFile)) {
// none of the elements are reachable => don't write this file at all!
return;
}
sourceFile.forEachChild(writeMarkedNodes);
result += sourceFile.endOfFileToken.getFullText(sourceFile);
} else {
result = text;
}
writeFile(destination, result);
});
return result;
}
//#endregion
//#region Utils
/**
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol, ts.Declaration] {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node: ts.Node): ts.ObjectLiteralElement | undefined {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getPropertySymbolsFromType(type: ts.Type, propName: ts.PropertyName) {
function getTextOfPropertyName(name: ts.PropertyName): string {
function isStringOrNumericLiteral(node: ts.Node): node is ts.StringLiteral | ts.NumericLiteral {
const kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined!;
}
}
const name = getTextOfPropertyName(propName);
if (name && type) {
const result: ts.Symbol[] = [];
const symbol = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (const t of (<ts.UnionType>type).types) {
const symbol = t.getProperty(name);
if (symbol) {
result.push(symbol);
}
}
return result;
}
if (symbol) {
result.push(symbol);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker: ts.TypeChecker, node: ts.ObjectLiteralElement): ts.Symbol[] {
const objectLiteral = <ts.ObjectLiteralExpression | ts.JsxAttributes>node.parent;
const contextualType = typeChecker.getContextualType(objectLiteral)!;
return getPropertySymbolsFromType(contextualType, node.name!)!;
}
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
// (2) when the aliased symbol is originating from an import.
//
function shouldSkipAlias(node: ts.Node, declaration: ts.Node): boolean {
if (node.kind !== ts.SyntaxKind.Identifier) {
return false;
}
if (node.parent === declaration) {
return true;
}
switch (declaration.kind) {
case ts.SyntaxKind.ImportClause:
case ts.SyntaxKind.ImportEqualsDeclaration:
return true;
case ts.SyntaxKind.ImportSpecifier:
return declaration.parent.kind === ts.SyntaxKind.NamedImports;
default:
return false;
}
}
if (!ts.isShorthandPropertyAssignment(node)) {
if (node.getChildCount() !== 0) {
return [null, null];
}
}
let symbol = checker.getSymbolAtLocation(node);
let importNode: ts.Declaration = null;
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
// We should mark the import as visited
importNode = symbol.declarations[0];
symbol = aliased;
}
}
if (symbol) {
// Because name in short-hand property assignment has two different meanings: property name and property value,
// using go-to-definition at such position should go to the variable declaration of the property value rather than
// go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
// is performed at the location of property access, we would like to go to definition of the property in the short-hand
// assignment. This case and others are handled by the following code.
if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
symbol = checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
}
// If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
// declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
// and return the property declaration for the referenced property.
// For example:
// import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
//
// function bar<T>(onfulfilled: (value: T) => void) { //....}
// interface Test {
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
const type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
const propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
}
}
}
// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
// object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
// For example
// interface Props{
// /*first*/prop1: number
// prop2: boolean
// }
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
const element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent as ts.Expression)) {
const propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
if (symbol && symbol.declarations) {
return [symbol, importNode];
}
return [null, null];
}
/** Get the token whose text contains the position */
function getTokenAtPosition(sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeEndPosition: boolean): ts.Node {
let current: ts.Node = sourceFile;
outer: while (true) {
// find the child that contains 'position'
for (const child of current.getChildren()) {
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
if (start > position) {
// If this child begins after position, then all subsequent children will as well.
break;
}
const end = child.getEnd();
if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) {
current = child;
continue outer;
}
}
return current;
}
}
//#endregion

View file

@ -134,7 +134,25 @@ function getTopLevelDeclaration(sourceFile, typeName) {
function getNodeText(sourceFile, node) {
return sourceFile.getFullText().substring(node.pos, node.end);
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
function hasModifier(modifiers, kind) {
if (modifiers) {
for (var i = 0; i < modifiers.length; i++) {
var mod = modifiers[i];
if (mod.kind === kind) {
return true;
}
}
}
return false;
}
function isStatic(member) {
return hasModifier(member.modifiers, ts.SyntaxKind.StaticKeyword);
}
function isDefaultExport(declaration) {
return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage) {
var result = getNodeText(sourceFile, declaration);
// if (result.indexOf('MonacoWorker') >= 0) {
// console.log('here!');
@ -142,6 +160,18 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
// }
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
var interfaceDeclaration = declaration;
var staticTypeName_1 = (isDefaultExport(interfaceDeclaration)
? importName + ".default"
: importName + "." + declaration.name.text);
var instanceTypeName_1 = staticTypeName_1;
var typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
if (typeParametersCnt > 0) {
var arr = [];
for (var i = 0; i < typeParametersCnt; i++) {
arr.push('any');
}
instanceTypeName_1 = instanceTypeName_1 + "<" + arr.join(',') + ">";
}
var members = interfaceDeclaration.members;
members.forEach(function (member) {
try {
@ -151,6 +181,15 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration) {
result = result.replace(memberText, '');
// console.log('AFTER: ', result);
}
else {
var memberName = member.name.text;
if (isStatic(member)) {
usage.push("a = " + staticTypeName_1 + "." + memberName + ";");
}
else {
usage.push("a = (<" + instanceTypeName_1 + ">b)." + memberName + ";");
}
}
}
catch (err) {
// life..
@ -211,6 +250,16 @@ function generateDeclarationFile(out, inputFiles, recipe) {
var endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
var lines = recipe.split(endl);
var result = [];
var usageCounter = 0;
var usageImports = [];
var usage = [];
usage.push("var a;");
usage.push("var b;");
var generateUsageImport = function (moduleId) {
var importName = 'm' + (++usageCounter);
usageImports.push("import * as " + importName + " from '" + moduleId.replace(/\.d\.ts$/, '') + "';");
return importName;
};
lines.forEach(function (line) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
@ -220,6 +269,7 @@ function generateDeclarationFile(out, inputFiles, recipe) {
if (!sourceFile_1) {
return;
}
var importName_1 = generateUsageImport(moduleId);
var replacer_1 = createReplacer(m1[2]);
var typeNames = m1[3].split(/,/);
typeNames.forEach(function (typeName) {
@ -232,7 +282,7 @@ function generateDeclarationFile(out, inputFiles, recipe) {
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration)));
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration, importName_1, usage)));
});
return;
}
@ -244,6 +294,7 @@ function generateDeclarationFile(out, inputFiles, recipe) {
if (!sourceFile_2) {
return;
}
var importName_2 = generateUsageImport(moduleId);
var replacer_2 = createReplacer(m2[2]);
var typeNames = m2[3].split(/,/);
var typesToExcludeMap_1 = {};
@ -271,7 +322,7 @@ function generateDeclarationFile(out, inputFiles, recipe) {
}
}
}
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration)));
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration, importName_2, usage)));
});
return;
}
@ -282,9 +333,12 @@ function generateDeclarationFile(out, inputFiles, recipe) {
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
resultTxt = format(resultTxt);
return resultTxt;
return [
resultTxt,
usageImports.join('\n') + "\n\n" + usage.join('\n')
];
}
function getFilesToWatch(out) {
function getIncludesInRecipe() {
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var lines = recipe.split(/\r\n|\n|\r/);
var result = [];
@ -292,24 +346,27 @@ function getFilesToWatch(out) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
var moduleId = m1[1];
result.push(moduleIdToPath(out, moduleId));
result.push(moduleId);
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
var moduleId = m2[1];
result.push(moduleIdToPath(out, moduleId));
result.push(moduleId);
return;
}
});
return result;
}
function getFilesToWatch(out) {
return getIncludesInRecipe().map(function (moduleId) { return moduleIdToPath(out, moduleId); });
}
exports.getFilesToWatch = getFilesToWatch;
function run(out, inputFiles) {
log('Starting monaco.d.ts generation');
SOURCE_FILE_MAP = {};
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var result = generateDeclarationFile(out, inputFiles, recipe);
var _a = generateDeclarationFile(out, inputFiles, recipe), result = _a[0], usageContent = _a[1];
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
var one = currentContent.replace(/\r\n/gm, '\n');
@ -317,6 +374,7 @@ function run(out, inputFiles) {
var isTheSame = one === other;
return {
content: result,
usageContent: usageContent,
filePath: DECLARATION_PATH,
isTheSame: isTheSame
};
@ -326,3 +384,78 @@ function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
exports.complainErrors = complainErrors;
var TypeScriptLanguageServiceHost = /** @class */ (function () {
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
else if (this._libs.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
}
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (options) {
return 'defaultLib:es5';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
};
return TypeScriptLanguageServiceHost;
}());
function execute() {
var OUTPUT_FILES = {};
var SRC_FILES = {};
var SRC_FILE_TO_EXPECTED_NAME = {};
getIncludesInRecipe().forEach(function (moduleId) {
if (/\.d\.ts$/.test(moduleId)) {
var fileName_1 = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName_1).toString();
return;
}
var fileName = path.join(SRC, moduleId) + '.ts';
SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
});
var languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
var t1 = Date.now();
Object.keys(SRC_FILES).forEach(function (fileName) {
var t = Date.now();
var emitOutput = languageService.getEmitOutput(fileName, true);
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
// console.log(`Generating .d.ts for ${fileName} took ${Date.now() - t} ms`);
});
console.log("Generating .d.ts took " + (Date.now() - t1) + " ms");
// console.log(result.filePath);
// fs.writeFileSync(result.filePath, result.content.replace(/\r\n/gm, '\n'));
// fs.writeFileSync(path.join(SRC, 'user.ts'), result.usageContent.replace(/\r\n/gm, '\n'));
return run('src', OUTPUT_FILES);
}
exports.execute = execute;

View file

@ -153,8 +153,30 @@ function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number
return sourceFile.getFullText().substring(node.pos, node.end);
}
function hasModifier(modifiers: ts.NodeArray<ts.Modifier>, kind: ts.SyntaxKind): boolean {
if (modifiers) {
for (let i = 0; i < modifiers.length; i++) {
let mod = modifiers[i];
if (mod.kind === kind) {
return true;
}
}
}
return false;
}
function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare): string {
function isStatic(member: ts.ClassElement | ts.TypeElement): boolean {
return hasModifier(member.modifiers, ts.SyntaxKind.StaticKeyword);
}
function isDefaultExport(declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean {
return (
hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword)
);
}
function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[]): string {
let result = getNodeText(sourceFile, declaration);
// if (result.indexOf('MonacoWorker') >= 0) {
// console.log('here!');
@ -163,7 +185,23 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
let interfaceDeclaration = <ts.InterfaceDeclaration | ts.ClassDeclaration>declaration;
let members: ts.NodeArray<ts.Node> = interfaceDeclaration.members;
const staticTypeName = (
isDefaultExport(interfaceDeclaration)
? `${importName}.default`
: `${importName}.${declaration.name.text}`
);
let instanceTypeName = staticTypeName;
const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
if (typeParametersCnt > 0) {
let arr: string[] = [];
for (let i = 0; i < typeParametersCnt; i++) {
arr.push('any');
}
instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`;
}
const members: ts.NodeArray<ts.ClassElement | ts.TypeElement> = interfaceDeclaration.members;
members.forEach((member) => {
try {
let memberText = getNodeText(sourceFile, member);
@ -171,6 +209,13 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
// console.log('BEFORE: ', result);
result = result.replace(memberText, '');
// console.log('AFTER: ', result);
} else {
const memberName = (<ts.Identifier | ts.StringLiteral>member.name).text;
if (isStatic(member)) {
usage.push(`a = ${staticTypeName}.${memberName};`);
} else {
usage.push(`a = (<${instanceTypeName}>b).${memberName};`);
}
}
} catch (err) {
// life..
@ -237,11 +282,24 @@ function createReplacer(data: string): (str: string) => string {
};
}
function generateDeclarationFile(out: string, inputFiles: { [file: string]: string; }, recipe: string): string {
function generateDeclarationFile(out: string, inputFiles: { [file: string]: string; }, recipe: string): [string, string] {
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
let lines = recipe.split(endl);
let result = [];
let result: string[] = [];
let usageCounter = 0;
let usageImports: string[] = [];
let usage: string[] = [];
usage.push(`var a;`);
usage.push(`var b;`);
const generateUsageImport = (moduleId: string) => {
let importName = 'm' + (++usageCounter);
usageImports.push(`import * as ${importName} from '${moduleId.replace(/\.d\.ts$/, '')}';`);
return importName;
};
lines.forEach(line => {
@ -254,6 +312,8 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
return;
}
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m1[2]);
let typeNames = m1[3].split(/,/);
@ -267,7 +327,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
});
return;
}
@ -281,6 +341,8 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
return;
}
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m2[2]);
let typeNames = m2[3].split(/,/);
@ -309,7 +371,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
}
}
}
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
});
return;
}
@ -324,10 +386,13 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
resultTxt = format(resultTxt);
return resultTxt;
return [
resultTxt,
`${usageImports.join('\n')}\n\n${usage.join('\n')}`
];
}
export function getFilesToWatch(out: string): string[] {
function getIncludesInRecipe(): string[] {
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let lines = recipe.split(/\r\n|\n|\r/);
let result = [];
@ -337,14 +402,14 @@ export function getFilesToWatch(out: string): string[] {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
let moduleId = m1[1];
result.push(moduleIdToPath(out, moduleId));
result.push(moduleId);
return;
}
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
let moduleId = m2[1];
result.push(moduleIdToPath(out, moduleId));
result.push(moduleId);
return;
}
});
@ -352,8 +417,13 @@ export function getFilesToWatch(out: string): string[] {
return result;
}
export function getFilesToWatch(out: string): string[] {
return getIncludesInRecipe().map((moduleId) => moduleIdToPath(out, moduleId));
}
export interface IMonacoDeclarationResult {
content: string;
usageContent: string;
filePath: string;
isTheSame: boolean;
}
@ -363,7 +433,7 @@ export function run(out: string, inputFiles: { [file: string]: string; }): IMona
SOURCE_FILE_MAP = {};
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let result = generateDeclarationFile(out, inputFiles, recipe);
let [result, usageContent] = generateDeclarationFile(out, inputFiles, recipe);
let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
@ -374,6 +444,7 @@ export function run(out: string, inputFiles: { [file: string]: string; }): IMona
return {
content: result,
usageContent: usageContent,
filePath: DECLARATION_PATH,
isTheSame
};
@ -382,3 +453,96 @@ export function run(out: string, inputFiles: { [file: string]: string; }): IMona
export function complainErrors() {
logErr('Not running monaco.d.ts generation due to compile errors');
}
interface ILibMap { [libName: string]: string; }
interface IFileMap { [fileName: string]: string; }
class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
private readonly _libs: ILibMap;
private readonly _files: IFileMap;
private readonly _compilerOptions: ts.CompilerOptions;
constructor(libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
getCompilationSettings(): ts.CompilerOptions {
return this._compilerOptions;
}
getScriptFileNames(): string[] {
return (
[]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files))
);
}
getScriptVersion(fileName: string): string {
return '1';
}
getProjectVersion(): string {
return '1';
}
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
} else if (this._libs.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
} else {
return ts.ScriptSnapshot.fromString('');
}
}
getScriptKind(fileName: string): ts.ScriptKind {
return ts.ScriptKind.TS;
}
getCurrentDirectory(): string {
return '';
}
getDefaultLibFileName(options: ts.CompilerOptions): string {
return 'defaultLib:es5';
}
isDefaultLibFileName(fileName: string): boolean {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
}
}
export function execute(): IMonacoDeclarationResult {
const OUTPUT_FILES: { [file: string]: string; } = {};
const SRC_FILES: IFileMap = {};
const SRC_FILE_TO_EXPECTED_NAME: { [filename: string]: string; } = {};
getIncludesInRecipe().forEach((moduleId) => {
if (/\.d\.ts$/.test(moduleId)) {
let fileName = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
return;
}
let fileName = path.join(SRC, moduleId) + '.ts';
SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
});
const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
var t1 = Date.now();
Object.keys(SRC_FILES).forEach((fileName) => {
var t = Date.now();
const emitOutput = languageService.getEmitOutput(fileName, true);
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
// console.log(`Generating .d.ts for ${fileName} took ${Date.now() - t} ms`);
});
console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
// console.log(result.filePath);
// fs.writeFileSync(result.filePath, result.content.replace(/\r\n/gm, '\n'));
// fs.writeFileSync(path.join(SRC, 'user.ts'), result.usageContent.replace(/\r\n/gm, '\n'));
return run('src', OUTPUT_FILES);
}

View file

@ -0,0 +1,82 @@
// This file is adding references to various symbols which should not be removed via tree shaking
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IHighlight } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from 'vs/base/common/worker/simpleWorker';
import { create as create2 } from 'vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from 'vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from 'vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from 'vs/editor/browser/widget/diffNavigator';
import * as editorAPI from 'vs/editor/editor.api';
(function () {
var a: any;
var b: any;
a = (<IContextViewService>b).layout; // IContextViewProvider
a = (<IWorkspaceContextService>b).getWorkspaceFolder; // IWorkspaceFolderProvider
a = (<IWorkspaceContextService>b).getWorkspace; // IWorkspaceFolderProvider
a = (<CountBadge>b).style; // IThemable
a = (<QuickOpenWidget>b).style; // IThemable
a = (<IEnvironmentService>b).userHome; // IUserHomeProvider
a = (<DiffNavigator>b).previous; // IDiffNavigator
a = (<ServiceIdentifier<any>>b).type;
a = (<IHighlight>b).start;
a = (<IHighlight>b).end;
a = (<SimpleWorkerClient<any>>b).getProxyObject; // IWorkerClient
a = create1;
a = create2;
// promise polyfill
a = PolyfillPromise.all;
a = PolyfillPromise.race;
a = PolyfillPromise.resolve;
a = PolyfillPromise.reject;
a = (<PolyfillPromise>b).then;
a = (<PolyfillPromise>b).catch;
// injection madness
a = (<SyncDescriptor0<any>>b).ctor;
a = (<SyncDescriptor0<any>>b).bind;
a = (<SyncDescriptor1<any, any>>b).ctor;
a = (<SyncDescriptor1<any, any>>b).bind;
a = (<SyncDescriptor1<any, any>>b).ctor;
a = (<SyncDescriptor1<any, any>>b).bind;
a = (<SyncDescriptor2<any, any, any>>b).ctor;
a = (<SyncDescriptor2<any, any, any>>b).bind;
a = (<SyncDescriptor3<any, any, any, any>>b).ctor;
a = (<SyncDescriptor3<any, any, any, any>>b).bind;
a = (<SyncDescriptor4<any, any, any, any, any>>b).ctor;
a = (<SyncDescriptor4<any, any, any, any, any>>b).bind;
a = (<SyncDescriptor5<any, any, any, any, any, any>>b).ctor;
a = (<SyncDescriptor5<any, any, any, any, any, any>>b).bind;
a = (<SyncDescriptor6<any, any, any, any, any, any, any>>b).ctor;
a = (<SyncDescriptor6<any, any, any, any, any, any, any>>b).bind;
a = (<SyncDescriptor7<any, any, any, any, any, any, any, any>>b).ctor;
a = (<SyncDescriptor7<any, any, any, any, any, any, any, any>>b).bind;
a = (<SyncDescriptor8<any, any, any, any, any, any, any, any, any>>b).ctor;
a = (<SyncDescriptor8<any, any, any, any, any, any, any, any, any>>b).bind;
// exported API
a = editorAPI.CancellationTokenSource;
a = editorAPI.Emitter;
a = editorAPI.KeyCode;
a = editorAPI.KeyMod;
a = editorAPI.Position;
a = editorAPI.Range;
a = editorAPI.Selection;
a = editorAPI.SelectionDirection;
a = editorAPI.Severity;
a = editorAPI.MarkerSeverity;
a = editorAPI.MarkerTag;
a = editorAPI.Promise;
a = editorAPI.Uri;
a = editorAPI.Token;
a = editorAPI.editor;
a = editorAPI.languages;
})();

View file

@ -25,10 +25,10 @@
"command.decrementNumberByTen": "Decrement by 10",
"emmetSyntaxProfiles": "Define profile for specified syntax or use your own profile with specific rules.",
"emmetExclude": "An array of languages where Emmet abbreviations should not be expanded.",
"emmetExtensionsPath": "Path to a folder containing Emmet profiles and snippets.'",
"emmetShowExpandedAbbreviation": "Shows expanded Emmet abbreviations as suggestions.\nThe option \"inMarkupAndStylesheetFilesOnly\" applies to html, haml, jade, slim, xml, xsl, css, scss, sass, less and stylus.\nThe option \"always\" applies to all parts of the file regardless of markup/css.",
"emmetShowAbbreviationSuggestions": "Shows possible Emmet abbreviations as suggestions. Not applicable in stylesheets or when emmet.showExpandedAbbreviation is set to \"never\".",
"emmetIncludeLanguages": "Enable Emmet abbreviations in languages that are not supported by default. Add a mapping here between the language and emmet supported language.\n E.g.: {\"vue-html\": \"html\", \"javascript\": \"javascriptreact\"}",
"emmetExtensionsPath": "Path to a folder containing Emmet profiles and snippets.",
"emmetShowExpandedAbbreviation": "Shows expanded Emmet abbreviations as suggestions.\nThe option `\"inMarkupAndStylesheetFilesOnly\"` applies to html, haml, jade, slim, xml, xsl, css, scss, sass, less and stylus.\nThe option `\"always\"` applies to all parts of the file regardless of markup/css.",
"emmetShowAbbreviationSuggestions": "Shows possible Emmet abbreviations as suggestions. Not applicable in stylesheets or when emmet.showExpandedAbbreviation is set to `\"never\"`.",
"emmetIncludeLanguages": "Enable Emmet abbreviations in languages that are not supported by default. Add a mapping here between the language and emmet supported language.\n E.g.: `{\"vue-html\": \"html\", \"javascript\": \"javascriptreact\"}`",
"emmetVariables": "Variables to be used in Emmet snippets",
"emmetTriggerExpansionOnTab": "When enabled, Emmet abbreviations are expanded when pressing TAB.",
"emmetPreferences": "Preferences used to modify behavior of some actions and resolvers of Emmet.",
@ -40,7 +40,7 @@
"emmetPreferencesCssBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations",
"emmetPreferencesSassBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations in Sass files",
"emmetPreferencesStylusBetween": "Symbol to be placed at the between CSS property and value when expanding CSS abbreviations in Stylus files",
"emmetShowSuggestionsAsSnippets": "If true, then Emmet suggestions will show up as snippets allowing you to order them as per editor.snippetSuggestions setting.",
"emmetShowSuggestionsAsSnippets": "If `true`, then Emmet suggestions will show up as snippets allowing you to order them as per `#editor.snippetSuggestions#` setting.",
"emmetPreferencesBemElementSeparator": "Element separator used for classes when using the BEM filter",
"emmetPreferencesBemModifierSeparator": "Modifier separator used for classes when using the BEM filter",
"emmetPreferencesFilterCommentBefore": "A definition of comment that should be placed before matched element when comment filter is applied.",
@ -54,5 +54,5 @@
"emmetPreferencesCssOProperties": "Comma separated CSS properties that get the 'o' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'o' prefix.",
"emmetPreferencesCssMsProperties": "Comma separated CSS properties that get the 'ms' vendor prefix when used in Emmet abbreviation that starts with `-`. Set to empty string to always avoid the 'ms' prefix.",
"emmetPreferencesCssFuzzySearchMinScore": "The minimum score (from 0 to 1) that fuzzy-matched abbreviation should achieve. Lower values may produce many false-positive matches, higher values may reduce possible matches.",
"emmetOptimizeStylesheetParsing": "When set to false, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to true, only the content around the current position in css/scss/less files is parsed."
"emmetOptimizeStylesheetParsing": "When set to `false`, the whole file is parsed to determine if current position is valid for expanding Emmet abbreviations. When set to `true`, only the content around the current position in css/scss/less files is parsed."
}

View file

@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as path from 'path';
import * as nls from 'vscode-nls';
@ -265,12 +264,12 @@ export class ExtensionLinter {
private async loadPackageJson(folder: Uri) {
const file = folder.with({ path: path.posix.join(folder.path, 'package.json') });
const exists = await fileExists(file.fsPath);
if (!exists) {
try {
const document = await workspace.openTextDocument(file);
return parseTree(document.getText());
} catch (err) {
return undefined;
}
const document = await workspace.openTextDocument(file);
return parseTree(document.getText());
}
private packageJsonChanged(folder: Uri) {
@ -338,20 +337,6 @@ function endsWith(haystack: string, needle: string): boolean {
}
}
function fileExists(path: string): Promise<boolean> {
return new Promise((resolve, reject) => {
fs.lstat(path, (err, stats) => {
if (!err) {
resolve(true);
} else if (err.code === 'ENOENT') {
resolve(false);
} else {
reject(err);
}
});
});
}
function parseUri(src: string) {
try {
return Uri.parse(src);

View file

@ -4,19 +4,19 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/ionide/ionide-fsgrammar/commit/bd8d1225f93894a50bc8da6f5a76409b024d3d22",
"version": "https://github.com/ionide/ionide-fsgrammar/commit/67c9f45ebbbd5a12d89ffad1661caf8452f1d552",
"name": "fsharp",
"scopeName": "source.fsharp",
"patterns": [
{
"include": "#compiler_directives"
},
{
"include": "#comments"
},
{
"include": "#constants"
},
{
"include": "#structure"
},
{
"include": "#strings"
},
@ -30,10 +30,10 @@
"include": "#definition"
},
{
"include": "#attributes"
"include": "#abstract_definition"
},
{
"include": "#method_calls"
"include": "#attributes"
},
{
"include": "#modules"
@ -44,6 +44,9 @@
{
"include": "#du_declaration"
},
{
"include": "#record_declaration"
},
{
"include": "#keywords"
},
@ -58,6 +61,96 @@
}
],
"repository": {
"generic_declaration": {
"patterns": [
{
"match": "([^<>,])",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"begin": "(<)",
"end": "(>)",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "([^<>,])",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#generic_declaration"
}
]
},
{
"include": "#keywords"
}
]
},
"record_signature": {
"patterns": [
{
"match": "[[:alpha:]0-9'`^_ ]+(=)([[:alpha:]0-9'`^_ ]+)",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "variable.parameter.fsharp"
}
}
},
{
"begin": "({)",
"end": "(})",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "[[:alpha:]0-9'`^_ ]+(=)([[:alpha:]0-9'`^_ ]+)",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "variable.parameter.fsharp"
}
}
},
{
"include": "#record_signature"
}
]
},
{
"include": "#keywords"
}
]
},
"anonymous_functions": {
"patterns": [
{
@ -66,15 +159,32 @@
"end": "(->)",
"beginCaptures": {
"1": {
"name": "keyword.other.function-definition.fsharp"
"name": "keyword.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
}
},
"patterns": [
{
"include": "#comments"
},
{
"include": "#member_declaration"
},
{
"match": "(:)(\\s*([?[:alpha:]0-9'`<>^._ ]+))*",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#variables"
}
@ -87,7 +197,7 @@
{
"name": "support.function.attribute.fsharp",
"begin": "\\[\\<",
"end": "\\>\\]",
"end": "\\>\\]|\\]",
"patterns": [
{
"include": "$self"
@ -178,57 +288,189 @@
}
]
},
"abstract_definition": {
"name": "abstract.definition.fsharp",
"begin": "\\b(abstract)\\s+(member)?(\\s+\\[\\<.*\\>\\])?\\s*([_[:alpha:]0-9,\\._`\\s]+)(:)",
"end": "\\s*(with)\\b|=|$",
"beginCaptures": {
"1": {
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.fsharp"
},
"3": {
"name": "support.function.attribute.fsharp"
},
"5": {
"name": "keyword.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.fsharp"
}
},
"patterns": [
{
"include": "#comments"
},
{
"include": "#common_declaration"
},
{
"match": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)){0,1}",
"captures": {
"1": {
"name": "variable.parameter.fsharp"
},
"2": {
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
}
}
},
{
"match": "(?!with|get|set\\b)\\b([\\w0-9'`^._]+)",
"comments": "Here we need the \\w modifier in order to check that the words isn't blacklisted",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#keywords"
}
]
},
"definition": {
"patterns": [
{
"name": "binding.fsharp",
"begin": "\\b(val mutable|val|let mutable|let inline|let|member|static member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]|(?<=,)\\s)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]|(?<=,)\\s)*)?",
"end": "((``.*``)|(with)\\b|=|$)",
"begin": "\\b(val mutable|val|let mutable|let inline|let|member val|member|static member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
"end": "\\s*(with\\b|=|\\n+=)",
"beginCaptures": {
"1": {
"name": "keyword.other.binding.fsharp"
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.other.function-recursive.fsharp"
"name": "keyword.fsharp"
},
"3": {
"name": "support.function.attribute.fsharp"
},
"4": {
"name": "keyword.other.access.fsharp"
"name": "keyword.fsharp"
},
"5": {
"name": "variable.other.binding.fsharp"
"name": "variable.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.other.fsharp"
},
"2": {
"name": "variable.other.binding.fsharp"
},
"3": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
}
},
"patterns": [
{
"include": "#variables"
"include": "#comments"
},
{
"include": "#member_declaration"
},
{
"match": "(:)(\\s*([?[:alpha:]0-9'<>^._ ]+))*",
"match": "(:)\\s*(\\()?\\s*(([?[:alpha:]0-9'`^._ ]+))*",
"captures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
}
}
},
{
"match": "(\\*\\s*\\()\\s*(([?[:alpha:]0-9'`^._ ]+))*",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "entity.name.type.fsharp"
}
}
},
{
"match": "(->)\\s*(\\()?\\s*([?[:alpha:]0-9'`^._ ]+)*",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
}
}
},
{
"match": "(\\*)(\\s*([?[:alpha:]0-9'`^._ ]+))*",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "entity.name.type.fsharp"
}
}
},
{
"begin": "(<)",
"end": "(>)",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"include": "#generic_declaration"
}
]
},
{
"begin": "({)",
"end": "(})",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"include": "#record_signature"
}
]
},
{
"include": "#variables"
},
{
"include": "#keywords"
}
]
}
@ -242,23 +484,26 @@
"end": "$|(\\|)",
"beginCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "([[:alpha:]0-9'`<>^._]+)\\s*(:)\\s*([[:alpha:]0-9'`<>^._]+)",
"include": "#comments"
},
{
"match": "([[:alpha:]0-9'`<>^._]+|``[[:alpha:]0-9' <>^._]+``)\\s*(:)\\s*([[:alpha:]0-9'`<>^._]+|``[[:alpha:]0-9' <>^._]+``)",
"captures": {
"1": {
"name": "variable.parameter.fsharp"
},
"2": {
"name": "keyword.other.fsharp"
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
@ -266,17 +511,7 @@
}
},
{
"match": "([[:alpha:]0-9'`<>^._]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"begin": "\\(",
"end": "\\)",
"match": "([[:alpha:]0-9'`<>^._]+)",
"match": "([[:alpha:]0-9'`^._]+)|``([[:alpha:]0-9'^._ ]+)``",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
@ -293,17 +528,12 @@
"keywords": {
"patterns": [
{
"name": "keyword.other.fsharp",
"name": "keyword.fsharp",
"match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|use|use\\!|struct|while|mutable)(?!')\\b"
},
{
"name": "meta.preprocessor.fsharp",
"begin": "^\\s*#\\s*(light)\\b",
"end": "(\\s|$)"
},
{
"name": "keyword.other.fsharp",
"match": "(&&&|\\|\\|\\||\\^\\^\\^|~~~|<<<|>>>|\\|>|\\->|\\<\\-|:>|:\\?>|:|\\[|\\]|\\;|<>|=|@|\\|\\||&&|{|}|\\||_|\\.\\.|\\+|\\-|\\*|\\/|\\^|\\!|\\>|\\>\\=|\\>\\>|\\<|\\<\\=|\\<\\<)"
"name": "keyword.symbol.fsharp",
"match": "(&&&|\\|\\|\\||\\^\\^\\^|~~~|<<<|>>>|\\|>|\\->|\\<\\-|:>|:\\?>|:|\\[|\\]|\\;|<>|=|@|\\|\\||&&|{|}|\\||_|\\.\\.|\\,|\\+|\\-|\\*|\\/|\\^|\\!|\\>|\\>\\=|\\>\\>|\\<|\\<\\=|\\(|\\)|\\<\\<)"
}
]
},
@ -312,18 +542,23 @@
{
"name": "entity.name.section.fsharp",
"begin": "\\b(namespace|module)\\s*(public|internal|private)?\\s+([[:alpha:]][[:alpha:]0-9'_. ]*)",
"end": "(\\s|$)",
"end": "(\\s?=|\\s|$)",
"beginCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"3": {
"name": "entity.name.section.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"name": "entity.name.section.fsharp",
@ -345,7 +580,7 @@
"end": "(\\s|$)",
"beginCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"2": {
"name": "entity.name.section.fsharp"
@ -372,7 +607,7 @@
"end": "(\\s|$)",
"beginCaptures": {
"1": {
"name": "keyword.other.namespace-definition.fsharp"
"name": "keyword.fsharp"
},
"2": {
"name": "entity.name.type.namespace.fsharp"
@ -485,7 +720,7 @@
"match": "(%0?-?(\\d+)?((a|t)|(\\.\\d+)?(f|F|e|E|g|G|M)|(b|c|s|d|i|x|X|o)|(s|b|O)|(\\+?A)))",
"captures": {
"1": {
"name": "keyword.other.format.specifier.fsharp"
"name": "keyword.format.specifier.fsharp"
}
}
}
@ -499,29 +734,132 @@
},
{
"name": "variable.parameter.fsharp",
"match": "[[:alpha:]'_]\\w*"
"match": "[[:alpha:]0-9'`<>^._ ]\\w*"
}
]
},
"common_declaration": {
"patterns": [
{
"begin": "\\s*(->)\\s*([[:alpha:]0-9'`^._ ]+)(<)",
"end": "(>)",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "entity.name.type.fsharp"
},
"3": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "([[:alpha:]0-9'`^._ ]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#keywords"
}
]
},
{
"match": "\\s*(->)\\s*([[:alpha:]0-9'`^._ ]+)",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "entity.name.type.fsharp"
}
}
},
{
"begin": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)(<))",
"end": "(>)",
"beginCaptures": {
"1": {
"name": "variable.parameter.fsharp"
},
"2": {
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "keyword.symbol.fsharp"
},
"4": {
"name": "entity.name.type.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "([[:alpha:]0-9'`^._ ]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#keywords"
}
]
}
]
},
"member_declaration": {
"patterns": [
{
"begin": "\\(",
"end": "\\)",
"begin": "(\\()",
"end": "(\\))",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"match": "\\?{0,1}([[:alpha:]0-9'`<>^._]+)\\s*(:{0,1})(\\s*([?[:alpha:]0-9'<>^._ ]+)){0,1}",
"include": "#comments"
},
{
"include": "#common_declaration"
},
{
"match": "\\?{0,1}([[:alpha:]0-9'`^._ ]+)\\s*(:{0,1})(\\s*([?[:alpha:]0-9'`<>^._ ]+)){0,1}",
"captures": {
"1": {
"name": "variable.parameter.fsharp"
},
"2": {
"name": "keyword.other.fsharp"
"name": "keyword.symbol.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#keywords"
}
]
}
@ -550,45 +888,210 @@
"patterns": [
{
"name": "record.fsharp",
"begin": "(type)[\\s]+(private|internal|public)?[\\s]*([[:alpha:]0-9'<>^:,._]+)[\\s]?(private|internal|public)?[\\s]*",
"end": "[\\s]*((with)|((as) ([[:alpha:]0-9']+))|(=)|[\\n=]|(\\(\\)))",
"begin": "\\b(type)[\\s]+(private|internal|public)?(\\s*\\[\\<.*\\>\\])?[\\s]*([[:alpha:]0-9'`^:,._]+|``[[:alpha:]0-9'`^:,._ ]+``)(<)",
"end": "\\s*((with)|((as)\\s*([[:alpha:]0-9']+))|(=)|[\\n=]|(\\(\\)))",
"beginCaptures": {
"1": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"3": {
"name": "entity.name.type.fsharp"
"name": "support.function.attribute.fsharp"
},
"4": {
"name": "keyword.other.fsharp"
"name": "entity.name.type.fsharp"
},
"5": {
"name": "keyword.symbol.fsharp"
}
},
"endCaptures": {
"2": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"3": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"4": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
},
"5": {
"name": "variable.parameter.fsharp"
},
"6": {
"name": "keyword.other.fsharp"
"name": "keyword.symbol.fsharp"
},
"7": {
"name": "constant.language.unit.fsharp"
}
},
"patterns": [
{
"include": "#comments"
},
{
"match": "\\s*(>)\\s*(private|internal|public)?",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
},
"2": {
"name": "keyword.fsharp"
}
}
},
{
"match": "([[:alpha:]0-9'`^._ ]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#member_declaration"
},
{
"include": "#keywords"
}
]
},
{
"name": "record.fsharp",
"begin": "\\b(type)[\\s]+(private|internal|public)?(\\s*\\[\\<.*\\>\\])?[\\s]*([[:alpha:]0-9'`^:,._]+<(.*)>|[[:alpha:]0-9'^:,._]+|``[[:alpha:]0-9'`^:,._ ]+``)[\\s]?(private|internal|public)?[\\s]*",
"end": "\\s*((with)|((as)\\s*([[:alpha:]0-9']+))|(=)|[\\n=]|(\\(\\)))",
"beginCaptures": {
"1": {
"name": "keyword.fsharp"
},
"2": {
"name": "keyword.fsharp"
},
"3": {
"name": "support.function.attribute.fsharp"
},
"4": {
"name": "entity.name.type.fsharp"
},
"6": {
"name": "keyword.fsharp"
}
},
"endCaptures": {
"2": {
"name": "keyword.fsharp"
},
"3": {
"name": "keyword.fsharp"
},
"4": {
"name": "keyword.fsharp"
},
"5": {
"name": "variable.parameter.fsharp"
},
"6": {
"name": "keyword.symbol.fsharp"
},
"7": {
"name": "constant.language.unit.fsharp"
}
},
"patterns": [
{
"include": "#comments"
},
{
"include": "#member_declaration"
}
]
}
]
},
"record_declaration": {
"patterns": [
{
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"end": "(?<=\\})",
"patterns": [
{
"include": "#comments"
},
{
"begin": "(((mutable)\\s[[:alpha:]]+)|[[:alpha:]0-9'`<>^._]*)\\s*((?<!:):(?!:))\\s*",
"beginCaptures": {
"3": {
"name": "keyword.fsharp"
},
"4": {
"name": "keyword.symbol.fsharp"
}
},
"end": "$|(;|\\})",
"endCaptures": {
"1": {
"name": "keyword.symbol.fsharp"
}
},
"patterns": [
{
"include": "#comments"
},
{
"match": "([[:alpha:]0-9'`^_ ]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
{
"include": "#keywords"
}
]
},
{
"include": "#chars"
},
{
"include": "#compiler_directives"
},
{
"include": "#constants"
},
{
"include": "#strings"
},
{
"include": "#chars"
},
{
"include": "#double_tick"
},
{
"include": "#definition"
},
{
"include": "#attributes"
},
{
"include": "#anonymous_functions"
},
{
"include": "#keywords"
},
{
"include": "#cexprs"
},
{
"include": "#text"
}
]
}
@ -601,7 +1104,7 @@
"match": "\\b(async|seq|promise|task|maybe|asyncMaybe|controller|scope|application|pipeline)\\s*\\{",
"captures": {
"0": {
"name": "keyword.other.fsharp"
"name": "keyword.fsharp"
}
}
}
@ -627,6 +1130,15 @@
"match": "\\\\"
}
]
},
"compiler_directives": {
"patterns": [
{
"name": "compiler_directive.fsharp",
"match": "\\s?(#if|#elif|#else|#elseif|#endif|#light|#nowarn)",
"captures": {}
}
]
}
}
}

View file

@ -23,7 +23,7 @@
},
{
"c": "type",
"t": "source.fsharp record.fsharp keyword.other.fsharp",
"t": "source.fsharp record.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -56,13 +56,13 @@
},
{
"c": "(",
"t": "source.fsharp record.fsharp",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
@ -78,7 +78,7 @@
},
{
"c": ":",
"t": "source.fsharp record.fsharp keyword.other.fsharp",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -99,18 +99,18 @@
}
},
{
"c": ", ",
"t": "source.fsharp record.fsharp",
"c": ",",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "age",
"c": " age",
"t": "source.fsharp record.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
@ -122,7 +122,7 @@
},
{
"c": ":",
"t": "source.fsharp record.fsharp keyword.other.fsharp",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -143,7 +143,18 @@
}
},
{
"c": ") ",
"c": ")",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " ",
"t": "source.fsharp record.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
@ -155,7 +166,7 @@
},
{
"c": "=",
"t": "source.fsharp record.fsharp keyword.other.fsharp",
"t": "source.fsharp record.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -177,7 +188,7 @@
},
{
"c": "let mutable",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -199,7 +210,7 @@
},
{
"c": "internalAge",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -221,7 +232,7 @@
},
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -254,7 +265,7 @@
},
{
"c": "new",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -264,7 +275,18 @@
}
},
{
"c": "(name",
"c": "(",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "name",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
@ -276,7 +298,7 @@
},
{
"c": ":",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -286,7 +308,29 @@
}
},
{
"c": "string) ",
"c": "string",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ")",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " ",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
@ -298,7 +342,7 @@
},
{
"c": "=",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -308,7 +352,51 @@
}
},
{
"c": " Person(name, ",
"c": " Person",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "(",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "name",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ",",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " ",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
@ -331,13 +419,13 @@
},
{
"c": ")",
"t": "source.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
@ -353,7 +441,7 @@
},
{
"c": "member",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -375,7 +463,7 @@
},
{
"c": "this.Name",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -397,7 +485,7 @@
},
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -452,7 +540,7 @@
},
{
"c": "member",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -474,7 +562,7 @@
},
{
"c": "this.Age",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -485,7 +573,7 @@
},
{
"c": " ",
"t": "source.fsharp",
"t": "source.fsharp binding.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -496,7 +584,7 @@
},
{
"c": "with",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -540,7 +628,7 @@
},
{
"c": "=",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -573,7 +661,7 @@
},
{
"c": "and",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -583,7 +671,51 @@
}
},
{
"c": " set(value) ",
"c": " set",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "(",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "value",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ")",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " ",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
@ -595,7 +727,7 @@
},
{
"c": "=",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -617,7 +749,7 @@
},
{
"c": "<-",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -650,7 +782,7 @@
},
{
"c": "member",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -672,7 +804,7 @@
},
{
"c": "this.HasABirthday",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -683,13 +815,13 @@
},
{
"c": " ",
"t": "source.fsharp binding.fsharp",
"t": "source.fsharp binding.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"hc_black": "variable: #9CDCFE"
}
},
{
@ -716,7 +848,7 @@
},
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -738,7 +870,7 @@
},
{
"c": "<-",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -760,7 +892,7 @@
},
{
"c": "+",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -804,7 +936,7 @@
},
{
"c": "member",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -826,7 +958,7 @@
},
{
"c": "this.IsOfAge",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -836,18 +968,7 @@
}
},
{
"c": " ",
"t": "source.fsharp binding.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "targetAge",
"c": " targetAge",
"t": "source.fsharp binding.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
@ -870,7 +991,7 @@
},
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -892,7 +1013,7 @@
},
{
"c": ">=",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -925,7 +1046,7 @@
},
{
"c": "override",
"t": "source.fsharp binding.fsharp keyword.other.binding.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -947,7 +1068,7 @@
},
{
"c": "this.ToString",
"t": "source.fsharp binding.fsharp variable.other.binding.fsharp",
"t": "source.fsharp binding.fsharp variable.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@ -958,13 +1079,13 @@
},
{
"c": " ",
"t": "source.fsharp binding.fsharp",
"t": "source.fsharp binding.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"hc_black": "variable: #9CDCFE"
}
},
{
@ -991,7 +1112,7 @@
},
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.other.fsharp",
"t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -1057,7 +1178,7 @@
},
{
"c": "+",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -1079,7 +1200,7 @@
},
{
"c": "+",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -1145,7 +1266,7 @@
},
{
"c": "+",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -1211,7 +1332,7 @@
},
{
"c": "+",
"t": "source.fsharp keyword.other.fsharp",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@ -1221,7 +1342,51 @@
}
},
{
"c": " (string)internalAge",
"c": " ",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "(",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "string",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ")",
"t": "source.fsharp keyword.symbol.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": "internalAge",
"t": "source.fsharp",
"r": {
"dark_plus": "default: #D4D4D4",

View file

@ -51,7 +51,7 @@
"command.stashPop": "Pop Stash...",
"command.stashPopLatest": "Pop Latest Stash",
"config.enabled": "Whether git is enabled",
"config.path": "Path to the git executable",
"config.path": "Path to the git executable.",
"config.autoRepositoryDetection": "Configures when repositories should be automatically detected.",
"config.autorefresh": "Whether auto refreshing is enabled",
"config.autofetch": "Whether auto fetching is enabled",

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/textmate/git.tmbundle/commit/d1db42c2d71948662098183a6df519fb53a7a15b",
"version": "https://github.com/textmate/git.tmbundle/commit/3f6ad2138200db14b57a090ecb2d2e733275ca3e",
"name": "Git Rebase Message",
"scopeName": "text.git-rebase",
"patterns": [
@ -29,7 +29,23 @@
"name": "meta.commit-message.git-rebase"
}
},
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|exec|x|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
"name": "meta.commit-command.git-rebase"
},
{
"captures": {
"1": {
"name": "support.function.git-rebase"
},
"2": {
"patterns": [
{
"include": "source.shell"
}
]
}
},
"match": "^\\s*(exec|x)\\s+(.*)$",
"name": "meta.commit-command.git-rebase"
}
]

View file

@ -1,12 +1,12 @@
{
"displayName": "HTML Language Features",
"description": "Provides rich language support for HTML, Razor, and Handlebar files",
"html.format.enable.desc": "Enable/disable default HTML formatter",
"html.format.enable.desc": "Enable/disable default HTML formatter.",
"html.format.wrapLineLength.desc": "Maximum amount of characters per line (0 = disable).",
"html.format.unformatted.desc": "List of tags, comma separated, that shouldn't be reformatted. 'null' defaults to all tags listed at https://www.w3.org/TR/html5/dom.html#phrasing-content.",
"html.format.contentUnformatted.desc": "List of tags, comma separated, where the content shouldn't be reformatted. 'null' defaults to the 'pre' tag.",
"html.format.indentInnerHtml.desc": "Indent <head> and <body> sections.",
"html.format.preserveNewLines.desc": "Whether existing line breaks before elements should be preserved. Only works before elements, not inside tags or for text.",
"html.format.preserveNewLines.desc": "Controls whether existing line breaks before elements should be preserved. Only works before elements, not inside tags or for text.",
"html.format.maxPreserveNewLines.desc": "Maximum number of line breaks to be preserved in one chunk. Use 'null' for unlimited.",
"html.format.indentHandlebars.desc": "Format and indent {{#foo}} and {{/foo}}.",
"html.format.endWithNewline.desc": "End with a newline.",
@ -16,11 +16,11 @@
"html.format.wrapAttributes.force": "Wrap each attribute except first.",
"html.format.wrapAttributes.forcealign": "Wrap each attribute except first and keep aligned.",
"html.format.wrapAttributes.forcemultiline": "Wrap each attribute.",
"html.suggest.angular1.desc": "Configures if the built-in HTML language support suggests Angular V1 tags and properties.",
"html.suggest.ionic.desc": "Configures if the built-in HTML language support suggests Ionic tags, properties and values.",
"html.suggest.html5.desc":"Configures if the built-in HTML language support suggests HTML5 tags, properties and values.",
"html.suggest.angular1.desc": "Controls whether the built-in HTML language support suggests Angular V1 tags and properties.",
"html.suggest.ionic.desc": "Controls whether the built-in HTML language support suggests Ionic tags, properties and values.",
"html.suggest.html5.desc": "Controls whether the built-in HTML language support suggests HTML5 tags, properties and values.",
"html.trace.server.desc": "Traces the communication between VS Code and the HTML language server.",
"html.validate.scripts": "Configures if the built-in HTML language support validates embedded scripts.",
"html.validate.styles": "Configures if the built-in HTML language support validates embedded styles.",
"html.validate.scripts": "Controls whether the built-in HTML language support validates embedded scripts.",
"html.validate.styles": "Controls whether the built-in HTML language support validates embedded styles.",
"html.autoClosingTags": "Enable/disable autoclosing of HTML tags."
}

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/atom/language-java/commit/b9f1a853a69184363b0fb15f52da07c9660bf730",
"version": "https://github.com/atom/language-java/commit/2f20bc5a5b07686ec0139e2969431210d81b6991",
"name": "Java",
"scopeName": "source.java",
"patterns": [
@ -1424,7 +1424,7 @@
},
"variables": {
"begin": "(?x)\n(?=\n (\n (void|boolean|byte|char|short|int|float|long|double)\n |\n (?>(\\w+\\.)*[A-Z]+\\w*) # e.g. `javax.ws.rs.Response`, or `String`\n )\n (\n <[\\w<>,\\.?\\s\\[\\]]*> # e.g. `HashMap<Integer, String>`, or `List<java.lang.String>`\n )?\n (\n (\\[\\])* # int[][]\n )?\n \\s+\n [A-Za-z_$][\\w$]* # At least one identifier after space\n ([\\w\\[\\],$][\\w\\[\\],\\s]*)? # possibly primitive array or additional identifiers\n \\s*(=|;)\n)",
"end": "(?=;)",
"end": "(?=\\=|;)",
"name": "meta.definition.variable.java",
"patterns": [
{
@ -1438,20 +1438,6 @@
{
"include": "#all-types"
},
{
"begin": "=",
"beginCaptures": {
"0": {
"name": "keyword.operator.assignment.java"
}
},
"end": "(?=;)",
"patterns": [
{
"include": "#code"
}
]
},
{
"include": "#code"
}
@ -1459,7 +1445,7 @@
},
"member-variables": {
"begin": "(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)",
"end": "(?=;)",
"end": "(?=\\=|;)",
"patterns": [
{
"include": "#storage-modifiers"

View file

@ -727,7 +727,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -738,7 +738,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -749,7 +749,7 @@
},
{
"c": "0.0",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java constant.numeric.decimal.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java constant.numeric.decimal.java",
"r": {
"dark_plus": "constant.numeric: #B5CEA8",
"light_plus": "constant.numeric: #09885A",
@ -826,7 +826,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -837,7 +837,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -848,7 +848,7 @@
},
{
"c": "10e3",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java constant.numeric.decimal.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java constant.numeric.decimal.java",
"r": {
"dark_plus": "constant.numeric: #B5CEA8",
"light_plus": "constant.numeric: #09885A",
@ -925,7 +925,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -936,7 +936,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -947,7 +947,7 @@
},
{
"c": "134l",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java constant.numeric.decimal.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java constant.numeric.decimal.java",
"r": {
"dark_plus": "constant.numeric: #B5CEA8",
"light_plus": "constant.numeric: #09885A",
@ -1398,7 +1398,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -1409,7 +1409,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -1420,7 +1420,7 @@
},
{
"c": "0",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java constant.numeric.decimal.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java constant.numeric.decimal.java",
"r": {
"dark_plus": "constant.numeric: #B5CEA8",
"light_plus": "constant.numeric: #09885A",
@ -2047,7 +2047,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -2058,7 +2058,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -2069,7 +2069,7 @@
},
{
"c": "0x5",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java constant.numeric.hex.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java constant.numeric.hex.java",
"r": {
"dark_plus": "constant.numeric: #B5CEA8",
"light_plus": "constant.numeric: #09885A",
@ -2179,7 +2179,7 @@
},
{
"c": "=",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.operator.assignment.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.operator.assignment.java",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
@ -2190,7 +2190,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -2201,7 +2201,7 @@
},
{
"c": "new",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java keyword.control.new.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java keyword.control.new.java",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
@ -2212,7 +2212,7 @@
},
{
"c": " ",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -2223,7 +2223,7 @@
},
{
"c": "Vector",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java meta.function-call.java entity.name.function.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.function-call.java entity.name.function.java",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
"light_plus": "entity.name.function: #795E26",
@ -2234,7 +2234,7 @@
},
{
"c": "(",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java meta.function-call.java punctuation.definition.parameters.begin.bracket.round.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.function-call.java punctuation.definition.parameters.begin.bracket.round.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@ -2245,7 +2245,7 @@
},
{
"c": ")",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.definition.variable.java meta.function-call.java punctuation.definition.parameters.end.bracket.round.java",
"t": "source.java meta.class.java meta.class.body.java meta.method.java meta.method.body.java meta.function-call.java punctuation.definition.parameters.end.bracket.round.java",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d7df3e324468b6535af67573d2956f9a852aa586",
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5",
"name": "JavaScript (with React support)",
"scopeName": "source.js",
"patterns": [
@ -341,7 +341,7 @@
"patterns": [
{
"name": "meta.var-single-variable.expr.js",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.js entity.name.function.js"
@ -581,7 +581,7 @@
}
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "storage.modifier.js"
@ -813,7 +813,7 @@
"include": "#comment"
},
{
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "meta.definition.property.js entity.name.function.js"
@ -2167,7 +2167,7 @@
},
{
"name": "meta.object.member.js",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.js"
@ -2412,7 +2412,7 @@
]
},
{
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\(\\s*$)",
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\()|(<))\\s*$)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.js"
@ -3004,7 +3004,7 @@
"include": "#object-identifiers"
},
{
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.js"
@ -3474,7 +3474,7 @@
"include": "#destructuring-parameter"
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
"1": {
"name": "storage.modifier.js"
@ -4608,7 +4608,7 @@
]
},
"jsx-tag-without-attributes-in-expression": {
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"patterns": [
{
@ -4668,7 +4668,7 @@
]
},
"jsx-tag-in-expression": {
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"patterns": [
{

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d7df3e324468b6535af67573d2956f9a852aa586",
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5",
"name": "JavaScript (with React support)",
"scopeName": "source.js.jsx",
"patterns": [
@ -341,7 +341,7 @@
"patterns": [
{
"name": "meta.var-single-variable.expr.js.jsx",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.js.jsx entity.name.function.js.jsx"
@ -581,7 +581,7 @@
}
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "storage.modifier.js.jsx"
@ -813,7 +813,7 @@
"include": "#comment"
},
{
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "meta.definition.property.js.jsx entity.name.function.js.jsx"
@ -2167,7 +2167,7 @@
},
{
"name": "meta.object.member.js.jsx",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.js.jsx"
@ -2412,7 +2412,7 @@
]
},
{
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\(\\s*$)",
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\()|(<))\\s*$)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.js.jsx"
@ -3004,7 +3004,7 @@
"include": "#object-identifiers"
},
{
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.js.jsx"
@ -3474,7 +3474,7 @@
"include": "#destructuring-parameter"
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
"1": {
"name": "storage.modifier.js.jsx"
@ -4608,7 +4608,7 @@
]
},
"jsx-tag-without-attributes-in-expression": {
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"patterns": [
{
@ -4668,7 +4668,7 @@
]
},
"jsx-tag-in-expression": {
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"patterns": [
{

View file

@ -4,23 +4,25 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/textmate/lua.tmbundle/commit/42da2c6ff5d86c068f72520f856190f413911a80",
"version": "https://github.com/textmate/lua.tmbundle/commit/8ae5641365b28f697121ba1133890e8d81f5b00e",
"name": "Lua",
"scopeName": "source.lua",
"comment": "Lua Syntax: version 0.8",
"patterns": [
{
"begin": "\\b((local\\b)\\s+)?(function)\\s*(\\s+[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*(:[a-zA-Z_][a-zA-Z0-9_]*)?\\s*)?(\\()",
"begin": "\\b(?:(local)\\s+)?(function)\\s*(?:\\s+([a-zA-Z_][a-zA-Z0-9_]*(?:([\\.:])[a-zA-Z_][a-zA-Z0-9_]*)?)\\s*)?(\\()",
"beginCaptures": {
"1": {
"name": "storage.modifier.local.lua"
},
"3": {
"2": {
"name": "keyword.control.lua"
},
"4": {
"3": {
"name": "entity.name.function.lua"
},
"4": {
"name": "punctuation.separator.parameter.lua"
},
"5": {
"name": "punctuation.definition.parameters.begin.lua"
}
@ -36,6 +38,10 @@
{
"match": "[a-zA-Z_][a-zA-Z0-9_]*",
"name": "variable.parameter.function.lua"
},
{
"match": ",",
"name": "punctuation.separator.arguments.lua"
}
]
},

View file

@ -55,7 +55,18 @@
}
},
{
"c": " fact ",
"c": " ",
"t": "source.lua meta.function.lua",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "fact",
"t": "source.lua meta.function.lua entity.name.function.lua",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
@ -66,7 +77,7 @@
}
},
{
"c": "(",
"c": " ",
"t": "source.lua meta.function.lua",
"r": {
"dark_plus": "default: #D4D4D4",
@ -76,6 +87,17 @@
"hc_black": "default: #FFFFFF"
}
},
{
"c": "(",
"t": "source.lua meta.function.lua punctuation.definition.parameters.begin.lua",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "n",
"t": "source.lua meta.function.lua variable.parameter.function.lua",

View file

@ -4,29 +4,47 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js fadeevab/make.tmbundle Syntaxes/Makefile.plist ./syntaxes/make.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "makefile",
"aliases": ["Makefile", "makefile"],
"extensions": [ ".mk" ],
"filenames": [ "Makefile", "makefile", "GNUmakefile", "OCamlMakefile" ],
"firstLine": "^#!\\s*/usr/bin/make",
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "makefile",
"scopeName": "source.makefile",
"path": "./syntaxes/make.tmLanguage.json"
}],
"languages": [
{
"id": "makefile",
"aliases": [
"Makefile",
"makefile"
],
"extensions": [
".mk"
],
"filenames": [
"Makefile",
"makefile",
"GNUmakefile",
"OCamlMakefile"
],
"firstLine": "^#!\\s*/usr/bin/make",
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "makefile",
"scopeName": "source.makefile",
"path": "./syntaxes/make.tmLanguage.json",
"tokenTypes": {
"string.interpolated": "other"
}
}
],
"configurationDefaults": {
"[makefile]": {
"editor.insertSpaces": false
}
}
}
}
}

View file

@ -19,7 +19,8 @@
".md",
".mdown",
".markdown",
".markdn"
".markdn",
".workbook"
],
"configuration": "./language-configuration.json"
}

View file

@ -23,7 +23,7 @@ export const githubSlugifier: Slugifier = new class implements Slugifier {
heading.trim()
.toLowerCase()
.replace(/\s+/g, '-') // Replace whitespace with -
.replace(/[\]\[\!\'\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`]/g, '') // Remove known puctuators
.replace(/[\]\[\!\'\#\$\%\&\'\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known puctuators
.replace(/^\-+/, '') // Remove leading -
.replace(/\-+$/, '') // Remove trailing -
);

View file

@ -1,8 +1,10 @@
{
"version": "0.1.0",
"version": "2.0.0",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"type": "shell",
"presentation": {
"reveal": "silent",
},
"args": ["run", "compile"],
"isBackground": true,
"problemMatcher": "$tsc-watch"

View file

@ -15,11 +15,11 @@ For more information about auto detection of Tasks, see the [documentation](http
### Script Explorer
The Npm Script Explorer shows the npm scripts found in your workspace. The explorer view is enabled by the setting `npm.enableScriptExplorer`.
The Npm Script Explorer shows the npm scripts found in your workspace. The explorer view is enabled by the setting `npm.enableScriptExplorer`. A script can be opened, run, or debug from the explorer.
### Run Scripts from the Editor
The extension provides commands to run the script containing the selection.
The extension provides code lense actions to run or debug a script from the editor.
## Settings
@ -29,3 +29,5 @@ The extension provides commands to run the script containing the selection.
- `npm.exclude` - Glob patterns for folders that should be excluded from automatic script detection. The pattern is matched against the **absolute path** of the package.json. For example, to exclude all test folders use '&ast;&ast;/test/&ast;&ast;'.
- `npm.enableScriptExplorer` - Enable an explorer view for npm scripts.
- `npm.scriptExplorerAction` - The default click action: `open` or `run`, the default is `open`.
- `npm.scriptCodeLens.enable` - Enable/disable the code lenses to run a script.

View file

@ -59,10 +59,6 @@
"dark": "resources/dark/continue.svg"
}
},
{
"command": "npm.runScriptFromSource",
"title": "%command.runScriptFromSource%"
},
{
"command": "npm.debugScript",
"title": "%command.debug%",
@ -98,10 +94,6 @@
"command": "npm.runScript",
"when": "false"
},
{
"command": "npm.runScriptFromSource",
"when": "false"
},
{
"command": "npm.debugScript",
"when": "false"
@ -122,13 +114,6 @@
"group": "navigation"
}
],
"editor/context": [
{
"command": "npm.runScriptFromSource",
"when": "resourceFilename == 'package.json'",
"group": "navigation@+1"
}
],
"view/item/context": [
{
"command": "npm.openScript",
@ -193,6 +178,12 @@
"scope": "resource",
"description": "%config.npm.runSilent%"
},
"npm.scriptCodeLens.enable": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "%config.scriptCodeLens.enable%"
},
"npm.packageManager": {
"scope": "resource",
"type": "string",

View file

@ -7,6 +7,7 @@
"config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.",
"config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts.",
"config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: 'open' or 'run', the default is 'open'.",
"config.scriptCodeLens.enable": "Enable the code lens to 'Run' or 'Debug' an npm script.",
"npm.parseError": "Npm task detection: failed to parse the file {0}",
"taskdef.script": "The npm script to customize.",
"taskdef.path": "The path to the folder of the package.json file that provides the script. Can be omitted.",
@ -15,6 +16,5 @@
"command.run": "Run",
"command.debug": "Debug",
"command.openScript": "Open",
"command.runInstall": "Run Install",
"command.runScriptFromSource": "Run Script"
"command.runInstall": "Run Install"
}

View file

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {
ExtensionContext, CodeLensProvider, TextDocument, commands, ProviderResult, CodeLens, CancellationToken,
workspace, tasks, Range, Command, Event, EventEmitter
} from 'vscode';
import {
createTask, startDebugging, findAllScriptRanges, extractDebugArgFromScript
} from './tasks';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export class NpmLensProvider implements CodeLensProvider {
private extensionContext: ExtensionContext;
private _onDidChangeCodeLenses: EventEmitter<void> = new EventEmitter<void>();
readonly onDidChangeCodeLenses: Event<void> = this._onDidChangeCodeLenses.event;
constructor(context: ExtensionContext) {
this.extensionContext = context;
context.subscriptions.push(commands.registerCommand('npm.runScriptFromLens', this.runScriptFromLens, this));
context.subscriptions.push(commands.registerCommand('npm.debugScriptFromLens', this.debugScriptFromLens, this));
}
public provideCodeLenses(document: TextDocument, _token: CancellationToken): ProviderResult<CodeLens[]> {
let result = findAllScriptRanges(document.getText());
let folder = workspace.getWorkspaceFolder(document.uri);
let lenses: CodeLens[] = [];
if (folder && !workspace.getConfiguration('npm', folder.uri).get<string>('scriptCodeLens.enable', 'true')) {
return lenses;
}
result.forEach((value, key) => {
let start = document.positionAt(value[0]);
let end = document.positionAt(value[0] + value[1]);
let range = new Range(start, end);
let command: Command = {
command: 'npm.runScriptFromLens',
title: localize('run', "Run"),
arguments: [document, key]
};
let lens: CodeLens = new CodeLens(range, command);
lenses.push(lens);
let debugArgs = extractDebugArgFromScript(value[2]);
if (debugArgs) {
command = {
command: 'npm.debugScriptFromLens',
title: localize('debug', "Debug"),
arguments: [document, key, debugArgs[0], debugArgs[1]]
};
lens = new CodeLens(range, command);
lenses.push(lens);
}
});
return lenses;
}
public refresh() {
this._onDidChangeCodeLenses.fire();
}
public runScriptFromLens(document: TextDocument, script: string) {
let uri = document.uri;
let folder = workspace.getWorkspaceFolder(uri);
if (folder) {
let task = createTask(script, `run ${script}`, folder, uri);
tasks.executeTask(task);
}
}
public debugScriptFromLens(document: TextDocument, script: string, protocol: string, port: number) {
let uri = document.uri;
let folder = workspace.getWorkspaceFolder(uri);
if (folder) {
startDebugging(script, protocol, port, folder);
}
}
}

View file

@ -9,17 +9,14 @@ import * as vscode from 'vscode';
import { addJSONProviders } from './features/jsonContributions';
import { NpmScriptsTreeDataProvider } from './npmView';
import { provideNpmScripts, invalidateScriptsCache, findScriptAtPosition, createTask } from './tasks';
import * as nls from 'vscode-nls';
let taskProvider: vscode.Disposable | undefined;
const localize = nls.loadMessageBundle();
import { invalidateScriptsCache, NpmTaskProvider } from './tasks';
import { NpmLensProvider } from './lenses';
export async function activate(context: vscode.ExtensionContext): Promise<void> {
taskProvider = registerTaskProvider(context);
const taskProvider = registerTaskProvider(context);
const treeDataProvider = registerExplorer(context);
const lensProvider = registerLensProvider(context);
configureHttpRequest();
vscode.workspace.onDidChangeConfiguration((e) => {
configureHttpRequest();
@ -34,9 +31,13 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
treeDataProvider.refresh();
}
}
if (e.affectsConfiguration('npm.scriptCodeLens.enable')) {
if (lensProvider) {
lensProvider.refresh();
}
}
});
context.subscriptions.push(addJSONProviders(httpRequest.xhr));
context.subscriptions.push(vscode.commands.registerCommand('npm.runScriptFromSource', runScriptFromSource));
}
function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposable | undefined {
@ -47,15 +48,10 @@ function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposab
watcher.onDidCreate((_e) => invalidateScriptsCache());
context.subscriptions.push(watcher);
let provider: vscode.TaskProvider = {
provideTasks: async () => {
return provideNpmScripts();
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
};
return vscode.workspace.registerTaskProvider('npm', provider);
let provider: vscode.TaskProvider = new NpmTaskProvider(context);
let disposable = vscode.workspace.registerTaskProvider('npm', provider);
context.subscriptions.push(disposable);
return disposable;
}
return undefined;
}
@ -70,36 +66,24 @@ function registerExplorer(context: vscode.ExtensionContext): NpmScriptsTreeDataP
return undefined;
}
function registerLensProvider(context: vscode.ExtensionContext): NpmLensProvider | undefined {
if (vscode.workspace.workspaceFolders) {
let npmSelector: vscode.DocumentSelector = {
language: 'json',
scheme: 'file',
pattern: '**/package.json'
};
let provider = new NpmLensProvider(context);
context.subscriptions.push(vscode.languages.registerCodeLensProvider(npmSelector, provider));
return provider;
}
return undefined;
}
function configureHttpRequest() {
const httpSettings = vscode.workspace.getConfiguration('http');
httpRequest.configure(httpSettings.get<string>('proxy', ''), httpSettings.get<boolean>('proxyStrictSSL', true));
}
async function runScriptFromSource() {
let editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
let document = editor.document;
let contents = document.getText();
let selection = editor.selection;
let offset = document.offsetAt(selection.anchor);
let script = findScriptAtPosition(contents, offset);
if (script) {
let uri = document.uri;
let folder = vscode.workspace.getWorkspaceFolder(uri);
if (folder) {
let task = createTask(script, `run ${script}`, folder, uri);
vscode.tasks.executeTask(task);
}
} else {
let message = localize('noScriptFound', 'Could not find a script at the selection.');
vscode.window.showErrorMessage(message);
}
}
export function deactivate(): void {
if (taskProvider) {
taskProvider.dispose();
}
}

View file

@ -6,14 +6,14 @@
import * as path from 'path';
import {
DebugConfiguration, Event, EventEmitter, ExtensionContext, Task,
Event, EventEmitter, ExtensionContext, Task,
TextDocument, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, Uri,
WorkspaceFolder, commands, debug, window, workspace, tasks, Selection, TaskGroup
WorkspaceFolder, commands, window, workspace, tasks, Selection, TaskGroup
} from 'vscode';
import { visit, JSONVisitor } from 'jsonc-parser';
import {
NpmTaskDefinition, getPackageJsonUriFromTask, getScripts,
isWorkspaceFolder, getPackageManager, getTaskName, createTask
isWorkspaceFolder, getTaskName, createTask, extractDebugArgFromScript, startDebugging
} from './tasks';
import * as nls from 'vscode-nls';
@ -162,25 +162,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
}
private extractDebugArg(scripts: any, task: Task): [string, number] | undefined {
let script: string = scripts[task.name];
// matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect,
// --inspect=1234, --inspect-brk, --inspect-brk=1234,
// --inspect=localhost:1245, --inspect=127.0.0.1:1234, --inspect=[aa:1:0:0:0]:1234, --inspect=:1234
let match = script.match(/--(inspect|debug)(-brk)?(=((\[[0-9a-fA-F:]*\]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z0-9\.]*):)?(\d+))?/);
if (match) {
if (match[6]) {
return [match[1], parseInt(match[6])];
}
if (match[1] === 'inspect') {
return [match[1], 9229];
}
if (match[1] === 'debug') {
return [match[1], 5858];
}
}
return undefined;
return extractDebugArgFromScript(scripts[task.name]);
}
private async debugScript(script: NpmScript) {
@ -193,7 +175,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
return;
}
let debugArg = await this.extractDebugArg(scripts, task);
let debugArg = this.extractDebugArg(scripts, task);
if (!debugArg) {
let message = localize('noDebugOptions', 'Could not launch "{0}" for debugging because the scripts lacks a node debug option, e.g. "--inspect-brk".', task.name);
let learnMore = localize('learnMore', 'Learn More');
@ -204,29 +186,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
}
return;
}
let protocol = 'inspector';
if (debugArg[0] === 'debug') {
protocol = 'legacy';
}
let packageManager = getPackageManager(script.getFolder());
const config: DebugConfiguration = {
type: 'node',
request: 'launch',
name: `Debug ${task.name}`,
runtimeExecutable: packageManager,
runtimeArgs: [
'run-script',
task.name,
],
port: debugArg[1],
protocol: protocol
};
if (isWorkspaceFolder(task.scope)) {
debug.startDebugging(task.scope, config);
}
startDebugging(task.name, debugArg[0], debugArg[1], script.getFolder());
}
private scriptNotValid(task: Task) {

View file

@ -4,7 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace } from 'vscode';
import {
TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace,
DebugConfiguration, debug, TaskProvider, ExtensionContext
} from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as minimatch from 'minimatch';
@ -22,6 +25,22 @@ type AutoDetect = 'on' | 'off';
let cachedTasks: Task[] | undefined = undefined;
export class NpmTaskProvider implements TaskProvider {
private extensionContext: ExtensionContext;
constructor(context: ExtensionContext) {
this.extensionContext = context;
}
public provideTasks() {
return provideNpmScripts();
}
public resolveTask(_task: Task): Task | undefined {
return undefined;
}
}
export function invalidateScriptsCache() {
cachedTasks = undefined;
}
@ -162,7 +181,7 @@ function isExcluded(folder: WorkspaceFolder, packageJsonUri: Uri) {
}
function isDebugScript(script: string): boolean {
let match = script.match(/--(inspect|debug)(-brk)?(=(\d*))?/);
let match = script.match(/--(inspect|debug)(-brk)?(=((\[[0-9a-fA-F:]*\]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z0-9\.]*):)?(\d+))?/);
return match !== null;
}
@ -269,6 +288,52 @@ async function readFile(file: string): Promise<string> {
});
}
export function extractDebugArgFromScript(scriptValue: string): [string, number] | undefined {
// matches --debug, --debug=1234, --debug-brk, debug-brk=1234, --inspect,
// --inspect=1234, --inspect-brk, --inspect-brk=1234,
// --inspect=localhost:1245, --inspect=127.0.0.1:1234, --inspect=[aa:1:0:0:0]:1234, --inspect=:1234
let match = scriptValue.match(/--(inspect|debug)(-brk)?(=((\[[0-9a-fA-F:]*\]|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z0-9\.]*):)?(\d+))?/);
if (match) {
if (match[6]) {
return [match[1], parseInt(match[6])];
}
if (match[1] === 'inspect') {
return [match[1], 9229];
}
if (match[1] === 'debug') {
return [match[1], 5858];
}
}
return undefined;
}
export function startDebugging(scriptName: string, protocol: string, port: number, folder: WorkspaceFolder) {
let p = 'inspector';
if (protocol === 'debug') {
p = 'legacy';
}
let packageManager = getPackageManager(folder);
const config: DebugConfiguration = {
type: 'node',
request: 'launch',
name: `Debug ${scriptName}`,
runtimeExecutable: packageManager,
runtimeArgs: [
'run-script',
scriptName,
],
port: port,
protocol: p
};
if (folder) {
debug.startDebugging(folder, config);
}
}
export type StringMap = { [s: string]: string; };
async function findAllScripts(buffer: string): Promise<StringMap> {
@ -278,7 +343,6 @@ async function findAllScripts(buffer: string): Promise<StringMap> {
let visitor: JSONVisitor = {
onError(_error: ParseErrorCode, _offset: number, _length: number) {
// TODO: inform user about the parse error
},
onObjectEnd() {
if (inScripts) {
@ -304,45 +368,39 @@ async function findAllScripts(buffer: string): Promise<StringMap> {
return scripts;
}
export function findScriptAtPosition(buffer: string, offset: number): string | undefined {
export function findAllScriptRanges(buffer: string): Map<string, [number, number, string]> {
var scripts: Map<string, [number, number, string]> = new Map();
let script: string | undefined = undefined;
let inScripts = false;
let scriptStart: number | undefined;
let visitor: JSONVisitor = {
onError(_error: ParseErrorCode, _offset: number, _length: number) {
// TODO: inform user about the parse error
},
onObjectEnd() {
if (inScripts) {
inScripts = false;
scriptStart = undefined;
}
},
onLiteralValue(value: any, nodeOffset: number, nodeLength: number) {
if (inScripts && scriptStart) {
if (offset >= scriptStart && offset < nodeOffset + nodeLength) {
// found the script
inScripts = false;
} else {
script = undefined;
}
onLiteralValue(value: any, offset: number, length: number) {
if (script) {
scripts.set(script, [offset, length, value]);
script = undefined;
}
},
onObjectProperty(property: string, nodeOffset: number, nodeLength: number) {
onObjectProperty(property: string, offset: number, length: number) {
if (property === 'scripts') {
inScripts = true;
}
else if (inScripts) {
scriptStart = nodeOffset;
script = property;
}
}
};
visit(buffer, visitor);
return script;
return scripts;
}
export async function getScripts(packageJsonUri: Uri): Promise<StringMap | undefined> {
if (packageJsonUri.scheme !== 'file') {

View file

@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "3.0.1-insiders.20180713"
"typescript": "3.0.1-insiders.20180723"
},
"scripts": {
"postinstall": "node ./postinstall"

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/MagicStack/MagicPython/commit/b453f26ed856c9b16a053517c41207e3a72cc7d5",
"version": "https://github.com/MagicStack/MagicPython/commit/fb56c6a98d684e30bed1b0f9647e85741a48f914",
"name": "MagicPython",
"scopeName": "source.python",
"patterns": [
@ -97,7 +97,8 @@
},
"docstring-statement": {
"begin": "^(?=\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))",
"end": "(?<=\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\")",
"comment": "the string either terminates correctly or by the beginning of a new line (this is for single line docstrings that aren't terminated) AND it's not followed by another docstring",
"end": "((?<=\\1)|^)(?!\\s*[rR]?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))",
"patterns": [
{
"include": "#docstring"
@ -164,7 +165,7 @@
{
"name": "string.quoted.docstring.single.python",
"begin": "(\\'|\\\")",
"end": "(\\1)|((?<!\\\\)\\n)",
"end": "(\\1)|(\\n)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.python"
@ -190,7 +191,7 @@
{
"name": "string.quoted.docstring.raw.single.python",
"begin": "([rR])(\\'|\\\")",
"end": "(\\2)|((?<!\\\\)\\n)",
"end": "(\\2)|(\\n)",
"beginCaptures": {
"1": {
"name": "storage.type.string.python"
@ -847,40 +848,45 @@
"match": "\\\\$"
},
"string-formatting": {
"name": "constant.character.format.placeholder.other.python",
"match": "(?x)\n % (\\([\\w\\s]*\\))?\n [-+#0 ]*\n (\\d+|\\*)? (\\.(\\d+|\\*))?\n ([hlL])?\n [diouxXeEfFgGcrsa%]\n"
"name": "meta.format.percent.python",
"match": "(?x)\n (\n % (\\([\\w\\s]*\\))?\n [-+#0 ]*\n (\\d+|\\*)? (\\.(\\d+|\\*))?\n ([hlL])?\n [diouxXeEfFgGcrsa%]\n )\n",
"captures": {
"1": {
"name": "constant.character.format.placeholder.other.python"
}
}
},
"string-brace-formatting": {
"patterns": [
{
"name": "constant.character.format.placeholder.other.python",
"match": "(?x)\n (?:\n {{ | }}\n | (?:\n {\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n",
"name": "meta.format.brace.python",
"match": "(?x)\n (\n {{ | }}\n | (?:\n {\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?\n })\n )\n",
"captures": {
"2": {
"name": "storage.type.format.python"
"1": {
"name": "constant.character.format.placeholder.other.python"
},
"3": {
"name": "storage.type.format.python"
},
"4": {
"name": "storage.type.format.python"
}
}
},
{
"name": "constant.character.format.placeholder.other.python",
"begin": "(?x)\n \\{\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n (:)\n (?=[^'\"}\\n]*\\})\n",
"end": "\\}",
"beginCaptures": {
"2": {
"name": "storage.type.format.python"
"name": "meta.format.brace.python",
"match": "(?x)\n (\n {\n \\w*? (\\.[[:alpha:]_]\\w*? | \\[[^\\]'\"]+\\])*?\n (![rsa])?\n (:)\n (\n [^'\"{}\\n]+?\n |\n \\{ [^'\"}\\n]*? \\}\n )*\n }\n )\n",
"captures": {
"1": {
"name": "constant.character.format.placeholder.other.python"
},
"3": {
"name": "storage.type.format.python"
},
"4": {
"name": "storage.type.format.python"
}
},
"patterns": [
{
"match": "(?x) \\{ [^'\"}\\n]*? \\} (?=.*?\\})\n"
}
]
}
}
]
},
@ -4537,7 +4543,7 @@
},
"string-quoted-single-line": {
"name": "string.quoted.single.python",
"begin": "(\\b[rR](?=[uU]))?([uU])?((['\"]))",
"begin": "(?:\\b([rR])(?=[uU]))?([uU])?((['\"]))",
"end": "(\\3)|((?<!\\\\)\\n)",
"beginCaptures": {
"1": {
@ -4711,7 +4717,7 @@
},
"string-quoted-multi-line": {
"name": "string.quoted.multi.python",
"begin": "(\\b[rR](?=[uU]))?([uU])?('''|\"\"\")",
"begin": "(?:\\b([rR])(?=[uU]))?([uU])?('''|\"\"\")",
"end": "(\\3)",
"beginCaptures": {
"1": {

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/d7df3e324468b6535af67573d2956f9a852aa586",
"version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/27425437b2144f43607047ae7ee9b826e36856a5",
"name": "TypeScriptReact",
"scopeName": "source.tsx",
"patterns": [
@ -341,7 +341,7 @@
"patterns": [
{
"name": "meta.var-single-variable.expr.tsx",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.tsx entity.name.function.tsx"
@ -581,7 +581,7 @@
}
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.))\\s*(\\??)(?=\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "storage.modifier.tsx"
@ -813,7 +813,7 @@
"include": "#comment"
},
{
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(\\?)?(?=(\\?\\s*)?\\s*\n# function assignment |\n(=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"1": {
"name": "meta.definition.property.tsx entity.name.function.tsx"
@ -2167,7 +2167,7 @@
},
{
"name": "meta.object.member.tsx",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.tsx"
@ -2412,7 +2412,7 @@
]
},
{
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\(\\s*$)",
"begin": "(?<=[(=,]|=>)\\s*(async)?(?=\\s*((((<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*))?\\()|(<))\\s*$)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.tsx"
@ -3004,7 +3004,7 @@
"include": "#object-identifiers"
},
{
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([\\(]\\s*([\\{\\[]\\s*)?$) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"match": "(?x)(?:(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$)) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)?\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*>\\s*)? # typeparameters\n \\(\\s*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\)))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)]|\\<[^<>]+\\>|\\([^\\(\\)]+\\))+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.tsx"
@ -3474,7 +3474,7 @@
"include": "#destructuring-parameter"
},
{
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*([\\(]\\s*([\\{\\[]\\s*)?$)))",
"match": "(?x)(?:(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(public|private|protected|readonly)\\s+)?(?:(\\.\\.\\.)\\s*)?(?<!=|:)(?<![_$[:alnum:]])(?:(?<=\\.\\.\\.)|(?<!\\.))(?:(this)|([_$[:alpha:]][_$[:alnum:]]*))\\s*(\\??)(?=\\s*(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*((<\\s*$)|([\\(]\\s*([\\{\\[]\\s*)?$))))",
"captures": {
"1": {
"name": "storage.modifier.tsx"
@ -4608,7 +4608,7 @@
]
},
"jsx-tag-without-attributes-in-expression": {
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"begin": "(?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))?\\s*(>))",
"patterns": [
{
@ -4668,7 +4668,7 @@
]
},
"jsx-tag-in-expression": {
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"begin": "(?x)\n (?<!\\+\\+|--)(?<=[({\\[,?=>:*]|&&|\\|\\||\\?|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?<!\\.|-)(:))?((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\\w.]*))(?<!\\.|-))(?=((<\\s*)|(\\s+))(?!\\?)|\\/?>))",
"patterns": [
{

View file

@ -462,6 +462,11 @@
"relative",
"non-relative"
],
"enumDescriptions": [
"%typescript.preferences.importModuleSpecifier.auto%",
"%typescript.preferences.importModuleSpecifier.relative%",
"%typescript.preferences.importModuleSpecifier.nonRelative%"
],
"default": "auto",
"description": "%typescript.preferences.importModuleSpecifier%",
"scope": "resource"
@ -477,18 +482,6 @@
"description": "%typescript.preferences.importModuleSpecifier%",
"scope": "resource"
},
"javascript.showUnused": {
"type": "boolean",
"default": true,
"description": "%typescript.showUnused%",
"scope": "resource"
},
"typescript.showUnused": {
"type": "boolean",
"default": true,
"description": "%typescript.showUnused%",
"scope": "resource"
},
"typescript.updateImportsOnFileMove.enabled": {
"type": "string",
"enum": [

View file

@ -15,7 +15,7 @@
"javascript.format.enable": "Enable/disable default JavaScript formatter.",
"format.insertSpaceAfterCommaDelimiter": "Defines space handling after a comma delimiter.",
"format.insertSpaceAfterConstructor": "Defines space handling after the constructor keyword. Requires using TypeScript 2.3.0 or newer in the workspace.",
"format.insertSpaceAfterSemicolonInForStatements": " Defines space handling after a semicolon in a for statement.",
"format.insertSpaceAfterSemicolonInForStatements": "Defines space handling after a semicolon in a for statement.",
"format.insertSpaceBeforeAndAfterBinaryOperators": "Defines space handling after a binary operator.",
"format.insertSpaceAfterKeywordsInControlFlowStatements": "Defines space handling after keywords in a control flow statement.",
"format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": "Defines space handling after function keyword for anonymous functions.",
@ -47,14 +47,16 @@
"typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)",
"typescript.quickSuggestionsForPaths": "Enable/disable quick suggestions when typing out an import path.",
"typescript.locale": "Sets the locale used to report JavaScript and TypeScript errors. Requires using TypeScript 2.6.0 or newer in the workspace. Default of 'null' uses VS Code's locale.",
"javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable 'experimentalDecorators' for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.",
"javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable `experimentalDecorators` for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.",
"typescript.autoImportSuggestions.enabled": "Enable/disable auto import suggestions. Requires using TypeScript 2.6.1 or newer in the workspace.",
"taskDefinition.tsconfig.description": "The tsconfig file that defines the TS build.",
"javascript.suggestionActions.enabled": "Enable/disable suggestion diagnostics for JavaScript files in the editor. Requires using TypeScript 2.8 or newer in the workspace.",
"typescript.suggestionActions.enabled": "Enable/disable suggestion diagnostics for TypeScript files in the editor. Requires using TypeScript 2.8 or newer in the workspace.",
"typescript.preferences.quoteStyle": "Preferred quote style to use for quick fixes: 'single' quotes, 'double' quotes, or 'auto' infer quote type from existing imports. Requires using TypeScript 2.9 or newer in the workspace.",
"typescript.preferences.importModuleSpecifier": "Preferred path style for auto imports:\n- \"relative\" to the file location.\n- \"non-relative\" based on the 'baseUrl' configured in your 'jsconfig.json' / 'tsconfig.json'.\n- \"auto\" infer the shortest path type.\nRequires using TypeScript 2.9 or newer in the workspace.",
"typescript.showUnused": "Enable/disable highlighting of unused variables in code. Requires using TypeScript 2.9 or newer in the workspace.",
"typescript.preferences.importModuleSpecifier": "Preferred path style for auto imports.",
"typescript.preferences.importModuleSpecifier.auto": "Infer the shortest path type.",
"typescript.preferences.importModuleSpecifier.relative": "Relative to the file location.",
"typescript.preferences.importModuleSpecifier.nonRelative": "Based on the `baseUrl` configured in your `jsconfig.json` / `tsconfig.json`.",
"typescript.updateImportsOnFileMove.enabled": "Enable/disable automatic updating of import paths when you rename or move a file in VS Code. Possible values are: 'prompt' on each rename, 'always' update paths automatically, and 'never' rename paths and don't prompt me. Requires using TypeScript 2.9 or newer in the workspace.",
"typescript.autoClosingTags": "Enable/disable automatic closing of JSX tags. Requires using TypeScript 3.0 or newer in the workspace."
}
}

View file

@ -16,6 +16,7 @@ import LogDirectoryProvider from './utils/logDirectoryProvider';
import ManagedFileContextManager from './utils/managedFileContext';
import { getContributedTypeScriptServerPlugins, TypeScriptServerPlugin } from './utils/plugins';
import * as ProjectStatus from './utils/projectStatus';
import { flatten } from './utils/arrays';
export function activate(
@ -36,7 +37,10 @@ export function activate(
context.subscriptions.push(module.register());
});
const supportedLanguage = [].concat.apply([], standardLanguageDescriptions.map(x => x.modeIds).concat(plugins.map(x => x.languages)));
const supportedLanguage = flatten([
...standardLanguageDescriptions.map(x => x.modeIds),
...plugins.map(x => x.languages)
]);
function didOpenTextDocument(textDocument: vscode.TextDocument): boolean {
if (isSupportedDocument(supportedLanguage, textDocument)) {
openListener.dispose();

View file

@ -364,14 +364,14 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
]
};
let response: Proto.CompletionDetailsResponse;
let details: Proto.CompletionEntryDetails[] | undefined;
try {
response = await this.client.execute('completionEntryDetails', args, token);
const response = await this.client.execute('completionEntryDetails', args, token);
details = response.body;
} catch {
return item;
}
const details = response.body;
if (!details || !details.length || !details[0]) {
return item;
}

View file

@ -17,12 +17,7 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase
super(client);
}
public async provideDefinition() {
// Implemented by provideDefinition2
return undefined;
}
public async provideDefinition2(
public async provideDefinition(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken | boolean
@ -44,10 +39,11 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase
const span = response.body.textSpan ? typeConverters.Range.fromTextSpan(response.body.textSpan) : undefined;
return locations
.map(location => {
const loc = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location);
return {
origin: span,
...loc,
const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location);
return <vscode.DefinitionLink>{
originSelectionRange: span,
targetRange: target.range,
targetUri: target.uri,
};
});
} catch {

View file

@ -5,25 +5,7 @@
import * as vscode from 'vscode';
import { ResourceMap } from '../utils/resourceMap';
export class DiagnosticSet {
private _map = new ResourceMap<vscode.Diagnostic[]>();
public set(
file: vscode.Uri,
diagnostics: vscode.Diagnostic[]
) {
this._map.set(file, diagnostics);
}
public get(file: vscode.Uri): vscode.Diagnostic[] {
return this._map.get(file) || [];
}
public clear(): void {
this._map = new ResourceMap<vscode.Diagnostic[]>();
}
}
import { DiagnosticLanguage, allDiagnosticLangauges } from '../utils/languageDescription';
export enum DiagnosticKind {
Syntax,
@ -31,25 +13,129 @@ export enum DiagnosticKind {
Suggestion
}
const allDiagnosticKinds = [DiagnosticKind.Syntax, DiagnosticKind.Semantic, DiagnosticKind.Suggestion];
class FileDiagnostics {
private readonly _diagnostics = new Map<DiagnosticKind, vscode.Diagnostic[]>();
constructor(
public readonly file: vscode.Uri,
public language: DiagnosticLanguage
) { }
public updateDiagnostics(
language: DiagnosticLanguage,
kind: DiagnosticKind,
diagnostics: vscode.Diagnostic[]
): boolean {
if (language !== this.language) {
this._diagnostics.clear();
this.language = language;
}
if (diagnostics.length === 0) {
const existing = this._diagnostics.get(kind);
if (!existing || existing && existing.length === 0) {
// No need to update
return false;
}
}
this._diagnostics.set(kind, diagnostics);
return true;
}
public getDiagnostics(settings: DiagnosticSettings): vscode.Diagnostic[] {
if (!settings.getValidate(this.language)) {
return [];
}
return [
...this.get(DiagnosticKind.Syntax),
...this.get(DiagnosticKind.Semantic),
...this.getSuggestionDiagnostics(settings),
];
}
private getSuggestionDiagnostics(settings: DiagnosticSettings) {
const enableSuggestions = settings.getEnableSuggestions(this.language);
return this.get(DiagnosticKind.Suggestion).filter(x => {
if (!enableSuggestions) {
// Still show unused
return x.tags && x.tags.indexOf(vscode.DiagnosticTag.Unnecessary) !== -1;
}
return true;
});
}
private get(kind: DiagnosticKind): vscode.Diagnostic[] {
return this._diagnostics.get(kind) || [];
}
}
interface LangaugeDiagnosticSettings {
readonly validate: boolean;
readonly enableSuggestions: boolean;
}
class DiagnosticSettings {
private static readonly defaultSettings: LangaugeDiagnosticSettings = {
validate: true,
enableSuggestions: true
};
private readonly _languageSettings = new Map<DiagnosticLanguage, LangaugeDiagnosticSettings>();
constructor() {
for (const language of allDiagnosticLangauges) {
this._languageSettings.set(language, DiagnosticSettings.defaultSettings);
}
}
public getValidate(language: DiagnosticLanguage): boolean {
return this.get(language).validate;
}
public setValidate(language: DiagnosticLanguage, value: boolean): boolean {
return this.update(language, settings => ({
validate: value,
enableSuggestions: settings.enableSuggestions
}));
}
public getEnableSuggestions(language: DiagnosticLanguage): boolean {
return this.get(language).enableSuggestions;
}
public setEnableSuggestions(language: DiagnosticLanguage, value: boolean): boolean {
return this.update(language, settings => ({
validate: settings.validate,
enableSuggestions: value
}));
}
private get(language: DiagnosticLanguage): LangaugeDiagnosticSettings {
return this._languageSettings.get(language) || DiagnosticSettings.defaultSettings;
}
private update(language: DiagnosticLanguage, f: (x: LangaugeDiagnosticSettings) => LangaugeDiagnosticSettings): boolean {
const currentSettings = this.get(language);
const newSettings = f(currentSettings);
this._languageSettings.set(language, newSettings);
return currentSettings.validate === newSettings.validate
&& currentSettings.enableSuggestions && currentSettings.enableSuggestions;
}
}
export class DiagnosticsManager {
private readonly _diagnostics = new Map<DiagnosticKind, DiagnosticSet>();
private readonly _diagnostics = new ResourceMap<FileDiagnostics>();
private readonly _settings = new DiagnosticSettings();
private readonly _currentDiagnostics: vscode.DiagnosticCollection;
private _pendingUpdates = new ResourceMap<any>();
private _validate: boolean = true;
private _enableSuggestions: boolean = true;
private readonly updateDelay = 50;
private readonly _updateDelay = 50;
constructor(
owner: string
) {
for (const kind of allDiagnosticKinds) {
this._diagnostics.set(kind, new DiagnosticSet());
}
this._currentDiagnostics = vscode.languages.createDiagnosticCollection(owner);
}
@ -64,63 +150,56 @@ export class DiagnosticsManager {
public reInitialize(): void {
this._currentDiagnostics.clear();
this._diagnostics.clear();
}
for (const diagnosticSet of this._diagnostics.values()) {
diagnosticSet.clear();
public setValidate(language: DiagnosticLanguage, value: boolean) {
const didUpdate = this._settings.setValidate(language, value);
if (didUpdate) {
this.rebuild();
}
}
public set validate(value: boolean) {
if (this._validate === value) {
return;
}
this._validate = value;
if (!value) {
this._currentDiagnostics.clear();
public setEnableSuggestions(language: DiagnosticLanguage, value: boolean) {
const didUpdate = this._settings.setEnableSuggestions(language, value);
if (didUpdate) {
this.rebuild();
}
}
public set enableSuggestions(value: boolean) {
if (this._enableSuggestions === value) {
return;
}
this._enableSuggestions = value;
if (!value) {
this._currentDiagnostics.clear();
}
}
public diagnosticsReceived(
public updateDiagnostics(
file: vscode.Uri,
language: DiagnosticLanguage,
kind: DiagnosticKind,
diagnostics: vscode.Diagnostic[]
): void {
let didUpdate = false;
const entry = this._diagnostics.get(file);
if (entry) {
didUpdate = entry.updateDiagnostics(language, kind, diagnostics);
} else if (diagnostics.length) {
const fileDiagnostics = new FileDiagnostics(file, language);
fileDiagnostics.updateDiagnostics(language, kind, diagnostics);
this._diagnostics.set(file, fileDiagnostics);
didUpdate = true;
}
if (didUpdate) {
this.scheduleDiagnosticsUpdate(file);
}
}
public configFileDiagnosticsReceived(
file: vscode.Uri,
diagnostics: vscode.Diagnostic[]
): void {
const collection = this._diagnostics.get(kind);
if (!collection) {
return;
}
if (diagnostics.length === 0) {
const existing = collection.get(file);
if (existing.length === 0) {
// No need to update
return;
}
}
collection.set(file, diagnostics);
this.scheduleDiagnosticsUpdate(file);
}
public configFileDiagnosticsReceived(file: vscode.Uri, diagnostics: vscode.Diagnostic[]): void {
this._currentDiagnostics.set(file, diagnostics);
}
public delete(resource: vscode.Uri): void {
this._currentDiagnostics.delete(resource);
this._diagnostics.delete(resource);
}
public getDiagnostics(file: vscode.Uri): vscode.Diagnostic[] {
@ -129,35 +208,24 @@ export class DiagnosticsManager {
private scheduleDiagnosticsUpdate(file: vscode.Uri) {
if (!this._pendingUpdates.has(file)) {
this._pendingUpdates.set(file, setTimeout(() => this.updateCurrentDiagnostics(file), this.updateDelay));
this._pendingUpdates.set(file, setTimeout(() => this.updateCurrentDiagnostics(file), this._updateDelay));
}
}
private updateCurrentDiagnostics(file: vscode.Uri) {
private updateCurrentDiagnostics(file: vscode.Uri): void {
if (this._pendingUpdates.has(file)) {
clearTimeout(this._pendingUpdates.get(file));
this._pendingUpdates.delete(file);
}
if (!this._validate) {
return;
}
const allDiagnostics = [
...this._diagnostics.get(DiagnosticKind.Syntax)!.get(file),
...this._diagnostics.get(DiagnosticKind.Semantic)!.get(file),
...this.getSuggestionDiagnostics(file),
];
this._currentDiagnostics.set(file, allDiagnostics);
const fileDiagnostics = this._diagnostics.get(file);
this._currentDiagnostics.set(file, fileDiagnostics ? fileDiagnostics.getDiagnostics(this._settings) : []);
}
private getSuggestionDiagnostics(file: vscode.Uri) {
return this._diagnostics.get(DiagnosticKind.Suggestion)!.get(file).filter(x => {
if (!this._enableSuggestions) {
// Still show unused
return x.tags && x.tags.indexOf(vscode.DiagnosticTag.Unnecessary) !== -1;
}
return true;
});
private rebuild(): void {
this._currentDiagnostics.clear();
for (const fileDiagnostic of Array.from(this._diagnostics.values)) {
this._currentDiagnostics.set(fileDiagnostic.file, fileDiagnostic.getDiagnostics(this._settings));
}
}
}

View file

@ -26,18 +26,21 @@ class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightPro
}
const args = typeConverters.Position.toFileLocationRequestArgs(file, position);
let items: Proto.OccurrencesResponseItem[] | undefined;
try {
const response = await this.client.execute('occurrences', args, token);
if (response && response.body) {
return response.body
.filter(x => !x.isInString)
.map(documentHighlightFromOccurance);
}
items = response.body;
} catch {
// noop
}
return [];
if (!items) {
return [];
}
return items
.filter(x => !x.isInString)
.map(documentHighlightFromOccurance);
}
}

View file

@ -7,10 +7,8 @@ import * as vscode from 'vscode';
import * as Proto from '../protocol';
import * as PConst from '../protocol.const';
import { ITypeScriptServiceClient } from '../typescriptService';
import API from '../utils/api';
import * as typeConverters from '../utils/typeConverters';
const getSymbolKind = (kind: string): vscode.SymbolKind => {
switch (kind) {
case PConst.Kind.module: return vscode.SymbolKind.Module;
@ -33,60 +31,33 @@ const getSymbolKind = (kind: string): vscode.SymbolKind => {
class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public constructor(
private readonly client: ITypeScriptServiceClient) { }
private readonly client: ITypeScriptServiceClient
) { }
public async provideDocumentSymbols(resource: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[] | vscode.SymbolInformation[]> {
const filepath = this.client.toPath(resource.uri);
if (!filepath) {
return [];
public async provideDocumentSymbols(resource: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[] | undefined> {
const file = this.client.toPath(resource.uri);
if (!file) {
return undefined;
}
const args: Proto.FileRequestArgs = {
file: filepath
};
let tree: Proto.NavigationTree | undefined;
try {
if (this.client.apiVersion.gte(API.v206)) {
const response = await this.client.execute('navtree', args, token);
if (response.body) {
// The root represents the file. Ignore this when showing in the UI
const tree = response.body;
if (tree.childItems) {
const result = new Array<vscode.DocumentSymbol>();
tree.childItems.forEach(item => TypeScriptDocumentSymbolProvider.convertNavTree(resource.uri, result, item));
return result;
}
}
} else {
const response = await this.client.execute('navbar', args, token);
if (response.body) {
const result = new Array<vscode.SymbolInformation>();
const foldingMap: ObjectMap<vscode.SymbolInformation> = Object.create(null);
response.body.forEach(item => TypeScriptDocumentSymbolProvider.convertNavBar(resource.uri, 0, foldingMap, result as vscode.SymbolInformation[], item));
return result;
}
}
return [];
} catch (e) {
return [];
const args: Proto.FileRequestArgs = { file };
const response = await this.client.execute('navtree', args, token);
tree = response.body;
} catch {
return undefined;
}
}
private static convertNavBar(resource: vscode.Uri, indent: number, foldingMap: ObjectMap<vscode.SymbolInformation>, bucket: vscode.SymbolInformation[], item: Proto.NavigationBarItem, containerLabel?: string): void {
const realIndent = indent + item.indent;
const key = `${realIndent}|${item.text}`;
if (realIndent !== 0 && !foldingMap[key] && TypeScriptDocumentSymbolProvider.shouldInclueEntry(item)) {
const result = new vscode.SymbolInformation(item.text,
getSymbolKind(item.kind),
containerLabel ? containerLabel : '',
typeConverters.Location.fromTextSpan(resource, item.spans[0]));
foldingMap[key] = result;
bucket.push(result);
}
if (item.childItems && item.childItems.length > 0) {
for (const child of item.childItems) {
TypeScriptDocumentSymbolProvider.convertNavBar(resource, realIndent + 1, foldingMap, bucket, child, item.text);
}
if (tree && tree.childItems) {
// The root represents the file. Ignore this when showing in the UI
const result: vscode.DocumentSymbol[] = [];
tree.childItems.forEach(item => TypeScriptDocumentSymbolProvider.convertNavTree(resource.uri, result, item));
return result;
}
return undefined;
}
private static convertNavTree(resource: vscode.Uri, bucket: vscode.DocumentSymbol[], item: Proto.NavigationTree): boolean {

View file

@ -10,53 +10,35 @@ import { ConfigurationDependentRegistration } from '../utils/dependentRegistrati
import * as typeConverters from '../utils/typeConverters';
import FileConfigurationManager from './fileConfigurationManager';
class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEditProvider, vscode.OnTypeFormattingEditProvider {
private enabled: boolean = true;
public constructor(
private readonly client: ITypeScriptServiceClient,
private readonly formattingOptionsManager: FileConfigurationManager
) { }
public updateConfiguration(config: vscode.WorkspaceConfiguration): void {
this.enabled = config.get('format.enable', true);
}
public isEnabled(): boolean {
return this.enabled;
}
private async doFormat(
document: vscode.TextDocument,
options: vscode.FormattingOptions,
args: Proto.FormatRequestArgs,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
await this.formattingOptionsManager.ensureConfigurationOptions(document, options, token);
try {
const response = await this.client.execute('format', args, token);
if (response.body) {
return response.body.map(typeConverters.TextEdit.fromCodeEdit);
}
} catch {
// noop
}
return [];
}
public async provideDocumentRangeFormattingEdits(
document: vscode.TextDocument,
range: vscode.Range,
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
): Promise<vscode.TextEdit[] | undefined> {
const file = this.client.toPath(document.uri);
if (!file) {
return [];
return undefined;
}
const args = typeConverters.Range.toFormattingRequestArgs(file, range);
return this.doFormat(document, options, args, token);
await this.formattingOptionsManager.ensureConfigurationOptions(document, options, token);
let edits: Proto.CodeEdit[] | undefined;
try {
const args = typeConverters.Range.toFormattingRequestArgs(file, range);
const response = await this.client.execute('format', args, token);
edits = response.body;
} catch {
// noop
}
return (edits || []).map(typeConverters.TextEdit.fromCodeEdit);
}
public async provideOnTypeFormattingEdits(
@ -66,17 +48,15 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
const filepath = this.client.toPath(document.uri);
if (!filepath) {
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
await this.formattingOptionsManager.ensureConfigurationOptions(document, options, token);
const args: Proto.FormatOnKeyRequestArgs = {
file: filepath,
line: position.line + 1,
offset: position.character + 1,
...typeConverters.Position.toFileLocationRequestArgs(file, position),
key: ch
};
try {

View file

@ -140,17 +140,18 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider {
await this.formattingOptionsManager.ensureConfigurationForDocument(document, undefined);
const args: Proto.GetApplicableRefactorsRequestArgs = typeConverters.Range.toFileRangeRequestArgs(file, rangeOrSelection);
let response: Proto.GetApplicableRefactorsResponse;
let refactorings: Proto.ApplicableRefactorInfo[];
try {
response = await this.client.execute('getApplicableRefactors', args, token);
if (!response || !response.body) {
const response = await this.client.execute('getApplicableRefactors', args, token);
if (!response.body) {
return undefined;
}
refactorings = response.body;
} catch {
return undefined;
}
return this.convertApplicableRefactors(response.body, document, file, rangeOrSelection);
return this.convertApplicableRefactors(refactorings, document, file, rangeOrSelection);
}
private convertApplicableRefactors(

View file

@ -78,7 +78,10 @@ class TscTaskProvider implements vscode.TaskProvider {
private async getAllTsConfigs(token: vscode.CancellationToken): Promise<TSConfig[]> {
const out = new Set<TSConfig>();
const configs = (await this.getTsConfigForActiveFile(token)).concat(await this.getTsConfigsInWorkspace());
const configs = [
...await this.getTsConfigForActiveFile(token),
...await this.getTsConfigsInWorkspace()
];
for (const config of configs) {
if (await exists(config.path)) {
out.add(config);

View file

@ -6,6 +6,13 @@
import * as jsonc from 'jsonc-parser';
import { dirname, join } from 'path';
import * as vscode from 'vscode';
import { flatten } from '../utils/arrays';
function mapNode<R>(node: jsonc.Node | undefined, f: (x: jsonc.Node) => R): R[] {
return node && node.type === 'array' && node.children
? node.children.map(f)
: [];
}
class TsconfigLinkProvider implements vscode.DocumentLinkProvider {
@ -18,34 +25,43 @@ class TsconfigLinkProvider implements vscode.DocumentLinkProvider {
return null;
}
return this.getNodes(root).map(node =>
new vscode.DocumentLink(
this.getRange(document, node),
this.getTarget(document, node)));
return [
this.getExendsLink(document, root),
...this.getFilesLinks(document, root),
...this.getReferencesLinks(document, root)
].filter(x => !!x) as vscode.DocumentLink[];
}
private getNodes(root: jsonc.Node): ReadonlyArray<jsonc.Node> {
const nodes: jsonc.Node[] = [];
const extendsNode = jsonc.findNodeAtLocation(root, ['extends']);
if (this.isPathValue(extendsNode)) {
nodes.push(extendsNode);
}
private getExendsLink(document: vscode.TextDocument, root: jsonc.Node): vscode.DocumentLink | undefined {
return this.pathNodeToLink(document, jsonc.findNodeAtLocation(root, ['extends']));
}
const referencesNode = jsonc.findNodeAtLocation(root, ['references']);
if (referencesNode && referencesNode.type === 'array' && referencesNode.children) {
for (const child of referencesNode.children) {
const path = jsonc.findNodeAtLocation(child, ['path']);
if (this.isPathValue(path)) {
nodes.push(path);
}
}
}
private getFilesLinks(document: vscode.TextDocument, root: jsonc.Node) {
return mapNode(
jsonc.findNodeAtLocation(root, ['files']),
node => this.pathNodeToLink(document, node));
}
return nodes;
private getReferencesLinks(document: vscode.TextDocument, root: jsonc.Node) {
return mapNode(
jsonc.findNodeAtLocation(root, ['references']),
child => this.pathNodeToLink(document, jsonc.findNodeAtLocation(child, ['path'])));
}
private pathNodeToLink(
document: vscode.TextDocument,
node: jsonc.Node | undefined
): vscode.DocumentLink | undefined {
return this.isPathValue(node)
? new vscode.DocumentLink(this.getRange(document, node), this.getTarget(document, node))
: undefined;
}
private isPathValue(extendsNode: jsonc.Node | undefined): extendsNode is jsonc.Node {
return extendsNode && extendsNode.type === 'string' && extendsNode.value;
return extendsNode
&& extendsNode.type === 'string'
&& extendsNode.value
&& !(extendsNode.value as string).includes('*');
}
private getTarget(document: vscode.TextDocument, node: jsonc.Node): vscode.Uri {
@ -68,7 +84,9 @@ export function register() {
const languages = ['json', 'jsonc'];
const selector: vscode.DocumentSelector = ([] as any[]).concat(
...languages.map(language => patterns.map((pattern): vscode.DocumentFilter => ({ language, pattern }))));
const selector: vscode.DocumentSelector = flatten(
languages.map(language =>
patterns.map((pattern): vscode.DocumentFilter => ({ language, pattern }))));
return vscode.languages.registerDocumentLinkProvider(selector, new TsconfigLinkProvider());
}

View file

@ -6,7 +6,7 @@
import { basename } from 'path';
import * as vscode from 'vscode';
import { CachedNavTreeResponse } from './features/baseCodeLensProvider';
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
import { DiagnosticKind } from './features/diagnostics';
import FileConfigurationManager from './features/fileConfigurationManager';
import TypeScriptServiceClient from './typescriptServiceClient';
import { CommandManager } from './utils/commandManager';
@ -22,11 +22,6 @@ const validateSetting = 'validate.enable';
const suggestionSetting = 'suggestionActions.enabled';
export default class LanguageProvider {
private readonly diagnosticsManager: DiagnosticsManager;
private _validate: boolean = true;
private _enableSuggestionDiagnostics: boolean = true;
private readonly disposables: vscode.Disposable[] = [];
constructor(
@ -37,12 +32,6 @@ export default class LanguageProvider {
private readonly typingsStatus: TypingsStatus,
private readonly fileConfigurationManager: FileConfigurationManager
) {
this.client.bufferSyncSupport.onDelete(resource => {
this.diagnosticsManager.delete(resource);
}, null, this.disposables);
this.diagnosticsManager = new DiagnosticsManager(description.diagnosticOwner);
vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this.disposables);
this.configurationChanged();
@ -53,8 +42,6 @@ export default class LanguageProvider {
public dispose(): void {
disposeAll(this.disposables);
this.diagnosticsManager.dispose();
}
@memoize
@ -85,7 +72,7 @@ export default class LanguageProvider {
this.disposables.push((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
this.disposables.push((await import('./features/jsDocCompletions')).register(selector, this.client, this.commandManager));
this.disposables.push((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter));
this.disposables.push((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.diagnosticsManager, this.telemetryReporter));
this.disposables.push((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter));
this.disposables.push((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter));
this.disposables.push((await import('./features/references')).register(selector, this.client));
this.disposables.push((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
@ -120,30 +107,15 @@ export default class LanguageProvider {
}
private updateValidate(value: boolean) {
if (this._validate === value) {
return;
}
this._validate = value;
this.diagnosticsManager.validate = value;
if (value) {
this.triggerAllDiagnostics();
}
this.client.diagnosticsManager.setValidate(this._diagnosticLanguage, value);
}
private updateSuggestionDiagnostics(value: boolean) {
if (this._enableSuggestionDiagnostics === value) {
return;
}
this._enableSuggestionDiagnostics = value;
this.diagnosticsManager.enableSuggestions = value;
if (value) {
this.triggerAllDiagnostics();
}
this.client.diagnosticsManager.setEnableSuggestions(this._diagnosticLanguage, value);
}
public reInitialize(): void {
this.diagnosticsManager.reInitialize();
this.client.diagnosticsManager.reInitialize();
}
public triggerAllDiagnostics(): void {
@ -153,7 +125,7 @@ export default class LanguageProvider {
public diagnosticsReceived(diagnosticsKind: DiagnosticKind, file: vscode.Uri, diagnostics: (vscode.Diagnostic & { reportUnnecessary: any })[]): void {
const config = vscode.workspace.getConfiguration(this.id, file);
const reportUnnecessary = config.get<boolean>('showUnused', true);
this.diagnosticsManager.diagnosticsReceived(diagnosticsKind, file, diagnostics.filter(diag => {
this.client.diagnosticsManager.updateDiagnostics(file, this._diagnosticLanguage, diagnosticsKind, diagnostics.filter(diag => {
if (!reportUnnecessary) {
diag.tags = undefined;
if (diag.reportUnnecessary && diag.severity === vscode.DiagnosticSeverity.Hint) {
@ -165,6 +137,10 @@ export default class LanguageProvider {
}
public configFileDiagnosticsReceived(file: vscode.Uri, diagnostics: vscode.Diagnostic[]): void {
this.diagnosticsManager.configFileDiagnosticsReceived(file, diagnostics);
this.client.diagnosticsManager.configFileDiagnosticsReceived(file, diagnostics);
}
private get _diagnosticLanguage() {
return this.description.diagnosticLanguage;
}
}

View file

@ -19,7 +19,7 @@ import TypeScriptServiceClient from './typescriptServiceClient';
import API from './utils/api';
import { CommandManager } from './utils/commandManager';
import { disposeAll } from './utils/dispose';
import { LanguageDescription } from './utils/languageDescription';
import { LanguageDescription, DiagnosticLanguage } from './utils/languageDescription';
import LogDirectoryProvider from './utils/logDirectoryProvider';
import { TypeScriptServerPlugin } from './utils/plugins';
import * as typeConverters from './utils/typeConverters';
@ -119,7 +119,8 @@ export default class TypeScriptServiceClientHost {
const description: LanguageDescription = {
id: 'typescript-plugins',
modeIds: Array.from(languages.values()),
diagnosticSource: 'ts-plugins',
diagnosticSource: 'ts-plugin',
diagnosticLanguage: DiagnosticLanguage.TypeScript,
diagnosticOwner: 'typescript',
isExternal: true
};

View file

@ -60,7 +60,6 @@ export interface ITypeScriptServiceClient {
execute(command: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.TypeDefinitionResponse>;
execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ReferencesResponse>;
execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: CancellationToken): Promise<Proto.NavtoResponse>;
execute(command: 'navbar', args: Proto.FileRequestArgs, token?: CancellationToken): Promise<Proto.NavBarResponse>;
execute(command: 'format', args: Proto.FormatRequestArgs, token?: CancellationToken): Promise<Proto.FormatResponse>;
execute(command: 'formatonkey', args: Proto.FormatOnKeyRequestArgs, token?: CancellationToken): Promise<Proto.FormatResponse>;
execute(command: 'rename', args: Proto.RenameRequestArgs, token?: CancellationToken): Promise<Proto.RenameResponse>;

View file

@ -9,7 +9,7 @@ import * as path from 'path';
import { CancellationToken, commands, Disposable, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode';
import * as nls from 'vscode-nls';
import BufferSyncSupport from './features/bufferSyncSupport';
import { DiagnosticKind } from './features/diagnostics';
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
import * as Proto from './protocol';
import { ITypeScriptServiceClient } from './typescriptService';
import API from './utils/api';
@ -197,6 +197,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
private readonly disposables: Disposable[] = [];
public readonly bufferSyncSupport: BufferSyncSupport;
public readonly diagnosticsManager: DiagnosticsManager;
constructor(
private readonly workspaceState: Memento,
@ -231,6 +232,11 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
this.bufferSyncSupport = new BufferSyncSupport(this, allModeIds);
this.onReady(() => { this.bufferSyncSupport.listen(); });
this.diagnosticsManager = new DiagnosticsManager('typescript');
this.bufferSyncSupport.onDelete(resource => {
this.diagnosticsManager.delete(resource);
}, null, this.disposables);
workspace.onDidChangeConfiguration(() => {
const oldConfiguration = this._configuration;
this._configuration = TypeScriptServiceConfiguration.loadFromWorkspace();
@ -974,7 +980,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
}
if (this.apiVersion.gte(API.v222)) {
this.cancellationPipeName = electron.getTempSock('tscancellation');
this.cancellationPipeName = electron.getTempFile('tscancellation');
args.push('--cancellationPipeName', this.cancellationPipeName + '*');
}

View file

@ -14,4 +14,8 @@ export function equals<T>(one: T[], other: T[], itemEquals: (a: T, b: T) => bool
}
return true;
}
export function flatten<T>(arr: T[][]): T[] {
return [].concat.apply([], arr);
}

View file

@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import Logger from './logger';
import { getTempFile, makeRandomHexString } from './temp';
import * as temp from './temp';
import path = require('path');
import os = require('os');
import fs = require('fs');
import net = require('net');
import cp = require('child_process');
@ -15,13 +15,25 @@ export interface IForkOptions {
execArgv?: string[];
}
export function getTempSock(prefix: string): string {
const fullName = `vscode-${prefix}-${makeRandomHexString(20)}`;
return getTempFile(fullName + '.sock');
const getRootTempDir = (() => {
let dir: string | undefined;
return () => {
if (!dir) {
dir = temp.getTempFile(`vscode-typescript`);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
}
return dir;
};
})();
export function getTempFile(prefix: string): string {
return path.join(getRootTempDir(), `${prefix}-${temp.makeRandomHexString(20)}.tmp`);
}
function generatePipeName(): string {
return getPipeName(makeRandomHexString(40));
return getPipeName(temp.makeRandomHexString(40));
}
function getPipeName(name: string): string {
@ -31,7 +43,7 @@ function getPipeName(name: string): string {
}
// Mac/Unix: use socket file
return path.join(os.tmpdir(), fullName + '.sock');
return path.join(getRootTempDir(), fullName + '.sock');
}
function generatePatchedEnv(

View file

@ -4,26 +4,36 @@
*--------------------------------------------------------------------------------------------*/
import * as languageModeIds from './languageModeIds';
export enum DiagnosticLanguage {
JavaScript,
TypeScript
}
export const allDiagnosticLangauges = [DiagnosticLanguage.JavaScript, DiagnosticLanguage.TypeScript];
export interface LanguageDescription {
readonly id: string;
readonly diagnosticOwner: string;
readonly diagnosticSource: string;
readonly diagnosticLanguage: DiagnosticLanguage;
readonly modeIds: string[];
readonly configFile?: string;
readonly isExternal?: boolean;
readonly diagnosticOwner: string;
}
export const standardLanguageDescriptions: LanguageDescription[] = [
{
id: 'typescript',
diagnosticSource: 'ts',
diagnosticOwner: 'typescript',
diagnosticSource: 'ts',
diagnosticLanguage: DiagnosticLanguage.TypeScript,
modeIds: [languageModeIds.typescript, languageModeIds.typescriptreact],
configFile: 'tsconfig.json'
}, {
id: 'javascript',
diagnosticSource: 'ts',
diagnosticOwner: 'typescript',
diagnosticSource: 'ts',
diagnosticLanguage: DiagnosticLanguage.JavaScript,
modeIds: [languageModeIds.javascript, languageModeIds.javascriptreact],
configFile: 'jsconfig.json'
}

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/atom/language-xml/commit/27352842917b911383122bdcf98ed0d69d55c179",
"version": "https://github.com/atom/language-xml/commit/bd810deb404a12bea8ec5799fda2909349ba2654",
"name": "XML",
"scopeName": "text.xml",
"patterns": [
@ -350,14 +350,38 @@
]
},
"comments": {
"begin": "<[!%]--",
"captures": {
"0": {
"name": "punctuation.definition.comment.xml"
"patterns": [
{
"begin": "<%--",
"captures": {
"0": {
"name": "punctuation.definition.comment.xml"
},
"end": "--%>",
"name": "comment.block.xml"
}
},
{
"begin": "<!--",
"captures": {
"0": {
"name": "punctuation.definition.comment.xml"
}
},
"end": "-->",
"name": "comment.block.xml",
"patterns": [
{
"begin": "--(?!>)",
"captures": {
"0": {
"name": "invalid.illegal.bad-comments-or-CDATA.xml"
}
}
}
]
}
},
"end": "--%?>",
"name": "comment.block.xml"
]
}
}
}

View file

@ -2,6 +2,6 @@
# yarn lockfile v1
typescript@3.0.1-insiders.20180713:
version "3.0.1-insiders.20180713"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1-insiders.20180713.tgz#02775b5197ab02b79ed5b84e7483c18ed164e55e"
typescript@3.0.1-insiders.20180723:
version "3.0.1-insiders.20180723"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1-insiders.20180723.tgz#266fbafb349a6429777ab3525cda3bb0a2adc661"

View file

@ -15,12 +15,12 @@ const compilation = require('./build/lib/compilation');
// Fast compile for development time
gulp.task('clean-client', util.rimraf('out'));
gulp.task('compile-client', ['clean-client'], compilation.compileTask('out', false));
gulp.task('compile-client', ['clean-client'], compilation.compileTask('src', 'out', false));
gulp.task('watch-client', ['clean-client'], compilation.watchTask('out', false));
// Full compile, including nls and inline sources in sourcemaps, for build
gulp.task('clean-client-build', util.rimraf('out-build'));
gulp.task('compile-client-build', ['clean-client-build'], compilation.compileTask('out-build', true));
gulp.task('compile-client-build', ['clean-client-build'], compilation.compileTask('src', 'out-build', true));
gulp.task('watch-client-build', ['clean-client-build'], compilation.watchTask('out-build', true));
// Default

View file

@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.26.0",
"distro": "655112e16611a8427ba96dbd6de2b05ecf2e3f6b",
"distro": "4b5c6aa6ea6f222d62d08ca5653049b200be93a5",
"author": {
"name": "Microsoft Corporation"
},
@ -51,7 +51,7 @@
"vscode-ripgrep": "^1.0.1",
"vscode-textmate": "^4.0.1",
"vscode-uri": "1.0.5",
"vscode-xterm": "3.6.0-beta3",
"vscode-xterm": "3.6.0-beta5",
"yauzl": "^2.9.1"
},
"devDependencies": {

View file

@ -69,7 +69,10 @@ loader.config({
nodeCachedDataDir: process.env['VSCODE_NODE_CACHED_DATA_DIR_' + process.pid]
});
loader.define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code
if (process.env['ELECTRON_RUN_AS_NODE'] || process.versions.electron) {
// running in Electron
loader.define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code
}
if (nlsConfig.pseudo) {
loader(['vs/nls'], function (nlsPlugin) {

View file

@ -114,13 +114,13 @@ export class BreadcrumbsWidget {
}
layout(dim: dom.Dimension): void {
if (!dim) {
this._scrollable.scanDomNode();
} else {
if (dim) {
this._domNode.style.width = `${dim.width}px`;
this._domNode.style.height = `${dim.height}px`;
this._scrollable.scanDomNode();
}
this._scrollable.setRevealOnScroll(false);
this._scrollable.scanDomNode();
this._scrollable.setRevealOnScroll(true);
}
style(style: IBreadcrumbsWidgetStyles): void {
@ -206,7 +206,9 @@ export class BreadcrumbsWidget {
private _reveal(nth: number): void {
const node = this._nodes[nth];
if (node) {
this._scrollable.setRevealOnScroll(false);
this._scrollable.setScrollPosition({ scrollLeft: node.offsetLeft });
this._scrollable.setRevealOnScroll(true);
}
}

View file

@ -8,7 +8,7 @@
import 'vs/css!./contextview';
import { Builder, $ } from 'vs/base/browser/builder';
import * as DOM from 'vs/base/browser/dom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
export interface IAnchor {
x: number;
@ -116,11 +116,9 @@ export class ContextView {
this.$view = $('.context-view').hide();
this.setContainer(container);
this.toDispose = [{
dispose: () => {
this.setContainer(null);
}
}];
this.toDispose = [toDisposable(() => {
this.setContainer(null);
})];
this.toDisposeOnClean = null;
}

View file

@ -22,6 +22,7 @@ export interface IIconLabelCreationOptions {
export interface IIconLabelValueOptions {
title?: string;
descriptionTitle?: string;
hideIcon?: boolean;
extraClasses?: string[];
italic?: boolean;
matches?: IMatch[];

View file

@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./list';
import { localize } from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import { range, firstIndex } from 'vs/base/common/arrays';
@ -355,6 +356,11 @@ class DOMFocusController<T> implements IDisposable {
return;
}
const style = window.getComputedStyle(tabIndexElement);
if (style.visibility === 'hidden' || style.display === 'none') {
return;
}
e.preventDefault();
e.stopPropagation();
tabIndexElement.focus();
@ -934,7 +940,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.onSelectionChange(this._onSelectionChange, this, this.disposables);
if (options.ariaLabel) {
this.view.domNode.setAttribute('aria-label', options.ariaLabel);
this.view.domNode.setAttribute('aria-label', localize('aria list', "{0}. Use the navigation keys to navigate.", options.ariaLabel));
}
this.style(options);

View file

@ -40,15 +40,18 @@
flex: 1 1 auto;
display: -ms-flexbox;
display: flex;
height: 2.6em;
align-items: center;
}
.monaco-menu .monaco-action-bar.vertical .action-label {
-ms-flex: 1 1 auto;
flex: 1 1 auto;
text-decoration: none;
padding: 0.8em 1em;
line-height: 1.1em;
padding: 0 1em;
background: none;
font-size: inherit;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .keybinding,
@ -56,15 +59,12 @@
display: inline-block;
-ms-flex: 2 1 auto;
flex: 2 1 auto;
padding: 0.8em 1em;
line-height: 1.1em;
font-size: 12px;
padding: 0 1em;
text-align: right;
font-size: inherit;
line-height: 1;
}
.monaco-menu .monaco-action-bar.vertical .submenu-indicator {
padding: 0.8em .5em;
}
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .keybinding,
.monaco-menu .monaco-action-bar.vertical .action-item.disabled .submenu-indicator {

View file

@ -163,6 +163,8 @@ export abstract class AbstractScrollableElement extends Widget {
private readonly _hideTimeout: TimeoutTimer;
private _shouldRender: boolean;
private _revealOnScroll: boolean;
private readonly _onScroll = this._register(new Emitter<ScrollEvent>());
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
@ -221,6 +223,8 @@ export abstract class AbstractScrollableElement extends Widget {
this._mouseIsOver = false;
this._shouldRender = true;
this._revealOnScroll = true;
}
public dispose(): void {
@ -286,6 +290,10 @@ export abstract class AbstractScrollableElement extends Widget {
}
}
public setRevealOnScroll(value: boolean) {
this._revealOnScroll = value;
}
// -------------------- mouse wheel scrolling --------------------
private _setListeningToMouseWheel(shouldListen: boolean): void {
@ -382,7 +390,9 @@ export abstract class AbstractScrollableElement extends Widget {
this._shouldRender = true;
}
this._reveal();
if (this._revealOnScroll) {
this._reveal();
}
if (!this._options.lazyRender) {
this._render();

View file

@ -84,7 +84,7 @@ export function getBaseLabel(resource: URI | string): string {
resource = URI.file(resource);
}
const base = pathsBasename(resource.fsPath) || resource.fsPath /* can be empty string if '/' is passed in */;
const base = pathsBasename(resource.path) || (resource.scheme === Schemas.file ? resource.fsPath : resource.path) /* can be empty string if '/' is passed in */;
// convert c: => C:
if (hasDriveLetter(base)) {

View file

@ -7,6 +7,18 @@
import * as paths from 'vs/base/common/paths';
import uri from 'vs/base/common/uri';
import { equalsIgnoreCase } from 'vs/base/common/strings';
import { Schemas } from 'vs/base/common/network';
import { isLinux } from 'vs/base/common/platform';
export function getComparisonKey(resource: uri): string {
return hasToIgnoreCase(resource) ? resource.toString().toLowerCase() : resource.toString();
}
export function hasToIgnoreCase(resource: uri): boolean {
// A file scheme resource is in the same platform as code, so ignore case for non linux platforms
// Resource can be from another platform. Lowering the case as an hack. Should come from File system provider
return resource.scheme === Schemas.file ? !isLinux : true;
}
export function basenameOrAuthority(resource: uri): string {
return paths.basename(resource.path) || resource.authority;

View file

@ -260,7 +260,8 @@ export class ChannelClient implements IChannelClient, IDisposable {
let uninitializedPromise: TPromise<any> | null = null;
const emitter = new Emitter<any>({
onFirstListenerAdd: () => {
uninitializedPromise = this.whenInitialized().then(() => {
uninitializedPromise = this.whenInitialized();
uninitializedPromise.then(() => {
uninitializedPromise = null;
this.send(request.raw);
});

View file

@ -150,6 +150,7 @@ export class Client implements IChannelClient, IDisposable {
}
this.activeRequests.splice(this.activeRequests.indexOf(listener), 1);
listener.dispose();
if (this.activeRequests.length === 0) {
this.disposeDelayer.trigger(() => this.disposeClient());

View file

@ -12,6 +12,8 @@ import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient }
import { join } from 'path';
import { tmpdir } from 'os';
import { generateUuid } from 'vs/base/common/uuid';
import { IDisposable } from 'vs/base/common/lifecycle';
import { TimeoutTimer } from 'vs/base/common/async';
export function generateRandomPipeName(): string {
const randomSuffix = generateUuid();
@ -23,17 +25,28 @@ export function generateRandomPipeName(): string {
}
}
export class Protocol implements IMessagePassingProtocol {
export class Protocol implements IDisposable, IMessagePassingProtocol {
private static readonly _headerLen = 17;
private static readonly _headerLen = 5;
private _isDisposed: boolean;
private _chunks: Buffer[];
private _firstChunkTimer: TimeoutTimer;
private _socketDataListener: (data: Buffer) => void;
private _socketEndListener: () => void;
private _socketCloseListener: () => void;
private _onMessage = new Emitter<any>();
readonly onMessage: Event<any> = this._onMessage.event;
constructor(private _socket: Socket, firstDataChunk?: Buffer) {
private _onClose = new Emitter<void>();
readonly onClose: Event<void> = this._onClose.event;
constructor(private _socket: Socket, firstDataChunk?: Buffer) {
this._isDisposed = false;
this._chunks = [];
let chunks: Buffer[] = [];
let totalLength = 0;
const state = {
@ -44,16 +57,16 @@ export class Protocol implements IMessagePassingProtocol {
const acceptChunk = (data: Buffer) => {
chunks.push(data);
this._chunks.push(data);
totalLength += data.length;
while (totalLength > 0) {
if (state.readHead) {
// expecting header -> read 17bytes for header
// expecting header -> read 5bytes for header
// information: `bodyIsJson` and `bodyLen`
if (totalLength >= Protocol._headerLen) {
const all = Buffer.concat(chunks);
const all = Buffer.concat(this._chunks);
state.bodyIsJson = all.readInt8(0) === 1;
state.bodyLen = all.readInt32BE(1);
@ -61,7 +74,7 @@ export class Protocol implements IMessagePassingProtocol {
const rest = all.slice(Protocol._headerLen);
totalLength = rest.length;
chunks = [rest];
this._chunks = [rest];
} else {
break;
@ -73,21 +86,27 @@ export class Protocol implements IMessagePassingProtocol {
// the actual message or wait for more data
if (totalLength >= state.bodyLen) {
const all = Buffer.concat(chunks);
const all = Buffer.concat(this._chunks);
let message = all.toString('utf8', 0, state.bodyLen);
if (state.bodyIsJson) {
message = JSON.parse(message);
}
this._onMessage.fire(message);
// ensure the public getBuffer returns a valid value if invoked from the event listeners
const rest = all.slice(state.bodyLen);
totalLength = rest.length;
chunks = [rest];
this._chunks = [rest];
state.bodyIsJson = false;
state.bodyLen = -1;
state.readHead = true;
this._onMessage.fire(message);
if (this._isDisposed) {
// check if an event listener lead to our disposal
break;
}
} else {
break;
}
@ -103,14 +122,43 @@ export class Protocol implements IMessagePassingProtocol {
}
};
_socket.on('data', (data: Buffer) => {
// Make sure to always handle the firstDataChunk if no more `data` event comes in
this._firstChunkTimer = new TimeoutTimer();
this._firstChunkTimer.setIfNotSet(() => {
acceptFirstDataChunk();
}, 0);
this._socketDataListener = (data: Buffer) => {
acceptFirstDataChunk();
acceptChunk(data);
});
};
_socket.on('data', this._socketDataListener);
_socket.on('end', () => {
this._socketEndListener = () => {
acceptFirstDataChunk();
});
};
_socket.on('end', this._socketEndListener);
this._socketCloseListener = () => {
this._onClose.fire();
};
_socket.once('close', this._socketCloseListener);
}
public dispose(): void {
this._isDisposed = true;
this._firstChunkTimer.dispose();
this._socket.removeListener('data', this._socketDataListener);
this._socket.removeListener('end', this._socketEndListener);
this._socket.removeListener('close', this._socketCloseListener);
}
public end(): void {
this._socket.end();
}
public getBuffer(): Buffer {
return Buffer.concat(this._chunks);
}
public send(message: any): void {
@ -123,10 +171,10 @@ export class Protocol implements IMessagePassingProtocol {
// ensure string
if (typeof message !== 'string') {
message = JSON.stringify(message);
header.writeInt8(1, 0);
header.writeInt8(1, 0, true);
}
const data = Buffer.from(message);
header.writeInt32BE(data.length, 1);
header.writeInt32BE(data.length, 1, true);
this._writeSoon(header, data);
}
@ -193,18 +241,19 @@ export class Server extends IPCServer {
export class Client extends IPCClient {
private _onClose = new Emitter<void>();
get onClose(): Event<void> { return this._onClose.event; }
public static fromSocket(socket: Socket, id: string): Client {
return new Client(new Protocol(socket), id);
}
constructor(private socket: Socket, id: string) {
super(new Protocol(socket), id);
socket.once('close', () => this._onClose.fire());
get onClose(): Event<void> { return this.protocol.onClose; }
constructor(private protocol: Protocol, id: string) {
super(protocol, id);
}
dispose(): void {
super.dispose();
this.socket.end();
this.socket = null;
this.protocol.end();
}
}
@ -229,7 +278,7 @@ export function connect(hook: any, clientId: string): TPromise<Client> {
return new TPromise<Client>((c, e) => {
const socket = createConnection(hook, () => {
socket.removeListener('error', e);
c(new Client(socket, clientId));
c(Client.fromSocket(socket, clientId));
});
socket.once('error', e);

View file

@ -87,4 +87,39 @@ suite('IPC, Socket Protocol', () => {
});
});
});
test('can devolve to a socket and evolve again without losing data', () => {
let resolve: (v: void) => void;
let result = new TPromise<void>((_resolve, _reject) => {
resolve = _resolve;
});
const sender = new Protocol(stream);
const receiver1 = new Protocol(stream);
assert.equal(stream.listenerCount('data'), 2);
assert.equal(stream.listenerCount('end'), 2);
receiver1.onMessage((msg) => {
assert.equal(msg.value, 1);
let buffer = receiver1.getBuffer();
receiver1.dispose();
assert.equal(stream.listenerCount('data'), 1);
assert.equal(stream.listenerCount('end'), 1);
const receiver2 = new Protocol(stream, buffer);
receiver2.onMessage((msg) => {
assert.equal(msg.value, 2);
resolve(void 0);
});
});
const msg1 = { value: 1 };
const msg2 = { value: 2 };
sender.send(msg1);
sender.send(msg2);
return result;
});
});

View file

@ -501,7 +501,8 @@ export class QuickOpenModel implements
IModel<QuickOpenEntry>,
IDataSource<QuickOpenEntry>,
IFilter<QuickOpenEntry>,
IRunner<QuickOpenEntry>
IRunner<QuickOpenEntry>,
IAccessiblityProvider<QuickOpenEntry>
{
private _entries: QuickOpenEntry[];
private _dataSource: IDataSource<QuickOpenEntry>;

View file

@ -109,13 +109,6 @@ export interface ITree {
*/
collapseAll(elements?: any[], recursive?: boolean): WinJS.Promise;
/**
* Collapses several elements.
* Collapses all elements at the greatest tree depth that has expanded elements.
* The returned promise returns a boolean for whether the elements were collapsed or not.
*/
collapseDeepestExpandedLevel(): WinJS.Promise;
/**
* Toggles an element's expansion state.
*/

View file

@ -184,10 +184,6 @@ export class Tree implements _.ITree {
return this.model.collapseAll(elements, recursive);
}
public collapseDeepestExpandedLevel(): WinJS.Promise {
return this.model.collapseDeepestExpandedLevel();
}
public toggleExpansion(element: any, recursive: boolean = false): WinJS.Promise {
return this.model.toggleExpansion(element, recursive);
}

View file

@ -559,17 +559,6 @@ export class Item {
return result;
}
public getChildren(): Item[] {
var child = this.firstChild;
var results = [];
while (child) {
results.push(child);
child = child.next;
}
return results;
}
private isAncestorOf(item: Item): boolean {
while (item) {
if (item.id === this.id) {
@ -1040,27 +1029,6 @@ export class TreeModel {
return WinJS.Promise.join(promises);
}
public collapseDeepestExpandedLevel(): WinJS.Promise {
var levelToCollapse = this.findDeepestExpandedLevel(this.input, 0);
var items = [this.input];
for (var i = 0; i < levelToCollapse; i++) {
items = arrays.flatten(items.map(node => node.getChildren()));
}
var promises = items.map(child => this.collapse(child, false));
return WinJS.Promise.join(promises);
}
private findDeepestExpandedLevel(item: Item, currentLevel: number): number {
var expandedChildren = item.getChildren().filter(child => child.isExpanded());
if (!expandedChildren.length) {
return currentLevel;
}
return Math.max(...expandedChildren.map(child => this.findDeepestExpandedLevel(child, currentLevel + 1)));
}
public toggleExpansion(element: any, recursive: boolean = false): WinJS.Promise {
return this.isExpanded(element) ? this.collapse(element, recursive) : this.expand(element);
}

View file

@ -220,7 +220,7 @@ export class ViewItem implements IViewItem {
this.element.removeAttribute('id');
}
if (this.model.hasChildren()) {
this.element.setAttribute('aria-expanded', String(!!this.model.isExpanded()));
this.element.setAttribute('aria-expanded', String(!!this._styles['expanded']));
} else {
this.element.removeAttribute('aria-expanded');
}

View file

@ -613,23 +613,6 @@ suite('TreeModel - Expansion', () => {
});
});
test('collapseDeepestExpandedLevel', () => {
return model.setInput(SAMPLE.DEEP2).then(() => {
return model.expand(SAMPLE.DEEP2.children[0]).then(() => {
return model.expand(SAMPLE.DEEP2.children[0].children[0]).then(() => {
assert(model.isExpanded(SAMPLE.DEEP2.children[0]));
assert(model.isExpanded(SAMPLE.DEEP2.children[0].children[0]));
return model.collapseDeepestExpandedLevel().then(() => {
assert(model.isExpanded(SAMPLE.DEEP2.children[0]));
assert(!model.isExpanded(SAMPLE.DEEP2.children[0].children[0]));
});
});
});
});
});
test('auto expand single child folders', () => {
return model.setInput(SAMPLE.DEEP).then(() => {
return model.expand(SAMPLE.DEEP.children[0]).then(() => {

View file

@ -54,3 +54,7 @@ export function testRepeat(n: number, description: string, callback: (this: any,
test(`${description} (iteration ${i})`, callback);
}
}
export function testRepeatOnly(n: number, description: string, callback: (this: any, done: MochaDone) => any): void {
suite.only('repeat', () => testRepeat(n, description, callback));
}

View file

@ -86,7 +86,7 @@ export class IssueReporter extends Disposable {
vscodeVersion: `${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`,
os: `${os.type()} ${os.arch()} ${os.release()}`
},
extensionsDisabled: this.environmentService.disableExtensions,
extensionsDisabled: !!this.environmentService.disableExtensions,
});
this.previewButton = new Button(document.getElementById('issue-reporter'));

View file

@ -154,14 +154,14 @@ export class CodeApplication {
});
});
let macOpenFiles: string[] = [];
let macOpenFileURIs: URI[] = [];
let runningTimeout: number = null;
app.on('open-file', (event: Event, path: string) => {
this.logService.trace('App#open-file: ', path);
event.preventDefault();
// Keep in array because more might come!
macOpenFiles.push(path);
macOpenFileURIs.push(URI.file(path));
// Clear previous handler if any
if (runningTimeout !== null) {
@ -175,10 +175,10 @@ export class CodeApplication {
this.windowsMainService.open({
context: OpenContext.DOCK /* can also be opening from finder while app is running */,
cli: this.environmentService.args,
pathsToOpen: macOpenFiles,
urisToOpen: macOpenFileURIs,
preferNewWindow: true /* dropping on the dock or opening from finder prefers to open in a new window */
});
macOpenFiles = [];
macOpenFileURIs = [];
runningTimeout = null;
}
}, 100);
@ -462,10 +462,10 @@ export class CodeApplication {
// Open our first window
const macOpenFiles = (<any>global).macOpenFiles as string[];
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
if (args['new-window'] && args._.length === 0) {
if (args['new-window'] && args._.length === 0 && (args['folder-uri'] || []).length === 0) {
this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
} else if (macOpenFiles && macOpenFiles.length && (!args._ || !args._.length)) {
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, pathsToOpen: macOpenFiles, initialStartup: true }); // mac: open-file event received on startup
} else if (macOpenFiles && macOpenFiles.length && (!args._ || !args._.length || !args['folder-uri'] || !args['folder-uri'].length)) {
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => URI.file(file)), initialStartup: true }); // mac: open-file event received on startup
} else {
this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!args._.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
}

View file

@ -16,6 +16,7 @@ import { repeat, pad } from 'vs/base/common/strings';
import { isWindows } from 'vs/base/common/platform';
import { app } from 'electron';
import { basename } from 'path';
import URI from 'vs/base/common/uri';
export interface VersionInfo {
vscodeVersion: string;
@ -50,29 +51,35 @@ export function getPerformanceInfo(info: IMainProcessInfo): Promise<PerformanceI
// Workspace Stats
const workspaceStatPromises = [];
if (info.windows.some(window => window.folders && window.folders.length > 0)) {
if (info.windows.some(window => window.folderURIs && window.folderURIs.length > 0)) {
info.windows.forEach(window => {
if (window.folders.length === 0) {
if (window.folderURIs.length === 0) {
return;
}
workspaceInfoMessages.push(`| Window (${window.title})`);
window.folders.forEach(folder => {
workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(async stats => {
window.folderURIs.forEach(uriComponents => {
const folderUri = URI.revive(uriComponents);
if (folderUri.scheme === 'file') {
const folder = folderUri.fsPath;
workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(async stats => {
let countMessage = `${stats.fileCount} files`;
if (stats.maxFilesReached) {
countMessage = `more than ${countMessage}`;
}
workspaceInfoMessages.push(`| Folder (${basename(folder)}): ${countMessage}`);
workspaceInfoMessages.push(formatWorkspaceStats(stats));
let countMessage = `${stats.fileCount} files`;
if (stats.maxFilesReached) {
countMessage = `more than ${countMessage}`;
}
workspaceInfoMessages.push(`| Folder (${basename(folder)}): ${countMessage}`);
workspaceInfoMessages.push(formatWorkspaceStats(stats));
const launchConfigs = await collectLaunchConfigs(folder);
if (launchConfigs.length > 0) {
workspaceInfoMessages.push(formatLaunchConfigs(launchConfigs));
}
}));
const launchConfigs = await collectLaunchConfigs(folder);
if (launchConfigs.length > 0) {
workspaceInfoMessages.push(formatLaunchConfigs(launchConfigs));
}
}));
} else {
workspaceInfoMessages.push(`| Folder (${folderUri.toString()}): RPerformance stats not available.`);
}
});
});
}
@ -129,33 +136,39 @@ export function printDiagnostics(info: IMainProcessInfo): Promise<any> {
// Workspace Stats
const workspaceStatPromises = [];
if (info.windows.some(window => window.folders && window.folders.length > 0)) {
if (info.windows.some(window => window.folderURIs && window.folderURIs.length > 0)) {
console.log('');
console.log('Workspace Stats: ');
info.windows.forEach(window => {
if (window.folders.length === 0) {
if (window.folderURIs.length === 0) {
return;
}
console.log(`| Window (${window.title})`);
window.folders.forEach(folder => {
workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(async stats => {
let countMessage = `${stats.fileCount} files`;
if (stats.maxFilesReached) {
countMessage = `more than ${countMessage}`;
}
console.log(`| Folder (${basename(folder)}): ${countMessage}`);
console.log(formatWorkspaceStats(stats));
await collectLaunchConfigs(folder).then(launchConfigs => {
if (launchConfigs.length > 0) {
console.log(formatLaunchConfigs(launchConfigs));
window.folderURIs.forEach(uriComponents => {
const folderUri = URI.revive(uriComponents);
if (folderUri.scheme === 'file') {
const folder = folderUri.fsPath;
workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(async stats => {
let countMessage = `${stats.fileCount} files`;
if (stats.maxFilesReached) {
countMessage = `more than ${countMessage}`;
}
});
}).catch(error => {
console.log(`| Error: Unable to collect workpsace stats for folder ${folder} (${error.toString()})`);
}));
console.log(`| Folder (${basename(folder)}): ${countMessage}`);
console.log(formatWorkspaceStats(stats));
await collectLaunchConfigs(folder).then(launchConfigs => {
if (launchConfigs.length > 0) {
console.log(formatLaunchConfigs(launchConfigs));
}
});
}).catch(error => {
console.log(`| Error: Unable to collect workspace stats for folder ${folder} (${error.toString()})`);
}));
} else {
console.log(`| Folder (${folderUri.toString()}): Workspace stats not available.`);
}
});
});
}

View file

@ -16,9 +16,8 @@ import { OpenContext, IWindowSettings } from 'vs/platform/windows/common/windows
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
import { whenDeleted } from 'vs/base/node/pfs';
import { IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces';
import { Schemas } from 'vs/base/common/network';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import URI from 'vs/base/common/uri';
import URI, { UriComponents } from 'vs/base/common/uri';
import { BrowserWindow } from 'electron';
import { Event } from 'vs/base/common/event';
@ -33,7 +32,7 @@ export interface IStartArguments {
export interface IWindowInfo {
pid: number;
title: string;
folders: string[];
folderURIs: UriComponents[];
}
export interface IMainProcessInfo {
@ -179,7 +178,7 @@ export class LaunchService implements ILaunchService {
}
// Start without file/folder arguments
else if (args._.length === 0) {
else if (args._.length === 0 && (args['folder-uri'] || []).length === 0) {
let openNewWindow = false;
// Force new window
@ -275,27 +274,25 @@ export class LaunchService implements ILaunchService {
}
private codeWindowToInfo(window: ICodeWindow): IWindowInfo {
const folders: string[] = [];
const folderURIs: URI[] = [];
if (window.openedFolderPath) {
folders.push(window.openedFolderPath);
if (window.openedFolderUri) {
folderURIs.push(window.openedFolderUri);
} else if (window.openedWorkspace) {
const rootFolders = this.workspacesMainService.resolveWorkspaceSync(window.openedWorkspace.configPath).folders;
rootFolders.forEach(root => {
if (root.uri.scheme === Schemas.file) { // todo@remote signal remote folders?
folders.push(root.uri.fsPath);
}
folderURIs.push(root.uri);
});
}
return this.browserWindowToInfo(window.win, folders);
return this.browserWindowToInfo(window.win, folderURIs);
}
private browserWindowToInfo(win: BrowserWindow, folders: string[] = []): IWindowInfo {
private browserWindowToInfo(win: BrowserWindow, folderURIs: URI[] = []): IWindowInfo {
return {
pid: win.webContents.getOSProcessId(),
title: win.getTitle(),
folders
folderURIs
} as IWindowInfo;
}
}

View file

@ -20,8 +20,9 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel }
import { KeybindingsResolver } from 'vs/code/electron-main/keyboard';
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IMenubarData, IMenubarMenuItemAction, IMenubarMenuItemSeparator } from 'vs/platform/menubar/common/menubar';
import URI from 'vs/base/common/uri';
// interface IExtensionViewlet {
// id: string;
@ -513,13 +514,16 @@ export class Menubar {
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem {
let label: string;
let path: string;
if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
path = workspace;
} else {
let uri: URI;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, { verbose: true }));
uri = workspace;
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true });
path = workspace.configPath;
uri = URI.file(workspace.configPath);
} else {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
uri = URI.file(workspace);
}
return new MenuItem(this.likeAction(commandId, {
@ -529,12 +533,13 @@ export class Menubar {
const success = this.windowsMainService.open({
context: OpenContext.MENU,
cli: this.environmentService.args,
pathsToOpen: [path], forceNewWindow: openInNewWindow,
urisToOpen: [uri],
forceNewWindow: openInNewWindow,
forceOpenWorkspaceAsFile: isFile
}).length > 0;
if (!success) {
this.historyMainService.removeFromRecentlyOpened([isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath]);
this.historyMainService.removeFromRecentlyOpened([workspace]);
}
}
}, false));

View file

@ -22,7 +22,8 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel }
import { KeybindingsResolver } from 'vs/code/electron-main/keyboard';
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import URI from 'vs/base/common/uri';
interface IMenuItemClickHandler {
inDevTools: (contents: Electron.WebContents) => void;
@ -194,7 +195,7 @@ export class CodeMenu {
private updateWorkspaceMenuItems(): void {
const window = this.windowsMainService.getLastActiveWindow();
const isInWorkspaceContext = window && !!window.openedWorkspace;
const isInFolderContext = window && !!window.openedFolderPath;
const isInFolderContext = window && !!window.openedFolderUri;
this.closeWorkspace.visible = isInWorkspaceContext;
this.closeFolder.visible = !isInWorkspaceContext;
@ -489,13 +490,16 @@ export class CodeMenu {
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem {
let label: string;
let path: string;
if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService));
path = workspace;
} else {
let uri: URI;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, { verbose: true }));
uri = workspace;
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true });
path = workspace.configPath;
uri = URI.file(workspace.configPath);
} else {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
uri = URI.file(workspace);
}
return new MenuItem(this.likeAction(commandId, {
@ -505,12 +509,12 @@ export class CodeMenu {
const success = this.windowsMainService.open({
context: OpenContext.MENU,
cli: this.environmentService.args,
pathsToOpen: [path], forceNewWindow: openInNewWindow,
urisToOpen: [uri], forceNewWindow: openInNewWindow,
forceOpenWorkspaceAsFile: isFile
}).length > 0;
if (!success) {
this.historyMainService.removeFromRecentlyOpened([isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath]);
this.historyMainService.removeFromRecentlyOpened([workspace]);
}
}
}, false));
@ -766,6 +770,7 @@ export class CodeMenu {
const toggleMinimap = this.createMenuItem(nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap"), 'editor.action.toggleMinimap');
const toggleRenderWhitespace = this.createMenuItem(nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"), 'editor.action.toggleRenderWhitespace');
const toggleRenderControlCharacters = this.createMenuItem(nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"), 'editor.action.toggleRenderControlCharacter');
const toggleBreadcrumbs = this.createMenuItem(nls.localize({ key: 'miToggleBreadcrumbs', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breadcrumbs"), 'breadcrumbs.toggle');
arrays.coalesce([
commands,
@ -788,7 +793,8 @@ export class CodeMenu {
toggleWordWrap,
toggleMinimap,
toggleRenderWhitespace,
toggleRenderControlCharacters
toggleRenderControlCharacters,
toggleBreadcrumbs
]).forEach(item => viewMenu.append(item));
}

View file

@ -297,8 +297,8 @@ export class CodeWindow implements ICodeWindow {
return this.currentConfig ? this.currentConfig.workspace : void 0;
}
get openedFolderPath(): string {
return this.currentConfig ? this.currentConfig.folderPath : void 0;
get openedFolderUri(): URI {
return this.currentConfig ? this.currentConfig.folderUri : void 0;
}
setReady(): void {

View file

@ -20,16 +20,15 @@ import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILogService } from 'vs/platform/log/common/log';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, ReadyState, IPathsToWaitFor, IEnterWorkspaceResult, IMessageBoxResult } from 'vs/platform/windows/common/windows';
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderPath } from 'vs/code/node/windowsFinder';
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri } from 'vs/code/node/windowsFinder';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import product from 'vs/platform/node/product';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { isEqual } from 'vs/base/common/paths';
import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent, ICodeWindow, IWindowState as ISingleWindowState, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService } from 'vs/platform/history/common/history';
import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { TPromise } from 'vs/base/common/winjs.base';
import { IWorkspacesMainService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, WORKSPACE_FILTER, isSingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesMainService, IWorkspaceIdentifier, WORKSPACE_FILTER, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { Schemas } from 'vs/base/common/network';
@ -37,6 +36,7 @@ import { normalizeNFC } from 'vs/base/common/normalization';
import URI from 'vs/base/common/uri';
import { Queue } from 'vs/base/common/async';
import { exists } from 'vs/base/node/pfs';
import { getComparisonKey, isEqual, hasToIgnoreCase } from 'vs/base/common/resources';
enum WindowError {
UNRESPONSIVE,
@ -49,11 +49,15 @@ interface INewWindowState extends ISingleWindowState {
interface IWindowState {
workspace?: IWorkspaceIdentifier;
folderPath?: string;
folderUri?: URI;
backupPath: string;
uiState: ISingleWindowState;
}
interface IBackwardCompatibleWindowState extends IWindowState {
folderPath?: string;
}
interface IWindowsState {
lastActiveWindow?: IWindowState;
lastPluginDevelopmentHostWindow?: IWindowState;
@ -67,7 +71,7 @@ interface IOpenBrowserWindowOptions {
cli?: ParsedArgs;
workspace?: IWorkspaceIdentifier;
folderPath?: string;
folderUri?: URI;
initialStartup?: boolean;
@ -88,7 +92,7 @@ interface IPathToOpen extends IPath {
workspace?: IWorkspaceIdentifier;
// the folder path for a Code instance to open
folderPath?: string;
folderUri?: URI;
// the backup spath for a Code instance to use
backupPath?: string;
@ -144,7 +148,7 @@ export class WindowsManager implements IWindowsMainService {
@IWorkspacesMainService private workspacesMainService: IWorkspacesMainService,
@IInstantiationService private instantiationService: IInstantiationService
) {
this.windowsState = this.stateService.getItem<IWindowsState>(WindowsManager.windowsStateStorageKey) || { openedWindows: [] };
this.windowsState = this.getWindowsState();
if (!Array.isArray(this.windowsState.openedWindows)) {
this.windowsState.openedWindows = [];
}
@ -153,6 +157,30 @@ export class WindowsManager implements IWindowsMainService {
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, environmentService, this);
}
private getWindowsState(): IWindowsState {
const windowsState = this.stateService.getItem<IWindowsState>(WindowsManager.windowsStateStorageKey) || { openedWindows: [] };
if (windowsState.lastActiveWindow) {
windowsState.lastActiveWindow = this.revive(windowsState.lastActiveWindow);
}
if (windowsState.lastPluginDevelopmentHostWindow) {
windowsState.lastPluginDevelopmentHostWindow = this.revive(windowsState.lastPluginDevelopmentHostWindow);
}
if (windowsState.openedWindows) {
windowsState.openedWindows = windowsState.openedWindows.map(windowState => this.revive(windowState));
}
return windowsState;
}
private revive(windowState: IWindowState): IWindowState {
if (windowState.folderUri) {
windowState.folderUri = URI.revive(windowState.folderUri);
}
if ((<IBackwardCompatibleWindowState>windowState).folderPath) {
windowState.folderUri = URI.file((<IBackwardCompatibleWindowState>windowState).folderPath);
}
return windowState;
}
ready(initialUserEnv: IProcessEnvironment): void {
this.initialUserEnv = initialUserEnv;
@ -294,10 +322,10 @@ export class WindowsManager implements IWindowsMainService {
}
// Any non extension host window with same workspace or folder
else if (!win.isExtensionDevelopmentHost && (!!win.openedWorkspace || !!win.openedFolderPath)) {
else if (!win.isExtensionDevelopmentHost && (!!win.openedWorkspace || !!win.openedFolderUri)) {
this.windowsState.openedWindows.forEach(o => {
const sameWorkspace = win.openedWorkspace && o.workspace && o.workspace.id === win.openedWorkspace.id;
const sameFolder = win.openedFolderPath && isEqual(o.folderPath, win.openedFolderPath, !isLinux /* ignorecase */);
const sameFolder = win.openedFolderUri && o.folderUri && isEqual(o.folderUri, win.openedFolderUri, hasToIgnoreCase(o.folderUri));
if (sameWorkspace || sameFolder) {
o.uiState = state.uiState;
@ -317,23 +345,24 @@ export class WindowsManager implements IWindowsMainService {
private toWindowState(win: ICodeWindow): IWindowState {
return {
workspace: win.openedWorkspace,
folderPath: win.openedFolderPath,
folderUri: win.openedFolderUri,
backupPath: win.backupPath,
uiState: win.serializeWindowState()
};
}
open(openConfig: IOpenConfiguration): ICodeWindow[] {
this.logService.trace('windowsManager#open');
openConfig = this.validateOpenConfig(openConfig);
let pathsToOpen = this.getPathsToOpen(openConfig);
// When run with --add, take the folders that are to be opened as
// folders that should be added to the currently active window.
let foldersToAdd: IPath[] = [];
let foldersToAdd: URI[] = [];
if (openConfig.addMode) {
foldersToAdd = pathsToOpen.filter(path => !!path.folderPath).map(path => ({ filePath: path.folderPath }));
pathsToOpen = pathsToOpen.filter(path => !path.folderPath);
foldersToAdd = pathsToOpen.filter(path => !!path.folderUri).map(path => path.folderUri);
pathsToOpen = pathsToOpen.filter(path => !path.folderUri);
}
let filesToOpen = pathsToOpen.filter(path => !!path.filePath && !path.createFilePath);
@ -362,12 +391,12 @@ export class WindowsManager implements IWindowsMainService {
//
// These are windows to open to show either folders or files (including diffing files or creating them)
//
const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderPath && !win.filePath).map(win => win.folderPath), folder => isLinux ? folder : folder.toLowerCase()); // prevent duplicates
const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderUri && !win.filePath).map(win => win.folderUri), folder => getComparisonKey(folder)); // prevent duplicates
//
// These are windows to restore because of hot-exit or from previous session (only performed once on startup!)
//
let foldersToRestore: string[] = [];
let foldersToRestore: URI[] = [];
let workspacesToRestore: IWorkspaceIdentifier[] = [];
let emptyToRestore: string[] = [];
if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath && !openConfig.cli['disable-restore-windows']) {
@ -377,21 +406,22 @@ export class WindowsManager implements IWindowsMainService {
workspacesToRestore.push(...this.workspacesMainService.getUntitledWorkspacesSync()); // collect from previous window session
emptyToRestore = this.backupMainService.getEmptyWindowBackupPaths();
emptyToRestore.push(...pathsToOpen.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => basename(w.backupPath))); // add empty windows with backupPath
emptyToRestore.push(...pathsToOpen.filter(w => !w.workspace && !w.folderUri && w.backupPath).map(w => basename(w.backupPath))); // add empty windows with backupPath
emptyToRestore = arrays.distinct(emptyToRestore); // prevent duplicates
}
//
// These are empty windows to open
//
const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderPath && !win.filePath && !win.backupPath).length;
const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderUri && !win.filePath && !win.backupPath).length;
// Open based on config
const usedWindows = this.doOpen(openConfig, workspacesToOpen, workspacesToRestore, foldersToOpen, foldersToRestore, emptyToRestore, emptyToOpen, filesToOpen, filesToCreate, filesToDiff, filesToWait, foldersToAdd);
// Make sure to pass focus to the most relevant of the windows if we open multiple
if (usedWindows.length > 1) {
let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && (!openConfig.pathsToOpen || !openConfig.pathsToOpen.length);
let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !(openConfig.cli['folder-uri'] || []).length && !(openConfig.urisToOpen || []).length;
let focusLastOpened = true;
let focusLastWindow = true;
@ -410,9 +440,9 @@ export class WindowsManager implements IWindowsMainService {
for (let i = usedWindows.length - 1; i >= 0; i--) {
const usedWindow = usedWindows[i];
if (
(usedWindow.openedWorkspace && workspacesToRestore.some(workspace => workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace
(usedWindow.openedFolderPath && foldersToRestore.some(folder => folder === usedWindow.openedFolderPath)) || // skip over restored folder
(usedWindow.backupPath && emptyToRestore.some(empty => empty === basename(usedWindow.backupPath))) // skip over restored empty window
(usedWindow.openedWorkspace && workspacesToRestore.some(workspace => workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace
(usedWindow.openedFolderUri && foldersToRestore.some(folder => isEqual(folder, usedWindow.openedFolderUri, hasToIgnoreCase(folder)))) || // skip over restored folder
(usedWindow.backupPath && emptyToRestore.some(empty => empty === basename(usedWindow.backupPath))) // skip over restored empty window
) {
continue;
}
@ -436,8 +466,8 @@ export class WindowsManager implements IWindowsMainService {
const recentlyOpenedFiles: string[] = [];
pathsToOpen.forEach(win => {
if (win.workspace || win.folderPath) {
recentlyOpenedWorkspaces.push(win.workspace || win.folderPath);
if (win.workspace || win.folderUri) {
recentlyOpenedWorkspaces.push(win.workspace || win.folderUri);
} else if (win.filePath) {
recentlyOpenedFiles.push(win.filePath);
}
@ -472,15 +502,15 @@ export class WindowsManager implements IWindowsMainService {
openConfig: IOpenConfiguration,
workspacesToOpen: IWorkspaceIdentifier[],
workspacesToRestore: IWorkspaceIdentifier[],
foldersToOpen: string[],
foldersToRestore: string[],
foldersToOpen: URI[],
foldersToRestore: URI[],
emptyToRestore: string[],
emptyToOpen: number,
filesToOpen: IPath[],
filesToCreate: IPath[],
filesToDiff: IPath[],
filesToWait: IPathsToWaitFor,
foldersToAdd: IPath[]
foldersToAdd: URI[]
) {
const usedWindows: ICodeWindow[] = [];
@ -516,6 +546,8 @@ export class WindowsManager implements IWindowsMainService {
// Special case: we started with --wait and we got back a folder to open. In this case
// we actually prefer to not open the folder but operate purely on the file.
if (typeof bestWindowOrFolder === 'string' && filesToWait) {
//TODO: #54483 Ben This should not happen
console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS);
bestWindowOrFolder = !openFilesInNewWindow ? this.getLastActiveWindow() : null;
}
@ -528,8 +560,8 @@ export class WindowsManager implements IWindowsMainService {
}
// Window is single folder
else if (bestWindowOrFolder.openedFolderPath) {
foldersToOpen.push(bestWindowOrFolder.openedFolderPath);
else if (bestWindowOrFolder.openedFolderUri) {
foldersToOpen.push(bestWindowOrFolder.openedFolderUri);
}
// Window is empty
@ -548,7 +580,9 @@ export class WindowsManager implements IWindowsMainService {
// We found a suitable folder to open: add it to foldersToOpen
else if (typeof bestWindowOrFolder === 'string') {
foldersToOpen.push(bestWindowOrFolder);
//TODO: #54483 Ben This should not happen
// foldersToOpen.push(bestWindowOrFolder);
console.error(`This should not happen`, bestWindowOrFolder, WindowsManager.WINDOWS);
}
// Finally, if no window or folder is found, just open the files in an empty window
@ -613,7 +647,8 @@ export class WindowsManager implements IWindowsMainService {
}
// Handle folders to open (instructed and to restore)
const allFoldersToOpen = arrays.distinct([...foldersToRestore, ...foldersToOpen], folder => isLinux ? folder : folder.toLowerCase()); // prevent duplicates
const allFoldersToOpen = arrays.distinct([...foldersToRestore, ...foldersToOpen], folder => getComparisonKey(folder)); // prevent duplicates
if (allFoldersToOpen.length > 0) {
// Check for existing instances
@ -635,12 +670,13 @@ export class WindowsManager implements IWindowsMainService {
// Open remaining ones
allFoldersToOpen.forEach(folderToOpen => {
if (windowsOnFolderPath.some(win => isEqual(win.openedFolderPath, folderToOpen, !isLinux /* ignorecase */))) {
if (windowsOnFolderPath.some(win => isEqual(win.openedFolderUri, folderToOpen, hasToIgnoreCase(win.openedFolderUri)))) {
return; // ignore folders that are already open
}
// Do open folder
usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, { folderPath: folderToOpen }, openFolderInNewWindow, filesToOpen, filesToCreate, filesToDiff, filesToWait));
usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, { folderUri: folderToOpen }, openFolderInNewWindow, filesToOpen, filesToCreate, filesToDiff, filesToWait));
// Reset these because we handled them
filesToOpen = [];
@ -705,7 +741,7 @@ export class WindowsManager implements IWindowsMainService {
return window;
}
private doAddFoldersToExistingWidow(window: ICodeWindow, foldersToAdd: IPath[]): ICodeWindow {
private doAddFoldersToExistingWidow(window: ICodeWindow, foldersToAdd: URI[]): ICodeWindow {
window.focus(); // make sure window has focus
window.ready().then(readyWindow => {
@ -725,7 +761,7 @@ export class WindowsManager implements IWindowsMainService {
cli: openConfig.cli,
initialStartup: openConfig.initialStartup,
workspace: folderOrWorkspace.workspace,
folderPath: folderOrWorkspace.folderPath,
folderUri: folderOrWorkspace.folderUri,
filesToOpen,
filesToCreate,
filesToDiff,
@ -742,7 +778,7 @@ export class WindowsManager implements IWindowsMainService {
let isCommandLineOrAPICall = false;
// Extract paths: from API
if (openConfig.pathsToOpen && openConfig.pathsToOpen.length > 0) {
if (openConfig.urisToOpen && openConfig.urisToOpen.length > 0) {
windowsToOpen = this.doExtractPathsFromAPI(openConfig);
isCommandLineOrAPICall = true;
}
@ -753,7 +789,7 @@ export class WindowsManager implements IWindowsMainService {
}
// Extract paths: from CLI
else if (openConfig.cli._.length > 0) {
else if (openConfig.cli._.length > 0 || (openConfig.cli['folder-uri'] || []).length > 0) {
windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli);
isCommandLineOrAPICall = true;
}
@ -768,13 +804,13 @@ export class WindowsManager implements IWindowsMainService {
// If we are in addMode, we should not do this because in that case all
// folders should be added to the existing window.
if (!openConfig.addMode && isCommandLineOrAPICall) {
const foldersToOpen = windowsToOpen.filter(path => !!path.folderPath);
const foldersToOpen = windowsToOpen.filter(path => !!path.folderUri);
if (foldersToOpen.length > 1) {
const workspace = this.workspacesMainService.createWorkspaceSync(foldersToOpen.map(folder => ({ uri: URI.file(folder.folderPath) })));
const workspace = this.workspacesMainService.createWorkspaceSync(foldersToOpen.map(folder => ({ uri: folder.folderUri })));
// Add workspace and remove folders thereby
windowsToOpen.push({ workspace });
windowsToOpen = windowsToOpen.filter(path => !path.folderPath);
windowsToOpen = windowsToOpen.filter(path => !path.folderUri);
}
}
@ -782,8 +818,8 @@ export class WindowsManager implements IWindowsMainService {
}
private doExtractPathsFromAPI(openConfig: IOpenConfiguration): IPath[] {
let pathsToOpen = openConfig.pathsToOpen.map(pathToOpen => {
const path = this.parsePath(pathToOpen, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile });
let pathsToOpen = openConfig.urisToOpen.map(pathToOpen => {
const path = this.parseUri(pathToOpen, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile });
// Warn if the requested path to open does not exist
if (!path) {
@ -792,7 +828,7 @@ export class WindowsManager implements IWindowsMainService {
type: 'info',
buttons: [localize('ok', "OK")],
message: localize('pathNotExistTitle', "Path does not exist"),
detail: localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", pathToOpen),
detail: localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", pathToOpen.scheme === Schemas.file ? pathToOpen.fsPath : pathToOpen.path),
noLink: true
};
@ -809,7 +845,20 @@ export class WindowsManager implements IWindowsMainService {
}
private doExtractPathsFromCLI(cli: ParsedArgs): IPath[] {
const pathsToOpen = arrays.coalesce(cli._.map(candidate => this.parsePath(candidate, { ignoreFileNotFound: true, gotoLineMode: cli.goto })));
const pathsToOpen = [];
// folder uris
if (cli['folder-uri'] && cli['folder-uri'].length) {
const arg = cli['folder-uri'];
const folderUris: string[] = typeof arg === 'string' ? [arg] : arg;
pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(URI.parse(candidate), { ignoreFileNotFound: true, gotoLineMode: cli.goto }))));
}
// folder or file paths
if (cli._ && cli._.length) {
pathsToOpen.push(...arrays.coalesce(cli._.map(candidate => this.parsePath(candidate, { ignoreFileNotFound: true, gotoLineMode: cli.goto }))));
}
if (pathsToOpen.length > 0) {
return pathsToOpen;
}
@ -842,9 +891,9 @@ export class WindowsManager implements IWindowsMainService {
}
// folder (if path is valid)
else if (lastActiveWindow.folderPath) {
const validatedFolder = this.parsePath(lastActiveWindow.folderPath);
if (validatedFolder && validatedFolder.folderPath) {
else if (lastActiveWindow.folderUri) {
const validatedFolder = this.parseUri(lastActiveWindow.folderUri);
if (validatedFolder && validatedFolder.folderUri) {
return [validatedFolder];
}
}
@ -870,16 +919,16 @@ export class WindowsManager implements IWindowsMainService {
windowsToOpen.push(...workspaceCandidates.map(candidate => this.parsePath(candidate.configPath)).filter(window => window && window.workspace));
// Folders
const folderCandidates = this.windowsState.openedWindows.filter(w => !!w.folderPath).map(w => w.folderPath);
if (lastActiveWindow && lastActiveWindow.folderPath) {
folderCandidates.push(lastActiveWindow.folderPath);
const folderCandidates = this.windowsState.openedWindows.filter(w => !!w.folderUri).map(w => w.folderUri);
if (lastActiveWindow && lastActiveWindow.folderUri) {
folderCandidates.push(lastActiveWindow.folderUri);
}
windowsToOpen.push(...folderCandidates.map(candidate => this.parsePath(candidate)).filter(window => window && window.folderPath));
windowsToOpen.push(...folderCandidates.map(candidate => this.parseUri(candidate)).filter(window => window && window.folderUri));
// Windows that were Empty
if (restoreWindows === 'all') {
const lastOpenedEmpty = this.windowsState.openedWindows.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => w.backupPath);
const lastActiveEmpty = lastActiveWindow && !lastActiveWindow.workspace && !lastActiveWindow.folderPath && lastActiveWindow.backupPath;
const lastOpenedEmpty = this.windowsState.openedWindows.filter(w => !w.workspace && !w.folderUri && w.backupPath).map(w => w.backupPath);
const lastActiveEmpty = lastActiveWindow && !lastActiveWindow.workspace && !lastActiveWindow.folderUri && lastActiveWindow.backupPath;
if (lastActiveEmpty) {
lastOpenedEmpty.push(lastActiveEmpty);
}
@ -914,6 +963,20 @@ export class WindowsManager implements IWindowsMainService {
return restoreWindows;
}
private parseUri(anyUri: URI, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen {
if (!anyUri) {
return null;
}
if (anyUri.scheme === Schemas.file) {
return this.parsePath(anyUri.fsPath, options);
}
return {
folderUri: anyUri
};
}
private parsePath(anyPath: string, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen {
if (!anyPath) {
return null;
@ -954,7 +1017,7 @@ export class WindowsManager implements IWindowsMainService {
// over to us)
else if (candidateStat.isDirectory()) {
return {
folderPath: candidate
folderUri: URI.file(candidate)
};
}
}
@ -1024,25 +1087,39 @@ export class WindowsManager implements IWindowsMainService {
}
// Fill in previously opened workspace unless an explicit path is provided and we are not unit testing
if (openConfig.cli._.length === 0 && !openConfig.cli.extensionTestsPath) {
if (openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0 && !openConfig.cli.extensionTestsPath) {
const extensionDevelopmentWindowState = this.windowsState.lastPluginDevelopmentHostWindow;
const workspaceToOpen = extensionDevelopmentWindowState && (extensionDevelopmentWindowState.workspace || extensionDevelopmentWindowState.folderPath);
const workspaceToOpen = extensionDevelopmentWindowState && (extensionDevelopmentWindowState.workspace || extensionDevelopmentWindowState.folderUri);
if (workspaceToOpen) {
openConfig.cli._ = [isSingleFolderWorkspaceIdentifier(workspaceToOpen) ? workspaceToOpen : workspaceToOpen.configPath];
if (isSingleFolderWorkspaceIdentifier(workspaceToOpen)) {
if (workspaceToOpen.scheme === Schemas.file) {
openConfig.cli._ = [workspaceToOpen.fsPath];
} else {
openConfig.cli['folder-uri'] = [workspaceToOpen.toString()];
}
} else {
openConfig.cli._ = [workspaceToOpen.configPath];
}
}
}
// Make sure we are not asked to open a workspace or folder that is already opened
if (openConfig.cli._.some(path => !!findWindowOnWorkspaceOrFolderPath(WindowsManager.WINDOWS, path))) {
if (openConfig.cli._.some(path => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.file(path)))) {
openConfig.cli._ = [];
}
if (openConfig.cli['folder-uri']) {
const arg = openConfig.cli['folder-uri'];
const folderUris: string[] = typeof arg === 'string' ? [arg] : arg;
if (folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.parse(uri)))) {
openConfig.cli['folder-uri'] = [];
}
}
// Open it
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: openConfig.cli._.length === 0, userEnv: openConfig.userEnv });
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0, userEnv: openConfig.userEnv });
}
private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow {
// Build IWindowConfiguration from config and options
const configuration: IWindowConfiguration = mixin({}, options.cli); // inherit all properties from CLI
configuration.appRoot = this.environmentService.appRoot;
@ -1051,7 +1128,7 @@ export class WindowsManager implements IWindowsMainService {
configuration.userEnv = assign({}, this.initialUserEnv, options.userEnv || {});
configuration.isInitialStartup = options.initialStartup;
configuration.workspace = options.workspace;
configuration.folderPath = options.folderPath;
configuration.folderUri = options.folderUri;
configuration.filesToOpen = options.filesToOpen;
configuration.filesToCreate = options.filesToCreate;
configuration.filesToDiff = options.filesToDiff;
@ -1141,8 +1218,8 @@ export class WindowsManager implements IWindowsMainService {
if (!configuration.extensionDevelopmentPath) {
if (configuration.workspace) {
configuration.backupPath = this.backupMainService.registerWorkspaceBackupSync(configuration.workspace);
} else if (configuration.folderPath) {
configuration.backupPath = this.backupMainService.registerFolderBackupSync(configuration.folderPath);
} else if (configuration.folderUri) {
configuration.backupPath = this.backupMainService.registerFolderBackupSync(configuration.folderUri);
} else {
configuration.backupPath = this.backupMainService.registerEmptyWindowBackupSync(options.emptyWindowBackupFolder);
}
@ -1179,8 +1256,8 @@ export class WindowsManager implements IWindowsMainService {
}
// Known Folder - load from stored settings
if (configuration.folderPath) {
const stateForFolder = this.windowsState.openedWindows.filter(o => isEqual(o.folderPath, configuration.folderPath, !isLinux /* ignorecase */)).map(o => o.uiState);
if (configuration.folderUri) {
const stateForFolder = this.windowsState.openedWindows.filter(o => o.folderUri && isEqual(o.folderUri, configuration.folderUri, hasToIgnoreCase(o.folderUri))).map(o => o.uiState);
if (stateForFolder.length) {
return stateForFolder[0];
}
@ -1613,7 +1690,7 @@ class Dialogs {
}
pickAndOpen(options: INativeOpenDialogOptions): void {
this.getFileOrFolderPaths(options).then(paths => {
this.getFileOrFolderUris(options).then(paths => {
const numberOfPaths = paths ? paths.length : 0;
// Telemetry
@ -1631,7 +1708,7 @@ class Dialogs {
this.windowsMainService.open({
context: OpenContext.DIALOG,
cli: this.environmentService.args,
pathsToOpen: paths,
urisToOpen: paths,
forceNewWindow: options.forceNewWindow,
forceOpenWorkspaceAsFile: options.dialogOptions && !equals(options.dialogOptions.filters, WORKSPACE_FILTER)
});
@ -1639,7 +1716,7 @@ class Dialogs {
});
}
private getFileOrFolderPaths(options: IInternalNativeOpenDialogOptions): TPromise<string[]> {
private getFileOrFolderUris(options: IInternalNativeOpenDialogOptions): TPromise<URI[]> {
// Ensure dialog options
if (!options.dialogOptions) {
@ -1677,7 +1754,7 @@ class Dialogs {
// Remember path in storage for next time
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(paths[0]));
return paths;
return paths.map(path => URI.file(path));
}
return void 0;
@ -1860,7 +1937,7 @@ class WorkspacesManager {
}
// Update window configuration properly based on transition to workspace
window.config.folderPath = void 0;
window.config.folderUri = void 0;
window.config.workspace = workspace;
window.config.backupPath = backupPath;
@ -1953,7 +2030,7 @@ class WorkspacesManager {
private getUntitledWorkspaceSaveDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
if (workspace) {
if (isSingleFolderWorkspaceIdentifier(workspace)) {
return dirname(workspace);
return workspace.scheme === Schemas.file ? dirname(workspace.fsPath) : void 0;
}
const resolvedWorkspace = this.workspacesMainService.resolveWorkspaceSync(workspace.configPath);

View file

@ -8,12 +8,14 @@
import * as platform from 'vs/base/common/platform';
import * as paths from 'vs/base/common/paths';
import { OpenContext } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IResolvedWorkspace } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { Schemas } from 'vs/base/common/network';
import URI from 'vs/base/common/uri';
import { hasToIgnoreCase, isEqual } from 'vs/base/common/resources';
export interface ISimpleWindow {
openedWorkspace?: IWorkspaceIdentifier;
openedFolderPath?: string;
openedFolderUri?: URI;
openedFilePath?: string;
extensionDevelopmentPath?: string;
lastFocusTime: number;
@ -30,7 +32,7 @@ export interface IBestWindowOrFolderOptions<W extends ISimpleWindow> {
workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace;
}
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions<W>): W | string {
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions<W>): W {
if (!newWindow && filePath && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) {
const windowOnFilePath = findWindowOnFilePath(windows, filePath, workspaceResolver);
if (windowOnFilePath) {
@ -54,9 +56,9 @@ function findWindowOnFilePath<W extends ISimpleWindow>(windows: W[], filePath: s
}
// Then go with single folder windows that are parent of the provided file path
const singleFolderWindowsOnFilePath = windows.filter(window => typeof window.openedFolderPath === 'string' && paths.isEqualOrParent(filePath, window.openedFolderPath, !platform.isLinux /* ignorecase */));
const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && window.openedFolderUri.scheme === Schemas.file && paths.isEqualOrParent(filePath, window.openedFolderUri.fsPath, !platform.isLinux /* ignorecase */));
if (singleFolderWindowsOnFilePath.length) {
return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderPath.length - b.openedFolderPath.length))[0];
return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri.path.length - b.openedFolderUri.path.length))[0];
}
return null;
@ -73,7 +75,7 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor
// match on folder
if (isSingleFolderWorkspaceIdentifier(workspace)) {
if (typeof window.openedFolderPath === 'string' && (paths.isEqual(window.openedFolderPath, workspace, !platform.isLinux /* ignorecase */))) {
if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace, hasToIgnoreCase(window.openedFolderUri))) {
return true;
}
}
@ -101,16 +103,16 @@ export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(wi
})[0];
}
export function findWindowOnWorkspaceOrFolderPath<W extends ISimpleWindow>(windows: W[], path: string): W {
export function findWindowOnWorkspaceOrFolderUri<W extends ISimpleWindow>(windows: W[], uri: URI): W {
return windows.filter(window => {
// check for workspace config path
if (window.openedWorkspace && paths.isEqual(window.openedWorkspace.configPath, path, !platform.isLinux /* ignorecase */)) {
if (window.openedWorkspace && isEqual(URI.file(window.openedWorkspace.configPath), uri, !platform.isLinux /* ignorecase */)) {
return true;
}
// check for folder path
if (window.openedFolderPath && paths.isEqual(window.openedFolderPath, path, !platform.isLinux /* ignorecase */)) {
if (window.openedFolderUri && isEqual(window.openedFolderUri, uri, hasToIgnoreCase(uri))) {
return true;
}

View file

@ -10,6 +10,7 @@ import { findBestWindowOrFolderForFile, ISimpleWindow, IBestWindowOrFolderOption
import { OpenContext } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
const fixturesFolder = require.toUrl('./fixtures');
@ -30,10 +31,10 @@ function options(custom?: Partial<IBestWindowOrFolderOptions<ISimpleWindow>>): I
};
}
const vscodeFolderWindow = { lastFocusTime: 1, openedFolderPath: path.join(fixturesFolder, 'vscode_folder') };
const lastActiveWindow = { lastFocusTime: 3, openedFolderPath: null };
const noVscodeFolderWindow = { lastFocusTime: 2, openedFolderPath: path.join(fixturesFolder, 'no_vscode_folder') };
const windows = [
const vscodeFolderWindow: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder')) };
const lastActiveWindow: ISimpleWindow = { lastFocusTime: 3, openedFolderUri: null };
const noVscodeFolderWindow: ISimpleWindow = { lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) };
const windows: ISimpleWindow[] = [
vscodeFolderWindow,
lastActiveWindow,
noVscodeFolderWindow,
@ -103,7 +104,7 @@ suite('WindowsFinder', () => {
windows,
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt')
})), vscodeFolderWindow);
const window = { lastFocusTime: 1, openedFolderPath: path.join(fixturesFolder, 'vscode_folder', 'nested_folder') };
const window: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder')) };
assert.equal(findBestWindowOrFolderForFile(options({
windows: [window],
filePath: path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')
@ -111,8 +112,8 @@ suite('WindowsFinder', () => {
});
test('More specific existing window wins', () => {
const window = { lastFocusTime: 2, openedFolderPath: path.join(fixturesFolder, 'no_vscode_folder') };
const nestedFolderWindow = { lastFocusTime: 1, openedFolderPath: path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder') };
const window: ISimpleWindow = { lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) };
const nestedFolderWindow: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) };
assert.equal(findBestWindowOrFolderForFile(options({
windows: [window, nestedFolderWindow],
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')
@ -120,7 +121,7 @@ suite('WindowsFinder', () => {
});
test('Workspace folder wins', () => {
const window = { lastFocusTime: 1, openedWorkspace: testWorkspace };
const window: ISimpleWindow = { lastFocusTime: 1, openedWorkspace: testWorkspace };
assert.equal(findBestWindowOrFolderForFile(options({
windows: [window],
filePath: path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')

View file

@ -1356,22 +1356,22 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
if (this.isSimpleWidget) {
commandDelegate = {
paste: (source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]) => {
this.cursor.trigger(source, editorCommon.Handler.Paste, { text, pasteOnNewLine, multicursorText });
this.trigger(source, editorCommon.Handler.Paste, { text, pasteOnNewLine, multicursorText });
},
type: (source: string, text: string) => {
this.cursor.trigger(source, editorCommon.Handler.Type, { text });
this.trigger(source, editorCommon.Handler.Type, { text });
},
replacePreviousChar: (source: string, text: string, replaceCharCnt: number) => {
this.cursor.trigger(source, editorCommon.Handler.ReplacePreviousChar, { text, replaceCharCnt });
this.trigger(source, editorCommon.Handler.ReplacePreviousChar, { text, replaceCharCnt });
},
compositionStart: (source: string) => {
this.cursor.trigger(source, editorCommon.Handler.CompositionStart, undefined);
this.trigger(source, editorCommon.Handler.CompositionStart, undefined);
},
compositionEnd: (source: string) => {
this.cursor.trigger(source, editorCommon.Handler.CompositionEnd, undefined);
this.trigger(source, editorCommon.Handler.CompositionEnd, undefined);
},
cut: (source: string) => {
this.cursor.trigger(source, editorCommon.Handler.Cut, undefined);
this.trigger(source, editorCommon.Handler.Cut, undefined);
}
};
} else {

View file

@ -1177,7 +1177,7 @@ interface IDataSource {
getModifiedEditor(): editorBrowser.ICodeEditor;
}
abstract class DiffEditorWidgetStyle extends Disposable {
abstract class DiffEditorWidgetStyle extends Disposable implements IDiffEditorWidgetStyle {
_dataSource: IDataSource;
_insertColor: Color;
@ -1228,6 +1228,9 @@ abstract class DiffEditorWidgetStyle extends Disposable {
protected abstract _getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, renderIndicators: boolean): IEditorsZones;
protected abstract _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations;
protected abstract _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations;
public abstract setEnableSplitViewResizing(enableSplitViewResizing: boolean): void;
public abstract layout(): number;
}
interface IMyViewZone extends editorBrowser.IViewZone {
@ -1529,10 +1532,6 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
this._sash.onDidReset(() => this.onSashReset());
}
public dispose(): void {
super.dispose();
}
public setEnableSplitViewResizing(enableSplitViewResizing: boolean): void {
let newDisableSash = (enableSplitViewResizing === false);
if (this._disableSash !== newDisableSash) {
@ -1778,10 +1777,6 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
}));
}
public dispose(): void {
super.dispose();
}
public setEnableSplitViewResizing(enableSplitViewResizing: boolean): void {
// Nothing to do..
}

View file

@ -276,25 +276,25 @@ const editorConfiguration: IConfigurationNode = {
'editor.wordSeparators': {
'type': 'string',
'default': EDITOR_DEFAULTS.wordSeparators,
'description': nls.localize('wordSeparators', "Characters that will be used as word separators when doing word related navigations or operations")
'description': nls.localize('wordSeparators', "Characters that will be used as word separators when doing word related navigations or operations.")
},
'editor.tabSize': {
'type': 'number',
'default': EDITOR_MODEL_DEFAULTS.tabSize,
'minimum': 1,
'description': nls.localize('tabSize', "The number of spaces a tab is equal to. This setting is overridden based on the file contents when [`editor.detectIndentation`](#editor.detectIndentation) is on."),
'description': nls.localize('tabSize', "The number of spaces a tab is equal to. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."),
'errorMessage': nls.localize('tabSize.errorMessage', "Expected 'number'. Note that the value \"auto\" has been replaced by the `editor.detectIndentation` setting.")
},
'editor.insertSpaces': {
'type': 'boolean',
'default': EDITOR_MODEL_DEFAULTS.insertSpaces,
'description': nls.localize('insertSpaces', "Insert spaces when pressing Tab. This setting is overridden based on the file contents when [`editor.detectIndentation`](#editor.detectIndentation) is on."),
'description': nls.localize('insertSpaces', "Insert spaces when pressing Tab. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."),
'errorMessage': nls.localize('insertSpaces.errorMessage', "Expected 'boolean'. Note that the value \"auto\" has been replaced by the `editor.detectIndentation` setting.")
},
'editor.detectIndentation': {
'type': 'boolean',
'default': EDITOR_MODEL_DEFAULTS.detectIndentation,
'description': nls.localize('detectIndentation', "When opening a file, [`editor.tabSize`](#editor.tabSize) and [`editor.insertSpaces`](#editor.insertSpaces) will be detected based on the file contents.")
'description': nls.localize('detectIndentation', "When opening a file, `#editor.tabSize#` and `#editor.insertSpaces#` will be detected based on the file contents.")
},
'editor.roundedSelection': {
'type': 'boolean',
@ -361,17 +361,17 @@ const editorConfiguration: IConfigurationNode = {
'editor.find.seedSearchStringFromSelection': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.find.seedSearchStringFromSelection,
'description': nls.localize('find.seedSearchStringFromSelection', "Controls if we seed the search string in Find Widget from editor selection")
'description': nls.localize('find.seedSearchStringFromSelection', "Controls whether the search string in the Find Widget is seeded from the editor selection.")
},
'editor.find.autoFindInSelection': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.find.autoFindInSelection,
'description': nls.localize('find.autoFindInSelection', "Controls if Find in Selection flag is turned on when multiple characters or lines of text are selected in the editor")
'description': nls.localize('find.autoFindInSelection', "Controls whether the Find in Selection flag is turned on when multiple characters or lines of text are selected in the editor.")
},
'editor.find.globalFindClipboard': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.find.globalFindClipboard,
'description': nls.localize('find.globalFindClipboard', "Controls if the Find Widget should read or modify the shared find clipboard on macOS"),
'description': nls.localize('find.globalFindClipboard', "Controls whether the Find Widget should read or modify the shared find clipboard on macOS."),
'included': platform.isMacintosh
},
'editor.wordWrap': {
@ -385,14 +385,14 @@ const editorConfiguration: IConfigurationNode = {
comment: [
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
]
}, "Lines will wrap at `editor.wordWrapColumn`."),
}, "Lines will wrap at `#editor.wordWrapColumn#`."),
nls.localize({
key: 'wordWrap.bounded',
comment: [
'- viewport means the edge of the visible window size.',
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
]
}, "Lines will wrap at the minimum of viewport and `editor.wordWrapColumn`."),
}, "Lines will wrap at the minimum of viewport and `#editor.wordWrapColumn#`."),
],
'default': EDITOR_DEFAULTS.wordWrap,
'description': nls.localize({
@ -401,7 +401,7 @@ const editorConfiguration: IConfigurationNode = {
'- \'off\', \'on\', \'wordWrapColumn\' and \'bounded\' refer to values the setting can take and should not be localized.',
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
]
}, "Controls how lines should wrap. Can be:\n - 'off' (disable wrapping),\n - 'on' (viewport wrapping),\n - 'wordWrapColumn' (wrap at `editor.wordWrapColumn`) or\n - 'bounded' (wrap at minimum of viewport and `editor.wordWrapColumn`).")
}, "Controls how lines should wrap.")
},
'editor.wordWrapColumn': {
'type': 'integer',
@ -413,13 +413,19 @@ const editorConfiguration: IConfigurationNode = {
'- `editor.wordWrap` refers to a different setting and should not be localized.',
'- \'wordWrapColumn\' and \'bounded\' refer to values the different setting can take and should not be localized.'
]
}, "Controls the wrapping column of the editor when `editor.wordWrap` is 'wordWrapColumn' or 'bounded'.")
}, "Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.")
},
'editor.wrappingIndent': {
'type': 'string',
'enum': ['none', 'same', 'indent', 'deepIndent'],
enumDescriptions: [
nls.localize('wrappingIndent.none', "No indentation. Wrapped lines begin at column 1."),
nls.localize('wrappingIndent.same', "Wrapped lines get the same indentation as the parent."),
nls.localize('wrappingIndent.indent', "Wrapped lines get +1 indentation toward the parent."),
nls.localize('wrappingIndent.deepIndent', "Wrapped lines get +2 indentation toward the parent."),
],
'default': 'same',
'description': nls.localize('wrappingIndent', "Controls the indentation of wrapped lines. Can be one of 'none', 'same', 'indent' or 'deepIndent'.")
'description': nls.localize('wrappingIndent', "Controls the indentation of wrapped lines."),
},
'editor.mouseWheelScrollSensitivity': {
'type': 'number',
@ -440,7 +446,7 @@ const editorConfiguration: IConfigurationNode = {
'- `ctrlCmd` refers to a value the setting can take and should not be localized.',
'- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.'
]
}, "The modifier to be used to add multiple cursors with the mouse. `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on macOS. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier. [Read more](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier)")
}, "The modifier to be used to add multiple cursors with the mouse. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier. [Read more](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier).")
},
'editor.multiCursorMergeOverlapping': {
'type': 'boolean',
@ -495,7 +501,7 @@ const editorConfiguration: IConfigurationNode = {
'editor.formatOnType': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.formatOnType,
'description': nls.localize('formatOnType', "Controls if the editor should automatically format the line after typing")
'description': nls.localize('formatOnType', "Controls if the editor should automatically format the line after typing.")
},
'editor.formatOnPaste': {
'type': 'boolean',
@ -510,13 +516,13 @@ const editorConfiguration: IConfigurationNode = {
'editor.suggestOnTriggerCharacters': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.suggestOnTriggerCharacters,
'description': nls.localize('suggestOnTriggerCharacters', "Controls if suggestions should automatically show up when typing trigger characters")
'description': nls.localize('suggestOnTriggerCharacters', "Controls if suggestions should automatically show up when typing trigger characters.")
},
'editor.acceptSuggestionOnEnter': {
'type': 'string',
'enum': ['on', 'smart', 'off'],
'default': EDITOR_DEFAULTS.contribInfo.acceptSuggestionOnEnter,
'description': nls.localize('acceptSuggestionOnEnter', "Controls if suggestions should be accepted on 'Enter' - in addition to 'Tab'. Helps to avoid ambiguity between inserting new lines or accepting suggestions. The value 'smart' means only accept a suggestion with Enter when it makes a textual change")
'description': nls.localize('acceptSuggestionOnEnter', "Controls if suggestions should be accepted on 'Enter' - in addition to 'Tab'. Helps to avoid ambiguity between inserting new lines or accepting suggestions. The value 'smart' means only accept a suggestion with Enter when it makes a textual change.")
},
'editor.acceptSuggestionOnCommitCharacter': {
'type': 'boolean',
@ -560,13 +566,13 @@ const editorConfiguration: IConfigurationNode = {
'type': 'integer',
'default': 0,
'minimum': 0,
'description': nls.localize('suggestFontSize', "Font size for the suggest widget")
'description': nls.localize('suggestFontSize', "Font size for the suggest widget.")
},
'editor.suggestLineHeight': {
'type': 'integer',
'default': 0,
'minimum': 0,
'description': nls.localize('suggestLineHeight', "Line height for the suggest widget")
'description': nls.localize('suggestLineHeight', "Line height for the suggest widget.")
},
'editor.suggest.filterGraceful': {
type: 'boolean',
@ -586,12 +592,12 @@ const editorConfiguration: IConfigurationNode = {
'editor.occurrencesHighlight': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.contribInfo.occurrencesHighlight,
'description': nls.localize('occurrencesHighlight', "Controls whether the editor should highlight semantic symbol occurrences")
'description': nls.localize('occurrencesHighlight', "Controls whether the editor should highlight semantic symbol occurrences.")
},
'editor.overviewRulerLanes': {
'type': 'integer',
'default': 3,
'description': nls.localize('overviewRulerLanes', "Controls the number of decorations that can show up at the same position in the overview ruler")
'description': nls.localize('overviewRulerLanes', "Controls the number of decorations that can show up at the same position in the overview ruler.")
},
'editor.overviewRulerBorder': {
'type': 'boolean',
@ -607,23 +613,23 @@ const editorConfiguration: IConfigurationNode = {
'editor.mouseWheelZoom': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.viewInfo.mouseWheelZoom,
'description': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding Ctrl")
'description': nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding Ctrl.")
},
'editor.cursorStyle': {
'type': 'string',
'enum': ['block', 'block-outline', 'line', 'line-thin', 'underline', 'underline-thin'],
'default': editorOptions.cursorStyleToString(EDITOR_DEFAULTS.viewInfo.cursorStyle),
'description': nls.localize('cursorStyle', "Controls the cursor style, accepted values are 'block', 'block-outline', 'line', 'line-thin', 'underline' and 'underline-thin'")
'description': nls.localize('cursorStyle', "Controls the cursor style.")
},
'editor.cursorWidth': {
'type': 'integer',
'default': EDITOR_DEFAULTS.viewInfo.cursorWidth,
'description': nls.localize('cursorWidth', "Controls the width of the cursor when editor.cursorStyle is set to 'line'")
'description': nls.localize('cursorWidth', "Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.")
},
'editor.fontLigatures': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.viewInfo.fontLigatures,
'description': nls.localize('fontLigatures', "Enables font ligatures")
'description': nls.localize('fontLigatures', "Enables font ligatures.")
},
'editor.hideCursorInOverviewRuler': {
'type': 'boolean',
@ -633,18 +639,23 @@ const editorConfiguration: IConfigurationNode = {
'editor.renderWhitespace': {
'type': 'string',
'enum': ['none', 'boundary', 'all'],
'enumDescriptions': [
'',
nls.localize('renderWhiteSpace.boundary', "Render whitespace characters except for single spaces between words."),
''
],
default: EDITOR_DEFAULTS.viewInfo.renderWhitespace,
description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters, possibilities are 'none', 'boundary', and 'all'. The 'boundary' option does not render single spaces between words.")
description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters.")
},
'editor.renderControlCharacters': {
'type': 'boolean',
default: EDITOR_DEFAULTS.viewInfo.renderControlCharacters,
description: nls.localize('renderControlCharacters', "Controls whether the editor should render control characters")
description: nls.localize('renderControlCharacters', "Controls whether the editor should render control characters.")
},
'editor.renderIndentGuides': {
'type': 'boolean',
default: EDITOR_DEFAULTS.viewInfo.renderIndentGuides,
description: nls.localize('renderIndentGuides', "Controls whether the editor should render indent guides")
description: nls.localize('renderIndentGuides', "Controls whether the editor should render indent guides.")
},
'editor.highlightActiveIndentGuide': {
'type': 'boolean',
@ -696,12 +707,12 @@ const editorConfiguration: IConfigurationNode = {
'editor.useTabStops': {
'type': 'boolean',
'default': EDITOR_DEFAULTS.useTabStops,
'description': nls.localize('useTabStops', "Inserting and deleting whitespace follows tab stops")
'description': nls.localize('useTabStops', "Inserting and deleting whitespace follows tab stops.")
},
'editor.trimAutoWhitespace': {
'type': 'boolean',
'default': EDITOR_MODEL_DEFAULTS.trimAutoWhitespace,
'description': nls.localize('trimAutoWhitespace', "Remove trailing auto inserted whitespace")
'description': nls.localize('trimAutoWhitespace', "Remove trailing auto inserted whitespace.")
},
'editor.stablePeek': {
'type': 'boolean',

Some files were not shown because too many files have changed in this diff Show more