fix: 更好的代码提示支持;修复禁用脚本功能导致的程序崩溃;

This commit is contained in:
寂静的羽夏 2025-04-19 18:57:10 +08:00
parent ef8bb9aa3a
commit f59755e3f0
10 changed files with 304 additions and 413 deletions

@ -1 +1 @@
Subproject commit 4307a2552e52d9f7e5c8fc2bd1d3148748e968f9 Subproject commit e5cef2dcf126037ffdc57a5aaf6a3b1d3f4c70ae

View File

@ -1692,7 +1692,7 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/dialog/mainwindow.cpp" line="3819"/> <location filename="../../src/dialog/mainwindow.cpp" line="3821"/>
<source>ConfirmAPPSave</source> <source>ConfirmAPPSave</source>
<translation></translation> <translation></translation>
</message> </message>
@ -2272,125 +2272,125 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2871"/> <location filename="../../src/class/pluginsystem.cpp" line="2875"/>
<source>RegisterScriptFnUnSupportedTypes:</source> <source>RegisterScriptFnUnSupportedTypes:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2881"/> <location filename="../../src/class/pluginsystem.cpp" line="2885"/>
<location filename="../../src/class/pluginsystem.cpp" line="2945"/> <location filename="../../src/class/pluginsystem.cpp" line="2953"/>
<source>RegisterScriptFnInvalidSig:</source> <source>RegisterScriptFnInvalidSig:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2889"/> <location filename="../../src/class/pluginsystem.cpp" line="2893"/>
<location filename="../../src/class/pluginsystem.cpp" line="2953"/> <location filename="../../src/class/pluginsystem.cpp" line="2961"/>
<source>RegisterScriptFnConflitSig:</source> <source>RegisterScriptFnConflitSig:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3004"/> <location filename="../../src/class/pluginsystem.cpp" line="3012"/>
<source>InvalidEnumName:</source> <source>InvalidEnumName:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3014"/> <location filename="../../src/class/pluginsystem.cpp" line="3022"/>
<source>InvalidEnumValue:</source> <source>InvalidEnumValue:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3049"/> <location filename="../../src/class/pluginsystem.cpp" line="3057"/>
<source>InvalidMarcosRegister:</source> <source>InvalidMarcosRegister:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3294"/> <location filename="../../src/class/pluginsystem.cpp" line="3302"/>
<source>ErrLoadPluginSDKVersion</source> <source>ErrLoadPluginSDKVersion</source>
<translation> SDK </translation> <translation> SDK </translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3298"/> <location filename="../../src/class/pluginsystem.cpp" line="3306"/>
<source>ErrLoadPluginNoName</source> <source>ErrLoadPluginNoName</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3319"/> <location filename="../../src/class/pluginsystem.cpp" line="3327"/>
<source>ErrLoadInitPlugin</source> <source>ErrLoadInitPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3326"/> <location filename="../../src/class/pluginsystem.cpp" line="3334"/>
<source>PluginName :</source> <source>PluginName :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3327"/> <location filename="../../src/class/pluginsystem.cpp" line="3335"/>
<source>PluginAuthor :</source> <source>PluginAuthor :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3328"/> <location filename="../../src/class/pluginsystem.cpp" line="3336"/>
<source>PluginWidgetRegister</source> <source>PluginWidgetRegister</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3432"/> <location filename="../../src/class/pluginsystem.cpp" line="3440"/>
<source>ErrLoadExtPluginSDKVersion</source> <source>ErrLoadExtPluginSDKVersion</source>
<translation> SDK </translation> <translation> SDK </translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3435"/> <location filename="../../src/class/pluginsystem.cpp" line="3443"/>
<source>ExtPluginAuthor :</source> <source>ExtPluginAuthor :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3436"/> <location filename="../../src/class/pluginsystem.cpp" line="3444"/>
<source>ExtPluginWidgetRegister</source> <source>ExtPluginWidgetRegister</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3452"/> <location filename="../../src/class/pluginsystem.cpp" line="3460"/>
<source>ErrLoadInitExtPlugin</source> <source>ErrLoadInitExtPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3477"/> <location filename="../../src/class/pluginsystem.cpp" line="3485"/>
<source>ChooseFile</source> <source>ChooseFile</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3484"/> <location filename="../../src/class/pluginsystem.cpp" line="3492"/>
<location filename="../../src/class/pluginsystem.cpp" line="3489"/> <location filename="../../src/class/pluginsystem.cpp" line="3497"/>
<source>Error</source> <source>Error</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3485"/> <location filename="../../src/class/pluginsystem.cpp" line="3493"/>
<source>FileNotExist</source> <source>FileNotExist</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3490"/> <location filename="../../src/class/pluginsystem.cpp" line="3498"/>
<source>FilePermission</source> <source>FilePermission</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3520"/> <location filename="../../src/class/pluginsystem.cpp" line="3528"/>
<source>EmptyNameDockWidget:</source> <source>EmptyNameDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3530"/> <location filename="../../src/class/pluginsystem.cpp" line="3538"/>
<source>InvalidNameDockWidget:</source> <source>InvalidNameDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3538"/> <location filename="../../src/class/pluginsystem.cpp" line="3546"/>
<source>InvalidNullDockWidget:</source> <source>InvalidNullDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3605"/> <location filename="../../src/class/pluginsystem.cpp" line="3613"/>
<source>Not allowed operation in non-UI thread</source> <source>Not allowed operation in non-UI thread</source>
<translation> UI 线</translation> <translation> UI 线</translation>
</message> </message>
@ -2754,14 +2754,14 @@
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="363"/> <location filename="../../src/class/scriptmachine.cpp" line="363"/>
<location filename="../../src/class/scriptmachine.cpp" line="1836"/> <location filename="../../src/class/scriptmachine.cpp" line="1839"/>
<location filename="../../src/class/scriptmachine.cpp" line="1848"/> <location filename="../../src/class/scriptmachine.cpp" line="1851"/>
<source>Script failed to build</source> <source>Script failed to build</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="378"/> <location filename="../../src/class/scriptmachine.cpp" line="378"/>
<location filename="../../src/class/scriptmachine.cpp" line="1864"/> <location filename="../../src/class/scriptmachine.cpp" line="1867"/>
<source>Cannot find &apos;int main()&apos; or &apos;void main()&apos;</source> <source>Cannot find &apos;int main()&apos; or &apos;void main()&apos;</source>
<translation> &quot;int main()&quot; &quot;void main()&quot;</translation> <translation> &quot;int main()&quot; &quot;void main()&quot;</translation>
</message> </message>
@ -2777,19 +2777,19 @@
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="432"/> <location filename="../../src/class/scriptmachine.cpp" line="432"/>
<location filename="../../src/class/scriptmachine.cpp" line="1901"/> <location filename="../../src/class/scriptmachine.cpp" line="1904"/>
<source>The script failed with an exception</source> <source>The script failed with an exception</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="440"/> <location filename="../../src/class/scriptmachine.cpp" line="440"/>
<location filename="../../src/class/scriptmachine.cpp" line="1910"/> <location filename="../../src/class/scriptmachine.cpp" line="1913"/>
<source>The script was aborted</source> <source>The script was aborted</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="447"/> <location filename="../../src/class/scriptmachine.cpp" line="447"/>
<location filename="../../src/class/scriptmachine.cpp" line="1917"/> <location filename="../../src/class/scriptmachine.cpp" line="1920"/>
<source>The script terminated unexpectedly</source> <source>The script terminated unexpectedly</source>
<translation>退</translation> <translation>退</translation>
</message> </message>

View File

@ -1692,7 +1692,7 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/dialog/mainwindow.cpp" line="3819"/> <location filename="../../src/dialog/mainwindow.cpp" line="3821"/>
<source>ConfirmAPPSave</source> <source>ConfirmAPPSave</source>
<translation></translation> <translation></translation>
</message> </message>
@ -2272,125 +2272,125 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2871"/> <location filename="../../src/class/pluginsystem.cpp" line="2875"/>
<source>RegisterScriptFnUnSupportedTypes:</source> <source>RegisterScriptFnUnSupportedTypes:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2881"/> <location filename="../../src/class/pluginsystem.cpp" line="2885"/>
<location filename="../../src/class/pluginsystem.cpp" line="2945"/> <location filename="../../src/class/pluginsystem.cpp" line="2953"/>
<source>RegisterScriptFnInvalidSig:</source> <source>RegisterScriptFnInvalidSig:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="2889"/> <location filename="../../src/class/pluginsystem.cpp" line="2893"/>
<location filename="../../src/class/pluginsystem.cpp" line="2953"/> <location filename="../../src/class/pluginsystem.cpp" line="2961"/>
<source>RegisterScriptFnConflitSig:</source> <source>RegisterScriptFnConflitSig:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3004"/> <location filename="../../src/class/pluginsystem.cpp" line="3012"/>
<source>InvalidEnumName:</source> <source>InvalidEnumName:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3014"/> <location filename="../../src/class/pluginsystem.cpp" line="3022"/>
<source>InvalidEnumValue:</source> <source>InvalidEnumValue:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3049"/> <location filename="../../src/class/pluginsystem.cpp" line="3057"/>
<source>InvalidMarcosRegister:</source> <source>InvalidMarcosRegister:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3294"/> <location filename="../../src/class/pluginsystem.cpp" line="3302"/>
<source>ErrLoadPluginSDKVersion</source> <source>ErrLoadPluginSDKVersion</source>
<translation> SDK </translation> <translation> SDK </translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3298"/> <location filename="../../src/class/pluginsystem.cpp" line="3306"/>
<source>ErrLoadPluginNoName</source> <source>ErrLoadPluginNoName</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3319"/> <location filename="../../src/class/pluginsystem.cpp" line="3327"/>
<source>ErrLoadInitPlugin</source> <source>ErrLoadInitPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3326"/> <location filename="../../src/class/pluginsystem.cpp" line="3334"/>
<source>PluginName :</source> <source>PluginName :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3327"/> <location filename="../../src/class/pluginsystem.cpp" line="3335"/>
<source>PluginAuthor :</source> <source>PluginAuthor :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3328"/> <location filename="../../src/class/pluginsystem.cpp" line="3336"/>
<source>PluginWidgetRegister</source> <source>PluginWidgetRegister</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3432"/> <location filename="../../src/class/pluginsystem.cpp" line="3440"/>
<source>ErrLoadExtPluginSDKVersion</source> <source>ErrLoadExtPluginSDKVersion</source>
<translation> SDK </translation> <translation> SDK </translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3435"/> <location filename="../../src/class/pluginsystem.cpp" line="3443"/>
<source>ExtPluginAuthor :</source> <source>ExtPluginAuthor :</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3436"/> <location filename="../../src/class/pluginsystem.cpp" line="3444"/>
<source>ExtPluginWidgetRegister</source> <source>ExtPluginWidgetRegister</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3452"/> <location filename="../../src/class/pluginsystem.cpp" line="3460"/>
<source>ErrLoadInitExtPlugin</source> <source>ErrLoadInitExtPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3477"/> <location filename="../../src/class/pluginsystem.cpp" line="3485"/>
<source>ChooseFile</source> <source>ChooseFile</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3484"/> <location filename="../../src/class/pluginsystem.cpp" line="3492"/>
<location filename="../../src/class/pluginsystem.cpp" line="3489"/> <location filename="../../src/class/pluginsystem.cpp" line="3497"/>
<source>Error</source> <source>Error</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3485"/> <location filename="../../src/class/pluginsystem.cpp" line="3493"/>
<source>FileNotExist</source> <source>FileNotExist</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3490"/> <location filename="../../src/class/pluginsystem.cpp" line="3498"/>
<source>FilePermission</source> <source>FilePermission</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3520"/> <location filename="../../src/class/pluginsystem.cpp" line="3528"/>
<source>EmptyNameDockWidget:</source> <source>EmptyNameDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3530"/> <location filename="../../src/class/pluginsystem.cpp" line="3538"/>
<source>InvalidNameDockWidget:</source> <source>InvalidNameDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3538"/> <location filename="../../src/class/pluginsystem.cpp" line="3546"/>
<source>InvalidNullDockWidget:</source> <source>InvalidNullDockWidget:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/pluginsystem.cpp" line="3605"/> <location filename="../../src/class/pluginsystem.cpp" line="3613"/>
<source>Not allowed operation in non-UI thread</source> <source>Not allowed operation in non-UI thread</source>
<translation> UI </translation> <translation> UI </translation>
</message> </message>
@ -2754,14 +2754,14 @@
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="363"/> <location filename="../../src/class/scriptmachine.cpp" line="363"/>
<location filename="../../src/class/scriptmachine.cpp" line="1836"/> <location filename="../../src/class/scriptmachine.cpp" line="1839"/>
<location filename="../../src/class/scriptmachine.cpp" line="1848"/> <location filename="../../src/class/scriptmachine.cpp" line="1851"/>
<source>Script failed to build</source> <source>Script failed to build</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="378"/> <location filename="../../src/class/scriptmachine.cpp" line="378"/>
<location filename="../../src/class/scriptmachine.cpp" line="1864"/> <location filename="../../src/class/scriptmachine.cpp" line="1867"/>
<source>Cannot find &apos;int main()&apos; or &apos;void main()&apos;</source> <source>Cannot find &apos;int main()&apos; or &apos;void main()&apos;</source>
<translation> &quot;int main()&quot; &quot;void main()&quot;</translation> <translation> &quot;int main()&quot; &quot;void main()&quot;</translation>
</message> </message>
@ -2777,19 +2777,19 @@
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="432"/> <location filename="../../src/class/scriptmachine.cpp" line="432"/>
<location filename="../../src/class/scriptmachine.cpp" line="1901"/> <location filename="../../src/class/scriptmachine.cpp" line="1904"/>
<source>The script failed with an exception</source> <source>The script failed with an exception</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="440"/> <location filename="../../src/class/scriptmachine.cpp" line="440"/>
<location filename="../../src/class/scriptmachine.cpp" line="1910"/> <location filename="../../src/class/scriptmachine.cpp" line="1913"/>
<source>The script was aborted</source> <source>The script was aborted</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../src/class/scriptmachine.cpp" line="447"/> <location filename="../../src/class/scriptmachine.cpp" line="447"/>
<location filename="../../src/class/scriptmachine.cpp" line="1917"/> <location filename="../../src/class/scriptmachine.cpp" line="1920"/>
<source>The script terminated unexpectedly</source> <source>The script terminated unexpectedly</source>
<translation>退</translation> <translation>退</translation>
</message> </message>

View File

@ -139,15 +139,15 @@ QString AsCompletion::wordSeperators() const {
return eow; return eow;
} }
void AsCompletion::processTrigger(const QString &trigger, bool AsCompletion::processTrigger(const QString &trigger,
const QString &content) { const QString &content) {
if (content.isEmpty()) { if (content.isEmpty()) {
return; return false;
} }
if (trigger == *SEMI_COLON_TRIGGER) { if (trigger == *SEMI_COLON_TRIGGER) {
clearFunctionTip(); clearFunctionTip();
return; return false;
} }
auto len = content.length(); auto len = content.length();
@ -173,13 +173,14 @@ void AsCompletion::processTrigger(const QString &trigger,
QByteArray content; QByteArray content;
}; };
auto engine = ScriptMachine::instance().engine();
// parse the tokens // parse the tokens
QVector<Token> tokens; QVector<Token> tokens;
qsizetype pos = 0; qsizetype pos = 0;
for (; p < end;) { for (; p < end;) {
asUINT tokenLen = 0; asUINT tokenLen = 0;
auto tt = auto tt = engine->ParseToken(p, len, &tokenLen);
ScriptMachine::instance().engine()->ParseToken(p, len, &tokenLen);
if (tt == asTC_WHITESPACE) { if (tt == asTC_WHITESPACE) {
p += tokenLen; p += tokenLen;
pos += tokenLen; pos += tokenLen;
@ -222,11 +223,16 @@ void AsCompletion::processTrigger(const QString &trigger,
QByteArray fn; QByteArray fn;
if (tokens.isEmpty()) { if (tokens.isEmpty()) {
popup()->hide(); popup()->hide();
return; return false;
} }
QString prefix; QString prefix;
auto etoken = tokens.back(); auto etoken = tokens.back();
if (etoken.type == asTC_VALUE || etoken.type == asTC_COMMENT ||
etoken.type == asTC_UNKNOWN) {
popup()->hide();
return false;
}
// if trigger is empty, it's making editing // if trigger is empty, it's making editing
if (trigger.isEmpty()) { if (trigger.isEmpty()) {
@ -246,20 +252,21 @@ void AsCompletion::processTrigger(const QString &trigger,
if (etoken.content == *DBL_COLON_TRIGGER) { if (etoken.content == *DBL_COLON_TRIGGER) {
processTrigger(*DBL_COLON_TRIGGER, content.left(etoken.pos)); processTrigger(*DBL_COLON_TRIGGER, content.left(etoken.pos));
setCompletionPrefix(prefix); setCompletionPrefix(prefix);
return; return true;
} else if (etoken.content == *DOT_TRIGGER) { } else if (etoken.content == *DOT_TRIGGER) {
processTrigger(*DOT_TRIGGER, content.left(etoken.pos)); processTrigger(*DOT_TRIGGER, content.left(etoken.pos));
setCompletionPrefix(prefix); setCompletionPrefix(prefix);
return; return true;
} else { } else {
applyEmptyNsNode(nodes, docNodes); applyEmptyNsNode(nodes, docNodes);
} }
} else if (etoken.type != asTC_IDENTIFIER) { } else if (etoken.type != asTC_IDENTIFIER) {
popup()->hide(); popup()->hide();
return; return false;
} }
if (trigger == *DOT_TRIGGER) { if (trigger == *DOT_TRIGGER) {
// member guessing ?
applyClassNodes(nodes); applyClassNodes(nodes);
} else if (etoken.content.length() >= triggerAmount()) { } else if (etoken.content.length() >= triggerAmount()) {
// completion for a.b.c or a::b.c or a::b::c.d or ::a::b.c // completion for a.b.c or a::b.c or a::b::c.d or ::a::b.c
@ -269,7 +276,7 @@ void AsCompletion::processTrigger(const QString &trigger,
if (idx >= 0) { if (idx >= 0) {
if (tokens.at(idx).content == *DOT_TRIGGER) { if (tokens.at(idx).content == *DOT_TRIGGER) {
popup()->hide(); popup()->hide();
return; return false;
} }
} }
nodes = parser.headerNodes().value(ns) + nodes = parser.headerNodes().value(ns) +
@ -281,7 +288,7 @@ void AsCompletion::processTrigger(const QString &trigger,
} }
if (nodes.isEmpty()) { if (nodes.isEmpty()) {
return; return true;
} }
} else if (trigger == *LEFT_PARE_TRIGGER) { } else if (trigger == *LEFT_PARE_TRIGGER) {
// the first is function name, an identifier // the first is function name, an identifier
@ -297,7 +304,7 @@ void AsCompletion::processTrigger(const QString &trigger,
if (idx >= 0 && idx < tokens.length()) { if (idx >= 0 && idx < tokens.length()) {
if (tokens.at(idx).content == *DOT_TRIGGER) { if (tokens.at(idx).content == *DOT_TRIGGER) {
popup()->hide(); popup()->hide();
return; return false;
} }
} }
@ -312,6 +319,7 @@ void AsCompletion::processTrigger(const QString &trigger,
setModel(new CodeCompletionModel(nodes, this)); setModel(new CodeCompletionModel(nodes, this));
setCompletionPrefix(prefix); setCompletionPrefix(prefix);
return true;
} }
QList<CodeInfoTip> AsCompletion::parseDocument() { QList<CodeInfoTip> AsCompletion::parseDocument() {
@ -387,7 +395,14 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
tip.type = CodeInfoTip::Type::Variable; tip.type = CodeInfoTip::Type::Variable;
break; break;
case QAsCodeParser::SymbolType::Class: case QAsCodeParser::SymbolType::Class:
case QAsCodeParser::SymbolType::Interface:
tip.type = CodeInfoTip::Type::Class;
for (auto &mem : sym.children) {
// TODO
}
break;
case QAsCodeParser::SymbolType::Invalid: case QAsCodeParser::SymbolType::Invalid:
case QAsCodeParser::SymbolType::Import:
continue; continue;
} }

View File

@ -38,7 +38,7 @@ public:
void clearFunctionTip(); void clearFunctionTip();
protected: protected:
virtual void processTrigger(const QString &trigger, virtual bool processTrigger(const QString &trigger,
const QString &content) override; const QString &content) override;
virtual QList<CodeInfoTip> parseDocument(); virtual QList<CodeInfoTip> parseDocument();

View File

@ -2840,6 +2840,10 @@ void PluginSystem::checkDirRootSafe(const QDir &dir) {
} }
void PluginSystem::registerFns(IWingPlugin *plg) { void PluginSystem::registerFns(IWingPlugin *plg) {
if (_angelplg == nullptr) {
return;
}
Q_ASSERT(plg); Q_ASSERT(plg);
auto fns = plg->registeredScriptFns(); auto fns = plg->registeredScriptFns();
if (fns.isEmpty()) { if (fns.isEmpty()) {
@ -2912,6 +2916,10 @@ void PluginSystem::registerFns(IWingPlugin *plg) {
} }
void PluginSystem::registerUnSafeFns(IWingPlugin *plg) { void PluginSystem::registerUnSafeFns(IWingPlugin *plg) {
if (_angelplg == nullptr) {
return;
}
Q_ASSERT(plg); Q_ASSERT(plg);
auto fns = plg->registeredScriptUnsafeFns(); auto fns = plg->registeredScriptUnsafeFns();

View File

@ -81,7 +81,6 @@ QAsCodeParser::parseIntell(qsizetype offset,
case SymbolType::Function: { case SymbolType::Function: {
sym.type = seg.additonalInfos.at(0); sym.type = seg.additonalInfos.at(0);
sym.additonalInfo = seg.additonalInfos.at(1); sym.additonalInfo = seg.additonalInfos.at(1);
sym.name = seg.name;
if (offset > seg.offset && offset < seg.end()) { if (offset > seg.offset && offset < seg.end()) {
sym.children = parseStatementBlock(sym.scope, seg.codes, sym.children = parseStatementBlock(sym.scope, seg.codes,
offset - seg.offset); offset - seg.offset);
@ -121,7 +120,13 @@ QAsCodeParser::parseIntell(qsizetype offset,
} }
break; break;
case SymbolType::Class: case SymbolType::Class:
sym.children = parseClassContent(offset, sym.scope, seg.codes);
break;
case SymbolType::Interface:
sym.children = parseInterfaceContent(offset, sym.scope, seg.codes);
break;
case SymbolType::Invalid: case SymbolType::Invalid:
case SymbolType::Import:
continue; continue;
} }
@ -440,6 +445,49 @@ QByteArray QAsCodeParser::parseType(bool allowConst, bool allowVariableType,
return dtType; return dtType;
} }
QAsCodeParser::Symbol
QAsCodeParser::parseFuncDefContent(const QByteArrayList &ns) {
Symbol sym;
sToken t1;
getToken(&t1);
if (t1.type != ttFuncDef) {
rewindErrorTo(&t1);
return sym;
}
sym.type = parseType(true);
if (_isSyntaxError)
return sym;
parseTypeMod(false);
if (_isSyntaxError)
return sym;
auto iden = parseIdentifier();
if (_isSyntaxError)
return sym;
sym.scope = ns;
sym.name = getSymbolString(iden);
sym.offset = iden.pos;
auto args = parseParameterListContent();
if (_isSyntaxError)
return sym;
sym.children = args;
getToken(&t1);
if (t1.type != ttEndStatement) {
rewindErrorTo(&t1);
return sym;
}
sym.symtype = SymbolType::FnDef;
return sym;
}
QList<QAsCodeParser::Symbol> QList<QAsCodeParser::Symbol>
QAsCodeParser::parseStatementBlock(const QByteArrayList &ns, QAsCodeParser::parseStatementBlock(const QByteArrayList &ns,
const QByteArray &code, qsizetype end) { const QByteArray &code, qsizetype end) {
@ -744,10 +792,7 @@ sToken QAsCodeParser::superficiallyParseStatementBlock() {
level--; level--;
else if (t1.type == ttStartStatementBlock) else if (t1.type == ttStartStatementBlock)
level++; level++;
else if (t1.type == ttNonTerminatedStringConstant) { else if (t1.type == ttEnd) {
rewindErrorTo(&t1);
return t1;
} else if (t1.type == ttEnd) {
rewindErrorTo(&start); rewindErrorTo(&start);
return start; return start;
} }
@ -928,12 +973,13 @@ QAsCodeParser::CodeSegment QAsCodeParser::parseInterface() {
auto id = parseIdentifier(); auto id = parseIdentifier();
seg.name = getSymbolString(id); seg.name = getSymbolString(id);
seg.offset = id.pos;
seg.scope = currentNs; seg.scope = currentNs;
seg.type = SymbolType::Class; seg.type = SymbolType::Interface;
// External shared declarations are ended with ';' // External shared declarations are ended with ';'
getToken(&t); getToken(&t);
seg.offset = t.pos;
if (t.type == ttEndStatement) { if (t.type == ttEndStatement) {
rewindTo(&t); rewindTo(&t);
parseToken(ttEndStatement); parseToken(ttEndStatement);
@ -1005,17 +1051,6 @@ void QAsCodeParser::superficiallyParseVarInit() {
} }
} }
void QAsCodeParser::parseStatement() {
sToken t1;
getToken(&t1);
rewindTo(&t1);
// TODO
if (isVarDecl()) {
}
}
QList<QAsCodeParser::Symbol> QList<QAsCodeParser::Symbol>
QAsCodeParser::parseDeclaration(const QByteArrayList &ns, bool isClassProp, QAsCodeParser::parseDeclaration(const QByteArrayList &ns, bool isClassProp,
bool isGlobalVar) { bool isGlobalVar) {
@ -1107,10 +1142,14 @@ QList<QAsCodeParser::CodeSegment> QAsCodeParser::parseScript(bool inBlock) {
rewindTo(&tStart); rewindTo(&tStart);
if (t1.type == ttImport) { if (t1.type == ttImport) {
CodeSegment seg;
seg.offset = t1.pos;
seg.type = SymbolType::Import;
segs << seg;
// import we don't support just skip // import we don't support just skip
skipCodeBlock(); skipCodeBlock();
// add empty invalid segment
segs << CodeSegment();
} else if (t1.type == ttEnum) // Handle enumerations } else if (t1.type == ttEnum) // Handle enumerations
segs << parseEnumeration(); segs << parseEnumeration();
else if (t1.type == ttTypedef) // Handle primitive typedefs else if (t1.type == ttTypedef) // Handle primitive typedefs
@ -1235,12 +1274,13 @@ QAsCodeParser::CodeSegment QAsCodeParser::parseClass() {
auto cls = parseIdentifier(); auto cls = parseIdentifier();
seg.name = getSymbolString(cls); seg.name = getSymbolString(cls);
seg.offset = cls.pos;
seg.scope = currentNs; seg.scope = currentNs;
seg.type = SymbolType::Class; seg.type = SymbolType::Class;
// External shared declarations are ended with ';' // External shared declarations are ended with ';'
getToken(&t); getToken(&t);
seg.offset = t.pos;
if (t.type == ttEndStatement) { if (t.type == ttEndStatement) {
rewindTo(&t); rewindTo(&t);
parseToken(ttEndStatement); parseToken(ttEndStatement);
@ -1383,112 +1423,103 @@ QAsCodeParser::parseGlobalVarDecls(const QByteArrayList &ns,
return parseDeclaration(ns, false, true); return parseDeclaration(ns, false, true);
} }
QAsCodeParser::CodeSegment QAsCodeParser::parseFunction(bool isMethod) { QAsCodeParser::CodeSegment QAsCodeParser::parseFunctionMethod() {
CodeSegment fn; CodeSegment seg;
sToken t1; sToken t1;
getToken(&t1); getToken(&t1);
if (!isMethod) {
// A global function can be marked as shared and external
while (t1.type == ttIdentifier) {
if (identifierIs(t1, SHARED_TOKEN) ||
identifierIs(t1, EXTERNAL_TOKEN)) {
rewindTo(&t1);
parseIdentifier();
if (_isSyntaxError)
return fn;
} else
break;
getToken(&t1);
}
}
// A class method can start with 'private' or 'protected' // A class method can start with 'private' or 'protected'
if (isMethod && t1.type == ttPrivate) { if (t1.type == ttPrivate) {
rewindTo(&t1); rewindTo(&t1);
parseToken(ttPrivate); parseToken(ttPrivate);
getToken(&t1); getToken(&t1);
} else if (isMethod && t1.type == ttProtected) { } else if (t1.type == ttProtected) {
rewindTo(&t1); rewindTo(&t1);
parseToken(ttProtected); parseToken(ttProtected);
getToken(&t1); getToken(&t1);
} }
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
// If it is a global function, or a method, except constructor and // If it is a global function, or a method, except constructor and
// destructor, then the return type is parsed // destructor, then the return type is parsed
sToken t2; sToken t2;
getToken(&t2); getToken(&t2);
rewindTo(&t1); rewindTo(&t1);
if (!isMethod || (t1.type != ttBitNot && t2.type != ttOpenParenthesis)) { if (t1.type != ttBitNot && t2.type != ttOpenParenthesis) {
auto id = parseType(true); auto id = parseType(true);
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
fn.additonalInfos.append(id); seg.additonalInfos.append(id);
parseTypeMod(false); parseTypeMod(false);
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
} }
// If this is a class destructor then it starts with ~, and no return type // If this is a class destructor then it starts with ~, and no return type
// is declared // is declared
if (isMethod && t1.type == ttBitNot) { if (t1.type == ttBitNot) {
parseToken(ttBitNot); parseToken(ttBitNot);
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
} }
auto iden = parseIdentifier(); auto iden = parseIdentifier();
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
fn.name = getSymbolString(iden); seg.name = getSymbolString(iden);
fn.offset = iden.pos; seg.offset = iden.pos;
auto params = parseParameterListContent(); auto params = parseParameterListContent();
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
if (!params.isEmpty()) {
if (fn.additonalInfos.isEmpty()) { if (seg.additonalInfos.isEmpty()) {
fn.additonalInfos.append(QByteArray()); seg.additonalInfos.append(QByteArray());
}
if (params.isEmpty()) {
seg.additonalInfos.append(QByteArray());
} else {
QByteArrayList args;
for (auto &p : params) {
args.append(p.type + ' ' + p.name);
} }
// fn.additonalInfos; seg.additonalInfos.append(args.join(", "));
} }
if (isMethod) { getToken(&t1);
getToken(&t1); rewindTo(&t1);
rewindTo(&t1);
// Is the method a const? // Is the method a const?
if (t1.type == ttConst) if (t1.type == ttConst)
parseToken(ttConst); parseToken(ttConst);
}
// TODO: Should support abstract methods, in which case no statement block // TODO: Should support abstract methods, in which case no statement block
// should be provided // should be provided
parseMethodAttributes(); parseMethodAttributes();
if (_isSyntaxError) if (_isSyntaxError)
return fn; return seg;
// External shared functions must be ended with ';' // External shared functions must be ended with ';'
getToken(&t1); getToken(&t1);
rewindTo(&t1); rewindTo(&t1);
seg.scope = currentNs;
if (t1.type == ttEndStatement) { if (t1.type == ttEndStatement) {
parseToken(ttEndStatement); parseToken(ttEndStatement);
// fn.ns = _curns; return seg;
return fn;
} }
// We should just find the end of the statement block here. The statements auto begin = t1.pos;
// will be parsed on request by the compiler once it starts the compilation.
superficiallyParseStatementBlock(); // We should just find the end of the statement block here.
// fn.ns = _curns; t1 = superficiallyParseStatementBlock();
// fn.code = code.mid(t1.pos, sourcePos - t1.pos); auto end = t1.pos;
// fn.valid = true; seg.codes = _code.sliced(begin, end - begin + 1);
return fn; return seg;
} }
QAsCodeParser::Symbol QAsCodeParser::Symbol
@ -1496,50 +1527,11 @@ QAsCodeParser::parseFuncDefContent(const QByteArrayList &ns,
const QByteArray &code) { const QByteArray &code) {
reset(); reset();
_code = code; _code = code;
return parseFuncDefContent(ns);
Symbol sym;
sToken t1;
getToken(&t1);
if (t1.type != ttFuncDef) {
rewindErrorTo(&t1);
return sym;
}
sym.type = parseType(true);
if (_isSyntaxError)
return sym;
parseTypeMod(false);
if (_isSyntaxError)
return sym;
auto iden = parseIdentifier();
if (_isSyntaxError)
return sym;
sym.scope = ns;
sym.name = getSymbolString(iden);
sym.offset = iden.pos;
auto args = parseParameterListContent();
if (_isSyntaxError)
return sym;
sym.children = args;
getToken(&t1);
if (t1.type != ttEndStatement) {
rewindErrorTo(&t1);
return sym;
}
sym.symtype = SymbolType::FnDef;
return sym;
} }
QList<QAsCodeParser::Symbol> QList<QAsCodeParser::Symbol>
QAsCodeParser::parseClassContent(const QByteArrayList &ns, QAsCodeParser::parseClassContent(qsizetype offset, const QByteArrayList &ns,
const QByteArray &code) { const QByteArray &code) {
reset(); reset();
_code = code; _code = code;
@ -1552,15 +1544,27 @@ QAsCodeParser::parseClassContent(const QByteArrayList &ns,
// Optional list of interfaces that are being implemented and classes that // Optional list of interfaces that are being implemented and classes that
// are being inherited // are being inherited
if (t.type == ttColon) { if (t.type == ttColon) {
// TODO: dont support temperily, later Symbol inhertSym;
parseOptionalScope();
parseIdentifier(); // assuming it as an interface
inhertSym.symtype = SymbolType::Interface;
Symbol isym;
isym.scope = parseOptionalScope();
isym.name = getSymbolString(parseIdentifier());
isym.symtype = SymbolType::Class; // assuming it as a class
inhertSym.children.append(isym);
getToken(&t); getToken(&t);
while (t.type == ttListSeparator) { while (t.type == ttListSeparator) {
parseOptionalScope(); isym.scope = parseOptionalScope();
parseIdentifier(); isym.name = getSymbolString(parseIdentifier());
inhertSym.children.append(isym);
getToken(&t); getToken(&t);
} }
syms.append(inhertSym);
} }
if (t.type != ttStartStatementBlock) { if (t.type != ttStartStatementBlock) {
@ -1574,23 +1578,32 @@ QAsCodeParser::parseClassContent(const QByteArrayList &ns,
while (t.type != ttEndStatementBlock && t.type != ttEnd) { while (t.type != ttEndStatementBlock && t.type != ttEnd) {
// Is it a property or a method? // Is it a property or a method?
if (t.type == ttFuncDef) { if (t.type == ttFuncDef) {
// auto fndef = parseFuncDefContent(); auto fndef = parseFuncDefContent(ns);
// if (fndef.isValid()) { syms.append(fndef);
// clssym.content.append(fndef);
// }
} else if (isFuncDecl(true)) { } else if (isFuncDecl(true)) {
auto fn = parseFunction(true); auto fn = parseFunctionMethod();
// if (fn.isValid()) {
// clssym.codesegs.insert(fn.nameInSrc, fn); // add function symbols
// } Symbol sym;
sym.symtype = fn.type;
sym.scope = fn.scope;
sym.offset = fn.offset;
sym.name = fn.name;
sym.type = fn.additonalInfos.at(0);
sym.additonalInfo = fn.additonalInfos.at(1);
syms.append(sym);
// deep parsing
if (offset >= fn.offset && offset < fn.end()) {
auto ss = parseStatementBlock(fn.scope, fn.codes, offset);
syms.append(ss);
}
} else if (isVirtualPropertyDecl()) { } else if (isVirtualPropertyDecl()) {
auto vp = parseVirtualPropertyDecl(true, false); auto vp = parseVirtualPropertyDecl(true, false);
// if (vp.isValid()) { syms.append(vp);
// clssym.content.append(vp);
// }
} else if (isVarDecl()) { } else if (isVarDecl()) {
// auto decl = parseDeclaration(true); auto decl = parseDeclaration(ns, true);
// clssym.content.append(decl); syms.append(decl);
} else if (t.type == ttEndStatement) } else if (t.type == ttEndStatement)
// Skip empty declarations // Skip empty declarations
getToken(&t); getToken(&t);
@ -1615,53 +1628,14 @@ QAsCodeParser::parseClassContent(const QByteArrayList &ns,
return syms; return syms;
} }
void QAsCodeParser::parseMixinContent() { QList<QAsCodeParser::Symbol>
sToken t; QAsCodeParser::parseInterfaceContent(qsizetype offset, const QByteArrayList &ns,
getToken(&t); const QByteArray &code) {
QList<Symbol> syms;
if (t.type != ttMixin) {
rewindErrorTo(&t);
return;
}
// A mixin token must be followed by a class declaration
// parseClassContent();
}
void QAsCodeParser::parseInterfaceContent() {
Symbol sym;
sToken t; sToken t;
// Allow keywords 'external' and 'shared' before 'interface'
getToken(&t); getToken(&t);
while (identifierIs(t, SHARED_TOKEN) || identifierIs(t, EXTERNAL_TOKEN)) {
rewindTo(&t);
parseIdentifier();
if (_isSyntaxError)
return;
getToken(&t);
}
if (t.type != ttInterface) {
rewindErrorTo(&t);
return;
}
auto id = parseIdentifier();
sym.name = getSymbolString(id);
// sym.nameInSrc = id.pos;
// External shared declarations are ended with ';'
getToken(&t);
if (t.type == ttEndStatement) {
rewindTo(&t);
parseToken(ttEndStatement);
return;
}
// Can optionally have a list of interfaces that are inherited // Can optionally have a list of interfaces that are inherited
if (t.type == ttColon) { if (t.type == ttColon) {
parseOptionalScope(); parseOptionalScope();
@ -1676,7 +1650,7 @@ void QAsCodeParser::parseInterfaceContent() {
if (t.type != ttStartStatementBlock) { if (t.type != ttStartStatementBlock) {
rewindErrorTo(&t); rewindErrorTo(&t);
return; return {};
} }
// Parse interface methods // Parse interface methods
@ -1685,22 +1659,18 @@ void QAsCodeParser::parseInterfaceContent() {
while (t.type != ttEndStatementBlock && t.type != ttEnd) { while (t.type != ttEndStatementBlock && t.type != ttEnd) {
if (isVirtualPropertyDecl()) { if (isVirtualPropertyDecl()) {
auto vp = parseVirtualPropertyDecl(true, true); auto vp = parseVirtualPropertyDecl(true, true);
// if (vp.isValid()) { syms.append(vp);
// sym.content.append(vp);
// }
} else if (t.type == ttEndStatement) { } else if (t.type == ttEndStatement) {
// Skip empty declarations // Skip empty declarations
getToken(&t); getToken(&t);
} else { } else {
// Parse the method signature // Parse the method signature
auto im = parseInterfaceMethod(); auto im = parseInterfaceMethod();
// if (im.isValid()) { syms.append(im);
// sym.content.append(im);
// }
} }
if (_isSyntaxError) if (_isSyntaxError)
return; return syms;
getToken(&t); getToken(&t);
rewindTo(&t); rewindTo(&t);
@ -1709,8 +1679,10 @@ void QAsCodeParser::parseInterfaceContent() {
getToken(&t); getToken(&t);
if (t.type != ttEndStatementBlock) { if (t.type != ttEndStatementBlock) {
rewindErrorTo(&t); rewindErrorTo(&t);
return; return syms;
} }
return syms;
} }
QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() { QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() {
@ -1719,7 +1691,7 @@ QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() {
auto ret = parseType(true); auto ret = parseType(true);
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
// sym.typeStr = getSymbolString(ret); sym.type = ret;
parseTypeMod(false); parseTypeMod(false);
if (_isSyntaxError) if (_isSyntaxError)
@ -1729,12 +1701,13 @@ QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() {
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
sym.name = getSymbolString(id); sym.name = getSymbolString(id);
// sym.nameInSrc = id.pos; sym.offset = id.pos;
auto args = parseParameterListContent(); auto args = parseParameterListContent();
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
// sym.content = args;
sym.children = args;
// Parse an optional const after the method definition // Parse an optional const after the method definition
sToken t1; sToken t1;
@ -1749,7 +1722,7 @@ QAsCodeParser::Symbol QAsCodeParser::parseInterfaceMethod() {
return sym; return sym;
} }
// sym.type = SymbolType::FnDecl; sym.symtype = SymbolType::Function;
return sym; return sym;
} }
@ -1777,7 +1750,7 @@ QAsCodeParser::parseVirtualPropertyDecl(bool isMethod, bool isInterface) {
auto id = parseType(true); auto id = parseType(true);
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
// sym.typeStr = getSymbolString(id); sym.type = id;
parseTypeMod(false); parseTypeMod(false);
if (_isSyntaxError) if (_isSyntaxError)
@ -1787,7 +1760,7 @@ QAsCodeParser::parseVirtualPropertyDecl(bool isMethod, bool isInterface) {
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
sym.name = getSymbolString(iden); sym.name = getSymbolString(iden);
// sym.nameInSrc = iden.pos; sym.offset = iden.pos;
getToken(&t1); getToken(&t1);
if (t1.type != ttStartStatementBlock) { if (t1.type != ttStartStatementBlock) {
@ -1825,11 +1798,7 @@ QAsCodeParser::parseVirtualPropertyDecl(bool isMethod, bool isInterface) {
if (t1.type == ttStartStatementBlock) { if (t1.type == ttStartStatementBlock) {
rewindTo(&t1); rewindTo(&t1);
superficiallyParseStatementBlock(); superficiallyParseStatementBlock();
// TODO: support deep parsing ?
// seg.valid = true;
// seg.code = code.mid(t1.pos, sourcePos - t1.pos);
// sym.codesegs.insert(t1.pos, seg);
if (_isSyntaxError) if (_isSyntaxError)
return sym; return sym;
} else if (t1.type == ttEndStatement) { } else if (t1.type == ttEndStatement) {
@ -1861,7 +1830,7 @@ QAsCodeParser::parseVirtualPropertyDecl(bool isMethod, bool isInterface) {
} }
} }
// sym.type = SymbolType::Property; sym.symtype = SymbolType::Variable;
return sym; return sym;
} }
@ -2206,75 +2175,6 @@ bool QAsCodeParser::isFuncDecl(
return false; return false;
} }
bool QAsCodeParser::isLambda() {
bool isLambda = false;
sToken t;
getToken(&t);
if (t.type == ttIdentifier && identifierIs(t, FUNCTION_TOKEN)) {
sToken t2;
getToken(&t2);
if (t2.type == ttOpenParenthesis) {
// Skip until )
while (t2.type != ttCloseParenthesis && t2.type != ttEnd)
getToken(&t2);
// The next token must be a {
getToken(&t2);
if (t2.type == ttStartStatementBlock)
isLambda = true;
}
}
rewindTo(&t);
return isLambda;
}
bool QAsCodeParser::isFunctionCall() {
sToken s;
sToken t1, t2;
getToken(&s);
t1 = s;
// A function call may be prefixed with scope resolution
if (t1.type == ttScope)
getToken(&t1);
getToken(&t2);
while (t1.type == ttIdentifier && t2.type == ttScope) {
getToken(&t1);
getToken(&t2);
}
// A function call starts with an identifier followed by an argument list
// The parser doesn't have enough RewindErrorTormation about scope to
// determine if the identifier is a datatype, so even if it happens to be
// the parser will identify the expression as a function call rather than a
// construct call. The compiler will sort this out later
if (t1.type != ttIdentifier) {
rewindTo(&s);
return false;
}
if (t2.type == ttOpenParenthesis) {
rewindTo(&s);
return true;
}
rewindTo(&s);
return false;
}
void QAsCodeParser::ParseStringConstant() {
sToken t;
getToken(&t);
if (t.type != ttStringConstant && t.type != ttMultilineStringConstant &&
t.type != ttHeredocStringConstant) {
rewindErrorTo(&t);
return;
}
}
bool QAsCodeParser::findTokenAfterType( bool QAsCodeParser::findTokenAfterType(
sToken &nextToken) { // Set a rewind point sToken &nextToken) { // Set a rewind point
sToken t, t1; sToken t, t1;
@ -2369,43 +2269,6 @@ bool QAsCodeParser::findTokenAfterType(
return true; return true;
} }
bool QAsCodeParser::findIdentifierAfterScope(sToken &nextToken) {
sToken t1, t2, t3;
// Determine the last identifier after scope in order to check if it is a
// type
getToken(&t1);
getToken(&t2);
rewindTo(&t1);
if (t1.type != ttScope && t2.type != ttScope) {
if (t1.type == ttIdentifier) {
nextToken = t1;
return true;
}
return false;
}
if (t1.type == ttScope)
t3 = t2;
else
t3 = t1;
rewindTo(&t3);
getToken(&t2);
while (t3.type == ttIdentifier) {
t2 = t3;
getToken(&t3);
if (t3.type == ttScope)
getToken(&t3);
else
break;
}
rewindTo(&t1);
nextToken = t2;
return true;
}
bool QAsCodeParser::isConstant(int tokenType) { bool QAsCodeParser::isConstant(int tokenType) {
if (tokenType == ttIntConstant || tokenType == ttFloatConstant || if (tokenType == ttIntConstant || tokenType == ttFloatConstant ||
tokenType == ttDoubleConstant || tokenType == ttStringConstant || tokenType == ttDoubleConstant || tokenType == ttStringConstant ||

View File

@ -24,7 +24,7 @@
#include <QMap> #include <QMap>
#include <QString> #include <QString>
// This class is the modification of as_parser. // This class comes from as_parser.h .
// You can modified it to support more features. // You can modified it to support more features.
/** It's a complex thing to fully support AngelScript code intellisense. /** It's a complex thing to fully support AngelScript code intellisense.
** I just support basic code completion. ** I just support basic code completion.
@ -41,16 +41,17 @@ public:
public: public:
enum class SymbolType { enum class SymbolType {
Invalid, Invalid,
Variable, // variable or property in class Variable, // variable or property in class
Enum, // an enum Enum, // an enum
Class, // a class type Class, // a class type
Function, // a function Function, // a function
TypeDef, // a typedef TypeDef, // a typedef
FnDef, // a funcdef FnDef, // a funcdef
Interface, // an interface
Import, // import but not supported
}; };
enum class Visiblity { Public, Private, Protected }; enum class Visiblity { Public, Private, Protected };
/** /**
* @brief The CodeSegment class * @brief The CodeSegment class
*/ */
@ -133,6 +134,7 @@ private:
CodeSegment parseInterface(); CodeSegment parseInterface();
CodeSegment parseFuncDef(); CodeSegment parseFuncDef();
CodeSegment parseFunction(); CodeSegment parseFunction();
CodeSegment parseFunctionMethod();
private: private:
// parse tokens // parse tokens
@ -168,18 +170,19 @@ private:
Symbol parseFuncDefContent(const QByteArrayList &ns, Symbol parseFuncDefContent(const QByteArrayList &ns,
const QByteArray &code); const QByteArray &code);
QList<Symbol> parseClassContent(const QByteArrayList &ns, Symbol parseFuncDefContent(const QByteArrayList &ns);
QList<Symbol> parseClassContent(qsizetype offset, const QByteArrayList &ns,
const QByteArray &code); const QByteArray &code);
QList<Symbol> parseInterfaceContent(qsizetype offset,
const QByteArrayList &ns,
const QByteArray &code);
QList<Symbol> parseStatementBlock(const QByteArrayList &ns, QList<Symbol> parseStatementBlock(const QByteArrayList &ns,
const QByteArray &code, qsizetype end); const QByteArray &code, qsizetype end);
private: private:
void parseStatement();
void parseMixinContent();
void parseInterfaceContent();
CodeSegment parseFunction(bool isMethod);
Symbol parseVirtualPropertyDecl(bool isMethod, bool isInterface); Symbol parseVirtualPropertyDecl(bool isMethod, bool isInterface);
QList<Symbol> parseParameterListContent(); QList<Symbol> parseParameterListContent();
@ -192,8 +195,6 @@ private:
bool isVarDecl(); bool isVarDecl();
bool isVirtualPropertyDecl(); bool isVirtualPropertyDecl();
bool isFuncDecl(bool isMethod); bool isFuncDecl(bool isMethod);
bool isLambda();
bool isFunctionCall();
void getToken(sToken *token); void getToken(sToken *token);
void rewindTo(const sToken *token); void rewindTo(const sToken *token);
@ -209,14 +210,11 @@ private:
private: private:
bool findTokenAfterType(sToken &nextToken); bool findTokenAfterType(sToken &nextToken);
bool findIdentifierAfterScope(sToken &nextToken);
bool typeExist(const QString &t); bool typeExist(const QString &t);
Symbol parseInterfaceMethod(); Symbol parseInterfaceMethod();
void ParseStringConstant();
private: private:
bool _errorWhileParsing; bool _errorWhileParsing;
bool _isSyntaxError; bool _isSyntaxError;

View File

@ -1825,7 +1825,10 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
auto ret = parser.parse(ccode); auto ret = parser.parse(ccode);
// check whether there is any enum/class // check whether there is any enum/class
if (ret.isEmpty()) { if (std::find_if(ret.begin(), ret.end(),
[](const QAsCodeParser::CodeSegment &seg) {
return seg.isValid();
}) == ret.end()) {
// ok, wrap the codes // ok, wrap the codes
ccode.prepend("void main(){").append("}"); ccode.prepend("void main(){").append("}");
// start to compile // start to compile

View File

@ -3786,13 +3786,15 @@ void MainWindow::closeEvent(QCloseEvent *event) {
} }
// then checking the scripting dialog // then checking the scripting dialog
if (!m_scriptDialog->about2Close()) { if (m_scriptDialog) {
event->ignore(); if (!m_scriptDialog->about2Close()) {
return; event->ignore();
} return;
}
// then abort all script running // then abort all script running
ScriptMachine::instance().abortScript(); ScriptMachine::instance().abortScript();
}
// then checking itself // then checking itself
if (!m_views.isEmpty()) { if (!m_views.isEmpty()) {
@ -3843,9 +3845,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
auto &set = SettingManager::instance(); auto &set = SettingManager::instance();
set.setDockLayout(m_dock->saveState()); set.setDockLayout(m_dock->saveState());
m_scriptDialog->saveDockLayout(); if (m_scriptDialog) {
set.setRecentFiles(m_recentmanager->saveRecent()); m_scriptDialog->saveDockLayout();
set.save(); set.setRecentFiles(m_recentmanager->saveRecent());
set.save();
}
PluginSystem::instance().destory(); PluginSystem::instance().destory();