Hello Code

This commit is contained in:
Erich Gamma 2015-11-13 14:39:38 +01:00
commit 8f35cc4768
1897 changed files with 704173 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
npm-debug.log
Thumbs.db
node_modules/
out/
out-build/
out-editor/
out-editor-min/
out-editor-ossfree/
out-editor-ossfree-min/
out-vscode/
out-vscode-min/
build/node_modules

45
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,45 @@
{
"version": "0.1.0",
"configurations": [
{
"name": "Unit Tests",
"type": "node",
"request": "launch",
"program": "node_modules/mocha/bin/_mocha",
"stopOnEntry": false,
"args": [
"--timeout",
"999999",
"--colors"
],
"cwd": ".",
"runtimeExecutable": null,
"runtimeArgs": [],
"env": {},
"sourceMaps": true,
"outDir": "out"
},
{
"name": "Attach to Extension Host",
"type": "node",
"request": "attach",
"port": 5870,
"sourceMaps": true,
"outDir": "out"
},
{
"name": "VSCode API Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceRoot}/extensions/vscode-api-tests/testWorkspace",
"--extensionDevelopmentPath=${workspaceRoot}/extensions/vscode-api-tests",
"--extensionTestsPath=${workspaceRoot}/extensions/vscode-api-tests/out"
],
"stopOnEntry": false,
"sourceMaps": true,
"outDir": "out"
}
]
}

15
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"editor.insertSpaces": false,
"files.trimTrailingWhitespace": true,
"files.exclude": {
".git": true,
"**/.DS_Store": true,
"**/coverage": true
},
"search.exclude": {
"**/node_modules/**": true,
"**/bower_components": true,
"out*/**": true,
"extensions/**/out/**": true
}
}

37
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,37 @@
{
"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"tasks": [
{
"taskName": "watch",
"args": [
"--no-color"
],
"isBuildCommand": true,
"isWatching": true,
"problemMatcher": {
"owner": "typescript",
"fileLocation": ["absolute"],
"pattern": {
"regexp": "^\\*\\*\\* Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$",
"file": 1,
"location": 2,
"message": 3
},
"watching": {
"beginsPattern": "^\\*\\*\\* Starting\\.\\.\\.$",
"endsPattern": "^\\*\\*\\* Finished"
}
}
},
{
"taskName": "test",
"args": [
"--no-color"
],
"showOutput": "always",
"isTestCommand": true
}
]
}

17
LICENSE.txt Normal file
View File

@ -0,0 +1,17 @@
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

196
OSSREADME.json Normal file
View File

@ -0,0 +1,196 @@
// Listing in here platform dependencies that come in at build time
[{
"name": "atom-brightray",
"repositoryURL": "https://github.com/atom/brightray",
"license": "MIT",
"isProd": true
},
{
"name": "chromium",
"version": "45.0.2454.85",
"repositoryURL": "http://www.chromium.org/Home",
"licenseDetail": [
"BSD License",
"",
"Copyright 2014 The Chromium Authors. All rights reserved.",
"",
"Redistribution and use in source and binary forms, with or without modification,",
"are permitted provided that the following conditions are met:",
"",
" * Redistributions of source code must retain the above copyright notice, this",
" list of conditions and the following disclaimer.",
"",
" * Redistributions in binary form must reproduce the above copyright notice,",
" this list of conditions and the following disclaimer in the documentation",
" and/or other materials provided with the distribution.",
"",
" * Neither the name Google Inc. nor the names of its contributors may be used to",
" endorse or promote products derived from this software without specific",
" prior written permission.",
"",
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND",
"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED",
"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE",
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR",
"ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON",
"ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isProd": true
},
{
"name": "libchromiumcontent",
"version": "45.0.2454.85 ",
"license": "MIT",
"repositoryURL": "https://github.com/atom/libchromiumcontent",
"isProd": true
},
{
"name": "nodejs",
"version": "4.1.1",
"repositoryURL": "https://github.com/nodejs/node",
"isProd": true
},
{
"name": "electron",
"version": "0.34.1",
"license": "MIT",
"repositoryURL": "https://github.com/atom/electron",
"isProd": true
},
{
"name": "inno setup",
"version": "5.5.6",
"repositoryURL": "https://github.com/jrsoftware/issrc",
"isProd": true
},
// ----------------------------------------------------------
// The following definitions are here for the sole purpose of
// defining licenses for dependencies where licensing cannot
// be inferred by tooling:
{
// Reason: LICENSE file missing in repo
// SOURCE: https://github.com/isaacs/core-util-is/blob/master/lib/util.js
"name":"core-util-is",
"isLicense": true,
"licenseDetail": [
"Copyright Joyent, Inc. and other Node contributors.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a",
"copy of this software and associated documentation files (the",
"\"Software\"), to deal in the Software without restriction, including",
"without limitation the rights to use, copy, modify, merge, publish,",
"distribute, sublicense, and/or sell copies of the Software, and to permit",
"persons to whom the Software is furnished to do so, subject to the",
"following conditions:",
"",
"The above copyright notice and this permission notice shall be included",
"in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS",
"OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN",
"NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,",
"DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR",
"OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE",
"USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: vscode-textmate is not public yet
// TODO: Remove once vscode-textmate visibility is made public
"name": "vscode-textmate",
"isLicense": true,
"licenseDetail": [
"The MIT License (MIT)",
"",
"Copyright (c) Microsoft Corporation",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
"SOFTWARE."
]
},
{
// Reason: LICENSE file missing in repo
"name": "winreg",
"isLicense": true,
"licenseDetail": [
"Copyright (c) Paul Bottin",
"",
"The BSD License",
"",
"Redistribution and use in source and binary forms, with or without",
"modification, are permitted provided that the following conditions",
"are met:",
"",
"1. Redistributions of source code must retain the above copyright",
" notice, this list of conditions and the following disclaimer.",
"",
"2. Redistributions in binary form must reproduce the above copyright",
" notice, this list of conditions and the following disclaimer in the",
" documentation and/or other materials provided with the distribution.",
"",
"THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND",
"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS",
"BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR",
"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF",
"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR",
"BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE",
"OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN",
"IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
]
},
{
// Reason: LICENSE file doesn't have Copyright statement
"name": "readdirp",
"isLicense": true,
"licenseDetail": [
"This software is released under the MIT license:",
"",
"Copyright (c) Thorsten Lorenz",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of",
"the Software, and to permit persons to whom the Software is furnished to do so,",
"subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS",
"FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR",
"COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER",
"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN",
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
}
]

1488
ThirdPartyNotices.txt Normal file

File diff suppressed because it is too large Load Diff

28
build/gulpfile.js Normal file
View File

@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var gulp = require('gulp');
var tsb = require('gulp-tsb');
var util = require('./lib/util');
var watcher = require('./lib/watch');
var assign = require('object-assign');
var compilation = tsb.create(assign({ verbose: true }, require('./tsconfig.json').compilerOptions));
gulp.task('compile', function() {
return gulp.src('**/*.ts', { base: '.' })
.pipe(compilation())
.pipe(gulp.dest(''));
});
gulp.task('watch', function() {
var src = gulp.src('**/*.ts', { base: '.' });
return watcher('**/*.ts', { base: '.' })
.pipe(util.incremental(compilation, src))
.pipe(gulp.dest(''));
});
gulp.task('default', ['compile']);

View File

@ -0,0 +1,71 @@
var fs = require('fs'),
path = require('path'),
glob = require('glob');
var StartState = 0;
var BundleRead = 1;
var ReadingFiles = 2;
exports.parse = function (content) {
var state = StartState,
lines = content.split(/\r\n|\n/),
bundledModules = {},
cssModules = {},
toDelete = {};
lines.forEach(function (line) {
line = line.trim();
switch (state) {
case StartState:
if (line.length > 0) {
if (/.*\.js$/.test(line)) {
bundledModules[line] = true;
cssModules[(line.substring(0, line.length - 2) + 'css').toLowerCase()] = true;
}
state = BundleRead;
}
break;
case BundleRead:
if ('----------------' === line) {
state = ReadingFiles;
}
break;
case ReadingFiles:
if (line.length === 0) {
state = StartState;
} else {
if (!bundledModules[line]) {
toDelete[line] = true;
}
}
break;
}
});
return {
bundledModules: bundledModules,
cssModules: cssModules,
toDelete: toDelete
};
};
//exports.cleanEmptyFolders = function (location) {
// glob.sync('**/*', {
// cwd: location
// }).sort(function (a, b) {
// if (a === b) {
// return 0;
// }
// if (a > b) {
// return -1;
// }
// return 1;
// }).forEach(function (file) {
//
// });
//
// console.log(all);
//
//}

260
build/lib/bundle.js Normal file
View File

@ -0,0 +1,260 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var fs = require('fs');
var path = require('path');
var vm = require('vm');
/**
* Bundle `entryPoints` given config `config`.
*/
function bundle(entryPoints, config, callback) {
var entryPointsMap = {};
entryPoints.forEach(function (module) {
entryPointsMap[module.name] = module;
});
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: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader = loaderModule.exports;
config.isBuild = true;
loader.config(config);
loader(Object.keys(entryPointsMap), function () {
var modules = loader.getBuildInfo();
callback(null, emitEntryPoints(modules, entryPointsMap));
}, function (err) { return callback(err, null); });
}
exports.bundle = bundle;
function emitEntryPoints(modules, entryPoints) {
var modulesMap = {};
modules.forEach(function (m) {
modulesMap[m.id] = m;
});
var modulesGraph = {};
modules.forEach(function (m) {
modulesGraph[m.id] = m.dependencies;
});
var sortedModules = topologicalSort(modulesGraph);
var result = [];
var usedPlugins = {};
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) {
delete allDependencies[exclude];
});
});
var includedModules = sortedModules.filter(function (module) {
return allDependencies[module];
});
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
result = result.concat(res.files);
for (var pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
var write = function (filename, contents) {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return result;
}
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules) {
var mainResult = {
sources: [],
dest: entryPoint + '.js'
}, results = [mainResult];
var usedPlugins = {};
var getLoaderPlugin = function (pluginName) {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
};
includedModules.forEach(function (c) {
var bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
var pluginName = c.substr(0, bangIndex);
var plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
var module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
var contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
}
else {
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
}
});
Object.keys(usedPlugins).forEach(function (pluginName) {
var plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
var req = (function () {
throw new Error('no-no!');
});
req.toUrl = function (something) { return something; };
var write = function (filename, contents) {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path) {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
var result = '';
if (typeof plugin.write === 'function') {
var write = (function (what) {
result += what;
});
write.getEntryPoint = function () {
return entryPoint;
};
write.asModule = function (moduleId, code) {
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId, myDeps, defineCallPosition, path, contents) {
// `defineCallPosition` is the position in code: |define()
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
var parensOffset = contents.indexOf('(', defineCallOffset);
var 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 + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str, desiredLine, desiredCol) {
if (desiredLine === 1) {
return desiredCol - 1;
}
var line = 1, lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes, graph) {
var result = {}, queue = rootNodes;
rootNodes.forEach(function (node) {
result[node] = true;
});
while (queue.length > 0) {
var el = queue.shift();
var myEdges = graph[el] || [];
myEdges.forEach(function (toNode) {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph) {
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
Object.keys(graph).forEach(function (fromNode) {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach(function (toNode) {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
var S = [], L = [];
Object.keys(allNodes).forEach(function (node) {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
var n = S.shift();
L.push(n);
var myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach(function (m) {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}

397
build/lib/bundle.ts Normal file
View File

@ -0,0 +1,397 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fs = require('fs');
import path = require('path');
import vm = require('vm');
interface IPosition {
line: number;
col: number;
}
interface IBuildModuleInfo {
id: string;
path: string;
defineLocation: IPosition;
dependencies: string[];
shim: string;
exports: any;
}
interface IBuildModuleInfoMap {
[moduleId:string]: IBuildModuleInfo;
}
interface ILoaderPlugin {
write(pluginName:string, moduleName:string, write:ILoaderPluginWriteFunc): void;
writeFile(pluginName:string, entryPoint:string, req:ILoaderPluginReqFunc, write:(filename:string, contents:string)=>void, config:any): void;
finishBuild(write:(filename:string, contents:string)=>void): void;
}
interface ILoaderPluginWriteFunc {
(something:string): void;
getEntryPoint(): string;
asModule(moduleId:string, code:string): void;
}
interface ILoaderPluginReqFunc {
(something:string): void;
toUrl(something:string): string;
}
export interface IEntryPoint {
name: string;
include: string[];
exclude: string[];
}
interface IEntryPointMap {
[moduleId:string]: IEntryPoint;
}
interface IGraph {
[node:string]: string[];
}
interface INodeSet {
[node:string]: boolean;
}
export interface IFile {
path: string;
contents: string;
}
export interface IConcatFile {
dest: string;
sources: IFile[];
}
export interface ILoaderConfig {
isBuild?: boolean;
}
/**
* Bundle `entryPoints` given config `config`.
*/
export function bundle(entryPoints:IEntryPoint[], config:ILoaderConfig, callback:(err:any, result:IConcatFile[]) => void): void {
let entryPointsMap:IEntryPointMap = {};
entryPoints.forEach((module:IEntryPoint) => {
entryPointsMap[module.name] = module;
});
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
var r: Function = <any> vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
var loaderModule = { exports: {} };
r.call({}, require, loaderModule, loaderModule.exports);
var loader:any = loaderModule.exports;
config.isBuild = true;
loader.config(config);
loader(Object.keys(entryPointsMap), () => {
let modules = <IBuildModuleInfo[]>loader.getBuildInfo();
callback(null, emitEntryPoints(modules, entryPointsMap));
}, (err) => callback(err, null))
}
function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap): IConcatFile[] {
let modulesMap: IBuildModuleInfoMap = {};
modules.forEach((m:IBuildModuleInfo) => {
modulesMap[m.id] = m;
});
let modulesGraph:IGraph = {};
modules.forEach((m:IBuildModuleInfo) => {
modulesGraph[m.id] = m.dependencies;
});
let sortedModules = topologicalSort(modulesGraph);
let result: IConcatFile[] = [];
let usedPlugins: IPluginMap = {};
Object.keys(entryPoints).forEach((moduleToBundle:string) => {
let info = entryPoints[moduleToBundle];
let rootNodes = [moduleToBundle].concat(info.include || []);
let allDependencies = visit(rootNodes, modulesGraph);
let excludes:string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
excludes.forEach((excludeRoot:string) => {
let allExcludes = visit([excludeRoot], modulesGraph);
Object.keys(allExcludes).forEach((exclude:string) => {
delete allDependencies[exclude];
});
});
let includedModules = sortedModules.filter((module:string) => {
return allDependencies[module];
});
let res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
result = result.concat(res.files);
for (let pluginName in res.usedPlugins) {
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
}
});
Object.keys(usedPlugins).forEach((pluginName:string) => {
let plugin = usedPlugins[pluginName];
if (typeof plugin.finishBuild === 'function') {
let write = (filename:string, contents:string) => {
result.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.finishBuild(write);
}
});
return result;
}
interface IPluginMap {
[moduleId:string]:ILoaderPlugin;
}
interface IEmitEntryPointResult {
files: IConcatFile[];
usedPlugins: IPluginMap;
}
function emitEntryPoint(modulesMap:IBuildModuleInfoMap, deps:IGraph, entryPoint:string, includedModules:string[]): IEmitEntryPointResult {
let mainResult: IConcatFile = {
sources: [],
dest: entryPoint + '.js'
},
results: IConcatFile[] = [mainResult];
let usedPlugins: IPluginMap = {};
let getLoaderPlugin = (pluginName:string):ILoaderPlugin => {
if (!usedPlugins[pluginName]) {
usedPlugins[pluginName] = modulesMap[pluginName].exports;
}
return usedPlugins[pluginName];
}
includedModules.forEach((c:string) => {
let bangIndex = c.indexOf('!');
if (bangIndex >= 0) {
let pluginName = c.substr(0, bangIndex);
let plugin = getLoaderPlugin(pluginName);
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
return;
}
let module = modulesMap[c];
if (module.path === 'empty:') {
return;
}
let contents = readFileAndRemoveBOM(module.path);
if (module.shim) {
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
} else {
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
}
});
Object.keys(usedPlugins).forEach((pluginName:string) => {
let plugin = usedPlugins[pluginName];
if (typeof plugin.writeFile === 'function') {
let req:ILoaderPluginReqFunc = <any>(() => {
throw new Error('no-no!');
});
req.toUrl = something => something;
let write = (filename:string, contents:string) => {
results.push({
dest: filename,
sources: [{
path: null,
contents: contents
}]
});
};
plugin.writeFile(pluginName, entryPoint, req, write, {});
}
});
return {
files: results,
usedPlugins: usedPlugins
};
}
function readFileAndRemoveBOM(path:string): string {
var BOM_CHAR_CODE = 65279;
var contents = fs.readFileSync(path, 'utf8');
// Remove BOM
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
contents = contents.substring(1);
}
return contents;
}
function emitPlugin(entryPoint:string, plugin:ILoaderPlugin, pluginName:string, moduleName:string): IFile {
let result = '';
if (typeof plugin.write === 'function') {
let write: ILoaderPluginWriteFunc = <any>((what) => {
result += what;
});
write.getEntryPoint = () => {
return entryPoint;
};
write.asModule = (moduleId:string, code:string) => {
code = code.replace(/^define\(/, 'define("'+moduleId+'",');
result += code;
};
plugin.write(pluginName, moduleName, write);
}
return {
path: null,
contents: result
};
}
function emitNamedModule(moduleId:string, myDeps:string[], defineCallPosition:IPosition, path:string, contents:string): IFile {
// `defineCallPosition` is the position in code: |define()
let defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
// `parensOffset` is the position in code: define|()
let parensOffset = contents.indexOf('(', defineCallOffset);
let insertStr = '"' + moduleId + '", ';
return {
path: path,
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
};
}
function emitShimmedModule(moduleId:string, myDeps:string[], factory:string, path:string, contents:string): IFile {
let strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
let strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
return {
path: path,
contents: contents + '\n;\n' + strDefine
};
}
/**
* Convert a position (line:col) to (offset) in string `str`
*/
function positionToOffset(str:string, desiredLine:number, desiredCol:number): number {
if (desiredLine === 1) {
return desiredCol - 1;
}
let line = 1,
lastNewLineOffset = -1;
do {
if (desiredLine === line) {
return lastNewLineOffset + 1 + desiredCol - 1;
}
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
line++;
} while (lastNewLineOffset >= 0);
return -1;
}
/**
* Return a set of reachable nodes in `graph` starting from `rootNodes`
*/
function visit(rootNodes:string[], graph:IGraph):INodeSet {
let result:INodeSet = {},
queue = rootNodes;
rootNodes.forEach((node) => {
result[node] = true;
});
while (queue.length > 0) {
let el = queue.shift();
let myEdges = graph[el] || [];
myEdges.forEach((toNode) => {
if (!result[toNode]) {
result[toNode] = true;
queue.push(toNode);
}
});
}
return result;
}
/**
* Perform a topological sort on `graph`
*/
function topologicalSort(graph:IGraph): string[] {
let allNodes:INodeSet = {},
outgoingEdgeCount:{[node:string]:number;} = {},
inverseEdges:IGraph = {};
Object.keys(graph).forEach((fromNode:string) => {
allNodes[fromNode] = true;
outgoingEdgeCount[fromNode] = graph[fromNode].length;
graph[fromNode].forEach((toNode) => {
allNodes[toNode] = true;
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
inverseEdges[toNode] = inverseEdges[toNode] || [];
inverseEdges[toNode].push(fromNode);
});
});
// https://en.wikipedia.org/wiki/Topological_sorting
let S: string[] = [],
L: string[] = [];
Object.keys(allNodes).forEach((node:string) => {
if (outgoingEdgeCount[node] === 0) {
delete outgoingEdgeCount[node];
S.push(node);
}
});
while (S.length > 0) {
// Ensure the exact same order all the time with the same inputs
S.sort();
let n:string = S.shift();
L.push(n);
let myInverseEdges = inverseEdges[n] || [];
myInverseEdges.forEach((m:string) => {
outgoingEdgeCount[m]--;
if (outgoingEdgeCount[m] === 0) {
delete outgoingEdgeCount[m];
S.push(m);
}
});
}
if (Object.keys(outgoingEdgeCount).length > 0) {
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
}
return L;
}

76
build/lib/copyrights.js Normal file
View File

@ -0,0 +1,76 @@
var es = require('event-stream');
var fs = require('fs');
var path = require('path');
var copyright = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------*/'
].join('\n');
var ignoreList = [
'/src/vs/languages/typescript/common/lib/lib.d.ts',
'/src/vs/languages/typescript/common/lib/lib.es6.d.ts',
'/src/vs/languages/typescript/common/lib/typescriptServices.d.ts',
'/src/vs/workbench/parts/emmet/node/emmet.d.ts',
'/src/vs/editor/standalone-languages/swift.ts',
'/src/vs/workbench/browser/media/octicons/octicons.css',
'/src/vs/base/test/node/encoding/fixtures/some_utf16be.css',
'/src/vs/base/test/node/encoding/fixtures/some_utf16le.css',
'/src/vs/workbench/services/search/test/node/fixtures/site.css',
'/src/vs/workbench/services/search/test/node/fixtures/some_utf16be.css',
'/src/vs/workbench/services/search/test/node/fixtures/some_utf16le.css',
'/src/vs/workbench/services/files/test/node/fixtures/service/some_utf16le.css',
'/extensions/lib.core.d.ts',
'/extensions/node.d.ts',
'/extensions/csharp-o/src/typings/applicationinsights.d.ts',
'/extensions/typescript/out/lib/lib.core.d.ts',
'/extensions/typescript/out/lib/lib.core.es6.d.ts',
'/extensions/typescript/out/lib/lib.d.ts',
'/extensions/typescript/out/lib/lib.dom.d.ts',
'/extensions/typescript/out/lib/lib.es6.d.ts',
'/extensions/typescript/out/lib/lib.scriptHost.d.ts',
'/extensions/typescript/out/lib/lib.webworker.d.ts',
'/extensions/typescript/src/lib/lib.core.d.ts',
'/extensions/typescript/src/lib/lib.core.es6.d.ts',
'/extensions/typescript/src/lib/lib.d.ts',
'/extensions/typescript/src/lib/lib.dom.d.ts',
'/extensions/typescript/src/lib/lib.es6.d.ts',
'/extensions/typescript/src/lib/lib.scriptHost.d.ts',
'/extensions/typescript/src/lib/lib.webworker.d.ts',
'/extensions/csharp-o/src/typings/semver/semver.d.ts'
];
function ignore(filePath) {
filePath = path.posix.normalize(filePath);
return ignoreList.some(function(p) {
return filePath.indexOf(p) !== -1;
});
}
exports.copyrights = function () {
return es.mapSync(function (file) {
if (file.contents) {
var contents = file.contents.toString('utf8');
if (contents.indexOf(copyright) !== 0 && !ignore(file.path)) {
throw new Error('File ' + file.path + ' does not contain copyright statement.');
}
}
});
};
exports.insertCopyrights = function() {
return es.mapSync(function (file) {
if (file.contents) {
var contents = file.contents.toString('utf8');
if (contents.indexOf(copyright) !== 0 && !ignore(file.path)) {
contents = copyright + '\n\n' + contents;
fs.writeFileSync(file.path, contents, 'utf8');
}
}
});
}

52
build/lib/git.js Normal file
View File

@ -0,0 +1,52 @@
var path = require('path');
var fs = require('fs');
exports.getVersion = function (repo) {
var git = path.join(repo, '.git');
var headPath = path.join(git, 'HEAD');
var head;
try {
head = fs.readFileSync(headPath, 'utf8').trim();
} catch (e) {
return void 0;
}
if (/^[0-9a-f]{40}$/i.test(head)) {
return head;
}
var refMatch = /^ref: (.*)$/.exec(head);
if (!refMatch) {
return void 0;
}
var ref = refMatch[1];
var refPath = path.join(git, ref);
try {
return fs.readFileSync(refPath, 'utf8').trim();
} catch (e) {
// noop
}
var packedRefsPath = path.join(git, 'packed-refs');
var 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 = {};
while (refsMatch = refsRegex.exec(refsRaw)) {
refs[refsMatch[2]] = refsMatch[1];
}
return refs[ref];
};

369
build/lib/nls.js Normal file
View File

@ -0,0 +1,369 @@
var ts = require('./typescript/typescriptServices');
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 clone = require('clone');
var path = require('path');
var CollectStepResult;
(function (CollectStepResult) {
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse";
CollectStepResult[CollectStepResult["No"] = 2] = "No";
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
})(CollectStepResult || (CollectStepResult = {}));
function collect(node, fn) {
var result = [];
function loop(node) {
var stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
ts.forEachChild(node, loop);
}
}
loop(node);
return result;
}
function zip(stream, zipper) {
if (zipper === void 0) { zipper = function (a, b) { return [a, b]; }; }
var pass = event_stream_1.through();
var oneBuffer = [];
var otherBuffer = [];
var result = pass.pipe(event_stream_1.through(function (f) {
oneBuffer.push(f);
flush();
}), function () {
flush();
result.emit('end');
});
function flush() {
while (oneBuffer.length > 0 && otherBuffer.length > 0) {
result.emit('data', zipper(oneBuffer.shift(), otherBuffer.shift()));
}
}
stream.pipe(event_stream_1.through(function (f) { return otherBuffer.push(f); }));
return event_stream_1.duplex(pass, result);
}
function template(lines) {
var 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) + "]);";
}
/**
* 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;
if (!f.sourceMap) {
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
}
var 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."));
}
var root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
var 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."));
}
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
}));
return event_stream_1.duplex(input, output);
}
function isImportNode(node) {
return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */;
}
var nls;
(function (nls_1) {
function fileFrom(file, contents, path) {
if (path === void 0) { path = file.path; }
return new File({
contents: new Buffer(contents),
base: file.base,
cwd: file.cwd,
path: path
});
}
nls_1.fileFrom = fileFrom;
function mappedPositionFrom(source, lc) {
return { source: 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 = (function () {
function SingleFileServiceHost(options, filename, contents) {
var _this = this;
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.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)) {
return CollectStepResult.No;
}
return node.kind === 160 /* 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 = service.getSourceFile(filename);
// all imports
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
// import nls = require('vs/nls');
var importEqualsDeclarations = imports
.filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; })
.filter(function (d) { return d.moduleReference.expression.getText() === "'vs/nls'"; });
// import ... from 'vs/nls';
var importDeclarations = imports
.filter(function (n) { return n.kind === 212 /* ImportDeclaration */; })
.map(function (n) { return n; })
.filter(function (d) { return d.moduleSpecifier.kind === 8 /* 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 ({
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
}); });
// `nls.localize(...)` calls
var nlsLocalizeCallExpressions = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === 214 /* NamespaceImport */; })
.map(function (d) { return d.importClause.namedBindings.name; })
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; })
.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; })
.filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; });
// `localize` named imports
var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; })
.map(function (d) { return 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); })
.flatten()
.filter(function (r) { return !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); })
.flatten()
.filter(function (r) { return !r.isWriteAccess; });
// find the deepest call expressions AST nodes that contain those references
var 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; });
// collect everything
var 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 ({
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 = (function () {
function TextModel(contents) {
var regex = /\r\n|\r|\n/g;
var index = 0;
var match;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
this.lines.push(contents.substring(index, match.index));
this.lineEndings.push(match[0]);
index = regex.lastIndex;
}
if (contents.length > 0) {
this.lines.push(contents.substring(index, contents.length));
this.lineEndings.push('');
}
}
TextModel.prototype.get = function (index) {
return this.lines[index];
};
TextModel.prototype.set = function (index, line) {
this.lines[index] = line;
};
Object.defineProperty(TextModel.prototype, "lineCount", {
get: function () {
return this.lines.length;
},
enumerable: true,
configurable: true
});
/**
* 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] || '';
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++) {
this.lines[i] = '';
}
};
TextModel.prototype.toString = function () {
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);
// patch the localize calls
lazy(patches).reverse().each(function (p) { return 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");
model.set(0, patchedFirstLine);
return model.toString();
}
nls_1.patchJavascript = patchJavascript;
function patchSourcemap(patches, rsm, smc) {
var 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 };
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;
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 });
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
}
return JSON.parse(smg.toString());
}
nls_1.patchSourcemap = patchSourcemap;
function patch(moduleId, typescript, javascript, sourcemap) {
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
if (localizeCalls.length === 0) {
return { javascript: javascript, sourcemap: 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;
// build patches
var patches = lazy(localizeCalls)
.map(function (lc) { return ([
{ 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 };
})
.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");
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
}
nls_1.patch = patch;
function patchFiles(javascriptFile, typescript) {
// hack?
var 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)];
result[0].sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
}
if (nls) {
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
}
return result;
}
nls_1.patchFiles = patchFiles;
})(nls || (nls = {}));
module.exports = nls;

485
build/lib/nls.ts Normal file
View File

@ -0,0 +1,485 @@
import * as ts from './typescript/typescriptServices';
import * as lazy from 'lazy.js';
import { duplex, through, mapSync, readArray, merge } from 'event-stream';
import { Stream } from 'stream';
import { ThroughStream } from 'through';
import File = require('vinyl');
import * as sm from 'source-map';
import assign = require('object-assign');
import clone = require('clone');
import filter = require('gulp-filter');
import path = require('path');
import fs = require('fs');
declare class FileSourceMap extends File {
public sourceMap: sm.RawSourceMap;
}
enum CollectStepResult {
Yes,
YesAndRecurse,
No,
NoAndRecurse
}
function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.Node[] {
const result: ts.Node[] = [];
function loop(node: ts.Node) {
var stepResult = fn(node);
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
result.push(node);
}
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
ts.forEachChild(node, loop);
}
}
loop(node);
return result;
}
function zip<A,B,R>(stream: Stream, zipper: (a: A, b: B) => R = (a,b) => <any> [a, b]): ThroughStream {
const pass = through();
const oneBuffer: any[] = [];
const otherBuffer: any[] = [];
const result = pass.pipe(through(f => {
oneBuffer.push(f);
flush();
}), () => {
flush();
result.emit('end');
});
function flush() {
while (oneBuffer.length > 0 && otherBuffer.length > 0) {
result.emit('data', zipper(oneBuffer.shift(), otherBuffer.shift()));
}
}
stream.pipe(through(f => otherBuffer.push(f)));
return duplex(pass, result);
}
function template(lines: string[]): string {
let indent = '', wrap = '';
if (lines.length > 1) {
indent = '\t';
wrap = '\n';
}
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(): Stream {
var input = through();
var output = input.pipe(through(function (f: FileSourceMap) {
if (!f.sourceMap) {
return this.emit('error', new Error(`File ${ f.relative } does not have sourcemaps.`));
}
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.`));
}
const root = f.sourceMap.sourceRoot;
if (root) {
source = path.join(root, source);
}
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.`));
}
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
}));
return duplex(input, output);
}
function isImportNode(node: ts.Node): boolean {
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
}
module nls {
export interface INlsStringResult {
javascript: string;
sourcemap: sm.RawSourceMap;
nls?: string;
nlsKeys?: string;
}
export interface ISpan {
start: ts.LineAndCharacter;
end: ts.LineAndCharacter;
}
export interface ILocalizeCall {
keySpan: ISpan;
key: string;
valueSpan: ISpan;
value: string;
}
export interface ILocalizeAnalysisResult {
localizeCalls: ILocalizeCall[];
nlsExpressions: ISpan[];
}
export interface IPatch {
span: ISpan;
content: string;
}
export function fileFrom(file: File, contents: string, path: string = file.path) {
return new File({
contents: new Buffer(contents),
base: file.base,
cwd: file.cwd,
path: path
});
}
export function mappedPositionFrom(source: string, lc: ts.LineAndCharacter): sm.MappedPosition {
return { source, line: lc.line + 1, column: lc.character };
}
export function lcFrom(position: sm.Position): ts.LineAndCharacter {
return { line: position.line - 1, character: position.column };
}
export class SingleFileServiceHost implements ts.LanguageServiceHost {
private file: ts.IScriptSnapshot;
private lib: ts.IScriptSnapshot;
constructor(private options: ts.CompilerOptions, private filename: string, contents: string) {
this.file = ts.ScriptSnapshot.fromString(contents);
this.lib = ts.ScriptSnapshot.fromString('');
}
getCompilationSettings = () => this.options;
getScriptFileNames = () => [this.filename];
getScriptVersion = () => '1';
getScriptSnapshot = (name: string) => name === this.filename ? this.file : this.lib;
getCurrentDirectory = () => '';
getDefaultLibFileName = () => 'lib.d.ts';
}
function isCallExpressionWithinTextSpanCollectStep(textSpan: ts.TextSpan, node: ts.Node): CollectStepResult {
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
return CollectStepResult.No;
}
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
}
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 service = ts.createLanguageService(serviceHost);
const sourceFile = service.getSourceFile(filename);
// all imports
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
// import nls = require('vs/nls');
const importEqualsDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
.map(n => <ts.ImportEqualsDeclaration> n)
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
.filter(d => (<ts.ExternalModuleReference>d.moduleReference).expression.getText() === "'vs/nls'");
// import ... from 'vs/nls';
const importDeclarations = imports
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
.map(n => <ts.ImportDeclaration> 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 => (<ts.ExternalModuleReference>d.moduleReference).expression)
.concat(importDeclarations.map(d => d.moduleSpecifier))
.map<ISpan>(d => ({
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
}));
// `nls.localize(...)` calls
const nlsLocalizeCallExpressions = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport)
.map(d => (<ts.NamespaceImport> d.importClause.namedBindings).name)
.concat(importEqualsDeclarations.map(d => d.name))
// find read-only references to `nls`
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(r => !r.isWriteAccess)
// find the deepest call expressions AST nodes that contain those references
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => <ts.CallExpression> n)
// only `localize` calls
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && (<ts.PropertyAccessExpression> n.expression).name.getText() === 'localize');
// `localize` named imports
const allLocalizeImportDeclarations = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)
.map(d => (<ts.NamedImports> d.importClause.namedBindings).elements)
.flatten()
// `localize` read-only references
const localizeReferences = allLocalizeImportDeclarations
.filter(d => d.name.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
.flatten()
.filter(r => !r.isWriteAccess);
// custom named `localize` read-only references
const namedLocalizeReferences = allLocalizeImportDeclarations
.filter(d => d.propertyName && d.propertyName.getText() === 'localize')
.map(n => service.getReferencesAtPosition(filename, n.name.pos + 1))
.flatten()
.filter(r => !r.isWriteAccess);
// find the deepest call expressions AST nodes that contain those references
const localizeCallExpressions = localizeReferences
.concat(namedLocalizeReferences)
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
.map(a => lazy(a).last())
.filter(n => !!n)
.map(n => <ts.CallExpression> n);
// collect everything
const localizeCalls = nlsLocalizeCallExpressions
.concat(localizeCallExpressions)
.map(e => e.arguments)
.filter(a => a.length > 1)
.sort((a, b) => a[0].getStart() - b[0].getStart())
.map<ILocalizeCall>(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()
};
}
export class TextModel {
private lines: string[];
private lineEndings: string[];
constructor(contents: string) {
const regex = /\r\n|\r|\n/g;
let index = 0;
let match: RegExpExecArray;
this.lines = [];
this.lineEndings = [];
while (match = regex.exec(contents)) {
this.lines.push(contents.substring(index, match.index));
this.lineEndings.push(match[0]);
index = regex.lastIndex;
}
if (contents.length > 0) {
this.lines.push(contents.substring(index, contents.length));
this.lineEndings.push('');
}
}
public get(index: number): string {
return this.lines[index];
}
public set(index: number, line: string): void {
this.lines[index] = line;
}
public get lineCount(): number {
return this.lines.length;
}
/**
* Applies patch(es) to the model.
* Multiple patches must be ordered.
* Does not support patches spanning multiple lines.
*/
public apply(patch: IPatch): void {
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 (let i = startLineNumber + 1; i <= endLineNumber; i++) {
this.lines[i] = '';
}
}
public toString(): string {
return lazy(this.lines).zip(this.lineEndings)
.flatten().toArray().join('');
}
}
export function patchJavascript(patches: IPatch[], contents: string, moduleId: string): string {
const model = new nls.TextModel(contents);
// patch the localize calls
lazy(patches).reverse().each(p => model.apply(p));
// patch the 'vs/nls' imports
const firstLine = model.get(0);
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
model.set(0, patchedFirstLine);
return model.toString();
}
export function patchSourcemap(patches: IPatch[], rsm: sm.RawSourceMap, smc: sm.SourceMapConsumer): sm.RawSourceMap {
const smg = new sm.SourceMapGenerator({
file: rsm.file,
sourceRoot: rsm.sourceRoot
});
patches = patches.reverse();
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) {
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, name: m.name, original, generated});
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
if (source) {
smg.setSourceContent(source, smc.sourceContentFor(source));
}
return JSON.parse(smg.toString());
}
export function patch(moduleId: string, typescript: string, javascript: string, sourcemap: sm.RawSourceMap): INlsStringResult {
const { localizeCalls, nlsExpressions } = analyze(typescript);
if (localizeCalls.length === 0) {
return { javascript, sourcemap };
}
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
const patches = lazy(localizeCalls)
.map(lc => ([
{ range: lc.keySpan, content: '' + (i++) },
{ range: lc.valueSpan, content: 'null' }
]))
.flatten()
.map<IPatch>(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, line => {
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
});
}
sourcemap = patchSourcemap(patches, sourcemap, smc);
return { javascript, sourcemap, nlsKeys, nls };
}
export function patchFiles(javascriptFile: File, typescript: string): File[] {
// hack?
const moduleId = javascriptFile.relative
.replace(/\.js$/, '')
.replace(/\\/g, '/');
const { javascript, sourcemap, nlsKeys, nls } = patch(
moduleId,
typescript,
javascriptFile.contents.toString(),
(<any>javascriptFile).sourceMap
);
const result: File[] = [fileFrom(javascriptFile, javascript)];
(<any>result[0]).sourceMap = sourcemap;
if (nlsKeys) {
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
}
if (nls) {
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
}
return result;
}
}
export = nls;

42
build/lib/reporter.js Normal file
View File

@ -0,0 +1,42 @@
var es = require('event-stream');
var _ = require('underscore');
var allErrors = [];
var count = 0;
function onStart() {
if (count++ > 0) {
return;
}
console.log('*** Starting...');
}
function onEnd() {
if (--count > 0) {
return ;
}
var errors = _.flatten(allErrors);
errors.map(function (err) { console.log('*** Error:', err); });
console.log('*** Finished with', errors.length, 'errors.');
}
module.exports = function () {
var errors = [];
allErrors.push(errors);
return function (err) {
if (err) {
errors.push(err);
return;
}
errors.length = 0;
onStart();
return es.through(null, function () {
onEnd();
this.emit('end');
});
};
};

67
build/lib/style.js Normal file
View File

@ -0,0 +1,67 @@
var es = require('event-stream');
var path = require('path');
module.exports = function (opts) {
return es.mapSync(function (file) {
if (file.stat.isDirectory()) {
return file;
}
var contents = file.contents.toString('utf8');
if (opts.complain) {
if (contents.indexOf('\r\n') >= 0) {
console.log(file.path + ' uses \\r\\n');
}
if (opts.whitespace) {
var lines = contents.split(/\r\n|\r|\n/);
var hadErrorLineNumber = 0;
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (line.length === 0) {
// empty lines are OK
continue;
}
if (/^[\t]*[^\s]/.test(line)) {
// good indent
continue;
} else if (/^[\t]* \*/.test(line)) {
// block comment using an extra space
continue;
} else if (/^[\t]+$/.test(line)) {
// empty line
continue;
} else {
// console.log(file.path + '(' + hadErrorLineNumber + ',1): Mixed whitespace indentation');
hadErrorLineNumber = i + 1;
break;
}
}
if (hadErrorLineNumber) {
console.log(file.path + '(' + hadErrorLineNumber + ',1): Mixed whitespace indentation');
}
}
} else {
var lines = contents.split(/\r\n|\r|\n/);
if (opts.whitespace) {
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
line = line.replace(/^\ {28}/, '\t\t\t\t\t\t\t');
line = line.replace(/^\ {24}/, '\t\t\t\t\t\t');
line = line.replace(/^\ {20}/, '\t\t\t\t\t');
line = line.replace(/^\ {16}/, '\t\t\t\t');
line = line.replace(/^\ {12}/, '\t\t\t');
line = line.replace(/^\ {8}/, '\t\t');
line = line.replace(/^\ {4}/, '\t');
lines[i] = line;
}
}
file.contents = new Buffer(lines.join('\n'), 'utf8');
}
return file;
});
};

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

4
build/lib/typings/clone.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
declare module 'clone' {
function fn<T>(obj: T): T;
export = fn;
}

18
build/lib/typings/event-stream.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
declare module "event-stream" {
import { Stream } from 'stream';
import { ThroughStream } from 'through';
function merge(...stream: Stream[]): ThroughStream;
function concat(...stream: Stream[]): ThroughStream;
function duplex(istream: Stream, ostream: Stream): ThroughStream;
function through(write?: (data: any) => void, end?: () => void,
opts?: {autoDestroy: boolean; }): ThroughStream;
function readArray<T>(array: T[]): ThroughStream;
function writeArray<T>(cb: (err:Error, array:T[]) => void): ThroughStream;
function mapSync<I,O>(cb: (data:I) => O): ThroughStream;
function map<I,O>(cb: (data:I, cb:(err?:Error, data?: O)=>void) => O): ThroughStream;
}

8
build/lib/typings/gulp-filter.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
declare module 'gulp-filter' {
import { ThroughStream } from 'through';
function fn(pattern: string): ThroughStream;
function fn(patterns: string[]): ThroughStream;
export = fn;
}

273
build/lib/typings/lazy.js.d.ts vendored Normal file
View File

@ -0,0 +1,273 @@
// Type definitions for Lazy.js 0.3.2
// Project: https://github.com/dtao/lazy.js/
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare function Lazy(value: string): Lazy.StringLikeSequence;
declare function Lazy<T>(value: T[]): Lazy.ArrayLikeSequence<T>;
declare function Lazy(value: any[]): Lazy.ArrayLikeSequence<any>;
declare function Lazy<T>(value: Object): Lazy.ObjectLikeSequence<T>;
declare function Lazy(value: Object): Lazy.ObjectLikeSequence<any>;
declare module Lazy {
function strict(): StrictLazy;
function generate<T>(generatorFn: GeneratorCallback<T>, length?: number): GeneratedSequence<T>;
function range(to: number): GeneratedSequence<number>;
function range(from: number, to: number, step?: number): GeneratedSequence<number>;
function repeat<T>(value: T, count?: number): GeneratedSequence<T>;
function on<T>(eventType: string): Sequence<T>;
function readFile(path: string): StringLikeSequence;
function makeHttpRequest(path: string): StringLikeSequence;
interface StrictLazy {
(value: string): StringLikeSequence;
<T>(value: T[]): ArrayLikeSequence<T>;
(value: any[]): ArrayLikeSequence<any>;
<T>(value: Object): ObjectLikeSequence<T>;
(value: Object): ObjectLikeSequence<any>;
strict(): StrictLazy;
generate<T>(generatorFn: GeneratorCallback<T>, length?: number): GeneratedSequence<T>;
range(to: number): GeneratedSequence<number>;
range(from: number, to: number, step?: number): GeneratedSequence<number>;
repeat<T>(value: T, count?: number): GeneratedSequence<T>;
on<T>(eventType: string): Sequence<T>;
readFile(path: string): StringLikeSequence;
makeHttpRequest(path: string): StringLikeSequence;
}
interface ArrayLike<T> {
length: number;
[index: number]: T;
}
interface Callback {
(): void;
}
interface ErrorCallback {
(error: any): void;
}
interface ValueCallback<T> {
(value: T): void;
}
interface GetKeyCallback<T> {
(value: T): string;
}
interface TestCallback<T> {
(value: T): boolean;
}
interface MapCallback<T, U> {
(value: T): U;
}
interface MapStringCallback {
(value: string): string;
}
interface NumberCallback<T> {
(value: T): number;
}
interface MemoCallback<T, U> {
(memo: U, value: T): U;
}
interface GeneratorCallback<T> {
(index: number): T;
}
interface CompareCallback {
(x: any, y: any): number;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface Iterator<T> {
new (sequence: Sequence<T>): Iterator<T>;
current(): T;
moveNext(): boolean;
}
interface GeneratedSequence<T> extends Sequence<T> {
new(generatorFn: GeneratorCallback<T>, length: number): GeneratedSequence<T>;
length(): number;
}
interface AsyncSequence<T> extends SequenceBase<T> {
each(callback: ValueCallback<T>): AsyncHandle<T>;
}
interface AsyncHandle<T> {
cancel(): void;
onComplete(callback: Callback): void;
onError(callback: ErrorCallback): void;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module Sequence {
function define(methodName: string[], overrides: Object): Function;
}
interface Sequence<T> extends SequenceBase<T> {
each(eachFn: ValueCallback<T>): Sequence<T>;
}
interface ArraySequence<T> extends SequenceBase<T[]> {
flatten(): Sequence<T>;
}
interface SequenceBase<T> extends SequenceBaser<T> {
first(): any;
first(count: number): Sequence<T>;
indexOf(value: any, startIndex?: number): Sequence<T>;
last(): any;
last(count: number): Sequence<T>;
lastIndexOf(value: any): Sequence<T>;
reverse(): Sequence<T>;
}
interface SequenceBaser<T> {
// TODO improve define() (needs ugly overload)
async(interval: number): AsyncSequence<T>;
chunk(size: number): Sequence<T>;
compact(): Sequence<T>;
concat(var_args: T[]): Sequence<T>;
concat(sequence: Sequence<T>): Sequence<T>;
consecutive(length: number): Sequence<T>;
contains(value: T): boolean;
countBy(keyFn: GetKeyCallback<T>): ObjectLikeSequence<T>;
countBy(propertyName: string): ObjectLikeSequence<T>;
dropWhile(predicateFn: TestCallback<T>): Sequence<T>;
every(predicateFn: TestCallback<T>): boolean;
filter(predicateFn: TestCallback<T>): Sequence<T>;
find(predicateFn: TestCallback<T>): Sequence<T>;
findWhere(properties: Object): Sequence<T>;
groupBy(keyFn: GetKeyCallback<T>): ObjectLikeSequence<T>;
initial(count?: number): Sequence<T>;
intersection(var_args: T[]): Sequence<T>;
invoke(methodName: string): Sequence<T>;
isEmpty(): boolean;
join(delimiter?: string): string;
map<U>(mapFn: MapCallback<T, U[]>): ArraySequence<U>;
map<U>(mapFn: MapCallback<T, U>): Sequence<U>;
max(valueFn?: NumberCallback<T>): T;
min(valueFn?: NumberCallback<T>): T;
none(valueFn?: TestCallback<T>): boolean;
pluck(propertyName: string): Sequence<T>;
reduce<U>(aggregatorFn: MemoCallback<T, U>, memo?: U): U;
reduceRight<U>(aggregatorFn: MemoCallback<T, U>, memo: U): U;
reject(predicateFn: TestCallback<T>): Sequence<T>;
rest(count?: number): Sequence<T>;
shuffle(): Sequence<T>;
some(predicateFn?: TestCallback<T>): boolean;
sort(sortFn?: CompareCallback, descending?: boolean): Sequence<T>;
sortBy(sortFn: string, descending?: boolean): Sequence<T>;
sortBy(sortFn: NumberCallback<T>, descending?: boolean): Sequence<T>;
sortedIndex(value: T): Sequence<T>;
size(): number;
sum(valueFn?: NumberCallback<T>): Sequence<T>;
takeWhile(predicateFn: TestCallback<T>): Sequence<T>;
union(var_args: T[]): Sequence<T>;
uniq(): Sequence<T>;
where(properties: Object): Sequence<T>;
without(...var_args: T[]): Sequence<T>;
without(var_args: T[]): Sequence<T>;
zip(var_args: T[]): ArraySequence<T>;
toArray(): T[];
toObject(): Object;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module ArrayLikeSequence {
function define(methodName: string[], overrides: Object): Function;
}
interface ArrayLikeSequence<T> extends Sequence<T> {
// define()X;
concat(var_args: T[]): ArrayLikeSequence<T>;
concat(sequence: Sequence<T>): Sequence<T>;
first(count?: number): ArrayLikeSequence<T>;
get(index: number): T;
length(): number;
map<U>(mapFn: MapCallback<T, U[]>): ArraySequence<U>;
map<U>(mapFn: MapCallback<T, U>): ArrayLikeSequence<U>;
pop(): ArrayLikeSequence<T>;
rest(count?: number): ArrayLikeSequence<T>;
reverse(): ArrayLikeSequence<T>;
shift(): ArrayLikeSequence<T>;
slice(begin: number, end?: number): ArrayLikeSequence<T>;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module ObjectLikeSequence {
function define(methodName: string[], overrides: Object): Function;
}
interface ObjectLikeSequence<T> extends Sequence<T> {
assign(other: Object): ObjectLikeSequence<T>;
// throws error
//async(): X;
defaults(defaults: Object): ObjectLikeSequence<T>;
functions(): Sequence<T>;
get(property: string): ObjectLikeSequence<T>;
invert(): ObjectLikeSequence<T>;
keys(): Sequence<string>;
omit(properties: string[]): ObjectLikeSequence<T>;
pairs(): Sequence<T>;
pick(properties: string[]): ObjectLikeSequence<T>;
toArray(): T[];
toObject(): Object;
values(): Sequence<T>;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module StringLikeSequence {
function define(methodName: string[], overrides: Object): Function;
}
interface StringLikeSequence extends SequenceBaser<string> {
charAt(index: number): string;
charCodeAt(index: number): number;
contains(value: string): boolean;
endsWith(suffix: string): boolean;
first(): string;
first(count: number): StringLikeSequence;
indexOf(substring: string, startIndex?: number): number;
last(): string;
last(count: number): StringLikeSequence;
lastIndexOf(substring: string, startIndex?: number): number;
mapString(mapFn: MapStringCallback): StringLikeSequence;
match(pattern: RegExp): StringLikeSequence;
reverse(): StringLikeSequence;
split(delimiter: string): StringLikeSequence;
split(delimiter: RegExp): StringLikeSequence;
startsWith(prefix: string): boolean;
substring(start: number, stop?: number): StringLikeSequence;
toLowerCase(): StringLikeSequence;
toUpperCase(): StringLikeSequence;
}
}
declare module 'lazy.js' {
export = Lazy;
}

18296
build/lib/typings/lib.es6.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

1536
build/lib/typings/node.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4
build/lib/typings/object-assign.d.ts vendored Normal file
View File

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

90
build/lib/typings/source-map.d.ts vendored Normal file
View File

@ -0,0 +1,90 @@
// Type definitions for source-map v0.1.38
// Project: https://github.com/mozilla/source-map
// Definitions by: Morten Houston Ludvigsen <https://github.com/MortenHoustonLudvigsen>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module SourceMap {
interface StartOfSourceMap {
file?: string;
sourceRoot?: string;
}
interface RawSourceMap extends StartOfSourceMap {
version: string;
sources: Array<string>;
names: Array<string>;
sourcesContent?: string;
mappings: string;
}
interface Position {
line: number;
column: number;
}
interface MappedPosition extends Position {
source: string;
name?: string;
}
interface MappingItem {
source: string;
generatedLine: number;
generatedColumn: number;
originalLine: number;
originalColumn: number;
name: string;
}
interface Mapping {
generated: Position;
original: Position;
source: string;
name?: string;
}
interface CodeWithSourceMap {
code: string;
map: SourceMapGenerator;
}
class SourceMapConsumer {
public static GENERATED_ORDER: number;
public static ORIGINAL_ORDER: number;
constructor(rawSourceMap: RawSourceMap);
public originalPositionFor(generatedPosition: Position): MappedPosition;
public generatedPositionFor(originalPosition: MappedPosition): Position;
public sourceContentFor(source: string): string;
public eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void;
}
class SourceMapGenerator {
constructor(startOfSourceMap?: StartOfSourceMap);
public static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
public addMapping(mapping: Mapping): void;
public setSourceContent(sourceFile: string, sourceContent: string): void;
public applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void;
public toString(): string;
}
class SourceNode {
constructor();
constructor(line: number, column: number, source: string);
constructor(line: number, column: number, source: string, chunk?: string, name?: string);
public static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode;
public add(chunk: string): void;
public prepend(chunk: string): void;
public setSourceContent(sourceFile: string, sourceContent: string): void;
public walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
public walkSourceContents(fn: (file: string, content: string) => void): void;
public join(sep: string): SourceNode;
public replaceRight(pattern: string, replacement: string): SourceNode;
public toString(): string;
public toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
}
}
declare module 'source-map' {
export = SourceMap;
}

22
build/lib/typings/through.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
// Type definitions for through
// Project: https://github.com/dominictarr/through
// Definitions by: Andrew Gaspar <https://github.com/AndrewGaspar/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module "through" {
import stream = require("stream");
function through(write?: (data:any) => void,
end?: () => void,
opts?: {
autoDestroy: boolean;
}): through.ThroughStream;
module through {
export interface ThroughStream extends stream.Transform {
autoDestroy: boolean;
}
}
export = through;
}

98
build/lib/typings/vinyl.d.ts vendored Normal file
View File

@ -0,0 +1,98 @@
// Type definitions for vinyl 0.4.3
// Project: https://github.com/wearefractal/vinyl
// Definitions by: vvakame <https://github.com/vvakame/>, jedmao <https://github.com/jedmao>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module 'vinyl' {
import fs = require('fs');
/**
* A virtual file format.
*/
class File {
constructor(options?: {
/**
* Default: process.cwd()
*/
cwd?: string;
/**
* Used for relative pathing. Typically where a glob starts.
*/
base?: string;
/**
* Full path to the file.
*/
path?: string;
/**
* Type: Buffer|Stream|null (Default: null)
*/
contents?: any;
});
/**
* Default: process.cwd()
*/
public cwd: string;
/**
* Used for relative pathing. Typically where a glob starts.
*/
public base: string;
/**
* Full path to the file.
*/
public path: string;
public stat: fs.Stats;
/**
* Type: Buffer|Stream|null (Default: null)
*/
public contents: any;
/**
* Returns path.relative for the file base and file path.
* Example:
* var file = new File({
* cwd: "/",
* base: "/test/",
* path: "/test/file.js"
* });
* console.log(file.relative); // file.js
*/
public relative: string;
public isBuffer(): boolean;
public isStream(): boolean;
public isNull(): boolean;
public isDirectory(): boolean;
/**
* Returns a new File object with all attributes cloned. Custom attributes are deep-cloned.
*/
public clone(opts?: { contents?: boolean }): File;
/**
* If file.contents is a Buffer, it will write it to the stream.
* If file.contents is a Stream, it will pipe it to the stream.
* If file.contents is null, it will do nothing.
*/
public pipe<T extends NodeJS.ReadWriteStream>(
stream: T,
opts?: {
/**
* If false, the destination stream will not be ended (same as node core).
*/
end?: boolean;
}
): T;
/**
* Returns a pretty String interpretation of the File. Useful for console.log.
*/
public inspect(): string;
}
export = File;
}

278
build/lib/util.js Normal file
View File

@ -0,0 +1,278 @@
var es = require('event-stream');
var debounce = require('debounce');
var filter = require('gulp-filter');
var azure = require('gulp-azure-storage');
var rename = require('gulp-rename');
var vzip = require('gulp-vinyl-zip');
var util = require('gulp-util');
var remote = require('gulp-remote-src');
var _ = require('underscore');
var path = require('path');
var fs = require('fs');
var rimraf = require('rimraf');
var NoCancellationToken = {
isCancellationRequested: function () {
return false;
}
};
exports.incremental = function (streamProvider, initial, supportsCancellation) {
var state = 'idle';
var input = es.through();
var output = es.through();
var buffer = Object.create(null);
var token = !supportsCancellation ? null : {
isCancellationRequested: function () {
// console.log('isCancellationRequested', Object.keys(buffer).length, new Date());
return Object.keys(buffer).length > 0;
}
};
var run = function (input, isCancellable) {
state = 'running';
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
input
.pipe(stream)
.pipe(es.through(null, function () {
state = 'idle';
eventuallyRun();
}))
.pipe(output);
};
if (initial) {
run(initial, false);
}
var eventuallyRun = debounce(function () {
var paths = Object.keys(buffer);
if (paths.length === 0) {
return;
}
var data = paths.map(function (path) {
return buffer[path];
});
buffer = Object.create(null);
run(es.readArray(data), true);
}, 500);
input.on('data', function (f) {
buffer[f.path] = f;
if (state === 'idle') {
eventuallyRun();
}
});
return es.duplex(input, output);
};
exports.fixWin32DirectoryPermissions = function () {
if (!/win32/.test(process.platform)) {
return es.through();
}
return es.mapSync(function (f) {
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
f.stat.mode = 16877;
}
return f;
});
};
exports.setExecutableBit = function (pattern) {
var setBit = es.mapSync(function (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
.pipe(_filter)
.pipe(setBit)
.pipe(_filter.restore);
return es.duplex(input, output);
};
exports.handleAzureJson = function (env) {
var input = es.through();
var azureJsonFilter = filter('**/*.azure.json', { restore: true });
var allOpts = [];
var result = es.through();
var output = input
.pipe(azureJsonFilter)
.pipe(es.through(function (f) {
util.log('Downloading binaries from Azure:', util.colors.yellow(f.relative), '...');
var opts = JSON.parse(f.contents.toString());
opts.prefix = _.template(opts.zip || opts.prefix)(env);
opts.output = path.join(path.dirname(f.relative), opts.output);
allOpts.push(opts);
}, function () {
var streams = allOpts.map(function (opts) {
var result = azure.download(_.extend(opts, { buffer: true, quiet: true }));
if (opts.zip) {
result = result.pipe(vzip.src());
}
return result.pipe(rename(function (p) {
p.dirname = path.join(opts.output, p.dirname);
}));
});
es.merge(streams)
.pipe(result)
.pipe(es.through(null, function() {
util.log('Finished downloading from Azure');
this.emit('end');
}));
this.emit('end');
}))
.pipe(azureJsonFilter.restore);
return es.duplex(input, es.merge(output, result));
};
exports.toFileUri = function (filePath) {
var match = filePath.match(/^([a-z])\:(.*)$/i);
if (match) {
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
}
return 'file://' + filePath.replace(/\\/g, '/');
};
exports.rebase = function (base, append) {
return es.mapSync(function (f) {
if (append) {
f.base = path.join(f.base, base);
} else {
f.base = base;
}
return f;
});
};
exports.skipDirectories = function () {
return es.mapSync(function (f) {
if (!f.isDirectory()) {
return f;
}
});
};
exports.cleanNodeModule = function (name, excludes, isNative) {
var glob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
var negate = function (str) { return '!' + str; };
var allFilter = filter(glob('**'), { restore: true });
var globs = [glob('**')].concat(excludes.map(_.compose(negate, glob)));
var input = es.through();
var nodeModuleInput = input.pipe(allFilter);
var output = nodeModuleInput.pipe(filter(globs));
if (isNative) {
output = es.merge(output, nodeModuleInput.pipe(filter(glob('**/*.node'))));
}
output = output.pipe(allFilter.restore);
return es.duplex(input, output);
};
exports.loadSourcemaps = function () {
var input = es.through();
var output = input
.pipe(es.map(function (f, cb) {
if (f.sourceMap) {
return cb(null, f);
}
if (!f.contents) {
return cb(new Error('empty file'));
}
var contents = f.contents.toString('utf8');
var reg = /\/\/# sourceMappingURL=(.*)$/g;
var lastMatch = null;
var match = null;
while (match = reg.exec(contents)) {
lastMatch = match;
}
if (!lastMatch) {
f.sourceMap = {
version : 3,
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sourcesContent: [contents]
};
return cb(null, f);
}
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
if (err) { return cb(err); }
f.sourceMap = JSON.parse(contents);
cb(null, f);
});
}));
return es.duplex(input, output);
};
exports.rimraf = function(dir) {
return function (cb) {
rimraf(dir, cb);
};
};
exports.downloadExtensions = function(extensions) {
var streams = Object.keys(extensions).map(function (fullName) {
var version = extensions[fullName];
var match = /^([^.]+)\.([^.]+)$/.exec(fullName);
if (!match) {
throw new Error('Bad extension: ' + fullName);
}
var publisher = match[1];
var name = match[2];
var url = 'https://' + publisher + '.gallery.vsassets.io/_apis/public/gallery/publisher/'
+ publisher + '/extension/' + name + '/' + version
+ '/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage';
return remote(url, { base: '' })
.pipe(vzip.src())
.pipe(filter('extension/**'))
.pipe(rename(function (p) {
p.dirname = path.posix.join(fullName, p.dirname.replace(/^extension[/\\]?/, ''));
}));
});
return es.merge(streams);
};

24
build/lib/watch/index.js Normal file
View File

@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var es = require('event-stream');
function handleDeletions() {
return es.mapSync(function (f) {
if (!f.contents) {
f.contents = new Buffer('');
f.stat = { mtime: new Date() };
}
return f;
});
}
var watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch');
module.exports = function () {
return watch.apply(null, arguments)
.pipe(handleDeletions());
};

View File

@ -0,0 +1,10 @@
{
"name": "watch",
"version": "1.0.0",
"description": "",
"author": "Microsoft ",
"private": true,
"devDependencies": {
"gulp-watch": "^4.3.5"
}
}

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var path = require('path');
var cp = require('child_process');
var fs = require('fs');
var File = require('vinyl');
var es = require('event-stream');
var filter = require('gulp-filter');
var watcherPath = path.join(__dirname, 'watcher.exe');
function toChangeType(type) {
switch (type) {
case '0': return 'change';
case '1': return 'add';
default: return 'unlink';
}
}
function watch(root) {
var result = es.through();
var child = cp.spawn(watcherPath, [root]);
child.stdout.on('data', function(data) {
var lines = data.toString('utf8').split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line.length === 0) {
continue;
}
var changeType = line[0];
var changePath = line.substr(2);
var changePathFull = path.join(root, changePath);
var file = new File({
path: changePathFull,
base: root
});
file.event = toChangeType(changeType);
result.emit('data', file);
}
});
child.stderr.on('data', function(data) {
result.emit('error', data);
});
child.on('exit', function(code) {
result.emit('error', 'Watcher died with code ' + code);
child = null;
});
process.once('SIGTERM', function () { process.exit(0); });
process.once('SIGTERM', function () { process.exit(0); });
process.once('exit', function () { child && child.kill(); });
return result;
}
var cache = Object.create(null);
module.exports = function(pattern, options) {
options = options || {};
var cwd = path.normalize(options.cwd || process.cwd());
var watcher = cache[cwd];
if (!watcher) {
watcher = cache[cwd] = watch(cwd);
}
var rebase = !options.base ? es.through() : es.mapSync(function (f) {
f.base = options.base;
return f;
});
return watcher
.pipe(filter(['**', '!.git{,/**}'])) // ignore all things git
.pipe(filter(pattern))
.pipe(es.map(function (file, cb) {
fs.stat(file.path, function (err, stat) {
if (err && err.code === 'ENOENT') { return cb(null, file); }
if (err) { return cb(); }
if (!stat.isFile()) { return cb(); }
fs.readFile(file.path, function (err, contents) {
if (err && err.code === 'ENOENT') { return cb(null, file); }
if (err) { return cb(); }
file.contents = contents;
file.stat = stat;
cb(null, file);
});
});
}))
.pipe(rebase);
};

BIN
build/lib/watch/watcher.exe Normal file

Binary file not shown.

12
build/tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": false,
"removeComments": false,
"preserveConstEnums": true,
"target": "ES5",
"sourceMap": false,
"experimentalDecorators": true,
"noLib": true
}
}

View File

@ -0,0 +1,22 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "sublimehq/Packages",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/sublimehq/Packages",
"licenseDetail": [
"Copyright (c) Sublime Packages project authors",
"",
"If not otherwise specified (see below), files in this folder fall under the following license: ",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information, ",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added ",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example ",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
}]

View File

@ -0,0 +1,10 @@
{
"comments": {
"lineComment": "REM"
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,19 @@
{
"name": "bat",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "bat",
"extensions": [ ".bat", ".cmd"],
"aliases": [ "Batch", "bat" ],
"configuration": "./bat.configuration.json"
}],
"grammars": [{
"language": "bat",
"scopeName": "source.dosbatch",
"path": "./syntaxes/Batch File.tmLanguage"
}]
}
}

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>uuid</key>
<string>E07EC438-7B75-4437-8AA1-DA94C1E6EACC</string>
<key>patterns</key>
<array>
<dict>
<key>name</key>
<string>keyword.command.dosbatch</string>
<key>match</key>
<string>\b(?i)(?:append|assoc|at|attrib|break|cacls|cd|chcp|chdir|chkdsk|chkntfs|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskcomp|diskcopy|doskey|echo|endlocal|erase|fc|find|findstr|format|ftype|graftabl|help|keyb|label|md|mkdir|mode|more|move|path|pause|popd|print|prompt|pushd|rd|recover|rem|ren|rename|replace|restore|rmdir|set|setlocal|shift|sort|start|subst|time|title|tree|type|ver|verify|vol|xcopy)\b</string>
</dict>
<dict>
<key>name</key>
<string>keyword.control.statement.dosbatch</string>
<key>match</key>
<string>\b(?i)(?:goto|call|exit)\b</string>
</dict>
<dict>
<key>name</key>
<string>keyword.control.conditional.if.dosbatch</string>
<key>match</key>
<string>\b(?i)if\s+((not)\s+)(exist|defined|errorlevel|cmdextversion)\b</string>
</dict>
<dict>
<key>name</key>
<string>keyword.control.conditional.dosbatch</string>
<key>match</key>
<string>\b(?i)(?:if|else)\b</string>
</dict>
<dict>
<key>name</key>
<string>keyword.control.repeat.dosbatch</string>
<key>match</key>
<string>\b(?i)for\b</string>
</dict>
<dict>
<key>name</key>
<string>keyword.operator.dosbatch</string>
<key>match</key>
<string>\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\b</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.command.rem.dosbatch</string>
</dict>
</dict>
<key>name</key>
<string>comment.line.rem.dosbatch</string>
<key>match</key>
<string>(?:^|\s)((?i)rem)(?:$|\s.*$)</string>
</dict>
<dict>
<key>name</key>
<string>comment.line.colons.dosbatch</string>
<key>match</key>
<string>\s*:\s*:.*$</string>
</dict>
<dict>
<key>begin</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.shell</string>
</dict>
</dict>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.shell</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.dosbatch</string>
<key>end</key>
<string>"</string>
</dict>
<dict>
<key>name</key>
<string>keyword.operator.pipe.dosbatch</string>
<key>match</key>
<string>[|]</string>
</dict>
<dict>
<key>name</key>
<string>keyword.operator.redirect.shell</string>
<key>match</key>
<string>&amp;&gt;|\d*&gt;&amp;\d*|\d*(&gt;&gt;|&gt;|&lt;)|\d*&lt;&amp;|\d*&lt;&gt;</string>
</dict>
</array>
<key>name</key>
<string>Batch File</string>
<key>scopeName</key>
<string>source.dosbatch</string>
<key>fileTypes</key>
<array>
<string>bat</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "mmcgrana/textmate-clojure",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/mmcgrana/textmate-clojure"
}]

View File

@ -0,0 +1,11 @@
{
"comments": {
"lineComment": ";",
"blockComment": [ "(comment", ")" ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,19 @@
{
"name": "clojure",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "clojure",
"aliases": ["Clojure", "clojure"],
"extensions": [".clj", ".cljs", ".cljx", ".clojure", ".edn"],
"configuration": "./clojure.configuration.json"
}],
"grammars": [{
"language": "clojure",
"scopeName": "source.clojure",
"path": "./syntaxes/Clojure.tmLanguage"
}]
}
}

View File

@ -0,0 +1,440 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>clj</string>
<string>cljs</string>
<string>clojure</string>
</array>
<key>foldingStartMarker</key>
<string>\(\s*$</string>
<key>foldingStopMarker</key>
<string>^\s*\)</string>
<key>keyEquivalent</key>
<string>^~C</string>
<key>name</key>
<string>Clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#comment</string>
</dict>
<dict>
<key>include</key>
<string>#shebang-comment</string>
</dict>
<dict>
<key>include</key>
<string>#qouted-sexp</string>
</dict>
<dict>
<key>include</key>
<string>#sexp</string>
</dict>
<dict>
<key>include</key>
<string>#keyfn</string>
</dict>
<dict>
<key>include</key>
<string>#string</string>
</dict>
<dict>
<key>include</key>
<string>#vector</string>
</dict>
<dict>
<key>include</key>
<string>#set</string>
</dict>
<dict>
<key>include</key>
<string>#map</string>
</dict>
<dict>
<key>include</key>
<string>#regexp</string>
</dict>
<dict>
<key>include</key>
<string>#var</string>
</dict>
<dict>
<key>include</key>
<string>#constants</string>
</dict>
<dict>
<key>include</key>
<string>#symbol</string>
</dict>
<dict>
<key>include</key>
<string>#whitespace</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>comment</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.clojure</string>
</dict>
</dict>
<key>match</key>
<string>(;).*$\n?</string>
<key>name</key>
<string>comment.line.semicolon.clojure</string>
</dict>
<key>constants</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(nil)(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>constant.language.nil.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(true|false)</string>
<key>name</key>
<string>constant.language.boolean.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+/\d+)</string>
<key>name</key>
<string>constant.numeric.ratio.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+r\d+)</string>
<key>name</key>
<string>constant.numeric.arbitrary-radix.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(0x\d+)</string>
<key>name</key>
<string>constant.numeric.hexidecimal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(0\d+)</string>
<key>name</key>
<string>constant.numeric.octal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(\d+)</string>
<key>name</key>
<string>constant.numeric.decimal.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{)):[a-zA-Z0-9\#\.\-\_\:\+\=\&gt;\&lt;\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>constant.keyword.clojure</string>
</dict>
</array>
</dict>
<key>keyfn</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{))(if(-[-a-z\?]*)?|when(-[-a-z]*)?|for(-[-a-z]*)?|cond|do|let(-[-a-z\?]*)?|binding|loop|recur|fn|throw[a-z\-]*|try|catch|finally|([a-z]*case))(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>storage.control.clojure</string>
</dict>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{))(declare-?|(in-)?ns|import|use|require|load|compile|(def[a-z\-]*))(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>keyword.control.clojure</string>
</dict>
</array>
</dict>
<key>map</key>
<dict>
<key>begin</key>
<string>(\{)</string>
<key>end</key>
<string>(\})</string>
<key>name</key>
<string>meta.map.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>qouted-sexp</key>
<dict>
<key>begin</key>
<string>(['``]\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(\))(\n)?</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.end.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>meta.after-expression.clojure</string>
</dict>
</dict>
<key>name</key>
<string>meta.qouted-expression.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>regexp</key>
<dict>
<key>begin</key>
<string>#\"</string>
<key>end</key>
<string>\"</string>
<key>name</key>
<string>string.regexp.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#regexp_escaped_char</string>
</dict>
</array>
</dict>
<key>regexp_escaped_char</key>
<dict>
<key>match</key>
<string>\\(\")</string>
<key>name</key>
<string>string.regexp.clojure</string>
</dict>
<key>set</key>
<dict>
<key>begin</key>
<string>(\#\{)</string>
<key>end</key>
<string>(\})</string>
<key>name</key>
<string>meta.set.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>sexp</key>
<dict>
<key>begin</key>
<string>(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(\))(\n)?</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.expression.end.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>meta.after-expression.clojure</string>
</dict>
</dict>
<key>name</key>
<string>meta.expression.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(?&lt;=\()(ns|def|def-|defn|defn-|defvar|defvar-|defmacro|defmacro-|deftest)\s+(.+?)(?=\s)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.clojure</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.global.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(?=\))</string>
<key>name</key>
<string>meta.definition.global.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>shebang-comment</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.shebang.clojure</string>
</dict>
</dict>
<key>match</key>
<string>^(\#!).*$\n?</string>
<key>name</key>
<string>comment.line.semicolon.clojure</string>
</dict>
<key>string</key>
<dict>
<key>begin</key>
<string>(")</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.clojure</string>
</dict>
</dict>
<key>end</key>
<string>(")</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.clojure</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escape.clojure</string>
</dict>
</array>
</dict>
<key>symbol</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(\w[\w\d]+)</string>
<key>name</key>
<string>meta.symbol.clojure</string>
</dict>
</array>
</dict>
<key>var</key>
<dict>
<key>match</key>
<string>(?&lt;=(\s|\(|\[|\{)\#)'[a-zA-Z0-9\.\-\_\:\+\=\&gt;\&lt;\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
<key>name</key>
<string>meta.var.clojure</string>
</dict>
<key>vector</key>
<dict>
<key>begin</key>
<string>(\[)</string>
<key>end</key>
<string>(\])</string>
<key>name</key>
<string>meta.vector.clojure</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>whitespace</key>
<dict>
<key>match</key>
<string>\s+$</string>
<key>name</key>
<string>invalid.trailing-whitespace</string>
</dict>
</dict>
<key>scopeName</key>
<string>source.clojure</string>
<key>smartTypingPairs</key>
<array>
<array>
<string>"</string>
<string>"</string>
</array>
<array>
<string>(</string>
<string>)</string>
</array>
<array>
<string>{</string>
<string>}</string>
</array>
<array>
<string>[</string>
<string>]</string>
</array>
</array>
<key>uuid</key>
<string>6A87759F-F746-4E84-B788-965B46363202</string>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "textmate/coffee-script.tmbundle",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/textmate/coffee-script.tmbundle"
}]

View File

@ -0,0 +1,11 @@
{
"comments": {
"lineComment": "#",
"blockComment": [ "###", "###" ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,23 @@
{
"name": "coffeescript",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "coffeescript",
"extensions": [ ".coffee" ],
"aliases": [ "CoffeeScript", "coffeescript", "coffee" ],
"configuration": "./coffeescript.configuration.json"
}],
"grammars": [{
"language": "coffeescript",
"scopeName": "source.coffee",
"path": "./syntaxes/CoffeeScript.tmLanguage"
}],
"debuggers": [{
"type": "node",
"enableBreakpointsFor": { "languageIds": ["coffeescript"] }
}]
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "textmate/c.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/c.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-c.tmbundle authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
}]

View File

@ -0,0 +1,11 @@
{
"comments": {
"lineComment": "//",
"blockComment": ["/*", "*/"]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,30 @@
{
"name": "cpp",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "c",
"extensions": [ ".c", ".h" ],
"aliases": [ "C", "c" ],
"configuration": "./cpp.configuration.json"
},
{
"id": "cpp",
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx" ],
"aliases": [ "C++", "Cpp", "cpp"],
"configuration": "./cpp.configuration.json"
}],
"grammars": [{
"language": "c",
"scopeName": "source.c",
"path": "./syntaxes/c.plist"
},
{
"language": "cpp",
"scopeName": "source.c++",
"path": "./syntaxes/c++.plist"
}]
}
}

View File

@ -0,0 +1,582 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>comment</key>
<string>I don't think anyone uses .hp. .cp tends to be paired with .h. (I could be wrong. :) -- chris</string>
<key>fileTypes</key>
<array>
<string>cc</string>
<string>cpp</string>
<string>cp</string>
<string>cxx</string>
<string>c++</string>
<string>C</string>
<string>h</string>
<string>hh</string>
<string>hpp</string>
<string>h++</string>
</array>
<key>firstLineMatch</key>
<string>-\*- C\+\+ -\*-</string>
<key>keyEquivalent</key>
<string>^~C</string>
<key>name</key>
<string>C++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#special_block</string>
</dict>
<dict>
<key>include</key>
<string>source.c</string>
</dict>
<dict>
<key>match</key>
<string>\b(friend|explicit|virtual)\b</string>
<key>name</key>
<string>storage.modifier.$1.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(private|protected|public):</string>
<key>name</key>
<string>storage.modifier.$1.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(catch|operator|try|throw|using)\b</string>
<key>name</key>
<string>keyword.control.c++</string>
</dict>
<dict>
<key>match</key>
<string>\bdelete\b(\s*\[\])?|\bnew\b(?!])</string>
<key>name</key>
<string>keyword.control.c++</string>
</dict>
<dict>
<key>comment</key>
<string>common C++ instance var naming idiom -- fMemberName</string>
<key>match</key>
<string>\b(f|m)[A-Z]\w*\b</string>
<key>name</key>
<string>variable.other.readwrite.member.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(this|nullptr)\b</string>
<key>name</key>
<string>variable.language.c++</string>
</dict>
<dict>
<key>match</key>
<string>\btemplate\b\s*</string>
<key>name</key>
<string>storage.type.template.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(const_cast|dynamic_cast|reinterpret_cast|static_cast)\b\s*</string>
<key>name</key>
<string>keyword.operator.cast.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq)\b</string>
<key>name</key>
<string>keyword.operator.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(class|wchar_t)\b</string>
<key>name</key>
<string>storage.type.c++</string>
</dict>
<dict>
<key>match</key>
<string>\b(constexpr|export|mutable|typename|thread_local)\b</string>
<key>name</key>
<string>storage.modifier.c++</string>
</dict>
<dict>
<key>begin</key>
<string>(?x)
(?: ^ # begin-of-line
| (?: (?&lt;!else|new|=) ) # or word + space before name
)
((?:[A-Za-z_][A-Za-z0-9_]*::)*+~[A-Za-z_][A-Za-z0-9_]*) # actual name
\s*(\() # start bracket or end-of-line
</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.name.function.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.begin.c</string>
</dict>
</dict>
<key>end</key>
<string>\)</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.end.c</string>
</dict>
</dict>
<key>name</key>
<string>meta.function.destructor.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(?x)
(?: ^ # begin-of-line
| (?: (?&lt;!else|new|=) ) # or word + space before name
)
((?:[A-Za-z_][A-Za-z0-9_]*::)*+~[A-Za-z_][A-Za-z0-9_]*) # actual name
\s*(\() # terminating semi-colon
</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.name.function.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.begin.c</string>
</dict>
</dict>
<key>end</key>
<string>\)</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.end.c</string>
</dict>
</dict>
<key>name</key>
<string>meta.function.destructor.prototype.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
</array>
<key>repository</key>
<dict>
<key>angle_brackets</key>
<dict>
<key>begin</key>
<string>&lt;</string>
<key>end</key>
<string>&gt;</string>
<key>name</key>
<string>meta.angle-brackets.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#angle_brackets</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<key>block</key>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.block.begin.c</string>
</dict>
</dict>
<key>end</key>
<string>\}</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.block.end.c</string>
</dict>
</dict>
<key>name</key>
<string>meta.block.c++</string>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.any-method.c</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.c</string>
</dict>
</dict>
<key>match</key>
<string>(?x)
(
(?!while|for|do|if|else|switch|catch|enumerate|return|r?iterate)(?: \b[A-Za-z_][A-Za-z0-9_]*+\b | :: )*+ # actual name
)
\s*(\()</string>
<key>name</key>
<string>meta.function-call.c</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<key>constructor</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(?x)
(?: ^\s*) # begin-of-line
((?!while|for|do|if|else|switch|catch|enumerate|r?iterate)[A-Za-z_][A-Za-z0-9_:]*) # actual name
\s*(\() # start bracket or end-of-line
</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.name.function.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.begin.c</string>
</dict>
</dict>
<key>end</key>
<string>\)</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.end.c</string>
</dict>
</dict>
<key>name</key>
<string>meta.function.constructor.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(?x)
(:) # begin-of-line
((?=\s*[A-Za-z_][A-Za-z0-9_:]* # actual name
\s*(\())) # start bracket or end-of-line
</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.c</string>
</dict>
</dict>
<key>end</key>
<string>(?=\{)</string>
<key>name</key>
<string>meta.function.constructor.initializer-list.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
</array>
</dict>
<key>special_block</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>\b(namespace)\b\s*([_A-Za-z][_A-Za-z0-9]*\b)?+</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.type.c++</string>
</dict>
</dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.namespace.$2</string>
</dict>
</dict>
<key>end</key>
<string>(?&lt;=\})|(?=(;|,|\(|\)|&gt;|\[|\]|=))</string>
<key>name</key>
<string>meta.namespace-block${2:+.$2}.c++</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.scope.c++</string>
</dict>
</dict>
<key>end</key>
<string>\}</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.scope.c++</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#special_block</string>
</dict>
<dict>
<key>include</key>
<string>#constructor</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>\b(class|struct)\b\s*([_A-Za-z][_A-Za-z0-9]*\b)?+(\s*:\s*(public|protected|private)\s*([_A-Za-z][_A-Za-z0-9]*\b)((\s*,\s*(public|protected|private)\s*[_A-Za-z][_A-Za-z0-9]*\b)*))?</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.type.c++</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>storage.type.modifier.c++</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>entity.name.type.inherited.c++</string>
</dict>
<key>6</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(public|protected|private)</string>
<key>name</key>
<string>storage.type.modifier.c++</string>
</dict>
<dict>
<key>match</key>
<string>[_A-Za-z][_A-Za-z0-9]*</string>
<key>name</key>
<string>entity.name.type.inherited.c++</string>
</dict>
</array>
</dict>
</dict>
<key>end</key>
<string>(?&lt;=\})|(?=(;|\(|\)|&gt;|\[|\]|=))</string>
<key>name</key>
<string>meta.class-struct-block.c++</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#angle_brackets</string>
</dict>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.block.begin.c++</string>
</dict>
</dict>
<key>end</key>
<string>(\})(\s*\n)?</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.invalid.c++</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>invalid.illegal.you-forgot-semicolon.c++</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#special_block</string>
</dict>
<dict>
<key>include</key>
<string>#constructor</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>\b(extern)(?=\s*")</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.modifier.c++</string>
</dict>
</dict>
<key>end</key>
<string>(?&lt;=\})|(?=\w)</string>
<key>name</key>
<string>meta.extern-block.c++</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.block.begin.c</string>
</dict>
</dict>
<key>end</key>
<string>\}</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.block.end.c</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#special_block</string>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>$base</string>
</dict>
</array>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>source.c++</string>
<key>uuid</key>
<string>26251B18-6B1D-11D9-AFDB-000D93589AF6</string>
</dict>
</plist>

File diff suppressed because it is too large Load Diff

1
extensions/csharp-o/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
bin

View File

@ -0,0 +1,29 @@
[
{
"name": "Omnisharp-roslyn",
"repositoryURL": "https://github.com/OmniSharp/omnisharp-roslyn",
"version": "1.5.5",
"license": "MIT",
"isProd": true
},
{
"name": "ScriptCS",
"repositoryURL": "https://github.com/scriptcs/scriptcs",
"version": "0.16.0",
"license": "Apache2",
"licenseDetail": [
"Copyright 2013 Glenn Block, Justin Rusbatch, Filip Wojcieszyn",
"",
"Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file ",
"except in compliance with the License. You may obtain a copy of the License at",
"",
"http://www.apache.org/licenses/LICENSE-2.0",
"",
"Unless required by applicable law or agreed to in writing, software distributed under the ",
"License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, ",
"either express or implied. See the License for the specific language governing permissions ",
"and limitations under the License."
],
"isProd": true
}
]

View File

@ -0,0 +1,55 @@
var gulp = require('gulp');
var decompress = require('gulp-decompress');
var download = require('gulp-download');
var del = require('del');
var fs = require('fs');
var join = require('path').join;
gulp.task('omnisharp:clean', function () {
return del('bin');
});
gulp.task('omnisharp:fetch', ['omnisharp:clean'], function () {
var release = 'https://github.com/OmniSharp/omnisharp-roslyn/releases/download/v1.5.6/omnisharp.tar.gz';
return download(release)
.pipe(decompress({strip: 1}))
.pipe(gulp.dest('bin'))
});
gulp.task('omnisharp:fixscripts', ['omnisharp:fetch'], function () {
var _fixes = Object.create(null);
_fixes['./bin/omnisharp.cmd'] = '@"%~dp0packages\\dnx-clr-win-x86.1.0.0-beta4\\bin\\dnx.exe" "%~dp0packages\\OmniSharp\\1.0.0\\root" run %*';
_fixes['./bin/omnisharp'] = '#!/bin/bash\n\
SOURCE="${BASH_SOURCE[0]}"\n\
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink\n\
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"\n\
SOURCE="$(readlink "$SOURCE")"\n\
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located\n\
done\n\
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"\n\
export SET DNX_APPBASE="$DIR/packages/OmniSharp/1.0.0/root"\n\
export PATH=/usr/local/bin:/Library/Frameworks/Mono.framework/Commands:$PATH # this is required for the users of the Homebrew Mono package\n\
exec "$DIR/packages/dnx-mono.1.0.0-beta4/bin/dnx" "$DNX_APPBASE" run "$@"\n\
\n';
var promises = Object.keys(_fixes).map(function (key) {
return new Promise(function(resolve, reject) {
fs.writeFile(join(__dirname, key), _fixes[key], function (err) {
if (err) {
reject(err);
} else {
resolve();
}
})
});
});
return Promise.all(promises)
});
gulp.task('omnisharp', ['omnisharp:fixscripts']);

View File

@ -0,0 +1,100 @@
{
"name": "csharp-o",
"version": "0.1.0",
"publisher": "vscode",
"engines": {
"vscode": "*"
},
"activationEvents": [
"onLanguage:csharp",
"onCommand:o.restart",
"onCommand:o.pickProjectAndStart",
"onCommand:o.restore",
"onCommand:o.execute",
"onCommand:o.showOutput",
"onCommand:o.execute",
"onCommand:o.execute-last-command"
],
"main": "./out/omnisharpMain",
"scripts": {
"postinstall": "gulp omnisharp",
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../gulpfile.plugins.js compile-plugin:csharp-o ./tsconfig.json"
},
"dependencies": {
"applicationinsights": "0.15.6",
"run-in-terminal": "*",
"semver": "*"
},
"devDependencies": {
"del": "^2.0.2",
"gulp": "^3.8.9",
"gulp-decompress": "^1.2.0",
"gulp-download": "^0.0.1",
"typescript": "^1.6.2"
},
"extensionDependencies": [
"vscode.csharp"
],
"contributes": {
"commands": [
{
"command": "o.restart",
"title": "Restart OmniSharp",
"category": "OmniSharp"
},
{
"command": "o.pickProjectAndStart",
"title": "Select Project",
"category": "OmniSharp"
},
{
"command": "o.restore",
"title": "Restore Packages",
"category": "dnx"
},
{
"command": "o.execute",
"title": "Run Command",
"category": "dnx"
}
],
"keybindings": [
{
"command": "o.showOutput",
"key": "Ctrl+L L",
"mac": "Cmd+L L"
},
{
"command": "o.execute",
"key": "Ctrl+L Shift+R",
"mac": "Cmd+L Shift+R"
},
{
"command": "o.execute-last-command",
"key": "Ctrl+L R",
"mac": "Cmd+L R"
},
{
"key": "shift+0",
"command": "^acceptSelectedSuggestion",
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
},
{
"key": "shift+9",
"command": "^acceptSelectedSuggestion",
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
},
{
"key": ".",
"command": "^acceptSelectedSuggestion",
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
}
],
"snippets": [
{
"language": "csharp",
"path": "./snippets/csharp.json"
}
]
}
}

View File

@ -0,0 +1,524 @@
{
"Attribute using recommended pattern": {
"prefix": "attribute",
"body": [
"[System.AttributeUsage(System.AttributeTargets.${All}, Inherited = ${false}, AllowMultiple = ${true})]",
"sealed class ${My}Attribute : System.Attribute",
"{",
" // See the attribute guidelines at",
" // http://go.microsoft.com/fwlink/?LinkId=85236",
" readonly string positionalString;",
" ",
" // This is a positional argument",
" public ${My}Attribute (string positionalString)",
" {",
" this.positionalString = positionalString;",
" ",
" // TODO: Implement code here",
" ${throw new System.NotImplementedException();}",
" }",
" ",
" public string PositionalString",
" {",
" get { return positionalString; }",
" }",
" ",
" // This is a named argument",
" public int NamedInt { get; set; }",
"}"
],
"description": "Attribute using recommended pattern"
},
"Checked block": {
"prefix": "checked",
"body": [
"checked",
"{",
" $0",
"}"
],
"description": "Checked block"
},
"Class": {
"prefix": "class",
"body": [
"class ${Name}",
"{",
" $0",
"}"
],
"description": "Class"
},
"Console.WriteLine": {
"prefix": "cw",
"body": [
"System.Console.WriteLine($0);"
],
"description": "Console.WriteLine"
},
"do...while loop": {
"prefix": "do",
"body": [
"do",
"{",
" $0",
"} while (${true});"
],
"description": "do...while loop"
},
"Else statement": {
"prefix": "else",
"body": [
"else",
"{",
" $0",
"}"
],
"description": "Else statement"
},
"Enum": {
"prefix": "enum",
"body": [
"enum ${Name}",
"{",
" $0",
"}"
],
"description": "Enum"
},
"Implementing Equals() according to guidelines": {
"prefix": "equals",
"body": [
"// override object.Equals",
"public override bool Equals (object obj)",
"{",
" //",
" // See the full list of guidelines at",
" // http://go.microsoft.com/fwlink/?LinkID=85237",
" // and also the guidance for operator== at",
" // http://go.microsoft.com/fwlink/?LinkId=85238",
" //",
" ",
" if (obj == null || GetType() != obj.GetType())",
" {",
" return false;",
" }",
" ",
" // TODO: write your implementation of Equals() here",
" ${1:throw new System.NotImplementedException();}",
" return base.Equals (obj);",
"}",
"",
"// override object.GetHashCode",
"public override int GetHashCode()",
"{",
" // TODO: write your implementation of GetHashCode() here",
" ${2:throw new System.NotImplementedException();}",
" return base.GetHashCode();",
"}"
],
"description": "Implementing Equals() according to guidelines"
},
"Exception": {
"prefix": "exception",
"body": [
"[System.Serializable]",
"public class ${My}Exception : ${System.Exception}",
"{",
" public ${My}Exception() { }",
" public ${My}Exception( string message ) : base( message ) { }",
" public ${My}Exception( string message, System.Exception inner ) : base( message, inner ) { }",
" protected ${My}Exception(",
" System.Runtime.Serialization.SerializationInfo info,",
" System.Runtime.Serialization.StreamingContext context ) : base( info, context ) { }",
"}"
],
"description": "Exception"
},
"Foreach statement": {
"prefix": "foreach",
"body": [
"foreach (${var} ${item} in ${collection})",
"{",
" $0",
"}"
],
"description": "Foreach statement"
},
"Reverse for loop": {
"prefix": "forr",
"body": [
"for (int ${i} = ${length} - 1; ${i} >= 0 ; ${i}--)",
"{",
" $0",
"}"
],
"description": "Reverse for loop"
},
"for loop": {
"prefix": "for",
"body": [
"for (int ${i} = 0; ${i} < ${length}; ${i}++)",
"{",
" $0",
"}"
],
"description": "for loop"
},
"if statement": {
"prefix": "if",
"body": [
"if (${true})",
"{",
" $0",
"}"
],
"description": "if statement"
},
"Indexer": {
"prefix": "indexer",
"body": [
"${public} ${object} this[${int} index]",
"{",
" get { $0 }",
" set { $1 }",
"}"
],
"description": "Indexer"
},
"Interface": {
"prefix": "interface",
"body": [
"interface I${Name}",
"{",
" $0",
"}"
],
"description": "Interface"
},
"Safely invoking an event": {
"prefix": "invoke",
"body": [
"${EventHandler} temp = ${MyEvent};",
"if (temp != null)",
"{",
" temp($0);",
"}"
],
"description": "Safely invoking an event"
},
"Simple iterator": {
"prefix": "iterator",
"body": [
"public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()",
"{",
" $0throw new System.NotImplementedException();",
" yield return default(${ElementType});",
"}"
],
"description": "Simple iterator"
},
"Named iterator/indexer pair using a nested class": {
"prefix": "iterindex",
"body": [
"public ${Name}Iterator ${Name}",
"{",
" get",
" {",
" return new ${Name}Iterator(this);",
" }",
"}",
"",
"public class ${Name}Iterator",
"{",
" readonly ${ClassName} outer;",
" ",
" internal ${Name}Iterator(${ClassName} outer)",
" {",
" this.outer = outer;",
" }",
" ",
" // TODO: provide an appropriate implementation here",
" public int Length { get { return 1; } }",
" ",
" public ${ElementType} this[int index]",
" {",
" get",
" {",
" //",
" // TODO: implement indexer here",
" //",
" // you have full access to ${ClassName} privates",
" //",
" ${throw new System.NotImplementedException();}",
" return default(${ElementType});",
" }",
" }",
" ",
" public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()",
" {",
" for (int i = 0; i < this.Length; i++)",
" {",
" yield return this[i];",
" }",
" }",
"}"
],
"description": "Named iterator/indexer pair using a nested class"
},
"Lock statement": {
"prefix": "lock",
"body": [
"lock (${this})",
"{",
" $0",
"}"
],
"description": "Lock statement"
},
"MessageBox.Show": {
"prefix": "mbox",
"body": [
"System.Windows.Forms.MessageBox.Show(\"${Text}\");$0"
],
"description": "MessageBox.Show"
},
"Namespace": {
"prefix": "namespace",
"body": [
"namespace ${Name}",
"{",
" $0",
"}"
],
"description": "Namespace"
},
"#if": {
"prefix": "ifd",
"body": [
"#if ${true}",
" $0",
"#endif"
],
"description": "#if"
},
"#region": {
"prefix": "region",
"body": [
"#region ${Name}",
" $0",
"#endregion"
],
"description": "#region"
},
"Property and backing field": {
"prefix": "propfull",
"body": [
"private ${int} ${myVar};",
"public ${int} ${MyProperty}",
"{",
" get { return ${myVar};}",
" set { ${myVar} = value;}",
"}",
"$0"
],
"description": "Property and backing field"
},
"propg": {
"prefix": "propg",
"body": [
"public ${int} ${MyProperty} { get; private set; }$0"
],
"description": "An automatically implemented property with a 'get' accessor and a private 'set' accessor. C# 3.0 or higher"
},
"prop": {
"prefix": "prop",
"body": [
"public ${int} ${MyProperty} { get; set; }$0"
],
"description": "An automatically implemented property. C# 3.0 or higher"
},
"sim": {
"prefix": "sim",
"body": [
"static int Main(string[] args)",
"{",
" $0",
" return 0;",
"}"
],
"description": "int Main()"
},
"Struct": {
"prefix": "struct",
"body": [
"struct ${Name}",
"{",
" $0",
"}"
],
"description": "Struct"
},
"svm": {
"prefix": "svm",
"body": [
"static void Main(string[] args)",
"{",
" $0",
"}"
],
"description": "void Main()"
},
"Switch statement": {
"prefix": "switch",
"body": [
"switch (${switch_on})",
"{",
" $0",
" default:",
"}"
],
"description": "Switch statement"
},
"Try finally": {
"prefix": "tryf",
"body": [
"try",
"{",
" ${_}",
"}",
"finally",
"{",
" $0",
"}"
],
"description": "Try finally"
},
"Try catch": {
"prefix": "try",
"body": [
"try",
"{",
" ${_}",
"}",
"catch (${System.Exception})",
"{",
" $0",
" throw;",
"}"
],
"description": "Try catch"
},
"Unchecked block": {
"prefix": "unchecked",
"body": [
"unchecked",
"{",
" $0",
"}"
],
"description": "Unchecked block"
},
"Unsafe statement": {
"prefix": "unsafe",
"body": [
"unsafe",
"{",
" $0",
"}"
],
"description": "Unsafe statement"
},
"Using statement": {
"prefix": "using",
"body": [
"using(${resource})",
"{",
" $0",
"}"
],
"description": "Using statement"
},
"While loop": {
"prefix": "while",
"body": [
"while (${true})",
"{",
" $0",
"}"
],
"description": "While loop"
}
}

View File

@ -0,0 +1,26 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {OmnisharpServer} from '../omnisharpServer';
import {Disposable} from 'vscode';
export default class AbstractProvider {
protected _server: OmnisharpServer;
protected _disposables: Disposable[];
constructor(server: OmnisharpServer) {
this._server = server;
this._disposables = [];
}
dispose() {
while (this._disposables.length) {
this._disposables.pop().dispose();
}
}
}

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {Disposable, Uri, workspace} from 'vscode';
import {OmnisharpServer} from '../omnisharpServer';
import * as proto from '../protocol';
function forwardDocumentChanges(server: OmnisharpServer): Disposable {
return workspace.onDidChangeTextDocument(event => {
let {document} = event;
if (document.isUntitled || document.languageId !== 'csharp') {
return;
}
if (!server.isRunning()) {
return;
}
server.makeRequest(proto.UpdateBuffer, <proto.Request>{
Buffer: document.getText(),
Filename: document.fileName
}).catch(err => {
console.error(err);
return err;
});
});
}
function forwardFileChanges(server: OmnisharpServer): Disposable {
function onFileSystemEvent(uri: Uri): void {
if (!server.isRunning()) {
return;
}
let req = { Filename: uri.fsPath };
server.makeRequest<boolean>(proto.FilesChanged, [req]).catch(err => {
console.warn('[o] failed to forward file change event for ' + uri.fsPath, err);
return err;
});
}
const watcher = workspace.createFileSystemWatcher('**/*.*');
let d1 = watcher.onDidCreate(onFileSystemEvent);
let d2 = watcher.onDidChange(onFileSystemEvent);
let d3 = watcher.onDidDelete(onFileSystemEvent);
return Disposable.from(watcher, d1, d2, d3);
}
export default function forwardChanges(server: OmnisharpServer): Disposable {
// combine file watching and text document watching
return Disposable.from(
forwardDocumentChanges(server),
forwardFileChanges(server));
}

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {CodeActionProvider, CodeActionContext, Command, CancellationToken, TextDocument, WorkspaceEdit, TextEdit, Range, Uri, workspace, commands} from 'vscode';
import {OmnisharpServer} from '../omnisharpServer';
import AbstractProvider from './abstractProvider';
import {TextChange, V2} from '../protocol';
import {toRange2} from '../typeConvertion';
export default class OmnisharpCodeActionProvider extends AbstractProvider implements CodeActionProvider {
private _disabled: boolean;
private _commandId: string;
constructor(server: OmnisharpServer) {
super(server);
this._commandId = 'omnisharp.runCodeAction';
this._updateEnablement();
let d1 = workspace.onDidChangeConfiguration(this._updateEnablement, this);
let d2 = commands.registerCommand(this._commandId, this._runCodeAction, this);
this._disposables.push(d1, d2);
}
private _updateEnablement(): void {
let value = workspace.getConfiguration().get('csharp.disableCodeActions', false);
this._disabled = value;
}
public provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): Promise<Command[]> {
if (this._disabled) {
return;
}
let req: V2.GetCodeActionsRequest = {
Filename: document.fileName,
Selection: OmnisharpCodeActionProvider._asRange(range)
}
return this._server.makeRequest<V2.GetCodeActionsResponse>(V2.GetCodeActions, req, token).then(response => {
return response.CodeActions.map(ca => {
return {
title: ca.Name,
command: this._commandId,
arguments: [ca.Identifier, document, range]
};
});
}, (error) => {
return Promise.reject('Problem invoking \'GetCodeActions\' on OmniSharp server: ' + error);
});
}
private _runCodeAction(id: string, document: TextDocument, range: Range): Promise<any> {
let req: V2.RunCodeActionRequest = {
Filename: document.fileName,
Selection: OmnisharpCodeActionProvider._asRange(range),
Identifier: id,
WantsTextChanges: true
};
return this._server.makeRequest<V2.RunCodeActionResponse>(V2.RunCodeAction, req).then(response => {
if (response && Array.isArray(response.Changes)) {
let edit = new WorkspaceEdit();
for (let change of response.Changes) {
let uri = Uri.file(change.FileName);
let edits: TextEdit[] = [];
for (let textChange of change.Changes) {
edits.push(TextEdit.replace(toRange2(textChange), textChange.NewText));
}
edit.set(uri, edits);
}
return workspace.applyEdit(edit);
}
}, (error) => {
return Promise.reject('Problem invoking \'RunCodeAction\' on OmniSharp server: ' + error);
});
}
private static _asRange(range: Range): V2.Range {
let {start, end} = range;
return {
Start: { Line: start.line + 1, Column: start.character + 1 },
End: { Line: end.line + 1, Column: end.character + 1 }
};
}
}

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {CancellationToken, CodeLens, SymbolKind, Range, Uri, TextDocument, CodeLensProvider, Position} from 'vscode';
import {createRequest, toRange, toLocation} from '../typeConvertion';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
class OmniSharpCodeLens extends CodeLens {
fileName: string;
constructor(fileName: string, range: Range) {
super(range);
this.fileName = fileName;
}
}
export default class OmniSharpCodeLensProvider extends AbstractSupport implements CodeLensProvider {
private static filteredSymbolNames: { [name: string]: boolean } = {
'Equals': true,
'Finalize': true,
'GetHashCode': true,
'ToString': true
};
provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
return this._server.makeRequest<proto.CurrentFileMembersAsTreeResponse>(proto.CurrentFileMembersAsTree, {
Filename: document.fileName
}, token).then(tree => {
var ret: CodeLens[] = [];
tree.TopLevelTypeDefinitions.forEach(node => OmniSharpCodeLensProvider._convertQuickFix(ret, document.fileName, node));
return ret;
});
}
private static _convertQuickFix(bucket: CodeLens[], fileName:string, node: proto.Node): void {
if (node.Kind === 'MethodDeclaration' && OmniSharpCodeLensProvider.filteredSymbolNames[node.Location.Text]) {
return;
}
let lens = new OmniSharpCodeLens(fileName, toRange(node.Location));
bucket.push(lens);
for (let child of node.ChildNodes) {
OmniSharpCodeLensProvider._convertQuickFix(bucket, fileName, child);
}
}
resolveCodeLens(codeLens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
if (codeLens instanceof OmniSharpCodeLens) {
let req = <proto.FindUsagesRequest>{
Filename: codeLens.fileName,
Line: codeLens.range.start.line + 1,
Column: codeLens.range.start.character + 1,
OnlyThisFile: false,
ExcludeDefinition: true
};
return this._server.makeRequest<proto.QuickFixResponse>(proto.FindUsages, req, token).then(res => {
if (!res || !Array.isArray(res.QuickFixes)) {
return;
}
let len = res.QuickFixes.length;
codeLens.command = {
title: len === 1 ? '1 reference' : `${len} references`,
command: 'editor.action.showReferences',
arguments: [Uri.file(req.Filename), codeLens.range.start, res.QuickFixes.map(toLocation)]
};
return codeLens;
});
}
}
}

View File

@ -0,0 +1,171 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as proto from '../protocol';
import {OmnisharpServer} from '../omnisharpServer';
import {Disposable, ViewColumn, commands, window} from 'vscode';
import {join, dirname, basename} from 'path';
import findLaunchTargets from '../launchTargetFinder';
import {runInTerminal} from 'run-in-terminal';
const isWin = /^win/.test(process.platform);
export default function registerCommands(server: OmnisharpServer) {
let d1 = commands.registerCommand('o.restart', () => server.restart());
let d2 = commands.registerCommand('o.pickProjectAndStart', () => pickProjectAndStart(server));
let d3 = commands.registerCommand('o.restore', () => dnxRestoreForAll(server));
let d4 = commands.registerCommand('o.execute', () => dnxExecuteCommand(server));
let d5 = commands.registerCommand('o.execute-last-command', () => dnxExecuteLastCommand(server));
let d6 = commands.registerCommand('o.showOutput', () => server.getChannel().show(ViewColumn.Three));
return Disposable.from(d1, d2, d3, d4, d5, d6);
}
function pickProjectAndStart(server: OmnisharpServer) {
return findLaunchTargets().then(targets => {
let currentPath = server.getSolutionPathOrFolder();
if (currentPath) {
for (let target of targets) {
if (target.target.fsPath === currentPath) {
target.label = `\u2713 ${target.label}`;
}
}
}
return window.showQuickPick(targets, {
matchOnDescription: true,
placeHolder: `Select 1 of ${targets.length} projects`
}).then(target => {
if (target) {
return server.restart(target.target.fsPath);
}
});
});
}
interface Command {
label: string;
description: string;
execute(): Thenable<any>;
}
let lastCommand: Command;
function dnxExecuteLastCommand(server: OmnisharpServer) {
if (lastCommand) {
lastCommand.execute();
} else {
dnxExecuteCommand(server);
}
}
function dnxExecuteCommand(server: OmnisharpServer) {
if (!server.isRunning()) {
return Promise.reject('OmniSharp server is not running.');
}
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
let commands: Command[] = [];
info.Dnx.Projects.forEach(project => {
Object.keys(project.Commands).forEach(key => {
commands.push({
label: `dnx ${key} - (${project.Name || basename(project.Path)})`,
description: dirname(project.Path),
execute() {
lastCommand = this;
let command = join(info.Dnx.RuntimePath, 'bin/dnx');
let args = [key];
// dnx-beta[1-6] needs a leading dot, like 'dnx . run'
if (/-beta[1-6]/.test(info.Dnx.RuntimePath)) {
args.unshift('.');
}
if (isWin) {
command += '.exe';
}
return runInTerminal(command, args, {
cwd: dirname(project.Path),
env: {
// KRE_COMPILATION_SERVER_PORT: workspace.DesignTimeHostPort
}
});
}
});
});
});
return window.showQuickPick(commands).then(command => {
if (command) {
return command.execute();
}
});
});
}
export function dnxRestoreForAll(server: OmnisharpServer) {
if (!server.isRunning()) {
return Promise.reject('OmniSharp server is not running.');
}
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
let commands:Command[] = [];
info.Dnx.Projects.forEach(project => {
commands.push({
label: `dnu restore - (${project.Name || basename(project.Path)})`,
description: dirname(project.Path),
execute() {
let command = join(info.Dnx.RuntimePath, 'bin/dnu');
if (isWin) {
command += '.cmd';
}
return runInTerminal(command, ['restore'], {
cwd: dirname(project.Path)
});
}
});
});
return window.showQuickPick(commands).then(command => {
if(command) {
return command.execute();
}
});
});
}
export function dnxRestoreForProject(server: OmnisharpServer, fileName: string) {
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then((info):Promise<any> => {
for(let project of info.Dnx.Projects) {
if (project.Path === fileName) {
let command = join(info.Dnx.RuntimePath, 'bin/dnu');
if (isWin) {
command += '.cmd';
}
return runInTerminal(command, ['restore'], {
cwd: dirname(project.Path)
});
}
}
return Promise.reject(`Failed to execute restore, try to run 'dnu restore' manually for ${fileName}.`)
});
}

View File

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {plain} from './documentation';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
import {createRequest} from '../typeConvertion';
import {CompletionItemProvider, CompletionItem, CompletionItemKind, Uri, CancellationToken, TextDocument, Range, Position} from 'vscode';
export default class OmniSharpCompletionItemProvider extends AbstractSupport implements CompletionItemProvider {
public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): Promise<CompletionItem[]> {
let wordToComplete = '';
let range = document.getWordRangeAtPosition(position);
if (range) {
wordToComplete = document.getText(new Range(range.start, position));
}
let req = createRequest<proto.AutoCompleteRequest>(document, position);
req.WordToComplete = wordToComplete;
req.WantDocumentationForEveryCompletionResult = true;
req.WantKind = true;
return this._server.makeRequest<proto.AutoCompleteResponse[]>(proto.AutoComplete, req).then(values => {
if (!values) {
return;
}
let result: CompletionItem[] = [];
let completions: { [c: string]: CompletionItem[] } = Object.create(null);
// transform AutoCompleteResponse to CompletionItem and
// group by code snippet
for (let value of values) {
let completion = new CompletionItem(value.CompletionText.replace(/\(|\)|<|>/g, ''));
completion.detail = value.DisplayText;
completion.documentation = plain(value.Description);
completion.kind = _kinds[value.Kind] || CompletionItemKind.Property;
let array = completions[completion.label];
if (!array) {
completions[completion.label] = [completion];
} else {
array.push(completion);
}
}
// per suggestion group, select on and indicate overloads
for (let key in completions) {
let suggestion = completions[key][0],
overloadCount = completions[key].length - 1;
if (overloadCount === 0) {
// remove non overloaded items
delete completions[key];
} else {
// indicate that there is more
suggestion.detail = `${suggestion.detail} (+ ${overloadCount} overload(s))`;
}
result.push(suggestion);
}
return result;
});
}
}
var _kinds: { [kind: string]: CompletionItemKind; } = Object.create(null);
_kinds['Variable'] = CompletionItemKind.Variable;
_kinds['Struct'] = CompletionItemKind.Interface;
_kinds['Interface'] = CompletionItemKind.Interface;
_kinds['Enum'] = CompletionItemKind.Enum;
_kinds['EnumMember'] = CompletionItemKind.Property;
_kinds['Property'] = CompletionItemKind.Property;
_kinds['Class'] = CompletionItemKind.Class;
_kinds['Field'] = CompletionItemKind.Field;
_kinds['EventField'] = CompletionItemKind.File;
_kinds['Method'] = CompletionItemKind.Method;

View File

@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {createRequest, toLocation} from '../typeConvertion';
import {Uri, TextDocument, Position, Location, CancellationToken, DefinitionProvider} from 'vscode';
export default class CSharpDefinitionProvider extends AbstractSupport implements DefinitionProvider {
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise<Location> {
let req = createRequest(document, position);
return this._server.makeRequest<Protocol.ResourceLocation>(Protocol.GoToDefinition, req, token).then(value => {
if (value && value.FileName) {
return toLocation(value);
}
});
}
}

View File

@ -0,0 +1,232 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {OmnisharpServer} from '../omnisharpServer';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
import {createRequest, toRange} from '../typeConvertion';
import {Disposable, Uri, CancellationTokenSource, TextDocument, TextDocumentChangeEvent, Range, Diagnostic, DiagnosticSeverity, Location, workspace, languages} from 'vscode';
export class Advisor {
private _disposable: Disposable;
private _server: OmnisharpServer;
private _packageRestoreCounter: number = 0;
private _projectSourceFileCounts: { [path: string]: number } = Object.create(null);
constructor(server: OmnisharpServer) {
this._server = server;
let d1 = server.onProjectChange(this._onProjectChange, this);
let d2 = server.onBeforePackageRestore(this._onBeforePackageRestore, this);
let d3 = server.onPackageRestore(this._onPackageRestore, this);
this._disposable = Disposable.from(d1, d2, d3);
}
public dispose() {
this._disposable.dispose();
}
public shouldValidateFiles(): boolean {
return this._isServerStarted()
&& !this._isRestoringPackages();
}
public shouldValidateProject(): boolean {
return this._isServerStarted()
&& !this._isRestoringPackages()
&& !this._isHugeProject();
}
private _onProjectChange(info: proto.ProjectInformationResponse): void {
if (info.DnxProject && info.DnxProject.SourceFiles) {
this._projectSourceFileCounts[info.DnxProject.Path] = info.DnxProject.SourceFiles.length;
}
if (info.MsBuildProject && info.MsBuildProject.SourceFiles) {
this._projectSourceFileCounts[info.MsBuildProject.Path] = info.MsBuildProject.SourceFiles.length;
}
}
private _onBeforePackageRestore(): void {
this._packageRestoreCounter += 1;
}
private _onPackageRestore(): void {
this._packageRestoreCounter -= 1;
}
private _isServerStarted(): boolean {
return this._server.isRunning();
}
private _isRestoringPackages(): boolean {
return this._packageRestoreCounter > 0;
}
private _isHugeProject(): boolean {
var sourceFileCount = 0;
for (var key in this._projectSourceFileCounts) {
sourceFileCount += this._projectSourceFileCounts[key];
if (sourceFileCount > 1000) {
return true;
}
}
return false;
}
}
export default function reportDiagnostics(server: OmnisharpServer, advisor: Advisor): Disposable {
return new DiagnosticsProvider(server, advisor);
}
class DiagnosticsProvider extends AbstractSupport {
private _validationAdvisor: Advisor;
private _disposable: Disposable;
private _documentValidations: { [uri: string]: CancellationTokenSource } = Object.create(null);
private _projectValidation: CancellationTokenSource;
private _diagnostics: vscode.DiagnosticCollection;
constructor(server: OmnisharpServer, validationAdvisor: Advisor) {
super(server);
this._validationAdvisor = validationAdvisor;
this._diagnostics = languages.createDiagnosticCollection('omnisharp');
let d1 = this._server.onPackageRestore(this._validateProject, this);
let d2 = this._server.onProjectChange(this._validateProject, this);
let d4 = workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this);
let d3 = workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this);
let d5 = workspace.onDidCloseTextDocument(this._onDocumentRemove, this);
this._disposable = Disposable.from(this._diagnostics, d1, d2, d3, d4, d5);
}
public dispose(): void {
if (this._projectValidation) {
this._projectValidation.dispose();
}
for (let key in this._documentValidations) {
this._documentValidations[key].dispose();
}
this._disposable.dispose();
}
private _onDocumentAddOrChange(document: TextDocument): void {
if (document.languageId === 'csharp' && document.uri.scheme === 'file') {
this._validateDocument(document);
this._validateProject();
}
}
private _onDocumentRemove(document: TextDocument) {
let key = document.uri.toString();
let didChange = false;
if (this._diagnostics[key]) {
didChange = true;
this._diagnostics[key].dispose();
delete this._diagnostics[key];
}
if (this._documentValidations[key]) {
didChange = true;
this._documentValidations[key].cancel();
delete this._documentValidations[key];
}
if (didChange) {
this._validateProject();
}
}
private _validateDocument(document: TextDocument): void {
if (!this._validationAdvisor.shouldValidateFiles()) {
return;
}
let key = document.uri.toString();
if (this._documentValidations[key]) {
this._documentValidations[key].cancel();
}
let source = new CancellationTokenSource();
let handle = setTimeout(() => {
let req: proto.Request = { Filename: document.fileName };
this._server.makeRequest<proto.QuickFixResponse>(proto.CodeCheck, req, source.token).then(value => {
// (re)set new diagnostics for this document
let diagnostics = value.QuickFixes.map(DiagnosticsProvider._asDiagnostic);
this._diagnostics.set(document.uri, diagnostics);
});
}, 750);
source.token.onCancellationRequested(() => clearTimeout(handle));
this._documentValidations[key] = source;
}
private _validateProject(): void {
if (!this._validationAdvisor.shouldValidateProject()) {
return;
}
if (this._projectValidation) {
this._projectValidation.cancel();
}
this._projectValidation = new CancellationTokenSource();
let handle = setTimeout(() => {
this._server.makeRequest<proto.QuickFixResponse>(proto.CodeCheck, {}, this._projectValidation.token).then(value => {
let quickFixes = value.QuickFixes.sort((a, b) => a.FileName.localeCompare(b.FileName));
let entries: [Uri, Diagnostic[]][] = [];
let lastEntry: [Uri, Diagnostic[]];
for (let quickFix of quickFixes) {
let diag = DiagnosticsProvider._asDiagnostic(quickFix);
let uri = Uri.file(quickFix.FileName);
if (lastEntry && lastEntry[0].toString() === uri.toString()) {
lastEntry[1].push(diag);
} else {
lastEntry = [uri, [diag]];
entries.push(lastEntry);
}
}
// replace all entries
this._diagnostics.set(entries);
});
}, 3000);
// clear timeout on cancellation
this._projectValidation.token.onCancellationRequested(() => {
clearTimeout(handle);
});
}
// --- data converter
private static _asDiagnostic(quickFix: proto.QuickFix): Diagnostic {
let severity = DiagnosticsProvider._asDiagnosticSeverity(quickFix.LogLevel);
let message = `${quickFix.Text} [${quickFix.Projects.map(n => DiagnosticsProvider._asProjectLabel(n)).join(', ') }]`;
return new Diagnostic(toRange(quickFix), message, severity);
}
private static _asDiagnosticSeverity(logLevel: string): DiagnosticSeverity {
switch (logLevel.toLowerCase()) {
case 'hidden':
case 'warning':
case 'warn':
return DiagnosticSeverity.Warning;
default:
return DiagnosticSeverity.Error;
}
}
private static _asProjectLabel(projectName: string): string {
var idx = projectName.indexOf('+');
return projectName.substr(idx + 1);
}
}

View File

@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
import {createRequest, toRange} from '../typeConvertion';
import {DocumentHighlightProvider, DocumentHighlight, DocumentHighlightKind, Uri, CancellationToken, TextDocument, Position, Range} from 'vscode';
export default class OmnisharpDocumentHighlightProvider extends AbstractSupport implements DocumentHighlightProvider {
public provideDocumentHighlights(resource: TextDocument, position: Position, token: CancellationToken): Promise<DocumentHighlight[]> {
let req = createRequest<proto.FindUsagesRequest>(resource, position);
req.OnlyThisFile = true;
req.ExcludeDefinition = false;
return this._server.makeRequest<proto.QuickFixResponse>(proto.FindUsages, req, token).then(res => {
if (res && Array.isArray(res.QuickFixes)) {
return res.QuickFixes.map(OmnisharpDocumentHighlightProvider._asDocumentHighlight);
}
});
}
private static _asDocumentHighlight(quickFix: proto.QuickFix): DocumentHighlight {
return new DocumentHighlight(toRange(quickFix), DocumentHighlightKind.Read);
}
}

View File

@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {toDocumentSymbol} from '../typeConvertion';
import {DocumentSymbolProvider, SymbolInformation, SymbolKind, Uri, TextDocument, Range, CancellationToken} from 'vscode';
export default class OmnisharpDocumentSymbolProvider extends AbstractSupport implements DocumentSymbolProvider {
public provideDocumentSymbols(document: TextDocument, token: CancellationToken): Promise<SymbolInformation[]> {
return this._server.makeRequest<Protocol.CurrentFileMembersAsTreeResponse>(Protocol.CurrentFileMembersAsTree, {Filename: document.fileName}, token).then(tree => {
var ret: SymbolInformation[] = [];
for (let node of tree.TopLevelTypeDefinitions) {
toDocumentSymbol(ret, node);
}
return ret;
});
}
}

View File

@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var _regExp = /<(\S*?).*?>((.|\r|\n)*?)<\/\1>/;
/**
* remove xml-tags from string
*/
export function plain(doc: string): string {
if (!doc) {
return doc;
}
var newDoc: string;
while (true) {
newDoc = doc.replace(_regExp,(m, g1, g2, g3) => g2);
if (newDoc === doc) {
break;
}
doc = newDoc;
}
return newDoc;
}

View File

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
import {Uri, DocumentRangeFormattingEditProvider, OnTypeFormattingEditProvider, FormattingOptions, CancellationToken, TextEdit, TextDocument, Range, Position} from 'vscode';
export default class FormattingSupport extends AbstractSupport implements DocumentRangeFormattingEditProvider {
public provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[]> {
let request = <proto.FormatRangeRequest>{
Filename: document.fileName,
Line: range.start.line + 1,
Column: range.start.character + 1,
EndLine: range.end.line + 1,
EndColumn: range.end.character + 1
};
return this._server.makeRequest<proto.FormatRangeResponse>(proto.FormatRange, request, token).then(res => {
if (res && Array.isArray(res.Changes)) {
return res.Changes.map(FormattingSupport._asEditOptionation);
}
});
}
public provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[]> {
let request = <proto.FormatAfterKeystrokeRequest> {
Filename: document.fileName,
Line: position.line + 1,
Column: position.character + 1,
Character: ch
};
return this._server.makeRequest<proto.FormatRangeResponse>(proto.FormatAfterKeystroke, request, token).then(res => {
if (res && Array.isArray(res.Changes)) {
return res.Changes.map(FormattingSupport._asEditOptionation);
}
});
}
private static _asEditOptionation(change: proto.TextChange): TextEdit {
return new TextEdit(
new Range(change.StartLine - 1, change.StartColumn - 1, change.EndLine - 1, change.EndColumn - 1),
change.NewText);
}
}

View File

@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {plain} from './documentation';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {createRequest} from '../typeConvertion';
import {HoverProvider, Hover, TextDocument, CancellationToken, Range, Position} from 'vscode';
export default class OmniSharpHoverProvider extends AbstractSupport implements HoverProvider {
public provideHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover> {
let req = createRequest<Protocol.TypeLookupRequest>(document, position);
req.IncludeDocumentation = true;
return this._server.makeRequest<Protocol.TypeLookupResponse>(Protocol.TypeLookup, req, token).then(value => {
if (value && value.Type) {
let contents = [plain(value.Documentation), { language: 'csharp', value: value.Type }];
return new Hover(contents);
}
});
}
}

View File

@ -0,0 +1,259 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import {OmnisharpServer} from '../omnisharpServer';
import {dnxRestoreForProject} from './commands';
import {basename} from 'path';
import * as proto from '../protocol';
export default function reportStatus(server: OmnisharpServer) {
return vscode.Disposable.from(
reportServerStatus(server),
forwardOutput(server),
reportDocumentStatus(server));
}
// --- document status
let defaultSelector: vscode.DocumentSelector = [
'csharp', // c#-files OR
{ pattern: '**/project.json' }, // project.json-files OR
{ pattern: '**/*.sln' }, // any solution file OR
{ pattern: '**/*.csproj' } // an csproj file
];
class Status {
selector: vscode.DocumentSelector;
text: string;
command: string;
color: string;
constructor(selector: vscode.DocumentSelector) {
this.selector = selector;
}
}
export function reportDocumentStatus(server: OmnisharpServer): vscode.Disposable {
let disposables: vscode.Disposable[] = [];
let entry = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, Number.MIN_VALUE);
let defaultStatus = new Status(defaultSelector);
let projectStatus: Status;
function render() {
if (!vscode.window.activeTextEditor) {
entry.hide();
return;
}
let document = vscode.window.activeTextEditor.document;
let status: Status;
if (projectStatus && vscode.languages.match(projectStatus.selector, document)) {
status = projectStatus;
} else if (defaultStatus.text && vscode.languages.match(defaultStatus.selector, document)) {
status = defaultStatus;
}
if (status) {
entry.text = status.text;
entry.command = status.command;
entry.color = status.color;
entry.show();
return;
}
entry.hide();
}
disposables.push(vscode.window.onDidChangeActiveTextEditor(render));
disposables.push(server.onServerError(err => {
defaultStatus.text = '$(flame) Error starting OmniSharp';
defaultStatus.command = 'o.showOutput';
defaultStatus.color = '';
render();
}));
disposables.push(server.onMultipleLaunchTargets(targets => {
defaultStatus.text = '$(flame) Select project';
defaultStatus.command = 'o.pickProjectAndStart';
defaultStatus.color = 'rgb(90, 218, 90)';
render();
}));
disposables.push(server.onBeforeServerStart(path => {
defaultStatus.text = '$(flame) Starting...';
defaultStatus.command = 'o.showOutput';
defaultStatus.color = '';
render();
}));
disposables.push(server.onServerStop(() => {
projectStatus = undefined;
defaultStatus.text = undefined;
}));
disposables.push(server.onServerStart(path => {
defaultStatus.text = '$(flame) Runnning';
defaultStatus.command = 'o.pickProjectAndStart';
defaultStatus.color = '';
render();
function updateProjectInfo() {
server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
let fileNames: vscode.DocumentSelector[] = [];
let label: string;
// show sln-file if applicable
if (info.MSBuild.SolutionPath) {
label = basename(info.MSBuild.SolutionPath)//workspace.getRelativePath(info.MSBuild.SolutionPath);
fileNames.push({ pattern: info.MSBuild.SolutionPath });
for (let project of info.MSBuild.Projects) {
fileNames.push({ pattern: project.Path });
for (let sourceFile of project.SourceFiles) {
fileNames.push({ pattern: sourceFile });
}
}
}
// show dnx projects if applicable
let count = 0;
for (let project of info.Dnx.Projects) {
count += 1;
fileNames.push({ pattern: project.Path });
for (let sourceFile of project.SourceFiles) {
fileNames.push({ pattern: sourceFile });
}
}
if (label) {
// we already have a message from a sln-file
} else if (count === 1) {
label = basename(info.Dnx.Projects[0].Path)//workspace.getRelativePath(info.Dnx.Projects[0].Path);
} else {
label = `${count} projects`;
}
// set project info
projectStatus = new Status(fileNames);
projectStatus.text = '$(flame) ' + label;
projectStatus.command = 'o.pickProjectAndStart';
// default is to change project
defaultStatus.text = '$(flame) Switch projects';
defaultStatus.command = 'o.pickProjectAndStart';
render();
});
}
disposables.push(server.onProjectAdded(updateProjectInfo));
disposables.push(server.onProjectChange(updateProjectInfo));
disposables.push(server.onProjectRemoved(updateProjectInfo));
}));
return vscode.Disposable.from(...disposables);
}
// ---- server status
export function reportServerStatus(server: OmnisharpServer): vscode.Disposable{
function appendLine(value: string = '') {
server.getChannel().appendLine(value);
}
let d0 = server.onServerError(err => {
appendLine('[ERROR] ' + err);
});
let d1 = server.onError(message => {
if (message.FileName) {
appendLine(`${message.FileName}(${message.Line},${message.Column})`);
}
appendLine(message.Text);
appendLine();
showMessageSoon();
});
let d2 = server.onMsBuildProjectDiagnostics(message => {
function asErrorMessage(message: proto.MSBuildDiagnosticsMessage) {
let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Error: ${message.Text}`;
appendLine(value);
}
function asWarningMessage(message: proto.MSBuildDiagnosticsMessage) {
let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Warning: ${message.Text}`;
appendLine(value);
}
if (message.Errors.length > 0 || message.Warnings.length > 0) {
appendLine(message.FileName);
message.Errors.forEach(error => asErrorMessage);
message.Warnings.forEach(warning => asWarningMessage);
appendLine();
showMessageSoon();
}
});
let d3 = server.onUnresolvedDependencies(message => {
let info = `There are unresolved dependencies from '${vscode.workspace.asRelativePath(message.FileName) }'. Please execute the restore command to continue.`;
return vscode.window.showInformationMessage(info, 'Restore').then(value => {
if (value) {
dnxRestoreForProject(server, message.FileName);
}
});
});
return vscode.Disposable.from(d0, d1, d2, d3);
}
// show user message
let _messageHandle: number;
function showMessageSoon() {
clearTimeout(_messageHandle);
_messageHandle = setTimeout(function() {
let message = "Some projects have trouble loading. Please review the output for more details.";
vscode.window.showWarningMessage(message, { title: "Show Output", command: 'o.showOutput' }).then(value => {
if (value) {
vscode.commands.executeCommand(value.command);
}
});
}, 1500);
}
// --- mirror output in channel
function forwardOutput(server: OmnisharpServer) {
const logChannel = server.getChannel();
const timing200Pattern = /^\[INFORMATION:OmniSharp.Middleware.LoggingMiddleware\] \/\w+: 200 \d+ms/;
function forward(message: string) {
// strip stuff like: /codecheck: 200 339ms
if(!timing200Pattern.test(message)) {
logChannel.append(message);
}
}
return vscode.Disposable.from(
server.onStdout(forward),
server.onStderr(forward));
}

View File

@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {createRequest, toLocation} from '../typeConvertion';
import {ReferenceProvider, Location, Range, TextDocument, Uri, CancellationToken, Position} from 'vscode';
export default class OmnisharpReferenceProvider extends AbstractSupport implements ReferenceProvider {
public provideReferences(document: TextDocument, position: Position, options: { includeDeclaration: boolean;}, token: CancellationToken): Promise<Location[]> {
let req = createRequest<Protocol.FindUsagesRequest>(document, position);
req.OnlyThisFile = false;
req.ExcludeDefinition = false;
return this._server.makeRequest<Protocol.QuickFixResponse>(Protocol.FindUsages, req, token).then(res => {
if (res && Array.isArray(res.QuickFixes)) {
return res.QuickFixes.map(toLocation);
}
});
}
}

View File

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as proto from '../protocol';
import {createRequest, toRange} from '../typeConvertion';
import {RenameProvider, TextEdit, WorkspaceEdit, TextDocument, Uri, CancellationToken, Position, Range} from 'vscode';
export default class OmnisharpRenameProvider extends AbstractSupport implements RenameProvider {
public provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): Promise<WorkspaceEdit> {
let request = createRequest<proto.RenameRequest>(document, position);
request.WantsTextChanges = true,
request.RenameTo = newName;
return this._server.makeRequest<proto.RenameResponse>(proto.Rename, request, token).then(response => {
if (!response) {
return;
}
const edit = new WorkspaceEdit();
response.Changes.forEach(change => {
const uri = Uri.file(change.FileName);
change.Changes.forEach(change => {
edit.replace(uri,
new Range(change.StartLine - 1, change.StartColumn - 1, change.EndLine - 1, change.EndColumn - 1),
change.NewText);
});
});
return edit;
});
}
}

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {createRequest} from '../typeConvertion';
import {SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, Uri, CancellationToken, TextDocument, Position} from 'vscode';
export default class OmniSharpSignatureHelpProvider extends AbstractSupport implements SignatureHelpProvider {
public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Promise<SignatureHelp> {
let req = createRequest(document, position);
return this._server.makeRequest<Protocol.SignatureHelp>(Protocol.SignatureHelp, req, token).then(res => {
let ret = new SignatureHelp();
ret.activeSignature = res.ActiveSignature;
ret.activeParameter = res.ActiveParameter;
for(let signature of res.Signatures) {
let signatureInfo = new SignatureInformation(signature.Label, signature.Documentation);
ret.signatures.push(signatureInfo);
for (let parameter of signature.Parameters) {
let parameterInfo = new ParameterInformation(
parameter.Label,
parameter.Documentation);
signatureInfo.parameters.push(parameterInfo);
}
}
return ret;
});
}
}

View File

@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import AbstractSupport from './abstractProvider';
import * as Protocol from '../protocol';
import {createRequest, toRange} from '../typeConvertion';
import {CancellationToken, Uri, Range, WorkspaceSymbolProvider, SymbolInformation, SymbolKind} from 'vscode';
export default class OmnisharpWorkspaceSymbolProvider extends AbstractSupport implements WorkspaceSymbolProvider {
public provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<SymbolInformation[]> {
return this._server.makeRequest<Protocol.FindSymbolsResponse>(Protocol.FindSymbols, <Protocol.FindSymbolsRequest> {
Filter: search,
Filename: ''
}, token).then(res => {
if (res && Array.isArray(res.QuickFixes)) {
return res.QuickFixes.map(OmnisharpWorkspaceSymbolProvider._asSymbolInformation);
}
});
}
private static _asSymbolInformation(symbolInfo: Protocol.SymbolLocation): SymbolInformation {
return new SymbolInformation(symbolInfo.Text, OmnisharpWorkspaceSymbolProvider._toKind(symbolInfo),
toRange(symbolInfo),
Uri.file(symbolInfo.FileName));
}
private static _toKind(symbolInfo: Protocol.SymbolLocation): SymbolKind {
switch (symbolInfo.Kind) {
case 'Method':
return SymbolKind.Method;
case 'Field':
case 'Property':
return SymbolKind.Field;
}
return SymbolKind.Class;
}
}

View File

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as paths from 'path';
import {EventEmitter} from 'events';
import {Uri, workspace} from 'vscode';
export interface LaunchTarget {
label: string;
description: string;
directory: Uri;
resource: Uri;
target: Uri;
}
export default function getLaunchTargets(): Thenable<LaunchTarget[]> {
return workspace.findFiles('{**/*.sln,**/*.csproj,**/project.json}', '{**/node_modules/**,**/.git/**,**/bower_components/**}', 100).then(resources => {
return select(resources, Uri.file(workspace.rootPath));
});
}
function select(resources: Uri[], root: Uri): LaunchTarget[] {
if (!Array.isArray(resources)) {
return [];
}
var targets: LaunchTarget[] = [],
hasCsProjFiles = false,
hasProjectJson = false,
hasProjectJsonAtRoot = false;
hasCsProjFiles = resources
.some(resource => /\.csproj$/.test(resource.fsPath));
resources.forEach(resource => {
// sln files
if (hasCsProjFiles && /\.sln$/.test(resource.fsPath)) {
targets.push({
label: paths.basename(resource.fsPath),
description: workspace.asRelativePath(paths.dirname(resource.fsPath)),
resource,
target: resource,
directory: Uri.file(paths.dirname(resource.fsPath))
});
}
// project.json files
if (/project.json$/.test(resource.fsPath)) {
var dirname = paths.dirname(resource.fsPath);
hasProjectJson = true;
hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === root.fsPath;
targets.push({
label: paths.basename(resource.fsPath),
description: workspace.asRelativePath(paths.dirname(resource.fsPath)),
resource,
target: Uri.file(dirname),
directory: Uri.file(dirname)
});
}
});
if (hasProjectJson && !hasProjectJsonAtRoot) {
targets.push({
label: paths.basename(root.fsPath),
description: '',
resource: root,
target: root,
directory: root
});
}
return targets.sort((a, b) => a.directory.fsPath.localeCompare(b.directory.fsPath));
}

View File

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import DefinitionProvider from './features/definitionProvider';
import CodeLensProvider from './features/codeLensProvider';
import DocumentHighlightProvider from './features/documentHighlightProvider';
import DocumentSymbolProvider from './features/documentSymbolProvider';
import CodeActionProvider from './features/codeActionProvider';
import ReferenceProvider from './features/referenceProvider';
import HoverProvider from './features/hoverProvider';
import RenameProvider from './features/renameProvider';
import FormatProvider from './features/formattingEditProvider';
import CompletionItemProvider from './features/completionItemProvider';
import WorkspaceSymbolProvider from './features/workspaceSymbolProvider';
import reportDiagnostics,{Advisor} from './features/diagnosticsProvider';
import SignatureHelpProvider from './features/signatureHelpProvider';
import registerCommands from './features/commands';
import {StdioOmnisharpServer} from './omnisharpServer';
import forwardChanges from './features/changeForwarding';
import reportStatus from './features/omnisharpStatus';
import findLaunchTargets from './launchTargetFinder';
import {Disposable, ExtensionContext, languages, extensions} from 'vscode';
export function activate(context: ExtensionContext): any {
const _selector: vscode.DocumentSelector = {
language: 'csharp',
scheme: 'file' // only files from disk
};
const server = new StdioOmnisharpServer();
let advisor = new Advisor(server);
let disposables: Disposable[] = [];
let localDisposables: Disposable[] = [];
disposables.push(server.onServerStart(() => {
// register language feature provider on start
localDisposables.push(languages.registerDefinitionProvider(_selector, new DefinitionProvider(server)));
localDisposables.push(languages.registerCodeLensProvider(_selector, new CodeLensProvider(server)));
localDisposables.push(languages.registerDocumentHighlightProvider(_selector, new DocumentHighlightProvider(server)));
localDisposables.push(languages.registerDocumentSymbolProvider(_selector, new DocumentSymbolProvider(server)));
localDisposables.push(languages.registerReferenceProvider(_selector, new ReferenceProvider(server)));
localDisposables.push(languages.registerHoverProvider(_selector, new HoverProvider(server)));
localDisposables.push(languages.registerRenameProvider(_selector, new RenameProvider(server)));
localDisposables.push(languages.registerDocumentRangeFormattingEditProvider(_selector, new FormatProvider(server)));
localDisposables.push(languages.registerOnTypeFormattingEditProvider(_selector, new FormatProvider(server), '}', ';'));
localDisposables.push(languages.registerCompletionItemProvider(_selector, new CompletionItemProvider(server), '.', '<'));
localDisposables.push(languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server)));
localDisposables.push(languages.registerSignatureHelpProvider(_selector, new SignatureHelpProvider(server), '(', ','));
let codeActionProvider = new CodeActionProvider(server);
localDisposables.push(codeActionProvider);
localDisposables.push(languages.registerCodeActionsProvider(_selector, codeActionProvider));
localDisposables.push(reportDiagnostics(server, advisor));
localDisposables.push(forwardChanges(server));
}));
disposables.push(server.onServerStop(() => {
// remove language feature providers on stop
Disposable.from(...localDisposables).dispose();
}));
disposables.push(registerCommands(server));
disposables.push(reportStatus(server));
// read and store last solution or folder path
server.autoStart(context.workspaceState.get<string>('lastSolutionPathOrFolder'));
server.onBeforeServerStart(path => context.workspaceState.update('lastSolutionPathOrFolder', path));
// stop server on deactivate
disposables.push(new Disposable(() => {
advisor.dispose();
server.stop();
}));
context.subscriptions.push(...disposables);
}

View File

@ -0,0 +1,507 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {EventEmitter} from 'events';
import {ChildProcess, exec} from 'child_process';
import {request} from 'http';
import {dirname} from 'path';
import {ReadLine, createInterface} from 'readline';
import omnisharpLauncher from './omnisharpServerLauncher';
import {Disposable, CancellationToken, OutputChannel, workspace, window} from 'vscode';
import {ErrorMessage, UnresolvedDependenciesMessage, MSBuildProjectDiagnostics, ProjectInformationResponse} from './protocol';
import getLaunchTargets, {LaunchTarget} from './launchTargetFinder';
enum ServerState {
Starting,
Started,
Stopped
}
interface Request {
path: string;
data?: any;
onSuccess: Function;
onError: Function;
_enqueued: number;
}
export abstract class OmnisharpServer {
private _eventBus = new EventEmitter();
private _start: Promise<void>;
private _state: ServerState = ServerState.Stopped;
private _solutionPath: string;
private _queue: Request[] = [];
private _isProcessingQueue = false;
private _channel: OutputChannel;
protected _serverProcess: ChildProcess;
protected _extraArgv: string[];
constructor() {
this._extraArgv = [];
this._channel = window.createOutputChannel('OmniSharp Log');
}
public isRunning(): boolean {
return this._state === ServerState.Started;
}
private _getState(): ServerState {
return this._state;
}
private _setState(value: ServerState) : void {
if (typeof value !== 'undefined' && value !== this._state) {
this._state = value;
this._fireEvent('stateChanged', this._state);
}
}
public getSolutionPathOrFolder(): string {
return this._solutionPath;
}
public getChannel(): vscode.OutputChannel {
return this._channel;
}
public onStdout(listener: (e: string) => any, thisArg?: any) {
return this._addListener('stdout', listener, thisArg);
}
public onStderr(listener: (e: string) => any, thisArg?: any) {
return this._addListener('stderr', listener, thisArg);
}
public onError(listener: (e: ErrorMessage) => any, thisArg?: any) {
return this._addListener('Error', listener, thisArg);
}
public onServerError(listener: (err: any) => any, thisArg?: any) {
return this._addListener('ServerError', listener, thisArg);
}
public onUnresolvedDependencies(listener: (e: UnresolvedDependenciesMessage) => any, thisArg?:any) {
return this._addListener('UnresolvedDependencies', listener, thisArg);
}
public onBeforePackageRestore(listener: () => any, thisArg?: any) {
return this._addListener('PackageRestoreStarted', listener, thisArg);
}
public onPackageRestore(listener: () => any, thisArg?: any) {
return this._addListener('PackageRestoreFinished', listener, thisArg);
}
public onProjectChange(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
return this._addListener('ProjectChanged', listener, thisArg);
}
public onProjectAdded(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
return this._addListener('ProjectAdded', listener, thisArg);
}
public onProjectRemoved(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
return this._addListener('ProjectRemoved', listener, thisArg);
}
public onMsBuildProjectDiagnostics(listener: (e: MSBuildProjectDiagnostics) => any, thisArg?: any) {
return this._addListener('MsBuildProjectDiagnostics', listener, thisArg);
}
public onBeforeServerStart(listener: (e:string) => any) {
return this._addListener('BeforeServerStart', listener);
}
public onServerStart(listener: (e: string) => any) {
return this._addListener('ServerStart', listener);
}
public onServerStop(listener: () => any) {
return this._addListener('ServerStop', listener);
}
public onMultipleLaunchTargets(listener: (targets: LaunchTarget[]) => any, thisArg?: any) {
return this._addListener('server:MultipleLaunchTargets', listener, thisArg);
}
public onOmnisharpStart(listener: () => any) {
return this._addListener('started', listener);
}
private _addListener(event: string, listener: (e: any) => any, thisArg?: any): Disposable {
listener = thisArg ? listener.bind(thisArg) : listener;
this._eventBus.addListener(event, listener);
return new Disposable(() => this._eventBus.removeListener(event, listener));
}
protected _fireEvent(event: string, args: any): void {
this._eventBus.emit(event, args);
}
public start(solutionPath: string): Promise<void> {
if (!this._start) {
this._start = this._doStart(solutionPath);
}
return this._start;
}
private _doStart(solutionPath: string): Promise<void> {
this._setState(ServerState.Starting);
this._solutionPath = solutionPath;
var cwd = dirname(solutionPath),
argv = ['-s', solutionPath, '--hostPID', process.pid.toString(), 'dnx:enablePackageRestore=false'].concat(this._extraArgv);
this._fireEvent('stdout', `[INFO] Starting OmniSharp at '${solutionPath}'...\n`);
this._fireEvent('BeforeServerStart', solutionPath);
return omnisharpLauncher(cwd, argv).then(value => {
this._serverProcess = value.process;
this._fireEvent('stdout', `[INFO] Started OmniSharp from '${value.command}' with process id ${value.process.pid}...\n`);
return this._doConnect();
}).then(_ => {
this._fireEvent('ServerStart', solutionPath);
this._setState(ServerState.Started);
this._processQueue();
}, err => {
this._fireEvent('ServerError', err);
throw err;
});
}
protected abstract _doConnect(): Promise<OmnisharpServer>;
public stop(): Promise<void> {
var ret: Promise<OmnisharpServer>;
if (!this._serverProcess) {
// nothing to kill
ret = Promise.resolve(undefined);
} else if (/^win/.test(process.platform)) {
// when killing a process in windows its child
// processes are *not* killed but become root
// processes. Therefore we use TASKKILL.EXE
ret = new Promise<OmnisharpServer>((resolve, reject) => {
var killer = exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, function (err, stdout, stderr) {
if (err) {
return reject(err);
}
});
killer.on('exit', resolve);
killer.on('error', reject);
});
} else {
this._serverProcess.kill('SIGTERM');
ret = Promise.resolve(undefined);
}
return ret.then(_ => {
this._start = null;
this._serverProcess = null;
this._setState(ServerState.Stopped);
this._fireEvent('ServerStop', this);
return;
});
}
public restart(solutionPath: string = this._solutionPath): Promise<void> {
if (solutionPath) {
return this.stop().then(() => {
this.start(solutionPath)
});
}
}
public autoStart(preferredPath:string): Thenable<void> {
return getLaunchTargets().then(targets => {
if (targets.length === 0) {
return new Promise<void>((resolve, reject) => {
// 1st watch for files
let watcher = workspace.createFileSystemWatcher('{**/*.sln,**/project.json}', false, true, true);
watcher.onDidCreate(uri => {
watcher.dispose();
resolve();
});
}).then(() => {
// 2nd try again
return this.autoStart(preferredPath);
});
}
if (targets.length > 1) {
for (let target of targets) {
if (target.target.fsPath === preferredPath) {
// start preferred path
return this.restart(preferredPath);
}
}
this._fireEvent('server:MultipleLaunchTargets', targets);
return Promise.reject<void>(undefined);
}
// just start
return this.restart(targets[0].target.fsPath);
});
}
public makeRequest<R>(path: string, data?: any, token?: CancellationToken): Promise<R> {
if (this._getState() !== ServerState.Started) {
return Promise.reject<R>('server has been stopped or not started');
}
let request: Request;
let promise = new Promise<any>((resolve, reject) => {
request = {
path,
data,
onSuccess: resolve,
onError: reject,
_enqueued: Date.now()
};
this._queue.push(request);
// this._statOnRequestStart(request);
if (this._getState() === ServerState.Started && !this._isProcessingQueue) {
this._processQueue();
}
});
if (token) {
token.onCancellationRequested(() => {
let idx = this._queue.indexOf(request);
if (idx !== -1) {
this._queue.splice(idx, 1);
let err = new Error('Canceled');
err.message = 'Canceled';
request.onError(err);
}
});
}
return promise;
}
private _processQueue(): void {
if (this._queue.length === 0) {
// nothing to do
this._isProcessingQueue = false;
return;
}
// signal that we are working on it
this._isProcessingQueue = true;
// send next request and recurse when done
var thisRequest = this._queue.shift();
this._makeNextRequest(thisRequest.path, thisRequest.data).then(value => {
thisRequest.onSuccess(value);
this._processQueue();
// this._statOnRequestEnd(thisRequest, true);
}, err => {
thisRequest.onError(err);
this._processQueue();
// this._statOnRequestEnd(thisRequest, false);
}).catch(err => {
console.error(err);
this._processQueue();
});
}
protected abstract _makeNextRequest(path: string, data: any): Promise<any>;
// private _statOnRequestStart(request: Request): void {
// console.log(`[DEBUG] *enqueuing* request '${request.path}' (queue size is ${this._queue.length})\n`);
// }
// private _statOnRequestEnd(request: Request, successfully: boolean): void {
// var duration = Date.now() - request._enqueued,
// state = successfully ? 'successfully' : 'with errors';
// console.log(`[DEBUG] request '${request.path}' finished *${state}* after ${duration}ms\n`);
// }
}
namespace WireProtocol {
export interface Packet {
Type: string;
Seq: number;
}
export interface RequestPacket extends Packet {
Command: string;
Arguments: any;
}
export interface ResponsePacket extends Packet {
Command: string;
Request_seq: number;
Running: boolean;
Success: boolean;
Message: string;
Body: any;
}
export interface EventPacket extends Packet {
Event: string;
Body: any;
}
}
export class StdioOmnisharpServer extends OmnisharpServer {
private static _seqPool = 1;
private static StartupTimeout = 1000 * 60;
private static ResponsePacketTimeout = 1000 * 60 * 15; // helps debugging
private _rl: ReadLine;
private _activeRequest: { [seq: number]: { onSuccess: Function; onError: Function; } } = Object.create(null);
private _callOnStop: Function[] = [];
constructor() {
super();
// extra argv
this._extraArgv.push('--stdio');
}
public stop(): Promise<void> {
while (this._callOnStop.length) {
this._callOnStop.pop()();
}
return super.stop();
}
protected _doConnect(): Promise<OmnisharpServer> {
this._serverProcess.stderr.on('data', (data: any) => this._fireEvent('stderr', String(data)));
this._rl = createInterface({
input: this._serverProcess.stdout,
output: this._serverProcess.stdin,
terminal: false
});
var p = new Promise<OmnisharpServer>((resolve, reject) => {
var listener: Disposable;
// timeout logic
var handle = setTimeout(() => {
listener && listener.dispose();
reject(new Error('Failed to start OmniSharp'));
}, StdioOmnisharpServer.StartupTimeout);
// handle started-event
listener = this.onOmnisharpStart(() => {
listener && listener.dispose();
clearTimeout(handle);
resolve(this);
});
});
this._startListening();
return p;
}
private _startListening(): void {
var onLineReceived = (line: string) => {
if (line[0] !== '{') {
this._fireEvent('stdout', `${line}\n`);
return;
}
var packet: WireProtocol.Packet;
try {
packet = JSON.parse(line);
} catch (e) {
// not json
return;
}
if (!packet.Type) {
// bogous packet
return;
}
switch (packet.Type) {
case 'response':
this._handleResponsePacket(<WireProtocol.ResponsePacket> packet);
break;
case 'event':
this._handleEventPacket(<WireProtocol.EventPacket> packet);
break;
default:
console.warn('unknown packet: ', packet);
break;
}
};
this._rl.addListener('line', onLineReceived);
this._callOnStop.push(() => this._rl.removeListener('line', onLineReceived));
}
private _handleResponsePacket(packet: WireProtocol.ResponsePacket): void {
var requestSeq = packet.Request_seq,
entry = this._activeRequest[requestSeq];
if (!entry) {
console.warn('Received a response WITHOUT a request', packet);
return;
}
delete this._activeRequest[requestSeq];
if (packet.Success) {
entry.onSuccess(packet.Body);
} else {
entry.onError(packet.Message || packet.Body);
}
}
private _handleEventPacket(packet: WireProtocol.EventPacket): void {
if (packet.Event === 'log') {
// handle log events
var entry = <{ LogLevel: string; Name: string; Message: string; }> packet.Body;
this._fireEvent('stdout', `[${entry.LogLevel}:${entry.Name}] ${entry.Message}\n`);
return;
} else {
// fwd all other events
this._fireEvent(packet.Event, packet.Body);
}
}
protected _makeNextRequest(path: string, data: any): Promise<any> {
var thisRequestPacket: WireProtocol.RequestPacket = {
Type: 'request',
Seq: StdioOmnisharpServer._seqPool++,
Command: path,
Arguments: data
};
return new Promise<any>((c, e) => {
this._activeRequest[thisRequestPacket.Seq] = {
onSuccess: c,
onError: e
};
this._serverProcess.stdin.write(JSON.stringify(thisRequestPacket) + '\n');
});
}
}

View File

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {exists as fileExists} from 'fs';
import {spawn, ChildProcess} from 'child_process';
import {workspace} from 'vscode';
import {satisfies} from 'semver';
import {join} from 'path';
var omnisharpEnv = 'OMNISHARP';
var isWindows = /^win/.test(process.platform);
export default function launch(cwd: string, args: string[]):Promise < { process: ChildProcess, command: string } > {
return new Promise((resolve, reject) => {
try {
(isWindows ? launchWindows(cwd, args) : launchNix(cwd, args)).then(value => {
// async error - when target not not ENEOT
value.process.on('error', reject);
// success after a short freeing event loop
setTimeout(function () {
resolve(value);
}, 0);
}, err => {
reject(err);
});
} catch (err) {
reject(err);
}
});
}
function launchWindows(cwd: string, args: string[]): Promise<{ process: ChildProcess, command: string }> {
return getOmnisharpPath().then(command => {
args = args.slice(0);
args.unshift(command);
args = [[
'/s',
'/c',
'"' + args.map(arg => /^[^"].* .*[^"]/.test(arg) ? `"${arg}"` : arg).join(' ') + '"'
].join(' ')];
let process = spawn('cmd', args, <any>{
windowsVerbatimArguments: true,
detached: false,
// env: details.env,
cwd: cwd
});
return {
process,
command
};
});
}
function launchNix(cwd: string, args: string[]): Promise<{ process: ChildProcess, command: string }>{
return new Promise((resolve, reject) => {
hasMono('>=4.0.1').then(hasIt => {
if (!hasIt) {
reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required. See http://go.microsoft.com/fwlink/?linkID=534832#_20001'));
} else {
resolve();
}
});
}).then(_ => {
return getOmnisharpPath();
}).then(command => {
let process = spawn(command, args, {
detached: false,
// env: details.env,
cwd
});
return {
process,
command
}
});
}
function getOmnisharpPath(): Promise<string> {
let pathCandidate: string;
let config = workspace.getConfiguration();
if (config.has('csharp.omnisharp')) {
// form config
pathCandidate = config.get<string>('csharp.omnisharp');
} else if (typeof process.env[omnisharpEnv] === 'string') {
// form enviroment variable
console.warn('[deprecated] use workspace or user settings with "csharp.omnisharp":"/path/to/omnisharp"');
pathCandidate = process.env[omnisharpEnv];
} else {
// bundled version of Omnisharp
pathCandidate = join(__dirname, '../bin/omnisharp')
if (isWindows) {
pathCandidate += '.cmd';
}
}
return new Promise<string>((resolve, reject) => {
fileExists(pathCandidate, localExists => {
if (localExists) {
resolve(pathCandidate);
} else {
reject('OmniSharp does not exist at location: ' + pathCandidate);
}
});
});
}
const versionRegexp = /(\d+\.\d+\.\d+)/;
export function hasMono(range?: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
let childprocess: ChildProcess;
try {
childprocess = spawn('mono', ['--version']);
} catch (e) {
return resolve(false);
}
childprocess.on('error', function (err: any) {
resolve(false);
});
let stdout = '';
childprocess.stdout.on('data', (data: NodeBuffer) => {
stdout += data.toString();
});
childprocess.stdout.on('close', () => {
let match = versionRegexp.exec(stdout),
ret: boolean;
if (!match) {
ret = false;
} else if (!range) {
ret = true;
} else {
ret = satisfies(match[1], range);
}
resolve(ret);
});
});
}

View File

@ -0,0 +1,416 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export var GoToDefinition = '/gotoDefinition';
export var CodeCheck = '/codecheck';
export var AutoComplete = '/autocomplete';
export var CurrentFileMembersAsTree = '/currentfilemembersastree';
export var TypeLookup = '/typelookup';
export var AddToProject = '/addtoproject';
export var RemoveFromProject = '/removefromproject';
export var FindUsages = '/findusages';
export var FindSymbols = '/findsymbols';
export var CodeFormat = '/codeformat';
export var GetCodeActions = '/getcodeactions';
export var RunCodeAction = '/runcodeaction';
export var FormatAfterKeystroke = '/formatAfterKeystroke';
export var FormatRange = '/formatRange';
export var UpdateBuffer = '/updatebuffer';
export var ChangeBuffer = '/changebuffer';
export var Projects = '/projects';
export var Rename = '/rename';
export var FilesChanged = '/filesChanged';
export var SignatureHelp = '/signatureHelp';
export interface Request {
Filename: string;
Line?: number;
Column?: number;
Buffer?: string;
}
export interface ChangeBufferRequest {
FileName: string;
StartLine: number;
StartColumn: number;
EndLine: number;
EndColumn: number;
NewText: string;
}
export interface AddToProjectRequest extends Request {
//?
}
export interface RemoveFromProjectRequest extends Request {
//?
}
export interface FindUsagesRequest extends Request {
// MaxWidth: number; ?
OnlyThisFile: boolean;
ExcludeDefinition: boolean;
}
export interface FindSymbolsRequest extends Request {
Filter: string;
}
export interface FormatRequest extends Request {
ExpandTab: boolean;
}
export interface CodeActionRequest extends Request {
CodeAction: number;
WantsTextChanges?: boolean;
SelectionStartColumn?: number;
SelectionStartLine?: number;
SelectionEndColumn?: number;
SelectionEndLine?: number;
}
export interface FormatResponse {
Buffer: string;
}
export interface TextChange {
NewText: string;
StartLine: number;
StartColumn: number;
EndLine: number;
EndColumn: number;
}
export interface FormatAfterKeystrokeRequest extends Request {
Character: string;
}
export interface FormatRangeRequest extends Request {
EndLine: number;
EndColumn: number;
}
export interface FormatRangeResponse {
Changes: TextChange[];
}
export interface ResourceLocation {
FileName: string;
Line: number;
Column: number;
}
export interface Error {
Message: string;
Line: number;
Column: number;
EndLine: number;
EndColumn: number;
FileName: string;
}
export interface ErrorResponse {
Errors: Error[];
}
export interface QuickFix {
LogLevel: string;
FileName: string;
Line: number;
Column: number;
EndLine: number;
EndColumn: number;
Text: string;
Projects: string[];
}
export interface SymbolLocation extends QuickFix {
Kind: string;
}
export interface QuickFixResponse {
QuickFixes: QuickFix[];
}
export interface FindSymbolsResponse {
QuickFixes: SymbolLocation[];
}
export interface TypeLookupRequest extends Request {
IncludeDocumentation: boolean;
}
export interface TypeLookupResponse {
Type: string;
Documentation: string;
}
export interface RunCodeActionResponse {
Text: string;
Changes: TextChange[];
}
export interface GetCodeActionsResponse {
CodeActions: string[];
}
export interface Node {
ChildNodes: Node[];
Location: QuickFix;
Kind: string;
}
export interface CurrentFileMembersAsTreeResponse {
TopLevelTypeDefinitions: Node[];
}
export interface AutoCompleteRequest extends Request {
WordToComplete: string;
WantDocumentationForEveryCompletionResult?: boolean;
WantImportableTypes?: boolean;
WantMethodHeader?: boolean;
WantSnippet?: boolean;
WantReturnType?: boolean;
WantKind?: boolean;
}
export interface AutoCompleteResponse {
CompletionText: string;
Description: string;
DisplayText: string;
RequiredNamespaceImport: string;
MethodHeader: string;
ReturnType: string;
Snippet: string;
Kind: string;
}
export interface ProjectInformationResponse {
MsBuildProject: MSBuildProject;
DnxProject: DnxProject;
}
export interface WorkspaceInformationResponse {
MSBuild: MsBuildWorkspaceInformation;
Dnx: DnxWorkspaceInformation;
ScriptCs: ScriptCsContext;
}
export interface MsBuildWorkspaceInformation {
SolutionPath: string;
Projects: MSBuildProject[];
}
export interface ScriptCsContext {
CsxFiles: { [n: string]: string };
References: { [n: string]: string };
Usings: { [n: string]: string };
ScriptPacks: { [n: string]: string };
Path: string;
}
export interface MSBuildProject {
ProjectGuid: string;
Path: string;
AssemblyName: string;
TargetPath: string;
TargetFramework: string;
SourceFiles: string[];
}
export interface DnxWorkspaceInformation {
RuntimePath: string;
DesignTimeHostPort: number;
Projects: DnxProject[];
}
export interface DnxProject {
Path: string;
Name: string;
Commands: { [name: string]: string; };
Configurations: string[];
ProjectSearchPaths: string[];
Frameworks: DnxFramework[];
GlobalJsonPath: string;
SourceFiles: string[];
}
export interface DnxFramework {
Name: string;
FriendlyName: string;
ShortName: string;
}
export interface RenameRequest extends Request {
RenameTo: string;
WantsTextChanges?: boolean;
}
export interface ModifiedFileResponse {
FileName: string;
Buffer: string;
Changes: TextChange[];
}
export interface RenameResponse {
Changes: ModifiedFileResponse[];
}
export interface SignatureHelp {
Signatures: SignatureHelpItem[];
ActiveSignature: number;
ActiveParameter: number;
}
export interface SignatureHelpItem {
Name: string;
Label: string;
Documentation: string;
Parameters: SignatureHelpParameter[];
}
export interface SignatureHelpParameter {
Name: string;
Label: string;
Documentation: string;
}
export interface MSBuildProjectDiagnostics {
FileName: string;
Warnings: MSBuildDiagnosticsMessage[];
Errors: MSBuildDiagnosticsMessage[];
}
export interface MSBuildDiagnosticsMessage {
LogLevel: string;
FileName: string;
Text: string;
StartLine: number;
StartColumn: number;
EndLine: number;
EndColumn: number;
}
export interface ErrorMessage {
Text: string;
FileName: string;
Line: number;
Column: number;
}
export interface PackageRestoreMessage {
FileName: string;
Succeeded: boolean;
}
export interface UnresolvedDependenciesMessage {
FileName: string;
UnresolvedDependencies: PackageDependency[];
}
export interface PackageDependency {
Name: string;
Version: string;
}
export namespace V2 {
export var GetCodeActions = '/v2/getcodeactions';
export var RunCodeAction = '/v2/runcodeaction';
export interface Point {
Line: number;
Column: number;
}
export interface Range {
Start: Point;
End: Point;
}
export interface GetCodeActionsRequest extends Request {
Selection: Range
}
export interface OmniSharpCodeAction {
Identifier: string;
Name: string;
}
export interface GetCodeActionsResponse {
CodeActions: OmniSharpCodeAction[];
}
export interface RunCodeActionRequest extends Request {
Identifier: string;
Selection: Range;
WantsTextChanges: boolean;
}
export interface RunCodeActionResponse {
Changes: ModifiedFileResponse[];
}
export interface MSBuildProjectDiagnostics {
FileName: string;
Warnings: MSBuildDiagnosticsMessage[];
Errors: MSBuildDiagnosticsMessage[];
}
export interface MSBuildDiagnosticsMessage {
LogLevel: string;
FileName: string;
Text: string;
StartLine: number;
StartColumn: number;
EndLine: number;
EndColumn: number;
}
export interface ErrorMessage {
Text: string;
FileName: string;
Line: number;
Column: number;
}
export interface PackageRestoreMessage {
FileName: string;
Succeeded: boolean;
}
export interface UnresolvedDependenciesMessage {
FileName: string;
UnresolvedDependencies: PackageDependency[];
}
export interface PackageDependency {
Name: string;
Version: string;
}
}

View File

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as proto from './protocol';
import * as vscode from 'vscode';
export function toLocation(location: proto.ResourceLocation): vscode.Location {
let {FileName, Line, Column} = location;
return new vscode.Location(vscode.Uri.file(FileName), new vscode.Position(Line - 1, Column - 1));
}
export function toRange(rangeLike: { Line: number; Column: number; EndLine: number; EndColumn: number;}): vscode.Range {
let {Line, Column, EndLine, EndColumn} = rangeLike;
return new vscode.Range(Line - 1, Column - 1, EndLine - 1, EndColumn - 1);
}
export function toRange2(rangeLike: { StartLine: number; StartColumn: number; EndLine: number; EndColumn: number;}): vscode.Range {
let {StartLine, StartColumn, EndLine, EndColumn} = rangeLike;
return new vscode.Range(StartLine - 1, StartColumn - 1, EndLine - 1, EndColumn - 1);
}
export function createRequest<T extends proto.Request>(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer:boolean = false): T {
let Line: number, Column: number;
if (where instanceof vscode.Position) {
Line = where.line + 1;
Column = where.character + 1;
} else if(where instanceof vscode.Range) {
Line = where.start.line + 1;
Column = where.start.character + 1
}
let request: proto.Request = {
Filename: document.fileName,
Buffer: includeBuffer ? document.getText() : undefined,
Line,
Column
};
return <T>request;
}
export function toDocumentSymbol(bucket: vscode.SymbolInformation[], node: proto.Node, containerLabel?: string): void {
let ret = new vscode.SymbolInformation(node.Location.Text, kinds[node.Kind],
toRange(node.Location),
undefined, containerLabel);
if (node.ChildNodes) {
for (let child of node.ChildNodes) {
toDocumentSymbol(bucket, child, ret.name)
}
}
bucket.push(ret);
}
var kinds: { [kind: string]: vscode.SymbolKind; } = Object.create(null);
kinds['NamespaceDeclaration'] = vscode.SymbolKind.Namespace;
kinds['ClassDeclaration'] = vscode.SymbolKind.Class;
kinds['FieldDeclaration'] = vscode.SymbolKind.Field;
kinds['PropertyDeclaration'] = vscode.SymbolKind.Property;
kinds['EventFieldDeclaration'] = vscode.SymbolKind.Property;
kinds['MethodDeclaration'] = vscode.SymbolKind.Method;
kinds['EnumDeclaration'] = vscode.SymbolKind.Enum;
kinds['StructDeclaration'] = vscode.SymbolKind.Enum;
kinds['EnumMemberDeclaration'] = vscode.SymbolKind.Property;
kinds['InterfaceDeclaration'] = vscode.SymbolKind.Interface;
kinds['VariableDeclaration'] = vscode.SymbolKind.Variable;

View File

@ -0,0 +1,69 @@
declare class Client {
public context: any;
public config: any;
public trackEvent(eventName: string, properties: {[key: string]: string}, measures?: {[key: string]: number}): void;
}
declare class ApplicationInsights {
static client: Client;
/**
* Initializes a client with the given instrumentation key, if this is not specified, the value will be
* read from the environment variable APPINSIGHTS_INSTRUMENTATIONKEY
* @returns {ApplicationInsights/Client} a new client
*/
static getClient(instrumentationKey?: string): Client;
/**
* Initializes the default client of the client and sets the default configuration
* @param instrumentationKey the instrumentation key to use. Optional, if this is not specified, the value will be
* read from the environment variable APPINSIGHTS_INSTRUMENTATIONKEY
* @returns {ApplicationInsights} this class
*/
static setup(instrumentationKey?: string): typeof ApplicationInsights;
/**
* Starts automatic collection of telemetry. Prior to calling start no telemetry will be collected
* @returns {ApplicationInsights} this class
*/
static start(): typeof ApplicationInsights;
/**
* Sets the state of console tracking (enabled by default)
* @param value if true console activity will be sent to Application Insights
* @returns {ApplicationInsights} this class
*/
static setAutoCollectConsole(value: boolean): typeof ApplicationInsights;
/**
* Sets the state of exception tracking (enabled by default)
* @param value if true uncaught exceptions will be sent to Application Insights
* @returns {ApplicationInsights} this class
*/
static setAutoCollectExceptions(value: boolean): typeof ApplicationInsights;
/**
* Sets the state of performance tracking (enabled by default)
* @param value if true performance counters will be collected every second and sent to Application Insights
* @returns {ApplicationInsights} this class
*/
static setAutoCollectPerformance(value: boolean): typeof ApplicationInsights;
/**
* Sets the state of request tracking (enabled by default)
* @param value if true requests will be sent to Application Insights
* @returns {ApplicationInsights} this class
*/
static setAutoCollectRequests(value: boolean): typeof ApplicationInsights;
/**
* Sets the state of enabling offline mode to cache event when client is offline (disabled by default)
* @param value if true events that happen while client is offline will be cahced on disk,
* client will retry to send events when back online
* @returns {ApplicationInsights} this class
*/
public static setOfflineMode(value: boolean): typeof ApplicationInsights;
/**
* Enables verbose debug logging
* @returns {ApplicationInsights} this class
*/
static enableVerboseLogging(): typeof ApplicationInsights;
}
declare module 'applicationinsights' {
export = ApplicationInsights;
}

View File

@ -0,0 +1,10 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/typings/mocha.d.ts'/>
/// <reference path='../../../../extensions/declares.d.ts'/>
/// <reference path='../../../../extensions/node.d.ts'/>
/// <reference path='../../../../extensions/lib.core.d.ts'/>

View File

@ -0,0 +1,125 @@
// Type definitions for semver v2.2.1
// Project: https://github.com/isaacs/node-semver
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module SemVerModule {
/**
* Return the parsed version, or null if it's not valid.
*/
function valid(v: string, loose?: boolean): string;
/**
* Return the version incremented by the release type (major, minor, patch, or prerelease), or null if it's not valid.
*/
function inc(v: string, release: string, loose?: boolean): string;
// Comparison
/**
* v1 > v2
*/
function gt(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 >= v2
*/
function gte(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 < v2
*/
function lt(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 <= v2
*/
function lte(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 == v2 This is true if they're logically equivalent, even if they're not the exact same string. You already know how to compare strings.
*/
function eq(v1: string, v2: string, loose?: boolean): boolean;
/**
* v1 != v2 The opposite of eq.
*/
function neq(v1: string, v2: string, loose?: boolean): boolean;
/**
* Pass in a comparison string, and it'll call the corresponding semver comparison function. "===" and "!==" do simple string comparison, but are included for completeness. Throws if an invalid comparison string is provided.
*/
function cmp(v1: string, comparator: any, v2: string, loose?: boolean): boolean;
/**
* Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if v2 is greater. Sorts in ascending order if passed to Array.sort().
*/
function compare(v1: string, v2: string, loose?: boolean): number;
/**
* The reverse of compare. Sorts an array of versions in descending order when passed to Array.sort().
*/
function rcompare(v1: string, v2: string, loose?: boolean): number;
// Ranges
/**
* Return the valid range or null if it's not valid
*/
function validRange(range: string, loose?: boolean): string;
/**
* Return true if the version satisfies the range.
*/
function satisfies(version: string, range: string, loose?: boolean): boolean;
/**
* Return the highest version in the list that satisfies the range, or null if none of them do.
*/
function maxSatisfying(versions: string[], range: string, loose?: boolean): string;
/**
* Return true if version is greater than all the versions possible in the range.
*/
function gtr(version: string, range: string, loose?: boolean): boolean;
/**
* Return true if version is less than all the versions possible in the range.
*/
function ltr(version: string, range: string, loose?: boolean): boolean;
/**
* Return true if the version is outside the bounds of the range in either the high or low direction. The hilo argument must be either the string '>' or '<'. (This is the function called by gtr and ltr.)
*/
function outside(version: string, range: string, hilo: string, loose?: boolean): boolean;
class SemVerBase {
raw: string;
loose: boolean;
format(): string;
inspect(): string;
toString(): string;
}
class SemVer extends SemVerBase {
constructor(version: string, loose?: boolean);
major: number;
minor: number;
patch: number;
version: string;
build: string[];
prerelease: string[];
compare(other:SemVer): number;
compareMain(other:SemVer): number;
comparePre(other:SemVer): number;
inc(release: string): SemVer;
}
class Comparator extends SemVerBase {
constructor(comp: string, loose?: boolean);
semver: SemVer;
operator: string;
value: boolean;
parse(comp: string): void;
test(version:SemVer): boolean;
}
class Range extends SemVerBase {
constructor(range: string, loose?: boolean);
set: Comparator[][];
parseRange(range: string): Comparator[];
test(version: SemVer): boolean;
}
}
declare module "semver" {
export = SemVerModule;
}

View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"noLib": true,
"target": "ES5",
"module": "commonjs",
"outDir": "out",
"sourceMap": true
},
"exclude": [
"node_modules"
]
}

View File

@ -0,0 +1,7 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "language-csharp",
"version": "0.11.0",
"license": "Dual-licensed under MIT and GPL",
"repositoryURL": "https://github.com/atom/language-csharp"
}]

View File

@ -0,0 +1,18 @@
{
"name": "csharp",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "csharp",
"extensions": [ ".cs", ".csx" ],
"aliases": [ "C#", "csharp" ]
}],
"grammars": [{
"language": "csharp",
"scopeName": "source.cs",
"path": "./syntaxes/csharp.json"
}]
}
}

View File

@ -0,0 +1,566 @@
{
"scopeName": "source.cs",
"name": "C#",
"fileTypes": [
"cs"
],
"foldingStartMarker": "^\\s*#\\s*region|^\\s*/\\*|^(?![^{]*?//|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|//|/\\*(?!.*?\\*/.*\\S))",
"foldingStopMarker": "^\\s*#\\s*endregion|^\\s*\\*/|^\\s*\\}",
"patterns": [
{
"captures": {
"1": {
"name": "keyword.other.using.cs"
}
},
"begin": "^\\s*(using)\\b\\s*",
"end": "\\s*(?:$|(;))",
"name": "meta.keyword.using.cs"
},
{
"begin": "^\\s*((namespace)\\s+([\\w.]+))",
"beginCaptures": {
"1": {
"name": "meta.namespace.identifier.cs"
},
"2": {
"name": "keyword.other.namespace.cs"
},
"3": {
"name": "entity.name.type.namespace.cs"
}
},
"end": "}",
"endCaptures": {
"0": {
"name": "punctuation.section.namespace.end.cs"
}
},
"name": "meta.namespace.cs",
"patterns": [
{
"begin": "{",
"beginCaptures": {
"0": {
"name": "punctuation.section.namespace.begin.cs"
}
},
"end": "(?=})",
"name": "meta.namespace.body.cs",
"patterns": [
{
"include": "#code"
}
]
}
]
},
{
"include": "#code"
}
],
"repository": {
"block": {
"patterns": [
{
"begin": "{",
"beginCaptures": {
"0": {
"name": "punctuation.section.block.begin.cs"
}
},
"end": "}",
"endCaptures": {
"0": {
"name": "punctuation.section.block.end.cs"
}
},
"name": "meta.block.cs",
"patterns": [
{
"include": "#code"
}
]
}
]
},
"builtinTypes": {
"patterns": [
{
"match": "\\b(bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|class|struct|enum|interface)\\b",
"name": "storage.type.cs"
}
]
},
"class": {
"begin": "(?=\\w?[\\w\\s]*(?:class|struct|interface|enum)\\s+\\w+)",
"end": "}",
"endCaptures": {
"0": {
"name": "punctuation.section.class.end.cs"
}
},
"name": "meta.class.cs",
"patterns": [
{
"include": "#storage-modifiers"
},
{
"include": "#comments"
},
{
"captures": {
"1": {
"name": "storage.modifier.cs"
},
"2": {
"name": "entity.name.type.class.cs"
}
},
"match": "(class|struct|interface|enum)\\s+(\\w+)",
"name": "meta.class.identifier.cs"
},
{
"begin": ":",
"end": "(?={)",
"patterns": [
{
"captures": {
"1": {
"name": "storage.type.cs"
}
},
"match": "\\s*,?([A-Za-z_]\\w*)\\b"
}
]
},
{
"begin": "{",
"beginCaptures": {
"0": {
"name": "punctuation.section.class.begin.cs"
}
},
"end": "(?=})",
"name": "meta.class.body.cs",
"patterns": [
{
"include": "#method"
},
{
"include": "#code"
}
]
}
]
},
"code": {
"patterns": [
{
"include": "#block"
},
{
"include": "#comments"
},
{
"include": "#class"
},
{
"include": "#constants"
},
{
"include": "#storage-modifiers"
},
{
"include": "#keywords"
},
{
"include": "#preprocessor"
},
{
"include": "#method-call"
},
{
"include": "#builtinTypes"
},
{
"include": "#documentation"
}
]
},
"comments": {
"patterns": [
{
"begin": "///",
"captures": {
"0": {
"name": "punctuation.definition.comment.cs"
}
},
"end": "$\\n?",
"name": "comment.block.documentation.cs",
"patterns": [
{
"include": "text.xml"
}
]
},
{
"begin": "/\\*",
"captures": {
"0": {
"name": "punctuation.definition.comment.cs"
}
},
"end": "\\*/\\n?",
"name": "comment.block.cs"
},
{
"begin": "//",
"captures": {
"1": {
"name": "punctuation.definition.comment.cs"
}
},
"end": "$\\n?",
"name": "comment.line.double-slash.cs"
}
]
},
"constants": {
"patterns": [
{
"match": "\\b(true|false|null|this|base)\\b",
"name": "constant.language.cs"
},
{
"match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b",
"name": "constant.numeric.cs"
},
{
"captures": {
"0": {
"name": "punctuation.definition.string.begin.cs"
}
},
"match": "@\"([^\"]|\"\")*\"",
"name": "string.quoted.double.literal.cs"
},
{
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.cs"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.cs"
}
},
"name": "string.quoted.double.cs",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.cs"
}
]
},
{
"begin": "'",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.cs"
}
},
"end": "'",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.cs"
}
},
"name": "string.quoted.single.cs",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.cs"
}
]
}
]
},
"keywords": {
"patterns": [
{
"match": "\\b(if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await)\\b",
"name": "keyword.control.cs"
},
{
"match": "\\b(from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending)\\b",
"name": "keyword.linq.cs"
},
{
"match": "\\b(new|is|as|using|checked|unchecked|typeof|sizeof|override|readonly|stackalloc)\\b",
"name": "keyword.operator.cs"
},
{
"match": "\\b(event|delegate|fixed|add|remove|set|get|value)\\b",
"name": "keyword.other.cs"
},
{
"match": "\\b(var)\\b",
"name": "storage.type.var.cs"
},
{
"match": "[@]\\b(var|event|delegate|add|remove|set|get|value|new|is|as|using|checked|unchecked|typeof|sizeof |override|readonly|stackalloc|from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending |if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await)\\b",
"name": "meta.class.body.cs"
}
]
},
"method": {
"patterns": [
{
"begin": "\\[",
"end": "\\]",
"name": "meta.method.annotation.cs",
"patterns": [
{
"include": "#constants"
},
{
"include": "#preprocessor"
},
{
"include": "#builtinTypes"
}
]
},
{
"begin": "(?=\\bnew\\s+)(?=[\\w<].*\\s+)(?=[^=]+\\()",
"end": "(?={|;)",
"name": "meta.new-object.cs",
"patterns": [
{
"include": "#code"
}
]
},
{
"begin": "(?<!=|=\\s)(?!new)(?!.*(=|\\/\\/|\\/\\*).*\\()(?=[\\w<].*\\s+.+\\()",
"end": "(})|(?=;)",
"endCaptures": {
"1": {
"name": "punctuation.section.method.end.cs"
}
},
"name": "meta.method.cs",
"patterns": [
{
"include": "#storage-modifiers"
},
{
"include": "#builtinTypes"
},
{
"begin": "([\\w.]+)\\s*\\(",
"beginCaptures": {
"1": {
"name": "entity.name.function.cs"
}
},
"end": "\\)",
"name": "meta.method.identifier.cs",
"patterns": [
{
"include": "#parameters"
},
{
"include": "#constants"
}
]
},
{
"begin": "(?=\\w.*\\s+[\\w.]+\\s*\\()",
"end": "(?=[\\w.]+\\s*\\()",
"name": "meta.method.return-type.cs",
"patterns": [
{
"include": "#builtinTypes"
}
]
},
{
"begin": ":\\s*(this|base)\\s*\\(",
"beginCaptures": {
"1": {
"name": "constant.language.cs"
}
},
"end": "\\)",
"name": "meta.method.base-call.cs",
"patterns": [
{
"include": "#builtinTypes"
}
]
},
{
"begin": "{",
"beginCaptures": {
"0": {
"name": "punctuation.section.method.begin.cs"
}
},
"end": "(?=})",
"name": "meta.method.body.cs",
"patterns": [
{
"include": "#code"
}
]
}
]
},
{
"begin": "(?!new)(?=[\\w<].*\\s+)(?=[^=]+\\{)",
"end": "}",
"endCaptures": {
"0": {
"name": "punctuation.section.property.end.cs"
}
},
"name": "meta.property.cs",
"patterns": [
{
"include": "#storage-modifiers"
},
{
"begin": "([\\w.]+)\\s*(?={)",
"captures": {
"1": {
"name": "entity.name.function.cs"
}
},
"end": "(?={)",
"name": "meta.method.identifier.cs"
},
{
"begin": "(?=\\w.*\\s+[\\w.]+\\s*\\{)",
"end": "(?=[\\w.]+\\s*\\{)",
"name": "meta.method.return-type.cs",
"patterns": [
{
"include": "#builtinTypes"
}
]
},
{
"begin": "{",
"beginCaptures": {
"0": {
"name": "punctuation.section.property.begin.cs"
}
},
"end": "(?=})",
"name": "meta.method.body.cs",
"patterns": [
{
"include": "#code"
}
]
}
]
}
]
},
"method-call": {
"begin": "([\\w$]+)\\s*(\\()",
"beginCaptures": {
"1": {
"name": "meta.method.cs"
},
"2": {
"name": "punctuation.definition.method-parameters.begin.cs"
}
},
"end": "\\)",
"endCaptures": {
"0": {
"name": "punctuation.definition.method-parameters.end.cs"
}
},
"name": "meta.method-call.cs",
"patterns": [
{
"match": ",",
"name": "punctuation.definition.seperator.parameter.cs"
},
{
"include": "#code"
}
]
},
"parameters": {
"begin": "\\b(ref|params|out)?\\s*\\b([\\w.\\[\\]]+)\\s+(\\w+)\\s*(=)?",
"beginCaptures": {
"1": {
"name": "storage.type.modifier.cs"
},
"2": {
"name": "storage.type.generic.cs"
},
"3": {
"name": "variable.parameter.function.cs"
},
"4": {
"name": "keyword.operator.assignment.cs"
}
},
"end": "(?:(,)|(?=[\\)]))",
"endCaptures": {
"1": {
"name": "punctuation.definition.separator.parameter.cs"
}
},
"patterns": [
{
"include": "#constants"
},
{
"include": "#block"
}
]
},
"preprocessor": {
"patterns": [
{
"captures": {
"2": {
"name": "meta.toc-list.region.cs"
}
},
"match": "^\\s*#\\s*(region)\\b\\s*([^\\/]+)\\s",
"name": "meta.preprocessor.cs"
},
{
"captures": {
"2": {
"name": "entity.name.function.preprocessor.cs"
}
},
"match": "^\\s*#\\s*(define|undef|if|elif)\\b\\s*(\\S*)",
"name": "meta.preprocessor.cs"
},
{
"match": "^\\s*#\\s*(if|else|elif|endif|define|undef|warning|error|line|pragma|region|endregion)\\b\\s*([^\\/]+)\\s",
"name": "meta.preprocessor.cs"
}
]
},
"storage-modifiers": {
"match": "\\b(event|delegate|internal|public|protected|private|static|const|new|sealed|abstract|virtual|override|extern|unsafe|readonly|volatile|implicit|explicit|operator|async|partial)\\b",
"name": "storage.modifier.cs"
}
}
}

View File

@ -0,0 +1,22 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "textmate/css.tmbundle",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/css.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-css.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this folder fall under the following license: ",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information, ",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added ",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example ",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
}]

View File

@ -0,0 +1,23 @@
{
"name": "css",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "css",
"aliases": ["CSS", "css"],
"extensions": [".css"],
"mimetypes": ["text/css"]
}],
"grammars": [{
"language": "css",
"scopeName": "source.css",
"path": "./syntaxes/css.plist"
}],
"snippets": [{
"language": "css",
"path": "./snippets/css.json"
}]
}
}

View File

@ -0,0 +1,19 @@
{
"transition property": {
"prefix": "transition",
"body": [
"transition: ${property} ${duration} ${timing-function} ${delay};",
"-webkit-transition: ${property} ${duration} ${timing-function} ${delay};",
"-o-transition: ${property} ${duration} ${timing-function} ${delay};",
"-moz-transition: ${property} ${duration} ${timing-function} ${delay};"
],
"description": "The transition property across browsers"
},
"border": {
"prefix": "border",
"body": [
"border: ${width} ${border-style} ${color};$0"
],
"description": "[width] [border-style] [color]"
}
}

View File

@ -0,0 +1,997 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>css</string>
<string>css.erb</string>
</array>
<key>keyEquivalent</key>
<string>^~C</string>
<key>name</key>
<string>CSS</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#comment-block</string>
</dict>
<dict>
<key>include</key>
<string>#selector</string>
</dict>
<dict>
<key>begin</key>
<string>\s*((@)charset\b)\s*</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.at-rule.charset.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.keyword.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*((?=;|$))</string>
<key>name</key>
<string>meta.at-rule.charset.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string-double</string>
</dict>
<dict>
<key>include</key>
<string>#string-single</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>\s*((@)import\b)\s*</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.at-rule.import.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.keyword.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*((?=;|\}))</string>
<key>name</key>
<string>meta.at-rule.import.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string-double</string>
</dict>
<dict>
<key>include</key>
<string>#string-single</string>
</dict>
<dict>
<key>begin</key>
<string>\s*(url)\s*(\()\s*</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.url.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*(\))\s*</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>[^'") \t]+</string>
<key>name</key>
<string>variable.parameter.url.css</string>
</dict>
<dict>
<key>include</key>
<string>#string-single</string>
</dict>
<dict>
<key>include</key>
<string>#string-double</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>#media-query-list</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>^\s*((@)font-face)\s*(?=\{)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.at-rule.font-face.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.keyword.css</string>
</dict>
</dict>
<key>end</key>
<string>(?!\G)</string>
<key>name</key>
<string>meta.at-rule.font-face.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#rule-list</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(?=^\s*@media\s*.*?\{)</string>
<key>end</key>
<string>\s*(\})</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.property-list.end.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>^\s*((@)media)(?=.*?\{)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.at-rule.media.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.keyword.css</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>support.constant.media.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*(?=\{)</string>
<key>name</key>
<string>meta.at-rule.media.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#media-query-list</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>\s*(\{)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.property-list.begin.css</string>
</dict>
</dict>
<key>end</key>
<string>(?=\})</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(?=\{)</string>
<key>end</key>
<string>(?!\G)</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#rule-list</string>
</dict>
</array>
</dict>
</array>
<key>repository</key>
<dict>
<key>color-values</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>comment</key>
<string>http://www.w3.org/TR/CSS21/syndata.html#value-def-color</string>
<key>match</key>
<string>\b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b</string>
<key>name</key>
<string>support.constant.color.w3c-standard-color-name.css</string>
</dict>
<dict>
<key>comment</key>
<string>These colours are mostly recognised but will not validate. ref: http://www.w3schools.com/css/css_colornames.asp</string>
<key>match</key>
<string>\b(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen)\b</string>
<key>name</key>
<string>invalid.deprecated.color.w3c-non-standard-color-name.css</string>
</dict>
<dict>
<key>begin</key>
<string>(hsla?|rgba?)\s*(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.misc.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>end</key>
<string>(\))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?x)\b
(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*){2}
(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\b)
(\s*,\s*((0?\.[0-9]+)|[0-1]))?
</string>
<key>name</key>
<string>constant.other.color.rgb-value.css</string>
</dict>
<dict>
<key>match</key>
<string>\b([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%</string>
<key>name</key>
<string>constant.other.color.rgb-percentage.css</string>
</dict>
<dict>
<key>include</key>
<string>#numeric-values</string>
</dict>
</array>
</dict>
</array>
</dict>
<key>comment-block</key>
<dict>
<key>begin</key>
<string>/\*</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.css</string>
</dict>
</dict>
<key>end</key>
<string>\*/</string>
<key>name</key>
<string>comment.block.css</string>
</dict>
<key>media-query</key>
<dict>
<key>begin</key>
<string>(?i)\s*(only|not)?\s*(all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)?</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.operator.logic.media.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>support.constant.media.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*(?:(,)|(?=[{;]))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.arbitrary-repitition.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>\s*(and)?\s*(\()\s*</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.operator.logic.media.css</string>
</dict>
</dict>
<key>end</key>
<string>\)</string>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(?x)
(
((min|max)-)?
(
((device-)?(height|width|aspect-ratio))|
(color(-index)?)|monochrome|resolution
)
)|grid|scan|orientation
\s*(?=[:)])</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>support.type.property-name.media.css</string>
</dict>
</dict>
<key>end</key>
<string>(:)|(?=\))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.separator.key-value.css</string>
</dict>
</dict>
</dict>
<dict>
<key>match</key>
<string>\b(portrait|landscape|progressive|interlace)</string>
<key>name</key>
<string>support.constant.property-value.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>constant.numeric.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.operator.arithmetic.css</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>constant.numeric.css</string>
</dict>
</dict>
<key>match</key>
<string>\s*(\d+)(/)(\d+)</string>
</dict>
<dict>
<key>include</key>
<string>#numeric-values</string>
</dict>
</array>
</dict>
</array>
</dict>
<key>media-query-list</key>
<dict>
<key>begin</key>
<string>\s*(?=[^{;])</string>
<key>end</key>
<string>\s*(?=[{;])</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#media-query</string>
</dict>
</array>
</dict>
<key>numeric-values</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.css</string>
</dict>
</dict>
<key>match</key>
<string>(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b</string>
<key>name</key>
<string>constant.other.color.rgb-value.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.other.unit.css</string>
</dict>
</dict>
<key>match</key>
<string>(?x)
(?:-|\+)?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))
((?:px|pt|ch|cm|mm|in|r?em|ex|pc|deg|g?rad|dpi|dpcm|s)\b|%)?
</string>
<key>name</key>
<string>constant.numeric.css</string>
</dict>
</array>
</dict>
<key>property-values</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\b(absolute|all(-scroll)?|always|armenian|auto|avoid|baseline|below|bidi-override|block|bold|bolder|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|geometricPrecision|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|optimize(Legibility|Quality|Speed)|outset|outside|overline|pointer|pre(-(wrap|line))?|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|sub|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical(-(ideographic|text))?|visible(Painted|Fill|Stroke)?|w-resize|wait|whitespace|zero|smaller|larger|((xx?-)?(small|large))|painted|fill|stroke)\b</string>
<key>name</key>
<string>support.constant.property-value.css</string>
</dict>
<dict>
<key>match</key>
<string>(\b(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace)\b)</string>
<key>name</key>
<string>support.constant.font-name.css</string>
</dict>
<dict>
<key>include</key>
<string>#numeric-values</string>
</dict>
<dict>
<key>include</key>
<string>#color-values</string>
</dict>
<dict>
<key>include</key>
<string>#string-double</string>
</dict>
<dict>
<key>include</key>
<string>#string-single</string>
</dict>
<dict>
<key>begin</key>
<string>(rect)\s*(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.misc.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>end</key>
<string>(\))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#numeric-values</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(format|local|url|attr|counter|counters)\s*(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.function.misc.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>end</key>
<string>(\))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string-single</string>
</dict>
<dict>
<key>include</key>
<string>#string-double</string>
</dict>
<dict>
<key>match</key>
<string>[^'") \t]+</string>
<key>name</key>
<string>variable.parameter.misc.css</string>
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>\!\s*important</string>
<key>name</key>
<string>keyword.other.important.css</string>
</dict>
</array>
</dict>
<key>rule-list</key>
<dict>
<key>begin</key>
<string>\{</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.property-list.begin.css</string>
</dict>
</dict>
<key>end</key>
<string>\}</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.property-list.end.css</string>
</dict>
</dict>
<key>name</key>
<string>meta.property-list.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#comment-block</string>
</dict>
<dict>
<key>begin</key>
<string>(?&lt;![-a-z])(?=[-a-z])</string>
<key>end</key>
<string>$|(?![-a-z])</string>
<key>name</key>
<string>meta.property-name.css</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\b(-webkit-[A-Za-z]+|-moz-[A-Za-z]+|-o-[A-Za-z]+|-ms-[A-Za-z]+|-khtml-[A-Za-z]+|zoom|z-index|y|x|wrap|word-wrap|word-spacing|word-break|word|width|widows|white-space-collapse|white-space|white|weight|volume|voice-volume|voice-stress|voice-rate|voice-pitch-range|voice-pitch|voice-family|voice-duration|voice-balance|voice|visibility|vertical-align|variant|user-select|up|unicode-bidi|unicode|trim|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform|top-width|top-style|top-right-radius|top-left-radius|top-color|top|timing-function|text-wrap|text-transform|text-shadow|text-replace|text-outline|text-justify|text-indent|text-height|text-emphasis|text-decoration|text-align-last|text-align|text|target-position|target-new|target-name|target|table-layout|tab-size|style-type|style-position|style-image|style|string-set|stretch|stress|stacking-strategy|stacking-shift|stacking-ruby|stacking|src|speed|speech-rate|speech|speak-punctuation|speak-numeral|speak-header|speak|span|spacing|space-collapse|space|sizing|size-adjust|size|shadow|respond-to|rule-width|rule-style|rule-color|rule|ruby-span|ruby-position|ruby-overhang|ruby-align|ruby|rows|rotation-point|rotation|role|right-width|right-style|right-color|right|richness|rest-before|rest-after|rest|resource|resolution|resize|reset|replace|repeat|rendering-intent|rate|radius|quotes|punctuation-trim|punctuation|property|profile|presentation-level|presentation|position|pointer-events|point|play-state|play-during|play-count|pitch-range|pitch|phonemes|pause-before|pause-after|pause|page-policy|page-break-inside|page-break-before|page-break-after|page|padding-top|padding-right|padding-left|padding-bottom|padding|pack|overhang|overflow-y|overflow-x|overflow-style|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|origin|orientation|orient|ordinal-group|opacity|offset|numeral|new|nav-up|nav-right|nav-left|nav-index|nav-down|nav|name|move-to|model|min-width|min-height|min|max-width|max-height|max|marquee-style|marquee-speed|marquee-play-count|marquee-direction|marquee|marks|mark-before|mark-after|mark|margin-top|margin-right|margin-left|margin-bottom|margin|mask-image|list-style-type|list-style-position|list-style-image|list-style|list|lines|line-stacking-strategy|line-stacking-shift|line-stacking-ruby|line-stacking|line-height|line|level|letter-spacing|length|left-width|left-style|left-color|left|label|justify|iteration-count|inline-box-align|initial-value|initial-size|initial-before-align|initial-before-adjust|initial-after-align|initial-after-adjust|index|indent|increment|image-resolution|image-orientation|image|icon|hyphens|hyphenate-resource|hyphenate-lines|hyphenate-character|hyphenate-before|hyphenate-after|hyphenate|height|header|hanging-punctuation|grid-rows|grid-columns|grid|gap|font-weight|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-family|font|float-offset|float|flex-group|flex|fit-position|fit|fill|filter|family|empty-cells|emphasis|elevation|duration|drop-initial-value|drop-initial-size|drop-initial-before-align|drop-initial-before-adjust|drop-initial-after-align|drop-initial-after-adjust|drop|down|dominant-baseline|display-role|display-model|display|direction|delay|decoration-break|decoration|cursor|cue-before|cue-after|cue|crop|counter-reset|counter-increment|counter|count|content|columns|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|column-break-before|column-break-after|column|color-profile|color|collapse|clip|clear|character|caption-side|break-inside|break-before|break-after|break|box-sizing|box-shadow|box-pack|box-orient|box-ordinal-group|box-lines|box-flex-group|box-flex|box-direction|box-decoration-break|box-align|box|bottom-width|bottom-style|bottom-right-radius|bottom-left-radius|bottom-color|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-length|border-left-width|border-left-style|border-left-color|border-left|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|bookmark-target|bookmark-level|bookmark-label|bookmark|binding|bidi|before|baseline-shift|baseline|balance|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-break|background-attachment|background|azimuth|attachment|appearance|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-duration|animation-direction|animation-delay|animation|alignment-baseline|alignment-adjust|alignment|align-last|align|after|adjust)\b</string>
<key>name</key>
<string>support.type.property-name.css</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(:)\s*</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.separator.key-value.css</string>
</dict>
</dict>
<key>end</key>
<string>\s*(;|(?=\}))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.terminator.rule.css</string>
</dict>
</dict>
<key>name</key>
<string>meta.property-value.css</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#property-values</string>
</dict>
</array>
</dict>
</array>
</dict>
<key>selector</key>
<dict>
<key>begin</key>
<string>\s*(?=[:.*#a-zA-Z])</string>
<key>end</key>
<string>(?=[/@{)])</string>
<key>name</key>
<string>meta.selector.css</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\b</string>
<key>name</key>
<string>entity.name.tag.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(\.)[a-zA-Z0-9_-]+</string>
<key>name</key>
<string>entity.other.attribute-name.class.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(#)[a-zA-Z][a-zA-Z0-9_-]*</string>
<key>name</key>
<string>entity.other.attribute-name.id.css</string>
</dict>
<dict>
<key>match</key>
<string>\*</string>
<key>name</key>
<string>entity.name.tag.wildcard.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(:+)(after|before|first-letter|first-line|selection)\b</string>
<key>name</key>
<string>entity.other.attribute-name.pseudo-element.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(:)((first|last)-child|(first|last|only)-of-type|empty|root|target|first|left|right)\b</string>
<key>name</key>
<string>entity.other.attribute-name.pseudo-class.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(:)(checked|enabled|default|disabled|indeterminate|invalid|optional|required|valid)\b</string>
<key>name</key>
<string>entity.other.attribute-name.pseudo-class.ui-state.css</string>
</dict>
<dict>
<key>begin</key>
<string>((:)not)(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.pseudo-class.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>end</key>
<string>\)</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#selector</string>
</dict>
</array>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.pseudo-class.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>constant.numeric.css</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>punctuation.section.function.css</string>
</dict>
</dict>
<key>match</key>
<string>((:)nth-(?:(?:last-)?child|(?:last-)?of-type))(\()(\-?(?:\d+n?|n)(?:\+\d+)?|even|odd)(\))</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
</dict>
<key>match</key>
<string>(:)(active|hover|link|visited|focus)\b</string>
<key>name</key>
<string>entity.other.attribute-name.pseudo-class.css</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.css</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.attribute.css</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.separator.operator.css</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>string.unquoted.attribute-value.css</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>string.quoted.double.attribute-value.css</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.css</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.css</string>
</dict>
</dict>
<key>match</key>
<string>(?i)(\[)\s*(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)(?:\s*([~|^$*]?=)\s*(?:(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)|((?&gt;(['"])(?:[^\\]|\\.)*?(\6)))))?\s*(\])</string>
<key>name</key>
<string>meta.attribute-selector.css</string>
</dict>
</array>
</dict>
<key>string-double</key>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.css</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.css</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.css</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escape.css</string>
</dict>
</array>
</dict>
<key>string-single</key>
<dict>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.css</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.css</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.css</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escape.css</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>source.css</string>
<key>uuid</key>
<string>69AA0917-B7BB-11D9-A7E2-000D93C8BE28</string>
</dict>
</plist>

98
extensions/declares.d.ts vendored Normal file
View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path="../src/vs/vscode.d.ts" />
/// <reference path="../src/typings/mocha.d.ts" />
/// <reference path="./node.d.ts" />
declare var define: {
(moduleName: string, dependencies: string[], callback: (...args: any[]) => any): any;
(moduleName: string, dependencies: string[], definition: any): any;
(moduleName: string, callback: (...args: any[]) => any): any;
(moduleName: string, definition: any): any;
(dependencies: string[], callback: (...args: any[]) => any): any;
(dependencies: string[], definition: any): any;
};
declare var require: {
toUrl(path: string): string;
(moduleName: string): any;
(dependencies: string[], callback: (...args: any[]) => any, errorback?: (err: any) => void): any;
config(data: any): any;
onError: Function;
__$__nodeRequire<T>(moduleName: string): T;
};
// Declaring the following because the code gets compiled with es5, which lack definitions for console and timers.
declare var console: {
info(message?: any, ...optionalParams: any[]): void;
profile(reportName?: string): void;
assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
clear(): void;
dir(value?: any, ...optionalParams: any[]): void;
warn(message?: any, ...optionalParams: any[]): void;
error(message?: any, ...optionalParams: any[]): void;
log(message?: any, ...optionalParams: any[]): void;
profileEnd(): void;
};
declare function clearTimeout(handle: number): void;
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
declare function clearInterval(handle: number): void;
declare function setInterval(handler: any, timeout?: any, ...args: any[]): number;
declare module 'vs/base/common/async' {
import vscode = require('vscode');
export interface ITask<T> {
(): T;
}
export class Delayer<T> {
public defaultDelay: number;
constructor(defaultDelay: number);
public trigger(task: ITask<T>, delay?: number): Thenable<T>;
public isTriggered():boolean;
public cancel(): void;
}
export class RunOnceScheduler {
constructor(runner:()=>void, timeout:number);
public dispose(): void;
public cancel(): void;
public schedule(): void;
}
}
declare module 'vs/base/node/stdFork' {
import cp = require('child_process');
export interface IForkOpts {
cwd?: string;
env?: any;
encoding?: string;
execArgv?: string[];
}
export function fork(modulePath: string, args: string[], options: IForkOpts, callback:(error:any, cp:cp.ChildProcess)=>void): void;
}
// Needed by TypeScript plugin to avoid code duplication
declare module 'vs/languages/lib/common/wireProtocol' {
import stream = require('stream');
export interface ICallback<T> {
(data:T):void;
}
export enum ReaderType {
Length = 0,
Line = 1
}
export class Reader<T> {
constructor(readable: stream.Readable, callback: ICallback<T>, type?: ReaderType);
}
}

View File

@ -0,0 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "language-docker",
"version": "0.0.0",
"license": "Apache2",
"repositoryURL": "https://github.com/docker/docker",
"description": "The file syntaxes/Dockerfile.tmLanguage was included from https://github.com/docker/docker/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage."
}]

View File

@ -0,0 +1,10 @@
{
"comments": {
"lineComment": "#"
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,20 @@
{
"name": "docker",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "dockerfile",
"extensions": [ ".dockerfile" ],
"filenames": [ "Dockerfile" ],
"aliases": [ "Dockerfile" ],
"configuration": "./dockerfile.configuration.json"
}],
"grammars": [{
"language": "dockerfile",
"scopeName": "source.dockerfile",
"path": "./syntaxes/Dockerfile.tmLanguage"
}]
}
}

View File

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>Dockerfile</string>
</array>
<key>name</key>
<string>Dockerfile</string>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.dockerfile</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.other.special-method.dockerfile</string>
</dict>
</dict>
<key>match</key>
<string>^\s*(?:(ONBUILD)\s+)?(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|VOLUME|USER|WORKDIR|COPY|LABEL|STOPSIGNAL)\s</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.operator.dockerfile</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.other.special-method.dockerfile</string>
</dict>
</dict>
<key>match</key>
<string>^\s*(?:(ONBUILD)\s+)?(CMD|ENTRYPOINT)\s</string>
</dict>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.dockerfile</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.dockerfile</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.dockerfile</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escaped.dockerfile</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.dockerfile</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.dockerfile</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.dockerfile</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>\\.</string>
<key>name</key>
<string>constant.character.escaped.dockerfile</string>
</dict>
</array>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.whitespace.comment.leading.dockerfile</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>comment.line.number-sign.dockerfile</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.dockerfile</string>
</dict>
</dict>
<key>comment</key>
<string>comment.line</string>
<key>match</key>
<string>^(\s*)((#).*$\n?)</string>
</dict>
</array>
<key>scopeName</key>
<string>source.dockerfile</string>
<key>uuid</key>
<string>a39d8795-59d2-49af-aa00-fe74ee29576e</string>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "ionide/ionide-fsharp",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/ionide/ionide-fsharp",
"description": "The file syntaxes/fsharp.json was included from https://github.com/ionide/ionide-fsharp/blob/develop/release/grammars/fsharp.json."
}]

View File

@ -0,0 +1,11 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "(*", "*)" ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View File

@ -0,0 +1,19 @@
{
"name": "fsharp",
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"contributes": {
"languages": [{
"id": "fsharp",
"extensions": [ ".fs", ".fsi", ".ml", ".mli", ".fsx", ".fsscript" ],
"aliases": [ "F#", "FSharp", "fsharp" ],
"configuration": "./fsharp.configuration.json"
}],
"grammars": [{
"language": "fsharp",
"scopeName": "source.fsharp",
"path": "./syntaxes/fsharp.json"
}]
}
}

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