F: Update ConceptCore API for error messages
This commit is contained in:
parent
a69bedb033
commit
6b86dc3a16
|
@ -1,3 +1,5 @@
|
|||
22.09.2024 Экстеор 4.9.5
|
||||
• сообщения об ошибках при несоответствии выражения конституенте
|
||||
30.08.2024 Экстеор 4.9.4
|
||||
• исправлена загрузка файлов версий 2017-2020 годов
|
||||
14.06.2024 Экстеор 4.9.3
|
||||
|
|
|
@ -1182,8 +1182,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,9,4,1000
|
||||
PRODUCTVERSION 4,9,4,1000
|
||||
FILEVERSION 4,9,5,1000
|
||||
PRODUCTVERSION 4,9,5,1000
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -1201,13 +1201,13 @@ BEGIN
|
|||
VALUE "Comments", "Ýêñïëèêàòîð òåîðèé "
|
||||
VALUE "CompanyName", "ÍÏ ÖÈÂÒ ÊÎÍÖÅÏÒ"
|
||||
VALUE "FileDescription", "Ýêñòåîð 4.9"
|
||||
VALUE "FileVersion", "4.9.4.1000"
|
||||
VALUE "FileVersion", "4.9.5.1000"
|
||||
VALUE "InternalName", "Ýêñòåîð 4.9"
|
||||
VALUE "LegalCopyright", "Copyright © NPMP CIHT CONCEPT 1994-2024"
|
||||
VALUE "LegalTrademarks", "Ýêñòåîð™"
|
||||
VALUE "OriginalFilename", "Exteor.exe"
|
||||
VALUE "ProductName", "Ýêñòåîð 4.9"
|
||||
VALUE "ProductVersion", "4.9.4.1000"
|
||||
VALUE "ProductVersion", "4.9.5.1000"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -3517,13 +3517,20 @@ BEGIN
|
|||
IXTRS_PAR_SYNTHAXERROR "Ñèíòàêñè÷åñêàÿ îøèáêà"
|
||||
IXTRS_RS_CHECK_SUCCESS "Ïðîâåðêà êîððåêòíîñòè âûðàæåíèÿ: ÎÊ"
|
||||
IXTRS_PAR_FAILURE "Ñèíòàêñè÷åñêèé àíàëèç âûðàæåíèÿ: ÎØÈÁÊÀ"
|
||||
IXTRS_TYPE_INCONSISTENT "Òèïèçàöèÿ âûðàæåíèÿ íå ñîîòâåòñòâóåò òèïó êîíñòèòóåíòû\n\n"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IXTRS_CST_NONEMPTY_BASE "Непустое выражение базисного/константного множества"
|
||||
IXTRS_CST_EMPTY_DERIVED "Пустое выражение для сложного понятия или утверждения"
|
||||
IXTRS_CALLABLE_NO_ARGS "Отсутствуют аргументы для параметризованной конституенты"
|
||||
IXTRS_CST_NONCALLABLE_ARGS
|
||||
"Параметризованное выражение не подходит для данного типа конституенты"
|
||||
IXTRS_CST_EXPECTED_LOGICAL
|
||||
"Данный тип конституенты требует логического выражения"
|
||||
IXTRS_CST_EXPECTED_TYPED
|
||||
"Данный тип конституенты требует теоретико-множественного выражения"
|
||||
IXTRS_TYPE_STRUCTURE "Âûðàæåíèå ðîäîâîé ñòðóêòóðû äîëæíî áûòü ñòóïåíüþ"
|
||||
IXTRS_TYPE_FUNCTION "Îæèäàëîñü âûðàæåíèå îáúÿâëåíèÿ ôóíêöèè"
|
||||
IXTRS_USE_RADICAL "Ðàäèêàëû çàïðåùåíû âíå äåêëàðàöèé òåðì-ôóíêöè: %1"
|
||||
IXTRS_FILTER_ARGUMENT "Òèïèçàöèÿ àðãóìåíòà ôèëüòðà íå êîððåêòíà: %1(%2)"
|
||||
IXTRS_FILTER_PARAM_ARITY
|
||||
|
|
|
@ -478,8 +478,13 @@
|
|||
#define IXTRS_OSS_RUNALL_PROMPT 3209
|
||||
#define IXTRS_OSS_RUNALL_SUCCESS 3210
|
||||
#define IXTRE_CANNOT_SAVE_DATA 3211
|
||||
#define IXTRS_CST_NONEMPTY_BASE 3470
|
||||
#define IXTRS_CST_EMPTY_DERIVED 3471
|
||||
#define IXTRS_CALLABLE_NO_ARGS 3472
|
||||
#define IXTRS_CST_NONCALLABLE_ARGS 3473
|
||||
#define IXTRS_CST_EXPECTED_LOGICAL 3474
|
||||
#define IXTRS_CST_EXPECTED_TYPED 3475
|
||||
#define IXTRS_TYPE_STRUCTURE 3480
|
||||
#define IXTRS_TYPE_FUNCTION 3483
|
||||
#define IXTRS_USE_RADICAL 3485
|
||||
#define IXTRS_FILTER_ARGUMENT 3486
|
||||
#define IXTRS_FILTER_PARAM_ARITY 3487
|
||||
|
@ -493,7 +498,6 @@
|
|||
#define IXTRS_PAR_SYNTHAXERROR 3500
|
||||
#define IXTRS_RS_CHECK_SUCCESS 3501
|
||||
#define IXTRS_PAR_FAILURE 3502
|
||||
#define IXTRS_TYPE_INCONSISTENT 3503
|
||||
#define IXTRS_PAR_EXPECTED_RP 3504
|
||||
#define IXTRS_PAR_EXPECTED_RC 3505
|
||||
#define IXTRS_PAR_QUANTDECL 3506
|
||||
|
|
|
@ -54,7 +54,7 @@ enum class ModelStatus : uint8_t {
|
|||
|
||||
[[nodiscard]] CString BasicDescriptionOf(ccl::oss::PictID pict, ccl::oss::OSSchema& oss);
|
||||
|
||||
[[nodiscard]] CString DescriptionOf(const ccl::rslang::Auditor& analytics, BOOL showAST);
|
||||
[[nodiscard]] CString DescriptionOf(const ccl::semantic::SchemaAuditor& analytics, BOOL showAST);
|
||||
[[nodiscard]] CString DescriptionOf(const ccl::rslang::Interpreter& calculator,
|
||||
const std::optional<ccl::rslang::ExpressionValue>& result,
|
||||
BOOL showAST);
|
||||
|
|
|
@ -75,8 +75,6 @@ DECLARE_MESSAGE_MAP()
|
|||
afx_msg void OnSimpleSyntax();
|
||||
|
||||
private:
|
||||
std::tuple<std::string, long> GetAnalyseExpr() const;
|
||||
|
||||
void UpdateStatus(ccl::semantic::ParsingStatus status, ccl::rslang::ValueClass vclass);
|
||||
void SetModified(BOOL bChanged = TRUE);
|
||||
BOOL IsModified() const noexcept;
|
||||
|
@ -88,7 +86,7 @@ private:
|
|||
void InitCstNameList();
|
||||
void UpdateStatusBar();
|
||||
|
||||
void Analyse();
|
||||
void ExpressAnalyse();
|
||||
};
|
||||
|
||||
} // namespace xtr::dialog
|
|
@ -11,7 +11,7 @@ class RSEdit : public BuffRichEdit {
|
|||
EntityUID activeUID{};
|
||||
|
||||
ccl::rslang::Parser parser{};
|
||||
std::unique_ptr<ccl::rslang::Auditor> checker{ nullptr };
|
||||
std::unique_ptr<ccl::semantic::SchemaAuditor> checker{ nullptr };
|
||||
CString astText{};
|
||||
|
||||
StrPos prefixLen{ 0 };
|
||||
|
|
|
@ -46,17 +46,17 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::LexerEID error) noexcept {
|
||||
switch (error) {
|
||||
default:
|
||||
case ccl::rslang::LexerEID::unknownSymbol: return IXTRS_LEX_UNKNOWN_SYM;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ParseEID error) noexcept {
|
||||
[[nodiscard]] constexpr uint32_t MsgIDFor(const uint32_t eid) noexcept {
|
||||
using ccl::rslang::LexerEID;
|
||||
using ccl::rslang::ParseEID;
|
||||
switch (error) {
|
||||
default:
|
||||
using ccl::rslang::SemanticEID;
|
||||
using ccl::rslang::ValueEID;
|
||||
using ccl::semantic::CstTypeEID;
|
||||
switch (static_cast<LexerEID>(eid)) {
|
||||
case LexerEID::unknownSymbol: return IXTRS_LEX_UNKNOWN_SYM;
|
||||
}
|
||||
|
||||
switch (static_cast<ParseEID>(eid)) {
|
||||
case ParseEID::syntax: return IXTRS_PAR_SYNTHAXERROR;
|
||||
case ParseEID::missingParenthesis: return IXTRS_PAR_EXPECTED_RP;
|
||||
case ParseEID::missingCurlyBrace: return IXTRS_PAR_EXPECTED_RC;
|
||||
|
@ -65,12 +65,8 @@ namespace {
|
|||
case ParseEID::expectedDeclaration: return IXTRS_PAR_EXPECTED_ARGDECL;
|
||||
case ParseEID::expectedLocal: return IXTRS_PAR_EXPECTED_VAR;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::SemanticEID error) noexcept {
|
||||
using ccl::rslang::SemanticEID;
|
||||
switch (error) {
|
||||
default:
|
||||
switch (static_cast<SemanticEID>(eid)) {
|
||||
case SemanticEID::localUndeclared: return IXTRS_TYPE_NAME_UKNOWN;
|
||||
case SemanticEID::localShadowing: return IXTRS_TYPE_NAME_DECLARED;
|
||||
case SemanticEID::globalFuncMissing: return IXTRS_TYPE_UNKNOWN_FUNCTION;
|
||||
|
@ -94,7 +90,6 @@ namespace {
|
|||
case SemanticEID::invalidArgsArity: return IXTRS_TYPE_FUNC_ARGNUM;
|
||||
case SemanticEID::invalidArgumentType: return IXTRS_TYPE_FUNC_WRONG_ARG;
|
||||
case SemanticEID::globalStructure: return IXTRS_TYPE_STRUCTURE;
|
||||
case SemanticEID::globalExpectedFunction: return IXTRS_TYPE_FUNCTION;
|
||||
case SemanticEID::radicalUsage: return IXTRS_USE_RADICAL;
|
||||
case SemanticEID::invalidFilterArgumentType: return IXTRS_FILTER_ARGUMENT;
|
||||
case SemanticEID::invalidFilterArity: return IXTRS_FILTER_PARAM_ARITY;
|
||||
|
@ -107,12 +102,17 @@ namespace {
|
|||
case SemanticEID::globalMissingAST: return IXTRS_GLOBAL_NO_AST;
|
||||
case SemanticEID::globalFuncNoInterpretation: return IXTRS_FUNCTION_CALL_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ValueEID error) noexcept {
|
||||
using ccl::rslang::ValueEID;
|
||||
switch (error) {
|
||||
default:
|
||||
switch (static_cast<CstTypeEID>(eid)) {
|
||||
case CstTypeEID::cstNonemptyBase: return IXTRS_CST_NONEMPTY_BASE;
|
||||
case CstTypeEID::cstEmptyDerived: return IXTRS_CST_EMPTY_DERIVED;
|
||||
case CstTypeEID::cstCallableNoArgs: return IXTRS_CALLABLE_NO_ARGS;
|
||||
case CstTypeEID::cstNonCallableHasArgs: return IXTRS_CST_NONCALLABLE_ARGS;
|
||||
case CstTypeEID::cstExpectedLogical: return IXTRS_CST_EXPECTED_LOGICAL;
|
||||
case CstTypeEID::cstExpectedTyped: return IXTRS_CST_EXPECTED_TYPED;
|
||||
}
|
||||
|
||||
switch (static_cast<ValueEID>(eid)) {
|
||||
case ValueEID::unknownError: return IXTRS_VALUE_UNKNOWN_ERROR;
|
||||
case ValueEID::typedOverflow: return IXTRS_VALUE_SET_LIMIT;
|
||||
case ValueEID::booleanLimit: return IXTRS_VALUE_BOOL_LIMIT;
|
||||
|
@ -121,6 +121,8 @@ namespace {
|
|||
case ValueEID::invalidDebool: return IXTRS_VALUE_DEBOOL;
|
||||
case ValueEID::iterateInfinity: return IXTRS_ITERATE_INFINITY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] CString ErrorMessage(const uint32_t errorCode, const std::vector<std::string>& params) {
|
||||
|
@ -128,16 +130,7 @@ namespace {
|
|||
auto prefix = Label(errType);
|
||||
prefix.AppendFormat(LR"(%04X)", errorCode);
|
||||
prefix += LR"(: )";
|
||||
const uint32_t msgID = [&]() noexcept -> uint32_t {
|
||||
switch (errType) {
|
||||
default:
|
||||
case ErrorType::UNKNOWN: return 0;
|
||||
case ErrorType::LEXER: return MsgIDFor(static_cast<ccl::rslang::LexerEID>(errorCode));
|
||||
case ErrorType::PARSER: return MsgIDFor(static_cast<ccl::rslang::ParseEID>(errorCode));
|
||||
case ErrorType::SEMANTIC: return MsgIDFor(static_cast<ccl::rslang::SemanticEID>(errorCode));
|
||||
case ErrorType::VALUE: return MsgIDFor(static_cast<ccl::rslang::ValueEID>(errorCode));
|
||||
}
|
||||
}();
|
||||
const uint32_t msgID = MsgIDFor(errorCode);
|
||||
if (msgID == 0) {
|
||||
return prefix;
|
||||
} else {
|
||||
|
@ -437,15 +430,15 @@ CString BasicDescriptionOf(const ccl::oss::PictID pict, ccl::oss::OSSchema& oss)
|
|||
return infoStr;
|
||||
}
|
||||
|
||||
CString DescriptionOf(const ccl::rslang::Auditor& analytics, const BOOL showAST) {
|
||||
CString DescriptionOf(const ccl::semantic::SchemaAuditor& analytics, const BOOL showAST) {
|
||||
CString msgLog{};
|
||||
const ccl::rslang::ExpressionType* type = &analytics.GetType();
|
||||
if (!analytics.isParsed) {
|
||||
if (!analytics.IsParsed()) {
|
||||
msgLog += mfc::LoadSID(IXTRS_PAR_FAILURE);
|
||||
} else if (!analytics.isTypeCorrect) {
|
||||
} else if (!analytics.IsTypeCorrect()) {
|
||||
type = nullptr;
|
||||
msgLog += mfc::LoadSID(IXTRS_TYPECHECK_FAILURE);
|
||||
} else if (!analytics.isValueCorrect) {
|
||||
} else if (!analytics.IsValueCorrect()) {
|
||||
msgLog += mfc::LoadSID(IXTRS_VALUECHECK_FAILURE);
|
||||
} else {
|
||||
msgLog += mfc::LoadSID(IXTRS_RS_CHECK_SUCCESS);
|
||||
|
@ -459,9 +452,9 @@ CString DescriptionOf(const ccl::rslang::Auditor& analytics, const BOOL showAST)
|
|||
msgLog += '\n';
|
||||
msgLog += mfc::FormatSID(IXTRS_REPORT_VALUE_CLASS, Label(analytics.GetValueClass()).GetString());
|
||||
|
||||
if (showAST && analytics.isParsed) {
|
||||
if (showAST && analytics.IsParsed()) {
|
||||
msgLog += '\n';
|
||||
msgLog += mfc::FormatSID(IXTRS_REPORT_AST, mfc::ToMFC(AST2String::Apply(analytics.parser.AST())).GetString());
|
||||
msgLog += mfc::FormatSID(IXTRS_REPORT_AST, mfc::ToMFC(AST2String::Apply(analytics.AST())).GetString());
|
||||
}
|
||||
|
||||
return msgLog;
|
||||
|
|
|
@ -400,19 +400,18 @@ BOOL CstDataPage::OnInsertBtn(uint32_t command) {
|
|||
}
|
||||
|
||||
void CstDataPage::OnAnalyse() {
|
||||
auto [str, basePos] = GetAnalyseExpr();
|
||||
const auto& cst = parent.editor->GetRS(parent.activeUID);
|
||||
const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
|
||||
|
||||
auto analyser = parent.editor->Core().RSLang().MakeAuditor();
|
||||
const ccl::rslang::ExpressionType* type{ nullptr };
|
||||
const auto typeOK = analyser->CheckType(str, ccl::rslang::Syntax::MATH);
|
||||
|
||||
const auto typeOK = analyser->CheckConstituenta(cst.alias, definitionText, cst.type);
|
||||
if (typeOK) {
|
||||
type = &analyser->GetType();
|
||||
}
|
||||
|
||||
const auto rstype = parent.editor->GetRS(parent.activeUID).type;
|
||||
const auto typeConsistent = typeOK
|
||||
&& (!ccl::semantic::IsBaseSet(rstype) || expressionCtrl.Text().IsEmpty())
|
||||
&& ccl::semantic::Schema::CheckTypeConstistency(analyser->GetType(), rstype);
|
||||
if (!typeConsistent) {
|
||||
if (!typeOK) {
|
||||
UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid);
|
||||
} else {
|
||||
if (!analyser->CheckValue()) {
|
||||
|
@ -423,7 +422,7 @@ void CstDataPage::OnAnalyse() {
|
|||
}
|
||||
|
||||
if (!empty(analyser->Errors().All())) {
|
||||
auto errorPosition = std::max(analyser->Errors().FirstErrorPos() - basePos, 0L);
|
||||
auto errorPosition = std::max(static_cast<long>(analyser->Errors().FirstErrorPos() - analyser->prefixLen), 0L);
|
||||
auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION));
|
||||
re->SetFocus();
|
||||
re->SetSel(errorPosition, errorPosition);
|
||||
|
@ -431,9 +430,6 @@ void CstDataPage::OnAnalyse() {
|
|||
|
||||
typificationCtrl.SetWindowTextW(info::Label(type));
|
||||
auto log = info::DescriptionOf(*analyser, XTROptions::ParseRSL().showAST);
|
||||
if (typeOK && !typeConsistent) {
|
||||
log = mfc::LoadSID(IXTRS_TYPE_INCONSISTENT) + log;
|
||||
}
|
||||
logCtrl.SetWindowTextW(log);
|
||||
}
|
||||
|
||||
|
@ -450,15 +446,23 @@ void CstDataPage::OnCalculate() {
|
|||
}
|
||||
BeginWaitCursor();
|
||||
|
||||
auto[str, basePos] = GetAnalyseExpr();
|
||||
const auto& cst = parent.editor->GetRS(parent.activeUID);
|
||||
const auto expr = mfc::ToSTL(expressionCtrl.Text());
|
||||
const auto fullExpr = ccl::rslang::Generator::GlobalDefinition(
|
||||
cst.alias,
|
||||
expr,
|
||||
cst.type == CstType::structured
|
||||
);
|
||||
const auto basePos = static_cast<StrPos>(ssize(fullExpr) - ssize(expr));
|
||||
|
||||
ccl::rslang::Interpreter calculator{
|
||||
parent.editor->Core().RSLang(),
|
||||
parent.editor->Core().RSLang().ASTContext(),
|
||||
parent.editor->Model().Calculations().Context()
|
||||
};
|
||||
const auto calcResult = calculator.Evaluate(str, ccl::rslang::Syntax::MATH);
|
||||
const auto calcResult = calculator.Evaluate(fullExpr, ccl::rslang::Syntax::MATH);
|
||||
if (!calcResult.has_value()) {
|
||||
auto errorPosition = std::max(calculator.Errors().FirstErrorPos() - basePos, 0L);
|
||||
auto errorPosition = std::max(static_cast<long>(calculator.Errors().FirstErrorPos() - basePos), 0L);
|
||||
auto* re = reinterpret_cast<ui::TextEdit*>(GetDlgItem(IXTRC_EXPRESSION));
|
||||
re->SetFocus();
|
||||
re->SetSel(errorPosition, errorPosition);
|
||||
|
@ -473,8 +477,8 @@ void CstDataPage::OnCalculate() {
|
|||
}
|
||||
|
||||
void CstDataPage::OnSimpleSyntax() {
|
||||
auto [expr, basePos] = GetAnalyseExpr();
|
||||
const auto asciiExpr = ccl::rslang::ConvertTo(expr, ccl::rslang::Syntax::ASCII);
|
||||
const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
|
||||
const auto asciiExpr = ccl::rslang::ConvertTo(definitionText, ccl::rslang::Syntax::ASCII);
|
||||
logCtrl.SetWindowTextW(mfc::ToMFC(asciiExpr));
|
||||
}
|
||||
|
||||
|
@ -487,14 +491,6 @@ BOOL CstDataPage::IsModified() const noexcept {
|
|||
return isModified;
|
||||
}
|
||||
|
||||
std::tuple<std::string, long> CstDataPage::GetAnalyseExpr() const {
|
||||
const auto& cst = parent.editor->GetRS(parent.activeUID);
|
||||
const auto expr = mfc::ToSTL(expressionCtrl.Text());
|
||||
const auto fullExpr = ccl::rslang::Generator::GlobalDefinition(cst.alias, expr,
|
||||
cst.type == CstType::structured);
|
||||
return { fullExpr, static_cast<long>(ssize(fullExpr) - ssize(expr)) };
|
||||
}
|
||||
|
||||
void CstDataPage::UpdateStatus(const ParsingStatus status, const ValueClass vclass) {
|
||||
parseStatus = status;
|
||||
valueStatus = vclass;
|
||||
|
@ -525,7 +521,7 @@ void CstDataPage::ClearSyntaxWindow() {
|
|||
|
||||
void CstDataPage::RunAutocheck() {
|
||||
if (parseStatus != ParsingStatus::VERIFIED && XTROptions::ParseRSL().autoCheck) {
|
||||
Analyse();
|
||||
ExpressAnalyse();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,10 +554,11 @@ void CstDataPage::InitCstNameList() {
|
|||
namePicker.SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
void CstDataPage::Analyse() {
|
||||
auto[str, basePos] = GetAnalyseExpr();
|
||||
void CstDataPage::ExpressAnalyse() {
|
||||
const auto& cst = parent.editor->GetRS(parent.activeUID);
|
||||
const auto definitionText = mfc::ToSTL(expressionCtrl.Text());
|
||||
auto analyser = parent.editor->Core().RSLang().MakeAuditor();
|
||||
if (!analyser->CheckType(str, ccl::rslang::Syntax::MATH)) {
|
||||
if (!analyser->CheckConstituenta(cst.alias, definitionText, cst.type)) {
|
||||
UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid);
|
||||
} else if (!analyser->CheckValue()) {
|
||||
UpdateStatus(ParsingStatus::VERIFIED, ValueClass::invalid);
|
||||
|
|
|
@ -425,8 +425,7 @@ BOOL RSEdit::UpdateAST() {
|
|||
return FALSE;
|
||||
} else {
|
||||
const auto& cst = context->GetRS(activeUID);
|
||||
const auto expression = Generator::GlobalDefinition(cst.alias, mfc::ToSTL(text), cst.type == CstType::structured);
|
||||
checker->CheckType(expression, ccl::rslang::Syntax::MATH);
|
||||
checker->CheckConstituenta(cst.alias, mfc::ToSTL(text), cst.type);
|
||||
astText = text;
|
||||
navigatorEnabled = FALSE;
|
||||
activeNode = std::nullopt;
|
||||
|
@ -438,25 +437,28 @@ void RSEdit::FormatSelectedBlock(const StrRange selection) {
|
|||
static constexpr COLORREF clrBg{ RGB(235, 235, 235) };
|
||||
static constexpr COLORREF clrReadOnlyBg{ RGB(255, 255, 211) };
|
||||
|
||||
if (XTROptions::ParseRSL().enableNavigator &&
|
||||
GetFocus()->GetSafeHwnd() == m_hWnd &&
|
||||
context != nullptr && UpdateAST() && checker->isParsed) {
|
||||
auto selectedNode = activeNode;
|
||||
if (!navigatorEnabled) {
|
||||
const auto clientRange = StrRange{ selection.start + prefixLen, selection.finish + prefixLen };
|
||||
selectedNode = ccl::rslang::FindMinimalNode(checker->parser.AST().Root(), clientRange);
|
||||
}
|
||||
if (selectedNode.has_value()) {
|
||||
const auto start = std::max(selectedNode.value()->pos.start - prefixLen, 0);
|
||||
const auto end = std::min(selectedNode.value()->pos.finish - prefixLen, astText.GetLength());
|
||||
|
||||
auto format = design::CharFormatRE();
|
||||
format.dwMask = CFM_BACKCOLOR;
|
||||
format.crBackColor = (GetStyle() & ES_READONLY) == 0 ? clrBg : clrReadOnlyBg;
|
||||
SetSel(start, end);
|
||||
SetSelectionCharFormat(format);
|
||||
}
|
||||
if (!XTROptions::ParseRSL().enableNavigator ||
|
||||
GetFocus()->GetSafeHwnd() != m_hWnd ||
|
||||
context == nullptr || !UpdateAST() || !checker->IsParsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto selectedNode = activeNode;
|
||||
if (!navigatorEnabled) {
|
||||
const auto clientRange = StrRange{ selection.start + prefixLen, selection.finish + prefixLen };
|
||||
selectedNode = ccl::rslang::FindMinimalNode(checker->AST().Root(), clientRange);
|
||||
}
|
||||
if (selectedNode.has_value()) {
|
||||
const auto start = std::max(selectedNode.value()->pos.start - prefixLen, 0);
|
||||
const auto end = std::min(selectedNode.value()->pos.finish - prefixLen, astText.GetLength());
|
||||
|
||||
auto format = design::CharFormatRE();
|
||||
format.dwMask = CFM_BACKCOLOR;
|
||||
format.crBackColor = (GetStyle() & ES_READONLY) == 0 ? clrBg : clrReadOnlyBg;
|
||||
SetSel(start, end);
|
||||
SetSelectionCharFormat(format);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RSEdit::FormatIdentifier(const ccl::rslang::TokenID tid, const StrRange pos) {
|
||||
|
@ -506,21 +508,24 @@ void RSEdit::AddReference() {
|
|||
}
|
||||
|
||||
BOOL RSEdit::NavigatorOn() {
|
||||
using ccl::rslang::FindMinimalNode;
|
||||
|
||||
if (navigatorEnabled) {
|
||||
return TRUE;
|
||||
} else if (!checker->isParsed) {
|
||||
}
|
||||
|
||||
if (!checker->IsParsed()) {
|
||||
activeNode = std::nullopt;
|
||||
MessageBeep(MB_ICONERROR);
|
||||
return FALSE;
|
||||
} else {
|
||||
navigatorEnabled = TRUE;
|
||||
const auto sel = GetSelectionRange();
|
||||
activeNode = FindMinimalNode(checker->parser.AST().Root(),
|
||||
StrRange{ sel.start + prefixLen, sel.finish + prefixLen });
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
navigatorEnabled = TRUE;
|
||||
const auto sel = GetSelectionRange();
|
||||
activeNode = ccl::rslang::FindMinimalNode(
|
||||
checker->AST().Root(),
|
||||
StrRange{ sel.start + prefixLen, sel.finish + prefixLen }
|
||||
);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
BOOL RSEdit::MoveUp() noexcept {
|
||||
|
@ -529,13 +534,13 @@ BOOL RSEdit::MoveUp() noexcept {
|
|||
|
||||
BOOL RSEdit::MoveDown() {
|
||||
if (!activeNode.has_value() || activeNode->ChildrenCount() == 0) {
|
||||
return false;
|
||||
return FALSE;
|
||||
} else if (activeNode->IsRoot()) {
|
||||
activeNode->MoveToChild(1); // Note: Для корневого узла перывым потомком является сама конституента
|
||||
return true;
|
||||
return TRUE;
|
||||
} else {
|
||||
activeNode->MoveToChild(0);
|
||||
return true;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user