mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
38
extensions/json/.vscode/launch.json
vendored
Normal file
38
extensions/json/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/client/out"],
|
||||
"preLaunchTask": "npm"
|
||||
},
|
||||
{
|
||||
"name": "Launch Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/client/out/test" ],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/client/out/test"],
|
||||
"preLaunchTask": "npm"
|
||||
},
|
||||
{
|
||||
"name": "Attach Language Server",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 6004,
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceRoot}/server/out"]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
30
extensions/json/.vscode/tasks.json
vendored
Normal file
30
extensions/json/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Available variables which can be used inside of strings.
|
||||
// ${workspaceRoot}: the root folder of the team
|
||||
// ${file}: the current opened file
|
||||
// ${fileBasename}: the current opened file's basename
|
||||
// ${fileDirname}: the current opened file's dirname
|
||||
// ${fileExtname}: the current opened file's extension
|
||||
// ${cwd}: the current working directory of the spawned process
|
||||
|
||||
// A task runner that calls a custom npm script that compiles the extension.
|
||||
{
|
||||
"version": "0.1.0",
|
||||
|
||||
// we want to run npm
|
||||
"command": "npm",
|
||||
|
||||
// the command is a shell script
|
||||
"isShellCommand": true,
|
||||
|
||||
// show the output window only if unrecognized errors occur.
|
||||
"showOutput": "silent",
|
||||
|
||||
// we run the custom script "compile" as defined in package.json
|
||||
"args": ["run", "compile"],
|
||||
|
||||
// The tsc compiler is started in watching mode
|
||||
"isWatching": true,
|
||||
|
||||
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
||||
7
extensions/json/.vscodeignore
Normal file
7
extensions/json/.vscodeignore
Normal file
@@ -0,0 +1,7 @@
|
||||
test/**
|
||||
client/tsconfig.json
|
||||
client/src/**
|
||||
server/tsconfig.json
|
||||
server/src/**
|
||||
server/node_modules/@types/**
|
||||
npm-shrinkwrap.json
|
||||
7
extensions/json/OSSREADME.json
Normal file
7
extensions/json/OSSREADME.json
Normal file
@@ -0,0 +1,7 @@
|
||||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "Benvie/JavaScriptNext.tmLanguage",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/Microsoft/vscode-JSON.tmLanguage"
|
||||
}]
|
||||
243
extensions/json/client/src/jsonMain.ts
Normal file
243
extensions/json/client/src/jsonMain.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
|
||||
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorRange, Color } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
|
||||
|
||||
import { DocumentColorRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
|
||||
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
let localize = nls.loadMessageBundle();
|
||||
|
||||
namespace VSCodeContentRequest {
|
||||
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
|
||||
}
|
||||
|
||||
export interface ISchemaAssociations {
|
||||
[pattern: string]: string[];
|
||||
}
|
||||
|
||||
namespace SchemaAssociationNotification {
|
||||
export const type: NotificationType<ISchemaAssociations, any> = new NotificationType('json/schemaAssociations');
|
||||
}
|
||||
|
||||
interface IPackageInfo {
|
||||
name: string;
|
||||
version: string;
|
||||
aiKey: string;
|
||||
}
|
||||
|
||||
interface Settings {
|
||||
json?: {
|
||||
schemas?: JSONSchemaSettings[];
|
||||
format?: { enable: boolean; };
|
||||
};
|
||||
http?: {
|
||||
proxy: string;
|
||||
proxyStrictSSL: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface JSONSettings {
|
||||
schemas: JSONSchemaSettings[];
|
||||
}
|
||||
|
||||
interface JSONSchemaSettings {
|
||||
fileMatch?: string[];
|
||||
url?: string;
|
||||
schema?: any;
|
||||
}
|
||||
|
||||
const ColorFormat_HEX = {
|
||||
opaque: '"#{red:X}{green:X}{blue:X}"',
|
||||
transparent: '"#{red:X}{green:X}{blue:X}{alpha:X}"'
|
||||
};
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
|
||||
let packageInfo = getPackageInfo(context);
|
||||
let telemetryReporter: TelemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||
context.subscriptions.push(telemetryReporter);
|
||||
|
||||
// The server is implemented in node
|
||||
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'jsonServerMain.js'));
|
||||
// The debug options for the server
|
||||
let debugOptions = { execArgv: ['--nolazy', '--inspect=6004'] };
|
||||
|
||||
// If the extension is launch in debug mode the debug server options are use
|
||||
// Otherwise the run options are used
|
||||
let serverOptions: ServerOptions = {
|
||||
run: { module: serverModule, transport: TransportKind.ipc },
|
||||
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
|
||||
};
|
||||
|
||||
let documentSelector = ['json'];
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for json documents
|
||||
documentSelector,
|
||||
synchronize: {
|
||||
// Synchronize the setting section 'json' to the server
|
||||
configurationSection: ['json', 'http'],
|
||||
fileEvents: workspace.createFileSystemWatcher('**/*.json')
|
||||
},
|
||||
middleware: {
|
||||
workspace: {
|
||||
didChangeConfiguration: () => client.sendNotification(DidChangeConfigurationNotification.type, { settings: getSettings() })
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
let client = new LanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), serverOptions, clientOptions);
|
||||
client.registerFeature(new ConfigurationFeature(client));
|
||||
|
||||
let disposable = client.start();
|
||||
client.onReady().then(() => {
|
||||
client.onTelemetry(e => {
|
||||
if (telemetryReporter) {
|
||||
telemetryReporter.sendTelemetryEvent(e.key, e.data);
|
||||
}
|
||||
});
|
||||
|
||||
// handle content request
|
||||
client.onRequest(VSCodeContentRequest.type, (uriPath: string) => {
|
||||
let uri = Uri.parse(uriPath);
|
||||
return workspace.openTextDocument(uri).then(doc => {
|
||||
return doc.getText();
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
|
||||
// register color provider
|
||||
context.subscriptions.push(languages.registerColorProvider(documentSelector, {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorRange[]> {
|
||||
let params = client.code2ProtocolConverter.asDocumentSymbolParams(document);
|
||||
return client.sendRequest(DocumentColorRequest.type, params).then(symbols => {
|
||||
return symbols.map(symbol => {
|
||||
let range = client.protocol2CodeConverter.asRange(symbol.range);
|
||||
let color = new Color(symbol.color.red * 255, symbol.color.green * 255, symbol.color.blue * 255, symbol.color.alpha);
|
||||
return new ColorRange(range, color, [ColorFormat_HEX]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// Push the disposable to the context's subscriptions so that the
|
||||
// client can be deactivated on extension deactivation
|
||||
context.subscriptions.push(disposable);
|
||||
|
||||
languages.setLanguageConfiguration('json', {
|
||||
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
|
||||
indentationRules: {
|
||||
increaseIndentPattern: /^.*(\{[^}]*|\[[^\]]*)$/,
|
||||
decreaseIndentPattern: /^\s*[}\]],?\s*$/
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getSchemaAssociation(context: ExtensionContext): ISchemaAssociations {
|
||||
let associations: ISchemaAssociations = {};
|
||||
extensions.all.forEach(extension => {
|
||||
let packageJSON = extension.packageJSON;
|
||||
if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation) {
|
||||
let jsonValidation = packageJSON.contributes.jsonValidation;
|
||||
if (Array.isArray(jsonValidation)) {
|
||||
jsonValidation.forEach(jv => {
|
||||
let { fileMatch, url } = jv;
|
||||
if (fileMatch && url) {
|
||||
if (url[0] === '.' && url[1] === '/') {
|
||||
url = Uri.file(path.join(extension.extensionPath, url)).toString();
|
||||
}
|
||||
if (fileMatch[0] === '%') {
|
||||
fileMatch = fileMatch.replace(/%APP_SETTINGS_HOME%/, '/User');
|
||||
fileMatch = fileMatch.replace(/%APP_WORKSPACES_HOME%/, '/Workspaces');
|
||||
} else if (fileMatch.charAt(0) !== '/' && !fileMatch.match(/\w+:\/\//)) {
|
||||
fileMatch = '/' + fileMatch;
|
||||
}
|
||||
let association = associations[fileMatch];
|
||||
if (!association) {
|
||||
association = [];
|
||||
associations[fileMatch] = association;
|
||||
}
|
||||
association.push(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return associations;
|
||||
}
|
||||
|
||||
function getSettings(): Settings {
|
||||
let httpSettings = workspace.getConfiguration('http');
|
||||
let jsonSettings = workspace.getConfiguration('json');
|
||||
|
||||
let schemas = [];
|
||||
|
||||
let settings: Settings = {
|
||||
http: {
|
||||
proxy: httpSettings.get('proxy'),
|
||||
proxyStrictSSL: httpSettings.get('proxyStrictSSL')
|
||||
},
|
||||
json: {
|
||||
format: jsonSettings.get('format'),
|
||||
schemas: schemas,
|
||||
}
|
||||
};
|
||||
let settingsSchemas = jsonSettings.get('schemas');
|
||||
if (Array.isArray(settingsSchemas)) {
|
||||
schemas.push(...settingsSchemas);
|
||||
}
|
||||
|
||||
let folders = workspace.workspaceFolders;
|
||||
if (folders) {
|
||||
folders.forEach(folder => {
|
||||
let jsonConfig = workspace.getConfiguration('json', folder.uri);
|
||||
let schemaConfigInfo = jsonConfig.inspect<JSONSchemaSettings[]>('schemas');
|
||||
let folderSchemas = schemaConfigInfo.workspaceFolderValue;
|
||||
if (Array.isArray(folderSchemas)) {
|
||||
folderSchemas.forEach(schema => {
|
||||
let url = schema.url;
|
||||
if (!url && schema.schema) {
|
||||
url = schema.schema.id;
|
||||
}
|
||||
if (url && url[0] === '.') {
|
||||
url = Uri.file(path.normalize(path.join(folder.uri.fsPath, url))).toString();
|
||||
}
|
||||
let fileMatch = schema.fileMatch;
|
||||
if (fileMatch) {
|
||||
fileMatch = fileMatch.map(m => folder.uri.toString() + '*' + m);
|
||||
}
|
||||
schemas.push({ url, fileMatch, schema: schema.schema });
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
function getPackageInfo(context: ExtensionContext): IPackageInfo {
|
||||
let extensionPackage = require(context.asAbsolutePath('./package.json'));
|
||||
if (extensionPackage) {
|
||||
return {
|
||||
name: extensionPackage.name,
|
||||
version: extensionPackage.version,
|
||||
aiKey: extensionPackage.aiKey
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
7
extensions/json/client/src/typings/ref.d.ts
vendored
Normal file
7
extensions/json/client/src/typings/ref.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../../src/vs/vscode.proposed.d.ts'/>
|
||||
10
extensions/json/client/tsconfig.json
Normal file
10
extensions/json/client/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"outDir": "./out",
|
||||
"lib": [
|
||||
"es5", "es2015.promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
18
extensions/json/language-configuration.json
Normal file
18
extensions/json/language-configuration.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": [ "/*", "*/" ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
{ "open": "{", "close": "}", "notIn": ["string"] },
|
||||
{ "open": "[", "close": "]", "notIn": ["string"] },
|
||||
{ "open": "(", "close": ")", "notIn": ["string"] },
|
||||
{ "open": "'", "close": "'", "notIn": ["string"] },
|
||||
{ "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
|
||||
{ "open": "`", "close": "`", "notIn": ["string", "comment"] }
|
||||
]
|
||||
}
|
||||
46
extensions/json/npm-shrinkwrap.json
generated
Normal file
46
extensions/json/npm-shrinkwrap.json
generated
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "json",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"applicationinsights": {
|
||||
"version": "0.18.0",
|
||||
"from": "applicationinsights@0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
|
||||
},
|
||||
"vscode-extension-telemetry": {
|
||||
"version": "0.0.8",
|
||||
"from": "vscode-extension-telemetry@>=0.0.8 <0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "3.3.1",
|
||||
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
|
||||
},
|
||||
"vscode-languageclient": {
|
||||
"version": "3.4.0-next.17",
|
||||
"from": "vscode-languageclient@next",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.4.0-next.17.tgz"
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.1.1",
|
||||
"from": "vscode-languageserver-protocol@>=3.1.1 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.1.1.tgz"
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.3.0",
|
||||
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "2.0.2",
|
||||
"from": "vscode-nls@>=2.0.2 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
|
||||
},
|
||||
"winreg": {
|
||||
"version": "1.2.3",
|
||||
"from": "winreg@1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
143
extensions/json/package.json
Normal file
143
extensions/json/package.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"name": "json",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onLanguage:json"
|
||||
],
|
||||
"enableProposedApi": true,
|
||||
"main": "./client/out/jsonMain",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:json-client && gulp compile-extension:json-server",
|
||||
"postinstall": "cd server && npm install",
|
||||
"install-client-next": "npm install vscode-languageclient@next -f -S",
|
||||
"install-client-local": "npm install ../../../vscode-languageserver-node/client -f -S",
|
||||
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-JSON.tmLanguage JSON.tmLanguage ./syntaxes/JSON.tmLanguage.json"
|
||||
},
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "json",
|
||||
"aliases": [
|
||||
"JSON",
|
||||
"json"
|
||||
],
|
||||
"extensions": [
|
||||
".json",
|
||||
".bowerrc",
|
||||
".jshintrc",
|
||||
".jscsrc",
|
||||
".eslintrc",
|
||||
".babelrc",
|
||||
".webmanifest",
|
||||
".code-workspace"
|
||||
],
|
||||
"mimetypes": [
|
||||
"application/json",
|
||||
"application/manifest+json"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "json",
|
||||
"scopeName": "source.json",
|
||||
"path": "./syntaxes/JSON.tmLanguage.json"
|
||||
}
|
||||
],
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.schema.json",
|
||||
"url": "http://json-schema.org/draft-04/schema#"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"id": "json",
|
||||
"order": 20,
|
||||
"type": "object",
|
||||
"title": "JSON",
|
||||
"properties": {
|
||||
"json.schemas": {
|
||||
"type": "array",
|
||||
"scope": "resource",
|
||||
"description": "%json.schemas.desc%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {
|
||||
"fileMatch": [
|
||||
"/myfile"
|
||||
],
|
||||
"url": "schemaURL"
|
||||
},
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"default": "/user.schema.json",
|
||||
"description": "%json.schemas.url.desc%"
|
||||
},
|
||||
"fileMatch": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": "MyFile.json",
|
||||
"description": "%json.schemas.fileMatch.item.desc%"
|
||||
},
|
||||
"minItems": 1,
|
||||
"description": "%json.schemas.fileMatch.desc%"
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "http://json-schema.org/draft-04/schema#",
|
||||
"description": "%json.schemas.schema.desc%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"json.format.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.format.enable.desc%"
|
||||
},
|
||||
"json.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
"enum": [
|
||||
"off",
|
||||
"messages",
|
||||
"verbose"
|
||||
],
|
||||
"default": "off",
|
||||
"description": "%json.tracing.desc%"
|
||||
},
|
||||
"json.colorDecorators.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.colorDecorators.enable.desc%",
|
||||
"deprecationMessage": "%json.colorDecorators.enable.deprecationMessage%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurationDefaults": {
|
||||
"[json]": {
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-extension-telemetry": "0.0.8",
|
||||
"vscode-languageclient": "3.4.0-next.17",
|
||||
"vscode-languageserver-protocol": "^3.1.1",
|
||||
"vscode-nls": "2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.51"
|
||||
}
|
||||
}
|
||||
11
extensions/json/package.nls.json
Normal file
11
extensions/json/package.nls.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"json.schemas.desc": "Associate schemas to JSON files in the current project",
|
||||
"json.schemas.url.desc": "A URL to a schema or a relative path to a schema in the current directory",
|
||||
"json.schemas.fileMatch.desc": "An array of file patterns to match against when resolving JSON files to schemas.",
|
||||
"json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.",
|
||||
"json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.",
|
||||
"json.format.enable.desc": "Enable/disable default JSON formatter (requires restart)",
|
||||
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
|
||||
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."
|
||||
}
|
||||
32
extensions/json/server/.vscode/launch.json
vendored
Normal file
32
extensions/json/server/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
// List of configurations. Add new configurations or edit existing ones.
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 6004,
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceRoot}/out"
|
||||
},
|
||||
{
|
||||
"name": "Unit Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/../../../node_modules/mocha/bin/_mocha",
|
||||
"stopOnEntry": false,
|
||||
"args": [
|
||||
"--timeout",
|
||||
"999999",
|
||||
"--colors"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"runtimeExecutable": null,
|
||||
"runtimeArgs": [],
|
||||
"env": {},
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceRoot}/out"
|
||||
}
|
||||
]
|
||||
}
|
||||
9
extensions/json/server/.vscode/tasks.json
vendored
Normal file
9
extensions/json/server/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"command": "npm",
|
||||
"isShellCommand": true,
|
||||
"showOutput": "silent",
|
||||
"args": ["run", "watch"],
|
||||
"isWatching": true,
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
||||
81
extensions/json/server/npm-shrinkwrap.json
generated
Normal file
81
extensions/json/server/npm-shrinkwrap.json
generated
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"name": "vscode-json-languageserver",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "1.0.2",
|
||||
"from": "agent-base@>=1.0.1 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-1.0.2.tgz"
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.6",
|
||||
"from": "debug@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz"
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"from": "extend@>=3.0.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz"
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "0.2.7",
|
||||
"from": "http-proxy-agent@>=0.2.6 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-0.2.7.tgz"
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "0.3.6",
|
||||
"from": "https-proxy-agent@>=0.3.5 <0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-0.3.6.tgz"
|
||||
},
|
||||
"jsonc-parser": {
|
||||
"version": "1.0.0",
|
||||
"from": "jsonc-parser@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-1.0.0.tgz"
|
||||
},
|
||||
"ms": {
|
||||
"version": "0.7.3",
|
||||
"from": "ms@0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz"
|
||||
},
|
||||
"request-light": {
|
||||
"version": "0.2.1",
|
||||
"from": "request-light@0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.1.tgz"
|
||||
},
|
||||
"vscode-json-languageservice": {
|
||||
"version": "2.0.16",
|
||||
"from": "vscode-json-languageservice@next",
|
||||
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.16.tgz"
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "3.3.1",
|
||||
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz"
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "3.4.0-next.6",
|
||||
"from": "vscode-languageserver@next",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.0-next.6.tgz"
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.1.1",
|
||||
"from": "vscode-languageserver-protocol@>=3.1.1 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.1.1.tgz"
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.3.0",
|
||||
"from": "vscode-languageserver-types@>=3.0.3 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz"
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "2.0.2",
|
||||
"from": "vscode-nls@>=2.0.2 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "1.0.1",
|
||||
"from": "vscode-uri@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
29
extensions/json/server/package.json
Normal file
29
extensions/json/server/package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "vscode-json-languageserver",
|
||||
"description": "JSON language server",
|
||||
"version": "1.0.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^1.0.0",
|
||||
"request-light": "^0.2.1",
|
||||
"vscode-json-languageservice": "^2.0.16",
|
||||
"vscode-languageserver": "3.4.0-next.6",
|
||||
"vscode-languageserver-protocol": "^3.1.1",
|
||||
"vscode-nls": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.51"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:json-server",
|
||||
"watch": "gulp watch-extension:json-server",
|
||||
"install-service-next": "npm install vscode-json-languageservice@next -f -S",
|
||||
"install-service-local": "npm install ../../../../vscode-json-languageservice -f -S",
|
||||
"install-server-next": "npm install vscode-languageserver@next -f -S",
|
||||
"install-server-local": "npm install ../../../../vscode-languageserver-node/server -f -S"
|
||||
}
|
||||
}
|
||||
325
extensions/json/server/src/jsonServerMain.ts
Normal file
325
extensions/json/server/src/jsonServerMain.ts
Normal file
@@ -0,0 +1,325 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {
|
||||
createConnection, IConnection,
|
||||
TextDocuments, TextDocument, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
|
||||
|
||||
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
|
||||
import path = require('path');
|
||||
import fs = require('fs');
|
||||
import URI from './utils/uri';
|
||||
import * as URL from 'url';
|
||||
import Strings = require('./utils/strings');
|
||||
import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
nls.config(process.env['VSCODE_NLS_CONFIG']);
|
||||
|
||||
interface ISchemaAssociations {
|
||||
[pattern: string]: string[];
|
||||
}
|
||||
|
||||
namespace SchemaAssociationNotification {
|
||||
export const type: NotificationType<ISchemaAssociations, any> = new NotificationType('json/schemaAssociations');
|
||||
}
|
||||
|
||||
namespace VSCodeContentRequest {
|
||||
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
|
||||
}
|
||||
|
||||
// Create a connection for the server
|
||||
let connection: IConnection = createConnection();
|
||||
|
||||
console.log = connection.console.log.bind(connection.console);
|
||||
console.error = connection.console.error.bind(connection.console);
|
||||
|
||||
// Create a simple text document manager. The text document manager
|
||||
// supports full document sync only
|
||||
let documents: TextDocuments = new TextDocuments();
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
documents.listen(connection);
|
||||
|
||||
let clientSnippetSupport = false;
|
||||
let clientDynamicRegisterSupport = false;
|
||||
|
||||
// After the server has started the client sends an initilize request. The server receives
|
||||
// in the passed params the rootPath of the workspace plus the client capabilities.
|
||||
let workspaceRoot: URI;
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
workspaceRoot = URI.parse(params.rootPath);
|
||||
|
||||
function hasClientCapability(...keys: string[]) {
|
||||
let c = params.capabilities;
|
||||
for (let i = 0; c && i < keys.length; i++) {
|
||||
c = c[keys[i]];
|
||||
}
|
||||
return !!c;
|
||||
}
|
||||
|
||||
clientSnippetSupport = hasClientCapability('textDocument', 'completion', 'completionItem', 'snippetSupport');
|
||||
clientDynamicRegisterSupport = hasClientCapability('workspace', 'symbol', 'dynamicRegistration');
|
||||
let capabilities: ServerCapabilities & CPServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : null,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
documentRangeFormattingProvider: false,
|
||||
colorProvider: true
|
||||
};
|
||||
|
||||
return { capabilities };
|
||||
});
|
||||
|
||||
let workspaceContext = {
|
||||
resolveRelativePath: (relativePath: string, resource: string) => {
|
||||
return URL.resolve(resource, relativePath);
|
||||
}
|
||||
};
|
||||
|
||||
let schemaRequestService = (uri: string): Thenable<string> => {
|
||||
if (Strings.startsWith(uri, 'file://')) {
|
||||
let fsPath = URI.parse(uri).fsPath;
|
||||
return new Promise<string>((c, e) => {
|
||||
fs.readFile(fsPath, 'UTF-8', (err, result) => {
|
||||
err ? e('') : c(result.toString());
|
||||
});
|
||||
});
|
||||
} else if (Strings.startsWith(uri, 'vscode://')) {
|
||||
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
|
||||
return responseText;
|
||||
}, error => {
|
||||
return error.message;
|
||||
});
|
||||
}
|
||||
if (uri.indexOf('//schema.management.azure.com/') !== -1) {
|
||||
connection.telemetry.logEvent({
|
||||
key: 'json.schema',
|
||||
value: {
|
||||
schemaURL: uri
|
||||
}
|
||||
});
|
||||
}
|
||||
let headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
};
|
||||
|
||||
// create the JSON language service
|
||||
let languageService = getLanguageService({
|
||||
schemaRequestService,
|
||||
workspaceContext,
|
||||
contributions: []
|
||||
});
|
||||
|
||||
// The settings interface describes the server relevant settings part
|
||||
interface Settings {
|
||||
json: {
|
||||
schemas: JSONSchemaSettings[];
|
||||
format: { enable: boolean; };
|
||||
};
|
||||
http: {
|
||||
proxy: string;
|
||||
proxyStrictSSL: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface JSONSchemaSettings {
|
||||
fileMatch?: string[];
|
||||
url?: string;
|
||||
schema?: JSONSchema;
|
||||
}
|
||||
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] = void 0;
|
||||
let schemaAssociations: ISchemaAssociations = void 0;
|
||||
let formatterRegistration: Thenable<Disposable> = null;
|
||||
|
||||
// The settings have changed. Is send on server activation as well.
|
||||
connection.onDidChangeConfiguration((change) => {
|
||||
var settings = <Settings>change.settings;
|
||||
configureHttpRequests(settings.http && settings.http.proxy, settings.http && settings.http.proxyStrictSSL);
|
||||
|
||||
jsonConfigurationSettings = settings.json && settings.json.schemas;
|
||||
updateConfiguration();
|
||||
|
||||
// dynamically enable & disable the formatter
|
||||
if (clientDynamicRegisterSupport) {
|
||||
let enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
|
||||
if (enableFormatter) {
|
||||
if (!formatterRegistration) {
|
||||
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }] });
|
||||
}
|
||||
} else if (formatterRegistration) {
|
||||
formatterRegistration.then(r => r.dispose());
|
||||
formatterRegistration = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// The jsonValidation extension configuration has changed
|
||||
connection.onNotification(SchemaAssociationNotification.type, associations => {
|
||||
schemaAssociations = associations;
|
||||
updateConfiguration();
|
||||
});
|
||||
|
||||
function updateConfiguration() {
|
||||
let languageSettings: LanguageSettings = {
|
||||
validate: true,
|
||||
allowComments: true,
|
||||
schemas: []
|
||||
};
|
||||
if (schemaAssociations) {
|
||||
for (var pattern in schemaAssociations) {
|
||||
let association = schemaAssociations[pattern];
|
||||
if (Array.isArray(association)) {
|
||||
association.forEach(uri => {
|
||||
languageSettings.schemas.push({ uri, fileMatch: [pattern] });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jsonConfigurationSettings) {
|
||||
jsonConfigurationSettings.forEach(schema => {
|
||||
let uri = schema.url;
|
||||
if (!uri && schema.schema) {
|
||||
uri = schema.schema.id;
|
||||
}
|
||||
if (!uri && schema.fileMatch) {
|
||||
uri = 'vscode://schemas/custom/' + encodeURIComponent(schema.fileMatch.join('&'));
|
||||
}
|
||||
if (uri) {
|
||||
if (uri[0] === '.' && workspaceRoot) {
|
||||
// workspace relative path
|
||||
uri = URI.file(path.normalize(path.join(workspaceRoot.fsPath, uri))).toString();
|
||||
}
|
||||
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
|
||||
}
|
||||
});
|
||||
}
|
||||
languageService.configure(languageSettings);
|
||||
|
||||
// Revalidate any open text documents
|
||||
documents.all().forEach(triggerValidation);
|
||||
}
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent((change) => {
|
||||
triggerValidation(change.document);
|
||||
});
|
||||
|
||||
// a document has closed: clear all diagnostics
|
||||
documents.onDidClose(event => {
|
||||
cleanPendingValidation(event.document);
|
||||
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
|
||||
});
|
||||
|
||||
let pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
|
||||
const validationDelayMs = 200;
|
||||
|
||||
function cleanPendingValidation(textDocument: TextDocument): void {
|
||||
let request = pendingValidationRequests[textDocument.uri];
|
||||
if (request) {
|
||||
clearTimeout(request);
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
}
|
||||
}
|
||||
|
||||
function triggerValidation(textDocument: TextDocument): void {
|
||||
cleanPendingValidation(textDocument);
|
||||
pendingValidationRequests[textDocument.uri] = setTimeout(() => {
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
validateTextDocument(textDocument);
|
||||
}, validationDelayMs);
|
||||
}
|
||||
|
||||
function validateTextDocument(textDocument: TextDocument): void {
|
||||
if (textDocument.getText().length === 0) {
|
||||
// ignore empty documents
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
let jsonDocument = getJSONDocument(textDocument);
|
||||
languageService.doValidation(textDocument, jsonDocument).then(diagnostics => {
|
||||
// Send the computed diagnostics to VSCode.
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
});
|
||||
}
|
||||
|
||||
connection.onDidChangeWatchedFiles((change) => {
|
||||
// Monitored files have changed in VSCode
|
||||
let hasChanges = false;
|
||||
change.changes.forEach(c => {
|
||||
if (languageService.resetSchema(c.uri)) {
|
||||
hasChanges = true;
|
||||
}
|
||||
});
|
||||
if (hasChanges) {
|
||||
documents.all().forEach(validateTextDocument);
|
||||
}
|
||||
});
|
||||
|
||||
let jsonDocuments = getLanguageModelCache<JSONDocument>(10, 60, document => languageService.parseJSONDocument(document));
|
||||
documents.onDidClose(e => {
|
||||
jsonDocuments.onDocumentRemoved(e.document);
|
||||
});
|
||||
connection.onShutdown(() => {
|
||||
jsonDocuments.dispose();
|
||||
});
|
||||
|
||||
function getJSONDocument(document: TextDocument): JSONDocument {
|
||||
return jsonDocuments.get(document);
|
||||
}
|
||||
|
||||
connection.onCompletion(textDocumentPosition => {
|
||||
let document = documents.get(textDocumentPosition.textDocument.uri);
|
||||
let jsonDocument = getJSONDocument(document);
|
||||
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
|
||||
});
|
||||
|
||||
connection.onCompletionResolve(completionItem => {
|
||||
return languageService.doResolve(completionItem);
|
||||
});
|
||||
|
||||
connection.onHover(textDocumentPositionParams => {
|
||||
let document = documents.get(textDocumentPositionParams.textDocument.uri);
|
||||
let jsonDocument = getJSONDocument(document);
|
||||
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
|
||||
});
|
||||
|
||||
connection.onDocumentSymbol(documentSymbolParams => {
|
||||
let document = documents.get(documentSymbolParams.textDocument.uri);
|
||||
let jsonDocument = getJSONDocument(document);
|
||||
return languageService.findDocumentSymbols(document, jsonDocument);
|
||||
});
|
||||
|
||||
connection.onDocumentRangeFormatting(formatParams => {
|
||||
let document = documents.get(formatParams.textDocument.uri);
|
||||
return languageService.format(document, formatParams.range, formatParams.options);
|
||||
});
|
||||
|
||||
connection.onRequest(DocumentColorRequest.type, params => {
|
||||
let document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
let jsonDocument = getJSONDocument(document);
|
||||
return languageService.findDocumentColors(document, jsonDocument);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
83
extensions/json/server/src/languageModelCache.ts
Normal file
83
extensions/json/server/src/languageModelCache.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TextDocument } from 'vscode-languageserver';
|
||||
|
||||
export interface LanguageModelCache<T> {
|
||||
get(document: TextDocument): T;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTimeInSec: number, parse: (document: TextDocument) => T): LanguageModelCache<T> {
|
||||
let languageModels: { [uri: string]: { version: number, languageId: string, cTime: number, languageModel: T } } = {};
|
||||
let nModels = 0;
|
||||
|
||||
let cleanupInterval = void 0;
|
||||
if (cleanupIntervalTimeInSec > 0) {
|
||||
cleanupInterval = setInterval(() => {
|
||||
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
let uris = Object.keys(languageModels);
|
||||
for (let uri of uris) {
|
||||
let languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < cutoffTime) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
}, cleanupIntervalTimeInSec * 1000);
|
||||
}
|
||||
|
||||
return {
|
||||
get(document: TextDocument): T {
|
||||
let version = document.version;
|
||||
let languageId = document.languageId;
|
||||
let languageModelInfo = languageModels[document.uri];
|
||||
if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) {
|
||||
languageModelInfo.cTime = Date.now();
|
||||
return languageModelInfo.languageModel;
|
||||
}
|
||||
let languageModel = parse(document);
|
||||
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() };
|
||||
if (!languageModelInfo) {
|
||||
nModels++;
|
||||
}
|
||||
|
||||
if (nModels === maxEntries) {
|
||||
let oldestTime = Number.MAX_VALUE;
|
||||
let oldestUri = null;
|
||||
for (let uri in languageModels) {
|
||||
let languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < oldestTime) {
|
||||
oldestUri = uri;
|
||||
oldestTime = languageModelInfo.cTime;
|
||||
}
|
||||
}
|
||||
if (oldestUri) {
|
||||
delete languageModels[oldestUri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
return languageModel;
|
||||
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
let uri = document.uri;
|
||||
if (languageModels[uri]) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
},
|
||||
dispose() {
|
||||
if (typeof cleanupInterval !== 'undefined') {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = void 0;
|
||||
languageModels = {};
|
||||
nModels = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
37
extensions/json/server/src/utils/strings.ts
Normal file
37
extensions/json/server/src/utils/strings.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
export function startsWith(haystack: string, needle: string): boolean {
|
||||
if (haystack.length < needle.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < needle.length; i++) {
|
||||
if (haystack[i] !== needle[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if haystack ends with needle.
|
||||
*/
|
||||
export function endsWith(haystack: string, needle: string): boolean {
|
||||
let diff = haystack.length - needle.length;
|
||||
if (diff > 0) {
|
||||
return haystack.lastIndexOf(needle) === diff;
|
||||
} else if (diff === 0) {
|
||||
return haystack === needle;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function convertSimple2RegExpPattern(pattern: string): string {
|
||||
return pattern.replace(/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&').replace(/[\*]/g, '.*');
|
||||
}
|
||||
351
extensions/json/server/src/utils/uri.ts
Normal file
351
extensions/json/server/src/utils/uri.ts
Normal file
@@ -0,0 +1,351 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
function _encode(ch: string): string {
|
||||
return '%' + ch.charCodeAt(0).toString(16).toUpperCase();
|
||||
}
|
||||
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
|
||||
function encodeURIComponent2(str: string): string {
|
||||
return encodeURIComponent(str).replace(/[!'()*]/g, _encode);
|
||||
}
|
||||
|
||||
function encodeNoop(str: string): string {
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
|
||||
* This class is a simple parser which creates the basic component paths
|
||||
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
|
||||
* and encoding.
|
||||
*
|
||||
* foo://example.com:8042/over/there?name=ferret#nose
|
||||
* \_/ \______________/\_________/ \_________/ \__/
|
||||
* | | | | |
|
||||
* scheme authority path query fragment
|
||||
* | _____________________|__
|
||||
* / \ / \
|
||||
* urn:example:animal:ferret:nose
|
||||
*
|
||||
*
|
||||
*/
|
||||
export default class URI {
|
||||
|
||||
private static _empty = '';
|
||||
private static _slash = '/';
|
||||
private static _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
||||
private static _driveLetterPath = /^\/[a-zA-z]:/;
|
||||
private static _upperCaseDrive = /^(\/)?([A-Z]:)/;
|
||||
|
||||
private _scheme: string;
|
||||
private _authority: string;
|
||||
private _path: string;
|
||||
private _query: string;
|
||||
private _fragment: string;
|
||||
private _formatted: string;
|
||||
private _fsPath: string;
|
||||
|
||||
constructor() {
|
||||
this._scheme = URI._empty;
|
||||
this._authority = URI._empty;
|
||||
this._path = URI._empty;
|
||||
this._query = URI._empty;
|
||||
this._fragment = URI._empty;
|
||||
|
||||
this._formatted = null;
|
||||
this._fsPath = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'.
|
||||
* The part before the first colon.
|
||||
*/
|
||||
get scheme() {
|
||||
return this._scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'.
|
||||
* The part between the first double slashes and the next slash.
|
||||
*/
|
||||
get authority() {
|
||||
return this._authority;
|
||||
}
|
||||
|
||||
/**
|
||||
* path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'.
|
||||
*/
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
|
||||
/**
|
||||
* query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'.
|
||||
*/
|
||||
get query() {
|
||||
return this._query;
|
||||
}
|
||||
|
||||
/**
|
||||
* fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'.
|
||||
*/
|
||||
get fragment() {
|
||||
return this._fragment;
|
||||
}
|
||||
|
||||
// ---- filesystem path -----------------------
|
||||
|
||||
/**
|
||||
* Returns a string representing the corresponding file system path of this URI.
|
||||
* Will handle UNC paths and normalize windows drive letters to lower-case. Also
|
||||
* uses the platform specific path separator. Will *not* validate the path for
|
||||
* invalid characters and semantics. Will *not* look at the scheme of this URI.
|
||||
*/
|
||||
get fsPath() {
|
||||
if (!this._fsPath) {
|
||||
var value: string;
|
||||
if (this._authority && this.scheme === 'file') {
|
||||
// unc path: file://shares/c$/far/boo
|
||||
value = `//${this._authority}${this._path}`;
|
||||
} else if (URI._driveLetterPath.test(this._path)) {
|
||||
// windows drive letter: file:///c:/far/boo
|
||||
value = this._path[1].toLowerCase() + this._path.substr(2);
|
||||
} else {
|
||||
// other path
|
||||
value = this._path;
|
||||
}
|
||||
if (process.platform === 'win32') {
|
||||
value = value.replace(/\//g, '\\');
|
||||
}
|
||||
this._fsPath = value;
|
||||
}
|
||||
return this._fsPath;
|
||||
}
|
||||
|
||||
// ---- modify to new -------------------------
|
||||
|
||||
public with(scheme: string, authority: string, path: string, query: string, fragment: string): URI {
|
||||
var ret = new URI();
|
||||
ret._scheme = scheme || this.scheme;
|
||||
ret._authority = authority || this.authority;
|
||||
ret._path = path || this.path;
|
||||
ret._query = query || this.query;
|
||||
ret._fragment = fragment || this.fragment;
|
||||
URI._validate(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public withScheme(value: string): URI {
|
||||
return this.with(value, undefined, undefined, undefined, undefined);
|
||||
}
|
||||
|
||||
public withAuthority(value: string): URI {
|
||||
return this.with(undefined, value, undefined, undefined, undefined);
|
||||
}
|
||||
|
||||
public withPath(value: string): URI {
|
||||
return this.with(undefined, undefined, value, undefined, undefined);
|
||||
}
|
||||
|
||||
public withQuery(value: string): URI {
|
||||
return this.with(undefined, undefined, undefined, value, undefined);
|
||||
}
|
||||
|
||||
public withFragment(value: string): URI {
|
||||
return this.with(undefined, undefined, undefined, undefined, value);
|
||||
}
|
||||
|
||||
// ---- parse & validate ------------------------
|
||||
|
||||
public static parse(value: string): URI {
|
||||
const ret = new URI();
|
||||
const data = URI._parseComponents(value);
|
||||
ret._scheme = data.scheme;
|
||||
ret._authority = decodeURIComponent(data.authority);
|
||||
ret._path = decodeURIComponent(data.path);
|
||||
ret._query = decodeURIComponent(data.query);
|
||||
ret._fragment = decodeURIComponent(data.fragment);
|
||||
URI._validate(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static file(path: string): URI {
|
||||
|
||||
const ret = new URI();
|
||||
ret._scheme = 'file';
|
||||
|
||||
// normalize to fwd-slashes
|
||||
path = path.replace(/\\/g, URI._slash);
|
||||
|
||||
// check for authority as used in UNC shares
|
||||
// or use the path as given
|
||||
if (path[0] === URI._slash && path[0] === path[1]) {
|
||||
let idx = path.indexOf(URI._slash, 2);
|
||||
if (idx === -1) {
|
||||
ret._authority = path.substring(2);
|
||||
} else {
|
||||
ret._authority = path.substring(2, idx);
|
||||
ret._path = path.substring(idx);
|
||||
}
|
||||
} else {
|
||||
ret._path = path;
|
||||
}
|
||||
|
||||
// Ensure that path starts with a slash
|
||||
// or that it is at least a slash
|
||||
if (ret._path[0] !== URI._slash) {
|
||||
ret._path = URI._slash + ret._path;
|
||||
}
|
||||
|
||||
URI._validate(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static _parseComponents(value: string): UriComponents {
|
||||
|
||||
const ret: UriComponents = {
|
||||
scheme: URI._empty,
|
||||
authority: URI._empty,
|
||||
path: URI._empty,
|
||||
query: URI._empty,
|
||||
fragment: URI._empty,
|
||||
};
|
||||
|
||||
const match = URI._regexp.exec(value);
|
||||
if (match) {
|
||||
ret.scheme = match[2] || ret.scheme;
|
||||
ret.authority = match[4] || ret.authority;
|
||||
ret.path = match[5] || ret.path;
|
||||
ret.query = match[7] || ret.query;
|
||||
ret.fragment = match[9] || ret.fragment;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static create(scheme?: string, authority?: string, path?: string, query?: string, fragment?: string): URI {
|
||||
return new URI().with(scheme, authority, path, query, fragment);
|
||||
}
|
||||
|
||||
private static _validate(ret: URI): void {
|
||||
|
||||
// validation
|
||||
// path, http://tools.ietf.org/html/rfc3986#section-3.3
|
||||
// If a URI contains an authority component, then the path component
|
||||
// must either be empty or begin with a slash ("/") character. If a URI
|
||||
// does not contain an authority component, then the path cannot begin
|
||||
// with two slash characters ("//").
|
||||
if (ret.authority && ret.path && ret.path[0] !== '/') {
|
||||
throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character');
|
||||
}
|
||||
if (!ret.authority && ret.path.indexOf('//') === 0) {
|
||||
throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
|
||||
}
|
||||
}
|
||||
|
||||
// ---- printing/externalize ---------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @param skipEncoding Do not encode the result, default is `false`
|
||||
*/
|
||||
public toString(skipEncoding: boolean = false): string {
|
||||
if (!skipEncoding) {
|
||||
if (!this._formatted) {
|
||||
this._formatted = URI._asFormatted(this, false);
|
||||
}
|
||||
return this._formatted;
|
||||
} else {
|
||||
// we don't cache that
|
||||
return URI._asFormatted(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static _asFormatted(uri: URI, skipEncoding: boolean): string {
|
||||
|
||||
const encoder = !skipEncoding
|
||||
? encodeURIComponent2
|
||||
: encodeNoop;
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
let { scheme, authority, path, query, fragment } = uri;
|
||||
if (scheme) {
|
||||
parts.push(scheme, ':');
|
||||
}
|
||||
if (authority || scheme === 'file') {
|
||||
parts.push('//');
|
||||
}
|
||||
if (authority) {
|
||||
authority = authority.toLowerCase();
|
||||
let idx = authority.indexOf(':');
|
||||
if (idx === -1) {
|
||||
parts.push(encoder(authority));
|
||||
} else {
|
||||
parts.push(encoder(authority.substr(0, idx)), authority.substr(idx));
|
||||
}
|
||||
}
|
||||
if (path) {
|
||||
// lower-case windown drive letters in /C:/fff
|
||||
const m = URI._upperCaseDrive.exec(path);
|
||||
if (m) {
|
||||
path = m[1] + m[2].toLowerCase() + path.substr(m[1].length + m[2].length);
|
||||
}
|
||||
|
||||
// encode every segement but not slashes
|
||||
// make sure that # and ? are always encoded
|
||||
// when occurring in paths - otherwise the result
|
||||
// cannot be parsed back again
|
||||
let lastIdx = 0;
|
||||
while (true) {
|
||||
let idx = path.indexOf(URI._slash, lastIdx);
|
||||
if (idx === -1) {
|
||||
parts.push(encoder(path.substring(lastIdx)).replace(/[#?]/, _encode));
|
||||
break;
|
||||
}
|
||||
parts.push(encoder(path.substring(lastIdx, idx)).replace(/[#?]/, _encode), URI._slash);
|
||||
lastIdx = idx + 1;
|
||||
};
|
||||
}
|
||||
if (query) {
|
||||
parts.push('?', encoder(query));
|
||||
}
|
||||
if (fragment) {
|
||||
parts.push('#', encoder(fragment));
|
||||
}
|
||||
|
||||
return parts.join(URI._empty);
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return <UriState>{
|
||||
scheme: this.scheme,
|
||||
authority: this.authority,
|
||||
path: this.path,
|
||||
fsPath: this.fsPath,
|
||||
query: this.query,
|
||||
fragment: this.fragment,
|
||||
external: this.toString(),
|
||||
$mid: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface UriComponents {
|
||||
scheme: string;
|
||||
authority: string;
|
||||
path: string;
|
||||
query: string;
|
||||
fragment: string;
|
||||
}
|
||||
|
||||
interface UriState extends UriComponents {
|
||||
$mid: number;
|
||||
fsPath: string;
|
||||
external: string;
|
||||
}
|
||||
15
extensions/json/server/tsconfig.json
Normal file
15
extensions/json/server/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"sourceMap": true,
|
||||
"sourceRoot": "../src",
|
||||
"outDir": "./out",
|
||||
"lib": [
|
||||
"es5", "es2015.promise"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
228
extensions/json/syntaxes/JSON.tmLanguage.json
Normal file
228
extensions/json/syntaxes/JSON.tmLanguage.json
Normal file
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/Microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/Microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
|
||||
"fileTypes": [
|
||||
"json",
|
||||
"sublime-settings",
|
||||
"sublime-menu",
|
||||
"sublime-keymap",
|
||||
"sublime-mousemap",
|
||||
"sublime-theme",
|
||||
"sublime-build",
|
||||
"sublime-project",
|
||||
"sublime-completions"
|
||||
],
|
||||
"foldingStartMarker": "(?x) # turn on extended mode\n ^ # a line beginning with\n \\s* # some optional space\n [{\\[] # the start of an object or array\n (?! # but not followed by\n .* # whatever\n [}\\]] # and the close of an object or array\n ,? # an optional comma\n \\s* # some optional space\n $ # at the end of the line\n )\n | # ...or...\n [{\\[] # the start of an object or array\n \\s* # some optional space\n $ # at the end of the line",
|
||||
"foldingStopMarker": "(?x) # turn on extended mode\n ^ # a line beginning with\n \\s* # some optional space\n [}\\]] # and the close of an object or array",
|
||||
"keyEquivalent": "^~J",
|
||||
"name": "JSON (Javascript Next)",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#value"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"array": {
|
||||
"begin": "\\[",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.array.begin.json"
|
||||
}
|
||||
},
|
||||
"end": "\\]",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.array.end.json"
|
||||
}
|
||||
},
|
||||
"name": "meta.structure.array.json",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#value"
|
||||
},
|
||||
{
|
||||
"match": ",",
|
||||
"name": "punctuation.separator.array.json"
|
||||
},
|
||||
{
|
||||
"match": "[^\\s\\]]",
|
||||
"name": "invalid.illegal.expected-array-separator.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "/\\*\\*(?!/)",
|
||||
"captures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.comment.json"
|
||||
}
|
||||
},
|
||||
"end": "\\*/",
|
||||
"name": "comment.block.documentation.json"
|
||||
},
|
||||
{
|
||||
"begin": "/\\*",
|
||||
"captures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.comment.json"
|
||||
}
|
||||
},
|
||||
"end": "\\*/",
|
||||
"name": "comment.block.json"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.json"
|
||||
}
|
||||
},
|
||||
"match": "(//).*$\\n?",
|
||||
"name": "comment.line.double-slash.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"constant": {
|
||||
"match": "\\b(?:true|false|null)\\b",
|
||||
"name": "constant.language.json"
|
||||
},
|
||||
"number": {
|
||||
"match": "(?x) # turn on extended mode\n -? # an optional minus\n (?:\n 0 # a zero\n | # ...or...\n [1-9] # a 1-9 character\n \\d* # followed by zero or more digits\n )\n (?:\n (?:\n \\. # a period\n \\d+ # followed by one or more digits\n )?\n (?:\n [eE] # an e character\n [+-]? # followed by an option +/-\n \\d+ # followed by one or more digits\n )? # make exponent optional\n )? # make decimal portion optional",
|
||||
"name": "constant.numeric.json"
|
||||
},
|
||||
"object": {
|
||||
"begin": "\\{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.dictionary.begin.json"
|
||||
}
|
||||
},
|
||||
"end": "\\}",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.dictionary.end.json"
|
||||
}
|
||||
},
|
||||
"name": "meta.structure.dictionary.json",
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "the JSON object key",
|
||||
"include": "#objectkey"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"begin": ":",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.separator.dictionary.key-value.json"
|
||||
}
|
||||
},
|
||||
"end": "(,)|(?=\\})",
|
||||
"endCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.separator.dictionary.pair.json"
|
||||
}
|
||||
},
|
||||
"name": "meta.structure.dictionary.value.json",
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "the JSON object value",
|
||||
"include": "#value"
|
||||
},
|
||||
{
|
||||
"match": "[^\\s,]",
|
||||
"name": "invalid.illegal.expected-dictionary-separator.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"match": "[^\\s\\}]",
|
||||
"name": "invalid.illegal.expected-dictionary-separator.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"string": {
|
||||
"begin": "\"",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.begin.json"
|
||||
}
|
||||
},
|
||||
"end": "\"",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.end.json"
|
||||
}
|
||||
},
|
||||
"name": "string.quoted.double.json",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#stringcontent"
|
||||
}
|
||||
]
|
||||
},
|
||||
"objectkey": {
|
||||
"begin": "\"",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.support.type.property-name.begin.json"
|
||||
}
|
||||
},
|
||||
"end": "\"",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.support.type.property-name.end.json"
|
||||
}
|
||||
},
|
||||
"name": "string.json support.type.property-name.json",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#stringcontent"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stringcontent": {
|
||||
"patterns": [
|
||||
{
|
||||
"match": "(?x) # turn on extended mode\n \\\\ # a literal backslash\n (?: # ...followed by...\n [\"\\\\/bfnrt] # one of these characters\n | # ...or...\n u # a u\n [0-9a-fA-F]{4}) # and four hex digits",
|
||||
"name": "constant.character.escape.json"
|
||||
},
|
||||
{
|
||||
"match": "\\\\.",
|
||||
"name": "invalid.illegal.unrecognized-string-escape.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#constant"
|
||||
},
|
||||
{
|
||||
"include": "#number"
|
||||
},
|
||||
{
|
||||
"include": "#string"
|
||||
},
|
||||
{
|
||||
"include": "#array"
|
||||
},
|
||||
{
|
||||
"include": "#object"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scopeName": "source.json",
|
||||
"uuid": "8f97457b-516e-48ce-83c7-08ae12fb327a"
|
||||
}
|
||||
14
extensions/json/test/colorize-fixtures/test.json
Normal file
14
extensions/json/test/colorize-fixtures/test.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
// a comment
|
||||
"options": {
|
||||
"myBool": true,
|
||||
"myInteger": 1,
|
||||
"myString": "String\u0056",
|
||||
"myNumber": 1.24,
|
||||
"myNull": null,
|
||||
"myArray": [ 1, "Hello", true, null, [], {}],
|
||||
"myObject" : {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
1168
extensions/json/test/colorize-results/test_json.json
Normal file
1168
extensions/json/test/colorize-results/test_json.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user