amazon-states-language-service
Advanced tools
Comparing version 1.6.1 to 1.6.2
@@ -8,3 +8,5 @@ "use strict"; | ||
const vscode_json_languageservice_1 = require("vscode-json-languageservice"); | ||
const constants_1 = require("../constants/constants"); | ||
const astUtilityFunctions_1 = require("../utils/astUtilityFunctions"); | ||
const yamlUtils_1 = require("../yaml/yamlUtils"); | ||
function getStatesFromStartAtNode(node, options) { | ||
@@ -51,10 +53,19 @@ if (node.keyNode.value === 'StartAt') { | ||
} | ||
function getCompletionList(items, replaceRange, shouldAddLeftQuote, shouldAddLeftSpace, shoudlAddTrailingComma) { | ||
function getCompletionList(items, replaceRange, languageId, options) { | ||
const { shouldAddLeftQuote, shouldAddRightQuote, shouldAddLeadingSpace, shoudlAddTrailingComma } = options; | ||
const list = { | ||
isIncomplete: false, | ||
items: items.map(name => { | ||
const shouldWrapStateNameInQuotes = languageId === constants_1.LANGUAGE_IDS.YAML && yamlUtils_1.isStateNameReservedYamlKeyword(name); | ||
const item = vscode_json_languageservice_1.CompletionItem.create(name); | ||
item.commitCharacters = [',']; | ||
item.kind = vscode_json_languageservice_1.CompletionItemKind.Value; | ||
item.textEdit = vscode_json_languageservice_1.TextEdit.replace(replaceRange, `${shouldAddLeftSpace ? ' ' : ''}${shouldAddLeftQuote ? '"' : ''}${name}"${shoudlAddTrailingComma ? ',' : ''}`); | ||
const newText = (shouldAddLeadingSpace ? ' ' : '') + | ||
(shouldAddLeftQuote ? '"' : '') + | ||
(shouldWrapStateNameInQuotes ? "'" : '') + | ||
name + | ||
(shouldWrapStateNameInQuotes ? "'" : '') + | ||
(shouldAddRightQuote ? '"' : '') + | ||
(shoudlAddTrailingComma ? ',' : ''); | ||
item.textEdit = vscode_json_languageservice_1.TextEdit.replace(replaceRange, newText); | ||
item.filterText = name; | ||
@@ -79,3 +90,9 @@ return item; | ||
const range = vscode_json_languageservice_1.Range.create(colonPosition, endPosition); | ||
return getCompletionList(states, range, true, true, true); | ||
const completeStateNameOptions = { | ||
shouldAddLeftQuote: true, | ||
shouldAddRightQuote: true, | ||
shouldAddLeadingSpace: true, | ||
shoudlAddTrailingComma: true | ||
}; | ||
return getCompletionList(states, range, document.languageId, completeStateNameOptions); | ||
} | ||
@@ -93,4 +110,21 @@ } | ||
const range = vscode_json_languageservice_1.Range.create(startPosition, endPosition); | ||
const isCursorAtTheBeginning = offset === node.offset; | ||
return getCompletionList(states, range, isCursorAtTheBeginning); | ||
if (document.languageId === constants_1.LANGUAGE_IDS.YAML) { | ||
const completeStateNameOptions = { | ||
shouldAddLeftQuote: false, | ||
shouldAddRightQuote: false, | ||
shouldAddLeadingSpace: false, | ||
shoudlAddTrailingComma: false | ||
}; | ||
return getCompletionList(states, range, document.languageId, completeStateNameOptions); | ||
} | ||
else { | ||
const isCursorAtTheBeginning = offset === node.offset; | ||
const completeStateNameOptions = { | ||
shouldAddLeftQuote: isCursorAtTheBeginning, | ||
shouldAddRightQuote: true, | ||
shouldAddLeadingSpace: false, | ||
shoudlAddTrailingComma: false | ||
}; | ||
return getCompletionList(states, range, document.languageId, completeStateNameOptions); | ||
} | ||
} | ||
@@ -97,0 +131,0 @@ } |
@@ -15,1 +15,4 @@ /*! | ||
}; | ||
export declare const YAML_PARSER_MESSAGES: { | ||
readonly DUPLICATE_KEY: "duplicate key"; | ||
}; |
@@ -17,2 +17,5 @@ "use strict"; | ||
}; | ||
exports.YAML_PARSER_MESSAGES = { | ||
DUPLICATE_KEY: 'duplicate key' | ||
}; | ||
//# sourceMappingURL=diagnosticStrings.js.map |
@@ -26,2 +26,3 @@ "use strict"; | ||
const completeAsl_1 = __importDefault(require("./completion/completeAsl")); | ||
const constants_1 = require("./constants/constants"); | ||
const validateStates_1 = __importDefault(require("./validation/validateStates")); | ||
@@ -42,3 +43,3 @@ const aslYamlLanguageService_1 = require("./yaml/aslYamlLanguageService"); | ||
{ | ||
uri: 'asl', | ||
uri: constants_1.LANGUAGE_IDS.JSON, | ||
fileMatch: ['*'], | ||
@@ -55,3 +56,3 @@ schema: bundled_json_1.default | ||
// Non JSON Schema validation will have source: 'asl' | ||
if (diagnostic.source !== 'asl') { | ||
if (diagnostic.source !== constants_1.LANGUAGE_IDS.JSON) { | ||
return Object.assign(Object.assign({}, diagnostic), { severity: vscode_json_languageservice_1.DiagnosticSeverity.Error }); | ||
@@ -58,0 +59,0 @@ } |
@@ -6,2 +6,3 @@ /*! | ||
import { ArrayASTNode, ASTNode, JSONDocument, ObjectASTNode, PropertyASTNode, StringASTNode } from 'vscode-json-languageservice'; | ||
import { Position } from 'vscode-languageserver-types'; | ||
export interface ASTTree extends JSONDocument { | ||
@@ -14,2 +15,15 @@ root?: ASTNode; | ||
} | ||
export interface CompleteStateNameOptions { | ||
shouldAddLeftQuote?: boolean; | ||
shouldAddRightQuote?: boolean; | ||
shouldAddLeadingSpace?: boolean; | ||
shoudlAddTrailingComma?: boolean; | ||
} | ||
export interface ProcessYamlDocForCompletionOutput { | ||
modifiedDocText: string; | ||
tempPositionForCompletions: Position; | ||
startPositionForInsertion: Position; | ||
endPositionForInsertion: Position; | ||
shouldPrependSpace: boolean; | ||
} | ||
export declare function isStringNode(node: ASTNode): node is StringASTNode; | ||
@@ -16,0 +30,0 @@ export declare function isPropertyNode(node: ASTNode): node is PropertyASTNode; |
@@ -29,2 +29,3 @@ "use strict"; | ||
const vscode_json_languageservice_1 = require("vscode-json-languageservice"); | ||
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument"); | ||
const vscode_languageserver_types_1 = require("vscode-languageserver-types"); | ||
@@ -36,2 +37,32 @@ const yamlParser07_1 = require("yaml-language-server/out/server/src/languageservice/parser/yamlParser07"); | ||
const completeAsl_1 = __importDefault(require("../completion/completeAsl")); | ||
const constants_1 = require("../constants/constants"); | ||
const diagnosticStrings_1 = require("../constants/diagnosticStrings"); | ||
const yamlUtils_1 = require("./yamlUtils"); | ||
function convertYAMLDiagnostic(yamlDiagnostic, textDocument) { | ||
const startLoc = yamlDiagnostic.location.start; | ||
let endLoc = yamlDiagnostic.location.end; | ||
let severity = yamlDiagnostic.severity; | ||
// Duplicate positioning returns incorrect end position and needs to be ovewritten | ||
if (yamlDiagnostic.message === diagnosticStrings_1.YAML_PARSER_MESSAGES.DUPLICATE_KEY) { | ||
const text = textDocument.getText(); | ||
// Update severity to error | ||
severity = 1; | ||
for (let loc = yamlDiagnostic.location.start; loc < text.length; loc++) { | ||
// Colon and whitespace character signal the end of the key. | ||
if (text.slice(loc, loc + 2).match(/:\s/)) { | ||
endLoc = loc; | ||
} | ||
else if (text[loc] === '\n') { | ||
break; | ||
} | ||
} | ||
} | ||
const startPos = textDocument.positionAt(startLoc); | ||
const endPos = textDocument.positionAt(endLoc); | ||
return { | ||
range: vscode_languageserver_types_1.Range.create(startPos, endPos), | ||
message: yamlDiagnostic.message, | ||
severity | ||
}; | ||
} | ||
exports.getLanguageService = function (params, schema, aslLanguageService) { | ||
@@ -49,4 +80,4 @@ const builtInParams = {}; | ||
// initialize schema | ||
schemaService.registerExternalSchema('asl-yaml', ['*.asl.yaml', '*.asl.yml'], schema); | ||
schemaService.getOrAddSchemaHandle('asl-yaml', schema); | ||
schemaService.registerExternalSchema(constants_1.LANGUAGE_IDS.YAML, ['*'], schema); | ||
schemaService.getOrAddSchemaHandle(constants_1.LANGUAGE_IDS.YAML, schema); | ||
const completer = new yamlCompletion_1.YAMLCompletion(schemaService); | ||
@@ -59,9 +90,5 @@ languageService.doValidation = function (textDocument) { | ||
const validation = yield aslLanguageService.doValidation(textDocument, currentYAMLDoc); | ||
const syd = currentYAMLDoc; | ||
if (syd.errors.length > 0) { | ||
validationResult.push(...syd.errors); | ||
} | ||
if (syd.warnings.length > 0) { | ||
validationResult.push(...syd.warnings); | ||
} | ||
validationResult.push(...currentYAMLDoc.errors | ||
.concat(currentYAMLDoc.warnings) | ||
.map(err => convertYAMLDiagnostic(err, textDocument))); | ||
validationResult.push(...validation); | ||
@@ -80,8 +107,8 @@ } | ||
Array.from(cursorLine).forEach(char => { | ||
if (char !== ' ') { | ||
if (char === ' ') { | ||
numberOfSpacesCursorLine++; | ||
} | ||
else if (char !== "'" && char !== '"') { | ||
hasCursorLineNonSpace = true; | ||
} | ||
else { | ||
numberOfSpacesCursorLine++; | ||
} | ||
}); | ||
@@ -121,67 +148,55 @@ if (!hasCursorLineNonSpace && numberOfSpacesCursorLine > 0) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const yamldoc = yamlParser07_1.parse(document.getText()); | ||
const offset = document.offsetAt(position); | ||
let currentDoc = arrUtils_1.matchOffsetToDocument(offset, yamldoc); | ||
let atSpace = false; | ||
// if a yaml doc is null, it must be given text to allow auto-completion | ||
const { modifiedDocText, tempPositionForCompletions, startPositionForInsertion, endPositionForInsertion, shouldPrependSpace } = yamlUtils_1.processYamlDocForCompletion(document, position); | ||
const processedDocument = vscode_languageserver_textdocument_1.TextDocument.create(document.uri, document.languageId, document.version, modifiedDocText); | ||
const offsetIntoOriginalDocument = document.offsetAt(position); | ||
const offsetIntoProcessedDocument = processedDocument.offsetAt(tempPositionForCompletions); | ||
const processedYamlDoc = yamlParser07_1.parse(modifiedDocText); | ||
const currentDoc = arrUtils_1.matchOffsetToDocument(offsetIntoProcessedDocument, processedYamlDoc); | ||
if (!currentDoc) { | ||
currentDoc = initializeDocument(document, offset); | ||
// move cursor position into new empty object | ||
position.character += 1; | ||
} | ||
const yamlCompletions = yield completer.doComplete(document, position, false); | ||
if (!currentDoc) { | ||
return { items: [], isIncomplete: false }; | ||
} | ||
// adjust position for completion | ||
const node = currentDoc.getNodeFromOffsetEndInclusive(offset); | ||
if (node.type === 'array') { | ||
// Resolves issue with array item insert text being off by a space | ||
position.character -= 1; | ||
} | ||
else if (document.getText().substring(offset, offset + 1) === '"') { | ||
// When attempting to auto-complete from inside an empty string, the position must be adjusted within bounds | ||
position.character += 1; | ||
} | ||
else if (document.getText().substring(offset - 2, offset) === ': ') { | ||
// yaml doesn't allow auto-completion from white-space after certain nodes | ||
atSpace = true; | ||
// initialize an empty string and adjust position to within the string before parsing yaml to json | ||
const newText = `${document.getText().substring(0, offset)}""\n${document.getText().substr(offset)}`; | ||
const parsedDoc = yamlParser07_1.parse(newText); | ||
currentDoc = arrUtils_1.matchOffsetToDocument(offset, parsedDoc); | ||
position.character += 1; | ||
} | ||
else if (node.type === 'property' || (node.type === 'object' && position.character !== 0)) { | ||
position.character -= 1; | ||
} | ||
if (currentDoc) { | ||
const aslCompletions = completeAsl_1.default(document, position, currentDoc, yamlCompletions, { | ||
ignoreColonOffset: true, | ||
shouldShowStateSnippets: isChildOfStates(document, offset) | ||
}); | ||
aslCompletions.items.forEach(completion => { | ||
// format json completions for yaml | ||
if (completion.textEdit) { | ||
// textEdit can't be done on white-space so insert text is used instead | ||
if (atSpace) { | ||
// remove any commas from json-completions | ||
completion.insertText = completion.textEdit.newText.replace(/[\,]/g, ''); | ||
completion.textEdit = undefined; | ||
const positionForDoComplete = Object.assign({}, tempPositionForCompletions); // Copy position to new object since doComplete modifies the position | ||
const yamlCompletions = yield completer.doComplete(processedDocument, positionForDoComplete, false); | ||
const aslOptions = { | ||
ignoreColonOffset: true, | ||
shouldShowStateSnippets: isChildOfStates(document, offsetIntoOriginalDocument) | ||
}; | ||
const aslCompletions = completeAsl_1.default(processedDocument, tempPositionForCompletions, currentDoc, yamlCompletions, aslOptions); | ||
const modifiedAslCompletionItems = aslCompletions.items.map(completionItem => { | ||
var _a; | ||
const completionItemCopy = Object.assign({}, completionItem); // Copy completion to new object to avoid overwriting any snippets | ||
if (completionItemCopy.insertText && completionItemCopy.kind === vscode_json_languageservice_1.CompletionItemKind.Snippet && document.languageId === constants_1.LANGUAGE_IDS.YAML) { | ||
completionItemCopy.insertText = js_yaml_1.safeDump(js_yaml_1.safeLoad(completionItemCopy.insertText)); | ||
// Remove quotation marks | ||
completionItemCopy.insertText = (_a = completionItemCopy.insertText) === null || _a === void 0 ? void 0 : _a.replace(/[']/g, ''); | ||
} | ||
else { | ||
const currentTextEdit = completionItemCopy.textEdit; | ||
if (currentTextEdit) { | ||
if (shouldPrependSpace) { | ||
if (currentTextEdit.newText && currentTextEdit.newText.charAt(0) !== ' ') { | ||
currentTextEdit.newText = ' ' + currentTextEdit.newText; | ||
} | ||
if (completionItemCopy.insertText && completionItemCopy.insertText.charAt(0) !== ' ') { | ||
completionItemCopy.insertText = ' ' + completionItemCopy.insertText; | ||
} | ||
} | ||
else { | ||
completion.textEdit.range.start.character = position.character; | ||
currentTextEdit.range.start = startPositionForInsertion; | ||
currentTextEdit.range.end = endPositionForInsertion; | ||
// Completions that include both a key and a value should replace everything right of the cursor. | ||
if (completionItemCopy.kind === vscode_json_languageservice_1.CompletionItemKind.Property) { | ||
currentTextEdit.range.end = { | ||
line: endPositionForInsertion.line, | ||
character: document.getText().length | ||
}; | ||
} | ||
} | ||
else if (completion.insertText && completion.kind === vscode_json_languageservice_1.CompletionItemKind.Snippet && document.languageId === 'asl-yaml') { | ||
completion.insertText = js_yaml_1.safeDump(js_yaml_1.safeLoad(completion.insertText)); | ||
// Remove quotes | ||
completion.insertText = completion.insertText.replace(/[']/g, ''); | ||
} | ||
}); | ||
return Promise.resolve(aslCompletions); | ||
} | ||
else { | ||
return { items: [], isIncomplete: false }; | ||
} | ||
} | ||
return completionItemCopy; | ||
}); | ||
const modifiedAslCompletions = { | ||
isIncomplete: aslCompletions.isIncomplete, | ||
items: modifiedAslCompletionItems | ||
}; | ||
return Promise.resolve(modifiedAslCompletions); | ||
}); | ||
@@ -237,10 +252,4 @@ }; | ||
}; | ||
// initialize brackets to surround the empty space when parsing | ||
const initializeDocument = function (text, offset) { | ||
// tslint:disable-next-line: prefer-template | ||
const newText = `${text.getText().substring(0, offset)}{}\r${text.getText().substr(offset)}`; | ||
return arrUtils_1.matchOffsetToDocument(offset, yamlParser07_1.parse(newText)); | ||
}; | ||
return languageService; | ||
}; | ||
//# sourceMappingURL=aslYamlLanguageService.js.map |
@@ -15,3 +15,3 @@ { | ||
"license": "MIT", | ||
"version": "1.6.1", | ||
"version": "1.6.2", | ||
"publisher": "aws", | ||
@@ -18,0 +18,0 @@ "categories": [ |
284055
35
4380