Skip to content

Commit

Permalink
fix: resolve known bugs in LU LSP. (#2098)
Browse files Browse the repository at this point in the history
* init

* fix LU LSP known bugs

* remove comment

* fix bugs

* remove unused variable

Co-authored-by: Andy Brown <asbrown002@gmail.com>
  • Loading branch information
cosmicshuai and a-b-r-o-w-n authored Feb 27, 2020
1 parent 73a08fb commit 1112c86
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Composer/packages/lib/code-editor/src/LuEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { registerLULanguage } from './languages';
import { createUrl, createWebSocket, createLanguageClient } from './utils/lspUtil';
import { RichEditor, RichEditorProps } from './RichEditor';

const LU_HELP = 'https://github.com/microsoft/botframework-cli/blob/master/packages/lu/docs/lu-file-format.md';
const LU_HELP = 'https://github.com/microsoft/botframework-cli/blob/master/packages/luis/docs/lu-file-format.md';
const placeholder = `> To learn more about the LU file format, read the documentation at
> ${LU_HELP}`;

Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/lib/code-editor/src/languages/lu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function registerLULanguage(monaco: typeof monacoEditor) {
],
[
// eslint-disable-next-line security/detect-unsafe-regex
/(@\s*)(ml|prebuilt|regex|list|composite|patternany|phraselist)(\s*[\w_]+)/,
/(@\s*)(ml|prebuilt|regex|list|composite|Pattern\.Any|phraseList)(\s*[\w_]+)/,
['intent-indentifier', 'entity-type', 'entity-name'],
],
[/(@\s*)(\s*[\w_]+)/, ['intent-indentifier', 'entity-name']],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class LUServer {
codeActionProvider: false,
completionProvider: {
resolveProvider: true,
triggerCharacters: ['@', ' ', '{', ':', '['],
triggerCharacters: ['@', ' ', '{', ':', '[', '('],
},
foldingRangeProvider: false,
documentOnTypeFormattingProvider: {
Expand Down Expand Up @@ -217,7 +217,6 @@ export class LUServer {
const lastLineContent = this.getLastLineContent(params);
const edits: TextEdit[] = [];
const curLineNumber = params.position.line;
const lineCount = document.lineCount;
const luDoc = this.getLUDocument(document);
const text = luDoc?.index().content || document.getText();
const lines = text.split('\n');
Expand All @@ -229,12 +228,7 @@ export class LUServer {
const inputState = this.getInputLineState(params);

const pos = params.position;
if (
key === '\n' &&
inputState === 'utterance' &&
lastLineContent.trim() !== '-' &&
curLineNumber === lineCount - 1
) {
if (key === '\n' && inputState === 'utterance' && lastLineContent.trim() !== '-') {
const newPos = Position.create(pos.line + 1, 0);
const item: TextEdit = TextEdit.insert(newPos, '- ');
edits.push(item);
Expand All @@ -257,21 +251,23 @@ export class LUServer {
}
}

if (
key === '\n' &&
inputState === 'listEntity' &&
lastLineContent.trim() !== '-' &&
curLineNumber === lineCount - 1
) {
const newPos = Position.create(pos.line + 1, 0);
if (key === '\n' && inputState === 'listEntity' && lastLineContent.trim() !== '-') {
const newPos = Position.create(pos.line, 0);
let insertStr = '';
const indentLevel = this.getIndentLevel(lastLineContent);
if (lastLineContent.trim().endsWith(':') || lastLineContent.trim().endsWith('=')) {
insertStr = '\t-';
insertStr = '\t'.repeat(indentLevel + 1) + '-';
} else {
insertStr = '-';
insertStr = '\t'.repeat(indentLevel) + '-';
}

const item: TextEdit = TextEdit.insert(newPos, insertStr);
edits.push(item);

//delete redundent \t from autoIndent
const deleteRange = Range.create(pos.line, pos.character - indentLevel, pos.line, pos.character);
const deleteItem: TextEdit = TextEdit.del(deleteRange);
edits.push(deleteItem);
}

if (lastLineContent.trim() === '-') {
Expand All @@ -297,10 +293,31 @@ export class LUServer {
}
}

private getIndentLevel(lineContent: string): number {
if (lineContent.includes('-')) {
const tabStr = lineContent.split('-')[0];
let numOfTab = 0;
let validIndentStr = true;
tabStr.split('').forEach(u => {
if (u === '\t') {
numOfTab += 1;
} else {
validIndentStr = false;
}
});

if (validIndentStr) {
return numOfTab;
}
}

return 0;
}

private getInputLineState(params: DocumentOnTypeFormattingParams): LineState {
const document = this.documents.get(params.textDocument.uri);
const position = params.position;
const regListEnity = /^\s*@\s*list\s*.*$/;
const regListEnity = /^\s*@\s*(list|phraseList)\s*.*$/;
const regUtterance = /^\s*#.*$/;
const regDashLine = /^\s*-.*$/;
const mlEntity = /^\s*@\s*ml\s*.*$/;
Expand Down Expand Up @@ -382,12 +399,14 @@ export class LUServer {
.join('\n');
const completionList: CompletionItem[] = [];
if (util.isEntityType(curLineContent)) {
const triggerChar = curLineContent[position.character - 1];
const extraWhiteSpace = triggerChar === '@' ? ' ' : '';
const entityTypes: string[] = EntityTypesObj.EntityType;
entityTypes.forEach(entity => {
const item = {
label: entity,
kind: CompletionItemKind.Keyword,
insertText: `${entity}`,
insertText: `${extraWhiteSpace}${entity}`,
documentation: `Enitity type: ${entity}`,
};

Expand All @@ -397,11 +416,13 @@ export class LUServer {

if (util.isPrebuiltEntity(curLineContent)) {
const prebuiltTypes: string[] = EntityTypesObj.Prebuilt;
const triggerChar = curLineContent[position.character - 1];
const extraWhiteSpace = triggerChar !== ' ' ? ' ' : '';
prebuiltTypes.forEach(entity => {
const item = {
label: entity,
kind: CompletionItemKind.Keyword,
insertText: `${entity}`,
insertText: `${extraWhiteSpace}${entity}`,
documentation: `Prebuilt enitity: ${entity}`,
};

Expand Down Expand Up @@ -439,6 +460,17 @@ export class LUServer {
completionList.push(item2);
}

if (util.isPhraseListEntity(curLineContent)) {
const item = {
label: 'interchangeable synonyms?',
kind: CompletionItemKind.Keyword,
insertText: `interchangeable`,
documentation: `interchangeable synonyms as part of the entity definition`,
};

completionList.push(item);
}

// completion for entities and patterns, use the text without current line due to usually it will cause parser errors, the luisjson will be undefined

let luisJson = await this.extractLUISContent(text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

export const EntityTypesObj = {
EntityType: ['ml', 'prebuilt', 'regex', 'list', 'composite', 'patternany', 'phraselist'],
EntityType: ['ml', 'prebuilt', 'regex', 'list', 'composite', 'Pattern.any', 'phraseList'],
Prebuilt: [
'age',
'datetimeV2',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ export function isSeperatedEntityDef(content: string): boolean {
}

export function isEntityName(content: string): boolean {
const hasNameEntifyDef = /^\s*@\s*(ml|list|regex|prebuilt|composite|patternany|phraselist)\s*([\w._]+|"[\w._\s]+")\s*$/;
const hasTypeEntityDef = /^\s*@\s*(ml|list|regex|prebuilt|composite|patternany|phraselist|intent)\s*$/;
const hasNameEntifyDef = /^\s*@\s*(ml|list|regex|prebuilt|composite|Pattern\.any|phraseList)\s*([\w._]+|"[\w._\s]+")\s*$/;
const hasTypeEntityDef = /^\s*@\s*(ml|list|regex|prebuilt|composite|Pattern\.any|phraseList|intent)\s*$/;
const hasNameEntifyDef2 = /^\s*@\s*([\w._]+|"[\w._\s]+")\s*$/;
return hasNameEntifyDef.test(content) || (!hasTypeEntityDef.test(content) && hasNameEntifyDef2.test(content));
}
Expand All @@ -93,6 +93,12 @@ export function isCompositeEntity(content: string): boolean {
const compositePatternDef2 = /^\s*@\s*composite\s*[\w]*\s*=\s*\[\s*.*\s*\]\s*$/;
return compositePatternDef.test(content) || compositePatternDef2.test(content);
}

export function isPhraseListEntity(content: string): boolean {
const phraseListEntityPatternDef = /^\s*@\s*phraseList\s*[\w]+\s*\(\s*$/;
return phraseListEntityPatternDef.test(content);
}

export function matchedEnterPattern(content: string): boolean {
const regexPatternDef = /^\s*-.*{\s*$/;
const regexPatternDef2 = /^\s*-.*{\s*}$/;
Expand Down Expand Up @@ -147,7 +153,7 @@ export const suggestionAllEntityTypes = [
'patternAnyEntities',
'preBuiltEntities',
'closedLists',
'phraselists',
'phraseLists',
'composites',
];

Expand All @@ -156,7 +162,7 @@ export const suggestionNoPatternAnyEntityTypes = [
'regex_entities',
'preBuiltEntities',
'closedLists',
'phraselists',
'phraseLists',
'composites',
];

Expand All @@ -166,7 +172,7 @@ export const suggestionNoCompositeEntityTypes = [
'patternAnyEntities',
'preBuiltEntities',
'closedLists',
'phraselists',
'phraseLists',
];

export function getSuggestionRoles(luisJson: any, suggestionEntityTypes: string[]): string[] {
Expand Down

0 comments on commit 1112c86

Please sign in to comment.