Skip to content

Commit

Permalink
[Console] Fix tokens parsing for nested objects
Browse files Browse the repository at this point in the history
  • Loading branch information
yuliacech committed May 13, 2024
1 parent 6cf32fb commit 1ff1acb
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,11 @@ export class MonacoEditorActionsProvider {
return AutocompleteType.BODY;
}

private async getSuggestions(model: monaco.editor.ITextModel, position: monaco.Position) {
private async getSuggestions(
model: monaco.editor.ITextModel,
position: monaco.Position,
context: monaco.languages.CompletionContext
) {
// determine autocomplete type
const autocompleteType = await this.getAutocompleteType(model, position);
if (!autocompleteType) {
Expand All @@ -311,14 +315,19 @@ export class MonacoEditorActionsProvider {
}

if (autocompleteType === AutocompleteType.BODY) {
// suggestions only when triggered by " or keyboard
if (context.triggerCharacter && context.triggerCharacter !== '"') {
return { suggestions: [] };
}
const requests = await this.getRequestsBetweenLines(
model,
position.lineNumber,
position.lineNumber
);
const requestStartLineNumber = requests[0].startLineNumber;
const suggestions = getBodyCompletionItems(model, position, requestStartLineNumber);
return {
suggestions: getBodyCompletionItems(model, position, requestStartLineNumber),
suggestions,
};
}

Expand All @@ -332,6 +341,6 @@ export class MonacoEditorActionsProvider {
context: monaco.languages.CompletionContext,
token: monaco.CancellationToken
): monaco.languages.ProviderResult<monaco.languages.CompletionList> {
return this.getSuggestions(model, position);
return this.getSuggestions(model, position, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ export const getBodyCompletionItems = (
// map autocomplete items to completion items
.map((item) => {
const suggestion = {
label: item.name!,
// convert name to a string
label: item.name + '',
insertText: getInsertText(item, bodyContent),
detail: i18nTexts.api,
// the kind is only used to configure the icon
Expand All @@ -294,12 +295,12 @@ const getInsertText = (
): string => {
let insertText = bodyContent.endsWith('"') ? '' : '"';
if (insertValue && insertValue !== '{' && insertValue !== '[') {
insertText = `${insertValue}"`;
insertText += `${insertValue}"`;
} else {
insertText = `${name}"`;
insertText += `${name}"`;
}
// check if there is template to add
if (template) {
if (template !== undefined) {
let templateLines;
const { __raw, value: templateValue } = template;
if (__raw && templateValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ describe('tokens_utils', () => {
value: '{"test":[],',
tokens: ['{'],
},
{
value: '{"property1":["nested1", []],"',
tokens: ['{'],
},
{
value: '{"property1":"value1","property2":',
tokens: ['{', 'property2'],
Expand All @@ -104,7 +108,15 @@ describe('tokens_utils', () => {
},
{
value: '{"property1":[123,"test"]',
tokens: ['{', 'property1'],
tokens: ['{'],
},
{
value: '{"property1":{"nested1":"value"},"',
tokens: ['{'],
},
{
value: '{"property1":{"nested1":"value","nested2":{}},"',
tokens: ['{'],
},
];
for (const testCase of testCases) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export const parseBody = (value: string): string[] => {
) {
skipWhitespace();
skipComments();
// inspect the current char: expecting a property name or a closing }
// inspect the current char
if (isDoubleQuote(char)) {
// property name: parse the string and add to tokens
const propertyName = parsePropertyName();
Expand All @@ -304,18 +304,17 @@ export const parseBody = (value: string): string[] => {
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();

skipWhitespace();
// check if the empty object was used as a property value
if (isPropertyName(currentToken)) {
// expecting a comma, otherwise the parser fails
if (!isComma(char)) {
throw new Error('Not able to parse');
}
// after finding the comma, the property value is parsed, the property name can be removed from scope
// the empty object was the value for this property name, remove it from tokens
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();
}
} else if (isComma(char)) {
// ignore the comma
next();
} else {
throw new Error('Not able to parse');
}
Expand All @@ -326,24 +325,23 @@ export const parseBody = (value: string): string[] => {
skipWhitespace();
skipComments();

// inspect the current char: expect a closing ] or a valid value
// inspect the current char
if (char === ']') {
// an empty array
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();

skipWhitespace();
// check if empty array was used as a property value
if (isPropertyName(currentToken)) {
// expecting a comma, otherwise the parser fails
if (!isComma(char)) {
throw new Error('Not able to parse');
}
// after finding the comma, the property value is parsed, the property name can be removed from scope
// the empty array was the value for this property name, remove it from tokens
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();
}
} else if (isComma(char)) {
// ignore the comma
next();
} else {
// parsing array items

Expand All @@ -363,35 +361,16 @@ export const parseBody = (value: string): string[] => {
} else {
throw new Error('Not able to parse');
}
// after parsing a simple value, expect a comma or a closing ]
if (isComma(char)) {
next();
} else if (char === ']') {
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();
skipWhitespace();
// check if empty array was used as a property value
if (isPropertyName(currentToken)) {
// expecting a comma, otherwise the parser fails
if (!isComma(char)) {
throw new Error('Not able to parse');
}
// after finding the comma, the property value is parsed, the property name can be removed from scope
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();
}
}
}
}
} else if (
// parsing property value
// parsing property value after a property name was found
isPropertyName(currentToken)
) {
skipWhitespace();
skipComments();
if (char === '{' || char === '[') {
// nested object or array
tokens.push(char);
currentToken = char;
next();
Expand All @@ -406,14 +385,9 @@ export const parseBody = (value: string): string[] => {
} else {
throw new Error('Not able to parse');
}
// after parsing a simple value, expect a comma
if (!isComma(char)) {
throw new Error('Not able to parse');
}
// after comma, this property name is parsed and can be removed from tokens
// after parsing a simple value, this property name is parsed and can be removed from tokens
tokens.pop();
currentToken = tokens[tokens.length - 1];
next();
}
} else {
throw new Error('Not able to parse');
Expand Down

0 comments on commit 1ff1acb

Please sign in to comment.