Fixes #2365: [json] JSON could complete identifier with quotes

This commit is contained in:
Martin Aeschlimann 2016-01-28 16:53:35 +01:00
parent 706413e537
commit 5785cf462e

View file

@ -107,10 +107,10 @@ export class JSONCompletion {
let isLast = properties.length === 0 || offset >= properties[properties.length - 1].start; let isLast = properties.length === 0 || offset >= properties[properties.length - 1].start;
if (schema) { if (schema) {
// property proposals with schema // property proposals with schema
this.getPropertySuggestions(schema, doc, node, currentKey, addValue, isLast, collector); this.getPropertySuggestions(schema, doc, node, addValue, isLast, collector);
} else if (node.parent) { } else {
// property proposals without schema // property proposals without schema
this.getSchemaLessPropertySuggestions(doc, node, collector); this.getSchemaLessPropertySuggestions(doc, node, currentKey, currentWord, isLast, collector);
} }
let location = node.getNodeLocation(); let location = node.getNodeLocation();
@ -134,7 +134,8 @@ export class JSONCompletion {
} else { } else {
// value proposals without schema // value proposals without schema
this.getSchemaLessValueSuggestions(doc, node, offset, document, collector); this.getSchemaLessValueSuggestions(doc, node, offset, document, collector);
} }
if (!node) { if (!node) {
this.contributions.forEach((contribution) => { this.contributions.forEach((contribution) => {
let collectPromise = contribution.collectDefaultSuggestions(textDocumentPosition.uri, collector); let collectPromise = contribution.collectDefaultSuggestions(textDocumentPosition.uri, collector);
@ -162,7 +163,7 @@ export class JSONCompletion {
}); });
} }
private getPropertySuggestions(schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, currentWord: string, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector): void { private getPropertySuggestions(schema: SchemaService.ResolvedSchema, doc: Parser.JSONDocument, node: Parser.ASTNode, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector): void {
let matchingSchemas: Parser.IApplicableSchema[] = []; let matchingSchemas: Parser.IApplicableSchema[] = [];
doc.validate(schema.schema, matchingSchemas, node.start); doc.validate(schema.schema, matchingSchemas, node.start);
@ -179,29 +180,34 @@ export class JSONCompletion {
}); });
} }
private getSchemaLessPropertySuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, collector: ISuggestionsCollector): void { private getSchemaLessPropertySuggestions(doc: Parser.JSONDocument, node: Parser.ASTNode, currentKey: string, currentWord: string, isLast: boolean, collector: ISuggestionsCollector): void {
let collectSuggestionsForSimilarObject = (obj: Parser.ObjectASTNode) => { let collectSuggestionsForSimilarObject = (obj: Parser.ObjectASTNode) => {
obj.properties.forEach((p) => { obj.properties.forEach((p) => {
let key = p.key.value; let key = p.key.value;
collector.add({ kind: CompletionItemKind.Property, label: key, insertText: this.getSnippetForSimilarProperty(key, p.value), documentation: '' }); collector.add({ kind: CompletionItemKind.Property, label: key, insertText: this.getSnippetForSimilarProperty(key, p.value), documentation: '' });
}); });
}; };
if (node.parent.type === 'property') { if (node.parent) {
// if the object is a property value, check the tree for other objects that hang under a property of the same name if (node.parent.type === 'property') {
let parentKey = (<Parser.PropertyASTNode>node.parent).key.value; // if the object is a property value, check the tree for other objects that hang under a property of the same name
doc.visit((n) => { let parentKey = (<Parser.PropertyASTNode>node.parent).key.value;
if (n.type === 'property' && (<Parser.PropertyASTNode>n).key.value === parentKey && (<Parser.PropertyASTNode>n).value && (<Parser.PropertyASTNode>n).value.type === 'object') { doc.visit((n) => {
collectSuggestionsForSimilarObject(<Parser.ObjectASTNode>(<Parser.PropertyASTNode>n).value); if (n.type === 'property' && (<Parser.PropertyASTNode>n).key.value === parentKey && (<Parser.PropertyASTNode>n).value && (<Parser.PropertyASTNode>n).value.type === 'object') {
} collectSuggestionsForSimilarObject(<Parser.ObjectASTNode>(<Parser.PropertyASTNode>n).value);
return true; }
}); return true;
} else if (node.parent.type === 'array') { });
// if the object is in an array, use all other array elements as similar objects } else if (node.parent.type === 'array') {
(<Parser.ArrayASTNode>node.parent).items.forEach((n) => { // if the object is in an array, use all other array elements as similar objects
if (n.type === 'object' && n !== node) { (<Parser.ArrayASTNode>node.parent).items.forEach((n) => {
collectSuggestionsForSimilarObject(<Parser.ObjectASTNode>n); if (n.type === 'object' && n !== node) {
} collectSuggestionsForSimilarObject(<Parser.ObjectASTNode>n);
}); }
});
}
}
if (!currentKey && currentWord.length > 0) {
collector.add({ kind: CompletionItemKind.Property, label: JSON.stringify(currentWord), insertText: this.getSnippetForProperty(currentWord, null, true, isLast), documentation: '' });
} }
} }
@ -403,35 +409,39 @@ export class JSONCompletion {
return result; return result;
} }
result += ': '; result += ': ';
let defaultVal = propertySchema.default; if (propertySchema) {
if (typeof defaultVal !== 'undefined') { let defaultVal = propertySchema.default;
result = result + this.getSnippetForValue(defaultVal); if (typeof defaultVal !== 'undefined') {
} else if (propertySchema.enum && propertySchema.enum.length > 0) { result = result + this.getSnippetForValue(defaultVal);
result = result + this.getSnippetForValue(propertySchema.enum[0]); } else if (propertySchema.enum && propertySchema.enum.length > 0) {
} else { result = result + this.getSnippetForValue(propertySchema.enum[0]);
switch (propertySchema.type) { } else {
case 'boolean': switch (propertySchema.type) {
result += '{{false}}'; case 'boolean':
break; result += '{{false}}';
case 'string': break;
result += '"{{}}"'; case 'string':
break; result += '"{{}}"';
case 'object': break;
result += '{\n\t{{}}\n}'; case 'object':
break; result += '{\n\t{{}}\n}';
case 'array': break;
result += '[\n\t{{}}\n]'; case 'array':
break; result += '[\n\t{{}}\n]';
case 'number': break;
result += '{{0}}'; case 'number':
break; result += '{{0}}';
case 'null': break;
result += '{{null}}'; case 'null':
break; result += '{{null}}';
default: break;
return result; default:
return result;
}
} }
} else {
result += '{{0}}';
} }
if (!isLast) { if (!isLast) {
result += ','; result += ',';