feat: 数值增加无符号切换格式;初步代码内容提示;

This commit is contained in:
寂静的羽夏 2025-04-06 20:11:30 +08:00
parent 7ee69b5ced
commit 7597663d76
13 changed files with 2160 additions and 1740 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ int asBuilder::StartNewModule(const char *moduleName) {
if (module == nullptr) if (module == nullptr)
return -1; return -1;
ClearAll(); clearAll();
return 0; return 0;
} }
@ -53,7 +53,7 @@ int asBuilder::Build() {
for (auto &mod : modifiedScripts) { for (auto &mod : modifiedScripts) {
module->AddScriptSection(mod.section.toUtf8(), mod.script.data(), module->AddScriptSection(mod.section.toUtf8(), mod.script.data(),
mod.script.size(), mod.lineOffset); mod.script.size());
} }
int r = module->Build(); int r = module->Build();

View File

@ -18,6 +18,8 @@
#include "ascompletion.h" #include "ascompletion.h"
#include "asdatabase.h" #include "asdatabase.h"
#include "class/aspreprocesser.h"
#include "class/qascodeparser.h"
#include "model/codecompletionmodel.h" #include "model/codecompletionmodel.h"
#include "wingcodeedit.h" #include "wingcodeedit.h"
@ -38,8 +40,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, LEFT_PARE_TRIGGER, ("("))
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, SEMI_COLON_TRIGGER, (";")) Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, SEMI_COLON_TRIGGER, (";"))
AsCompletion::AsCompletion(asIScriptEngine *engine, WingCodeEdit *p) AsCompletion::AsCompletion(asIScriptEngine *engine, WingCodeEdit *p)
: WingCompleter(p), parser(engine), _engine(engine), : WingCompleter(p), parser(engine), _engine(engine), m_parseDocument(true) {
m_parseDocument(false) {
Q_ASSERT(engine); Q_ASSERT(engine);
setTriggerList({*DOT_TRIGGER, *DBL_COLON_TRIGGER, setTriggerList({*DOT_TRIGGER, *DBL_COLON_TRIGGER,
@ -80,7 +81,7 @@ void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes) {
} }
emptyNsNodes.append(parser.keywordNodes()); emptyNsNodes.append(parser.keywordNodes());
} }
nodes = emptyNsNodes; nodes.append(emptyNsNodes);
} }
void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) { void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) {
@ -134,10 +135,6 @@ void AsCompletion::processTrigger(const QString &trigger,
QList<CodeInfoTip> nodes; QList<CodeInfoTip> nodes;
// TODO: PRs are welcomed !!!
// If this software is well-known or brings me lots of
// financial support, I will implement it myself.
// PARSING THE DOCUMENT
if (m_parseDocument) { if (m_parseDocument) {
nodes.append(parseDocument()); nodes.append(parseDocument());
} }
@ -286,7 +283,64 @@ void AsCompletion::processTrigger(const QString &trigger,
setCompletionPrefix(prefix); setCompletionPrefix(prefix);
} }
QList<CodeInfoTip> AsCompletion::parseDocument() { return {}; } QList<CodeInfoTip> AsCompletion::parseDocument() {
auto editor = qobject_cast<WingCodeEdit *>(widget());
if (editor == nullptr) {
return {};
}
auto code = editor->toPlainText();
// first preprocess the code
AsPreprocesser prepc(_engine);
// TODO: set include callback
// prepc.setIncludeCallback();
auto r = prepc.loadSectionFromMemory(QStringLiteral("ASCOMPLETION"),
code.toUtf8());
if (r <= 0) {
return {};
}
auto data = prepc.scriptData();
QList<CodeInfoTip> ret;
for (auto &d : data) {
QAsCodeParser parser(_engine);
auto syms =
parser.parseAndIntell(editor->textCursor().position(), d.script);
for (auto &sym : syms) {
CodeInfoTip tip;
tip.name = sym.name;
tip.nameSpace = QString::fromUtf8(sym.scope.join("::"));
switch (sym.symtype) {
case QAsCodeParser::SymbolType::Function:
tip.type = CodeInfoTip::Type::Function;
tip.addinfo.insert(CodeInfoTip::RetType,
QString::fromUtf8(sym.type));
tip.addinfo.insert(CodeInfoTip::Args,
QString::fromUtf8(sym.additonalInfo));
break;
case QAsCodeParser::SymbolType::Enum:
tip.type = CodeInfoTip::Type::Enum;
break;
case QAsCodeParser::SymbolType::Variable:
case QAsCodeParser::SymbolType::Class:
case QAsCodeParser::SymbolType::TypeDef:
case QAsCodeParser::SymbolType::FnDef:
case QAsCodeParser::SymbolType::VarsDecl:
case QAsCodeParser::SymbolType::Invalid:
continue;
}
ret.append(tip);
}
}
return ret;
}
bool AsCompletion::eventFilter(QObject *watched, QEvent *event) { bool AsCompletion::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {

View File

@ -1,12 +1,26 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "asconsolecompletion.h" #include "asconsolecompletion.h"
#include "control/scriptingconsole.h" #include "control/scriptingconsole.h"
AsConsoleCompletion::AsConsoleCompletion(asIScriptEngine *engine, AsConsoleCompletion::AsConsoleCompletion(asIScriptEngine *engine,
ScriptingConsole *p) ScriptingConsole *p)
: AsCompletion(engine, p), _console(p) {} : AsCompletion(engine, p), _console(p) {
setParseDocument(false);
QList<CodeInfoTip> AsConsoleCompletion::parseDocument() {
// TODO
return {};
} }

View File

@ -1,3 +1,20 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#ifndef ASCONSOLECOMPLETION_H #ifndef ASCONSOLECOMPLETION_H
#define ASCONSOLECOMPLETION_H #define ASCONSOLECOMPLETION_H
@ -11,10 +28,6 @@ public:
explicit AsConsoleCompletion(asIScriptEngine *engine, ScriptingConsole *p); explicit AsConsoleCompletion(asIScriptEngine *engine, ScriptingConsole *p);
virtual ~AsConsoleCompletion() = default; virtual ~AsConsoleCompletion() = default;
// AsCompletion interface
protected:
virtual QList<CodeInfoTip> parseDocument() override;
private: private:
ScriptingConsole *_console; ScriptingConsole *_console;
}; };

View File

@ -41,14 +41,14 @@ AsPreprocesser::AsPreprocesser(asIScriptEngine *engine) : engine(engine) {
AsPreprocesser::~AsPreprocesser() { void ClearAll(); } AsPreprocesser::~AsPreprocesser() { void ClearAll(); }
int AsPreprocesser::AddSectionFromFile(const QString &filename) { int AsPreprocesser::loadSectionFromFile(const QString &filename) {
// The file name stored in the set should be the fully resolved name because // The file name stored in the set should be the fully resolved name because
// it is possible to name the same file in multiple ways using relative // it is possible to name the same file in multiple ways using relative
// paths. // paths.
auto fullpath = QFileInfo(filename).absoluteFilePath(); auto fullpath = QFileInfo(filename).absoluteFilePath();
if (IncludeIfNotAlreadyIncluded(fullpath)) { if (includeIfNotAlreadyIncluded(fullpath)) {
int r = LoadScriptSection(fullpath); int r = loadScriptSection(fullpath);
if (r < 0) if (r < 0)
return r; return r;
else else
@ -58,55 +58,57 @@ int AsPreprocesser::AddSectionFromFile(const QString &filename) {
return 0; return 0;
} }
QList<AsPreprocesser::ScriptData> AsPreprocesser::GetScriptData() const { int AsPreprocesser::loadSectionFromMemory(const QString &section,
const QByteArray &code) {
int r = processScriptSection(code, section);
if (r < 0)
return r;
else
return 1;
}
QList<AsPreprocesser::ScriptData> AsPreprocesser::scriptData() const {
return modifiedScripts; return modifiedScripts;
} }
asIScriptEngine *AsPreprocesser::GetEngine() { return engine; } asIScriptEngine *AsPreprocesser::getEngine() { return engine; }
void AsPreprocesser::SetIncludeCallback(INCLUDECALLBACK_t callback, void AsPreprocesser::setIncludeCallback(INCLUDECALLBACK_t callback,
void *userParam) { void *userParam) {
includeCallback = callback; includeCallback = callback;
includeParam = userParam; includeParam = userParam;
} }
void AsPreprocesser::SetPragmaCallback(PRAGMACALLBACK_t callback, void AsPreprocesser::setPragmaCallback(PRAGMACALLBACK_t callback,
void *userParam) { void *userParam) {
pragmaCallback = callback; pragmaCallback = callback;
pragmaParam = userParam; pragmaParam = userParam;
} }
void AsPreprocesser::DefineWord(const QString &word) { void AsPreprocesser::defineWord(const QString &word) {
if (!definedWords.contains(word)) { if (!definedWords.contains(word)) {
definedWords.append(word); definedWords.append(word);
} }
} }
unsigned int AsPreprocesser::GetSectionCount() const { unsigned int AsPreprocesser::sectionCount() const {
return (unsigned int)(includedScripts.size()); return (unsigned int)(includedScripts.size());
} }
QString AsPreprocesser::GetSectionName(unsigned int idx) const { QString AsPreprocesser::sectionName(unsigned int idx) const {
if (qsizetype(idx) >= qsizetype(includedScripts.size())) if (qsizetype(idx) >= qsizetype(includedScripts.size()))
return {}; return {};
return includedScripts.at(idx); return includedScripts.at(idx);
} }
void AsPreprocesser::ClearAll() { includedScripts.clear(); } void AsPreprocesser::clearAll() { includedScripts.clear(); }
int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length, int AsPreprocesser::processScriptSection(const QByteArray &script,
const QString &sectionname, const QString &sectionname) {
int lineOffset) {
QVector<QPair<QString, bool>> includes; QVector<QPair<QString, bool>> includes;
QByteArray modifiedScript; QByteArray modifiedScript = script;
// Perform a superficial parsing of the script first to store the metadata
if (length)
modifiedScript = script.left(length);
else
modifiedScript = script;
// First perform the checks for #if directives to exclude code that // First perform the checks for #if directives to exclude code that
// shouldn't be compiled // shouldn't be compiled
@ -144,13 +146,13 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
// Overwrite the #if directive with space characters to // Overwrite the #if directive with space characters to
// avoid compiler error // avoid compiler error
pos += len; pos += len;
OverwriteCode(modifiedScript, start, pos - start); overwriteCode(modifiedScript, start, pos - start);
// Has this identifier been defined by the application or // Has this identifier been defined by the application or
// not? // not?
if (!definedWords.contains(word)) { if (!definedWords.contains(word)) {
// Exclude all the code until and including the #endif // Exclude all the code until and including the #endif
pos = ExcludeCode(modifiedScript, pos); pos = excludeCode(modifiedScript, pos);
} else { } else {
nested++; nested++;
} }
@ -158,7 +160,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
} else if (token == "endif") { } else if (token == "endif") {
// Only remove the #endif if there was a matching #if // Only remove the #endif if there was a matching #if
if (nested > 0) { if (nested > 0) {
OverwriteCode(modifiedScript, start, pos - start); overwriteCode(modifiedScript, start, pos - start);
nested--; nested--;
} }
} }
@ -231,7 +233,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
// Overwrite the include directive with space // Overwrite the include directive with space
// characters to avoid compiler error // characters to avoid compiler error
OverwriteCode(modifiedScript, start, pos - start); overwriteCode(modifiedScript, start, pos - start);
} }
} }
@ -279,7 +281,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
// Overwrite the include directive with // Overwrite the include directive with
// space characters to avoid compiler error // space characters to avoid compiler error
OverwriteCode(modifiedScript, start, overwriteCode(modifiedScript, start,
pos - start); pos - start);
} }
} else { } else {
@ -305,7 +307,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
// Overwrite the pragma directive with space characters // Overwrite the pragma directive with space characters
// to avoid compiler error // to avoid compiler error
OverwriteCode(modifiedScript, start, pos - start); overwriteCode(modifiedScript, start, pos - start);
int r = pragmaCallback int r = pragmaCallback
? pragmaCallback(pragmaText, this, sectionname, ? pragmaCallback(pragmaText, this, sectionname,
@ -324,14 +326,14 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
// Don't search for includes within statement blocks or // Don't search for includes within statement blocks or
// between tokens in statements // between tokens in statements
else { else {
pos = SkipStatement(modifiedScript, pos); pos = skipStatement(modifiedScript, pos);
} }
} }
// Build the actual script // Build the actual script
engine->SetEngineProperty(asEP_COPY_SCRIPT_SECTIONS, true); engine->SetEngineProperty(asEP_COPY_SCRIPT_SECTIONS, true);
AddScriptSection(sectionname, modifiedScript, lineOffset); addScriptSection(sectionname, modifiedScript);
if (includes.size() > 0) { if (includes.size() > 0) {
// If the callback has been set, then call it for each included file // If the callback has been set, then call it for each included file
@ -362,7 +364,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
} }
// Include the script section // Include the script section
int r = AddSectionFromFile(includes[n].first); int r = loadSectionFromFile(includes[n].first);
if (r < 0) if (r < 0)
return r; return r;
} }
@ -372,7 +374,7 @@ int AsPreprocesser::ProcessScriptSection(const QByteArray &script, int length,
return 0; return 0;
} }
int AsPreprocesser::LoadScriptSection(const QString &filename) { int AsPreprocesser::loadScriptSection(const QString &filename) {
// Open the script file // Open the script file
QFile f(filename); QFile f(filename);
@ -396,10 +398,10 @@ int AsPreprocesser::LoadScriptSection(const QString &filename) {
// Process the script section even if it is zero length so that the name is // Process the script section even if it is zero length so that the name is
// registered // registered
return ProcessScriptSection(code, code.length(), filename, 0); return processScriptSection(code, filename);
} }
bool AsPreprocesser::IncludeIfNotAlreadyIncluded(const QString &filename) { bool AsPreprocesser::includeIfNotAlreadyIncluded(const QString &filename) {
if (includedScripts.contains(filename)) { if (includedScripts.contains(filename)) {
// Already included // Already included
return false; return false;
@ -410,7 +412,7 @@ bool AsPreprocesser::IncludeIfNotAlreadyIncluded(const QString &filename) {
return true; return true;
} }
int AsPreprocesser::SkipStatement(const QByteArray &modifiedScript, int pos) { int AsPreprocesser::skipStatement(const QByteArray &modifiedScript, int pos) {
asUINT len = 0; asUINT len = 0;
// Skip until ; or { whichever comes first // Skip until ; or { whichever comes first
@ -445,7 +447,7 @@ int AsPreprocesser::SkipStatement(const QByteArray &modifiedScript, int pos) {
return pos; return pos;
} }
int AsPreprocesser::ExcludeCode(QByteArray &modifiedScript, int pos) { int AsPreprocesser::excludeCode(QByteArray &modifiedScript, int pos) {
asUINT len = 0; asUINT len = 0;
int nested = 0; int nested = 0;
while (pos < (int)modifiedScript.size()) { while (pos < (int)modifiedScript.size()) {
@ -459,7 +461,7 @@ int AsPreprocesser::ExcludeCode(QByteArray &modifiedScript, int pos) {
engine->ParseToken(modifiedScript.data() + pos, engine->ParseToken(modifiedScript.data() + pos,
modifiedScript.size() - pos, &len); modifiedScript.size() - pos, &len);
QString token = modifiedScript.mid(pos, len); QString token = modifiedScript.mid(pos, len);
OverwriteCode(modifiedScript, pos, len); overwriteCode(modifiedScript, pos, len);
if (token == "if") { if (token == "if") {
nested++; nested++;
@ -470,7 +472,7 @@ int AsPreprocesser::ExcludeCode(QByteArray &modifiedScript, int pos) {
} }
} }
} else if (modifiedScript[pos] != '\n') { } else if (modifiedScript[pos] != '\n') {
OverwriteCode(modifiedScript, pos, len); overwriteCode(modifiedScript, pos, len);
} }
pos += len; pos += len;
} }
@ -478,7 +480,7 @@ int AsPreprocesser::ExcludeCode(QByteArray &modifiedScript, int pos) {
return pos; return pos;
} }
void AsPreprocesser::OverwriteCode(QByteArray &modifiedScript, int start, void AsPreprocesser::overwriteCode(QByteArray &modifiedScript, int start,
int len) { int len) {
auto code = modifiedScript.data() + start; auto code = modifiedScript.data() + start;
for (int n = 0; n < len; n++) { for (int n = 0; n < len; n++) {
@ -488,11 +490,10 @@ void AsPreprocesser::OverwriteCode(QByteArray &modifiedScript, int start,
} }
} }
void AsPreprocesser::AddScriptSection(const QString &section, void AsPreprocesser::addScriptSection(const QString &section,
const QByteArray &code, int lineOffset) { const QByteArray &code) {
ScriptData data; ScriptData data;
data.section = section; data.section = section;
data.lineOffset = lineOffset;
data.script = code; data.script = code;
modifiedScripts.append(data); modifiedScripts.append(data);
} }

View File

@ -70,7 +70,6 @@ public:
public: public:
struct ScriptData { struct ScriptData {
QString section; QString section;
int lineOffset = -1;
QByteArray script; QByteArray script;
}; };
@ -79,41 +78,40 @@ public:
// Returns 1 if the file was included // Returns 1 if the file was included
// 0 if the file had already been included before // 0 if the file had already been included before
// <0 on error // <0 on error
int AddSectionFromFile(const QString &filename); int loadSectionFromFile(const QString &filename);
int loadSectionFromMemory(const QString &section, const QByteArray &code);
QList<ScriptData> GetScriptData() const; QList<ScriptData> scriptData() const;
// Returns the engine // Returns the engine
asIScriptEngine *GetEngine(); asIScriptEngine *getEngine();
// Register the callback for resolving include directive // Register the callback for resolving include directive
void SetIncludeCallback(INCLUDECALLBACK_t callback, void *userParam); void setIncludeCallback(INCLUDECALLBACK_t callback, void *userParam);
// Register the callback for resolving pragma directive // Register the callback for resolving pragma directive
void SetPragmaCallback(PRAGMACALLBACK_t callback, void *userParam); void setPragmaCallback(PRAGMACALLBACK_t callback, void *userParam);
// Add a pre-processor define for conditional compilation // Add a pre-processor define for conditional compilation
void DefineWord(const QString &word); void defineWord(const QString &word);
// Enumerate included script sections // Enumerate included script sections
unsigned int GetSectionCount() const; unsigned int sectionCount() const;
QString GetSectionName(unsigned int idx) const; QString sectionName(unsigned int idx) const;
protected: protected:
void ClearAll(); void clearAll();
int ProcessScriptSection(const QByteArray &script, int length, void addScriptSection(const QString &section, const QByteArray &code);
const QString &sectionname, int lineOffset); int processScriptSection(const QByteArray &script,
int LoadScriptSection(const QString &filename); const QString &sectionname);
bool IncludeIfNotAlreadyIncluded(const QString &filename); int loadScriptSection(const QString &filename);
bool includeIfNotAlreadyIncluded(const QString &filename);
int SkipStatement(const QByteArray &modifiedScript, int pos); int skipStatement(const QByteArray &modifiedScript, int pos);
int ExcludeCode(QByteArray &modifiedScript, int pos); int excludeCode(QByteArray &modifiedScript, int pos);
void OverwriteCode(QByteArray &modifiedScript, int start, int len); void overwriteCode(QByteArray &modifiedScript, int start, int len);
void AddScriptSection(const QString &section, const QByteArray &code,
int lineOffset);
asIScriptEngine *engine; asIScriptEngine *engine;
QList<ScriptData> modifiedScripts; QList<ScriptData> modifiedScripts;

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@
// This class is the modification of as_parser. // This class is the modification of as_parser.
// 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 like local or global ** I just support basic code completion.
* variables/functions.
** If you are interested in implement a well-featured intellisense like ** If you are interested in implement a well-featured intellisense like
* Qt creator or Visual Studio, PRs are welcomed !!! * Qt creator or Visual Studio, PRs are welcomed !!!
*/ */
@ -42,101 +41,115 @@ public:
public: public:
enum class SymbolType { enum class SymbolType {
Invalid, Invalid,
FnDecl, Variable, // variable or property in class
Import,
Value, // a common value
Variable, // a variable
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
Property, // a property VarsDecl, // global variable decalration
}; };
enum class Visiblity { Public, Private, Protected }; enum class Visiblity { Public, Private, Protected };
struct Symbol; /**
* @brief The CodeSegment class
*/
struct CodeSegment { struct CodeSegment {
bool valid = false; QByteArrayList scope;
// QByteArrayList ns; QString name;
QByteArray ret; SymbolType type = QAsCodeParser::SymbolType::Invalid;
QByteArray name; int offset = -1;
qsizetype nameInSrc = -1; QString codes;
QList<Symbol> args;
QByteArray code;
bool isValid() const { return valid; } QByteArrayList additonalInfos; // for other additonal infos
public:
bool isValid() const { return type != SymbolType::Invalid; }
bool hasCodes() const { return !codes.isEmpty(); }
}; };
struct Symbol { struct Symbol {
SymbolType type = SymbolType::Invalid; SymbolType symtype = QAsCodeParser::SymbolType::Invalid;
QByteArrayList scope;
QString name; QString name;
qsizetype nameInSrc = -1; QByteArray type;
QString typeStr; int offset = -1;
Visiblity vis = Visiblity::Public; Visiblity vis = QAsCodeParser::Visiblity::Public;
QList<Symbol> content; QByteArray additonalInfo; // for other additonal info
// QByteArrayList ns; // namespaces QList<Symbol> children;
QMap<qsizetype, CodeSegment> codesegs; // used in class
// size_t scope = 0; // 0 for all
bool isValid() const { return type != SymbolType::Invalid; }
}; };
using SymbolTable = QMap<size_t, Symbol>;
private:
// QMap< offset , CodeSegment>
QMap<qsizetype, CodeSegment> m_segs; // global functions
public: public:
SymbolTable parse(const QByteArray &codes); // First, we should parse and split the code into segments
QList<QAsCodeParser::CodeSegment> parse(const QByteArray &codes);
SymbolTable parseIntell(qsizetype offset, const QByteArray &codes); // Then, we can deep parsing for code completion
QList<Symbol> parseIntell(qsizetype offset,
const QList<QAsCodeParser::CodeSegment> &segs);
// so, a helper function?
QList<Symbol> parseAndIntell(qsizetype offset, const QByteArray &codes);
private: private:
void ParseScript(bool inBlock); QList<QAsCodeParser::CodeSegment> parseScript(bool inBlock);
void appendValidSeg(QList<QAsCodeParser::CodeSegment> &container,
QAsCodeParser::CodeSegment seg);
void skipCodeBlock();
QByteArray getSymbolString(const sToken &t); QByteArray getSymbolString(const sToken &t);
QByteArrayList getRealNamespace(const QByteArrayList &ns); QByteArrayList getRealNamespace(const QByteArrayList &ns);
// Statements
sToken superficiallyParseVarInit();
sToken superficiallyParseStatementBlock();
void parseMethodAttributes();
private:
CodeSegment parseEnumeration();
CodeSegment parseTypedef();
CodeSegment parseClass();
CodeSegment parseMixin();
CodeSegment parseInterface();
CodeSegment parseFuncDef();
CodeSegment parseFunction();
private:
// parse tokens // parse tokens
sToken ParseIdentifier(); sToken parseIdentifier();
sToken ParseToken(int token); sToken parseToken(int token);
sToken ParseRealType(); sToken parseRealType();
sToken ParseDataType(bool allowVariableType = false, sToken parseDataType(bool allowVariableType = false,
bool allowAuto = false); bool allowAuto = false);
sToken ParseOneOf(int *tokens, int count); sToken parseOneOf(int *tokens, int count);
sToken ParseType(bool allowConst, bool allowVariableType = false, sToken parseType(bool allowConst, bool allowVariableType = false,
bool allowAuto = false); bool allowAuto = false);
// Statements void parseNamespace();
sToken SuperficiallyParseVarInit();
// parse and get symbols private:
Symbol ParseImport(); // deep parsing
void ParseEnumeration(); void parseStatementBlock();
void ParseTypedef(); void parseStatement();
void ParseClass();
void ParseMixin(); private:
void ParseInterface(); void parseEnumerationContent();
Symbol ParseFuncDef(); void parseTypedefContent();
void ParseNamespace(); void parseClassContent();
void parseMixinContent();
void parseInterfaceContent();
Symbol parseFuncDefContent();
void ParseReturn(); void ParseReturn();
void ParseBreak(); void ParseBreak();
void ParseContinue(); void ParseContinue();
void ParseTryCatch(); void ParseTryCatch();
void ParseIf(); void ParseIf();
void ParseLambda(); void ParseLambda();
void ParseStatement(); CodeSegment parseFunction(bool isMethod);
CodeSegment ParseFunction(bool isMethod = false);
void ParseExpressionStatement(); void ParseExpressionStatement();
void ParseListPattern(); void ParseListPattern();
void ParseStatementBlock();
void ParseAssignment(); void ParseAssignment();
void ParseAssignOperator(); void ParseAssignOperator();
@ -155,13 +168,12 @@ private:
QByteArrayList ParseOptionalScope(); QByteArrayList ParseOptionalScope();
Symbol ParseVirtualPropertyDecl(bool isMethod, bool isInterface); Symbol parseVirtualPropertyDecl(bool isMethod, bool isInterface);
QList<Symbol> ParseParameterList(); QList<Symbol> parseParameterListContent();
// parse but not get symbols // parse but not get symbols
void ParseTypeMod(bool isParam); void ParseTypeMod(bool isParam);
void ParseFunctionCall(); void ParseFunctionCall();
void SuperficiallyParseStatementBlock();
void ParseInitList(); void ParseInitList();
void ParseCast(); void ParseCast();
void ParseVariableAccess(); void ParseVariableAccess();
@ -169,49 +181,48 @@ private:
void ParseConstant(); void ParseConstant();
private: private:
void Reset(); void reset();
bool IsVarDecl(); bool isVarDecl();
bool IsVirtualPropertyDecl(); bool isVirtualPropertyDecl();
bool IsFuncDecl(bool isMethod); bool isFuncDecl(bool isMethod);
bool IsLambda(); bool isLambda();
bool IsFunctionCall(); bool isFunctionCall();
void GetToken(sToken *token); void getToken(sToken *token);
void RewindTo(const sToken *token); void rewindTo(const sToken *token);
void RewindErrorTo(sToken *token); void rewindErrorTo(sToken *token);
void SetPos(size_t pos); void SetPos(size_t pos);
bool IsRealType(int tokenType); bool isRealType(int tokenType);
bool IdentifierIs(const sToken &t, const char *str); bool identifierIs(const sToken &t, const char *str);
bool IsDataType(const sToken &token); bool isDataType(const sToken &token);
private: private:
bool CheckTemplateType(const sToken &t); bool checkTemplateType(const sToken &t);
bool ParseTemplTypeList(bool required = true); bool parseTemplTypeList(bool required = true);
void ParseMethodAttributes();
void ParseArgList(bool withParenthesis = true); void parseArgList(bool withParenthesis = true);
void SuperficiallyParseExpression(); void superficiallyParseExpression();
private: private:
bool FindTokenAfterType(sToken &nextToken); bool findTokenAfterType(sToken &nextToken);
bool FindIdentifierAfterScope(sToken &nextToken); bool findIdentifierAfterScope(sToken &nextToken);
bool IsConstant(int tokenType); bool isConstant(int tokenType);
bool IsOperator(int tokenType); bool isOperator(int tokenType);
bool IsPreOperator(int tokenType); bool isPreOperator(int tokenType);
bool IsPostOperator(int tokenType); bool isPostOperator(int tokenType);
bool IsAssignOperator(int tokenType); bool isAssignOperator(int tokenType);
bool DoesTypeExist(const QString &t); bool typeExist(const QString &t);
Symbol ParseFunctionDefinition(); Symbol parseFunctionDefinition();
QList<Symbol> ParseDeclaration(bool isClassProp = false, QList<Symbol> parseDeclaration(bool isClassProp = false,
bool isGlobalVar = false); bool isGlobalVar = false);
Symbol ParseInterfaceMethod(); Symbol parseInterfaceMethod();
void ParseStringConstant(); void ParseStringConstant();
@ -224,13 +235,14 @@ private:
asCScriptEngine *engine; asCScriptEngine *engine;
// size_t _curscope = 0; // size_t _curscope = 0;
SymbolTable _symtable;
QByteArray code; QByteArray code;
QByteArray tempString; // Used for reduzing amount of dynamic allocations QByteArray tempString; // Used for reduzing amount of dynamic allocations
sToken lastToken; sToken lastToken;
size_t sourcePos; size_t sourcePos;
QByteArrayList currentNs;
}; };
#endif // QASCODEPARSER_H #endif // QASCODEPARSER_H

View File

@ -265,12 +265,12 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) {
asBuilder builder(_engine); asBuilder builder(_engine);
for (auto &m : PluginSystem::instance().scriptMarcos()) { for (auto &m : PluginSystem::instance().scriptMarcos()) {
builder.DefineWord(m); builder.defineWord(m);
} }
// Set the pragma callback so we can detect // Set the pragma callback so we can detect
builder.SetPragmaCallback(&ScriptMachine::pragmaCallback, this); builder.setPragmaCallback(&ScriptMachine::pragmaCallback, this);
builder.SetIncludeCallback(&ScriptMachine::includeCallback, this); builder.setIncludeCallback(&ScriptMachine::includeCallback, this);
// Compile the script // Compile the script
auto r = builder.StartNewModule("script"); auto r = builder.StartNewModule("script");
@ -278,7 +278,7 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) {
return false; return false;
} }
r = builder.AddSectionFromFile(script.toUtf8()); r = builder.loadSectionFromFile(script.toUtf8());
if (r < 0) { if (r < 0) {
return false; return false;
} }
@ -522,7 +522,7 @@ int ScriptMachine::pragmaCallback(const QByteArray &pragmaText,
const QString &sectionname, void *userParam) { const QString &sectionname, void *userParam) {
Q_UNUSED(userParam); Q_UNUSED(userParam);
asIScriptEngine *engine = builder->GetEngine(); asIScriptEngine *engine = builder->getEngine();
// Filter the pragmaText so only what is of interest remains // Filter the pragmaText so only what is of interest remains
// With this the user can add comments and use different whitespaces // With this the user can add comments and use different whitespaces
@ -589,7 +589,7 @@ int ScriptMachine::includeCallback(const QString &include, bool quotedInclude,
inc += QStringLiteral(".as"); inc += QStringLiteral(".as");
} }
return builder->AddSectionFromFile(inc); return builder->loadSectionFromFile(inc);
} }
QString ScriptMachine::processTranslation(const char *content, QString ScriptMachine::processTranslation(const char *content,

View File

@ -724,25 +724,40 @@ MainWindow::buildUpNumberShowDock(ads::CDockManager *dock,
actionGroup->setExclusive(true); actionGroup->setExclusive(true);
auto le = Utilities::checkIsLittleEndian(); auto le = Utilities::checkIsLittleEndian();
m_littleEndian = new QAction(actionGroup); auto aLittleEndian = new QAction(actionGroup);
m_littleEndian->setText(tr("LittleEndian")); aLittleEndian->setText(tr("LittleEndian"));
m_littleEndian->setCheckable(true); aLittleEndian->setCheckable(true);
m_littleEndian->setChecked(le); aLittleEndian->setChecked(le);
connect(m_littleEndian, &QAction::triggered, this, [=] { connect(aLittleEndian, &QAction::triggered, this, [=] {
m_islittle = true; m_islittle = true;
this->on_locChanged(); this->on_locChanged();
}); });
m_numshowtable->addAction(m_littleEndian); m_numshowtable->addAction(aLittleEndian);
m_bigEndian = new QAction(actionGroup); auto aBigEndian = new QAction(actionGroup);
m_bigEndian->setText(tr("BigEndian")); aBigEndian->setText(tr("BigEndian"));
m_bigEndian->setCheckable(true); aBigEndian->setCheckable(true);
m_bigEndian->setChecked(!le); aBigEndian->setChecked(!le);
connect(m_bigEndian, &QAction::triggered, this, [=] { connect(aBigEndian, &QAction::triggered, this, [=] {
m_islittle = false; m_islittle = false;
this->on_locChanged(); this->on_locChanged();
}); });
m_numshowtable->addAction(m_bigEndian); m_numshowtable->addAction(aBigEndian);
a = new QAction(this);
a->setSeparator(true);
m_numshowtable->addAction(a);
auto aUnsignedHex = new QAction(this);
aUnsignedHex->setText(tr("UnsignedHex"));
aUnsignedHex->setCheckable(true);
aUnsignedHex->setChecked(false);
connect(aUnsignedHex, &QAction::toggled, this, [=](bool b) {
m_unsignedHex = b;
this->on_locChanged();
});
m_numshowtable->addAction(aUnsignedHex);
m_numshowtable->setContextMenuPolicy( m_numshowtable->setContextMenuPolicy(
Qt::ContextMenuPolicy::ActionsContextMenu); Qt::ContextMenuPolicy::ActionsContextMenu);
@ -2834,7 +2849,9 @@ void MainWindow::on_locChanged() {
auto s = processEndian(n); auto s = processEndian(n);
_numsitem->setNumData( _numsitem->setNumData(
NumShowModel::NumTableIndex::Uint64, NumShowModel::NumTableIndex::Uint64,
QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())); m_unsignedHex
? QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())
: QString::number(s));
auto s1 = processEndian(qsizetype(n)); auto s1 = processEndian(qsizetype(n));
_numsitem->setNumData(NumShowModel::NumTableIndex::Int64, _numsitem->setNumData(NumShowModel::NumTableIndex::Int64,
QString::number(s1)); QString::number(s1));
@ -2853,7 +2870,9 @@ void MainWindow::on_locChanged() {
auto s = processEndian(quint32(n)); auto s = processEndian(quint32(n));
_numsitem->setNumData( _numsitem->setNumData(
NumShowModel::NumTableIndex::Uint32, NumShowModel::NumTableIndex::Uint32,
QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())); m_unsignedHex
? QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())
: QString::number(s));
auto s1 = processEndian(qint32(n)); auto s1 = processEndian(qint32(n));
_numsitem->setNumData(NumShowModel::NumTableIndex::Int32, _numsitem->setNumData(NumShowModel::NumTableIndex::Int32,
QString::number(s1)); QString::number(s1));
@ -2872,7 +2891,9 @@ void MainWindow::on_locChanged() {
auto s = processEndian(quint16(n)); auto s = processEndian(quint16(n));
_numsitem->setNumData( _numsitem->setNumData(
NumShowModel::NumTableIndex::Ushort, NumShowModel::NumTableIndex::Ushort,
QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())); m_unsignedHex
? QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())
: QString::number(s));
auto s1 = processEndian(qint16(n)); auto s1 = processEndian(qint16(n));
_numsitem->setNumData(NumShowModel::NumTableIndex::Short, _numsitem->setNumData(NumShowModel::NumTableIndex::Short,
QString::number(s1)); QString::number(s1));
@ -2885,7 +2906,9 @@ void MainWindow::on_locChanged() {
auto s = uchar(s1); auto s = uchar(s1);
_numsitem->setNumData( _numsitem->setNumData(
NumShowModel::NumTableIndex::Byte, NumShowModel::NumTableIndex::Byte,
QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())); m_unsignedHex
? QStringLiteral("0x%1").arg(QString::number(s, 16).toUpper())
: QString::number(s));
_numsitem->setNumData(NumShowModel::NumTableIndex::Char, _numsitem->setNumData(NumShowModel::NumTableIndex::Char,
QString::number(s1)); QString::number(s1));
} else { } else {

View File

@ -555,9 +555,6 @@ private:
QLabel *m_lblsellen = nullptr; QLabel *m_lblsellen = nullptr;
QStatusBar *m_status = nullptr; QStatusBar *m_status = nullptr;
QAction *m_littleEndian = nullptr;
QAction *m_bigEndian = nullptr;
QAction *m_aShowMetafg = nullptr; QAction *m_aShowMetafg = nullptr;
QAction *m_aShowMetabg = nullptr; QAction *m_aShowMetabg = nullptr;
QAction *m_aShowMetaComment = nullptr; QAction *m_aShowMetaComment = nullptr;
@ -603,9 +600,6 @@ private:
QString m_lastusedpath; QString m_lastusedpath;
bool m_islittle = true; bool m_islittle = true;
bool m_enablePlugin = true; bool m_unsignedHex = false;
// Guard against recursion
bool _isHandlingEvent = false;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H