From 5565ff9d4ae9c5bdebb0589cf2dd22df67878fbd Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Tue, 25 Aug 2020 12:21:30 +0800 Subject: [PATCH] teach: adjust regexp validator --- packages/plugin-teach/src/database/mysql.ts | 47 +++------------------ packages/plugin-teach/src/internal.ts | 25 +++-------- packages/plugin-teach/tests/basic.spec.ts | 4 +- 3 files changed, 14 insertions(+), 62 deletions(-) diff --git a/packages/plugin-teach/src/database/mysql.ts b/packages/plugin-teach/src/database/mysql.ts index d19f2b888b..c0b3e86b44 100644 --- a/packages/plugin-teach/src/database/mysql.ts +++ b/packages/plugin-teach/src/database/mysql.ts @@ -2,7 +2,6 @@ import { Context, extendDatabase, Message } from 'koishi-core' import { clone, defineProperty, Observed, pick } from 'koishi-utils' import { Dialogue, DialogueTest } from '../utils' import { escape } from 'mysql' -import { RegExpError } from '../internal' import { format } from 'util' import MysqlDatabase from 'koishi-plugin-mysql/dist/database' @@ -12,30 +11,6 @@ declare module 'koishi-core/dist/context' { } } -declare module 'koishi-core/dist/plugins/message' { - namespace Message { - export namespace Teach { - let WhitespaceCharset: string - let NonspaceCharset: string - let UnsupportedCharset: string - let UnsupportedWordBoundary: string - let UnsupportedNongreedy: string - let UnsupportedLookaround: string - let UnsupportedNoncapturing: string - let UnsupportedNamedGroup: string - } - } -} - -Message.Teach.WhitespaceCharset = '问题中的空白字符会被自动删除,你无需使用 \\s。' -Message.Teach.NonspaceCharset = '问题中的空白字符会被自动删除,请使用 . 代替 \\S。' -Message.Teach.UnsupportedCharset = '目前不支持在正则表达式中使用 \\%s,请使用 [%s] 代替。' -Message.Teach.UnsupportedWordBoundary = '目前不支持在正则表达式中使用单词边界。' -Message.Teach.UnsupportedNongreedy = '目前不支持在正则表达式中使用非捕获组。' -Message.Teach.UnsupportedLookaround = '目前不支持在正则表达式中使用断言。' -Message.Teach.UnsupportedNoncapturing = '目前不支持在正则表达式中使用非捕获组。' -Message.Teach.UnsupportedNamedGroup = '目前不支持在正则表达式中使用具名组。' - extendDatabase('koishi-plugin-mysql', { async getDialoguesById(ids, fields) { if (!ids.length) return [] @@ -124,32 +99,22 @@ extendDatabase('koishi-plugin-mysql', ({ listFields }) => export default function apply(ctx: Context, config: Dialogue.Config) { config.validateRegExp = { onEscapeCharacterSet(start, end, kind, negate) { - // eslint-disable-next-line curly - if (kind === 'space') throw negate - ? new RegExpError(Message.Teach.WhitespaceCharset) - : new RegExpError(Message.Teach.NonspaceCharset) - let chars = kind === 'digit' ? '0-9' : '_0-9a-z' - let source = kind === 'digit' ? 'd' : 'w' - if (negate) { - chars = '^' + chars - source = source.toUpperCase() - } - throw new RegExpError(format(Message.Teach.UnsupportedCharset, source, chars)) + throw new SyntaxError('unsupported escape character set') }, onQuantifier(start, end, min, max, greedy) { - if (!greedy) throw new RegExpError(Message.Teach.UnsupportedNongreedy) + if (!greedy) throw new SyntaxError('unsupported non-greedy quantifier') }, onWordBoundaryAssertion() { - throw new RegExpError(Message.Teach.UnsupportedWordBoundary) + throw new SyntaxError('unsupported word boundary assertion') }, onLookaroundAssertionEnter() { - throw new RegExpError(Message.Teach.UnsupportedLookaround) + throw new SyntaxError('unsupported lookaround assertion') }, onGroupEnter() { - throw new RegExpError(Message.Teach.UnsupportedNoncapturing) + throw new SyntaxError('unsupported non-capturing group') }, onCapturingGroupEnter(start, name) { - if (name) throw new RegExpError(Message.Teach.UnsupportedNamedGroup) + if (name) throw new SyntaxError('unsupported named capturing group') }, } diff --git a/packages/plugin-teach/src/internal.ts b/packages/plugin-teach/src/internal.ts index 54ae1a0f6a..f7d5df9682 100644 --- a/packages/plugin-teach/src/internal.ts +++ b/packages/plugin-teach/src/internal.ts @@ -2,9 +2,9 @@ import { Context, Message } from 'koishi-core' import { Dialogue } from './utils' import { update } from './update' import { RegExpValidator } from 'regexpp' -import { defineProperty, Logger } from 'koishi-utils' +import { defineProperty } from 'koishi-utils' import { formatQuestionAnswers } from './search' -import { format, types } from 'util' +import { format } from 'util' import leven from 'leven' declare module 'koishi-core/dist/plugins/message' { @@ -30,14 +30,7 @@ Message.Teach.IllegalRegExp = '问题含有错误的或不支持的正则表达 Message.Teach.MayModifyAnswer = '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。' Message.Teach.MaybeRegExp = '推测你想%s的问题是正则表达式。发送空行或句号以添加 -x 选项,使用 -i 选项以忽略本提示。' -export class RegExpError extends Error { - name = 'RegExpError' -} - -const validator = new RegExpValidator() - export default function apply(ctx: Context, config: Dialogue.Config) { - const logger = new Logger('teach') defineProperty(ctx.app, 'teachHistory', {}) ctx.command('teach') @@ -86,6 +79,8 @@ export default function apply(ctx: Context, config: Dialogue.Config) { return question.startsWith('^') || question.endsWith('$') } + const validator = new RegExpValidator(config.validateRegExp) + ctx.on('dialogue/before-modify', async (argv) => { const { options, session, target, dialogues } = argv const { question, answer, ignoreHint, regexp } = options @@ -121,17 +116,7 @@ export default function apply(ctx: Context, config: Dialogue.Config) { try { questions.map(q => validator.validatePattern(q)) } catch (error) { - if (!types.isNativeError(error)) { - logger.warn(question, error) - return Message.Teach.IllegalRegExp - } else if (error.name === 'RegExpError') { - return error.message - } else { - if (!error.message.startsWith('SyntaxError')) { - logger.warn(question, error.stack) - } - return Message.Teach.IllegalRegExp - } + return Message.Teach.IllegalRegExp } } }) diff --git a/packages/plugin-teach/tests/basic.spec.ts b/packages/plugin-teach/tests/basic.spec.ts index aad7bf8ae3..2653eba92e 100644 --- a/packages/plugin-teach/tests/basic.spec.ts +++ b/packages/plugin-teach/tests/basic.spec.ts @@ -43,7 +43,9 @@ describe('koishi-plugin-teach', () => { await session1.shouldHaveReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。') await session1.shouldHaveReply('# foo bar -P 1', '修改了已存在的问答,编号为 1。') await session1.shouldHaveReply('#1 -P 1', '问答 1 没有发生改动。') - await session1.shouldHaveReply('#1 ~ baz', '问答 1 已成功修改。') + await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') + await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') + await session1.shouldHaveReply('.', '问答 1 已成功修改。') await session1.shouldHaveReply('foo', 'baz') })