提交 a749a073 编写于 作者: M Martin Aeschlimann

[json] refactor intellisense participants to not depend on schema

上级 dcdff0a5
......@@ -10,6 +10,8 @@ import WinJS = require('vs/base/common/winjs.base');
import nls = require('vs/nls');
import JSONWorker = require('vs/languages/json/common/jsonWorker');
import {IRequestService} from 'vs/platform/request/common/request';
import URI from 'vs/base/common/uri';
import {JSONLocation} from 'vs/languages/json/common/parser/jsonLocation';
export class BowerJSONContribution implements JSONWorker.IJSONWorkerContribution {
......@@ -27,8 +29,13 @@ export class BowerJSONContribution implements JSONWorker.IJSONWorkerContribution
this.requestService = requestService;
}
public collectDefaultSuggestions(contributionId: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'http://json.schemastore.org/bower') {
private isBowerFile(resource: URI): boolean {
var path = resource.path;
return Strings.endsWith(path, '/bower.json') || Strings.endsWith(path, '/.bower.json');
}
public collectDefaultSuggestions(resource: URI, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isBowerFile(resource)) {
var defaultValue = {
'name': '{{name}}',
'description': '{{description}}',
......@@ -39,11 +46,11 @@ export class BowerJSONContribution implements JSONWorker.IJSONWorkerContribution
};
result.add({ type: 'type', label: nls.localize('json.bower.default', 'Default bower.json'), codeSnippet: JSON.stringify(defaultValue, null, '\t'), documentationLabel: '' });
}
return WinJS.Promise.as(0);
return null;
}
public collectPropertySuggestions(contributionId: string, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (contributionId === 'bower-packages') {
public collectPropertySuggestions(resource: URI, location: JSONLocation, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (this.isBowerFile(resource) && (location.matches(['dependencies']) || location.matches(['devDependencies']))) {
if (currentWord.length > 0) {
var queryUrl = 'https://bower.herokuapp.com/packages/search/' + encodeURIComponent(currentWord);
......@@ -94,16 +101,17 @@ export class BowerJSONContribution implements JSONWorker.IJSONWorkerContribution
result.setAsIncomplete();
}
}
return WinJS.Promise.as(0);
return null;
}
public collectValueSuggestions(contributionId: string, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
public collectValueSuggestions(resource: URI, location: JSONLocation, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
// not implemented. Could be do done calling the bower command. Waiting for web API: https://github.com/bower/registry/issues/26
return WinJS.Promise.as(0);
return null;
}
public getInfoContribution(contributionId: string, pack: string): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (contributionId === 'bower-package') {
public getInfoContribution(resource: URI, location: JSONLocation): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (this.isBowerFile(resource) && (location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']))) {
var pack = location.getSegments()[location.getSegments().length - 1];
var htmlContent : HtmlContent.IHTMLContentElement[] = [];
htmlContent.push({className: 'type', text: nls.localize('json.bower.package.hover', '{0}', pack) });
......
......@@ -5,12 +5,15 @@
'use strict';
import HtmlContent = require('vs/base/common/htmlContent');
import Strings = require('vs/base/common/strings');
import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import WinJS = require('vs/base/common/winjs.base');
import nls = require('vs/nls');
import JSONWorker = require('vs/languages/json/common/jsonWorker');
import {INullService} from 'vs/platform/instantiation/common/instantiation';
import URI from 'vs/base/common/uri';
import {JSONLocation} from 'vs/languages/json/common/parser/jsonLocation';
var globProperties:Modes.ISuggestion[] = [
{ type: 'value', label: nls.localize('fileLabel', "Files by Extension"), codeSnippet: '"**/*.{{extension}}": true', documentationLabel: nls.localize('fileDescription', "Match all files of a specific file extension.")},
......@@ -32,27 +35,34 @@ export class GlobPatternContribution implements JSONWorker.IJSONWorkerContributi
constructor(@INullService ns) {
}
public collectDefaultSuggestions(contributionId: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
return WinJS.Promise.as(0);
private isSettingsFile(resource: URI): boolean {
var path = resource.path;
return Strings.endsWith(path, '/settings.json');
}
public collectPropertySuggestions(contributionId: string, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (contributionId === 'glob-pattern') {
public collectDefaultSuggestions(resource: URI, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
return null;
}
public collectPropertySuggestions(resource: URI, location: JSONLocation, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (this.isSettingsFile(resource) && (location.matches(['files.exclude']) || location.matches(['search.exclude']))) {
globProperties.forEach((e) => result.add(e));
}
return WinJS.Promise.as(0);
return null;
}
public collectValueSuggestions(contributionId: string, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'glob-pattern') {
public collectValueSuggestions(resource: URI, location: JSONLocation, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isSettingsFile(resource) && (location.matches(['files.exclude']) || location.matches(['search.exclude']))) {
globValues.forEach((e) => result.add(e));
}
return WinJS.Promise.as(0);
return null;
}
public getInfoContribution(contributionId: string, pack: string): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
public getInfoContribution(resource: URI, location: JSONLocation): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
return null;
}
}
\ No newline at end of file
......@@ -5,10 +5,13 @@
'use strict';
import HtmlContent = require('vs/base/common/htmlContent');
import Strings = require('vs/base/common/strings');
import WinJS = require('vs/base/common/winjs.base');
import nls = require('vs/nls');
import JSONWorker = require('vs/languages/json/common/jsonWorker');
import {IRequestService} from 'vs/platform/request/common/request';
import URI from 'vs/base/common/uri';
import {JSONLocation} from 'vs/languages/json/common/parser/jsonLocation';
var LIMIT = 40;
......@@ -23,12 +26,17 @@ export class PackageJSONContribution implements JSONWorker.IJSONWorkerContributi
private requestService : IRequestService;
private isPackageJSONFile(resource: URI): boolean {
var path = resource.path;
return Strings.endsWith(path, '/package.json');
}
public constructor(@IRequestService requestService: IRequestService) {
this.requestService = requestService;
}
public collectDefaultSuggestions(contributionId: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'http://json.schemastore.org/package') {
public collectDefaultSuggestions(resource: URI, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isPackageJSONFile(resource)) {
var defaultValue = {
'name': '{{name}}',
'description': '{{description}}',
......@@ -39,11 +47,11 @@ export class PackageJSONContribution implements JSONWorker.IJSONWorkerContributi
};
result.add({ type: 'module', label: nls.localize('json.package.default', 'Default package.json'), codeSnippet: JSON.stringify(defaultValue, null, '\t'), documentationLabel: '' });
}
return WinJS.Promise.as(0);
return null;
}
public collectPropertySuggestions(contributionId: string, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (contributionId === 'npm-packages') {
public collectPropertySuggestions(resource: URI, location: JSONLocation, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (this.isPackageJSONFile(resource) && (location.matches(['dependencies']) || location.matches(['devDependencies']) || location.matches(['optionalDependencies']) || location.matches(['peerDependencies']))) {
var queryUrl : string;
if (currentWord.length > 0) {
queryUrl = 'https://skimdb.npmjs.com/registry/_design/app/_view/browseAll?group_level=1&limit=' + LIMIT + '&start_key=%5B%22' + encodeURIComponent(currentWord) + '%22%5D&end_key=%5B%22'+ encodeURIComponent(currentWord + 'z') + '%22,%7B%7D%5D';
......@@ -99,11 +107,11 @@ export class PackageJSONContribution implements JSONWorker.IJSONWorkerContributi
result.setAsIncomplete();
}
}
return WinJS.Promise.as(0);
return null;
}
public collectValueSuggestions(contributionId: string, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'npm-packages') {
public collectValueSuggestions(resource: URI, location: JSONLocation, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isPackageJSONFile(resource) && (location.matches(['dependencies']) || location.matches(['devDependencies']) || location.matches(['optionalDependencies']) || location.matches(['peerDependencies']))) {
var queryUrl = 'http://registry.npmjs.org/' + encodeURIComponent(currentKey) + '/latest';
return this.requestService.makeRequest({
......@@ -128,11 +136,13 @@ export class PackageJSONContribution implements JSONWorker.IJSONWorkerContributi
return 0;
});
}
return WinJS.Promise.as(0);
return null;
}
public getInfoContribution(contributionId: string, pack: string): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (contributionId === 'npm-package') {
public getInfoContribution(resource: URI, location: JSONLocation): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (this.isPackageJSONFile(resource) && (location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) {
var pack = location.getSegments()[location.getSegments().length - 1];
var htmlContent : HtmlContent.IHTMLContentElement[] = [];
htmlContent.push({className: 'type', text: nls.localize('json.npm.package.hover', '{0}', pack) });
......
......@@ -5,10 +5,13 @@
'use strict';
import HtmlContent = require('vs/base/common/htmlContent');
import Strings = require('vs/base/common/strings');
import WinJS = require('vs/base/common/winjs.base');
import nls = require('vs/nls');
import JSONWorker = require('vs/languages/json/common/jsonWorker');
import {IRequestService} from 'vs/platform/request/common/request';
import {JSONLocation} from 'vs/languages/json/common/parser/jsonLocation';
import URI from 'vs/base/common/uri';
var LIMIT = 40;
......@@ -20,8 +23,13 @@ export class ProjectJSONContribution implements JSONWorker.IJSONWorkerContributi
this.requestService = requestService;
}
public collectDefaultSuggestions(contributionId: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'http://json.schemastore.org/project') {
private isProjectJSONFile(resource: URI): boolean {
var path = resource.path;
return Strings.endsWith(path, '/project.json');
}
public collectDefaultSuggestions(resource: URI, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isProjectJSONFile(resource)) {
var defaultValue = {
'version': '{{1.0.0-*}}',
'dependencies': {},
......@@ -32,11 +40,11 @@ export class ProjectJSONContribution implements JSONWorker.IJSONWorkerContributi
};
result.add({ type: 'type', label: nls.localize('json.project.default', 'Default project.json'), codeSnippet: JSON.stringify(defaultValue, null, '\t'), documentationLabel: '' });
}
return WinJS.Promise.as(0);
return null;
}
public collectPropertySuggestions(contributionId: string, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (contributionId === 'nugget-packages') {
public collectPropertySuggestions(resource: URI, location: JSONLocation, currentWord: string, addValue: boolean, isLast:boolean, result: JSONWorker.ISuggestionsCollector) : WinJS.Promise {
if (this.isProjectJSONFile(resource) && (location.matches(['dependencies']) || location.matches(['frameworks', '*', 'dependencies']) || location.matches(['frameworks', '*', 'frameworkAssemblies']))) {
var queryUrl : string;
if (currentWord.length > 0) {
queryUrl = 'https://www.nuget.org/api/v2/Packages?'
......@@ -94,11 +102,11 @@ export class ProjectJSONContribution implements JSONWorker.IJSONWorkerContributi
return 0;
});
}
return WinJS.Promise.as(0);
return null;
}
public collectValueSuggestions(contributionId: string, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (contributionId === 'nugget-packages') {
public collectValueSuggestions(resource: URI, location: JSONLocation, currentKey: string, result: JSONWorker.ISuggestionsCollector): WinJS.Promise {
if (this.isProjectJSONFile(resource) && (location.matches(['dependencies']) || location.matches(['frameworks', '*', 'dependencies']) || location.matches(['frameworks', '*', 'frameworkAssemblies']))) {
var queryUrl = 'https://www.myget.org/F/aspnetrelease/api/v2/Packages?'
+ '$filter=Id%20eq%20\''
+ encodeURIComponent(currentKey)
......@@ -137,12 +145,12 @@ export class ProjectJSONContribution implements JSONWorker.IJSONWorkerContributi
return 0;
});
}
return WinJS.Promise.as(0);
return null;
}
public getInfoContribution(contributionId: string, pack: string): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (contributionId === 'nugget-package') {
public getInfoContribution(resource: URI, location: JSONLocation): WinJS.TPromise<HtmlContent.IHTMLContentElement[]> {
if (this.isProjectJSONFile(resource) && (location.matches(['dependencies', '*']) || location.matches(['frameworks', '*', 'dependencies', '*']) || location.matches(['frameworks', '*', 'frameworkAssemblies', '*']))) {
var pack = location.getSegments()[location.getSegments().length - 1];
var htmlContent : HtmlContent.IHTMLContentElement[] = [];
htmlContent.push({className: 'type', text: nls.localize('json.nugget.package.hover', '{0}', pack) });
......
......@@ -104,12 +104,19 @@ export class JSONIntellisense {
if (schema) {
// property proposals with schema
var isLast = properties.length === 0 || offset >= properties[properties.length - 1].start;
collectionPromises.push(this.getPropertySuggestions(schema, doc, node, currentKey, addValue, isLast, collector));
this.getPropertySuggestions(resource, schema, doc, node, currentKey, addValue, isLast, collector);
} else if (node.parent) {
// property proposals without schema
collectionPromises.push(this.getSchemaLessPropertySuggestions(doc, node, collector));
this.getSchemaLessPropertySuggestions(doc, node, collector);
}
var location = node.getNodeLocation();
this.contributions.forEach((contribution) => {
var collectPromise = contribution.collectPropertySuggestions(resource, location, currentWord, addValue, isLast, collector);
if (collectPromise) {
collectionPromises.push();
}
});
}
// proposals for values
......@@ -122,20 +129,46 @@ export class JSONIntellisense {
if (schema) {
// value proposals with schema
collectionPromises.push(this.getValueSuggestions(schema, doc, node, offset, collector));
this.getValueSuggestions(resource, schema, doc, node, offset, collector);
} else {
// value proposals without schema
collectionPromises.push(this.getSchemaLessValueSuggestions(doc, node, offset, modelMirror, collector));
this.getSchemaLessValueSuggestions(doc, node, offset, modelMirror, collector);
}
if (!node) {
this.contributions.forEach((contribution) => {
var collectPromise = contribution.collectDefaultSuggestions(resource, collector);
if (collectPromise) {
collectionPromises.push(collectPromise);
}
});
} else {
if ((node.type === 'property') && offset > (<Parser.PropertyASTNode> node).colonOffset) {
var parentKey = (<Parser.PropertyASTNode>node).key.value;
var valueNode = (<Parser.PropertyASTNode> node).value;
if (!valueNode || offset <= valueNode.end) {
var location = node.parent.getNodeLocation();
this.contributions.forEach((contribution) => {
var collectPromise = contribution.collectValueSuggestions(resource, location, parentKey, collector);
if (collectPromise) {
collectionPromises.push(collectPromise);
}
});
}
}
}
return WinJS.Promise.join(collectionPromises).then(() => { return result; } );
});
}
private getPropertySuggestions(schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, currentWord: string, addValue: boolean, isLast: boolean, collector: JsonWorker.ISuggestionsCollector): WinJS.Promise {
private getPropertySuggestions(resource: URI, schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, currentWord: string, addValue: boolean, isLast: boolean, collector: JsonWorker.ISuggestionsCollector): void {
var matchingSchemas: Parser.IApplicableSchema[] = [];
doc.validate(schema.schema, matchingSchemas, node.start);
var collectPromises: WinJS.TPromise<Modes.ISuggestion[]>[] = [];
matchingSchemas.forEach((s) => {
if (s.node === node && !s.inverted) {
var schemaProperties = s.schema.properties;
......@@ -145,19 +178,11 @@ export class JSONIntellisense {
collector.add({ type: 'property', label: key, codeSnippet: this.getSnippetForProperty(key, propertySchema, addValue, isLast), documentationLabel: propertySchema.description || '' });
});
}
var contributionKey = s.schema.id;
if (contributionKey) {
this.contributions.forEach((contribution) => {
collectPromises.push(contribution.collectPropertySuggestions(contributionKey, currentWord, addValue, isLast, collector));
});
}
}
});
return WinJS.Promise.join(collectPromises);
}
private getSchemaLessPropertySuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, collector: JsonWorker.ISuggestionsCollector): WinJS.Promise {
private getSchemaLessPropertySuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, collector: JsonWorker.ISuggestionsCollector): void {
var collectSuggestionsForSimilarObject = (obj: Parser.ObjectASTNode) => {
obj.properties.forEach((p) => {
var key = p.key.value;
......@@ -181,10 +206,9 @@ export class JSONIntellisense {
}
});
}
return WinJS.Promise.as(0);
}
public getSchemaLessValueSuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, modelMirror: EditorCommon.IMirrorModel, collector: JsonWorker.ISuggestionsCollector): WinJS.Promise {
public getSchemaLessValueSuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, modelMirror: EditorCommon.IMirrorModel, collector: JsonWorker.ISuggestionsCollector): void {
var collectSuggestionsForValues = (value: Parser.ASTNode) => {
var content = this.getMatchingSnippet(value, modelMirror);
collector.add({ type: this.getSuggestionType(value.type), label: content, codeSnippet: content, documentationLabel: '' });
......@@ -231,24 +255,20 @@ export class JSONIntellisense {
}
}
}
return WinJS.Promise.as(0);
}
public getValueSuggestions(schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, collector: JsonWorker.ISuggestionsCollector) : WinJS.Promise {
public getValueSuggestions(resource: URI, schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, offset: number, collector: JsonWorker.ISuggestionsCollector) : void {
var collectPromises: WinJS.TPromise<Modes.ISuggestion[]>[] = [];
if (!node) {
this.addDefaultSuggestion(schema.schema, collector);
this.contributions.forEach((contribution) => {
collectPromises.push(contribution.collectDefaultSuggestions(schema.schema.id, collector));
});
} else {
var parentKey: string = null;
if (node && (node.type === 'property') && offset > (<Parser.PropertyASTNode> node).colonOffset) {
var valueNode = (<Parser.PropertyASTNode> node).value;
if (valueNode && offset > valueNode.end) {
return WinJS.Promise.as(0); // we are past the value node
return; // we are past the value node
}
parentKey = (<Parser.PropertyASTNode>node).key.value;
node = node.parent;
......@@ -256,6 +276,7 @@ export class JSONIntellisense {
if (node && (parentKey !== null || node.type === 'array')) {
var matchingSchemas: Parser.IApplicableSchema[] = [];
doc.validate(schema.schema, matchingSchemas, node.start);
matchingSchemas.forEach((s) => {
if (s.node === node && !s.inverted && s.schema) {
if (s.schema.items) {
......@@ -269,19 +290,11 @@ export class JSONIntellisense {
this.addEnumSuggestion(propertySchema, collector);
}
}
var contributionKey = s.schema.id;
if (contributionKey) {
this.contributions.forEach((contribution) => {
collectPromises.push(contribution.collectValueSuggestions(contributionKey, parentKey, collector));
});
}
}
});
}
}
return WinJS.Promise.join(collectPromises);
}
private addBooleanSuggestion(value: boolean, collector: JsonWorker.ISuggestionsCollector): void {
......
......@@ -32,6 +32,7 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import {IResourceService} from 'vs/editor/common/services/resourceService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {JSONLocation} from './parser/jsonLocation';
export interface IOptionsSchema {
/**
......@@ -64,10 +65,10 @@ export interface ISuggestionsCollector {
}
export interface IJSONWorkerContribution {
getInfoContribution(contributionId: string, propertyKey: string) : WinJS.TPromise<HtmlContent.IHTMLContentElement[]>;
collectPropertySuggestions(contributionId: string, currentWord: string, addValue: boolean, isLast:boolean, result: ISuggestionsCollector) : WinJS.Promise;
collectValueSuggestions(contributionId: string, propertyKey: string, result: ISuggestionsCollector): WinJS.Promise;
collectDefaultSuggestions(contributionId: string, result: ISuggestionsCollector): WinJS.Promise;
getInfoContribution(resource: URI, location: JSONLocation) : WinJS.TPromise<HtmlContent.IHTMLContentElement[]>;
collectPropertySuggestions(resource: URI, location: JSONLocation, currentWord: string, addValue: boolean, isLast:boolean, result: ISuggestionsCollector) : WinJS.Promise;
collectValueSuggestions(resource: URI, location: JSONLocation, propertyKey: string, result: ISuggestionsCollector): WinJS.Promise;
collectDefaultSuggestions(resource: URI, result: ISuggestionsCollector): WinJS.Promise;
}
export class JSONWorker extends AbstractModeWorker implements Modes.IExtraInfoSupport {
......@@ -235,13 +236,12 @@ export class JSONWorker extends AbstractModeWorker implements Modes.IExtraInfoSu
return true;
});
if (contributonId && node.name) {
for (var i= this.contributions.length -1; i >= 0; i--) {
var contribution = this.contributions[i];
var promise = contribution.getInfoContribution(contributonId, node.name);
if (promise) {
return promise.then((htmlContent) => { return this.createInfoResult(htmlContent, originalNode, modelMirror); } );
}
var location = node.getNodeLocation();
for (var i= this.contributions.length -1; i >= 0; i--) {
var contribution = this.contributions[i];
var promise = contribution.getInfoContribution(resource, location);
if (promise) {
return promise.then((htmlContent) => { return this.createInfoResult(htmlContent, originalNode, modelMirror); } );
}
}
......@@ -356,28 +356,28 @@ export class JSONWorker extends AbstractModeWorker implements Modes.IExtraInfoSu
}
};
return this.jsonIntellisense.getValueSuggestions(schema, doc, node.parent, node.start, collector).then(() => {
var range = modelMirror.getRangeFromOffsetAndLength(node.start, node.end - node.start);
var text = modelMirror.getValueInRange(range);
for (var i = 0, len = proposals.length; i < len; i++) {
if (Strings.equalsIgnoreCase(proposals[i].label, text)) {
var nextIdx = i;
if (up) {
nextIdx = (i + 1) % len;
} else {
nextIdx = i - 1;
if (nextIdx < 0) {
nextIdx = len - 1;
}
this.jsonIntellisense.getValueSuggestions(resource, schema, doc, node.parent, node.start, collector);
var range = modelMirror.getRangeFromOffsetAndLength(node.start, node.end - node.start);
var text = modelMirror.getValueInRange(range);
for (var i = 0, len = proposals.length; i < len; i++) {
if (Strings.equalsIgnoreCase(proposals[i].label, text)) {
var nextIdx = i;
if (up) {
nextIdx = (i + 1) % len;
} else {
nextIdx = i - 1;
if (nextIdx < 0) {
nextIdx = len - 1;
}
return {
value: proposals[nextIdx].label,
range: range
};
}
return {
value: proposals[nextIdx].label,
range: range
};
}
return null;
});
}
return null;
}
});
}
......
/*---------------------------------------------------------------------------------------------
* 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 class JSONLocation {
private segments: string[];
constructor(segments: string[]) {
this.segments = segments;
}
public append(segment: string) : JSONLocation {
return new JSONLocation(this.segments.concat(segment));
}
public getSegments() {
return this.segments;
}
public matches(segments: string[]) {
var k = 0;
for (var i= 0; k < segments.length && i < this.segments.length; i++) {
if (segments[k] === this.segments[i] || segments[k] === '*') {
k++;
} else if (segments[k] !== '**') {
return false;
}
}
return k === segments.length;
}
public toString() : string {
return '[' + this.segments.join('][') + ']';
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@ import Arrays = require('vs/base/common/arrays');
import Types = require('vs/base/common/types');
import Json = require('vs/base/common/json');
import JsonSchema = require('vs/base/common/jsonSchema');
import {JSONLocation} from './jsonLocation';
import SchemaService = require('vs/languages/json/common/jsonSchemaService');
export interface IRange {
......@@ -36,21 +37,15 @@ export class ASTNode {
this.parent = parent;
}
public getPath():string[] {
var path:string[] = [];
if (this.parent) {
path = this.parent.getPath();
if (this.name) {
path.push(this.name);
}
return path;
} else {
return path;
public getNodeLocation(): JSONLocation {
var path = this.parent ? this.parent.getNodeLocation() : new JSONLocation([]);
if (this.name) {
path = path.append(this.name);
}
return path;
}
public getChildNodes(): ASTNode[] {
return [];
}
......@@ -925,7 +920,7 @@ export class JSONParser {
_scanner.scan(); // consume ColonToken
if (!node.setValue(_parseValue(node, node.key.getValue()))) {
if (!node.setValue(_parseValue(node, key.value))) {
return _error(nls.localize('ValueExpected', 'Value expected'), node, [], [Json.SyntaxKind.CloseBraceToken, Json.SyntaxKind.CommaToken]);
}
node.end = node.value.end;
......@@ -1013,7 +1008,7 @@ export class JSONParser {
_scanner.scan();
_doc.root = _parseValue(null, 'root');
_doc.root = _parseValue(null, null);
if (!_doc.root) {
_error(nls.localize('Invalid symbol', 'Expected a JSON object, array or literal'));
} else if (_scanner.getToken() !== Json.SyntaxKind.EOF) {
......
......@@ -104,7 +104,7 @@ suite('JSON - Parsing', () => {
var node = result.getNodeFromOffset(1);
assert.equal(node.type, 'object');
assert.deepEqual(node.getPath(), []);
assert.deepEqual(node.getNodeLocation().getSegments(), []);
assert.strictEqual(result.getNodeFromOffset(2), null);
......@@ -114,8 +114,7 @@ suite('JSON - Parsing', () => {
node = result.getNodeFromOffset(2);
assert.equal(node.type, 'null');
assert.equal(node.name, '0');
assert.deepEqual(node.getPath(), ['0']);
assert.deepEqual(node.getNodeLocation().getSegments(), ['0']);
result = parser.parse('{"a":true}');
assert.strictEqual(result.errors.length, 0);
......@@ -124,7 +123,7 @@ suite('JSON - Parsing', () => {
assert.equal(node.type, 'string');
assert.equal((<Parser.StringASTNode>node).isKey, true);
assert.deepEqual(node.getPath(), ['a']);
assert.deepEqual(node.getNodeLocation().getSegments(), ['a']);
node = result.getNodeFromOffset(4);
......@@ -141,8 +140,7 @@ suite('JSON - Parsing', () => {
node = result.getNodeFromOffset(5);
assert.equal(node.type, 'boolean');
assert.equal(node.name, 'a');
assert.deepEqual(node.getPath(), ['a']);
assert.deepEqual(node.getNodeLocation().getSegments(), ['a']);
});
......@@ -155,14 +153,14 @@ suite('JSON - Parsing', () => {
assert.strictEqual(result.errors.length, 0);
var node = result.getNodeFromOffset(content.indexOf('key2') + 2);
var path = node.getPath();
var location = node.getNodeLocation();
assert.deepEqual(path, ['key', 'key2']);
assert.deepEqual(location.getSegments(), ['key', 'key2']);
node = result.getNodeFromOffset(content.indexOf('42') + 1);
path = node.getPath();
location = node.getNodeLocation();
assert.deepEqual(path, ['key', 'key2']);
assert.deepEqual(location.getSegments(), ['key', 'key2']);
});
test('Nested AST in Array', function() {
......@@ -173,9 +171,9 @@ suite('JSON - Parsing', () => {
assert.strictEqual(result.errors.length, 0);
var node = result.getNodeFromOffset(17);
var path = node.getPath();
var location = node.getNodeLocation();
assert.deepEqual(path, ['key', '0', 'key2']);
assert.deepEqual(location.getSegments(), ['key', '0', 'key2']);
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册