in src/documents/parameters/ParameterValues.ts [116:200]
export async function addMissingParameters(
parameterDefinitionsSource: IParameterDefinitionsSource,
parameterValuesSource: IParameterValuesSource,
// An editor for the the parameter values source document
parameterValuesSourceEditor: TextEditor,
parentParameterDefinitions: IParameterDefinitionsSource | undefined,
onlyRequiredParameters: boolean
): Promise<void> {
// We don't currently handle the case where there is no "parameters" object
// Find the location to insert new stuff in the parameters section
const parameterValuesDocument = parameterValuesSource.document;
const parametersObjectValue = parameterValuesSource.parameterValuesProperty?.value?.asObjectValue;
if (parameterValuesSource.parameterValuesProperty && parametersObjectValue) {
// Where insert?
// Find last non-whitespace token inside the parameters section
const parametersProperty = parameterValuesSource.parameterValuesProperty;
let lastTokenInParameters: Json.Token | undefined;
for (let i = parametersProperty.span.endIndex - 1; // Start before the closing "}"
i >= parametersProperty.span.startIndex;
--i) {
lastTokenInParameters = parameterValuesDocument.jsonParseResult.getTokenAtCharacterIndex(i, Json.Comments.includeCommentTokens);
if (lastTokenInParameters) {
break;
}
}
const insertIndex: number = lastTokenInParameters
? lastTokenInParameters.span.afterEndIndex
: parametersObjectValue.span.endIndex;
const insertPosition = parameterValuesDocument.getDocumentPosition(insertIndex);
const missingParams: IParameterDefinition[] = getMissingParameters(
parameterDefinitionsSource,
parameterValuesSource,
onlyRequiredParameters);
if (missingParams.length === 0) {
return;
}
// Create insertion text
let paramsAsText: string[] = [];
for (let param of missingParams) {
const paramText = createParameterFromTemplateParameter(parameterDefinitionsSource, param, parentParameterDefinitions, defaultTabSize);
paramsAsText.push(paramText);
}
let newText = paramsAsText.join(`,${EOL}`);
// Determine indentation
const parametersObjectIndent = parameterValuesDocument.getDocumentPosition(parametersProperty?.nameValue.span.startIndex).column;
const lastParameter = parameterValuesSource.parameterValueDefinitions.length > 0 ? parameterValuesSource.parameterValueDefinitions[parameterValuesSource.parameterValueDefinitions.length - 1] : undefined;
const lastParameterIndent = lastParameter ? parameterValuesDocument.getDocumentPosition(lastParameter?.fullSpan.startIndex).column : undefined;
const newTextIndent = lastParameterIndent === undefined ? parametersObjectIndent + defaultTabSize : lastParameterIndent;
let indentedText = indentMultilineString(newText, newTextIndent);
let insertText = EOL + indentedText;
// If insertion point is on the same line as the end of the parameters object, then add a newline
// afterwards and indent it (e.g. parameters object = empty, {})
if (parameterValuesDocument.getDocumentPosition(insertIndex).line
=== parameterValuesDocument.getDocumentPosition(parametersObjectValue.span.endIndex).line
) {
insertText += EOL + ' '.repeat(defaultTabSize);
}
// Add comma before?
let commaEdit = createEditToAddCommaBeforePosition(parameterValuesSource, insertIndex);
assert(!commaEdit || commaEdit.span.endIndex <= insertIndex);
if (commaEdit?.span.startIndex === insertIndex) {
// vscode doesn't like both edits starting at the same location, so
// just add the comma directly to the string (this is the common case)
commaEdit = undefined;
insertText = `,${insertText}`;
}
await parameterValuesSourceEditor.edit(editBuilder => {
editBuilder.insert(getVSCodePositionFromPosition(insertPosition), insertText);
if (commaEdit) {
editBuilder.replace(
getVSCodeRangeFromSpan(parameterValuesDocument, commaEdit.span),
commaEdit.insertText);
}
});
}
}