Merge branch 'master' into ben/sqlite

This commit is contained in:
Benjamin Pasero 2018-10-13 16:38:26 +02:00
commit e4b21b6794
226 changed files with 5088 additions and 4601 deletions

View file

@ -13,7 +13,6 @@ const es = require('event-stream');
const util = require('./lib/util');
const remote = require('gulp-remote-src');
const zip = require('gulp-vinyl-zip');
const assign = require('object-assign');
const pkg = require('../package.json');
@ -55,7 +54,7 @@ gulp.task('mixin', function () {
.pipe(util.rebase(2))
.pipe(productJsonFilter)
.pipe(buffer())
.pipe(json(o => assign({}, require('../product.json'), o)))
.pipe(json(o => Object.assign({}, require('../product.json'), o)))
.pipe(productJsonFilter.restore);
all = es.merge(mixin);

View file

@ -4,33 +4,33 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var es = require("event-stream");
var pickle = require('chromium-pickle-js');
var Filesystem = require('asar/lib/filesystem');
var VinylFile = require("vinyl");
var minimatch = require("minimatch");
const path = require("path");
const es = require("event-stream");
const pickle = require('chromium-pickle-js');
const Filesystem = require('asar/lib/filesystem');
const VinylFile = require("vinyl");
const minimatch = require("minimatch");
function createAsar(folderPath, unpackGlobs, destFilename) {
var shouldUnpackFile = function (file) {
for (var i = 0; i < unpackGlobs.length; i++) {
const shouldUnpackFile = (file) => {
for (let i = 0; i < unpackGlobs.length; i++) {
if (minimatch(file.relative, unpackGlobs[i])) {
return true;
}
}
return false;
};
var filesystem = new Filesystem(folderPath);
var out = [];
const filesystem = new Filesystem(folderPath);
const out = [];
// Keep track of pending inserts
var pendingInserts = 0;
var onFileInserted = function () { pendingInserts--; };
let pendingInserts = 0;
let onFileInserted = () => { pendingInserts--; };
// Do not insert twice the same directory
var seenDir = {};
var insertDirectoryRecursive = function (dir) {
const seenDir = {};
const insertDirectoryRecursive = (dir) => {
if (seenDir[dir]) {
return;
}
var lastSlash = dir.lastIndexOf('/');
let lastSlash = dir.lastIndexOf('/');
if (lastSlash === -1) {
lastSlash = dir.lastIndexOf('\\');
}
@ -40,8 +40,8 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
seenDir[dir] = true;
filesystem.insertDirectory(dir);
};
var insertDirectoryForFile = function (file) {
var lastSlash = file.lastIndexOf('/');
const insertDirectoryForFile = (file) => {
let lastSlash = file.lastIndexOf('/');
if (lastSlash === -1) {
lastSlash = file.lastIndexOf('\\');
}
@ -49,7 +49,7 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
insertDirectoryRecursive(file.substring(0, lastSlash));
}
};
var insertFile = function (relativePath, stat, shouldUnpack) {
const insertFile = (relativePath, stat, shouldUnpack) => {
insertDirectoryForFile(relativePath);
pendingInserts++;
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted);
@ -59,13 +59,13 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
return;
}
if (!file.stat.isFile()) {
throw new Error("unknown item in stream!");
throw new Error(`unknown item in stream!`);
}
var shouldUnpack = shouldUnpackFile(file);
const shouldUnpack = shouldUnpackFile(file);
insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack);
if (shouldUnpack) {
// The file goes outside of xx.asar, in a folder xx.asar.unpacked
var relative = path.relative(folderPath, file.path);
const relative = path.relative(folderPath, file.path);
this.queue(new VinylFile({
cwd: folderPath,
base: folderPath,
@ -79,34 +79,33 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
out.push(file.contents);
}
}, function () {
var _this = this;
var finish = function () {
let finish = () => {
{
var headerPickle = pickle.createEmpty();
const headerPickle = pickle.createEmpty();
headerPickle.writeString(JSON.stringify(filesystem.header));
var headerBuf = headerPickle.toBuffer();
var sizePickle = pickle.createEmpty();
const headerBuf = headerPickle.toBuffer();
const sizePickle = pickle.createEmpty();
sizePickle.writeUInt32(headerBuf.length);
var sizeBuf = sizePickle.toBuffer();
const sizeBuf = sizePickle.toBuffer();
out.unshift(headerBuf);
out.unshift(sizeBuf);
}
var contents = Buffer.concat(out);
const contents = Buffer.concat(out);
out.length = 0;
_this.queue(new VinylFile({
this.queue(new VinylFile({
cwd: folderPath,
base: folderPath,
path: destFilename,
contents: contents
}));
_this.queue(null);
this.queue(null);
};
// Call finish() only when all file inserts have finished...
if (pendingInserts === 0) {
finish();
}
else {
onFileInserted = function () {
onFileInserted = () => {
pendingInserts--;
if (pendingInserts === 0) {
finish();

View file

@ -4,19 +4,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var vm = require("vm");
const fs = require("fs");
const path = require("path");
const vm = require("vm");
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
var entryPointsMap = {};
entryPoints.forEach(function (module) {
const entryPointsMap = {};
entryPoints.forEach((module) => {
entryPointsMap[module.name] = module;
});
var allMentionedModulesMap = {};
entryPoints.forEach(function (module) {
const allMentionedModulesMap = {};
entryPoints.forEach((module) => {
allMentionedModulesMap[module.name] = true;
(module.include || []).forEach(function (includedModule) {
allMentionedModulesMap[includedModule] = true;
@ -25,11 +25,11 @@ function bundle(entryPoints, config, callback) {
allMentionedModulesMap[excludedModule] = true;
});
});
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
var r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
var loaderModule = { exports: {} };
const code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
const r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
const loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader = loaderModule.exports;
const loader = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
if (!config.paths['vs/nls']) {
@ -39,16 +39,16 @@ function bundle(entryPoints, config, callback) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
loader.config(config);
loader(['require'], function (localRequire) {
var resolvePath = function (path) {
var r = localRequire.toUrl(path);
loader(['require'], (localRequire) => {
const resolvePath = (path) => {
const r = localRequire.toUrl(path);
if (!/\.js/.test(r)) {
return r + '.js';
}
return r;
};
for (var moduleId in entryPointsMap) {
var entryPoint = entryPointsMap[moduleId];
for (const moduleId in entryPointsMap) {
const entryPoint = entryPointsMap[moduleId];
if (entryPoint.append) {
entryPoint.append = entryPoint.append.map(resolvePath);
}
@ -57,59 +57,59 @@ function bundle(entryPoints, config, callback) {
}
}
});
loader(Object.keys(allMentionedModulesMap), function () {
var modules = loader.getBuildInfo();
var partialResult = emitEntryPoints(modules, entryPointsMap);
var cssInlinedResources = loader('vs/css').getInlinedResources();
loader(Object.keys(allMentionedModulesMap), () => {
const modules = loader.getBuildInfo();
const partialResult = emitEntryPoints(modules, entryPointsMap);
const cssInlinedResources = loader('vs/css').getInlinedResources();
callback(null, {
files: partialResult.files,
cssInlinedResources: cssInlinedResources,
bundleData: partialResult.bundleData
});
}, function (err) { return callback(err, null); });
}, (err) => callback(err, null));
}
exports.bundle = bundle;
function emitEntryPoints(modules, entryPoints) {
var modulesMap = {};
modules.forEach(function (m) {
const modulesMap = {};
modules.forEach((m) => {
modulesMap[m.id] = m;
});
var modulesGraph = {};
modules.forEach(function (m) {
const modulesGraph = {};
modules.forEach((m) => {
modulesGraph[m.id] = m.dependencies;
});
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
var bundleData = {
const sortedModules = topologicalSort(modulesGraph);
let result = [];
const usedPlugins = {};
const bundleData = {
graph: modulesGraph,
bundles: {}
};
Object.keys(entryPoints).forEach(function (moduleToBundle) {
var info = entryPoints[moduleToBundle];
var rootNodes = [moduleToBundle].concat(info.include || []);
var allDependencies = visit(rootNodes, modulesGraph);
var excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach(function (excludeRoot) {
var allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach(function (exclude) {
Object.keys(entryPoints).forEach((moduleToBundle) => {
const info = entryPoints[moduleToBundle];
const rootNodes = [moduleToBundle].concat(info.include || []);
const allDependencies = visit(rootNodes, modulesGraph);
const excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot) => {
const allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude) => {
delete allDependencies[exclude];
});
});
var includedModules = sortedModules.filter(function (module) {
const includedModules = sortedModules.filter((module) => {
return allDependencies[module];
});
bundleData.bundles[moduleToBundle] = includedModules;
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.append || [], info.dest);
const res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.append || [], info.dest);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
for (const pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
var write = function (filename, contents) {
const write = (filename, contents) => {
result.push({
dest: filename,
sources: [{
@ -128,16 +128,16 @@ function emitEntryPoints(modules, entryPoints) {
};
}
function extractStrings(destFiles) {
var parseDefineCall = function (moduleMatch, depsMatch) {
var module = moduleMatch.replace(/^"|"$/g, '');
var deps = depsMatch.split(',');
deps = deps.map(function (dep) {
const parseDefineCall = (moduleMatch, depsMatch) => {
const module = moduleMatch.replace(/^"|"$/g, '');
let deps = depsMatch.split(',');
deps = deps.map((dep) => {
dep = dep.trim();
dep = dep.replace(/^"|"$/g, '');
dep = dep.replace(/^'|'$/g, '');
var prefix = null;
var _path = null;
var pieces = dep.split('!');
let prefix = null;
let _path = null;
const pieces = dep.split('!');
if (pieces.length > 1) {
prefix = pieces[0] + '!';
_path = pieces[1];
@ -147,7 +147,7 @@ function extractStrings(destFiles) {
_path = pieces[0];
}
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
var res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
const res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
return prefix + res;
}
return prefix + _path;
@ -157,7 +157,7 @@ function extractStrings(destFiles) {
deps: deps
};
};
destFiles.forEach(function (destFile) {
destFiles.forEach((destFile) => {
if (!/\.js$/.test(destFile.dest)) {
return;
}
@ -165,44 +165,44 @@ function extractStrings(destFiles) {
return;
}
// Do one pass to record the usage counts for each module id
var useCounts = {};
destFile.sources.forEach(function (source) {
var matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
const useCounts = {};
destFile.sources.forEach((source) => {
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
if (!matches) {
return;
}
var defineCall = parseDefineCall(matches[1], matches[2]);
const defineCall = parseDefineCall(matches[1], matches[2]);
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
defineCall.deps.forEach(function (dep) {
defineCall.deps.forEach((dep) => {
useCounts[dep] = (useCounts[dep] || 0) + 1;
});
});
var sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort(function (a, b) {
const sortedByUseModules = Object.keys(useCounts);
sortedByUseModules.sort((a, b) => {
return useCounts[b] - useCounts[a];
});
var replacementMap = {};
sortedByUseModules.forEach(function (module, index) {
const replacementMap = {};
sortedByUseModules.forEach((module, index) => {
replacementMap[module] = index;
});
destFile.sources.forEach(function (source) {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, function (_, moduleMatch, depsMatch) {
var defineCall = parseDefineCall(moduleMatch, depsMatch);
return "define(__m[" + replacementMap[defineCall.module] + "/*" + defineCall.module + "*/], __M([" + defineCall.deps.map(function (dep) { return replacementMap[dep] + '/*' + dep + '*/'; }).join(',') + "])";
destFile.sources.forEach((source) => {
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
const defineCall = parseDefineCall(moduleMatch, depsMatch);
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
});
});
destFile.sources.unshift({
path: null,
contents: [
'(function() {',
"var __m = " + JSON.stringify(sortedByUseModules) + ";",
"var __M = function(deps) {",
" var result = [];",
" for (var i = 0, len = deps.length; i < len; i++) {",
" result[i] = __m[deps[i]];",
" }",
" return result;",
"};"
`var __m = ${JSON.stringify(sortedByUseModules)};`,
`var __M = function(deps) {`,
` var result = [];`,
` for (var i = 0, len = deps.length; i < len; i++) {`,
` result[i] = __m[deps[i]];`,
` }`,
` return result;`,
`};`
].join('\n')
});
destFile.sources.push({
@ -214,7 +214,7 @@ function extractStrings(destFiles) {
}
function removeDuplicateTSBoilerplate(destFiles) {
// Taken from typescript compiler => emitFiles
var BOILERPLATE = [
const BOILERPLATE = [
{ start: /^var __extends/, end: /^}\)\(\);$/ },
{ start: /^var __assign/, end: /^};$/ },
{ start: /^var __decorate/, end: /^};$/ },
@ -223,14 +223,14 @@ function removeDuplicateTSBoilerplate(destFiles) {
{ start: /^var __awaiter/, end: /^};$/ },
{ start: /^var __generator/, end: /^};$/ },
];
destFiles.forEach(function (destFile) {
var SEEN_BOILERPLATE = [];
destFile.sources.forEach(function (source) {
var lines = source.contents.split(/\r\n|\n|\r/);
var newLines = [];
var IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
destFiles.forEach((destFile) => {
const SEEN_BOILERPLATE = [];
destFile.sources.forEach((source) => {
const lines = source.contents.split(/\r\n|\n|\r/);
const newLines = [];
let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (IS_REMOVING_BOILERPLATE) {
newLines.push('');
if (END_BOILERPLATE.test(line)) {
@ -238,8 +238,8 @@ function removeDuplicateTSBoilerplate(destFiles) {
}
}
else {
for (var j = 0; j < BOILERPLATE.length; j++) {
var boilerplate = BOILERPLATE[j];
for (let j = 0; j < BOILERPLATE.length; j++) {
const boilerplate = BOILERPLATE[j];
if (boilerplate.start.test(line)) {
if (SEEN_BOILERPLATE[j]) {
IS_REMOVING_BOILERPLATE = true;
@ -267,30 +267,30 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
if (!dest) {
dest = entryPoint + '.js';
}
var mainResult = {
const mainResult = {
sources: [],
dest: dest
}, results = [mainResult];
var usedPlugins = {};
var getLoaderPlugin = function (pluginName) {
const usedPlugins = {};
const getLoaderPlugin = (pluginName) => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach(function (c) {
var bangIndex = c.indexOf('!');
includedModules.forEach((c) => {
const bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
var pluginName = c.substr(0, bangIndex);
var plugin = getLoaderPlugin(pluginName);
const pluginName = c.substr(0, bangIndex);
const plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
var module = modulesMap[c];
const module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
var contents = readFileAndRemoveBOM(module.path);
const contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
}
@ -298,14 +298,14 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
Object.keys(usedPlugins).forEach((pluginName) => {
const plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
var req = (function () {
const req = (() => {
throw new Error('no-no!');
});
req.toUrl = function (something) { return something; };
var write = function (filename, contents) {
req.toUrl = something => something;
const write = (filename, contents) => {
results.push({
dest: filename,
sources: [{
@ -317,15 +317,15 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
var toIFile = function (path) {
var contents = readFileAndRemoveBOM(path);
const toIFile = (path) => {
const contents = readFileAndRemoveBOM(path);
return {
path: path,
contents: contents
};
};
var toPrepend = (prepend || []).map(toIFile);
var toAppend = (append || []).map(toIFile);
const toPrepend = (prepend || []).map(toIFile);
const toAppend = (append || []).map(toIFile);
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
return {
files: results,
@ -333,8 +333,8 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
};
}
function readFileAndRemoveBOM(path) {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
const BOM_CHAR_CODE = 65279;
let contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
@ -342,15 +342,15 @@ function readFileAndRemoveBOM(path) {
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
var result = '';
let result = '';
if (typeof plugin.write === 'function') {
var write = (function (what) {
const write = ((what) => {
result += what;
});
write.getEntryPoint = function () {
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = function (moduleId, code) {
write.asModule = (moduleId, code) => {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
@ -363,18 +363,18 @@ function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
}
function emitNamedModule(moduleId, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
var parensOffset = contents.indexOf('(', defineCallOffset);
var insertStr = '"' + moduleId + '", ';
const parensOffset = contents.indexOf('(', defineCallOffset);
const insertStr = '"' + moduleId + '", ';
return {
path: path,
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
};
}
function emitShimmedModule(moduleId, myDeps, factory, path, contents) {
var strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
var strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
@ -387,8 +387,8 @@ function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
var line = 1;
var lastNewLineOffset = -1;
let line = 1;
let lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
@ -402,15 +402,15 @@ function positionToOffset(str, desiredLine, desiredCol) {
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
var result = {};
var queue = rootNodes;
rootNodes.forEach(function (node) {
const result = {};
const queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
var el = queue.shift();
var myEdges = graph[el] || [];
myEdges.forEach(function (toNode) {
const el = queue.shift();
const myEdges = graph[el] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
@ -423,11 +423,11 @@ function visit(rootNodes, graph) {
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach(function (fromNode) {
const allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach((fromNode) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach(function (toNode) {
graph[fromNode].forEach((toNode) => {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
@ -435,8 +435,8 @@ function topologicalSort(graph) {
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
var S = [], L = [];
Object.keys(allNodes).forEach(function (node) {
const S = [], L = [];
Object.keys(allNodes).forEach((node) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
@ -445,10 +445,10 @@ function topologicalSort(graph) {
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
var n = S.shift();
const n = S.shift();
L.push(n);
var myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach(function (m) {
const myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];

View file

@ -4,27 +4,26 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var fs = require("fs");
var gulp = require("gulp");
var bom = require("gulp-bom");
var sourcemaps = require("gulp-sourcemaps");
var tsb = require("gulp-tsb");
var path = require("path");
var _ = require("underscore");
var monacodts = require("../monaco/api");
var nls = require("./nls");
var reporter_1 = require("./reporter");
var util = require("./util");
var watch = require('./watch');
var assign = require("object-assign");
var reporter = reporter_1.createReporter();
const es = require("event-stream");
const fs = require("fs");
const gulp = require("gulp");
const bom = require("gulp-bom");
const sourcemaps = require("gulp-sourcemaps");
const tsb = require("gulp-tsb");
const path = require("path");
const _ = require("underscore");
const monacodts = require("../monaco/api");
const nls = require("./nls");
const reporter_1 = require("./reporter");
const util = require("./util");
const watch = require('./watch');
const reporter = reporter_1.createReporter();
function getTypeScriptCompilerOptions(src) {
var rootDir = path.join(__dirname, "../../" + src);
var tsconfig = require("../../" + src + "/tsconfig.json");
var options;
const rootDir = path.join(__dirname, `../../${src}`);
const tsconfig = require(`../../${src}/tsconfig.json`);
let options;
if (tsconfig.extends) {
options = assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
}
else {
options = tsconfig.compilerOptions;
@ -41,16 +40,16 @@ function getTypeScriptCompilerOptions(src) {
return options;
}
function createCompile(src, build, emitError) {
var opts = _.clone(getTypeScriptCompilerOptions(src));
const opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
var ts = tsb.create(opts, true, undefined, function (err) { return reporter(err.toString()); });
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
return function (token) {
var utf8Filter = util.filter(function (data) { return /(\/|\\)test(\/|\\).*utf8/.test(data.path); });
var tsFilter = util.filter(function (data) { return /\.ts$/.test(data.path); });
var noDeclarationsFilter = util.filter(function (data) { return !(/\.d\.ts$/.test(data.path)); });
var input = es.through();
var output = input
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path)));
const input = es.through();
const output = input
.pipe(utf8Filter)
.pipe(bom())
.pipe(utf8Filter.restore)
@ -70,7 +69,7 @@ function createCompile(src, build, emitError) {
return es.duplex(input, output);
};
}
var typesDts = [
const typesDts = [
'node_modules/typescript/lib/*.d.ts',
'node_modules/@types/**/*.d.ts',
'!node_modules/@types/webpack/**/*',
@ -78,10 +77,10 @@ var typesDts = [
];
function compileTask(src, out, build) {
return function () {
var compile = createCompile(src, build, true);
var srcPipe = es.merge(gulp.src(src + "/**", { base: "" + src }), gulp.src(typesDts));
const compile = createCompile(src, build, true);
const srcPipe = es.merge(gulp.src(`${src}/**`, { base: `${src}` }), gulp.src(typesDts));
// 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); });
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
return srcPipe
.pipe(compile())
.pipe(dtsFilter)
@ -93,11 +92,11 @@ function compileTask(src, out, build) {
exports.compileTask = compileTask;
function watchTask(out, build) {
return function () {
var compile = createCompile('src', build);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
var watchSrc = watch('src/**', { base: 'src' });
const compile = createCompile('src', build);
const src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
const watchSrc = watch('src/**', { base: 'src' });
// 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); });
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
return watchSrc
.pipe(util.incremental(compile, src, true))
.pipe(dtsFilter)
@ -108,33 +107,33 @@ function watchTask(out, build) {
}
exports.watchTask = watchTask;
function monacodtsTask(out, isWatch) {
var basePath = path.resolve(process.cwd(), out);
var neededFiles = {};
const basePath = path.resolve(process.cwd(), out);
const neededFiles = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
neededFiles[filePath] = true;
});
var inputFiles = {};
for (var filePath in neededFiles) {
const inputFiles = {};
for (const filePath in neededFiles) {
if (/\bsrc(\/|\\)vs\b/.test(filePath)) {
// This file is needed from source => simply read it now
inputFiles[filePath] = fs.readFileSync(filePath).toString();
}
}
var setInputFile = function (filePath, contents) {
const setInputFile = (filePath, contents) => {
if (inputFiles[filePath] === contents) {
// no change
return;
}
inputFiles[filePath] = contents;
var neededInputFilesCount = Object.keys(neededFiles).length;
var availableInputFilesCount = Object.keys(inputFiles).length;
const neededInputFilesCount = Object.keys(neededFiles).length;
const availableInputFilesCount = Object.keys(inputFiles).length;
if (neededInputFilesCount === availableInputFilesCount) {
run();
}
};
var run = function () {
var result = monacodts.run(out, inputFiles);
const run = () => {
const result = monacodts.run(out, inputFiles);
if (!result.isTheSame) {
if (isWatch) {
fs.writeFileSync(result.filePath, result.content);
@ -145,14 +144,14 @@ function monacodtsTask(out, isWatch) {
}
}
};
var resultStream;
let resultStream;
if (isWatch) {
watch('build/monaco/*').pipe(es.through(function () {
run();
}));
}
resultStream = es.through(function (data) {
var filePath = path.normalize(path.resolve(basePath, data.relative));
const filePath = path.normalize(path.resolve(basePath, data.relative));
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}

View file

@ -18,7 +18,6 @@ import * as nls from './nls';
import { createReporter } from './reporter';
import * as util from './util';
const watch = require('./watch');
import assign = require('object-assign');
const reporter = createReporter();
@ -27,7 +26,7 @@ function getTypeScriptCompilerOptions(src: string) {
const tsconfig = require(`../../${src}/tsconfig.json`);
let options: { [key: string]: any };
if (tsconfig.extends) {
options = assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
} else {
options = tsconfig.compilerOptions;
}

View file

@ -3,39 +3,28 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var fs = require("fs");
var glob = require("glob");
var gulp = require("gulp");
var path = require("path");
var File = require("vinyl");
var vsce = require("vsce");
var stats_1 = require("./stats");
var util2 = require("./util");
var remote = require("gulp-remote-src");
var vzip = require('gulp-vinyl-zip');
var filter = require("gulp-filter");
var rename = require("gulp-rename");
var util = require('gulp-util');
var buffer = require('gulp-buffer');
var json = require("gulp-json-editor");
var webpack = require('webpack');
var webpackGulp = require('webpack-stream');
var root = path.resolve(path.join(__dirname, '..', '..'));
const es = require("event-stream");
const fs = require("fs");
const glob = require("glob");
const gulp = require("gulp");
const path = require("path");
const File = require("vinyl");
const vsce = require("vsce");
const stats_1 = require("./stats");
const util2 = require("./util");
const remote = require("gulp-remote-src");
const vzip = require('gulp-vinyl-zip');
const filter = require("gulp-filter");
const rename = require("gulp-rename");
const util = require('gulp-util');
const buffer = require('gulp-buffer');
const json = require("gulp-json-editor");
const webpack = require('webpack');
const webpackGulp = require('webpack-stream');
const root = path.resolve(path.join(__dirname, '..', '..'));
function fromLocal(extensionPath, sourceMappingURLBase) {
var webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
if (fs.existsSync(webpackFilename)) {
return fromLocalWebpack(extensionPath, sourceMappingURLBase);
}
@ -44,30 +33,30 @@ function fromLocal(extensionPath, sourceMappingURLBase) {
}
}
function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
var result = es.through();
var packagedDependencies = [];
var packageJsonConfig = require(path.join(extensionPath, 'package.json'));
var webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
for (var key in webpackRootConfig.externals) {
const result = es.through();
const packagedDependencies = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
for (const key in webpackRootConfig.externals) {
if (key in packageJsonConfig.dependencies) {
packagedDependencies.push(key);
}
}
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies: packagedDependencies }).then(function (fileNames) {
var files = fileNames
.map(function (fileName) { return path.join(extensionPath, fileName); })
.map(function (filePath) { return new File({
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
.map(filePath => new File({
path: filePath,
stat: fs.statSync(filePath),
base: extensionPath,
contents: fs.createReadStream(filePath)
}); });
var filesStream = es.readArray(files);
}));
const filesStream = es.readArray(files);
// check for a webpack configuration files, then invoke webpack
// and merge its output with the files stream. also rewrite the package.json
// file to a new entry point
var webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
var packageJsonFilter = filter(function (f) {
const webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
const packageJsonFilter = filter(f => {
if (path.basename(f.path) === 'package.json') {
// only modify package.json's next to the webpack file.
// to be safe, use existsSync instead of path comparison.
@ -75,22 +64,22 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
}
return false;
}, { restore: true });
var patchFilesStream = filesStream
const patchFilesStream = filesStream
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json(function (data) {
.pipe(json((data) => {
// hardcoded entry point directory!
data.main = data.main.replace('/out/', /dist/);
return data;
}))
.pipe(packageJsonFilter.restore);
var webpackStreams = webpackConfigLocations.map(function (webpackConfigPath) {
var webpackDone = function (err, stats) {
util.log("Bundled extension: " + util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath))) + "...");
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
const webpackDone = (err, stats) => {
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
if (err) {
result.emit('error', err);
}
var compilation = stats.compilation;
const { compilation } = stats;
if (compilation.errors.length > 0) {
result.emit('error', compilation.errors.join('\n'));
}
@ -98,8 +87,8 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
result.emit('error', compilation.warnings.join('\n'));
}
};
var webpackConfig = __assign({}, require(webpackConfigPath), { mode: 'production' });
var relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
const webpackConfig = Object.assign({}, require(webpackConfigPath), { mode: 'production' });
const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
return webpackGulp(webpackConfig, webpack, webpackDone)
.pipe(es.through(function (data) {
data.stat = data.stat || {};
@ -111,9 +100,9 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
// * rewrite sourceMappingURL
// * save to disk so that upload-task picks this up
if (sourceMappingURLBase) {
var contents = data.contents.toString('utf8');
const contents = data.contents.toString('utf8');
data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) {
return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/" + relativeOutputPath + "/" + g1;
return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`;
}), 'utf8');
if (/\.js\.map$/.test(data.path)) {
if (!fs.existsSync(path.dirname(data.path))) {
@ -125,8 +114,14 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
this.emit('data', data);
}));
});
es.merge.apply(es, webpackStreams.concat([patchFilesStream])).pipe(result);
}).catch(function (err) {
es.merge(...webpackStreams, patchFilesStream)
// .pipe(es.through(function (data) {
// // debug
// console.log('out', data.path, data.contents.length);
// this.emit('data', data);
// }))
.pipe(result);
}).catch(err => {
console.error(extensionPath);
console.error(packagedDependencies);
result.emit('error', err);
@ -134,56 +129,56 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
}
function fromLocalNormal(extensionPath) {
var result = es.through();
const result = es.through();
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
.then(function (fileNames) {
var files = fileNames
.map(function (fileName) { return path.join(extensionPath, fileName); })
.map(function (filePath) { return new File({
.then(fileNames => {
const files = fileNames
.map(fileName => path.join(extensionPath, fileName))
.map(filePath => new File({
path: filePath,
stat: fs.statSync(filePath),
base: extensionPath,
contents: fs.createReadStream(filePath)
}); });
}));
es.readArray(files).pipe(result);
})
.catch(function (err) { return result.emit('error', err); });
.catch(err => result.emit('error', err));
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
}
var baseHeaders = {
const baseHeaders = {
'X-Market-Client-Id': 'VSCode Build',
'User-Agent': 'VSCode Build',
'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2',
};
function fromMarketplace(extensionName, version, metadata) {
var _a = extensionName.split('.'), publisher = _a[0], name = _a[1];
var url = "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/" + publisher + "/vsextensions/" + name + "/" + version + "/vspackage";
util.log('Downloading extension:', util.colors.yellow(extensionName + "@" + version), '...');
var options = {
const [publisher, name] = extensionName.split('.');
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: url,
requestOptions: {
gzip: true,
headers: baseHeaders
}
};
var packageJsonFilter = filter('package.json', { restore: true });
const packageJsonFilter = filter('package.json', { restore: true });
return remote('', options)
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(function (p) { return p.dirname = p.dirname.replace(/^extension\/?/, ''); }))
.pipe(rename(p => p.dirname = p.dirname.replace(/^extension\/?/, '')))
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json({ __metadata: metadata }))
.pipe(packageJsonFilter.restore);
}
exports.fromMarketplace = fromMarketplace;
var excludedExtensions = [
const excludedExtensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
];
var builtInExtensions = require('../builtInExtensions.json');
const builtInExtensions = require('../builtInExtensions.json');
/**
* We're doing way too much stuff at once, with webpack et al. So much stuff
* that while downloading extensions from the marketplace, node js doesn't get enough
@ -191,13 +186,13 @@ var builtInExtensions = require('../builtInExtensions.json');
* marketplace server cuts off the http request. So, we sequentialize the extensino tasks.
*/
function sequence(streamProviders) {
var result = es.through();
const result = es.through();
function pop() {
if (streamProviders.length === 0) {
result.emit('end');
}
else {
var fn = streamProviders.shift();
const fn = streamProviders.shift();
fn()
.on('end', function () { setTimeout(pop, 0); })
.pipe(result, { end: false });
@ -207,39 +202,27 @@ function sequence(streamProviders) {
return result;
}
function packageExtensionsStream(optsIn) {
var opts = optsIn || {};
var localExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(function (manifestPath) {
var extensionPath = path.dirname(path.join(root, manifestPath));
var extensionName = path.basename(extensionPath);
const opts = optsIn || {};
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(manifestPath => {
const extensionPath = path.dirname(path.join(root, manifestPath));
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
})
.filter(function (_a) {
var name = _a.name;
return excludedExtensions.indexOf(name) === -1;
})
.filter(function (_a) {
var name = _a.name;
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
})
.filter(function (_a) {
var name = _a.name;
return builtInExtensions.every(function (b) { return b.name !== name; });
});
var localExtensions = function () { return es.merge.apply(es, localExtensionDescriptions.map(function (extension) {
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
const localExtensions = () => es.merge(...localExtensionDescriptions.map(extension => {
return fromLocal(extension.path, opts.sourceMappingURLBase)
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
})); };
var localExtensionDependencies = function () { return gulp.src('extensions/node_modules/**', { base: '.' }); };
var marketplaceExtensions = function () { return es.merge.apply(es, builtInExtensions
.filter(function (_a) {
var name = _a.name;
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
})
.map(function (extension) {
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' });
const marketplaceExtensions = () => es.merge(...builtInExtensions
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.map(extension => {
return fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
})); };
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions])
.pipe(util2.setExecutableBit(['**/*.sh']))
.pipe(filter(['**', '!**/*.js.map']));

View file

@ -4,15 +4,15 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var fs = require("fs");
const path = require("path");
const fs = require("fs");
/**
* Returns the sha1 commit version of a repository or undefined in case of failure.
*/
function getVersion(repo) {
var git = path.join(repo, '.git');
var headPath = path.join(git, 'HEAD');
var head;
const git = path.join(repo, '.git');
const headPath = path.join(git, 'HEAD');
let head;
try {
head = fs.readFileSync(headPath, 'utf8').trim();
}
@ -22,29 +22,29 @@ function getVersion(repo) {
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
var refMatch = /^ref: (.*)$/.exec(head);
const refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
}
var ref = refMatch[1];
var refPath = path.join(git, ref);
const ref = refMatch[1];
const refPath = path.join(git, ref);
try {
return fs.readFileSync(refPath, 'utf8').trim();
}
catch (e) {
// noop
}
var packedRefsPath = path.join(git, 'packed-refs');
var refsRaw;
const packedRefsPath = path.join(git, 'packed-refs');
let refsRaw;
try {
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
}
catch (e) {
return void 0;
}
var refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
var refsMatch;
var refs = {};
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
let refsMatch;
let refs = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];
}

File diff suppressed because it is too large Load diff

View file

@ -348,7 +348,7 @@ export interface ITask<T> {
interface ILimitedTaskFactory<T> {
factory: ITask<Promise<T>>;
c: (value?: T | Thenable<T>) => void;
c: (value?: T | Promise<T>) => void;
e: (error?: any) => void;
}

View file

@ -3,13 +3,12 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var ts = require("typescript");
var lazy = require("lazy.js");
var event_stream_1 = require("event-stream");
var File = require("vinyl");
var sm = require("source-map");
var assign = require("object-assign");
var path = require("path");
const ts = require("typescript");
const lazy = require("lazy.js");
const event_stream_1 = require("event-stream");
const File = require("vinyl");
const sm = require("source-map");
const path = require("path");
var CollectStepResult;
(function (CollectStepResult) {
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
@ -18,9 +17,9 @@ var CollectStepResult;
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
})(CollectStepResult || (CollectStepResult = {}));
function collect(node, fn) {
var result = [];
const result = [];
function loop(node) {
var stepResult = fn(node);
const stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
@ -32,43 +31,45 @@ function collect(node, fn) {
return result;
}
function clone(object) {
var result = {};
for (var id in object) {
const result = {};
for (const id in object) {
result[id] = object[id];
}
return result;
}
function template(lines) {
var indent = '', wrap = '';
let indent = '', wrap = '';
if (lines.length > 1) {
indent = '\t';
wrap = '\n';
}
return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);";
return `/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
define([], [${wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
}
/**
* Returns a stream containing the patched JavaScript and source maps.
*/
function nls() {
var input = event_stream_1.through();
var output = input.pipe(event_stream_1.through(function (f) {
var _this = this;
const input = event_stream_1.through();
const output = input.pipe(event_stream_1.through(function (f) {
if (!f.sourceMap) {
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`));
}
var source = f.sourceMap.sources[0];
let source = f.sourceMap.sources[0];
if (!source) {
return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map."));
return this.emit('error', new Error(`File ${f.relative} does not have a source in the source map.`));
}
var root = f.sourceMap.sourceRoot;
const root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
var typescript = f.sourceMap.sourcesContent[0];
const typescript = f.sourceMap.sourcesContent[0];
if (!typescript) {
return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map."));
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
}
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
}));
return event_stream_1.duplex(input, output);
}
@ -76,8 +77,7 @@ function isImportNode(node) {
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
}
(function (nls_1) {
function fileFrom(file, contents, path) {
if (path === void 0) { path = file.path; }
function fileFrom(file, contents, path = file.path) {
return new File({
contents: Buffer.from(contents),
base: file.base,
@ -87,29 +87,27 @@ function isImportNode(node) {
}
nls_1.fileFrom = fileFrom;
function mappedPositionFrom(source, lc) {
return { source: source, line: lc.line + 1, column: lc.character };
return { source, line: lc.line + 1, column: lc.character };
}
nls_1.mappedPositionFrom = mappedPositionFrom;
function lcFrom(position) {
return { line: position.line - 1, character: position.column };
}
nls_1.lcFrom = lcFrom;
var SingleFileServiceHost = /** @class */ (function () {
function SingleFileServiceHost(options, filename, contents) {
var _this = this;
class SingleFileServiceHost {
constructor(options, filename, contents) {
this.options = options;
this.filename = filename;
this.getCompilationSettings = function () { return _this.options; };
this.getScriptFileNames = function () { return [_this.filename]; };
this.getScriptVersion = function () { return '1'; };
this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; };
this.getCurrentDirectory = function () { return ''; };
this.getDefaultLibFileName = function () { return 'lib.d.ts'; };
this.getCompilationSettings = () => this.options;
this.getScriptFileNames = () => [this.filename];
this.getScriptVersion = () => '1';
this.getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib;
this.getCurrentDirectory = () => '';
this.getDefaultLibFileName = () => 'lib.d.ts';
this.file = ts.ScriptSnapshot.fromString(contents);
this.lib = ts.ScriptSnapshot.fromString('');
}
return SingleFileServiceHost;
}());
}
nls_1.SingleFileServiceHost = SingleFileServiceHost;
function isCallExpressionWithinTextSpanCollectStep(textSpan, node) {
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
@ -117,97 +115,96 @@ function isImportNode(node) {
}
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
}
function analyze(contents, options) {
if (options === void 0) { options = {}; }
var filename = 'file.ts';
var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
var service = ts.createLanguageService(serviceHost);
var sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
function analyze(contents, options = {}) {
const filename = 'file.ts';
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
const service = ts.createLanguageService(serviceHost);
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
// all imports
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
// import nls = require('vs/nls');
var importEqualsDeclarations = imports
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportEqualsDeclaration; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference; })
.filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; });
const importEqualsDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
.map(n => n)
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
.filter(d => d.moduleReference.expression.getText() === '\'vs/nls\'');
// import ... from 'vs/nls';
var importDeclarations = imports
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportDeclaration; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral; })
.filter(function (d) { return d.moduleSpecifier.getText() === '\'vs/nls\''; })
.filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; });
var nlsExpressions = importEqualsDeclarations
.map(function (d) { return d.moduleReference.expression; })
.concat(importDeclarations.map(function (d) { return d.moduleSpecifier; }))
.map(function (d) { return ({
const importDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
.map(n => n)
.filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral)
.filter(d => d.moduleSpecifier.getText() === '\'vs/nls\'')
.filter(d => !!d.importClause && !!d.importClause.namedBindings);
const nlsExpressions = importEqualsDeclarations
.map(d => d.moduleReference.expression)
.concat(importDeclarations.map(d => d.moduleSpecifier))
.map(d => ({
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
}); });
}));
// `nls.localize(...)` calls
var nlsLocalizeCallExpressions = importDeclarations
.filter(function (d) { return !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport); })
.map(function (d) { return d.importClause.namedBindings.name; })
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
const nlsLocalizeCallExpressions = importDeclarations
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport))
.map(d => d.importClause.namedBindings.name)
.concat(importEqualsDeclarations.map(d => d.name))
// find read-only references to `nls`
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; })
.filter(r => !r.isWriteAccess)
// find the deepest call expressions AST nodes that contain those references
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
.map(function (a) { return lazy(a).last(); })
.filter(function (n) { return !!n; })
.map(function (n) { return n; })
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => n)
// only `localize` calls
.filter(function (n) { return n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize'; });
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize');
// `localize` named imports
var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports); })
.map(function (d) { return [].concat(d.importClause.namedBindings.elements); })
const allLocalizeImportDeclarations = importDeclarations
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports))
.map(d => [].concat(d.importClause.namedBindings.elements))
.flatten();
// `localize` read-only references
var localizeReferences = allLocalizeImportDeclarations
.filter(function (d) { return d.name.getText() === 'localize'; })
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
const localizeReferences = allLocalizeImportDeclarations
.filter(d => d.name.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
.filter(r => !r.isWriteAccess);
// custom named `localize` read-only references
var namedLocalizeReferences = allLocalizeImportDeclarations
.filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; })
.map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); })
const namedLocalizeReferences = allLocalizeImportDeclarations
.filter(d => d.propertyName && d.propertyName.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.name.pos + 1))
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
.filter(r => !r.isWriteAccess);
// find the deepest call expressions AST nodes that contain those references
var localizeCallExpressions = localizeReferences
const localizeCallExpressions = localizeReferences
.concat(namedLocalizeReferences)
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
.map(function (a) { return lazy(a).last(); })
.filter(function (n) { return !!n; })
.map(function (n) { return n; });
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => n);
// collect everything
var localizeCalls = nlsLocalizeCallExpressions
const localizeCalls = nlsLocalizeCallExpressions
.concat(localizeCallExpressions)
.map(function (e) { return e.arguments; })
.filter(function (a) { return a.length > 1; })
.sort(function (a, b) { return a[0].getStart() - b[0].getStart(); })
.map(function (a) { return ({
.map(e => e.arguments)
.filter(a => a.length > 1)
.sort((a, b) => a[0].getStart() - b[0].getStart())
.map(a => ({
keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) },
key: a[0].getText(),
valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) },
value: a[1].getText()
}); });
}));
return {
localizeCalls: localizeCalls.toArray(),
nlsExpressions: nlsExpressions.toArray()
};
}
nls_1.analyze = analyze;
var TextModel = /** @class */ (function () {
function TextModel(contents) {
var regex = /\r\n|\r|\n/g;
var index = 0;
var match;
class TextModel {
constructor(contents) {
const regex = /\r\n|\r|\n/g;
let index = 0;
let match;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
@ -220,85 +217,80 @@ function isImportNode(node) {
this.lineEndings.push('');
}
}
TextModel.prototype.get = function (index) {
get(index) {
return this.lines[index];
};
TextModel.prototype.set = function (index, line) {
}
set(index, line) {
this.lines[index] = line;
};
Object.defineProperty(TextModel.prototype, "lineCount", {
get: function () {
return this.lines.length;
},
enumerable: true,
configurable: true
});
}
get lineCount() {
return this.lines.length;
}
/**
* Applies patch(es) to the model.
* Multiple patches must be ordered.
* Does not support patches spanning multiple lines.
*/
TextModel.prototype.apply = function (patch) {
var startLineNumber = patch.span.start.line;
var endLineNumber = patch.span.end.line;
var startLine = this.lines[startLineNumber] || '';
var endLine = this.lines[endLineNumber] || '';
apply(patch) {
const startLineNumber = patch.span.start.line;
const endLineNumber = patch.span.end.line;
const startLine = this.lines[startLineNumber] || '';
const endLine = this.lines[endLineNumber] || '';
this.lines[startLineNumber] = [
startLine.substring(0, patch.span.start.character),
patch.content,
endLine.substring(patch.span.end.character)
].join('');
for (var i = startLineNumber + 1; i <= endLineNumber; i++) {
for (let i = startLineNumber + 1; i <= endLineNumber; i++) {
this.lines[i] = '';
}
};
TextModel.prototype.toString = function () {
}
toString() {
return lazy(this.lines).zip(this.lineEndings)
.flatten().toArray().join('');
};
return TextModel;
}());
}
}
nls_1.TextModel = TextModel;
function patchJavascript(patches, contents, moduleId) {
var model = new nls.TextModel(contents);
const model = new nls.TextModel(contents);
// patch the localize calls
lazy(patches).reverse().each(function (p) { return model.apply(p); });
lazy(patches).reverse().each(p => model.apply(p));
// patch the 'vs/nls' imports
var firstLine = model.get(0);
var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
const firstLine = model.get(0);
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
model.set(0, patchedFirstLine);
return model.toString();
}
nls_1.patchJavascript = patchJavascript;
function patchSourcemap(patches, rsm, smc) {
var smg = new sm.SourceMapGenerator({
const smg = new sm.SourceMapGenerator({
file: rsm.file,
sourceRoot: rsm.sourceRoot
});
patches = patches.reverse();
var currentLine = -1;
var currentLineDiff = 0;
var source = null;
smc.eachMapping(function (m) {
var patch = patches[patches.length - 1];
var original = { line: m.originalLine, column: m.originalColumn };
var generated = { line: m.generatedLine, column: m.generatedColumn };
let currentLine = -1;
let currentLineDiff = 0;
let source = null;
smc.eachMapping(m => {
const patch = patches[patches.length - 1];
const original = { line: m.originalLine, column: m.originalColumn };
const generated = { line: m.generatedLine, column: m.generatedColumn };
if (currentLine !== generated.line) {
currentLineDiff = 0;
}
currentLine = generated.line;
generated.column += currentLineDiff;
if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
var originalLength = patch.span.end.character - patch.span.start.character;
var modifiedLength = patch.content.length;
var lengthDiff = modifiedLength - originalLength;
const originalLength = patch.span.end.character - patch.span.start.character;
const modifiedLength = patch.content.length;
const lengthDiff = modifiedLength - originalLength;
currentLineDiff += lengthDiff;
generated.column += lengthDiff;
patches.pop();
}
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
source = source.replace(/\\/g, '/');
smg.addMapping({ source: source, name: m.name, original: original, generated: generated });
smg.addMapping({ source, name: m.name, original, generated });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
@ -307,47 +299,47 @@ function isImportNode(node) {
}
nls_1.patchSourcemap = patchSourcemap;
function patch(moduleId, typescript, javascript, sourcemap) {
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
const { localizeCalls, nlsExpressions } = analyze(typescript);
if (localizeCalls.length === 0) {
return { javascript: javascript, sourcemap: sourcemap };
return { javascript, sourcemap };
}
var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; }));
var nls = template(localizeCalls.map(function (lc) { return lc.value; }));
var smc = new sm.SourceMapConsumer(sourcemap);
var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
var i = 0;
const nlsKeys = template(localizeCalls.map(lc => lc.key));
const nls = template(localizeCalls.map(lc => lc.value));
const smc = new sm.SourceMapConsumer(sourcemap);
const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
let i = 0;
// build patches
var patches = lazy(localizeCalls)
.map(function (lc) { return ([
const patches = lazy(localizeCalls)
.map(lc => ([
{ range: lc.keySpan, content: '' + (i++) },
{ range: lc.valueSpan, content: 'null' }
]); })
]))
.flatten()
.map(function (c) {
var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
return { span: { start: start, end: end }, content: c.content };
.map(c => {
const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
return { span: { start, end }, content: c.content };
})
.toArray();
javascript = patchJavascript(patches, javascript, moduleId);
// since imports are not within the sourcemap information,
// we must do this MacGyver style
if (nlsExpressions.length) {
javascript = javascript.replace(/^define\(.*$/m, function (line) {
return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
javascript = javascript.replace(/^define\(.*$/m, line => {
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
return { javascript, sourcemap, nlsKeys, nls };
}
nls_1.patch = patch;
function patchFiles(javascriptFile, typescript) {
// hack?
var moduleId = javascriptFile.relative
const moduleId = javascriptFile.relative
.replace(/\.js$/, '')
.replace(/\\/g, '/');
var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls;
var result = [fileFrom(javascriptFile, javascript)];
const { javascript, sourcemap, nlsKeys, nls } = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap);
const result = [fileFrom(javascriptFile, javascript)];
result[0].sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));

View file

@ -8,7 +8,6 @@ import * as lazy from 'lazy.js';
import { duplex, through } from 'event-stream';
import * as File from 'vinyl';
import * as sm from 'source-map';
import assign = require('object-assign');
import * as path from 'path';
declare class FileSourceMap extends File {
@ -174,7 +173,7 @@ module nls {
export function analyze(contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
const filename = 'file.ts';
const serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
const service = ts.createLanguageService(serviceHost);
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);

View file

@ -4,30 +4,30 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var gulp = require("gulp");
var concat = require("gulp-concat");
var minifyCSS = require("gulp-cssnano");
var filter = require("gulp-filter");
var flatmap = require("gulp-flatmap");
var sourcemaps = require("gulp-sourcemaps");
var uglify = require("gulp-uglify");
var composer = require("gulp-uglify/composer");
var gulpUtil = require("gulp-util");
var path = require("path");
var pump = require("pump");
var uglifyes = require("uglify-es");
var VinylFile = require("vinyl");
var bundle = require("./bundle");
var i18n_1 = require("./i18n");
var stats_1 = require("./stats");
var util = require("./util");
var REPO_ROOT_PATH = path.join(__dirname, '../..');
const es = require("event-stream");
const gulp = require("gulp");
const concat = require("gulp-concat");
const minifyCSS = require("gulp-cssnano");
const filter = require("gulp-filter");
const flatmap = require("gulp-flatmap");
const sourcemaps = require("gulp-sourcemaps");
const uglify = require("gulp-uglify");
const composer = require("gulp-uglify/composer");
const gulpUtil = require("gulp-util");
const path = require("path");
const pump = require("pump");
const uglifyes = require("uglify-es");
const VinylFile = require("vinyl");
const bundle = require("./bundle");
const i18n_1 = require("./i18n");
const stats_1 = require("./stats");
const util = require("./util");
const REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
}
function loaderConfig(emptyPaths) {
var result = {
const result = {
paths: {
'vs': 'out-build/vs',
'vscode': 'empty:'
@ -38,20 +38,20 @@ function loaderConfig(emptyPaths) {
return result;
}
exports.loaderConfig = loaderConfig;
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
function loader(src, bundledFileHeader, bundleLoader) {
var sources = [
src + "/vs/loader.js"
let sources = [
`${src}/vs/loader.js`
];
if (bundleLoader) {
sources = sources.concat([
src + "/vs/css.js",
src + "/vs/nls.js"
`${src}/vs/css.js`,
`${src}/vs/nls.js`
]);
}
var isFirst = true;
let isFirst = true;
return (gulp
.src(sources, { base: "" + src })
.src(sources, { base: `${src}` })
.pipe(es.through(function (data) {
if (isFirst) {
isFirst = false;
@ -74,12 +74,12 @@ function loader(src, bundledFileHeader, bundleLoader) {
})));
}
function toConcatStream(src, bundledFileHeader, sources, dest) {
var useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
const 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
var containsOurCopyright = false;
for (var i = 0, len = sources.length; i < len; i++) {
var fileContents = sources[i].contents;
let containsOurCopyright = false;
for (let i = 0, len = sources.length; i < len; i++) {
const fileContents = sources[i].contents;
if (IS_OUR_COPYRIGHT_REGEXP.test(fileContents)) {
containsOurCopyright = true;
break;
@ -91,9 +91,9 @@ function toConcatStream(src, bundledFileHeader, sources, dest) {
contents: bundledFileHeader
});
}
var treatedSources = sources.map(function (source) {
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
var base = source.path ? root + ("/" + src) : '';
const treatedSources = sources.map(function (source) {
const root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
const base = source.path ? root + `/${src}` : '';
return new VinylFile({
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
base: base,
@ -111,33 +111,33 @@ function toBundleStream(src, bundledFileHeader, bundles) {
}));
}
function optimizeTask(opts) {
var src = opts.src;
var entryPoints = opts.entryPoints;
var otherSources = opts.otherSources;
var resources = opts.resources;
var loaderConfig = opts.loaderConfig;
var bundledFileHeader = opts.header;
var bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
var out = opts.out;
const src = opts.src;
const entryPoints = opts.entryPoints;
const otherSources = opts.otherSources;
const resources = opts.resources;
const loaderConfig = opts.loaderConfig;
const bundledFileHeader = opts.header;
const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
const out = opts.out;
return function () {
var bundlesStream = es.through(); // this stream will contain the bundled files
var resourcesStream = es.through(); // this stream will contain the resources
var bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
const bundlesStream = es.through(); // this stream will contain the bundled files
const resourcesStream = es.through(); // this stream will contain the resources
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err || !result) {
return bundlesStream.emit('error', JSON.stringify(err));
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
var filteredResources = resources.slice();
const filteredResources = resources.slice();
result.cssInlinedResources.forEach(function (resource) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log('optimizer', 'excluding inlined: ' + resource);
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: "" + src }).pipe(resourcesStream);
var bundleInfoArray = [];
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
const bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
path: 'bundleInfo.json',
@ -147,9 +147,9 @@ function optimizeTask(opts) {
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
var otherSourcesStream = es.through();
var otherSourcesStreamArr = [];
gulp.src(otherSources, { base: "" + src })
const otherSourcesStream = es.through();
const otherSourcesStreamArr = [];
gulp.src(otherSources, { base: `${src}` })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
@ -160,7 +160,7 @@ function optimizeTask(opts) {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
var result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
const result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: undefined,
@ -180,14 +180,14 @@ exports.optimizeTask = optimizeTask;
* to have a file "context" to include our copyright only once per file.
*/
function uglifyWithCopyrights() {
var preserveComments = function (f) {
return function (_node, comment) {
var text = comment.value;
var type = comment.type;
const preserveComments = (f) => {
return (_node, comment) => {
const text = comment.value;
const type = comment.type;
if (/@minifier_do_not_preserve/.test(text)) {
return false;
}
var isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
const isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
if (isOurCopyright) {
if (f.__hasOurCopyright) {
return false;
@ -205,10 +205,10 @@ function uglifyWithCopyrights() {
return false;
};
};
var minify = composer(uglifyes);
var input = es.through();
var output = input
.pipe(flatmap(function (stream, f) {
const minify = composer(uglifyes);
const input = es.through();
const output = input
.pipe(flatmap((stream, f) => {
return stream.pipe(minify({
output: {
comments: preserveComments(f),
@ -219,18 +219,18 @@ function uglifyWithCopyrights() {
return es.duplex(input, output);
}
function minifyTask(src, sourceMapBaseUrl) {
var sourceMappingURL = sourceMapBaseUrl ? (function (f) { return sourceMapBaseUrl + "/" + f.relative + ".map"; }) : undefined;
return function (cb) {
var jsFilter = filter('**/*.js', { restore: true });
var cssFilter = filter('**/*.css', { restore: true });
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
return cb => {
const jsFilter = filter('**/*.js', { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.write('./', {
sourceMappingURL: sourceMappingURL,
sourceMappingURL,
sourceRoot: undefined,
includeContent: true,
addComment: true
}), gulp.dest(src + '-min'), function (err) {
}), gulp.dest(src + '-min'), (err) => {
if (err instanceof uglify.GulpUglifyError) {
console.error("Uglify error in '" + (err.cause && err.cause.filename) + "'");
console.error(`Uglify error in '${err.cause && err.cause.filename}'`);
}
cb(err);
});

View file

@ -4,20 +4,20 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var _ = require("underscore");
var util = require("gulp-util");
var fs = require("fs");
var path = require("path");
var allErrors = [];
var startTime = null;
var count = 0;
const es = require("event-stream");
const _ = require("underscore");
const util = require("gulp-util");
const fs = require("fs");
const path = require("path");
const allErrors = [];
let startTime = null;
let count = 0;
function onStart() {
if (count++ > 0) {
return;
}
startTime = new Date().getTime();
util.log("Starting " + util.colors.green('compilation') + "...");
util.log(`Starting ${util.colors.green('compilation')}...`);
}
function onEnd() {
if (--count > 0) {
@ -25,7 +25,7 @@ function onEnd() {
}
log();
}
var buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
const buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
try {
fs.mkdirSync(path.dirname(buildLogPath));
}
@ -33,42 +33,39 @@ catch (err) {
// ignore
}
function log() {
var errors = _.flatten(allErrors);
var seen = new Set();
errors.map(function (err) {
const errors = _.flatten(allErrors);
const seen = new Set();
errors.map(err => {
if (!seen.has(err)) {
seen.add(err);
util.log(util.colors.red('Error') + ": " + err);
util.log(`${util.colors.red('Error')}: ${err}`);
}
});
var regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
var messages = errors
.map(function (err) { return regex.exec(err); })
.filter(function (match) { return !!match; })
.map(function (x) { return x; })
.map(function (_a) {
var path = _a[1], line = _a[2], column = _a[3], message = _a[4];
return ({ path: path, line: parseInt(line), column: parseInt(column), message: message });
});
const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
const messages = errors
.map(err => regex.exec(err))
.filter(match => !!match)
.map(x => x)
.map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message }));
try {
fs.writeFileSync(buildLogPath, JSON.stringify(messages));
}
catch (err) {
//noop
}
util.log("Finished " + util.colors.green('compilation') + " with " + errors.length + " errors after " + util.colors.magenta((new Date().getTime() - startTime) + ' ms'));
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime) + ' ms')}`);
}
function createReporter() {
var errors = [];
const errors = [];
allErrors.push(errors);
var ReportFunc = /** @class */ (function () {
function ReportFunc(err) {
class ReportFunc {
constructor(err) {
errors.push(err);
}
ReportFunc.hasErrors = function () {
static hasErrors() {
return errors.length > 0;
};
ReportFunc.end = function (emitError) {
}
static end(emitError) {
errors.length = 0;
onStart();
return es.through(undefined, function () {
@ -78,7 +75,7 @@ function createReporter() {
log();
}
errors.__logged__ = true;
var err = new Error("Found " + errors.length + " errors");
const err = new Error(`Found ${errors.length} errors`);
err.__reporter__ = true;
this.emit('error', err);
}
@ -86,9 +83,8 @@ function createReporter() {
this.emit('end');
}
});
};
return ReportFunc;
}());
}
}
return ReportFunc;
}
exports.createReporter = createReporter;

View file

@ -5,25 +5,25 @@
'use strict';
var snaps;
(function (snaps) {
var fs = require('fs');
var path = require('path');
var os = require('os');
var cp = require('child_process');
var mksnapshot = path.join(__dirname, "../../node_modules/.bin/" + (process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'));
var product = require('../../product.json');
var arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
const fs = require('fs');
const path = require('path');
const os = require('os');
const cp = require('child_process');
const mksnapshot = path.join(__dirname, `../../node_modules/.bin/${process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'}`);
const product = require('../../product.json');
const arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
//
var loaderFilepath;
var startupBlobFilepath;
let loaderFilepath;
let startupBlobFilepath;
switch (process.platform) {
case 'darwin':
loaderFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Resources/app/out/vs/loader.js";
startupBlobFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin";
loaderFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`;
break;
case 'win32':
case 'linux':
loaderFilepath = "VSCode-" + process.platform + "-" + arch + "/resources/app/out/vs/loader.js";
startupBlobFilepath = "VSCode-" + process.platform + "-" + arch + "/snapshot_blob.bin";
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
default:
throw new Error('Unknown platform');
}
@ -31,11 +31,24 @@ var snaps;
startupBlobFilepath = path.join(__dirname, '../../../', startupBlobFilepath);
snapshotLoader(loaderFilepath, startupBlobFilepath);
function snapshotLoader(loaderFilepath, startupBlobFilepath) {
var inputFile = fs.readFileSync(loaderFilepath);
var wrappedInputFile = "\n\t\tvar Monaco_Loader_Init;\n\t\t(function() {\n\t\t\tvar doNotInitLoader = true;\n\t\t\t" + inputFile.toString() + ";\n\t\t\tMonaco_Loader_Init = function() {\n\t\t\t\tAMDLoader.init();\n\t\t\t\tCSSLoaderPlugin.init();\n\t\t\t\tNLSLoaderPlugin.init();\n\n\t\t\t\treturn { define, require };\n\t\t\t}\n\t\t})();\n\t\t";
var wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
const inputFile = fs.readFileSync(loaderFilepath);
const wrappedInputFile = `
var Monaco_Loader_Init;
(function() {
var doNotInitLoader = true;
${inputFile.toString()};
Monaco_Loader_Init = function() {
AMDLoader.init();
CSSLoaderPlugin.init();
NLSLoaderPlugin.init();
return { define, require };
}
})();
`;
const wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
console.log(wrappedInputFilepath);
fs.writeFileSync(wrappedInputFilepath, wrappedInputFile);
cp.execFileSync(mksnapshot, [wrappedInputFilepath, "--startup_blob", startupBlobFilepath]);
cp.execFileSync(mksnapshot, [wrappedInputFilepath, `--startup_blob`, startupBlobFilepath]);
}
})(snaps || (snaps = {}));

View file

@ -4,13 +4,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
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 dirCache = {};
const ts = require("typescript");
const fs = require("fs");
const path = require("path");
const tss = require("./treeshaking");
const REPO_ROOT = path.join(__dirname, '../../');
const SRC_DIR = path.join(REPO_ROOT, 'src');
let dirCache = {};
function writeFile(filePath, contents) {
function ensureDirs(dirPath) {
if (dirCache[dirPath]) {
@ -27,39 +27,39 @@ function writeFile(filePath, contents) {
fs.writeFileSync(filePath, contents);
}
function extractEditor(options) {
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
delete tsConfig.compilerOptions.types;
tsConfig.exclude = [];
options.compilerOptions = tsConfig.compilerOptions;
var result = tss.shake(options);
for (var fileName in result) {
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
writeFile(path.join(options.destRoot, fileName), result[fileName]);
}
}
var copied = {};
var copyFile = function (fileName) {
let copied = {};
const copyFile = (fileName) => {
if (copied[fileName]) {
return;
}
copied[fileName] = true;
var srcPath = path.join(options.sourcesRoot, fileName);
var dstPath = path.join(options.destRoot, fileName);
const srcPath = path.join(options.sourcesRoot, fileName);
const dstPath = path.join(options.destRoot, fileName);
writeFile(dstPath, fs.readFileSync(srcPath));
};
var writeOutputFile = function (fileName, contents) {
const writeOutputFile = (fileName, contents) => {
writeFile(path.join(options.destRoot, fileName), contents);
};
for (var fileName in result) {
for (let 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;
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;
if (/^vs\/css!/.test(importedFileName)) {
importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
}
@ -94,27 +94,27 @@ function extractEditor(options) {
}
exports.extractEditor = extractEditor;
function createESMSourcesAndResources2(options) {
var SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
var getDestAbsoluteFilePath = function (file) {
var dest = options.renames[file.replace(/\\/g, '/')] || file;
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
const getDestAbsoluteFilePath = (file) => {
let dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, "tsconfig.json");
return path.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
}
return path.join(OUT_RESOURCES_FOLDER, dest);
};
var allFiles = walkDirRecursive(SRC_FOLDER);
for (var i = 0; i < allFiles.length; i++) {
var file = allFiles[i];
const allFiles = walkDirRecursive(SRC_FOLDER);
for (let i = 0; i < allFiles.length; i++) {
const file = allFiles[i];
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
continue;
}
if (file === 'tsconfig.json') {
var tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
@ -127,13 +127,13 @@ function createESMSourcesAndResources2(options) {
}
if (/\.ts$/.test(file)) {
// Transform the .ts file
var fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
var info = ts.preProcessFile(fileContents);
for (var i_1 = info.importedFiles.length - 1; i_1 >= 0; i_1--) {
var importedFilename = info.importedFiles[i_1].fileName;
var pos = info.importedFiles[i_1].pos;
var end = info.importedFiles[i_1].end;
var importedFilepath = void 0;
let fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
const info = ts.preProcessFile(fileContents);
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
const importedFilename = info.importedFiles[i].fileName;
const pos = info.importedFiles[i].pos;
const end = info.importedFiles[i].end;
let importedFilepath;
if (/^vs\/css!/.test(importedFilename)) {
importedFilepath = importedFilename.substr('vs/css!'.length) + '.css';
}
@ -143,7 +143,7 @@ function createESMSourcesAndResources2(options) {
if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) {
importedFilepath = path.join(path.dirname(file), importedFilepath);
}
var relativePath = void 0;
let relativePath;
if (importedFilepath === path.dirname(file)) {
relativePath = '../' + path.basename(path.dirname(file));
}
@ -161,25 +161,25 @@ function createESMSourcesAndResources2(options) {
+ fileContents.substring(end + 1));
}
fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
return "import * as " + m1 + " from " + m2 + ";";
return `import * as ${m1} from ${m2};`;
});
write(getDestAbsoluteFilePath(file), fileContents);
continue;
}
console.log("UNKNOWN FILE: " + file);
console.log(`UNKNOWN FILE: ${file}`);
}
function walkDirRecursive(dir) {
if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
dir += '/';
}
var result = [];
let result = [];
_walkDirRecursive(dir, result, dir.length);
return result;
}
function _walkDirRecursive(dir, result, trimPos) {
var files = fs.readdirSync(dir);
for (var i = 0; i < files.length; i++) {
var file = path.join(dir, files[i]);
const files = fs.readdirSync(dir);
for (let i = 0; i < files.length; i++) {
const file = path.join(dir, files[i]);
if (fs.statSync(file).isDirectory()) {
_walkDirRecursive(file, result, trimPos);
}
@ -194,10 +194,10 @@ function createESMSourcesAndResources2(options) {
}
writeFile(absoluteFilePath, contents);
function toggleComments(fileContents) {
var lines = fileContents.split(/\r\n|\r|\n/);
var mode = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
let lines = fileContents.split(/\r\n|\r|\n/);
let mode = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (mode === 0) {
if (/\/\/ ESM-comment-begin/.test(line)) {
mode = 1;
@ -236,30 +236,30 @@ function transportCSS(module, enqueue, write) {
if (!/\.css/.test(module)) {
return false;
}
var filename = path.join(SRC_DIR, module);
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(fileContents, inlineResources === 'base64', inlineResourcesLimit);
const filename = path.join(SRC_DIR, module);
const fileContents = fs.readFileSync(filename).toString();
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(fileContents, inlineResources === 'base64', inlineResourcesLimit);
write(module, newContents);
return true;
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));
return _replaceURL(contents, (url) => {
let imagePath = path.join(path.dirname(module), url);
let fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath));
if (fileContents.length < inlineByteLimit) {
var MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png';
var DATA = ';base64,' + fileContents.toString('base64');
const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png';
let DATA = ';base64,' + fileContents.toString('base64');
if (!forceBase64 && /\.svg$/.test(url)) {
// .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
var newText = fileContents.toString()
let newText = fileContents.toString()
.replace(/"/g, '\'')
.replace(/</g, '%3C')
.replace(/>/g, '%3E')
.replace(/&/g, '%26')
.replace(/#/g, '%23')
.replace(/\s+/g, ' ');
var encodedData = ',' + newText;
let encodedData = ',' + newText;
if (encodedData.length < DATA.length) {
DATA = encodedData;
}
@ -272,12 +272,8 @@ function transportCSS(module, enqueue, write) {
}
function _replaceURL(contents, replacer) {
// Use ")" as the terminator as quotes are oftentimes not used at all
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, function (_) {
var matches = [];
for (var _i = 1; _i < arguments.length; _i++) {
matches[_i - 1] = arguments[_i];
}
var url = matches[0];
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_, ...matches) => {
let url = matches[0];
// Eliminate starting quotes (the initial whitespace is not captured)
if (url.charAt(0) === '"' || url.charAt(0) === '\'') {
url = url.substring(1);

View file

@ -4,44 +4,43 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var util = require("gulp-util");
var appInsights = require("applicationinsights");
var Entry = /** @class */ (function () {
function Entry(name, totalCount, totalSize) {
const es = require("event-stream");
const util = require("gulp-util");
const appInsights = require("applicationinsights");
class Entry {
constructor(name, totalCount, totalSize) {
this.name = name;
this.totalCount = totalCount;
this.totalSize = totalSize;
}
Entry.prototype.toString = function (pretty) {
toString(pretty) {
if (!pretty) {
if (this.totalCount === 1) {
return this.name + ": " + this.totalSize + " bytes";
return `${this.name}: ${this.totalSize} bytes`;
}
else {
return this.name + ": " + this.totalCount + " files with " + this.totalSize + " bytes";
return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`;
}
}
else {
if (this.totalCount === 1) {
return "Stats for '" + util.colors.grey(this.name) + "': " + Math.round(this.totalSize / 1204) + "KB";
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
}
else {
var count = this.totalCount < 100
const count = this.totalCount < 100
? util.colors.green(this.totalCount.toString())
: util.colors.red(this.totalCount.toString());
return "Stats for '" + util.colors.grey(this.name) + "': " + count + " files, " + Math.round(this.totalSize / 1204) + "KB";
return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
}
}
};
return Entry;
}());
var _entries = new Map();
}
}
const _entries = new Map();
function createStatsStream(group, log) {
var entry = new Entry(group, 0, 0);
const entry = new Entry(group, 0, 0);
_entries.set(entry.name, entry);
return es.through(function (data) {
var file = data;
const file = data;
if (typeof file.path === 'string') {
entry.totalCount += 1;
if (Buffer.isBuffer(file.contents)) {
@ -58,13 +57,13 @@ function createStatsStream(group, log) {
}, function () {
if (log) {
if (entry.totalCount === 1) {
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + Math.round(entry.totalSize / 1204) + "KB");
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
}
else {
var count = entry.totalCount < 100
const count = entry.totalCount < 100
? util.colors.green(entry.totalCount.toString())
: util.colors.red(entry.totalCount.toString());
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + count + " files, " + Math.round(entry.totalSize / 1204) + "KB");
util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
}
}
this.emit('end');
@ -72,9 +71,9 @@ function createStatsStream(group, log) {
}
exports.createStatsStream = createStatsStream;
function submitAllStats(productJson, commit) {
var sorted = [];
const sorted = [];
// move entries for single files to the front
_entries.forEach(function (value) {
_entries.forEach(value => {
if (value.totalCount === 1) {
sorted.unshift(value);
}
@ -83,8 +82,7 @@ function submitAllStats(productJson, commit) {
}
});
// print to console
for (var _i = 0, sorted_1 = sorted; _i < sorted_1.length; _i++) {
var entry = sorted_1[_i];
for (const entry of sorted) {
console.log(entry.toString(true));
}
// send data as telementry event when the
@ -92,12 +90,11 @@ function submitAllStats(productJson, commit) {
if (!productJson || !productJson.aiConfig || typeof productJson.aiConfig.asimovKey !== 'string') {
return Promise.resolve(false);
}
return new Promise(function (resolve) {
return new Promise(resolve => {
try {
var sizes = {};
var counts = {};
for (var _i = 0, sorted_2 = sorted; _i < sorted_2.length; _i++) {
var entry = sorted_2[_i];
const sizes = {};
const counts = {};
for (const entry of sorted) {
sizes[entry.name] = entry.totalSize;
counts[entry.name] = entry.totalCount;
}
@ -119,10 +116,10 @@ function submitAllStats(productJson, commit) {
*/
appInsights.defaultClient.trackEvent({
name: 'monacoworkbench/packagemetrics',
properties: { commit: commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
properties: { commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
});
appInsights.defaultClient.flush({
callback: function () {
callback: () => {
appInsights.dispose();
resolve(true);
}

View file

@ -4,30 +4,30 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var assert = require("assert");
var i18n = require("../i18n");
suite('XLF Parser Tests', function () {
var sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
var sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
var originalFilePath = 'vs/base/common/keybinding';
var keys = ['key1', 'key2'];
var messages = ['Key #1', 'Key #2 &'];
var translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', function () {
var xlf = new i18n.XLF('vscode-workbench');
const assert = require("assert");
const i18n = require("../i18n");
suite('XLF Parser Tests', () => {
const sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
const sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
const originalFilePath = 'vs/base/common/keybinding';
const keys = ['key1', 'key2'];
const messages = ['Key #1', 'Key #2 &'];
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', () => {
const xlf = new i18n.XLF('vscode-workbench');
xlf.addFile(originalFilePath, keys, messages);
var xlfString = xlf.toString();
const xlfString = xlf.toString();
assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf);
});
test('XLF to keys & messages conversion', function () {
test('XLF to keys & messages conversion', () => {
i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) {
assert.deepEqual(resolvedFiles[0].messages, translatedMessages);
assert.strictEqual(resolvedFiles[0].originalFilePath, originalFilePath);
});
});
test('JSON file source path to Transifex resource match', function () {
var editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
var platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
test('JSON file source path to Transifex resource match', () => {
const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform);
assert.deepEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib);
assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor);

View file

@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'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'));
const fs = require("fs");
const path = require("path");
const ts = require("typescript");
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
var ShakeLevel;
(function (ShakeLevel) {
ShakeLevel[ShakeLevel["Files"] = 0] = "Files";
@ -15,37 +15,37 @@ var ShakeLevel;
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function printDiagnostics(diagnostics) {
for (var i = 0; i < diagnostics.length; i++) {
var diag = diagnostics[i];
var result = '';
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
let result = '';
if (diag.file) {
result += diag.file.fileName + ": ";
result += `${diag.file.fileName}: `;
}
if (diag.file && diag.start) {
var location_1 = diag.file.getLineAndCharacterOfPosition(diag.start);
result += "- " + (location_1.line + 1) + "," + location_1.character + " - ";
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
result += `- ${location.line + 1},${location.character} - `;
}
result += JSON.stringify(diag.messageText);
console.log(result);
}
}
function shake(options) {
var languageService = createTypeScriptLanguageService(options);
var program = languageService.getProgram();
var globalDiagnostics = program.getGlobalDiagnostics();
const languageService = createTypeScriptLanguageService(options);
const program = languageService.getProgram();
const globalDiagnostics = program.getGlobalDiagnostics();
if (globalDiagnostics.length > 0) {
printDiagnostics(globalDiagnostics);
throw new Error("Compilation Errors encountered.");
throw new Error(`Compilation Errors encountered.`);
}
var syntacticDiagnostics = program.getSyntacticDiagnostics();
const syntacticDiagnostics = program.getSyntacticDiagnostics();
if (syntacticDiagnostics.length > 0) {
printDiagnostics(syntacticDiagnostics);
throw new Error("Compilation Errors encountered.");
throw new Error(`Compilation Errors encountered.`);
}
var semanticDiagnostics = program.getSemanticDiagnostics();
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
printDiagnostics(semanticDiagnostics);
throw new Error("Compilation Errors encountered.");
throw new Error(`Compilation Errors encountered.`);
}
markNodes(languageService, options);
return generateResult(languageService, options.shakeLevel);
@ -54,98 +54,98 @@ exports.shake = shake;
//#region Discovery, LanguageService & Setup
function createTypeScriptLanguageService(options) {
// Discover referenced files
var FILES = discoverAndReadFiles(options);
const FILES = discoverAndReadFiles(options);
// Add fake usage files
options.inlineEntryPoints.forEach(function (inlineEntryPoint, index) {
FILES["inlineEntryPoint:" + index + ".ts"] = inlineEntryPoint;
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
});
// Add additional typings
options.typings.forEach(function (typing) {
var filePath = path.join(options.sourcesRoot, typing);
options.typings.forEach((typing) => {
const filePath = path.join(options.sourcesRoot, typing);
FILES[typing] = fs.readFileSync(filePath).toString();
});
// 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();
const RESOLVED_LIBS = {};
options.libs.forEach((filename) => {
const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, "").options);
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
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) {
const FILES = {};
const in_queue = Object.create(null);
const queue = [];
const enqueue = (moduleId) => {
if (in_queue[moduleId]) {
return;
}
in_queue[moduleId] = true;
queue.push(moduleId);
};
options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); });
options.entryPoints.forEach((entryPoint) => enqueue(entryPoint));
while (queue.length > 0) {
var moduleId = queue.shift();
var dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
const moduleId = queue.shift();
const 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;
const dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[`${moduleId}.d.ts`] = dts_filecontents;
continue;
}
var ts_filename = void 0;
let ts_filename;
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;
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;
}
var importedModuleId = importedFileName;
let importedModuleId = importedFileName;
if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) {
importedModuleId = path.join(path.dirname(moduleId), importedModuleId);
}
enqueue(importedModuleId);
}
FILES[moduleId + ".ts"] = ts_filecontents;
FILES[`${moduleId}.ts`] = ts_filecontents;
}
return FILES;
}
/**
* A TypeScript language service host
*/
var TypeScriptLanguageServiceHost = /** @class */ (function () {
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
class TypeScriptLanguageServiceHost {
constructor(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
getCompilationSettings() {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
}
getScriptFileNames() {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (_fileName) {
}
getScriptVersion(_fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
}
getProjectVersion() {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
}
getScriptSnapshot(fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
@ -155,21 +155,20 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (_fileName) {
}
getScriptKind(_fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
}
getCurrentDirectory() {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (_options) {
}
getDefaultLibFileName(_options) {
return 'defaultLib:lib.d.ts';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
}
isDefaultLibFileName(fileName) {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
};
return TypeScriptLanguageServiceHost;
}());
}
}
//#endregion
//#region Tree Shaking
var NodeColor;
@ -186,7 +185,7 @@ function setColor(node, color) {
}
function nodeOrParentIsBlack(node) {
while (node) {
var color = getColor(node);
const color = getColor(node);
if (color === 2 /* Black */) {
return true;
}
@ -198,8 +197,7 @@ 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];
for (const child of node.getChildren()) {
if (nodeOrChildIsBlack(child)) {
return true;
}
@ -207,22 +205,22 @@ function nodeOrChildIsBlack(node) {
return false;
}
function markNodes(languageService, options) {
var program = languageService.getProgram();
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
if (options.shakeLevel === 0 /* Files */) {
// Mark all source files Black
program.getSourceFiles().forEach(function (sourceFile) {
program.getSourceFiles().forEach((sourceFile) => {
setColor(sourceFile, 2 /* Black */);
});
return;
}
var black_queue = [];
var gray_queue = [];
var sourceFilesLoaded = {};
const black_queue = [];
const gray_queue = [];
const sourceFilesLoaded = {};
function enqueueTopLevelModuleStatements(sourceFile) {
sourceFile.forEachChild(function (node) {
sourceFile.forEachChild((node) => {
if (ts.isImportDeclaration(node)) {
if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) {
setColor(node, 2 /* Black */);
@ -259,7 +257,7 @@ function markNodes(languageService, options) {
gray_queue.push(node);
}
function enqueue_black(node) {
var previousColor = getColor(node);
const previousColor = getColor(node);
if (previousColor === 2 /* Black */) {
return;
}
@ -277,12 +275,12 @@ function markNodes(languageService, options) {
if (nodeOrParentIsBlack(node)) {
return;
}
var fileName = node.getSourceFile().fileName;
const fileName = node.getSourceFile().fileName;
if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) {
setColor(node, 2 /* Black */);
return;
}
var sourceFile = node.getSourceFile();
const sourceFile = node.getSourceFile();
if (!sourceFilesLoaded[sourceFile.fileName]) {
sourceFilesLoaded[sourceFile.fileName] = true;
enqueueTopLevelModuleStatements(sourceFile);
@ -293,15 +291,15 @@ function markNodes(languageService, options) {
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());
const 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);
for (let i = 0, len = references.length; i < len; i++) {
const reference = references[i];
const referenceSourceFile = program.getSourceFile(reference.fileName);
if (!referenceSourceFile) {
continue;
}
var referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
if (ts.isMethodDeclaration(referenceNode.parent)
|| ts.isPropertyDeclaration(referenceNode.parent)
|| ts.isGetAccessor(referenceNode.parent)
@ -313,9 +311,9 @@ function markNodes(languageService, options) {
}
}
function enqueueFile(filename) {
var sourceFile = program.getSourceFile(filename);
const sourceFile = program.getSourceFile(filename);
if (!sourceFile) {
console.warn("Cannot find source file " + filename);
console.warn(`Cannot find source file ${filename}`);
return;
}
enqueue_black(sourceFile);
@ -325,8 +323,8 @@ function markNodes(languageService, options) {
// this import should be ignored
return;
}
var nodeSourceFile = node.getSourceFile();
var fullPath;
const nodeSourceFile = node.getSourceFile();
let fullPath;
if (/(^\.\/)|(^\.\.\/)/.test(importText)) {
fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts';
}
@ -335,25 +333,25 @@ function markNodes(languageService, options) {
}
enqueueFile(fullPath);
}
options.entryPoints.forEach(function (moduleId) { return enqueueFile(moduleId + '.ts'); });
options.entryPoints.forEach(moduleId => 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 () {
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;
var node = void 0;
let node;
if (step % 100 === 0) {
console.log(step + "/" + (step + black_queue.length + gray_queue.length) + " (" + black_queue.length + ", " + gray_queue.length + ")");
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;
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_1);
setColor(node_1, 2 /* Black */);
black_queue.push(node);
setColor(node, 2 /* Black */);
i--;
}
}
@ -362,17 +360,18 @@ function markNodes(languageService, options) {
node = black_queue.shift();
}
else {
return "break";
// only gray nodes remaining...
break;
}
var nodeSourceFile = node.getSourceFile();
var loop = function (node) {
var _a = getRealNodeSymbol(checker, node), symbol = _a[0], symbolImportNode = _a[1];
const nodeSourceFile = node.getSourceFile();
const loop = (node) => {
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
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];
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)
@ -380,9 +379,9 @@ function markNodes(languageService, options) {
}
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;
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)
@ -396,8 +395,7 @@ function markNodes(languageService, options) {
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (var _i = 0, _b = declaration.heritageClauses; _i < _b.length; _i++) {
var heritageClause = _b[_i];
for (let heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
}
@ -410,17 +408,12 @@ function markNodes(languageService, options) {
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();
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;
@ -430,28 +423,28 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
return false;
}
function generateResult(languageService, shakeLevel) {
var program = languageService.getProgram();
const program = languageService.getProgram();
if (!program) {
throw new Error('Could not get program from language service');
}
var result = {};
var writeFile = function (filePath, contents) {
let result = {};
const writeFile = (filePath, contents) => {
result[filePath] = contents;
};
program.getSourceFiles().forEach(function (sourceFile) {
var fileName = sourceFile.fileName;
program.getSourceFiles().forEach((sourceFile) => {
const fileName = sourceFile.fileName;
if (/^defaultLib:/.test(fileName)) {
return;
}
var destination = fileName;
const destination = fileName;
if (/\.d\.ts$/.test(fileName)) {
if (nodeOrChildIsBlack(sourceFile)) {
writeFile(destination, sourceFile.text);
}
return;
}
var text = sourceFile.text;
var result = '';
let text = sourceFile.text;
let result = '';
function keep(node) {
result += text.substring(node.pos, node.end);
}
@ -480,24 +473,24 @@ function generateResult(languageService, shakeLevel) {
}
}
else {
var survivingImports = [];
for (var i = 0; i < node.importClause.namedBindings.elements.length; i++) {
var importNode = node.importClause.namedBindings.elements[i];
let survivingImports = [];
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
const 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);
const leadingTriviaWidth = node.getLeadingTriviaWidth();
const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
if (survivingImports.length > 0) {
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + ", {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
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) + ";");
return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
else {
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
return write(leadingTrivia + "import " + node.importClause.name.text + " from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`);
}
}
}
@ -509,9 +502,9 @@ function generateResult(languageService, shakeLevel) {
}
}
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];
let toWrite = node.getFullText();
for (let i = node.members.length - 1; i >= 0; i--) {
const member = node.members[i];
if (getColor(member) === 2 /* Black */ || !member.name) {
// keep method
continue;
@ -520,8 +513,8 @@ function generateResult(languageService, shakeLevel) {
// TODO: keep all members ending with `Brand`...
continue;
}
var pos = member.pos - node.pos;
var end = member.end - node.pos;
let pos = member.pos - node.pos;
let end = member.end - node.pos;
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
}
return write(toWrite);
@ -553,9 +546,9 @@ function generateResult(languageService, shakeLevel) {
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker, node) {
var getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
var getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
var getNameFromPropertyName = ts.getNameFromPropertyName;
const getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
const getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
const getNameFromPropertyName = ts.getNameFromPropertyName;
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
@ -583,15 +576,15 @@ function getRealNodeSymbol(checker, node) {
return [null, null];
}
}
var parent = node.parent;
var symbol = checker.getSymbolAtLocation(node);
var importNode = null;
const { parent } = node;
let symbol = checker.getSymbolAtLocation(node);
let importNode = null;
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
var aliased = checker.getAliasedSymbol(symbol);
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
// We should mark the import as visited
importNode = symbol.declarations[0];
@ -620,17 +613,17 @@ function getRealNodeSymbol(checker, node) {
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
(node === (parent.propertyName || parent.name))) {
var name_1 = getNameFromPropertyName(node);
var type = checker.getTypeAtLocation(parent.parent);
if (name_1 && type) {
const name = getNameFromPropertyName(node);
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
var prop = type.types[0].getProperty(name_1);
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
}
else {
var prop = type.getProperty(name_1);
const prop = type.getProperty(name);
if (prop) {
symbol = prop;
}
@ -646,11 +639,11 @@ function getRealNodeSymbol(checker, node) {
// }
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
var element = getContainingObjectLiteralElement(node);
const element = getContainingObjectLiteralElement(node);
if (element) {
var contextualType = element && checker.getContextualType(element.parent);
const contextualType = element && checker.getContextualType(element.parent);
if (contextualType) {
var propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
if (propertySymbols) {
symbol = propertySymbols[0];
}
@ -664,17 +657,16 @@ function getRealNodeSymbol(checker, node) {
}
/** Get the token whose text contains the position */
function getTokenAtPosition(sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
var current = sourceFile;
let 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);
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;
}
var end = child.getEnd();
const end = child.getEnd();
if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) {
current = child;
continue outer;

View file

@ -3,51 +3,30 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var path_1 = require("path");
var Lint = require("tslint");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const path_1 = require("path");
const Lint = require("tslint");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts) {
var _this = _super.call(this, file, opts) || this;
_this.imports = Object.create(null);
return _this;
}
ImportPatterns.prototype.visitImportDeclaration = function (node) {
var path = node.moduleSpecifier.getText();
}
exports.Rule = Rule;
class ImportPatterns extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
this.imports = Object.create(null);
}
visitImportDeclaration(node) {
let path = node.moduleSpecifier.getText();
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
if (this.imports[path]) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Duplicate imports for '" + path + "'."));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Duplicate imports for '${path}'.`));
}
this.imports[path] = true;
};
return ImportPatterns;
}(Lint.RuleWalker));
}
}

View file

@ -3,82 +3,60 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var minimatch = require("minimatch");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var configs = this.getOptions().ruleArguments;
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
var config = configs_1[_i];
const ts = require("typescript");
const Lint = require("tslint");
const minimatch = require("minimatch");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
const configs = this.getOptions().ruleArguments;
for (const config of configs) {
if (minimatch(sourceFile.fileName, config.target)) {
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions(), config));
}
}
return [];
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super);
function ImportPatterns(file, opts, _config) {
var _this = _super.call(this, file, opts) || this;
_this._config = _config;
return _this;
}
ImportPatterns.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class ImportPatterns extends Lint.RuleWalker {
constructor(file, opts, _config) {
super(file, opts);
this._config = _config;
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
ImportPatterns.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
ImportPatterns.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
ImportPatterns.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
if (path[0] === '.') {
path = path_1.join(this.getSourceFile().fileName, path);
}
var restrictions;
let restrictions;
if (typeof this._config.restrictions === 'string') {
restrictions = [this._config.restrictions];
}
else {
restrictions = this._config.restrictions;
}
var matched = false;
for (var _i = 0, restrictions_1 = restrictions; _i < restrictions_1.length; _i++) {
var pattern = restrictions_1[_i];
let matched = false;
for (const pattern of restrictions) {
if (minimatch(path, pattern)) {
matched = true;
break;
@ -86,8 +64,7 @@ var ImportPatterns = /** @class */ (function (_super) {
}
if (!matched) {
// None of the restrictions matched
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + restrictions.join(' or ') + "' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Imports violates '${restrictions.join(' or ')}' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
}
};
return ImportPatterns;
}(Lint.RuleWalker));
}
}

View file

@ -3,39 +3,22 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
var ruleArgs = this.getOptions().ruleArguments[0];
var config;
for (var i = parts.length - 1; i >= 0; i--) {
const ts = require("typescript");
const Lint = require("tslint");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
const parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
const ruleArgs = this.getOptions().ruleArguments[0];
let config;
for (let i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(function (key) {
Object.keys(ruleArgs).forEach(key => {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
@ -47,58 +30,54 @@ var Rule = /** @class */ (function (_super) {
return [];
}
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var LayeringRule = /** @class */ (function (_super) {
__extends(LayeringRule, _super);
function LayeringRule(file, config, opts) {
var _this = _super.call(this, file, opts) || this;
_this._config = config;
return _this;
}
LayeringRule.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class LayeringRule extends Lint.RuleWalker {
constructor(file, config, opts) {
super(file, opts);
this._config = config;
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
LayeringRule.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
LayeringRule.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
LayeringRule.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
if (path[0] === '.') {
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
}
var parts = path_1.dirname(path).split(/\\|\//);
for (var i = parts.length - 1; i >= 0; i--) {
var part = parts[i];
const parts = path_1.dirname(path).split(/\\|\//);
for (let i = parts.length - 1; i >= 0; i--) {
const part = parts[i];
if (this._config.allowed.has(part)) {
// GOOD - same layer
return;
}
if (this._config.disallowed.has(part)) {
// BAD - wrong layer
var message = "Bad layering. You are not allowed to access '" + part + "' from here, allowed layers are: [" + LayeringRule._print(this._config.allowed) + "]";
const message = `Bad layering. You are not allowed to access '${part}' from here, allowed layers are: [${LayeringRule._print(this._config.allowed)}]`;
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
return;
}
}
};
LayeringRule._print = function (set) {
var r = [];
set.forEach(function (e) { return r.push(e); });
}
static _print(set) {
const r = [];
set.forEach(e => r.push(e));
return r.join(', ');
};
return LayeringRule;
}(Lint.RuleWalker));
}
}

View file

@ -3,60 +3,41 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var path_1 = require("path");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const ts = require("typescript");
const Lint = require("tslint");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
if (/vs(\/|\\)editor/.test(sourceFile.fileName)) {
// the vs/editor folder is allowed to use the standalone editor
return [];
}
return this.applyWithWalker(new NoStandaloneEditorRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
__extends(NoStandaloneEditorRuleWalker, _super);
function NoStandaloneEditorRuleWalker(file, opts) {
return _super.call(this, file, opts) || this;
}
NoStandaloneEditorRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
}
exports.Rule = Rule;
class NoStandaloneEditorRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
};
NoStandaloneEditorRuleWalker.prototype.visitImportDeclaration = function (node) {
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
};
NoStandaloneEditorRuleWalker.prototype.visitCallExpression = function (node) {
_super.prototype.visitCallExpression.call(this, node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
var path = node.arguments[0];
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
};
NoStandaloneEditorRuleWalker.prototype._validateImport = function (path, node) {
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
@ -68,8 +49,7 @@ var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
}
};
return NoStandaloneEditorRuleWalker;
}(Lint.RuleWalker));
}
}

View file

@ -3,35 +3,17 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
const ts = require("typescript");
const Lint = require("tslint");
/**
* Implementation of the no-unexternalized-strings rule.
*/
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
}
}
exports.Rule = Rule;
function isStringLiteral(node) {
return node && node.kind === ts.SyntaxKind.StringLiteral;
@ -42,73 +24,70 @@ function isObjectLiteral(node) {
function isPropertyAssignment(node) {
return node && node.kind === ts.SyntaxKind.PropertyAssignment;
}
var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
__extends(NoUnexternalizedStringsRuleWalker, _super);
function NoUnexternalizedStringsRuleWalker(file, opts) {
var _this = _super.call(this, file, opts) || this;
_this.signatures = Object.create(null);
_this.ignores = Object.create(null);
_this.messageIndex = undefined;
_this.keyIndex = undefined;
_this.usedKeys = Object.create(null);
var options = _this.getOptions();
var first = options && options.length > 0 ? options[0] : null;
class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
this.signatures = Object.create(null);
this.ignores = Object.create(null);
this.messageIndex = undefined;
this.keyIndex = undefined;
this.usedKeys = Object.create(null);
const options = this.getOptions();
const first = options && options.length > 0 ? options[0] : null;
if (first) {
if (Array.isArray(first.signatures)) {
first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; });
first.signatures.forEach((signature) => this.signatures[signature] = true);
}
if (Array.isArray(first.ignores)) {
first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; });
first.ignores.forEach((ignore) => this.ignores[ignore] = true);
}
if (typeof first.messageIndex !== 'undefined') {
_this.messageIndex = first.messageIndex;
this.messageIndex = first.messageIndex;
}
if (typeof first.keyIndex !== 'undefined') {
_this.keyIndex = first.keyIndex;
this.keyIndex = first.keyIndex;
}
}
return _this;
}
NoUnexternalizedStringsRuleWalker.prototype.visitSourceFile = function (node) {
var _this = this;
_super.prototype.visitSourceFile.call(this, node);
Object.keys(this.usedKeys).forEach(function (key) {
var occurrences = _this.usedKeys[key];
visitSourceFile(node) {
super.visitSourceFile(node);
Object.keys(this.usedKeys).forEach(key => {
const occurrences = this.usedKeys[key];
if (occurrences.length > 1) {
occurrences.forEach(function (occurrence) {
_this.addFailure((_this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), "Duplicate key " + occurrence.key.getText() + " with different message value.")));
occurrences.forEach(occurrence => {
this.addFailure((this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `Duplicate key ${occurrence.key.getText()} with different message value.`)));
});
}
});
};
NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (node) {
}
visitStringLiteral(node) {
this.checkStringLiteral(node);
_super.prototype.visitStringLiteral.call(this, node);
};
NoUnexternalizedStringsRuleWalker.prototype.checkStringLiteral = function (node) {
var text = node.getText();
var doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
var info = this.findDescribingParent(node);
super.visitStringLiteral(node);
}
checkStringLiteral(node) {
const text = node.getText();
const doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
const info = this.findDescribingParent(node);
// Ignore strings in import and export nodes.
if (info && info.isImport && doubleQuoted) {
var fix = [
const fix = [
Lint.Replacement.replaceFromTo(node.getStart(), 1, '\''),
Lint.Replacement.replaceFromTo(node.getStart() + text.length - 1, 1, '\''),
];
this.addFailureAtNode(node, NoUnexternalizedStringsRuleWalker.ImportFailureMessage, fix);
return;
}
var callInfo = info ? info.callInfo : null;
var functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
const callInfo = info ? info.callInfo : null;
const functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
if (functionName && this.ignores[functionName]) {
return;
}
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
var s = node.getText();
var fix = [
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")"),
const s = node.getText();
const fix = [
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`),
];
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Unexternalized string found: ${node.getText()}`, fix));
return;
}
// We have a single quoted string outside a localize function name.
@ -116,7 +95,7 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
return;
}
// We have a string that is a direct argument into the localize call.
var keyArg = callInfo && callInfo.argIndex === this.keyIndex
const keyArg = callInfo && callInfo.argIndex === this.keyIndex
? callInfo.callExpression.arguments[this.keyIndex]
: null;
if (keyArg) {
@ -124,12 +103,12 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
else if (isObjectLiteral(keyArg)) {
for (var i = 0; i < keyArg.properties.length; i++) {
var property = keyArg.properties[i];
for (let i = 0; i < keyArg.properties.length; i++) {
const property = keyArg.properties[i];
if (isPropertyAssignment(property)) {
var name_1 = property.name.getText();
if (name_1 === 'key') {
var initializer = property.initializer;
const name = property.name.getText();
if (name === 'key') {
const initializer = property.initializer;
if (isStringLiteral(initializer)) {
this.recordKey(initializer, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
}
@ -139,42 +118,42 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
}
}
}
var messageArg = callInfo.callExpression.arguments[this.messageIndex];
const messageArg = callInfo.callExpression.arguments[this.messageIndex];
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal."));
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), `Message argument to '${callInfo.callExpression.expression.getText()}' must be a string literal.`));
return;
}
};
NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) {
var text = keyNode.getText();
}
recordKey(keyNode, messageNode) {
const text = keyNode.getText();
// We have an empty key
if (text.match(/(['"]) *\1/)) {
if (messageNode) {
this.addFailureAtNode(keyNode, "Key is empty for message: " + messageNode.getText());
this.addFailureAtNode(keyNode, `Key is empty for message: ${messageNode.getText()}`);
}
else {
this.addFailureAtNode(keyNode, "Key is empty.");
this.addFailureAtNode(keyNode, `Key is empty.`);
}
return;
}
var occurrences = this.usedKeys[text];
let occurrences = this.usedKeys[text];
if (!occurrences) {
occurrences = [];
this.usedKeys[text] = occurrences;
}
if (messageNode) {
if (occurrences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) {
if (occurrences.some(pair => pair.message ? pair.message.getText() === messageNode.getText() : false)) {
return;
}
}
occurrences.push({ key: keyNode, message: messageNode });
};
NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) {
var parent;
}
findDescribingParent(node) {
let parent;
while ((parent = node.parent)) {
var kind = parent.kind;
const kind = parent.kind;
if (kind === ts.SyntaxKind.CallExpression) {
var callExpression = parent;
const callExpression = parent;
return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(node) } };
}
else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) {
@ -189,8 +168,7 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
node = parent;
}
return null;
};
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
return NoUnexternalizedStringsRuleWalker;
}(Lint.RuleWalker));
}
}
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';

View file

@ -3,62 +3,43 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Lint = require("tslint");
var fs = require("fs");
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
const Lint = require("tslint");
const fs = require("fs");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new TranslationRemindRuleWalker(sourceFile, this.getOptions()));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var TranslationRemindRuleWalker = /** @class */ (function (_super) {
__extends(TranslationRemindRuleWalker, _super);
function TranslationRemindRuleWalker(file, opts) {
return _super.call(this, file, opts) || this;
}
TranslationRemindRuleWalker.prototype.visitImportDeclaration = function (node) {
var declaration = node.moduleSpecifier.getText();
if (declaration !== "'" + TranslationRemindRuleWalker.NLS_MODULE + "'") {
}
exports.Rule = Rule;
class TranslationRemindRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
}
visitImportDeclaration(node) {
const declaration = node.moduleSpecifier.getText();
if (declaration !== `'${TranslationRemindRuleWalker.NLS_MODULE}'`) {
return;
}
this.visitImportLikeDeclaration(node);
};
TranslationRemindRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
var reference = node.moduleReference.getText();
if (reference !== "require('" + TranslationRemindRuleWalker.NLS_MODULE + "')") {
}
visitImportEqualsDeclaration(node) {
const reference = node.moduleReference.getText();
if (reference !== `require('${TranslationRemindRuleWalker.NLS_MODULE}')`) {
return;
}
this.visitImportLikeDeclaration(node);
};
TranslationRemindRuleWalker.prototype.visitImportLikeDeclaration = function (node) {
var currentFile = node.getSourceFile().fileName;
var matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
var matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
}
visitImportLikeDeclaration(node) {
const currentFile = node.getSourceFile().fileName;
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
if (!matchService && !matchPart) {
return;
}
var resource = matchService ? matchService[0] : matchPart[0];
var resourceDefined = false;
var json;
const resource = matchService ? matchService[0] : matchPart[0];
let resourceDefined = false;
let json;
try {
json = fs.readFileSync('./build/lib/i18n.resources.json', 'utf8');
}
@ -66,17 +47,16 @@ var TranslationRemindRuleWalker = /** @class */ (function (_super) {
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
return;
}
var workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach(function (existingResource) {
const workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach((existingResource) => {
if (existingResource.name === resource) {
resourceDefined = true;
return;
}
});
if (!resourceDefined) {
this.addFailureAtNode(node, "Please add '" + resource + "' to ./build/lib/i18n.resources.json file to use translations here.");
this.addFailureAtNode(node, `Please add '${resource}' to ./build/lib/i18n.resources.json file to use translations here.`);
}
};
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';
return TranslationRemindRuleWalker;
}(Lint.RuleWalker));
}
}
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';

View file

@ -1,4 +0,0 @@
declare module 'object-assign' {
function fn(target: any, ...sources: any[]): any;
export = fn;
}

View file

@ -4,29 +4,29 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var es = require("event-stream");
var debounce = require("debounce");
var _filter = require("gulp-filter");
var rename = require("gulp-rename");
var _ = require("underscore");
var path = require("path");
var fs = require("fs");
var _rimraf = require("rimraf");
var git = require("./git");
var VinylFile = require("vinyl");
var NoCancellationToken = { isCancellationRequested: function () { return false; } };
const es = require("event-stream");
const debounce = require("debounce");
const _filter = require("gulp-filter");
const rename = require("gulp-rename");
const _ = require("underscore");
const path = require("path");
const fs = require("fs");
const _rimraf = require("rimraf");
const git = require("./git");
const VinylFile = require("vinyl");
const NoCancellationToken = { isCancellationRequested: () => false };
function incremental(streamProvider, initial, supportsCancellation) {
var input = es.through();
var output = es.through();
var state = 'idle';
var buffer = Object.create(null);
var token = !supportsCancellation ? undefined : { isCancellationRequested: function () { return Object.keys(buffer).length > 0; } };
var run = function (input, isCancellable) {
const input = es.through();
const output = es.through();
let state = 'idle';
let buffer = Object.create(null);
const token = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
const run = (input, isCancellable) => {
state = 'running';
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(undefined, function () {
.pipe(es.through(undefined, () => {
state = 'idle';
eventuallyRun();
}))
@ -35,16 +35,16 @@ function incremental(streamProvider, initial, supportsCancellation) {
if (initial) {
run(initial, false);
}
var eventuallyRun = debounce(function () {
var paths = Object.keys(buffer);
const eventuallyRun = debounce(() => {
const paths = Object.keys(buffer);
if (paths.length === 0) {
return;
}
var data = paths.map(function (path) { return buffer[path]; });
const data = paths.map(path => buffer[path]);
buffer = Object.create(null);
run(es.readArray(data), true);
}, 500);
input.on('data', function (f) {
input.on('data', (f) => {
buffer[f.path] = f;
if (state === 'idle') {
eventuallyRun();
@ -57,7 +57,7 @@ function fixWin32DirectoryPermissions() {
if (!/win32/.test(process.platform)) {
return es.through();
}
return es.mapSync(function (f) {
return es.mapSync(f => {
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
f.stat.mode = 16877;
}
@ -66,16 +66,16 @@ function fixWin32DirectoryPermissions() {
}
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
function setExecutableBit(pattern) {
var setBit = es.mapSync(function (f) {
const setBit = es.mapSync(f => {
f.stat.mode = /* 100755 */ 33261;
return f;
});
if (!pattern) {
return setBit;
}
var input = es.through();
var filter = _filter(pattern, { restore: true });
var output = input
const input = es.through();
const filter = _filter(pattern, { restore: true });
const output = input
.pipe(filter)
.pipe(setBit)
.pipe(filter.restore);
@ -83,7 +83,7 @@ function setExecutableBit(pattern) {
}
exports.setExecutableBit = setExecutableBit;
function toFileUri(filePath) {
var match = filePath.match(/^([a-z])\:(.*)$/i);
const match = filePath.match(/^([a-z])\:(.*)$/i);
if (match) {
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
}
@ -91,7 +91,7 @@ function toFileUri(filePath) {
}
exports.toFileUri = toFileUri;
function skipDirectories() {
return es.mapSync(function (f) {
return es.mapSync(f => {
if (!f.isDirectory()) {
return f;
}
@ -99,15 +99,15 @@ function skipDirectories() {
}
exports.skipDirectories = skipDirectories;
function cleanNodeModule(name, excludes, includes) {
var toGlob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
var negate = function (str) { return '!' + str; };
var allFilter = _filter(toGlob('**'), { restore: true });
var globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
var input = es.through();
var nodeModuleInput = input.pipe(allFilter);
var output = nodeModuleInput.pipe(_filter(globs));
const toGlob = (path) => '**/node_modules/' + name + (path ? '/' + path : '');
const negate = (str) => '!' + str;
const allFilter = _filter(toGlob('**'), { restore: true });
const globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
const input = es.through();
const nodeModuleInput = input.pipe(allFilter);
let output = nodeModuleInput.pipe(_filter(globs));
if (includes) {
var includeGlobs = includes.map(toGlob);
const includeGlobs = includes.map(toGlob);
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
}
output = output.pipe(allFilter.restore);
@ -115,9 +115,9 @@ function cleanNodeModule(name, excludes, includes) {
}
exports.cleanNodeModule = cleanNodeModule;
function loadSourcemaps() {
var input = es.through();
var output = input
.pipe(es.map(function (f, cb) {
const input = es.through();
const output = input
.pipe(es.map((f, cb) => {
if (f.sourceMap) {
cb(undefined, f);
return;
@ -126,10 +126,10 @@ function loadSourcemaps() {
cb(new Error('empty file'));
return;
}
var contents = f.contents.toString('utf8');
var reg = /\/\/# sourceMappingURL=(.*)$/g;
var lastMatch = null;
var match = null;
const contents = f.contents.toString('utf8');
const reg = /\/\/# sourceMappingURL=(.*)$/g;
let lastMatch = null;
let match = null;
while (match = reg.exec(contents)) {
lastMatch = match;
}
@ -145,7 +145,7 @@ function loadSourcemaps() {
return;
}
f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
if (err) {
return cb(err);
}
@ -157,10 +157,10 @@ function loadSourcemaps() {
}
exports.loadSourcemaps = loadSourcemaps;
function stripSourceMappingURL() {
var input = es.through();
var output = input
.pipe(es.mapSync(function (f) {
var contents = f.contents.toString('utf8');
const input = es.through();
const output = input
.pipe(es.mapSync(f => {
const contents = f.contents.toString('utf8');
f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
return f;
}));
@ -168,23 +168,23 @@ function stripSourceMappingURL() {
}
exports.stripSourceMappingURL = stripSourceMappingURL;
function rimraf(dir) {
var retries = 0;
var retry = function (cb) {
_rimraf(dir, { maxBusyTries: 1 }, function (err) {
let retries = 0;
const retry = (cb) => {
_rimraf(dir, { maxBusyTries: 1 }, (err) => {
if (!err) {
return cb();
}
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
return setTimeout(function () { return retry(cb); }, 10);
return setTimeout(() => retry(cb), 10);
}
return cb(err);
});
};
return function (cb) { return retry(cb); };
return cb => retry(cb);
}
exports.rimraf = rimraf;
function getVersion(root) {
var version = process.env['BUILD_SOURCEVERSION'];
let version = process.env['BUILD_SOURCEVERSION'];
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
version = git.getVersion(root);
}
@ -192,14 +192,14 @@ function getVersion(root) {
}
exports.getVersion = getVersion;
function rebase(count) {
return rename(function (f) {
var parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
return rename(f => {
const parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
f.dirname = parts.slice(count).join(path.sep);
});
}
exports.rebase = rebase;
function filter(fn) {
var result = es.through(function (data) {
const result = es.through(function (data) {
if (fn(data)) {
this.emit('data', data);
}
@ -212,8 +212,8 @@ function filter(fn) {
}
exports.filter = filter;
function versionStringToNumber(versionStr) {
var semverRegex = /(\d+)\.(\d+)\.(\d+)/;
var match = versionStr.match(semverRegex);
const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
const match = versionStr.match(semverRegex);
if (!match) {
throw new Error('Version string is not properly formatted: ' + versionStr);
}

View file

@ -4,30 +4,22 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var ts = require("typescript");
var path = require("path");
var util = require("gulp-util");
var tsfmt = require('../../tsfmt.json');
function log(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
util.log.apply(util, [util.colors.cyan('[monaco.d.ts]'), message].concat(rest));
const fs = require("fs");
const ts = require("typescript");
const path = require("path");
const util = require("gulp-util");
const tsfmt = require('../../tsfmt.json');
function log(message, ...rest) {
util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
}
var SRC = path.join(__dirname, '../../src');
var OUT_ROOT = path.join(__dirname, '../../');
var RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
var DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
const SRC = path.join(__dirname, '../../src');
const OUT_ROOT = path.join(__dirname, '../../');
const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
var CURRENT_PROCESSING_RULE = '';
function logErr(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
function logErr(message, ...rest) {
util.log(util.colors.red('[monaco.d.ts]'), 'WHILE HANDLING RULE: ', CURRENT_PROCESSING_RULE);
util.log.apply(util, [util.colors.red('[monaco.d.ts]'), message].concat(rest));
util.log(util.colors.red('[monaco.d.ts]'), message, ...rest);
}
function moduleIdToPath(out, moduleId) {
if (/\.d\.ts/.test(moduleId)) {
@ -35,16 +27,16 @@ function moduleIdToPath(out, moduleId) {
}
return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
}
var SOURCE_FILE_MAP = {};
let SOURCE_FILE_MAP = {};
function getSourceFile(out, inputFiles, moduleId) {
if (!SOURCE_FILE_MAP[moduleId]) {
var filePath = path.normalize(moduleIdToPath(out, moduleId));
let filePath = path.normalize(moduleIdToPath(out, moduleId));
if (!inputFiles.hasOwnProperty(filePath)) {
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
return null;
}
var fileContents = inputFiles[filePath];
var sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
let fileContents = inputFiles[filePath];
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
SOURCE_FILE_MAP[moduleId] = sourceFile;
}
return SOURCE_FILE_MAP[moduleId];
@ -58,8 +50,8 @@ function isDeclaration(a) {
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
}
function visitTopLevelDeclarations(sourceFile, visitor) {
var stop = false;
var visit = function (node) {
let stop = false;
let visit = (node) => {
if (stop) {
return;
}
@ -81,19 +73,19 @@ function visitTopLevelDeclarations(sourceFile, visitor) {
visit(sourceFile);
}
function getAllTopLevelDeclarations(sourceFile) {
var all = [];
visitTopLevelDeclarations(sourceFile, function (node) {
let all = [];
visitTopLevelDeclarations(sourceFile, (node) => {
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
var interfaceDeclaration = node;
var triviaStart = interfaceDeclaration.pos;
var triviaEnd = interfaceDeclaration.name.pos;
var triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
let interfaceDeclaration = node;
let triviaStart = interfaceDeclaration.pos;
let triviaEnd = interfaceDeclaration.name.pos;
let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
if (triviaText.indexOf('@internal') === -1) {
all.push(node);
}
}
else {
var nodeText = getNodeText(sourceFile, node);
let nodeText = getNodeText(sourceFile, node);
if (nodeText.indexOf('@internal') === -1) {
all.push(node);
}
@ -103,8 +95,8 @@ function getAllTopLevelDeclarations(sourceFile) {
return all;
}
function getTopLevelDeclaration(sourceFile, typeName) {
var result = null;
visitTopLevelDeclarations(sourceFile, function (node) {
let result = null;
visitTopLevelDeclarations(sourceFile, (node) => {
if (isDeclaration(node) && node.name) {
if (node.name.text === typeName) {
result = node;
@ -126,8 +118,8 @@ function getNodeText(sourceFile, node) {
}
function hasModifier(modifiers, kind) {
if (modifiers) {
for (var i = 0; i < modifiers.length; i++) {
var mod = modifiers[i];
for (let i = 0; i < modifiers.length; i++) {
let mod = modifiers[i];
if (mod.kind === kind) {
return true;
}
@ -143,35 +135,35 @@ function isDefaultExport(declaration) {
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
}
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage) {
var result = getNodeText(sourceFile, declaration);
let result = getNodeText(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);
let interfaceDeclaration = declaration;
const staticTypeName = (isDefaultExport(interfaceDeclaration)
? `${importName}.default`
: `${importName}.${declaration.name.text}`);
let instanceTypeName = staticTypeName;
const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
if (typeParametersCnt > 0) {
var arr = [];
for (var i = 0; i < typeParametersCnt; i++) {
let arr = [];
for (let i = 0; i < typeParametersCnt; i++) {
arr.push('any');
}
instanceTypeName_1 = instanceTypeName_1 + "<" + arr.join(',') + ">";
instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`;
}
var members = interfaceDeclaration.members;
members.forEach(function (member) {
const members = interfaceDeclaration.members;
members.forEach((member) => {
try {
var memberText = getNodeText(sourceFile, member);
let memberText = getNodeText(sourceFile, member);
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
result = result.replace(memberText, '');
}
else {
var memberName = member.name.text;
const memberName = member.name.text;
if (isStatic(member)) {
usage.push("a = " + staticTypeName_1 + "." + memberName + ";");
usage.push(`a = ${staticTypeName}.${memberName};`);
}
else {
usage.push("a = (<" + instanceTypeName_1 + ">b)." + memberName + ";");
usage.push(`a = (<${instanceTypeName}>b).${memberName};`);
}
}
}
@ -186,9 +178,9 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
}
function format(text) {
// Parse the source text
var sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
// Get the formatting edits on the input sources
var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
let edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
// Apply the edits on the input code
return applyEdits(text, edits);
function getRuleProvider(options) {
@ -198,11 +190,11 @@ function format(text) {
}
function applyEdits(text, edits) {
// Apply edits in reverse on the existing text
var result = text;
for (var i = edits.length - 1; i >= 0; i--) {
var change = edits[i];
var head = result.slice(0, change.span.start);
var tail = result.slice(change.span.start + change.span.length);
let result = text;
for (let i = edits.length - 1; i >= 0; i--) {
let change = edits[i];
let head = result.slice(0, change.span.start);
let tail = result.slice(change.span.start + change.span.length);
result = head + change.newText + tail;
}
return result;
@ -210,131 +202,131 @@ function format(text) {
}
function createReplacer(data) {
data = data || '';
var rawDirectives = data.split(';');
var directives = [];
rawDirectives.forEach(function (rawDirective) {
let rawDirectives = data.split(';');
let directives = [];
rawDirectives.forEach((rawDirective) => {
if (rawDirective.length === 0) {
return;
}
var pieces = rawDirective.split('=>');
var findStr = pieces[0];
var replaceStr = pieces[1];
let pieces = rawDirective.split('=>');
let findStr = pieces[0];
let replaceStr = pieces[1];
findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&');
findStr = '\\b' + findStr + '\\b';
directives.push([new RegExp(findStr, 'g'), replaceStr]);
});
return function (str) {
for (var i = 0; i < directives.length; i++) {
return (str) => {
for (let i = 0; i < directives.length; i++) {
str = str.replace(directives[i][0], directives[i][1]);
}
return str;
};
}
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$/, '') + "';");
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
let lines = recipe.split(endl);
let result = [];
let usageCounter = 0;
let usageImports = [];
let usage = [];
usage.push(`var a;`);
usage.push(`var b;`);
const generateUsageImport = (moduleId) => {
let 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\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
lines.forEach(line => {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m1[1];
var sourceFile_1 = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile_1) {
let moduleId = m1[1];
const sourceFile = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile) {
return;
}
var importName_1 = generateUsageImport(moduleId);
var replacer_1 = createReplacer(m1[2]);
var typeNames = m1[3].split(/,/);
typeNames.forEach(function (typeName) {
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m1[2]);
let typeNames = m1[3].split(/,/);
typeNames.forEach((typeName) => {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
let declaration = getTopLevelDeclaration(sourceFile, typeName);
if (!declaration) {
logErr('Cannot find type ' + typeName);
return;
}
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration, importName_1, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
});
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
CURRENT_PROCESSING_RULE = line;
var moduleId = m2[1];
var sourceFile_2 = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile_2) {
let moduleId = m2[1];
const sourceFile = getSourceFile(out, inputFiles, moduleId);
if (!sourceFile) {
return;
}
var importName_2 = generateUsageImport(moduleId);
var replacer_2 = createReplacer(m2[2]);
var typeNames = m2[3].split(/,/);
var typesToExcludeMap_1 = {};
var typesToExcludeArr_1 = [];
typeNames.forEach(function (typeName) {
const importName = generateUsageImport(moduleId);
let replacer = createReplacer(m2[2]);
let typeNames = m2[3].split(/,/);
let typesToExcludeMap = {};
let typesToExcludeArr = [];
typeNames.forEach((typeName) => {
typeName = typeName.trim();
if (typeName.length === 0) {
return;
}
typesToExcludeMap_1[typeName] = true;
typesToExcludeArr_1.push(typeName);
typesToExcludeMap[typeName] = true;
typesToExcludeArr.push(typeName);
});
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
if (isDeclaration(declaration) && declaration.name) {
if (typesToExcludeMap_1[declaration.name.text]) {
if (typesToExcludeMap[declaration.name.text]) {
return;
}
}
else {
// node is ts.VariableStatement
var nodeText = getNodeText(sourceFile_2, declaration);
for (var i = 0; i < typesToExcludeArr_1.length; i++) {
if (nodeText.indexOf(typesToExcludeArr_1[i]) >= 0) {
let nodeText = getNodeText(sourceFile, declaration);
for (let i = 0; i < typesToExcludeArr.length; i++) {
if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
return;
}
}
}
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration, importName_2, usage)));
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
});
return;
}
result.push(line);
});
var resultTxt = result.join(endl);
let resultTxt = result.join(endl);
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
resultTxt = format(resultTxt);
return [
resultTxt,
usageImports.join('\n') + "\n\n" + usage.join('\n')
`${usageImports.join('\n')}\n\n${usage.join('\n')}`
];
}
function getIncludesInRecipe() {
var recipe = fs.readFileSync(RECIPE_PATH).toString();
var lines = recipe.split(/\r\n|\n|\r/);
var result = [];
lines.forEach(function (line) {
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let lines = recipe.split(/\r\n|\n|\r/);
let result = [];
lines.forEach(line => {
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m1) {
var moduleId = m1[1];
let moduleId = m1[1];
result.push(moduleId);
return;
}
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
if (m2) {
var moduleId = m2[1];
let moduleId = m2[1];
result.push(moduleId);
return;
}
@ -342,24 +334,24 @@ function getIncludesInRecipe() {
return result;
}
function getFilesToWatch(out) {
return getIncludesInRecipe().map(function (moduleId) { return moduleIdToPath(out, moduleId); });
return getIncludesInRecipe().map((moduleId) => 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 _a = generateDeclarationFile(out, inputFiles, recipe), result = _a[0], usageContent = _a[1];
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
let recipe = fs.readFileSync(RECIPE_PATH).toString();
let [result, usageContent] = generateDeclarationFile(out, inputFiles, recipe);
let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
log('Finished monaco.d.ts generation');
var one = currentContent.replace(/\r\n/gm, '\n');
var other = result.replace(/\r\n/gm, '\n');
var isTheSame = one === other;
const one = currentContent.replace(/\r\n/gm, '\n');
const other = result.replace(/\r\n/gm, '\n');
const isTheSame = one === other;
return {
content: result,
usageContent: usageContent,
filePath: DECLARATION_PATH,
isTheSame: isTheSame
isTheSame
};
}
exports.run = run;
@ -367,28 +359,28 @@ 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) {
class TypeScriptLanguageServiceHost {
constructor(libs, files, compilerOptions) {
this._libs = libs;
this._files = files;
this._compilerOptions = compilerOptions;
}
// --- language service host ---------------
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
getCompilationSettings() {
return this._compilerOptions;
};
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
}
getScriptFileNames() {
return ([]
.concat(Object.keys(this._libs))
.concat(Object.keys(this._files)));
};
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (_fileName) {
}
getScriptVersion(_fileName) {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
}
getProjectVersion() {
return '1';
};
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
}
getScriptSnapshot(fileName) {
if (this._files.hasOwnProperty(fileName)) {
return ts.ScriptSnapshot.fromString(this._files[fileName]);
}
@ -398,42 +390,41 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
else {
return ts.ScriptSnapshot.fromString('');
}
};
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (_fileName) {
}
getScriptKind(_fileName) {
return ts.ScriptKind.TS;
};
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
}
getCurrentDirectory() {
return '';
};
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (_options) {
}
getDefaultLibFileName(_options) {
return 'defaultLib:es5';
};
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
}
isDefaultLibFileName(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) {
const OUTPUT_FILES = {};
const SRC_FILES = {};
const SRC_FILE_TO_EXPECTED_NAME = {};
getIncludesInRecipe().forEach((moduleId) => {
if (/\.d\.ts$/.test(moduleId)) {
var fileName_1 = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName_1).toString();
let fileName = path.join(SRC, moduleId);
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
return;
}
var fileName = path.join(SRC, moduleId) + '.ts';
let 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, {}));
const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
var t1 = Date.now();
Object.keys(SRC_FILES).forEach(function (fileName) {
var emitOutput = languageService.getEmitOutput(fileName, true);
Object.keys(SRC_FILES).forEach((fileName) => {
const emitOutput = languageService.getEmitOutput(fileName, true);
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
});
console.log("Generating .d.ts took " + (Date.now() - t1) + " ms");
console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
return run('src', OUTPUT_FILES);
}
exports.execute = execute;

View file

@ -5,8 +5,6 @@
"@types/azure": "0.9.19",
"@types/debounce": "^1.0.0",
"@types/documentdb": "1.10.2",
"@types/es6-collections": "0.5.31",
"@types/es6-promise": "0.0.33",
"@types/glob": "^7.1.1",
"@types/gulp": "^4.0.5",
"@types/gulp-concat": "^0.0.32",

View file

@ -3,70 +3,27 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var child_process_1 = require("child_process");
var azure = require("azure-storage");
const child_process_1 = require("child_process");
const azure = require("azure-storage");
function queueSigningRequest(quality, commit) {
var retryOperations = new azure.ExponentialRetryPolicyFilter();
var queueSvc = azure
const retryOperations = new azure.ExponentialRetryPolicyFilter();
const queueSvc = azure
.createQueueService(process.env['AZURE_STORAGE_ACCOUNT_2'], process.env['AZURE_STORAGE_ACCESS_KEY_2'])
.withFilter(retryOperations);
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder();
var message = quality + "/" + commit;
return new Promise(function (c, e) { return queueSvc.createMessage('sign-darwin', message, function (err) { return err ? e(err) : c(); }); });
const message = `${quality}/${commit}`;
return new Promise((c, e) => queueSvc.createMessage('sign-darwin', message, err => err ? e(err) : c()));
}
function main(quality) {
return __awaiter(this, void 0, void 0, function () {
var commit;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
commit = child_process_1.execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
console.log("Queueing signing request for '" + quality + "/" + commit + "'...");
return [4 /*yield*/, queueSigningRequest(quality, commit)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
async function main(quality) {
const commit = child_process_1.execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
console.log(`Queueing signing request for '${quality}/${commit}'...`);
await queueSigningRequest(quality, commit);
// console.log('Waiting on signed build...');
// await waitForSignedBuild(quality, commit);
// console.log('Found signed build!');
}
main(process.argv[2]).catch(function (err) {
main(process.argv[2]).catch(err => {
console.error(err);
process.exit(1);
});

View file

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "es2017",
"module": "commonjs",
"removeComments": false,
"preserveConstEnums": true,

View file

@ -42,16 +42,6 @@
dependencies:
"@types/node" "*"
"@types/es6-collections@0.5.31":
version "0.5.31"
resolved "https://registry.yarnpkg.com/@types/es6-collections/-/es6-collections-0.5.31.tgz#faad21c930cd0ea7f71f51b9e5b555796c5ab23f"
integrity sha512-djEvbdTH5Uw7V0WqdMQLG4NK3+iu/FMZy/ylyhWEFnW5xOsXEWpivo/dhP+cR43Az+ipytza7dTSnpsWCxKYAw==
"@types/es6-promise@0.0.33":
version "0.0.33"
resolved "https://registry.yarnpkg.com/@types/es6-promise/-/es6-promise-0.0.33.tgz#280a707e62b1b6bef1a86cc0861ec63cd06c7ff3"
integrity sha512-HKJFVLCGrWQ/1unEw8JdaTxu6n3EUxmwTxJ6D0O1x0gD8joCsgoTWxEgevb7fp2XIogNjof3KEd+3bJoGne/nw==
"@types/events@*":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"

View file

@ -112,7 +112,6 @@
"mkdirp": "^0.5.0",
"mocha": "^2.2.5",
"mocha-junit-reporter": "^1.17.0",
"object-assign": "^4.0.1",
"optimist": "0.3.5",
"p-all": "^1.0.0",
"pump": "^1.0.1",

View file

@ -5,20 +5,35 @@
"strictNullChecks": true
},
"include": [
"./typings",
"./typings"
],
"files": [
"./vs/base/browser/browser.ts",
"./vs/base/browser/dom.ts",
"./vs/base/browser/event.ts",
"./vs/base/browser/fastDomNode.ts",
"./vs/base/browser/globalMouseMoveMonitor.ts",
"./vs/base/browser/history.ts",
"./vs/base/browser/iframe.ts",
"./vs/base/browser/keyboardEvent.ts",
"./vs/base/browser/mouseEvent.ts",
"./vs/base/browser/touch.ts",
"./vs/base/browser/ui/aria/aria.ts",
"./vs/base/browser/ui/contextview/contextview.ts",
"./vs/base/browser/ui/list/list.ts",
"./vs/base/browser/ui/list/splice.ts",
"./vs/base/browser/ui/octiconLabel/octiconLabel.mock.ts",
"./vs/base/browser/ui/octiconLabel/octiconLabel.ts",
"./vs/base/browser/ui/scrollbar/abstractScrollbar.ts",
"./vs/base/browser/ui/scrollbar/horizontalScrollbar.ts",
"./vs/base/browser/ui/scrollbar/scrollableElement.ts",
"./vs/base/browser/ui/scrollbar/scrollableElementOptions.ts",
"./vs/base/browser/ui/scrollbar/scrollbarArrow.ts",
"./vs/base/browser/ui/scrollbar/scrollbarState.ts",
"./vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts",
"./vs/base/browser/ui/scrollbar/verticalScrollbar.ts",
"./vs/base/browser/ui/tree/tree.ts",
"./vs/base/browser/ui/widget.ts",
"./vs/base/common/actions.ts",
"./vs/base/common/amd.ts",
"./vs/base/common/arrays.ts",
@ -47,13 +62,14 @@
"./vs/base/common/idGenerator.ts",
"./vs/base/common/iterator.ts",
"./vs/base/common/jsonSchema.ts",
"./vs/base/common/keyCodes.ts",
"./vs/base/common/keybindingParser.ts",
"./vs/base/common/keyCodes.ts",
"./vs/base/common/labels.ts",
"./vs/base/common/lifecycle.ts",
"./vs/base/common/linkedList.ts",
"./vs/base/common/map.ts",
"./vs/base/common/marshalling.ts",
"./vs/base/common/mime.ts",
"./vs/base/common/network.ts",
"./vs/base/common/normalization.ts",
"./vs/base/common/numbers.ts",
@ -88,21 +104,84 @@
"./vs/base/test/node/uri.test.perf.ts",
"./vs/base/worker/defaultWorkerFactory.ts",
"./vs/base/worker/workerMain.ts",
"./vs/code/code.main.ts",
"./vs/code/electron-browser/issue/issueReporterPage.ts",
"./vs/code/electron-browser/issue/issueReporterUtil.ts",
"./vs/code/electron-main/keyboard.ts",
"./vs/code/electron-main/theme.ts",
"./vs/code/node/shellEnv.ts",
"./vs/editor/browser/config/charWidthReader.ts",
"./vs/editor/browser/config/configuration.ts",
"./vs/editor/browser/config/elementSizeObserver.ts",
"./vs/editor/browser/controller/coreCommands.ts",
"./vs/editor/browser/controller/mouseHandler.ts",
"./vs/editor/browser/controller/mouseTarget.ts",
"./vs/editor/browser/controller/pointerHandler.ts",
"./vs/editor/browser/controller/textAreaHandler.ts",
"./vs/editor/browser/controller/textAreaInput.ts",
"./vs/editor/browser/controller/textAreaState.ts",
"./vs/editor/browser/core/editorState.ts",
"./vs/editor/browser/editorBrowser.ts",
"./vs/editor/browser/editorDom.ts",
"./vs/editor/browser/editorExtensions.ts",
"./vs/editor/browser/editorExtensions",
"./vs/editor/browser/services/abstractCodeEditorService.ts",
"./vs/editor/browser/services/bulkEditService.ts",
"./vs/editor/browser/services/codeEditorService.ts",
"./vs/editor/browser/services/codeEditorServiceImpl.ts",
"./vs/editor/browser/services/openerService.ts",
"./vs/editor/browser/view/dynamicViewOverlay.ts",
"./vs/editor/browser/view/viewController.ts",
"./vs/editor/browser/view/viewImpl.ts",
"./vs/editor/browser/view/viewLayer.ts",
"./vs/editor/browser/view/viewOutgoingEvents.ts",
"./vs/editor/browser/view/viewOverlays.ts",
"./vs/editor/browser/view/viewPart.ts",
"./vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts",
"./vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts",
"./vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts",
"./vs/editor/browser/viewParts/decorations/decorations.ts",
"./vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts",
"./vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts",
"./vs/editor/browser/viewParts/indentGuides/indentGuides.ts",
"./vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts",
"./vs/editor/browser/viewParts/lines/rangeUtil.ts",
"./vs/editor/browser/viewParts/lines/viewLine.ts",
"./vs/editor/browser/viewParts/lines/viewLines.ts",
"./vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts",
"./vs/editor/browser/viewParts/margin/margin.ts",
"./vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts",
"./vs/editor/browser/viewParts/minimap/minimap.ts",
"./vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts",
"./vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts",
"./vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts",
"./vs/editor/browser/viewParts/rulers/rulers.ts",
"./vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts",
"./vs/editor/browser/viewParts/selections/selections.ts",
"./vs/editor/browser/viewParts/viewCursors/viewCursor.ts",
"./vs/editor/browser/viewParts/viewCursors/viewCursors.ts",
"./vs/editor/browser/viewParts/viewZones/viewZones.ts",
"./vs/editor/browser/widget/codeEditorWidget.ts",
"./vs/editor/browser/widget/diffNavigator.ts",
"./vs/editor/common/commands/replaceCommand.ts",
"./vs/editor/common/commands/shiftCommand.ts",
"./vs/editor/common/commands/surroundSelectionCommand.ts",
"./vs/editor/common/commands/trimTrailingWhitespaceCommand.ts",
"./vs/editor/common/config/commonEditorConfig.ts",
"./vs/editor/common/config/editorOptions.ts",
"./vs/editor/common/config/editorZoom.ts",
"./vs/editor/common/config/fontInfo.ts",
"./vs/editor/common/controller/cursor.ts",
"./vs/editor/common/controller/cursorCollection.ts",
"./vs/editor/common/controller/cursorColumnSelection.ts",
"./vs/editor/common/controller/cursorCommon.ts",
"./vs/editor/common/controller/cursorDeleteOperations.ts",
"./vs/editor/common/controller/cursorEvents.ts",
"./vs/editor/common/controller/cursorMoveCommands.ts",
"./vs/editor/common/controller/cursorMoveOperations.ts",
"./vs/editor/common/controller/cursorTypeOperations.ts",
"./vs/editor/common/controller/cursorWordOperations.ts",
"./vs/editor/common/controller/oneCursor.ts",
"./vs/editor/common/controller/wordCharacterClassifier.ts",
"./vs/editor/common/core/characterClassifier.ts",
"./vs/editor/common/core/editOperation.ts",
@ -139,6 +218,7 @@
"./vs/editor/common/modes/languageFeatureRegistry.ts",
"./vs/editor/common/modes/languageSelector.ts",
"./vs/editor/common/modes/linkComputer.ts",
"./vs/editor/common/modes/modesRegistry.ts",
"./vs/editor/common/modes/nullMode.ts",
"./vs/editor/common/modes/supports.ts",
"./vs/editor/common/modes/supports/characterPair.ts",
@ -150,40 +230,95 @@
"./vs/editor/common/modes/supports/tokenization.ts",
"./vs/editor/common/modes/textToHtmlTokenizer.ts",
"./vs/editor/common/modes/tokenizationRegistry.ts",
"./vs/editor/common/services/editorSimpleWorker.ts",
"./vs/editor/common/services/editorWorkerService.ts",
"./vs/editor/common/services/editorWorkerServiceImpl.ts",
"./vs/editor/common/services/languagesRegistry.ts",
"./vs/editor/common/services/modelService.ts",
"./vs/editor/common/services/modelServiceImpl.ts",
"./vs/editor/common/services/modeService.ts",
"./vs/editor/common/services/modeServiceImpl.ts",
"./vs/editor/common/services/resolverService.ts",
"./vs/editor/common/services/resourceConfiguration.ts",
"./vs/editor/common/services/resourceConfigurationImpl.ts",
"./vs/editor/common/services/webWorker.ts",
"./vs/editor/common/standalone/standaloneBase.ts",
"./vs/editor/common/view/editorColorRegistry.ts",
"./vs/editor/common/view/minimapCharRenderer.ts",
"./vs/editor/common/view/overviewZoneManager.ts",
"./vs/editor/common/view/renderingContext.ts",
"./vs/editor/common/view/runtimeMinimapCharRenderer.ts",
"./vs/editor/common/view/viewContext.ts",
"./vs/editor/common/view/viewEventDispatcher.ts",
"./vs/editor/common/view/viewEvents.ts",
"./vs/editor/common/viewLayout/lineDecorations.ts",
"./vs/editor/common/viewLayout/linesLayout.ts",
"./vs/editor/common/viewLayout/viewLayout.ts",
"./vs/editor/common/viewLayout/viewLineRenderer.ts",
"./vs/editor/common/viewLayout/viewLinesViewportData.ts",
"./vs/editor/common/viewLayout/whitespaceComputer.ts",
"./vs/editor/common/viewModel/characterHardWrappingLineMapper.ts",
"./vs/editor/common/viewModel/prefixSumComputer.ts",
"./vs/editor/common/viewModel/splitLinesCollection.ts",
"./vs/editor/common/viewModel/viewEventHandler.ts",
"./vs/editor/common/viewModel/viewModel.ts",
"./vs/editor/common/viewModel/viewModelDecorations.ts",
"./vs/editor/common/viewModel/viewModelImpl.ts",
"./vs/editor/contrib/bracketMatching/bracketMatching.ts",
"./vs/editor/contrib/caretOperations/caretOperations.ts",
"./vs/editor/contrib/caretOperations/moveCaretCommand.ts",
"./vs/editor/contrib/caretOperations/transpose.ts",
"./vs/editor/contrib/clipboard/clipboard.ts",
"./vs/editor/contrib/codeAction/codeActionTrigger.ts",
"./vs/editor/contrib/colorPicker/colorPickerModel.ts",
"./vs/editor/contrib/comment/blockCommentCommand.ts",
"./vs/editor/contrib/cursorUndo/cursorUndo.ts",
"./vs/editor/contrib/dnd/dragAndDropCommand.ts",
"./vs/editor/contrib/find/findState.ts",
"./vs/editor/contrib/find/replaceAllCommand.ts",
"./vs/editor/contrib/find/replacePattern.ts",
"./vs/editor/contrib/fontZoom/fontZoom.ts",
"./vs/editor/contrib/goToDefinition/clickLinkGesture.ts",
"./vs/editor/contrib/hover/getHover.ts",
"./vs/editor/contrib/hover/hoverOperation.ts",
"./vs/editor/contrib/hover/hoverWidgets.ts",
"./vs/editor/contrib/indentation/indentUtils.ts",
"./vs/editor/contrib/inPlaceReplace/inPlaceReplaceCommand.ts",
"./vs/editor/contrib/linesOperations/copyLinesCommand.ts",
"./vs/editor/contrib/linesOperations/deleteLinesCommand.ts",
"./vs/editor/contrib/linesOperations/sortLinesCommand.ts",
"./vs/editor/contrib/links/getLinks.ts",
"./vs/editor/contrib/quickOpen/quickOpen.ts",
"./vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.ts",
"./vs/editor/contrib/wordOperations/wordOperations.ts",
"./vs/editor/editor.worker.ts",
"./vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts",
"./vs/editor/standalone/browser/standaloneCodeServiceImpl.ts",
"./vs/editor/standalone/common/monarch/monarchCommon.ts",
"./vs/editor/standalone/common/monarch/monarchCompile.ts",
"./vs/editor/standalone/common/monarch/monarchTypes.ts",
"./vs/editor/standalone/common/standaloneThemeService.ts",
"./vs/editor/standalone/common/themes.ts",
"./vs/editor/test/common/commentMode.ts",
"./vs/editor/test/common/core/viewLineToken.ts",
"./vs/editor/test/common/editorTestUtils.ts",
"./vs/editor/test/common/mocks/mockMode.ts",
"./vs/editor/test/common/mocks/testConfiguration.ts",
"./vs/editor/test/common/model/benchmark/benchmarkUtils.ts",
"./vs/editor/test/common/modes/supports/javascriptOnEnterRules.ts",
"./vs/editor/test/common/modesTestUtils.ts",
"./vs/editor/test/common/view/minimapCharRendererFactory.ts",
"./vs/monaco.d.ts",
"./vs/nls.d.ts",
"./vs/nls.mock.ts",
"./vs/platform/actions/common/actions.ts",
"./vs/platform/backup/common/backup.ts",
"./vs/platform/broadcast/electron-browser/broadcastService.ts",
"./vs/platform/clipboard/common/clipboardService.ts",
"./vs/platform/clipboard/electron-browser/clipboardService.ts",
"./vs/platform/commands/common/commands.ts",
"./vs/platform/configuration/common/configuration.ts",
"./vs/platform/configuration/common/configurationRegistry.ts",
"./vs/platform/contextkey/common/contextkey.ts",
"./vs/platform/download/common/download.ts",
"./vs/platform/editor/common/editor.ts",
@ -199,6 +334,9 @@
"./vs/platform/instantiation/common/serviceCollection.ts",
"./vs/platform/integrity/common/integrity.ts",
"./vs/platform/jsonschemas/common/jsonContributionRegistry.ts",
"./vs/platform/keybinding/common/keybindingResolver.ts",
"./vs/platform/keybinding/common/keybindingsRegistry.ts",
"./vs/platform/keybinding/common/resolvedKeybindingItem.ts",
"./vs/platform/lifecycle/common/lifecycle.ts",
"./vs/platform/localizations/common/localizations.ts",
"./vs/platform/log/common/bufferLog.ts",
@ -220,37 +358,59 @@
"./vs/platform/search/common/search.ts",
"./vs/platform/state/common/state.ts",
"./vs/platform/statusbar/common/statusbar.ts",
"./vs/platform/storage/common/storage.ts",
"./vs/platform/telemetry/common/telemetry.ts",
"./vs/platform/telemetry/common/telemetryUtils.ts",
"./vs/platform/telemetry/node/telemetryNodeUtils.ts",
"./vs/platform/theme/common/colorRegistry.ts",
"./vs/platform/theme/common/themeService.ts",
"./vs/platform/update/common/update.ts",
"./vs/platform/update/node/update.config.contribution.ts",
"./vs/platform/url/common/url.ts",
"./vs/platform/url/common/urlService.ts",
"./vs/platform/workbench/common/contextkeys.ts",
"./vs/platform/workspace/common/workspace.ts",
"./vs/platform/workspace/test/common/testWorkspace.ts",
"./vs/platform/workspaces/common/workspaces.ts",
"./vs/platform/workspaces/node/workspaces.ts",
"./vs/workbench/api/shared/tasks.ts",
"./vs/workbench/browser/parts/quickinput/quickInputUtils.ts",
"./vs/workbench/browser/parts/statusbar/statusbar.ts",
"./vs/workbench/common/activity.ts",
"./vs/workbench/common/composite.ts",
"./vs/workbench/common/contributions.ts",
"./vs/workbench/common/extensionHostProtocol.ts",
"./vs/workbench/common/memento.ts",
"./vs/workbench/common/panel.ts",
"./vs/workbench/common/resources.ts",
"./vs/workbench/common/viewlet.ts",
"./vs/workbench/parts/codeEditor/browser/menuPreventer.ts",
"./vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts",
"./vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts",
"./vs/workbench/parts/execution/common/execution.ts",
"./vs/workbench/parts/extensions/common/extensionQuery.ts",
"./vs/workbench/parts/logs/common/logConstants.ts",
"./vs/workbench/parts/markers/electron-browser/constants.ts",
"./vs/workbench/parts/markers/electron-browser/markers.ts",
"./vs/workbench/parts/markers/electron-browser/markersModel.ts",
"./vs/workbench/parts/markers/electron-browser/messages.ts",
"./vs/workbench/parts/outline/electron-browser/outline.ts",
"./vs/workbench/parts/output/common/output.ts",
"./vs/workbench/parts/performance/electron-browser/stats.ts",
"./vs/workbench/parts/scm/electron-browser/scmUtil.ts",
"./vs/workbench/parts/search/common/constants.ts",
"./vs/workbench/parts/tasks/common/taskTemplates.ts",
"./vs/workbench/parts/terminal/browser/terminalWidgetManager.ts",
"./vs/workbench/parts/terminal/common/terminal.ts",
"./vs/workbench/parts/terminal/node/terminalCommandTracker.ts",
"./vs/workbench/parts/webview/electron-browser/webviewProtocols.ts",
"./vs/workbench/parts/welcome/gettingStarted/electron-browser/gettingStarted.ts",
"./vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts",
"./vs/workbench/services/activity/common/activity.ts",
"./vs/workbench/services/backup/common/backup.ts",
"./vs/workbench/services/configuration/common/configuration.ts",
"./vs/workbench/services/configuration/common/jsonEditing.ts",
"./vs/workbench/services/configurationResolver/common/configurationResolver.ts",
"./vs/workbench/services/decorations/browser/decorations.ts",
"./vs/workbench/services/extensions/node/lazyPromise.ts",
"./vs/workbench/services/extensions/node/proxyIdentifier.ts",
@ -264,7 +424,11 @@
"./vs/workbench/services/scm/common/scmService.ts",
"./vs/workbench/services/search/node/search.ts",
"./vs/workbench/services/textMate/electron-browser/textMateService.ts",
"./vs/workbench/services/themes/common/colorThemeSchema.ts",
"./vs/workbench/services/themes/common/fileIconThemeSchema.ts",
"./vs/workbench/services/themes/common/workbenchThemeService.ts",
"./vs/workbench/services/title/common/titleService.ts",
"./vs/workbench/services/workspace/common/workspaceEditing.ts",
"./vs/workbench/test/electron-browser/api/mock.ts"
],
"exclude": [

View file

@ -381,37 +381,37 @@ declare module 'vscode-xterm' {
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'key', listener: (key?: string, event?: KeyboardEvent) => void): void;
on(type: 'key', listener: (key: string, event: KeyboardEvent) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'keypress' | 'keydown', listener: (event?: KeyboardEvent) => void): void;
on(type: 'keypress' | 'keydown', listener: (event: KeyboardEvent) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'refresh', listener: (data?: { start: number, end: number }) => void): void;
on(type: 'refresh', listener: (data: {start: number, end: number}) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'resize', listener: (data?: { cols: number, rows: number }) => void): void;
on(type: 'resize', listener: (data: {cols: number, rows: number}) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'scroll', listener: (ydisp?: number) => void): void;
on(type: 'scroll', listener: (ydisp: number) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.
* @param listener The listener.
*/
on(type: 'title', listener: (title?: string) => void): void;
on(type: 'title', listener: (title: string) => void): void;
/**
* Registers an event listener.
* @param type The type of the event.

View file

@ -728,7 +728,7 @@ export function getLargestChildWidth(parent: HTMLElement, children: HTMLElement[
// ----------------------------------------------------------------------------------------
export function isAncestor(testChild: Node | null, testAncestor: Node): boolean {
export function isAncestor(testChild: Node | null, testAncestor: Node | null): boolean {
while (testChild) {
if (testChild === testAncestor) {
return true;

View file

@ -39,9 +39,9 @@ export function standardMouseMoveMerger(lastEvent: IStandardMouseMoveEventData,
export class GlobalMouseMoveMonitor<R> extends Disposable {
private hooks: IDisposable[];
private mouseMoveEventMerger: IEventMerger<R>;
private mouseMoveCallback: IMouseMoveCallback<R>;
private onStopCallback: IOnStopCallback;
private mouseMoveEventMerger: IEventMerger<R> | null;
private mouseMoveCallback: IMouseMoveCallback<R> | null;
private onStopCallback: IOnStopCallback | null;
constructor() {
super();
@ -69,7 +69,7 @@ export class GlobalMouseMoveMonitor<R> extends Disposable {
let onStopCallback = this.onStopCallback;
this.onStopCallback = null;
if (invokeStopCallback) {
if (invokeStopCallback && onStopCallback) {
onStopCallback();
}
}
@ -94,8 +94,8 @@ export class GlobalMouseMoveMonitor<R> extends Disposable {
let windowChain = IframeUtils.getSameOriginWindowChain();
for (let i = 0; i < windowChain.length; i++) {
this.hooks.push(dom.addDisposableThrottledListener(windowChain[i].window.document, 'mousemove',
(data: R) => this.mouseMoveCallback(data),
(lastEvent: R, currentEvent) => this.mouseMoveEventMerger(lastEvent, currentEvent as MouseEvent)
(data: R) => this.mouseMoveCallback!(data),
(lastEvent: R, currentEvent) => this.mouseMoveEventMerger!(lastEvent, currentEvent as MouseEvent)
));
this.hooks.push(dom.addDisposableListener(windowChain[i].window.document, 'mouseup', (e: MouseEvent) => this.stopMonitoring(true)));
}

View file

@ -127,12 +127,12 @@ interface IGeckoMouseWheelEvent {
export class StandardMouseWheelEvent {
public readonly browserEvent: MouseWheelEvent;
public readonly browserEvent: MouseWheelEvent | null;
public readonly deltaY: number;
public readonly deltaX: number;
public readonly target: Node;
constructor(e: MouseWheelEvent, deltaX: number = 0, deltaY: number = 0) {
constructor(e: MouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {
this.browserEvent = e || null;
this.target = e ? (e.target || (<any>e).targetNode || e.srcElement) : null;

View file

@ -28,7 +28,7 @@ interface TouchData {
}
export interface GestureEvent extends MouseEvent {
initialTarget: EventTarget;
initialTarget: EventTarget | undefined;
translationX: number;
translationY: number;
pageX: number;
@ -71,7 +71,7 @@ export class Gesture extends Disposable {
private dispatched: boolean;
private targets: HTMLElement[];
private handle: IDisposable;
private handle: IDisposable | null;
private activeTouches: { [id: number]: TouchData; };

View file

@ -99,10 +99,10 @@ export class ContextView extends Disposable {
private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur'];
private static readonly BUBBLE_DOWN_EVENTS = ['click'];
private container: HTMLElement;
private container: HTMLElement | null;
private view: HTMLElement;
private delegate: IDelegate;
private toDisposeOnClean: IDisposable;
private delegate: IDelegate | null;
private toDisposeOnClean: IDisposable | null;
private toDisposeOnSetContainer: IDisposable;
constructor(container: HTMLElement) {
@ -117,7 +117,7 @@ export class ContextView extends Disposable {
this._register(toDisposable(() => this.setContainer(null)));
}
public setContainer(container: HTMLElement): void {
public setContainer(container: HTMLElement | null): void {
if (this.container) {
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
this.container.removeChild(this.view);
@ -130,13 +130,13 @@ export class ContextView extends Disposable {
const toDisposeOnSetContainer: IDisposable[] = [];
ContextView.BUBBLE_UP_EVENTS.forEach(event => {
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container!, event, (e: Event) => {
this.onDOMEvent(e, <HTMLElement>document.activeElement, false);
}));
});
ContextView.BUBBLE_DOWN_EVENTS.forEach(event => {
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container!, event, (e: Event) => {
this.onDOMEvent(e, <HTMLElement>document.activeElement, true);
}, true));
});
@ -172,13 +172,13 @@ export class ContextView extends Disposable {
return;
}
if (this.delegate.canRelayout === false) {
if (this.delegate!.canRelayout === false) {
this.hide();
return;
}
if (this.delegate.layout) {
this.delegate.layout();
if (this.delegate!.layout) {
this.delegate!.layout!();
}
this.doLayout();
@ -191,7 +191,7 @@ export class ContextView extends Disposable {
}
// Get anchor
let anchor = this.delegate.getAnchor();
let anchor = this.delegate!.getAnchor();
// Compute around
let around: IView;
@ -220,8 +220,8 @@ export class ContextView extends Disposable {
const viewSizeWidth = DOM.getTotalWidth(this.view);
const viewSizeHeight = DOM.getTotalHeight(this.view);
const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
const anchorPosition = this.delegate!.anchorPosition || AnchorPosition.BELOW;
const anchorAlignment = this.delegate!.anchorAlignment || AnchorAlignment.LEFT;
const verticalAnchor: ILayoutAnchor = { offset: around.top, size: around.height, position: anchorPosition === AnchorPosition.BELOW ? LayoutAnchorPosition.Before : LayoutAnchorPosition.After };
@ -246,7 +246,7 @@ export class ContextView extends Disposable {
DOM.addClass(this.view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top');
DOM.addClass(this.view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right');
const containerPosition = DOM.getDomNodePagePosition(this.container);
const containerPosition = DOM.getDomNodePagePosition(this.container!);
this.view.style.top = `${top - containerPosition.top}px`;
this.view.style.left = `${left - containerPosition.left}px`;
this.view.style.width = 'initial';

View file

@ -5,29 +5,23 @@
import { GestureEvent } from 'vs/base/browser/touch';
export interface IVirtualDelegate<T> {
export interface IListVirtualDelegate<T> {
getHeight(element: T): number;
getTemplateId(element: T): string;
}
// TODO@joao rename to IListRenderer
export interface IRenderer<TElement, TTemplateData> {
export interface IListRenderer<T, TTemplateData> {
templateId: string;
renderTemplate(container: HTMLElement): TTemplateData;
renderElement(element: TElement, index: number, templateData: TTemplateData): void;
disposeElement(element: TElement, index: number, templateData: TTemplateData): void;
renderElement(element: T, index: number, templateData: TTemplateData): void;
disposeElement(element: T, index: number, templateData: TTemplateData): void;
disposeTemplate(templateData: TTemplateData): void;
}
export interface IListOpenEvent<T> {
elements: T[];
indexes: number[];
browserEvent?: UIEvent;
}
export interface IListEvent<T> {
elements: T[];
indexes: number[];
browserEvent?: UIEvent;
}
export interface IListMouseEvent<T> {
@ -49,6 +43,7 @@ export interface IListGestureEvent<T> {
}
export interface IListContextMenuEvent<T> {
browserEvent: UIEvent;
element: T;
index: number;
anchor: HTMLElement | { x: number; y: number; };

View file

@ -6,13 +6,13 @@
import 'vs/css!./list';
import { IDisposable } from 'vs/base/common/lifecycle';
import { range } from 'vs/base/common/arrays';
import { IVirtualDelegate, IRenderer, IListEvent, IListOpenEvent, IListContextMenuEvent } from './list';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent } from './list';
import { List, IListStyles, IListOptions } from './listWidget';
import { IPagedModel } from 'vs/base/common/paging';
import { Event, mapEvent } from 'vs/base/common/event';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
export interface IPagedRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
export interface IPagedRenderer<TElement, TTemplateData> extends IListRenderer<TElement, TTemplateData> {
renderPlaceholder(index: number, templateData: TTemplateData): void;
}
@ -21,7 +21,7 @@ export interface ITemplateData<T> {
disposable: IDisposable;
}
class PagedRenderer<TElement, TTemplateData> implements IRenderer<number, ITemplateData<TTemplateData>> {
class PagedRenderer<TElement, TTemplateData> implements IListRenderer<number, ITemplateData<TTemplateData>> {
get templateId(): string { return this.renderer.templateId; }
@ -71,7 +71,7 @@ export class PagedList<T> implements IDisposable {
constructor(
container: HTMLElement,
virtualDelegate: IVirtualDelegate<number>,
virtualDelegate: IListVirtualDelegate<number>,
renderers: IPagedRenderer<T, any>[],
options: IListOptions<any> = {}
) {
@ -111,7 +111,7 @@ export class PagedList<T> implements IDisposable {
return mapEvent(this.list.onFocusChange, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
}
get onOpen(): Event<IListOpenEvent<T>> {
get onOpen(): Event<IListEvent<T>> {
return mapEvent(this.list.onOpen, ({ elements, indexes, browserEvent }) => ({ elements: elements.map(e => this._model.get(e)), indexes, browserEvent }));
}
@ -124,7 +124,7 @@ export class PagedList<T> implements IDisposable {
}
get onContextMenu(): Event<IListContextMenuEvent<T>> {
return mapEvent(this.list.onContextMenu, ({ element, index, anchor }) => ({ element: this._model.get(element), index, anchor }));
return mapEvent(this.list.onContextMenu, ({ element, index, anchor, browserEvent }) => ({ element: this._model.get(element), index, anchor, browserEvent }));
}
get model(): IPagedModel<T> {
@ -164,14 +164,6 @@ export class PagedList<T> implements IDisposable {
this.list.focusPrevious(n, loop);
}
selectNext(n?: number, loop?: boolean): void {
this.list.selectNext(n, loop);
}
selectPrevious(n?: number, loop?: boolean): void {
this.list.selectPrevious(n, loop);
}
focusNextPage(): void {
this.list.focusNextPage();
}

View file

@ -12,7 +12,7 @@ import { domEvent } from 'vs/base/browser/event';
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollEvent, ScrollbarVisibility } from 'vs/base/common/scrollable';
import { RangeMap, shift } from './rangeMap';
import { IVirtualDelegate, IRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
import { RowCache, IRow } from './rowCache';
import { isWindows } from 'vs/base/common/platform';
import * as browser from 'vs/base/browser/browser';
@ -60,7 +60,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private itemId: number;
private rangeMap: RangeMap;
private cache: RowCache<T>;
private renderers = new Map<string, IRenderer<T, any>>();
private renderers = new Map<string, IListRenderer<T, any>>();
private lastRenderTop: number;
private lastRenderHeight: number;
private _domNode: HTMLElement;
@ -78,8 +78,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
constructor(
container: HTMLElement,
private virtualDelegate: IVirtualDelegate<T>,
renderers: IRenderer<T, any>[],
private virtualDelegate: IListVirtualDelegate<T>,
renderers: IListRenderer<T, any>[],
options: IListViewOptions = DefaultOptions
) {
this.items = [];

View file

@ -16,7 +16,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Event, Emitter, EventBufferer, chain, mapEvent, anyEvent } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IVirtualDelegate, IRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListOpenEvent } from './list';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
import { ListView, IListViewOptions } from './listView';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
@ -31,6 +31,7 @@ export interface IIdentityProvider<T> {
interface ITraitChangeEvent {
indexes: number[];
browserEvent?: UIEvent;
}
type ITraitTemplateData = HTMLElement;
@ -40,7 +41,7 @@ interface IRenderedContainer {
index: number;
}
class TraitRenderer<T> implements IRenderer<T, ITraitTemplateData>
class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
{
private renderedElements: IRenderedContainer[] = [];
@ -159,14 +160,14 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
* @param indexes Indexes which should have this trait.
* @return The old indexes which had this trait.
*/
set(indexes: number[]): number[] {
set(indexes: number[], browserEvent?: UIEvent): number[] {
const result = this.indexes;
this.indexes = indexes;
const toRender = disjunction(result, indexes);
this.renderer.renderIndexes(toRender);
this._onChange.fire({ indexes });
this._onChange.fire({ indexes, browserEvent });
return result;
}
@ -268,7 +269,7 @@ class KeyboardController<T> implements IDisposable {
private onEnter(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.setSelection(this.list.getFocus());
this.list.setSelection(this.list.getFocus(), e.browserEvent);
if (this.openController.shouldOpen(e.browserEvent)) {
this.list.open(this.list.getFocus(), e.browserEvent);
@ -278,7 +279,7 @@ class KeyboardController<T> implements IDisposable {
private onUpArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusPrevious();
this.list.focusPrevious(1, false, e.browserEvent);
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
@ -286,7 +287,7 @@ class KeyboardController<T> implements IDisposable {
private onDownArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusNext();
this.list.focusNext(1, false, e.browserEvent);
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
@ -294,7 +295,7 @@ class KeyboardController<T> implements IDisposable {
private onPageUpArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusPreviousPage();
this.list.focusPreviousPage(e.browserEvent);
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
@ -302,7 +303,7 @@ class KeyboardController<T> implements IDisposable {
private onPageDownArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusNextPage();
this.list.focusNextPage(e.browserEvent);
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
@ -310,14 +311,14 @@ class KeyboardController<T> implements IDisposable {
private onCtrlA(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.setSelection(range(this.list.length));
this.list.setSelection(range(this.list.length), e.browserEvent);
this.view.domNode.focus();
}
private onEscape(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.setSelection([]);
this.list.setSelection([], e.browserEvent);
this.view.domNode.focus();
}
@ -417,7 +418,13 @@ class MouseController<T> implements IDisposable {
.map(e => new StandardKeyboardEvent(e))
.filter(e => this.didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
.filter(e => { e.preventDefault(); e.stopPropagation(); return false; })
.event as Event<any>;
.map(event => {
const index = this.list.getFocus()[0];
const element = this.view.element(index);
const anchor = this.view.domElement(index);
return { index, element, anchor, browserEvent: event.browserEvent };
})
.event;
const fromKeyup = chain(domEvent(this.view.domNode, 'keyup'))
.filter(() => {
@ -426,18 +433,18 @@ class MouseController<T> implements IDisposable {
return didJustPressContextMenuKey;
})
.filter(() => this.list.getFocus().length > 0)
.map(() => {
.map(browserEvent => {
const index = this.list.getFocus()[0];
const element = this.view.element(index);
const anchor = this.view.domElement(index);
return { index, element, anchor };
return { index, element, anchor, browserEvent };
})
.filter(({ anchor }) => !!anchor)
.event;
const fromMouse = chain(this.view.onContextMenu)
.filter(() => !this.didJustPressContextMenuKey)
.map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.clientX + 1, y: browserEvent.clientY } }))
.map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.clientX + 1, y: browserEvent.clientY }, browserEvent }))
.event;
return anyEvent<IListContextMenuEvent<T>>(fromKeydown, fromKeyup, fromMouse);
@ -502,7 +509,7 @@ class MouseController<T> implements IDisposable {
const focus = e.index;
if (selection.every(s => s !== focus)) {
this.list.setFocus([focus]);
this.list.setFocus([focus], e.browserEvent);
}
if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) {
@ -510,7 +517,7 @@ class MouseController<T> implements IDisposable {
}
if (this.options.selectOnMouseDown && !isMouseRightClick(e.browserEvent)) {
this.list.setSelection([focus]);
this.list.setSelection([focus], e.browserEvent);
if (this.openController.shouldOpen(e.browserEvent)) {
this.list.open([focus], e.browserEvent);
@ -525,7 +532,7 @@ class MouseController<T> implements IDisposable {
if (!this.options.selectOnMouseDown) {
const focus = this.list.getFocus();
this.list.setSelection(focus);
this.list.setSelection(focus, e.browserEvent);
if (this.openController.shouldOpen(e.browserEvent)) {
this.list.open(focus, e.browserEvent);
@ -539,7 +546,7 @@ class MouseController<T> implements IDisposable {
}
const focus = this.list.getFocus();
this.list.setSelection(focus);
this.list.setSelection(focus, e.browserEvent);
this.list.pin(focus);
}
@ -558,16 +565,16 @@ class MouseController<T> implements IDisposable {
}
const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange));
this.list.setSelection(newSelection);
this.list.setSelection(newSelection, e.browserEvent);
} else if (this.isSelectionSingleChangeEvent(e)) {
const selection = this.list.getSelection();
const newSelection = selection.filter(i => i !== focus);
if (selection.length === newSelection.length) {
this.list.setSelection([...newSelection, focus]);
this.list.setSelection([...newSelection, focus], e.browserEvent);
} else {
this.list.setSelection(newSelection);
this.list.setSelection(newSelection, e.browserEvent);
}
}
}
@ -800,11 +807,11 @@ function relativeComplement(one: number[], other: number[]): number[] {
const numericSort = (a: number, b: number) => a - b;
class PipelineRenderer<T> implements IRenderer<T, any> {
class PipelineRenderer<T> implements IListRenderer<T, any> {
constructor(
private _templateId: string,
private renderers: IRenderer<T, any>[]
private renderers: IListRenderer<T, any>[]
) { }
get templateId(): string {
@ -865,8 +872,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
readonly onContextMenu: Event<IListContextMenuEvent<T>> = Event.None;
private _onOpen = new Emitter<IListOpenEvent<T>>();
readonly onOpen: Event<IListOpenEvent<T>> = this._onOpen.event;
private _onOpen = new Emitter<IListEvent<T>>();
readonly onOpen: Event<IListEvent<T>> = this._onOpen.event;
private _onPin = new Emitter<number[]>();
@memoize get onPin(): Event<IListEvent<T>> {
@ -896,8 +903,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
constructor(
container: HTMLElement,
virtualDelegate: IVirtualDelegate<T>,
renderers: IRenderer<T, any>[],
virtualDelegate: IListVirtualDelegate<T>,
renderers: IListRenderer<T, any>[],
options: IListOptions<T> = DefaultOptions
) {
this.focus = new FocusTrait(i => this.getElementDomId(i));
@ -993,7 +1000,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.view.layout(height);
}
setSelection(indexes: number[]): void {
setSelection(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
@ -1001,24 +1008,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
indexes = indexes.sort(numericSort);
this.selection.set(indexes);
}
selectNext(n = 1, loop = false): void {
if (this.length === 0) { return; }
const selection = this.selection.get();
let index = selection.length > 0 ? selection[0] + n : 0;
this.setSelection(loop ? [index % this.length] : [Math.min(index, this.length - 1)]);
}
selectPrevious(n = 1, loop = false): void {
if (this.length === 0) { return; }
const selection = this.selection.get();
let index = selection.length > 0 ? selection[0] - n : 0;
if (loop && index < 0) {
index = this.length + (index % this.length);
}
this.setSelection([Math.max(index, 0)]);
this.selection.set(indexes, browserEvent);
}
getSelection(): number[] {
@ -1029,7 +1019,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
return this.getSelection().map(i => this.view.element(i));
}
setFocus(indexes: number[]): void {
setFocus(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new Error(`Invalid index ${index}`);
@ -1037,17 +1027,17 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
indexes = indexes.sort(numericSort);
this.focus.set(indexes);
this.focus.set(indexes, browserEvent);
}
focusNext(n = 1, loop = false): void {
focusNext(n = 1, loop = false, browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
const focus = this.focus.get();
let index = focus.length > 0 ? focus[0] + n : 0;
this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)]);
}
focusPrevious(n = 1, loop = false): void {
focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
const focus = this.focus.get();
let index = focus.length > 0 ? focus[0] - n : 0;
@ -1055,7 +1045,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.setFocus([Math.max(index, 0)]);
}
focusNextPage(): void {
focusNextPage(browserEvent?: UIEvent): void {
let lastPageIndex = this.view.indexAt(this.view.getScrollTop() + this.view.renderHeight);
lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1;
const lastPageElement = this.view.element(lastPageIndex);
@ -1074,7 +1064,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
}
focusPreviousPage(): void {
focusPreviousPage(browserEvent?: UIEvent): void {
let firstPageIndex: number;
const scrollTop = this.view.getScrollTop();
@ -1100,12 +1090,12 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
}
focusLast(): void {
focusLast(browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
this.setFocus([this.length - 1]);
}
focusFirst(): void {
focusFirst(browserEvent?: UIEvent): void {
if (this.length === 0) { return; }
this.setFocus([0]);
}
@ -1201,8 +1191,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.styleController.style(styles);
}
private toListEvent({ indexes }: ITraitChangeEvent) {
return { indexes, elements: indexes.map(i => this.view.element(i)) };
private toListEvent({ indexes, browserEvent }: ITraitChangeEvent) {
return { indexes, elements: indexes.map(i => this.view.element(i)), browserEvent };
}
private _onFocusChange(): void {

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IRenderer } from './list';
import { IListRenderer } from './list';
import { IDisposable } from 'vs/base/common/lifecycle';
import { $, removeClass } from 'vs/base/browser/dom';
@ -25,7 +25,7 @@ export class RowCache<T> implements IDisposable {
private cache = new Map<string, IRow[]>();
constructor(private renderers: Map<string, IRenderer<T, any>>) { }
constructor(private renderers: Map<string, IListRenderer<T, any>>) { }
/**
* Returns a row either by creating a new one or reusing

View file

@ -86,14 +86,18 @@ export abstract class AbstractScrollbar extends Widget {
/**
* Creates the slider dom node, adds it to the container & hooks up the events
*/
protected _createSlider(top: number, left: number, width: number, height: number): void {
protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {
this.slider = createFastDomNode(document.createElement('div'));
this.slider.setClassName('slider');
this.slider.setPosition('absolute');
this.slider.setTop(top);
this.slider.setLeft(left);
this.slider.setWidth(width);
this.slider.setHeight(height);
if (typeof width === 'number') {
this.slider.setWidth(width);
}
if (typeof height === 'number') {
this.slider.setHeight(height);
}
this.slider.setLayerHinting(true);
this.domNode.domNode.appendChild(this.slider.domNode);

View file

@ -53,7 +53,7 @@ export class HorizontalScrollbar extends AbstractScrollbar {
});
}
this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, null, options.horizontalSliderSize);
this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);
}
protected _updateSlider(sliderSize: number, sliderPosition: number): void {

View file

@ -167,7 +167,7 @@ export abstract class AbstractScrollableElement extends Widget {
private readonly _onScroll = this._register(new Emitter<ScrollEvent>());
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable?: Scrollable) {
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable: Scrollable) {
super();
element.style.overflow = 'hidden';
this._options = resolveOptions(options);

View file

@ -120,7 +120,7 @@ export interface ScrollableElementResolvedOptions {
mouseWheelScrollSensitivity: number;
mouseWheelSmoothScroll: boolean;
arrowSize: number;
listenOnDomNode: HTMLElement;
listenOnDomNode: HTMLElement | null;
horizontal: ScrollbarVisibility;
horizontalScrollbarSize: number;
horizontalSliderSize: number;

View file

@ -12,7 +12,7 @@ export class ScrollbarVisibilityController extends Disposable {
private _visibility: ScrollbarVisibility;
private _visibleClassName: string;
private _invisibleClassName: string;
private _domNode: FastDomNode<HTMLElement>;
private _domNode: FastDomNode<HTMLElement> | null;
private _shouldBeVisible: boolean;
private _isNeeded: boolean;
private _isVisible: boolean;
@ -89,7 +89,9 @@ export class ScrollbarVisibilityController extends Disposable {
// The CSS animation doesn't play otherwise
this._revealTimer.setIfNotSet(() => {
this._domNode.setClassName(this._visibleClassName);
if (this._domNode) {
this._domNode.setClassName(this._visibleClassName);
}
}, 0);
}
@ -99,6 +101,8 @@ export class ScrollbarVisibilityController extends Disposable {
return;
}
this._isVisible = false;
this._domNode.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
if (this._domNode) {
this._domNode.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
}
}
}

View file

@ -54,7 +54,7 @@ export class VerticalScrollbar extends AbstractScrollbar {
});
}
this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, null);
this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);
}
protected _updateSlider(sliderSize: number, sliderPosition: number): void {

View file

@ -13,7 +13,7 @@ import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { IContextViewProvider, AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { IVirtualDelegate, IRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
import { domEvent } from 'vs/base/browser/event';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
@ -37,7 +37,7 @@ interface ISelectListTemplateData {
disposables: IDisposable[];
}
class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemplateData> {
class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectListTemplateData> {
get templateId(): string { return SELECT_OPTION_ENTRY_TEMPLATE_ID; }
@ -86,7 +86,7 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
}
}
export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISelectOptionItem> {
export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<ISelectOptionItem> {
private static readonly DEFAULT_DROPDOWN_MINIMUM_BOTTOM_MARGIN = 32;
private static readonly DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN = 2;

View file

@ -5,13 +5,13 @@
import 'vs/css!./tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget';
import { IVirtualDelegate, IRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController, IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
import { append, $ } from 'vs/base/browser/dom';
import { Event, Relay, chain } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
@ -45,9 +45,9 @@ export function createComposedTreeListOptions<T, N extends { element: T }>(optio
};
}
export class ComposedTreeDelegate<T, N extends { element: T }> implements IVirtualDelegate<N> {
export class ComposedTreeDelegate<T, N extends { element: T }> implements IListVirtualDelegate<N> {
constructor(private delegate: IVirtualDelegate<T>) { }
constructor(private delegate: IListVirtualDelegate<T>) { }
getHeight(element: N): number {
return this.delegate.getHeight(element.element);
@ -71,12 +71,7 @@ function renderDefaultTwistie<T>(node: ITreeNode<T, any>, twistie: HTMLElement):
}
}
export interface ITreeRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
renderTwistie?(element: TElement, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<TElement>;
}
class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
readonly templateId: string;
private renderedElements = new Map<T, ITreeNode<T, TFilterData>>();
@ -84,7 +79,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
private disposables: IDisposable[] = [];
constructor(
private renderer: ITreeRenderer<T, TTemplateData>,
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>
) {
this.templateId = renderer.templateId;
@ -98,8 +93,8 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
renderTemplate(container: HTMLElement): ITreeListTemplateData<TTemplateData> {
const el = append(container, $('.monaco-tl-row'));
const twistie = append(el, $('.tl-twistie'));
const contents = append(el, $('.tl-contents'));
const twistie = append(el, $('.monaco-tl-twistie'));
const contents = append(el, $('.monaco-tl-contents'));
const templateData = this.renderer.renderTemplate(contents);
return { twistie, templateData };
@ -112,11 +107,11 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
this.renderTwistie(node, templateData.twistie);
this.renderer.renderElement(node.element, index, templateData.templateData);
this.renderer.renderElement(node, index, templateData.templateData);
}
disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData);
this.renderer.disposeElement(node, index, templateData.templateData);
this.renderedNodes.delete(node);
this.renderedElements.set(node.element);
}
@ -165,6 +160,8 @@ function isInputElement(e: HTMLElement): boolean {
}
export interface ITreeOptions<T, TFilterData = void> extends IListOptions<T>, IIndexTreeModelOptions<T, TFilterData> { }
export interface ITreeEvent<T, TFilterData> extends IListEvent<ITreeNode<T, TFilterData>> { }
export interface ITreeContextMenuEvent<T, TFilterData> extends IListContextMenuEvent<ITreeNode<T, TFilterData>> { }
export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable {
@ -173,11 +170,20 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
protected disposables: IDisposable[] = [];
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
readonly onDidChangeFocus: Event<ITreeEvent<T, TFilterData>>;
readonly onDidChangeSelection: Event<ITreeEvent<T, TFilterData>>;
readonly onContextMenu: Event<ITreeContextMenuEvent<T, TFilterData>>;
get onDidFocus(): Event<void> { return this.view.onDidFocus; }
get onDidBlur(): Event<void> { return this.view.onDidBlur; }
get onDidDispose(): Event<void> { return this.view.onDidDispose; }
constructor(
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[],
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
options?: ITreeOptions<T, TFilterData>
) {
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
@ -187,9 +193,14 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
this.disposables.push(...treeRenderers);
this.view = new List(container, treeDelegate, treeRenderers, createComposedTreeListOptions<T, ITreeNode<T, TFilterData>>(options));
this.onDidChangeFocus = this.view.onFocusChange;
this.onDidChangeSelection = this.view.onSelectionChange;
this.onContextMenu = this.view.onContextMenu;
this.model = this.createModel(this.view, options);
onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState;
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount;
this.view.onMouseClick(this.onMouseClick, this, this.disposables);
@ -202,10 +213,42 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables);
}
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
// Widget
refilter(): void {
this.model.refilter();
getHTMLElement(): HTMLElement {
return this.view.getHTMLElement();
}
domFocus(): void {
this.view.domFocus();
}
layout(height?: number): void {
this.view.layout(height);
}
style(styles: IListStyles): void {
this.view.style(styles);
}
// Tree navigation
getParentElement(ref: TRef | null = null): T | null {
return this.model.getParentElement(ref);
}
getFirstElementChild(ref: TRef | null = null): T | null {
return this.model.getFirstElementChild(ref);
}
getLastElementAncestor(ref: TRef | null = null): T | null {
return this.model.getLastElementAncestor(ref);
}
// Tree
getNode(location?: TRef): ITreeNode<T, TFilterData> {
return this.model.getNode(location);
}
collapse(location: TRef): boolean {
@ -216,6 +259,89 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
return this.model.setCollapsed(location, false);
}
toggleCollapsed(ref: TRef): void {
this.model.toggleCollapsed(ref);
}
collapseAll(): void {
this.model.collapseAll();
}
isCollapsed(ref: TRef): boolean {
return this.model.isCollapsed(ref);
}
isExpanded(ref: TRef): boolean {
return !this.isCollapsed(ref);
}
refilter(): void {
this.model.refilter();
}
setSelection(elements: TRef[], browserEvent?: UIEvent): void {
const indexes = elements.map(e => this.model.getListIndex(e));
this.view.setSelection(indexes, browserEvent);
}
getSelection(): T[] {
const nodes = this.view.getSelectedElements();
return nodes.map(n => n.element);
}
setFocus(elements: TRef[]): void {
const indexes = elements.map(e => this.model.getListIndex(e));
this.view.setFocus(indexes);
}
focusNext(n = 1, loop = false): void {
this.view.focusNext(n, loop);
}
focusPrevious(n = 1, loop = false): void {
this.view.focusPrevious(n, loop);
}
focusNextPage(): void {
this.view.focusNextPage();
}
focusPreviousPage(): void {
this.view.focusPreviousPage();
}
focusLast(): void {
this.view.focusLast();
}
focusFirst(): void {
this.view.focusFirst();
}
getFocus(): T[] {
const nodes = this.view.getFocusedElements();
return nodes.map(n => n.element);
}
open(elements: TRef[]): void {
const indexes = elements.map(e => this.model.getListIndex(e));
this.view.open(indexes);
}
reveal(location: TRef, relativeTop?: number): void {
const index = this.model.getListIndex(location);
this.view.reveal(index, relativeTop);
}
/**
* Returns the relative position of an element rendered in the list.
* Returns `null` if the element isn't *entirely* in the visible viewport.
*/
getRelativeTop(location: TRef): number | null {
const index = this.model.getListIndex(location);
return this.view.getRelativeTop(index);
}
private onMouseClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
const node = e.element;
const location = this.model.getNodeLocation(node);
@ -293,6 +419,8 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
this.model.toggleCollapsed(location);
}
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
dispose(): void {
this.disposables = dispose(this.disposables);
this.view.dispose();

View file

@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions, ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async';
@ -39,14 +39,25 @@ interface IDataTreeListTemplateData<T> {
templateData: T;
}
class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>> {
function unpack<T, TFilterData>(node: ITreeNode<IDataTreeNode<T>, TFilterData>): ITreeNode<T, TFilterData> {
return new Proxy(Object.create(null), {
get: (_: any, name: string) => {
switch (name) {
case 'element': return node.element.element;
default: return node[name];
}
}
});
}
class DataTreeRenderer<T, TFilterData, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, TFilterData, IDataTreeListTemplateData<TTemplateData>> {
readonly templateId: string;
private renderedNodes = new Map<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>>();
private disposables: IDisposable[] = [];
constructor(
private renderer: IRenderer<T, TTemplateData>,
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
readonly onDidChangeTwistieState: Event<IDataTreeNode<T>>
) {
this.templateId = renderer.templateId;
@ -57,8 +68,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return { templateData };
}
renderElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.renderElement(node.element, index, templateData.templateData);
renderElement(element: ITreeNode<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.renderElement(unpack(element), index, templateData.templateData);
}
renderTwistie(element: IDataTreeNode<T>, twistieElement: HTMLElement): boolean {
@ -70,8 +81,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return false;
}
disposeElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData);
disposeElement(element: ITreeNode<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(unpack(element), index, templateData.templateData);
}
disposeTemplate(templateData: IDataTreeListTemplateData<TTemplateData>): void {
@ -96,8 +107,8 @@ export class DataTree<T extends NonNullable<any>, TFilterData = void> implements
constructor(
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[],
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<T, TFilterData, any>[],
private dataSource: IDataSource<T>,
options?: ITreeOptions<T, TFilterData>
) {

View file

@ -5,21 +5,21 @@
import { ISpliceable } from 'vs/base/common/sequence';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { Emitter, Event } from 'vs/base/common/event';
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
import { tail2 } from 'vs/base/common/arrays';
import { ITreeFilterResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
import { ITreeFilterDataResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
interface IMutableTreeNode<T, TFilterData> extends ITreeNode<T, TFilterData> {
readonly parent: IMutableTreeNode<T, TFilterData> | undefined;
readonly children: IMutableTreeNode<T, TFilterData>[];
collapsible: boolean;
collapsed: boolean;
revealedCount: number;
filterData: TFilterData | undefined;
renderNodeCount: number;
visible: boolean;
filterData: TFilterData | undefined;
}
function isFilterResult<T>(obj: any): obj is ITreeFilterResult<T> {
function isFilterResult<T>(obj: any): obj is ITreeFilterDataResult<T> {
return typeof obj === 'object' && 'visibility' in obj && 'data' in obj;
}
@ -30,8 +30,10 @@ function treeNodeToElement<T>(node: IMutableTreeNode<T, any>): ITreeElement<T> {
return { element, children, collapsed };
}
function getVisibleState(visibility: TreeVisibility): boolean | undefined {
function getVisibleState(visibility: boolean | TreeVisibility): boolean | undefined {
switch (visibility) {
case true: return true;
case false: return false;
case TreeVisibility.Hidden: return false;
case TreeVisibility.Visible: return true;
case TreeVisibility.Recurse: return undefined;
@ -49,13 +51,18 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
depth: 0,
collapsible: false,
collapsed: false,
revealedCount: 0,
renderNodeCount: 0,
visible: true,
filterData: undefined
};
private eventBufferer = new EventBufferer();
private _onDidChangeCollapseState = new Emitter<ITreeNode<T, TFilterData>>();
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>> = this._onDidChangeCollapseState.event;
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeCollapseState.event);
private _onDidChangeRenderNodeCount = new Emitter<ITreeNode<T, TFilterData>>();
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeRenderNodeCount.event);
private filter?: ITreeFilter<T, TFilterData>;
@ -74,25 +81,25 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
throw new Error('Invalid tree location');
}
const { parentNode, listIndex, revealed } = this.findParentNode(location);
const { parentNode, listIndex, revealed } = this.getParentNodeWithListIndex(location);
const treeListElementsToInsert: ITreeNode<T, TFilterData>[] = [];
const nodesToInsertIterator = Iterator.map(Iterator.from(toInsert), el => this.createTreeNode(el, parentNode, revealed, treeListElementsToInsert, onDidCreateNode));
const nodesToInsert: IMutableTreeNode<T, TFilterData>[] = [];
let revealedCount = 0;
let renderNodeCount = 0;
Iterator.forEach(nodesToInsertIterator, node => {
nodesToInsert.push(node);
revealedCount += node.revealedCount;
renderNodeCount += node.renderNodeCount;
});
const lastIndex = location[location.length - 1];
const deletedNodes = parentNode.children.splice(lastIndex, deleteCount, ...nodesToInsert);
if (revealed) {
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + node.revealedCount, 0);
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + node.renderNodeCount, 0);
this._updateAncestorsRevealedCount(parentNode, revealedCount - visibleDeleteCount);
this._updateAncestorsRenderNodeCount(parentNode, renderNodeCount - visibleDeleteCount);
this.list.splice(listIndex, visibleDeleteCount, treeListElementsToInsert);
}
@ -109,44 +116,43 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
getListIndex(location: number[]): number {
return this.findNode(location).listIndex;
return this.getTreeNodeWithListIndex(location).listIndex;
}
setCollapsed(location: number[], collapsed: boolean): boolean {
const { node, listIndex, revealed } = this.findNode(location);
return this._setCollapsed(node, listIndex, revealed, collapsed);
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
return this.eventBufferer.bufferEvents(() => this._setCollapsed(node, listIndex, revealed, collapsed));
}
toggleCollapsed(location: number[]): void {
const { node, listIndex, revealed } = this.findNode(location);
this._setCollapsed(node, listIndex, revealed);
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
this.eventBufferer.bufferEvents(() => this._setCollapsed(node, listIndex, revealed));
}
// // TODO@joao cleanup
// setCollapsedAll(collapsed: boolean): void {
// if (collapsed) {
// const queue = [...this.root.children]; // TODO@joao use a linked list
// let listIndex = 0;
collapseAll(): void {
const queue = [...this.root.children]; // TODO@joao use a linked list
let listIndex = 0;
// while (queue.length > 0) {
// const node = queue.shift();
// const revealed = listIndex < this.root.children.length;
// this._setCollapsed(node, listIndex, revealed, collapsed);
this.eventBufferer.bufferEvents(() => {
while (queue.length > 0) {
const node = queue.shift();
const revealed = listIndex < this.root.children.length;
this._setCollapsed(node, listIndex, revealed, true);
// queue.push(...node.children);
// listIndex++;
// }
// }
// }
queue.push(...node.children);
listIndex++;
}
});
}
isCollapsed(location: number[]): boolean {
return this.findNode(location).node.collapsed;
return this.getTreeNode(location).collapsed;
}
refilter(): void {
const previousRevealedCount = this.root.revealedCount;
const previousRenderNodeCount = this.root.renderNodeCount;
const toInsert = this.updateNodeAfterFilterChange(this.root);
this.list.splice(0, previousRevealedCount, toInsert);
this.list.splice(0, previousRenderNodeCount, toInsert);
}
private _setCollapsed(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, collapsed?: boolean | undefined): boolean {
@ -165,10 +171,10 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
node.collapsed = collapsed;
if (revealed) {
const previousRevealedCount = node.revealedCount;
const previousRenderNodeCount = node.renderNodeCount;
const toInsert = this.updateNodeAfterCollapseChange(node);
this.list.splice(listIndex + 1, previousRevealedCount - 1, toInsert.slice(1));
this.list.splice(listIndex + 1, previousRenderNodeCount - 1, toInsert.slice(1));
this._onDidChangeCollapseState.fire(node);
}
@ -189,7 +195,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
depth: parent.depth + 1,
collapsible: typeof treeElement.collapsible === 'boolean' ? treeElement.collapsible : (typeof treeElement.collapsed === 'boolean'),
collapsed: !!treeElement.collapsed,
revealedCount: 1,
renderNodeCount: 1,
visible: true,
filterData: undefined
};
@ -201,28 +207,29 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
const childElements = Iterator.from(treeElement.children);
const childNodes = Iterator.map(childElements, el => this.createTreeNode(el, node, revealed && !treeElement.collapsed, treeListElements, onDidCreateNode));
const childRevealed = revealed && visible !== false && !node.collapsed;
const childNodes = Iterator.map(childElements, el => this.createTreeNode(el, node, childRevealed, treeListElements, onDidCreateNode));
let hasVisibleDescendants = false;
let revealedCount = 1;
let renderNodeCount = 1;
Iterator.forEach(childNodes, child => {
node.children.push(child);
hasVisibleDescendants = hasVisibleDescendants || child.visible;
revealedCount += child.revealedCount;
renderNodeCount += child.renderNodeCount;
});
node.collapsible = node.collapsible || node.children.length > 0;
node.visible = typeof visible === 'undefined' ? hasVisibleDescendants : visible;
if (!node.visible) {
node.revealedCount = 0;
node.renderNodeCount = 0;
if (revealed) {
treeListElements.pop();
}
} else if (!node.collapsed) {
node.revealedCount = revealedCount;
node.renderNodeCount = renderNodeCount;
}
if (onDidCreateNode) {
@ -233,11 +240,11 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
private updateNodeAfterCollapseChange(node: IMutableTreeNode<T, TFilterData>): ITreeNode<T, TFilterData>[] {
const previousRevealedCount = node.revealedCount;
const previousRenderNodeCount = node.renderNodeCount;
const result: ITreeNode<T, TFilterData>[] = [];
this._updateNodeAfterCollapseChange(node, result);
this._updateAncestorsRevealedCount(node.parent, result.length - previousRevealedCount);
this._updateAncestorsRenderNodeCount(node.parent, result.length - previousRenderNodeCount);
return result;
}
@ -248,23 +255,24 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
result.push(node);
node.revealedCount = 1;
node.renderNodeCount = 1;
if (!node.collapsed) {
for (const child of node.children) {
node.revealedCount += this._updateNodeAfterCollapseChange(child, result);
node.renderNodeCount += this._updateNodeAfterCollapseChange(child, result);
}
}
return node.revealedCount;
this._onDidChangeRenderNodeCount.fire(node);
return node.renderNodeCount;
}
private updateNodeAfterFilterChange(node: IMutableTreeNode<T, TFilterData>): ITreeNode<T, TFilterData>[] {
const previousRevealedCount = node.revealedCount;
const previousRenderNodeCount = node.renderNodeCount;
const result: ITreeNode<T, TFilterData>[] = [];
this._updateNodeAfterFilterChange(node, result);
this._updateAncestorsRevealedCount(node.parent, result.length - previousRevealedCount);
this._updateAncestorsRenderNodeCount(node.parent, result.length - previousRenderNodeCount);
return result;
}
@ -286,7 +294,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
const resultStartLength = result.length;
node.revealedCount = node === this.root ? 0 : 1;
node.renderNodeCount = node === this.root ? 0 : 1;
let hasVisibleDescendants = false;
if (visible !== false || !node.collapsed) {
@ -300,25 +308,27 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
if (!node.visible) {
node.revealedCount = 0;
node.renderNodeCount = 0;
if (revealed) {
result.pop();
}
} else if (!node.collapsed) {
node.revealedCount += result.length - resultStartLength;
node.renderNodeCount += result.length - resultStartLength;
}
this._onDidChangeRenderNodeCount.fire(node);
return node.visible;
}
private _updateAncestorsRevealedCount(node: IMutableTreeNode<T, TFilterData>, diff: number): void {
private _updateAncestorsRenderNodeCount(node: IMutableTreeNode<T, TFilterData>, diff: number): void {
if (diff === 0) {
return;
}
while (node) {
node.revealedCount += diff;
node.renderNodeCount += diff;
this._onDidChangeRenderNodeCount.fire(node);
node = node.parent;
}
}
@ -338,8 +348,24 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
}
}
private findNode(location: number[]): { node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean } {
const { parentNode, listIndex, revealed } = this.findParentNode(location);
// cheap
private getTreeNode(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root): IMutableTreeNode<T, TFilterData> {
if (location.length === 0) {
return node;
}
const [index, ...rest] = location;
if (index < 0 || index > node.children.length) {
throw new Error('Invalid tree location');
}
return this.getTreeNode(rest, node.children[index]);
}
// expensive
private getTreeNodeWithListIndex(location: number[]): { node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean } {
const { parentNode, listIndex, revealed } = this.getParentNodeWithListIndex(location);
const index = location[location.length - 1];
if (index < 0 || index > parentNode.children.length) {
@ -351,7 +377,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
return { node, listIndex, revealed };
}
private findParentNode(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root, listIndex: number = 0, revealed = true): { parentNode: IMutableTreeNode<T, TFilterData>; listIndex: number; revealed: boolean; } {
private getParentNodeWithListIndex(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root, listIndex: number = 0, revealed = true): { parentNode: IMutableTreeNode<T, TFilterData>; listIndex: number; revealed: boolean; } {
const [index, ...rest] = location;
if (index < 0 || index > node.children.length) {
@ -360,7 +386,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
// TODO@joao perf!
for (let i = 0; i < index; i++) {
listIndex += node.children[i].revealedCount;
listIndex += node.children[i].renderNodeCount;
}
revealed = revealed && !node.collapsed;
@ -369,7 +395,11 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
return { parentNode: node, listIndex, revealed };
}
return this.findParentNode(rest, node.children[index], listIndex + 1, revealed);
return this.getParentNodeWithListIndex(rest, node.children[index], listIndex + 1, revealed);
}
getNode(location: number[] = []): ITreeNode<T, TFilterData> {
return this.getTreeNode(location);
}
// TODO@joao perf!
@ -391,4 +421,38 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
return tail2(location)[0];
}
getParentElement(location: number[]): T | null {
const parentLocation = this.getParentNodeLocation(location);
const node = this.getTreeNode(parentLocation);
return node === this.root ? null : node.element;
}
getFirstElementChild(location: number[]): T | null {
const node = this.getTreeNode(location);
if (node.children.length === 0) {
return null;
}
return node.children[0].element;
}
getLastElementAncestor(location: number[]): T | null {
const node = this.getTreeNode(location);
if (node.children.length === 0) {
return null;
}
return this._getLastElementAncestor(node);
}
private _getLastElementAncestor(node: ITreeNode<T, TFilterData>): T | null {
if (node.children.length === 0) {
return node.element;
}
return this._getLastElementAncestor(node.children[node.children.length - 1]);
}
}

View file

@ -19,12 +19,14 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
private nodes = new Map<T, ITreeNode<T, TFilterData>>();
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
get size(): number { return this.nodes.size; }
constructor(list: ISpliceable<ITreeNode<T, TFilterData>>, options: IObjectTreeModelOptions<T, TFilterData> = {}) {
this.model = new IndexTreeModel(list, options);
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState;
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount;
}
setChildren(element: T | null, children?: ISequence<ITreeElement<T>>): Iterator<ITreeElement<T>> {
@ -45,6 +47,21 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
return this.model.splice([...location, 0], Number.MAX_VALUE, children, onDidCreateNode, onDidDeleteNode);
}
getParentElement(ref: T | null = null): T | null {
const location = this.getElementLocation(ref);
return this.model.getParentElement(location);
}
getFirstElementChild(ref: T | null = null): T | null {
const location = this.getElementLocation(ref);
return this.model.getFirstElementChild(location);
}
getLastElementAncestor(ref: T | null = null): T | null {
const location = this.getElementLocation(ref);
return this.model.getLastElementAncestor(location);
}
getListIndex(element: T): number {
const location = this.getElementLocation(element);
return this.model.getListIndex(location);
@ -60,6 +77,10 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
this.model.toggleCollapsed(location);
}
collapseAll(): void {
this.model.collapseAll();
}
isCollapsed(element: T): boolean {
const location = this.getElementLocation(element);
return this.model.isCollapsed(location);
@ -69,6 +90,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
this.model.refilter();
}
getNode(element: T = null): ITreeNode<T, TFilterData> {
const location = this.getElementLocation(element);
return this.model.getNode(location);
}
getNodeLocation(node: ITreeNode<T, TFilterData>): T {
return node.element;
}

View file

@ -9,13 +9,17 @@
align-items: center;
}
.monaco-tl-row > .tl-twistie,
.monaco-tl-row > .tl-contents {
.monaco-tl-row > .monaco-tl-twistie,
.monaco-tl-row > .monaco-tl-contents {
height: 100%;
}
.monaco-tl-row > .tl-twistie {
.monaco-tl-row > .monaco-tl-twistie {
font-size: 10px;
text-align: right;
padding-right: 10px;
}
.monaco-tl-row > .monaco-tl-contents {
flex: 1;
}

View file

@ -5,6 +5,7 @@
import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator';
import { IListRenderer } from 'vs/base/browser/ui/list/list';
export const enum TreeVisibility {
Hidden,
@ -12,13 +13,15 @@ export const enum TreeVisibility {
Recurse // TODO@joao come up with a better name
}
export interface ITreeFilterResult<TFilterData> {
visibility: TreeVisibility;
export interface ITreeFilterDataResult<TFilterData> {
visibility: boolean | TreeVisibility;
data: TFilterData;
}
export type TreeFilterResult<TFilterData> = boolean | TreeVisibility | ITreeFilterDataResult<TFilterData>;
export interface ITreeFilter<T, TFilterData = void> {
filter(element: T): boolean | TreeVisibility | ITreeFilterResult<TFilterData>;
filter(element: T): TreeFilterResult<TFilterData>;
}
export interface ITreeOptions<T, TFilterData = void> {
@ -39,19 +42,32 @@ export interface ITreeNode<T, TFilterData = void> {
readonly depth: number;
readonly collapsible: boolean;
readonly collapsed: boolean;
readonly revealedCount: number;
readonly renderNodeCount: number;
readonly visible: boolean;
readonly filterData: TFilterData | undefined;
}
export interface ITreeModel<T, TFilterData, TRef> {
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
getListIndex(ref: TRef): number;
setCollapsed(ref: TRef, collapsed: boolean): boolean;
toggleCollapsed(ref: TRef): void;
collapseAll(): void;
isCollapsed(ref: TRef): boolean;
refilter(): void;
getNode(location?: TRef): ITreeNode<T, any>;
getNodeLocation(node: ITreeNode<T, any>): TRef;
getParentNodeLocation(location: TRef): TRef | null;
getParentElement(location: TRef): T | null;
getFirstElementChild(location: TRef): T | null;
getLastElementAncestor(location: TRef): T | null;
}
export interface ITreeRenderer<T, TFilterData, TTemplateData> extends IListRenderer<ITreeNode<T, TFilterData>, TTemplateData> {
renderTwistie?(element: T, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<T>;
}

View file

@ -16,7 +16,7 @@ export interface IAction extends IDisposable {
id: string;
label: string;
tooltip: string;
class: string;
class: string | undefined;
enabled: boolean;
checked: boolean;
radio: boolean;
@ -56,7 +56,7 @@ export class Action implements IAction {
protected _id: string;
protected _label: string;
protected _tooltip: string;
protected _cssClass: string;
protected _cssClass: string | undefined;
protected _enabled: boolean;
protected _checked: boolean;
protected _radio: boolean;
@ -104,15 +104,15 @@ export class Action implements IAction {
}
}
get class(): string {
get class(): string | undefined {
return this._cssClass;
}
set class(value: string) {
set class(value: string | undefined) {
this._setClass(value);
}
protected _setClass(value: string): void {
protected _setClass(value: string | undefined): void {
if (this._cssClass !== value) {
this._cssClass = value;
this._onDidChange.fire({ class: value });

View file

@ -299,16 +299,16 @@ function topStep<T>(array: T[], compare: (a: T, b: T) => number, result: T[], i:
/**
* @returns a new array with all undefined or null values removed. The original array is not modified at all.
*/
export function coalesce<T>(array: T[]): T[];
export function coalesce<T>(array: T[], inplace: true): void;
export function coalesce<T>(array: T[], inplace?: true): void | T[] {
export function coalesce<T>(array: (T | undefined | null)[]): T[];
export function coalesce<T>(array: (T | undefined | null)[], inplace: true): void;
export function coalesce<T>(array: (T | undefined | null)[], inplace?: true): void | T[] {
if (!array) {
if (!inplace) {
return array;
}
}
if (!inplace) {
return array.filter(e => !!e);
return <T[]>array.filter(e => !!e);
} else {
let to = 0;

View file

@ -406,12 +406,13 @@ export class EventBufferer {
};
}
bufferEvents(fn: () => void): void {
bufferEvents<R = void>(fn: () => R): R {
const buffer: Function[] = [];
this.buffers.push(buffer);
fn();
const r = fn();
this.buffers.pop();
buffer.forEach(flush => flush());
return r;
}
}

View file

@ -80,7 +80,7 @@ export abstract class ReferenceCollection<T> {
const { object } = reference;
const dispose = once(() => {
if (--reference.counter === 0) {
this.destroyReferencedObject(reference.object);
this.destroyReferencedObject(key, reference.object);
delete this.references[key];
}
});
@ -91,7 +91,7 @@ export abstract class ReferenceCollection<T> {
}
protected abstract createReferencedObject(key: string): T;
protected abstract destroyReferencedObject(object: T): void;
protected abstract destroyReferencedObject(key: string, object: T): void;
}
export class ImmortalReference<T> implements IReference<T> {

View file

@ -5,6 +5,7 @@
import * as paths from 'vs/base/common/paths';
import * as strings from 'vs/base/common/strings';
import * as arrays from 'vs/base/common/arrays';
import { match } from 'vs/base/common/glob';
export const MIME_TEXT = 'text/plain';
@ -136,10 +137,10 @@ export function guessMimeTypes(path: string, firstLine?: string): string[] {
return [MIME_UNKNOWN];
}
function guessMimeTypeByPath(path: string, filename: string, associations: ITextMimeAssociationItem[]): string {
let filenameMatch: ITextMimeAssociationItem;
let patternMatch: ITextMimeAssociationItem;
let extensionMatch: ITextMimeAssociationItem;
function guessMimeTypeByPath(path: string, filename: string, associations: ITextMimeAssociationItem[]): string | null {
let filenameMatch: ITextMimeAssociationItem | null = null;
let patternMatch: ITextMimeAssociationItem | null = null;
let extensionMatch: ITextMimeAssociationItem | null = null;
// We want to prioritize associations based on the order they are registered so that the last registered
// association wins over all other. This is for https://github.com/Microsoft/vscode/issues/20074
@ -154,9 +155,9 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
// Longest pattern match
if (association.filepattern) {
if (!patternMatch || association.filepattern.length > patternMatch.filepattern.length) {
if (!patternMatch || association.filepattern.length > patternMatch.filepattern!.length) {
const target = association.filepatternOnPath ? path : filename; // match on full path if pattern contains path separator
if (match(association.filepatternLowercase, target)) {
if (match(association.filepatternLowercase!, target)) {
patternMatch = association;
}
}
@ -164,8 +165,8 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
// Longest extension match
if (association.extension) {
if (!extensionMatch || association.extension.length > extensionMatch.extension.length) {
if (strings.endsWith(filename, association.extensionLowercase)) {
if (!extensionMatch || association.extension.length > extensionMatch.extension!.length) {
if (strings.endsWith(filename, association.extensionLowercase!)) {
extensionMatch = association;
}
}
@ -190,7 +191,7 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
return null;
}
function guessMimeTypeByFirstline(firstLine: string): string {
function guessMimeTypeByFirstline(firstLine: string): string | null {
if (strings.startsWithUTF8BOM(firstLine)) {
firstLine = firstLine.substr(1);
}
@ -234,7 +235,7 @@ export function suggestFilename(langId: string, prefix: string): string {
const extensions = registeredAssociations
.filter(assoc => !assoc.userConfigured && assoc.extension && assoc.id === langId)
.map(assoc => assoc.extension);
const extensionsWithDotFirst = extensions
const extensionsWithDotFirst = arrays.coalesce(extensions)
.filter(assoc => strings.startsWith(assoc, '.'));
if (extensionsWithDotFirst.length > 0) {

View file

@ -82,14 +82,14 @@ export function isBoolean(obj: any): obj is boolean {
/**
* @returns whether the provided parameter is undefined.
*/
export function isUndefined(obj: any): boolean {
export function isUndefined(obj: any): obj is undefined {
return typeof (obj) === _typeof.undefined;
}
/**
* @returns whether the provided parameter is undefined or null.
*/
export function isUndefinedOrNull(obj: any): boolean {
export function isUndefinedOrNull(obj: any): obj is undefined | null {
return isUndefined(obj) || obj === null;
}

View file

@ -5,7 +5,7 @@
import * as assert from 'assert';
import { ListView } from 'vs/base/browser/ui/list/listView';
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import { range } from 'vs/base/common/arrays';
suite('ListView', function () {
@ -14,14 +14,14 @@ suite('ListView', function () {
element.style.height = '200px';
element.style.width = '200px';
const delegate: IVirtualDelegate<number> = {
const delegate: IListVirtualDelegate<number> = {
getHeight() { return 20; },
getTemplateId() { return 'template'; }
};
let templatesCount = 0;
const renderer: IRenderer<number, void> = {
const renderer: IListRenderer<number, void> = {
templateId: 'template',
renderTemplate() { templatesCount++; },
renderElement() { },

View file

@ -54,7 +54,7 @@ suite('Reference Collection', () => {
private _count = 0;
get count() { return this._count; }
protected createReferencedObject(key: string): number { this._count++; return key.length; }
protected destroyReferencedObject(object: number): void { this._count--; }
protected destroyReferencedObject(key: string, object: number): void { this._count--; }
}
test('simple', () => {

View file

@ -67,10 +67,10 @@ export class DefaultWorkerFactory implements IWorkerFactory {
private static LAST_WORKER_ID = 0;
private _label: string;
private _label: string | undefined;
private _webWorkerFailedBeforeError: any;
constructor(label: string) {
constructor(label: string | undefined) {
this._label = label;
this._webWorkerFailedBeforeError = false;
}

View file

@ -187,7 +187,7 @@ class CSSBasedConfiguration extends Disposable {
return this._cache.get(bareFontInfo);
}
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[]): CharWidthRequest {
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[] | null): CharWidthRequest {
let result = new CharWidthRequest(chr, type);
all.push(result);
if (monospace) {

View file

@ -8,13 +8,13 @@ import { IDimension } from 'vs/editor/common/editorCommon';
export class ElementSizeObserver extends Disposable {
private referenceDomElement: HTMLElement;
private referenceDomElement: HTMLElement | null;
private measureReferenceDomElementToken: any;
private changeCallback: () => void;
private width: number;
private height: number;
constructor(referenceDomElement: HTMLElement, changeCallback: () => void) {
constructor(referenceDomElement: HTMLElement | null, changeCallback: () => void) {
super();
this.referenceDomElement = referenceDomElement;
this.changeCallback = changeCallback;

View file

@ -121,7 +121,7 @@ export namespace EditorScroll_ {
select?: boolean;
}
export function parse(args: RawArguments): ParsedArguments {
export function parse(args: RawArguments): ParsedArguments | null {
let direction: Direction;
switch (args.to) {
case RawDirection.Up:
@ -720,11 +720,11 @@ export namespace CoreNavigationCommands {
for (let i = 0, len = states.length; i < len; i++) {
const state = states[i];
if (newModelPosition && !state.modelState.selection.containsPosition(newModelPosition)) {
if (newModelPosition && !state.modelState!.selection.containsPosition(newModelPosition)) {
continue;
}
if (newViewPosition && !state.viewState.selection.containsPosition(newViewPosition)) {
if (newViewPosition && !state.viewState!.selection.containsPosition(newViewPosition)) {
continue;
}
@ -1419,7 +1419,7 @@ export namespace CoreNavigationCommands {
public runCoreEditorCommand(cursors: ICursors, args: any): void {
const revealLineArg = <RevealLine_.RawArguments>args;
let lineNumber = revealLineArg.lineNumber + 1;
let lineNumber = (revealLineArg.lineNumber || 0) + 1;
if (lineNumber < 1) {
lineNumber = 1;
}
@ -1499,7 +1499,20 @@ export namespace CoreNavigationCommands {
export namespace CoreEditingCommands {
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends EditorCommand {
export abstract class CoreEditingCommand extends EditorCommand {
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
const cursors = editor._getCursors();
if (!cursors) {
// the editor has no view => has no cursors
return;
}
this.runCoreEditingCommand(editor, cursors, args || {});
}
public abstract runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void;
}
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
constructor() {
super({
id: 'lineBreakInsert',
@ -1507,19 +1520,19 @@ export namespace CoreEditingCommands {
kbOpts: {
weight: CORE_WEIGHT,
kbExpr: EditorContextKeys.textInputFocus,
primary: null,
primary: 0,
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_O }
}
});
}
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
editor.pushUndoStop();
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
}
});
export const Outdent: EditorCommand = registerEditorCommand(new class extends EditorCommand {
export const Outdent: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
constructor() {
super({
id: 'outdent',
@ -1535,14 +1548,14 @@ export namespace CoreEditingCommands {
});
}
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
editor.pushUndoStop();
editor.executeCommands(this.id, TypeOperations.outdent(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
editor.executeCommands(this.id, TypeOperations.outdent(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
editor.pushUndoStop();
}
});
export const Tab: EditorCommand = registerEditorCommand(new class extends EditorCommand {
export const Tab: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
constructor() {
super({
id: 'tab',
@ -1558,14 +1571,14 @@ export namespace CoreEditingCommands {
});
}
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
editor.pushUndoStop();
editor.executeCommands(this.id, TypeOperations.tab(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
editor.executeCommands(this.id, TypeOperations.tab(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
editor.pushUndoStop();
}
});
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends EditorCommand {
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
constructor() {
super({
id: 'deleteLeft',
@ -1580,9 +1593,8 @@ export namespace CoreEditingCommands {
});
}
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
const cursors = editor._getCursors();
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
if (shouldPushStackElementBefore) {
editor.pushUndoStop();
}
@ -1591,7 +1603,7 @@ export namespace CoreEditingCommands {
}
});
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends EditorCommand {
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
constructor() {
super({
id: 'deleteRight',
@ -1605,9 +1617,8 @@ export namespace CoreEditingCommands {
});
}
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
const cursors = editor._getCursors();
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
if (shouldPushStackElementBefore) {
editor.pushUndoStop();
}
@ -1618,10 +1629,6 @@ export namespace CoreEditingCommands {
}
function findFocusedEditor(accessor: ServicesAccessor): ICodeEditor {
return accessor.get(ICodeEditorService).getFocusedCodeEditor();
}
function registerCommand(command: Command) {
command.register();
}
@ -1645,10 +1652,10 @@ class EditorOrNativeTextInputCommand extends Command {
public runCommand(accessor: ServicesAccessor, args: any): void {
let focusedEditor = findFocusedEditor(accessor);
let focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
// Only if editor text focus (i.e. not if editor has widget focus).
if (focusedEditor && focusedEditor.hasTextFocus()) {
return this._runEditorHandler(focusedEditor, args);
return this._runEditorHandler(accessor, focusedEditor, args);
}
// Ignore this action when user is focused on an element that allows for entering text
@ -1662,18 +1669,18 @@ class EditorOrNativeTextInputCommand extends Command {
let activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
if (activeEditor) {
activeEditor.focus();
return this._runEditorHandler(activeEditor, args);
return this._runEditorHandler(accessor, activeEditor, args);
}
}
private _runEditorHandler(editor: ICodeEditor, args: any): void {
private _runEditorHandler(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
let HANDLER = this._editorHandler;
if (typeof HANDLER === 'string') {
editor.trigger('keyboard', HANDLER, args);
} else {
args = args || {};
args.source = 'keyboard';
HANDLER.runEditorCommand(null, editor, args);
HANDLER.runEditorCommand(accessor, editor, args);
}
}
}
@ -1694,7 +1701,7 @@ class EditorHandlerCommand extends Command {
}
public runCommand(accessor: ServicesAccessor, args: any): void {
const editor = findFocusedEditor(accessor);
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
if (!editor) {
return;
}

View file

@ -25,7 +25,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController';
/**
* Merges mouse events when mouse move events are throttled
*/
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory) {
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory | null) {
return function (lastEvent: EditorMouseEvent, currentEvent: EditorMouseEvent): EditorMouseEvent {
let targetIsWidget = false;
if (mouseTargetFactory) {
@ -55,9 +55,9 @@ export interface IPointerHandlerHelper {
/**
* Decode a position from a rendered dom node
*/
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position;
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null;
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange;
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null;
getLineWidth(lineNumber: number): number;
}
@ -113,7 +113,7 @@ export class MouseHandler extends ViewEventHandler {
return;
}
let e = new StandardMouseWheelEvent(browserEvent);
if (e.browserEvent.ctrlKey || e.browserEvent.metaKey) {
if (e.browserEvent!.ctrlKey || e.browserEvent!.metaKey) {
let zoomLevel: number = EditorZoom.getZoomLevel();
let delta = e.deltaY > 0 ? 1 : -1;
EditorZoom.setZoomLevel(zoomLevel + delta);
@ -148,7 +148,7 @@ export class MouseHandler extends ViewEventHandler {
}
// --- end event handlers
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
let clientPos = new ClientCoordinates(clientX, clientY);
let pos = clientPos.toPageCoordinates();
let editorPos = createEditorPagePosition(this.viewHelper.viewDomNode);
@ -276,7 +276,7 @@ class MouseDownOperation extends Disposable {
private _currentSelection: Selection;
private _isActive: boolean;
private _lastMouseEvent: EditorMouseEvent;
private _lastMouseEvent: EditorMouseEvent | null;
constructor(
context: ViewContext,
@ -336,7 +336,7 @@ class MouseDownOperation extends Disposable {
this._mouseState.setStartButtons(e);
this._mouseState.setModifiers(e);
let position = this._findMousePosition(e, true);
if (!position) {
if (!position || !position.position) {
// Ignoring because position is unknown
return;
}
@ -353,7 +353,7 @@ class MouseDownOperation extends Disposable {
&& !this._isActive // the mouse is not down yet
&& !this._currentSelection.isEmpty() // we don't drag single cursor
&& (position.type === editorBrowser.MouseTargetType.CONTENT_TEXT) // single click on text
&& this._currentSelection.containsPosition(position.position) // single click on a selection
&& position.position && this._currentSelection.containsPosition(position.position) // single click on a selection
) {
this._mouseState.isDragAndDrop = true;
this._isActive = true;
@ -362,11 +362,11 @@ class MouseDownOperation extends Disposable {
createMouseMoveEventMerger(null),
(e) => this._onMouseDownThenMove(e),
() => {
let position = this._findMousePosition(this._lastMouseEvent, true);
let position = this._findMousePosition(this._lastMouseEvent!, true);
this._viewController.emitMouseDrop({
event: this._lastMouseEvent,
target: position ? this._createMouseTarget(this._lastMouseEvent, true) : null // Ignoring because position is unknown, e.g., Content View Zone
event: this._lastMouseEvent!,
target: (position ? this._createMouseTarget(this._lastMouseEvent!, true) : null) // Ignoring because position is unknown, e.g., Content View Zone
});
this._stop();
@ -399,6 +399,9 @@ class MouseDownOperation extends Disposable {
return;
}
this._onScrollTimeout.setIfNotSet(() => {
if (!this._lastMouseEvent) {
return;
}
let position = this._findMousePosition(this._lastMouseEvent, false);
if (!position) {
// Ignoring because position is unknown
@ -416,7 +419,7 @@ class MouseDownOperation extends Disposable {
this._currentSelection = e.selections[0];
}
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget {
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget | null {
const editorContent = e.editorPos;
const model = this._context.model;
const viewLayout = this._context.viewLayout;
@ -464,7 +467,7 @@ class MouseDownOperation extends Disposable {
return null;
}
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget {
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget | null {
let positionOutsideEditor = this._getPositionOutsideEditor(e);
if (positionOutsideEditor) {
return positionOutsideEditor;
@ -486,7 +489,7 @@ class MouseDownOperation extends Disposable {
return t;
}
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position {
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position | null {
// Force position on view zones to go above or below depending on where selection started from
let selectionStart = new Position(this._currentSelection.selectionStartLineNumber, this._currentSelection.selectionStartColumn);
let positionBefore = viewZoneData.positionBefore;
@ -503,6 +506,9 @@ class MouseDownOperation extends Disposable {
}
private _dispatchMouse(position: MouseTarget, inSelectionMode: boolean): void {
if (!position.position) {
return;
}
this._viewController.dispatchMouse({
position: position.position,
mouseColumn: position.mouseColumn,
@ -546,7 +552,7 @@ class MouseDownState {
private _startedOnLineNumbers: boolean;
public get startedOnLineNumbers(): boolean { return this._startedOnLineNumbers; }
private _lastMouseDownPosition: Position;
private _lastMouseDownPosition: Position | null;
private _lastMouseDownPositionEqualCount: number;
private _lastMouseDownCount: number;
private _lastSetMouseDownCountTime: number;

View file

@ -19,8 +19,8 @@ import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
export interface IViewZoneData {
viewZoneId: number;
positionBefore: Position;
positionAfter: Position;
positionBefore: Position | null;
positionAfter: Position | null;
position: Position;
afterLineNumber: number;
}
@ -84,20 +84,20 @@ declare var IETextRange: {
};
interface IHitTestResult {
position: Position;
hitTarget: Element;
position: Position | null;
hitTarget: Element | null;
}
export class MouseTarget implements IMouseTarget {
public readonly element: Element;
public readonly element: Element | null;
public readonly type: MouseTargetType;
public readonly mouseColumn: number;
public readonly position: Position;
public readonly range: EditorRange;
public readonly position: Position | null;
public readonly range: EditorRange | null;
public readonly detail: any;
constructor(element: Element, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
this.element = element;
this.type = type;
this.mouseColumn = mouseColumn;
@ -247,11 +247,11 @@ export class HitTestContext {
this._viewHelper = viewHelper;
}
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData | null {
return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset);
}
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData {
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData | null {
// The target is either a view zone or the empty space after the last view-line
let viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
@ -259,7 +259,7 @@ export class HitTestContext {
let viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
lineCount = context.model.getLineCount(),
positionBefore: Position | null = null,
position: Position,
position: Position | null,
positionAfter: Position | null = null;
if (viewZoneWhitespace.afterLineNumber !== lineCount) {
@ -286,7 +286,7 @@ export class HitTestContext {
afterLineNumber: viewZoneWhitespace.afterLineNumber,
positionBefore: positionBefore,
positionAfter: positionAfter,
position: position
position: position!
};
}
return null;
@ -323,11 +323,11 @@ export class HitTestContext {
return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);
}
public findAttribute(element: Element, attr: string): string {
public findAttribute(element: Element, attr: string): string | null {
return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode);
}
private static _findAttribute(element: Element, attr: string, stopAt: Element): string {
private static _findAttribute(element: Element, attr: string, stopAt: Element): string | null {
while (element && element !== document.body) {
if (element.hasAttribute && element.hasAttribute(attr)) {
return element.getAttribute(attr);
@ -344,11 +344,11 @@ export class HitTestContext {
return this._viewHelper.getLineWidth(lineNumber);
}
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange {
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null {
return this._viewHelper.visibleRangeForPosition2(lineNumber, column);
}
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
return this._viewHelper.getPositionFromDOMInfo(spanNode, offset);
}
@ -386,10 +386,10 @@ abstract class BareHitTestRequest {
class HitTestRequest extends BareHitTestRequest {
private readonly _ctx: HitTestContext;
public readonly target: Element;
public readonly target: Element | null;
public readonly targetPath: Uint8Array;
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element) {
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element | null) {
super(ctx, editorPos, pos);
this._ctx = ctx;
@ -410,11 +410,15 @@ class HitTestRequest extends BareHitTestRequest {
return new MouseTarget(this.target, type, this.mouseColumn, position, range, detail);
}
public withTarget(target: Element): HitTestRequest {
public withTarget(target: Element | null): HitTestRequest {
return new HitTestRequest(this._ctx, this.editorPos, this.pos, target);
}
}
interface ResolvedHitTestRequest extends HitTestRequest {
readonly target: Element;
}
const EMPTY_CONTENT_AFTER_LINES: IEmptyContentData = { isAfterLines: true };
function createEmptyContentDataInLines(horizontalDistanceToText: number): IEmptyContentData {
@ -451,7 +455,7 @@ export class MouseTargetFactory {
return false;
}
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement): IMouseTarget {
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
const ctx = new HitTestContext(this._context, this._viewHelper, lastViewCursorsRenderData);
const request = new HitTestRequest(ctx, editorPos, pos, target);
try {
@ -484,23 +488,26 @@ export class MouseTargetFactory {
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
}
// we know for a fact that request.target is not null
const resolvedRequest = <ResolvedHitTestRequest>request;
let result: MouseTarget | null = null;
result = result || MouseTargetFactory._hitTestContentWidget(ctx, request);
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, request);
result = result || MouseTargetFactory._hitTestMinimap(ctx, request);
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, request);
result = result || MouseTargetFactory._hitTestViewZone(ctx, request);
result = result || MouseTargetFactory._hitTestMargin(ctx, request);
result = result || MouseTargetFactory._hitTestViewCursor(ctx, request);
result = result || MouseTargetFactory._hitTestTextArea(ctx, request);
result = result || MouseTargetFactory._hitTestViewLines(ctx, request, domHitTestExecuted);
result = result || MouseTargetFactory._hitTestScrollbar(ctx, request);
result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest);
result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted);
result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest);
return (result || request.fulfill(MouseTargetType.UNKNOWN));
}
private static _hitTestContentWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestContentWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
// Is it a content widget?
if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) {
let widgetId = ctx.findAttribute(request.target, 'widgetId');
@ -513,7 +520,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestOverlayWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestOverlayWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
// Is it an overlay widget?
if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) {
let widgetId = ctx.findAttribute(request.target, 'widgetId');
@ -526,7 +533,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestViewCursor(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestViewCursor(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
if (request.target) {
// Check if we've hit a painted cursor
@ -577,7 +584,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestViewZone(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestViewZone(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
let viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset);
if (viewZoneData) {
let mouseTargetType = (request.isInContentArea ? MouseTargetType.CONTENT_VIEW_ZONE : MouseTargetType.GUTTER_VIEW_ZONE);
@ -587,7 +594,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestTextArea(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestTextArea(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
// Is it the textarea?
if (ElementPath.isTextArea(request.targetPath)) {
return request.fulfill(MouseTargetType.TEXTAREA);
@ -595,7 +602,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestMargin(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestMargin(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
if (request.isInMarginArea) {
let res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset);
let pos = res.range.getStartPosition();
@ -628,7 +635,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestViewLines(ctx: HitTestContext, request: HitTestRequest, domHitTestExecuted: boolean): MouseTarget {
private static _hitTestViewLines(ctx: HitTestContext, request: ResolvedHitTestRequest, domHitTestExecuted: boolean): MouseTarget | null {
if (!ElementPath.isChildOfViewLines(request.targetPath)) {
return null;
}
@ -666,7 +673,7 @@ export class MouseTargetFactory {
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
}
private static _hitTestMinimap(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestMinimap(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
if (ElementPath.isChildOfMinimap(request.targetPath)) {
const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);
const maxColumn = ctx.model.getLineMaxColumn(possibleLineNumber);
@ -675,7 +682,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
if (request.target && request.target.nodeType === 1) {
let className = request.target.className;
@ -689,7 +696,7 @@ export class MouseTargetFactory {
return null;
}
private static _hitTestScrollbar(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
private static _hitTestScrollbar(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
// Is it the overview ruler?
// Is it a child of the scrollable element?
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
@ -817,7 +824,7 @@ export class MouseTargetFactory {
// Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span
let startContainer = range.startContainer;
let hitTarget: HTMLElement;
let hitTarget: HTMLElement | null = null;
if (startContainer.nodeType === startContainer.TEXT_NODE) {
// startContainer is expected to be the token text
@ -842,7 +849,7 @@ export class MouseTargetFactory {
let parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? (<HTMLElement>parent2).className : null;
if (parent2ClassName === ViewLine.CLASS_NAME) {
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length);
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent!.length);
return {
position: p,
hitTarget: null
@ -919,7 +926,7 @@ export class MouseTargetFactory {
if (parent2ClassName === ViewLine.CLASS_NAME) {
let rangeToContainEntireSpan = textRange.duplicate();
rangeToContainEntireSpan.moveToElementText(parentElement);
rangeToContainEntireSpan.moveToElementText(parentElement!);
rangeToContainEntireSpan.setEndPoint('EndToStart', textRange);
resultPosition = ctx.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);

View file

@ -234,7 +234,7 @@ export class PointerHandler implements IDisposable {
}
}
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget {
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null {
return this.handler.getTargetAtClientPoint(clientX, clientY);
}

View file

@ -29,7 +29,7 @@ import { EndOfLinePreference } from 'vs/editor/common/model';
import { getMapForWordSeparators, WordCharacterClass } from 'vs/editor/common/controller/wordCharacterClassifier';
export interface ITextAreaHandlerHelper {
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange;
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange | null;
}
class VisibleTextAreaData {
@ -55,7 +55,7 @@ const canUseZeroSizeTextarea = (browser.isEdgeOrIE || browser.isFirefox);
interface LocalClipboardMetadata {
lastCopiedValue: string;
isFromEmptySelection: boolean;
multicursorText: string[];
multicursorText: string[] | null;
}
/**
@ -66,17 +66,17 @@ interface LocalClipboardMetadata {
class LocalClipboardMetadataManager {
public static INSTANCE = new LocalClipboardMetadataManager();
private _lastState: LocalClipboardMetadata;
private _lastState: LocalClipboardMetadata | null;
constructor() {
this._lastState = null;
}
public set(state: LocalClipboardMetadata): void {
public set(state: LocalClipboardMetadata | null): void {
this._lastState = state;
}
public get(pastedText: string): LocalClipboardMetadata {
public get(pastedText: string): LocalClipboardMetadata | null {
if (this._lastState && this._lastState.lastCopiedValue === pastedText) {
// match!
return this._lastState;
@ -104,7 +104,7 @@ export class TextAreaHandler extends ViewPart {
/**
* Defined only when the text area is visible (composition case).
*/
private _visibleTextArea: VisibleTextAreaData;
private _visibleTextArea: VisibleTextAreaData | null;
private _selections: Selection[];
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
@ -191,7 +191,7 @@ export class TextAreaHandler extends ViewPart {
return whatToCopy;
},
getHTMLToCopy: (): string => {
getHTMLToCopy: (): string | null => {
if (!this._copyWithSyntaxHighlighting && !CopyOptions.forceCopyWithSyntaxHighlighting) {
return null;
}
@ -307,10 +307,10 @@ export class TextAreaHandler extends ViewPart {
if (browser.isEdgeOrIE) {
// Due to isEdgeOrIE (where the textarea was not cleared initially)
// we cannot assume the text consists only of the composited text
this._visibleTextArea = this._visibleTextArea.setWidth(0);
this._visibleTextArea = this._visibleTextArea!.setWidth(0);
} else {
// adjust width by its size
this._visibleTextArea = this._visibleTextArea.setWidth(measureText(e.data, this._fontInfo));
this._visibleTextArea = this._visibleTextArea!.setWidth(measureText(e.data, this._fontInfo));
}
this._render();
}));
@ -564,7 +564,7 @@ export class TextAreaHandler extends ViewPart {
function measureText(text: string, fontInfo: BareFontInfo): number {
// adjust width by its size
const canvasElem = <HTMLCanvasElement>document.createElement('canvas');
const context = canvasElem.getContext('2d');
const context = canvasElem.getContext('2d')!;
context.font = createFontString(fontInfo);
const metrics = context.measureText(text);

View file

@ -36,7 +36,7 @@ export interface IPasteData {
export interface ITextAreaInputHost {
getPlainTextToCopy(): string;
getHTMLToCopy(): string;
getHTMLToCopy(): string | null;
getScreenReaderContent(currentState: TextAreaState): TextAreaState;
deduceModelPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
}
@ -400,10 +400,10 @@ export class TextAreaInput extends Disposable {
}
const _newSelectionStartPosition = this._textAreaState.deduceEditorPosition(newSelectionStart);
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0], _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0]!, _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
const _newSelectionEndPosition = this._textAreaState.deduceEditorPosition(newSelectionEnd);
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0], _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0]!, _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
const newSelection = new Selection(
newSelectionStartPosition.lineNumber, newSelectionStartPosition.column,
@ -513,7 +513,7 @@ class ClipboardEventUtils {
throw new Error('ClipboardEventUtils.getTextData: Cannot use text data!');
}
public static setTextData(e: ClipboardEvent, text: string, richText: string): void {
public static setTextData(e: ClipboardEvent, text: string, richText: string | null): void {
if (e.clipboardData) {
e.clipboardData.setData('text/plain', text);
if (richText !== null) {

View file

@ -19,9 +19,9 @@ export class EditorState {
private readonly flags: number;
private readonly position: Position;
private readonly selection: Range;
private readonly modelVersionId: string;
private readonly position: Position | null;
private readonly selection: Range | null;
private readonly modelVersionId: string | null;
private readonly scrollLeft: number;
private readonly scrollTop: number;
@ -88,7 +88,7 @@ export class StableEditorScrollState {
}
constructor(
private readonly _visiblePosition: Position,
private readonly _visiblePosition: Position | null,
private readonly _visiblePositionScrollDelta: number
) {
}

View file

@ -15,7 +15,7 @@ import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelDecorationsChangedEvent } from 'vs/editor/common/model/textModelEvents';
import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ICursors, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
import { ICursors } from 'vs/editor/common/controller/cursorCommon';
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
import { ITextModel, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration } from 'vs/editor/common/model';
@ -64,7 +64,7 @@ export interface IViewZone {
/**
* An optional dom node for the view zone that will be placed in the margin area.
*/
marginDomNode?: HTMLElement;
marginDomNode?: HTMLElement | null;
/**
* Callback which gives the relative top of the view zone as it appears (taking scrolling into account).
*/
@ -121,12 +121,12 @@ export interface IContentWidgetPosition {
* Desired position for the content widget.
* `preference` will also affect the placement.
*/
position: IPosition;
position: IPosition | null;
/**
* Optionally, a range can be provided to further
* define the position of the content widget.
*/
range?: IRange;
range?: IRange | null;
/**
* Placement preference for position, in order of preference.
*/
@ -154,7 +154,7 @@ export interface IContentWidget {
* Get the placement of the content widget.
* If null is returned, the content widget will be placed off screen.
*/
getPosition(): IContentWidgetPosition;
getPosition(): IContentWidgetPosition | null;
}
/**
@ -201,7 +201,7 @@ export interface IOverlayWidget {
* Get the placement of the overlay widget.
* If null is returned, the overlay widget is responsible to place itself.
*/
getPosition(): IOverlayWidgetPosition;
getPosition(): IOverlayWidgetPosition | null;
}
/**
@ -273,7 +273,7 @@ export interface IMouseTarget {
/**
* The target element
*/
readonly element: Element;
readonly element: Element | null;
/**
* The target type
*/
@ -281,7 +281,7 @@ export interface IMouseTarget {
/**
* The 'approximate' editor position
*/
readonly position: Position;
readonly position: Position | null;
/**
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
*/
@ -289,7 +289,7 @@ export interface IMouseTarget {
/**
* The 'approximate' editor range
*/
readonly range: Range;
readonly range: Range | null;
/**
* Some extra detail.
*/
@ -300,7 +300,7 @@ export interface IMouseTarget {
*/
export interface IEditorMouseEvent {
readonly event: IMouseEvent;
readonly target: IMouseTarget;
readonly target: IMouseTarget | null;
}
/**
@ -481,7 +481,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
/**
* Saves current view state of the editor in a serializable object.
*/
saveViewState(): editorCommon.ICodeEditorViewState;
saveViewState(): editorCommon.ICodeEditorViewState | null;
/**
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
@ -509,7 +509,17 @@ export interface ICodeEditor extends editorCommon.IEditor {
/**
* Type the getModel() of IEditor.
*/
getModel(): ITextModel;
getModel(): ITextModel | null;
/**
* Sets the current model attached to this editor.
* If the previous model was created by the editor via the value key in the options
* literal object, it will be destroyed. Otherwise, if the previous model was set
* via setModel, or the model key in the options literal object, the previous model
* will not be destroyed.
* It is safe to call setModel(null) to simply detach the current model from the editor.
*/
setModel(model: ITextModel | null): void;
/**
* Returns the current editor's configuration
@ -599,22 +609,17 @@ export interface ICodeEditor extends editorCommon.IEditor {
* @param source The source of the call.
* @param command The commands to execute
*/
executeCommands(source: string, commands: editorCommon.ICommand[]): void;
executeCommands(source: string, commands: (editorCommon.ICommand | null)[]): void;
/**
* @internal
*/
_getCursors(): ICursors;
/**
* @internal
*/
_getCursorConfiguration(): CursorConfiguration;
_getCursors(): ICursors | null;
/**
* Get all the decorations on a line (filtering out decorations from other editors).
*/
getLineDecorations(lineNumber: number): IModelDecoration[];
getLineDecorations(lineNumber: number): IModelDecoration[] | null;
/**
* All decorations added through this call will get the ownerId of this editor.
@ -673,12 +678,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
/**
* @internal
*/
getTelemetryData(): { [key: string]: any; };
getTelemetryData(): { [key: string]: any; } | null;
/**
* Returns the editor's dom node
*/
getDomNode(): HTMLElement;
getDomNode(): HTMLElement | null;
/**
* Add a content widget. Widgets must have unique ids, otherwise they will be overwritten.
@ -725,6 +730,79 @@ export interface ICodeEditor extends editorCommon.IEditor {
*/
render(): void;
/**
* Get the hit test target at coordinates `clientX` and `clientY`.
* The coordinates are relative to the top-left of the viewport.
*
* @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
*/
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null;
/**
* Get the visible position for `position`.
* The result position takes scrolling into account and is relative to the top left corner of the editor.
* Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor.
* Explanation 2: the results of this method will not change if the container of the editor gets repositioned.
* Warning: the results of this method are innacurate for positions that are outside the current editor viewport.
*/
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; } | null;
/**
* Apply the same font settings as the editor to `target`.
*/
applyFontInfo(target: HTMLElement): void;
/**
* Check if the current instance has a model attached.
* @internal
*/
hasModel(): this is IActiveCodeEditor;
}
/**
* @internal
*/
export interface IActiveCodeEditor extends ICodeEditor {
/**
* Returns the primary position of the cursor.
*/
getPosition(): Position;
/**
* Returns the primary selection of the editor.
*/
getSelection(): Selection;
/**
* Returns all the selections of the editor.
*/
getSelections(): Selection[];
/**
* Saves current view state of the editor in a serializable object.
*/
saveViewState(): editorCommon.ICodeEditorViewState;
/**
* Type the getModel() of IEditor.
*/
getModel(): ITextModel;
/**
* @internal
*/
_getCursors(): ICursors;
/**
* Get all the decorations on a line (filtering out decorations from other editors).
*/
getLineDecorations(lineNumber: number): IModelDecoration[];
/**
* Returns the editor's dom node
*/
getDomNode(): HTMLElement;
/**
* Get the hit test target at coordinates `clientX` and `clientY`.
* The coordinates are relative to the top-left of the viewport.
@ -741,11 +819,6 @@ export interface ICodeEditor extends editorCommon.IEditor {
* Warning: the results of this method are innacurate for positions that are outside the current editor viewport.
*/
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; };
/**
* Apply the same font settings as the editor to `target`.
*/
applyFontInfo(target: HTMLElement): void;
}
/**
@ -790,7 +863,7 @@ export interface IDiffEditor extends editorCommon.IEditor {
/**
* Saves current view state of the editor in a serializable object.
*/
saveViewState(): editorCommon.IDiffEditorViewState;
saveViewState(): editorCommon.IDiffEditorViewState | null;
/**
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
@ -800,7 +873,17 @@ export interface IDiffEditor extends editorCommon.IEditor {
/**
* Type the getModel() of IEditor.
*/
getModel(): editorCommon.IDiffEditorModel;
getModel(): editorCommon.IDiffEditorModel | null;
/**
* Sets the current model attached to this editor.
* If the previous model was created by the editor via the value key in the options
* literal object, it will be destroyed. Otherwise, if the previous model was set
* via setModel, or the model key in the options literal object, the previous model
* will not be destroyed.
* It is safe to call setModel(null) to simply detach the current model from the editor.
*/
setModel(model: editorCommon.IDiffEditorModel | null): void;
/**
* Get the `original` editor.
@ -815,19 +898,19 @@ export interface IDiffEditor extends editorCommon.IEditor {
/**
* Get the computed diff information.
*/
getLineChanges(): editorCommon.ILineChange[];
getLineChanges(): editorCommon.ILineChange[] | null;
/**
* Get information based on computed diff about a line number from the original model.
* If the diff computation is not finished or the model is missing, will return null.
*/
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation;
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation | null;
/**
* Get information based on computed diff about a line number from the modified model.
* If the diff computation is not finished or the model is missing, will return null.
*/
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation;
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation | null;
}
/**
@ -855,7 +938,7 @@ export function isDiffEditor(thing: any): thing is IDiffEditor {
/**
*@internal
*/
export function getCodeEditor(thing: any): ICodeEditor {
export function getCodeEditor(thing: any): ICodeEditor | null {
if (isCodeEditor(thing)) {
return thing;
}

View file

@ -135,7 +135,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
private _editorViewDomNode: HTMLElement;
private _globalMouseMoveMonitor: GlobalMouseMoveMonitor<EditorMouseEvent>;
private _keydownListener: IDisposable;
private _keydownListener: IDisposable | null;
constructor(editorViewDomNode: HTMLElement) {
super();
@ -162,7 +162,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
};
this._globalMouseMoveMonitor.startMonitoring(myMerger, mouseMoveCallback, () => {
this._keydownListener.dispose();
this._keydownListener!.dispose();
onStopCallback();
});
}

View file

@ -26,7 +26,7 @@ export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editor
//#region Command
export interface ICommandKeybindingsOptions extends IKeybindings {
kbExpr?: ContextKeyExpr;
kbExpr?: ContextKeyExpr | null;
weight: number;
}
export interface ICommandMenubarOptions {
@ -38,17 +38,17 @@ export interface ICommandMenubarOptions {
}
export interface ICommandOptions {
id: string;
precondition: ContextKeyExpr;
kbOpts?: ICommandKeybindingsOptions;
precondition: ContextKeyExpr | null;
kbOpts?: ICommandKeybindingsOptions | null;
description?: ICommandHandlerDescription;
menubarOpts?: ICommandMenubarOptions;
}
export abstract class Command {
public readonly id: string;
public readonly precondition: ContextKeyExpr;
private readonly _kbOpts: ICommandKeybindingsOptions;
private readonly _menubarOpts: ICommandMenubarOptions;
private readonly _description: ICommandHandlerDescription;
public readonly precondition: ContextKeyExpr | null;
private readonly _kbOpts: ICommandKeybindingsOptions | null | undefined;
private readonly _menubarOpts: ICommandMenubarOptions | null | undefined;
private readonly _description: ICommandHandlerDescription | null | undefined;
constructor(opts: ICommandOptions) {
this.id = opts.id;
@ -87,7 +87,7 @@ export abstract class Command {
id: this.id,
handler: (accessor, args) => this.runCommand(accessor, args),
weight: this._kbOpts.weight,
when: kbWhen,
when: kbWhen || null,
primary: this._kbOpts.primary,
secondary: this._kbOpts.secondary,
win: this._kbOpts.win,
@ -160,7 +160,7 @@ export abstract class EditorCommand extends Command {
return;
}
return this.runEditorCommand(editorAccessor, editor, args);
return this.runEditorCommand(editorAccessor, editor!, args);
});
}
@ -185,7 +185,7 @@ export abstract class EditorAction extends EditorCommand {
public label: string;
public alias: string;
private menuOpts: IEditorCommandMenuOptions;
private menuOpts: IEditorCommandMenuOptions | undefined;
constructor(opts: IActionOptions) {
super(opts);

View file

@ -70,7 +70,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
return Object.keys(this._diffEditors).map(id => this._diffEditors[id]);
}
getFocusedCodeEditor(): ICodeEditor {
getFocusedCodeEditor(): ICodeEditor | null {
let editorWithWidgetFocus: ICodeEditor | null = null;
let editors = this.listCodeEditors();
@ -92,7 +92,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
abstract removeDecorationType(key: string): void;
abstract resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions;
abstract resolveDecorationOptions(decorationTypeKey: string | undefined, writable: boolean): IModelDecorationOptions;
private _transientWatchers: { [uri: string]: ModelTransientSettingWatcher; } = {};
@ -125,8 +125,8 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
delete this._transientWatchers[w.uri];
}
abstract getActiveCodeEditor(): ICodeEditor;
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
abstract getActiveCodeEditor(): ICodeEditor | null;
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
}
export class ModelTransientSettingWatcher {

View file

@ -35,7 +35,7 @@ export interface ICodeEditorService {
/**
* Returns the current focused code editor (if the focus is in the editor or in an editor widget) or null.
*/
getFocusedCodeEditor(): ICodeEditor;
getFocusedCodeEditor(): ICodeEditor | null;
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
removeDecorationType(key: string): void;
@ -44,6 +44,6 @@ export interface ICodeEditorService {
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
getTransientModelProperty(model: ITextModel, key: string): any;
getActiveCodeEditor(): ICodeEditor;
openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
getActiveCodeEditor(): ICodeEditor | null;
openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
}

View file

@ -66,8 +66,8 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
return provider.getOptions(this, writable);
}
abstract getActiveCodeEditor(): ICodeEditor;
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
abstract getActiveCodeEditor(): ICodeEditor | null;
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
}
interface IModelDecorationOptionsProvider extends IDisposable {
@ -79,9 +79,9 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
public refCount: number;
private _parentTypeKey: string;
private _beforeContentRules: DecorationCSSRules;
private _afterContentRules: DecorationCSSRules;
private _parentTypeKey: string | undefined;
private _beforeContentRules: DecorationCSSRules | null;
private _afterContentRules: DecorationCSSRules | null;
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
this._parentTypeKey = providerArgs.parentTypeKey;
@ -127,15 +127,15 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
private _disposables: IDisposable[];
public refCount: number;
public className: string;
public className: string | undefined;
public inlineClassName: string;
public inlineClassNameAffectsLetterSpacing: boolean;
public beforeContentClassName: string;
public afterContentClassName: string;
public glyphMarginClassName: string;
public beforeContentClassName: string | undefined;
public afterContentClassName: string | undefined;
public glyphMarginClassName: string | undefined;
public isWholeLine: boolean;
public overviewRuler: IModelDecorationOverviewRulerOptions;
public stickiness: TrackedRangeStickiness;
public stickiness: TrackedRangeStickiness | undefined;
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
this.refCount = 0;
@ -250,7 +250,7 @@ class DecorationCSSRules {
private _hasContent: boolean;
private _hasLetterSpacing: boolean;
private _ruleType: ModelDecorationCSSRuleType;
private _themeListener: IDisposable;
private _themeListener: IDisposable | null;
private _providerArgs: ProviderArguments;
private _usesThemeColors: boolean;
@ -278,6 +278,8 @@ class DecorationCSSRules {
this._removeCSS();
this._buildCSS();
});
} else {
this._themeListener = null;
}
}
@ -361,7 +363,7 @@ class DecorationCSSRules {
/**
* Build the CSS for decorations styled via `className`.
*/
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions): string {
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions | undefined): string {
if (!opts) {
return '';
}
@ -375,7 +377,7 @@ class DecorationCSSRules {
/**
* Build the CSS for decorations styled via `inlineClassName`.
*/
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions): string {
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions | undefined): string {
if (!opts) {
return '';
}
@ -390,7 +392,7 @@ class DecorationCSSRules {
/**
* Build the CSS for decorations styled before or after content.
*/
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions): string {
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions | undefined): string {
if (!opts) {
return '';
}
@ -406,7 +408,7 @@ class DecorationCSSRules {
}
}
if (typeof opts.contentText === 'string') {
const truncated = opts.contentText.match(/^.*$/m)[0]; // only take first line
const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line
const escaped = truncated.replace(/['\\]/g, '\\$&');
cssTextArr.push(strings.format(_CSS_MAP.contentText, escaped));
@ -423,11 +425,11 @@ class DecorationCSSRules {
/**
* Build the CSS for decorations styled via `glpyhMarginClassName`.
*/
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions): string {
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions | undefined): string {
if (!opts) {
return '';
}
let cssTextArr = [];
let cssTextArr: string[] = [];
if (typeof opts.gutterIconPath !== 'undefined') {
if (typeof opts.gutterIconPath === 'string') {
@ -489,7 +491,7 @@ class CSSNameHelper {
return 'ced-' + key + '-' + type;
}
public static getSelector(key: string, parentKey: string, ruleType: ModelDecorationCSSRuleType): string {
public static getSelector(key: string, parentKey: string | undefined, ruleType: ModelDecorationCSSRuleType): string {
let selector = '.monaco-editor .' + this.getClassName(key, ruleType);
if (parentKey) {
selector = selector + '.' + this.getClassName(parentKey, ruleType);

View file

@ -29,15 +29,17 @@ export class OpenerService implements IOpenerService {
open(resource: URI, options?: { openToSide?: boolean }): Promise<any> {
/* __GDPR__
"openerService" : {
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
if (this._telemetryService) {
/* __GDPR__
"openerService" : {
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
}
const { scheme, path, query, fragment } = resource;
let promise: Thenable<any>;
let promise: Thenable<any> | undefined = undefined;
if (scheme === Schemas.http || scheme === Schemas.https || scheme === Schemas.mailto) {
// open http or default mail application
@ -59,7 +61,7 @@ export class OpenerService implements IOpenerService {
let selection: {
startLineNumber: number;
startColumn: number;
};
} | undefined = undefined;
const match = /^L?(\d+)(?:,(\d+))?/.exec(fragment);
if (match) {
// support file:///some/file.js#73,84

View file

@ -12,10 +12,6 @@ import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
import { CoreNavigationCommands, CoreEditorCommand } from 'vs/editor/browser/controller/coreCommands';
import { IConfiguration } from 'vs/editor/common/editorCommon';
export interface ExecCoreEditorCommandFunc {
(editorCommand: CoreEditorCommand, args: any): void;
}
export interface IMouseDispatchData {
position: Position;
/**
@ -36,7 +32,9 @@ export interface IMouseDispatchData {
}
export interface ICommandDelegate {
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void;
executeEditorCommand(editorCommand: CoreEditorCommand, args: any): void;
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void;
type(source: string, text: string): void;
replacePreviousChar(source: string, text: string, replaceCharCnt: number): void;
compositionStart(source: string): void;
@ -48,30 +46,27 @@ export class ViewController {
private readonly configuration: IConfiguration;
private readonly viewModel: IViewModel;
private readonly _execCoreEditorCommandFunc: ExecCoreEditorCommandFunc;
private readonly outgoingEvents: ViewOutgoingEvents;
private readonly commandDelegate: ICommandDelegate;
constructor(
configuration: IConfiguration,
viewModel: IViewModel,
execCommandFunc: ExecCoreEditorCommandFunc,
outgoingEvents: ViewOutgoingEvents,
commandDelegate: ICommandDelegate
) {
this.configuration = configuration;
this.viewModel = viewModel;
this._execCoreEditorCommandFunc = execCommandFunc;
this.outgoingEvents = outgoingEvents;
this.commandDelegate = commandDelegate;
}
private _execMouseCommand(editorCommand: CoreEditorCommand, args: any): void {
args.source = 'mouse';
this._execCoreEditorCommandFunc(editorCommand, args);
this.commandDelegate.executeEditorCommand(editorCommand, args);
}
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void {
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void {
this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText);
}
@ -96,7 +91,7 @@ export class ViewController {
}
public setSelection(source: string, modelSelection: Selection): void {
this._execCoreEditorCommandFunc(CoreNavigationCommands.SetSelection, {
this.commandDelegate.executeEditorCommand(CoreNavigationCommands.SetSelection, {
source: source,
selection: modelSelection
});

View file

@ -13,7 +13,7 @@ import { IConfiguration } from 'vs/editor/common/editorCommon';
import { TextAreaHandler, ITextAreaHandlerHelper } from 'vs/editor/browser/controller/textAreaHandler';
import { PointerHandler } from 'vs/editor/browser/controller/pointerHandler';
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import { ViewController, ExecCoreEditorCommandFunc, ICommandDelegate } from 'vs/editor/browser/view/viewController';
import { ViewController, ICommandDelegate } from 'vs/editor/browser/view/viewController';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import { ContentViewOverlays, MarginViewOverlays } from 'vs/editor/browser/view/viewOverlays';
import { ViewContentWidgets } from 'vs/editor/browser/viewParts/contentWidgets/contentWidgets';
@ -51,14 +51,16 @@ import { IMouseEvent } from 'vs/base/browser/mouseEvent';
export interface IContentWidgetData {
widget: editorBrowser.IContentWidget;
position: editorBrowser.IContentWidgetPosition;
position: editorBrowser.IContentWidgetPosition | null;
}
export interface IOverlayWidgetData {
widget: editorBrowser.IOverlayWidget;
position: editorBrowser.IOverlayWidgetPosition;
position: editorBrowser.IOverlayWidgetPosition | null;
}
const invalidFunc = () => { throw new Error(`Invalid change accessor`); };
export class View extends ViewEventHandler {
private eventDispatcher: ViewEventDispatcher;
@ -88,7 +90,7 @@ export class View extends ViewEventHandler {
private overflowGuardContainer: FastDomNode<HTMLElement>;
// Actual mutable state
private _renderAnimationFrame: IDisposable;
private _renderAnimationFrame: IDisposable | null;
constructor(
commandDelegate: ICommandDelegate,
@ -96,14 +98,14 @@ export class View extends ViewEventHandler {
themeService: IThemeService,
model: IViewModel,
cursor: Cursor,
execCoreEditorCommandFunc: ExecCoreEditorCommandFunc
outgoingEvents: ViewOutgoingEvents
) {
super();
this._cursor = cursor;
this._renderAnimationFrame = null;
this.outgoingEvents = new ViewOutgoingEvents(model);
this.outgoingEvents = outgoingEvents;
let viewController = new ViewController(configuration, model, execCoreEditorCommandFunc, this.outgoingEvents, commandDelegate);
let viewController = new ViewController(configuration, model, this.outgoingEvents, commandDelegate);
// The event dispatcher will always go through _renderOnce before dispatching any events
this.eventDispatcher = new ViewEventDispatcher((callback: () => void) => this._renderOnce(callback));
@ -462,14 +464,10 @@ export class View extends ViewEventHandler {
return visibleRange.left;
}
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
return this.pointerHandler.getTargetAtClientPoint(clientX, clientY);
}
public getInternalEventBus(): ViewOutgoingEvents {
return this.outgoingEvents;
}
public createOverviewRuler(cssClassName: string): OverviewRuler {
return new OverviewRuler(this._context, cssClassName);
}
@ -500,8 +498,9 @@ export class View extends ViewEventHandler {
safeInvoke1Arg(callback, changeAccessor);
// Invalidate changeAccessor
changeAccessor.addZone = null;
changeAccessor.removeZone = null;
changeAccessor.addZone = invalidFunc;
changeAccessor.removeZone = invalidFunc;
changeAccessor.layoutZone = invalidFunc;
if (zonesHaveChanged) {
this._context.viewLayout.onHeightMaybeChanged();

View file

@ -12,7 +12,7 @@ import { createStringBuilder, IStringBuilder } from 'vs/editor/common/core/strin
* Represents a visible line
*/
export interface IVisibleLine extends ILine {
getDomNode(): HTMLElement;
getDomNode(): HTMLElement | null;
setDomNode(domNode: HTMLElement): void;
/**
@ -87,7 +87,7 @@ export class RenderedLinesCollection<T extends ILine> {
/**
* @returns Lines that were removed from this collection
*/
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] {
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] | null {
if (this.getCount() === 0) {
// no lines
return null;
@ -167,7 +167,7 @@ export class RenderedLinesCollection<T extends ILine> {
return someoneNotified;
}
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] {
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] | null {
if (this.getCount() === 0) {
// no lines
return null;
@ -527,8 +527,8 @@ class ViewLayerRenderer<T extends IVisibleLine> {
let line = ctx.lines[i];
if (wasInvalid[i]) {
let source = <HTMLElement>hugeDomNode.firstChild;
let lineDomNode = line.getDomNode();
lineDomNode.parentNode.replaceChild(source, lineDomNode);
let lineDomNode = line.getDomNode()!;
lineDomNode.parentNode!.replaceChild(source, lineDomNode);
line.setDomNode(source);
}
}

View file

@ -143,14 +143,14 @@ export class ViewOutgoingEvents extends Disposable {
class ExternalMouseTarget implements IMouseTarget {
public readonly element: Element;
public readonly element: Element | null;
public readonly type: MouseTargetType;
public readonly mouseColumn: number;
public readonly position: Position;
public readonly range: Range;
public readonly position: Position | null;
public readonly range: Range | null;
public readonly detail: any;
constructor(element: Element, type: MouseTargetType, mouseColumn: number, position: Position, range: Range, detail: any) {
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number, position: Position | null, range: Range | null, detail: any) {
this.element = element;
this.type = type;
this.mouseColumn = mouseColumn;

View file

@ -56,7 +56,7 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
let dynamicOverlay = this._dynamicOverlays[i];
dynamicOverlay.dispose();
}
this._dynamicOverlays = null;
this._dynamicOverlays = [];
}
public getDomNode(): FastDomNode<HTMLElement> {
@ -123,8 +123,6 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
dynamicOverlay.prepareRender(ctx);
dynamicOverlay.onDidRender();
}
return null;
}
public render(ctx: RestrictedRenderingContext): void {
@ -143,8 +141,8 @@ export class ViewOverlayLine implements IVisibleLine {
private _configuration: IConfiguration;
private _dynamicOverlays: DynamicViewOverlay[];
private _domNode: FastDomNode<HTMLElement>;
private _renderedContent: string;
private _domNode: FastDomNode<HTMLElement> | null;
private _renderedContent: string | null;
private _lineHeight: number;
constructor(configuration: IConfiguration, dynamicOverlays: DynamicViewOverlay[]) {
@ -156,7 +154,7 @@ export class ViewOverlayLine implements IVisibleLine {
this._renderedContent = null;
}
public getDomNode(): HTMLElement {
public getDomNode(): HTMLElement | null {
if (!this._domNode) {
return null;
}

View file

@ -20,7 +20,6 @@ export abstract class ViewPart extends ViewEventHandler {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
super.dispose();
}
@ -58,7 +57,7 @@ export class PartFingerprints {
return parseInt(r, 10);
}
public static collect(child: Element, stopAt: Element): Uint8Array {
public static collect(child: Element | null, stopAt: Element): Uint8Array {
let result: PartFingerprint[] = [], resultLen = 0;
while (child && child !== document.body) {

View file

@ -53,8 +53,7 @@ export class ViewContentWidgets extends ViewPart {
public dispose(): void {
super.dispose();
this._widgets = null;
this.domNode = null;
this._widgets = {};
}
// --- begin event handlers
@ -113,7 +112,7 @@ export class ViewContentWidgets extends ViewPart {
this.setShouldRender();
}
public setWidgetPosition(widget: IContentWidget, position: IPosition, range: IRange, preference: ContentWidgetPositionPreference[]): void {
public setWidgetPosition(widget: IContentWidget, position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
const myWidget = this._widgets[widget.getId()];
myWidget.setPosition(position, range, preference);
@ -127,7 +126,7 @@ export class ViewContentWidgets extends ViewPart {
delete this._widgets[widgetId];
const domNode = myWidget.domNode.domNode;
domNode.parentNode.removeChild(domNode);
domNode.parentNode!.removeChild(domNode);
domNode.removeAttribute('monaco-visible-content-widget');
this.setShouldRender();
@ -191,17 +190,17 @@ class Widget {
private _contentLeft: number;
private _lineHeight: number;
private _position: IPosition;
private _viewPosition: Position;
private _range: IRange;
private _viewRange: Range;
private _preference: ContentWidgetPositionPreference[];
private _position: IPosition | null;
private _viewPosition: Position | null;
private _range: IRange | null;
private _viewRange: Range | null;
private _preference: ContentWidgetPositionPreference[] | null;
private _cachedDomNodeClientWidth: number;
private _cachedDomNodeClientHeight: number;
private _maxWidth: number;
private _isVisible: boolean;
private _renderData: Coordinate;
private _renderData: Coordinate | null;
constructor(context: ViewContext, viewDomNode: FastDomNode<HTMLElement>, actual: IContentWidget) {
this._context = context;
@ -219,7 +218,7 @@ class Widget {
this._lineHeight = this._context.configuration.editor.lineHeight;
this._setPosition(null, null);
this._preference = null;
this._preference = [];
this._cachedDomNodeClientWidth = -1;
this._cachedDomNodeClientHeight = -1;
this._maxWidth = this._getMaxWidth();
@ -247,9 +246,9 @@ class Widget {
this._setPosition(this._position, this._range);
}
private _setPosition(position: IPosition, range: IRange): void {
this._position = position;
this._range = range;
private _setPosition(position: IPosition | null | undefined, range: IRange | null | undefined): void {
this._position = position || null;
this._range = range || null;
this._viewPosition = null;
this._viewRange = null;
@ -270,14 +269,14 @@ class Widget {
private _getMaxWidth(): number {
return (
this.allowEditorOverflow
? window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
? window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth
: this._contentWidth
);
}
public setPosition(position: IPosition, range: IRange, preference: ContentWidgetPositionPreference[]): void {
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
this._setPosition(position, range);
this._preference = preference;
this._preference = preference || null;
this._cachedDomNodeClientWidth = -1;
this._cachedDomNodeClientHeight = -1;
}
@ -325,7 +324,7 @@ class Widget {
};
}
private _layoutBoxInPage(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult {
private _layoutBoxInPage(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult | null {
let aboveLeft0 = topLeft.left - ctx.scrollLeft;
let belowLeft0 = bottomLeft.left - ctx.scrollLeft;
@ -345,8 +344,8 @@ class Widget {
let absoluteAboveLeft = domNodePosition.left + aboveLeft - dom.StandardWindow.scrollX;
let absoluteBelowLeft = domNodePosition.left + belowLeft - dom.StandardWindow.scrollX;
let INNER_WIDTH = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
let INNER_HEIGHT = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
let INNER_WIDTH = window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth;
let INNER_HEIGHT = window.innerHeight || document.documentElement!.clientHeight || document.body.clientHeight;
// Leave some clearance to the bottom
let TOP_PADDING = 22;
@ -393,7 +392,7 @@ class Widget {
/**
* Compute `this._topLeft`
*/
private _getTopAndBottomLeft(ctx: RenderingContext): [Coordinate, Coordinate] {
private _getTopAndBottomLeft(ctx: RenderingContext): [Coordinate, Coordinate] | [null, null] {
if (!this._viewPosition) {
return [null, null];
}
@ -437,58 +436,53 @@ class Widget {
return [topLeft, bottomLeft];
}
private _prepareRenderWidget(ctx: RenderingContext): Coordinate {
private _prepareRenderWidget(ctx: RenderingContext): Coordinate | null {
const [topLeft, bottomLeft] = this._getTopAndBottomLeft(ctx);
if (!topLeft) {
if (!topLeft || !bottomLeft) {
return null;
}
let placement: IBoxLayoutResult | null = null;
let fetchPlacement = (): void => {
if (placement) {
return;
}
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
const domNode = this.domNode.domNode;
this._cachedDomNodeClientWidth = domNode.clientWidth;
this._cachedDomNodeClientHeight = domNode.clientHeight;
}
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
const domNode = this.domNode.domNode;
this._cachedDomNodeClientWidth = domNode.clientWidth;
this._cachedDomNodeClientHeight = domNode.clientHeight;
}
if (this.allowEditorOverflow) {
placement = this._layoutBoxInPage(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
} else {
placement = this._layoutBoxInViewport(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
}
};
let placement: IBoxLayoutResult | null;
if (this.allowEditorOverflow) {
placement = this._layoutBoxInPage(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
} else {
placement = this._layoutBoxInViewport(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
}
// Do two passes, first for perfect fit, second picks first option
for (let pass = 1; pass <= 2; pass++) {
for (let i = 0; i < this._preference.length; i++) {
let pref = this._preference[i];
if (pref === ContentWidgetPositionPreference.ABOVE) {
fetchPlacement();
if (!placement) {
// Widget outside of viewport
return null;
}
if (pass === 2 || placement.fitsAbove) {
return new Coordinate(placement.aboveTop, placement.aboveLeft);
}
} else if (pref === ContentWidgetPositionPreference.BELOW) {
fetchPlacement();
if (!placement) {
// Widget outside of viewport
return null;
}
if (pass === 2 || placement.fitsBelow) {
return new Coordinate(placement.belowTop, placement.belowLeft);
}
} else {
if (this.allowEditorOverflow) {
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
if (this._preference) {
for (let pass = 1; pass <= 2; pass++) {
for (let i = 0; i < this._preference.length; i++) {
// placement
let pref = this._preference[i];
if (pref === ContentWidgetPositionPreference.ABOVE) {
if (!placement) {
// Widget outside of viewport
return null;
}
if (pass === 2 || placement.fitsAbove) {
return new Coordinate(placement.aboveTop, placement.aboveLeft);
}
} else if (pref === ContentWidgetPositionPreference.BELOW) {
if (!placement) {
// Widget outside of viewport
return null;
}
if (pass === 2 || placement.fitsBelow) {
return new Coordinate(placement.belowTop, placement.belowLeft);
}
} else {
return topLeft;
if (this.allowEditorOverflow) {
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
} else {
return topLeft;
}
}
}
}

View file

@ -36,7 +36,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
super.dispose();
}

View file

@ -34,7 +34,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
super.dispose();
}

View file

@ -16,7 +16,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
private _context: ViewContext;
private _lineHeight: number;
private _typicalHalfwidthCharacterWidth: number;
private _renderResult: string[];
private _renderResult: string[] | null;
constructor(context: ViewContext) {
super();
@ -30,7 +30,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}
@ -83,14 +82,14 @@ export class DecorationsOverlay extends DynamicViewOverlay {
// Sort decorations for consistent render output
decorations = decorations.sort((a, b) => {
if (a.options.zIndex < b.options.zIndex) {
if (a.options.zIndex! < b.options.zIndex!) {
return -1;
}
if (a.options.zIndex > b.options.zIndex) {
if (a.options.zIndex! > b.options.zIndex!) {
return 1;
}
const aClassName = a.options.className;
const bClassName = b.options.className;
const aClassName = a.options.className!;
const bClassName = b.options.className!;
if (aClassName < bClassName) {
return -1;
@ -160,23 +159,23 @@ export class DecorationsOverlay extends DynamicViewOverlay {
continue;
}
const className = d.options.className;
const showIfCollapsed = d.options.showIfCollapsed;
const className = d.options.className!;
const showIfCollapsed = Boolean(d.options.showIfCollapsed);
let range = d.range;
if (showIfCollapsed && range.endColumn === 1 && range.endLineNumber !== range.startLineNumber) {
range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber - 1, this._context.model.getLineMaxColumn(range.endLineNumber - 1));
}
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange, range)) {
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange!, range)) {
// merge into previous decoration
prevRange = Range.plusRange(prevRange, range);
prevRange = Range.plusRange(prevRange!, range);
continue;
}
// flush previous decoration
if (prevClassName !== null) {
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
}
prevClassName = className;
@ -185,7 +184,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
}
if (prevClassName !== null) {
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
}
}

View file

@ -79,7 +79,7 @@ export class GlyphMarginOverlay extends DedupOverlay {
private _glyphMargin: boolean;
private _glyphMarginLeft: number;
private _glyphMarginWidth: number;
private _renderResult: string[];
private _renderResult: string[] | null;
constructor(context: ViewContext) {
super();
@ -94,7 +94,6 @@ export class GlyphMarginOverlay extends DedupOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}

View file

@ -18,7 +18,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
private _primaryLineNumber: number;
private _lineHeight: number;
private _spaceWidth: number;
private _renderResult: string[];
private _renderResult: string[] | null;
private _enabled: boolean;
private _activeIndentEnabled: boolean;
@ -37,7 +37,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}

View file

@ -22,11 +22,11 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
private _lineHeight: number;
private _renderLineNumbers: RenderLineNumbersType;
private _renderCustomLineNumbers: (lineNumber: number) => string;
private _renderCustomLineNumbers: ((lineNumber: number) => string) | null;
private _lineNumbersLeft: number;
private _lineNumbersWidth: number;
private _lastCursorModelPosition: Position;
private _renderResult: string[];
private _renderResult: string[] | null;
constructor(context: ViewContext) {
super();
@ -50,7 +50,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}

View file

@ -48,7 +48,7 @@ export class RangeUtil {
range.selectNodeContents(endNode);
}
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList {
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList | DOMRectList | null {
let range = this._createRange();
try {
range.setStart(startElement, startOffset);
@ -94,7 +94,7 @@ export class RangeUtil {
return result;
}
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList, clientRectDeltaLeft: number): HorizontalRange[] {
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList | DOMRectList | null, clientRectDeltaLeft: number): HorizontalRange[] | null {
if (!clientRects || clientRects.length === 0) {
return null;
}
@ -111,7 +111,7 @@ export class RangeUtil {
return this._mergeAdjacentRanges(result);
}
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] {
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] | null {
// Panic check
let min = 0;
let max = domNode.children.length - 1;
@ -149,8 +149,8 @@ export class RangeUtil {
return null;
}
startOffset = Math.min(startElement.textContent.length, Math.max(0, startOffset));
endOffset = Math.min(endElement.textContent.length, Math.max(0, endOffset));
startOffset = Math.min(startElement.textContent!.length, Math.max(0, startOffset));
endOffset = Math.min(endElement.textContent!.length, Math.max(0, endOffset));
let clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, endNode);
return this._createHorizontalRangesFromClientRects(clientRects, clientRectDeltaLeft);

View file

@ -114,7 +114,7 @@ export class ViewLine implements IVisibleLine {
private _options: ViewLineOptions;
private _isMaybeInvalid: boolean;
private _renderedViewLine: IRenderedViewLine;
private _renderedViewLine: IRenderedViewLine | null;
constructor(options: ViewLineOptions) {
this._options = options;
@ -124,7 +124,7 @@ export class ViewLine implements IVisibleLine {
// --- begin IVisibleLineData
public getDomNode(): HTMLElement {
public getDomNode(): HTMLElement | null {
if (this._renderedViewLine && this._renderedViewLine.domNode) {
return this._renderedViewLine.domNode.domNode;
}
@ -282,7 +282,10 @@ export class ViewLine implements IVisibleLine {
return this._renderedViewLine.getWidthIsFast();
}
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
if (!this._renderedViewLine) {
return null;
}
startColumn = startColumn | 0; // @perf
endColumn = endColumn | 0; // @perf
@ -308,16 +311,19 @@ export class ViewLine implements IVisibleLine {
}
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
if (!this._renderedViewLine) {
return 1;
}
return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset);
}
}
interface IRenderedViewLine {
domNode: FastDomNode<HTMLElement>;
domNode: FastDomNode<HTMLElement> | null;
readonly input: RenderLineInput;
getWidth(): number;
getWidthIsFast(): boolean;
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[];
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null;
getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number;
}
@ -326,13 +332,13 @@ interface IRenderedViewLine {
*/
class FastRenderedViewLine implements IRenderedViewLine {
public domNode: FastDomNode<HTMLElement>;
public domNode: FastDomNode<HTMLElement> | null;
public readonly input: RenderLineInput;
private readonly _characterMapping: CharacterMapping;
private readonly _charWidth: number;
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
constructor(domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
this.domNode = domNode;
this.input = renderLineInput;
@ -348,7 +354,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
return true;
}
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
const startPosition = this._getCharPosition(startColumn);
const endPosition = this._getCharPosition(endColumn);
return [new HorizontalRange(startPosition, endPosition - startPosition)];
@ -364,7 +370,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
}
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
let spanNodeTextContentLength = spanNode.textContent.length;
let spanNodeTextContentLength = spanNode.textContent!.length;
let spanIndex = -1;
while (spanNode) {
@ -393,7 +399,7 @@ class RenderedViewLine implements IRenderedViewLine {
/**
* This is a map that is used only when the line is guaranteed to have no RTL text.
*/
private _pixelOffsetCache: Int32Array;
private _pixelOffsetCache: Int32Array | null;
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) {
this.domNode = domNode;
@ -438,7 +444,7 @@ class RenderedViewLine implements IRenderedViewLine {
/**
* Visible ranges for a model range
*/
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
if (this._pixelOffsetCache !== null) {
// the text is LTR
let startOffset = this._readPixelOffset(startColumn, context);
@ -457,7 +463,7 @@ class RenderedViewLine implements IRenderedViewLine {
return this._readVisibleRangesForRange(startColumn, endColumn, context);
}
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
if (startColumn === endColumn) {
let pixelOffset = this._readPixelOffset(startColumn, context);
if (pixelOffset === -1) {
@ -529,7 +535,7 @@ class RenderedViewLine implements IRenderedViewLine {
return r[0].left;
}
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
if (startColumn === 1 && endColumn === this._characterMapping.length) {
// This branch helps IE with bidi text & gives a performance boost to other browsers when reading visible ranges for an entire line
@ -552,7 +558,7 @@ class RenderedViewLine implements IRenderedViewLine {
* Returns the column for the text found at a specific offset inside a rendered dom node
*/
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
let spanNodeTextContentLength = spanNode.textContent.length;
let spanNodeTextContentLength = spanNode.textContent!.length;
let spanIndex = -1;
while (spanNode) {
@ -566,7 +572,7 @@ class RenderedViewLine implements IRenderedViewLine {
}
class WebKitRenderedViewLine extends RenderedViewLine {
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
let output = super._readVisibleRangesForRange(startColumn, endColumn, context);
if (!output || output.length === 0 || startColumn === endColumn || (startColumn === 1 && endColumn === this._characterMapping.length)) {
@ -592,7 +598,7 @@ class WebKitRenderedViewLine extends RenderedViewLine {
}
}
const createRenderedLine: (domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
const createRenderedLine: (domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
if (browser.isWebKit) {
return createWebKitRenderedLine;
}

View file

@ -78,7 +78,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
private _maxLineWidth: number;
private _asyncUpdateLineWidths: RunOnceScheduler;
private _horizontalRevealRequest: HorizontalRevealRequest;
private _horizontalRevealRequest: HorizontalRevealRequest | null;
private _lastRenderedData: LastRenderedData;
constructor(context: ViewContext, linesContent: FastDomNode<HTMLElement>) {
@ -281,7 +281,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
// ----------- HELPERS FOR OTHERS
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
let viewLineDomNode = this._getViewLineDomNode(spanNode);
if (viewLineDomNode === null) {
// Couldn't find view line node
@ -319,7 +319,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return new Position(lineNumber, column);
}
private _getViewLineDomNode(node: HTMLElement): HTMLElement {
private _getViewLineDomNode(node: HTMLElement | null): HTMLElement | null {
while (node && node.nodeType === 1) {
if (node.className === ViewLine.CLASS_NAME) {
return node;
@ -355,15 +355,15 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return this._visibleLines.getVisibleLine(lineNumber).getWidth();
}
public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] {
public linesVisibleRangesForRange(_range: Range, includeNewLines: boolean): LineVisibleRanges[] | null {
if (this.shouldRender()) {
// Cannot read from the DOM because it is dirty
// i.e. the model & the dom are out of sync, so I'd be reading something stale
return null;
}
let originalEndLineNumber = range.endLineNumber;
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
let originalEndLineNumber = _range.endLineNumber;
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
if (!range) {
return null;
}
@ -371,7 +371,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
let visibleRanges: LineVisibleRanges[] = [], visibleRangesLen = 0;
let domReadingContext = new DomReadingContext(this.domNode.domNode, this._textRangeRestingSpot);
let nextLineModelLineNumber: number;
let nextLineModelLineNumber: number = 0;
if (includeNewLines) {
nextLineModelLineNumber = this._context.model.coordinatesConverter.convertViewPositionToModelPosition(new Position(range.startLineNumber, 1)).lineNumber;
}
@ -411,7 +411,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return visibleRanges;
}
private visibleRangesForRange2(range: Range): HorizontalRange[] {
private visibleRangesForRange2(_range: Range): HorizontalRange[] | null {
if (this.shouldRender()) {
// Cannot read from the DOM because it is dirty
@ -419,7 +419,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return null;
}
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
if (!range) {
return null;
}
@ -453,7 +453,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return result;
}
public visibleRangeForPosition(position: Position): HorizontalRange {
public visibleRangeForPosition(position: Position): HorizontalRange | null {
const visibleRanges = this.visibleRangesForRange2(new Range(position.lineNumber, position.column, position.lineNumber, position.column));
if (!visibleRanges) {
return null;

View file

@ -15,7 +15,7 @@ export class LinesDecorationsOverlay extends DedupOverlay {
private _decorationsLeft: number;
private _decorationsWidth: number;
private _renderResult: string[];
private _renderResult: string[] | null;
constructor(context: ViewContext) {
super();
@ -28,7 +28,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}

View file

@ -11,7 +11,7 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents';
export class MarginViewLineDecorationsOverlay extends DedupOverlay {
private _context: ViewContext;
private _renderResult: string[];
private _renderResult: string[] | null;
constructor(context: ViewContext) {
super();
@ -22,7 +22,6 @@ export class MarginViewLineDecorationsOverlay extends DedupOverlay {
public dispose(): void {
this._context.removeEventHandler(this);
this._context = null;
this._renderResult = null;
super.dispose();
}

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