feat: 更好的代码填充;
This commit is contained in:
parent
f51630c6f0
commit
f87c0970be
|
@ -4,7 +4,7 @@
|
||||||
# You can redistribute this file and/or modify it under the terms of the BSD
|
# You can redistribute this file and/or modify it under the terms of the BSD
|
||||||
# 3-Clause.
|
# 3-Clause.
|
||||||
#
|
#
|
||||||
# THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
|
# THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
|
|
@ -64,8 +64,10 @@ AsCompletion::AsCompletion(WingCodeEdit *p)
|
||||||
|
|
||||||
AsCompletion::~AsCompletion() {}
|
AsCompletion::~AsCompletion() {}
|
||||||
|
|
||||||
void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes) {
|
void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes,
|
||||||
|
const QList<CodeInfoTip> &docNodes) {
|
||||||
static QList<CodeInfoTip> emptyNsNodes;
|
static QList<CodeInfoTip> emptyNsNodes;
|
||||||
|
|
||||||
if (emptyNsNodes.isEmpty()) {
|
if (emptyNsNodes.isEmpty()) {
|
||||||
auto &hn = parser.headerNodes();
|
auto &hn = parser.headerNodes();
|
||||||
for (auto p = hn.constKeyValueBegin(); p != hn.constKeyValueEnd();
|
for (auto p = hn.constKeyValueBegin(); p != hn.constKeyValueEnd();
|
||||||
|
@ -81,6 +83,24 @@ void AsCompletion::applyEmptyNsNode(QList<CodeInfoTip> &nodes) {
|
||||||
}
|
}
|
||||||
emptyNsNodes.append(parser.keywordNodes());
|
emptyNsNodes.append(parser.keywordNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodes.clear();
|
||||||
|
|
||||||
|
for (auto &p : docNodes) {
|
||||||
|
if (p.nameSpace.isEmpty()) {
|
||||||
|
nodes.append(p);
|
||||||
|
} else {
|
||||||
|
if (p.dontAddGlobal) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeInfoTip tip;
|
||||||
|
tip.type = CodeInfoTip::Type::Group;
|
||||||
|
tip.name = p.nameSpace;
|
||||||
|
nodes.append(tip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes.append(emptyNsNodes);
|
nodes.append(emptyNsNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,9 +154,10 @@ void AsCompletion::processTrigger(const QString &trigger,
|
||||||
auto code = content.toUtf8();
|
auto code = content.toUtf8();
|
||||||
|
|
||||||
QList<CodeInfoTip> nodes;
|
QList<CodeInfoTip> nodes;
|
||||||
|
QList<CodeInfoTip> docNodes;
|
||||||
|
|
||||||
if (m_parseDocument) {
|
if (m_parseDocument) {
|
||||||
nodes.append(parseDocument());
|
docNodes = parseDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!trigger.isEmpty() && trigger != *DOT_TRIGGER) {
|
if (!trigger.isEmpty() && trigger != *DOT_TRIGGER) {
|
||||||
|
@ -213,7 +234,7 @@ void AsCompletion::processTrigger(const QString &trigger,
|
||||||
prefix = etoken.content;
|
prefix = etoken.content;
|
||||||
tokens.removeLast();
|
tokens.removeLast();
|
||||||
if (tokens.isEmpty()) {
|
if (tokens.isEmpty()) {
|
||||||
applyEmptyNsNode(nodes);
|
applyEmptyNsNode(nodes, docNodes);
|
||||||
} else {
|
} else {
|
||||||
etoken = tokens.back(); // checking later
|
etoken = tokens.back(); // checking later
|
||||||
}
|
}
|
||||||
|
@ -231,7 +252,7 @@ void AsCompletion::processTrigger(const QString &trigger,
|
||||||
setCompletionPrefix(prefix);
|
setCompletionPrefix(prefix);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
applyEmptyNsNode(nodes);
|
applyEmptyNsNode(nodes, docNodes);
|
||||||
}
|
}
|
||||||
} else if (etoken.type != asTC_IDENTIFIER) {
|
} else if (etoken.type != asTC_IDENTIFIER) {
|
||||||
popup()->hide();
|
popup()->hide();
|
||||||
|
@ -251,7 +272,14 @@ void AsCompletion::processTrigger(const QString &trigger,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodes = parser.headerNodes().value(ns);
|
nodes = parser.headerNodes().value(ns) +
|
||||||
|
parser.enumsNodes().value(ns);
|
||||||
|
for (auto &n : docNodes) {
|
||||||
|
if (n.nameSpace == ns) {
|
||||||
|
nodes.append(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nodes.isEmpty()) {
|
if (nodes.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,9 +300,11 @@ void AsCompletion::processTrigger(const QString &trigger,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = parser.headerNodes().value(ns);
|
nodes = parser.headerNodes().value(ns);
|
||||||
|
|
||||||
if (nodes.isEmpty()) {
|
if (nodes.isEmpty()) {
|
||||||
applyEmptyNsNode(nodes);
|
applyEmptyNsNode(nodes, docNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,9 +321,10 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto code = editor->toPlainText();
|
auto code = editor->toPlainText();
|
||||||
|
auto engine = ScriptMachine::instance().engine();
|
||||||
|
|
||||||
// first preprocess the code
|
// first preprocess the code
|
||||||
AsPreprocesser prepc(ScriptMachine::instance().engine());
|
AsPreprocesser prepc(engine);
|
||||||
// TODO: set include callback
|
// TODO: set include callback
|
||||||
// prepc.setIncludeCallback();
|
// prepc.setIncludeCallback();
|
||||||
|
|
||||||
|
@ -307,7 +338,7 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
||||||
QList<CodeInfoTip> ret;
|
QList<CodeInfoTip> ret;
|
||||||
|
|
||||||
for (auto &d : data) {
|
for (auto &d : data) {
|
||||||
QAsCodeParser parser(ScriptMachine::instance().engine());
|
QAsCodeParser parser(engine);
|
||||||
auto syms =
|
auto syms =
|
||||||
parser.parseAndIntell(editor->textCursor().position(), d.script);
|
parser.parseAndIntell(editor->textCursor().position(), d.script);
|
||||||
|
|
||||||
|
@ -326,12 +357,28 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
||||||
break;
|
break;
|
||||||
case QAsCodeParser::SymbolType::Enum:
|
case QAsCodeParser::SymbolType::Enum:
|
||||||
tip.type = CodeInfoTip::Type::Enum;
|
tip.type = CodeInfoTip::Type::Enum;
|
||||||
|
for (auto &e : sym.children) {
|
||||||
|
CodeInfoTip en;
|
||||||
|
en.dontAddGlobal = true;
|
||||||
|
en.name = e.name;
|
||||||
|
en.nameSpace = QString::fromUtf8(e.scope.join("::"));
|
||||||
|
en.type = CodeInfoTip::Type::Enumerater;
|
||||||
|
if (!e.additonalInfo.isEmpty()) {
|
||||||
|
en.addinfo.insert(CodeInfoTip::Comment,
|
||||||
|
en.name + QStringLiteral(" = ") +
|
||||||
|
e.additonalInfo);
|
||||||
|
}
|
||||||
|
ret.append(en);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QAsCodeParser::SymbolType::TypeDef:
|
||||||
|
tip.type = CodeInfoTip::Type::KeyWord;
|
||||||
break;
|
break;
|
||||||
case QAsCodeParser::SymbolType::Variable:
|
case QAsCodeParser::SymbolType::Variable:
|
||||||
|
tip.type = CodeInfoTip::Type::Variable;
|
||||||
|
break;
|
||||||
case QAsCodeParser::SymbolType::Class:
|
case QAsCodeParser::SymbolType::Class:
|
||||||
case QAsCodeParser::SymbolType::TypeDef:
|
|
||||||
case QAsCodeParser::SymbolType::FnDef:
|
case QAsCodeParser::SymbolType::FnDef:
|
||||||
case QAsCodeParser::SymbolType::VarsDecl:
|
|
||||||
case QAsCodeParser::SymbolType::Invalid:
|
case QAsCodeParser::SymbolType::Invalid:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,8 @@ public:
|
||||||
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void applyEmptyNsNode(QList<CodeInfoTip> &nodes);
|
void applyEmptyNsNode(QList<CodeInfoTip> &nodes,
|
||||||
|
const QList<CodeInfoTip> &docNodes);
|
||||||
void applyClassNodes(QList<CodeInfoTip> &nodes);
|
void applyClassNodes(QList<CodeInfoTip> &nodes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -177,6 +177,10 @@ const QHash<QString, QList<CodeInfoTip>> &ASDataBase::headerNodes() const {
|
||||||
return _headerNodes;
|
return _headerNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QHash<QString, QList<CodeInfoTip>> &ASDataBase::enumsNodes() const {
|
||||||
|
return _enumsNodes;
|
||||||
|
}
|
||||||
|
|
||||||
void ASDataBase::addGlobalFunctionCompletion(asIScriptEngine *engine) {
|
void ASDataBase::addGlobalFunctionCompletion(asIScriptEngine *engine) {
|
||||||
Q_ASSERT(engine);
|
Q_ASSERT(engine);
|
||||||
|
|
||||||
|
@ -210,6 +214,13 @@ void ASDataBase::addEnumCompletion(asIScriptEngine *engine) {
|
||||||
einfo.name = etype->GetName();
|
einfo.name = etype->GetName();
|
||||||
einfo.type = CodeInfoTip::Type::Enum;
|
einfo.type = CodeInfoTip::Type::Enum;
|
||||||
|
|
||||||
|
auto ens = einfo.nameSpace;
|
||||||
|
if (ens.isEmpty()) {
|
||||||
|
ens = einfo.name;
|
||||||
|
} else {
|
||||||
|
ens += QStringLiteral("::") + einfo.name;
|
||||||
|
}
|
||||||
|
|
||||||
for (asUINT i = 0; i < etype->GetEnumValueCount(); ++i) {
|
for (asUINT i = 0; i < etype->GetEnumValueCount(); ++i) {
|
||||||
int v;
|
int v;
|
||||||
auto e = etype->GetEnumValueByIndex(i, &v);
|
auto e = etype->GetEnumValueByIndex(i, &v);
|
||||||
|
@ -221,6 +232,7 @@ void ASDataBase::addEnumCompletion(asIScriptEngine *engine) {
|
||||||
QStringLiteral(" = ") +
|
QStringLiteral(" = ") +
|
||||||
QString::number(v));
|
QString::number(v));
|
||||||
einfo.children.append(en);
|
einfo.children.append(en);
|
||||||
|
_enumsNodes[ens].append(en);
|
||||||
}
|
}
|
||||||
|
|
||||||
etype->Release();
|
etype->Release();
|
||||||
|
|
|
@ -42,6 +42,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const QHash<QString, QList<CodeInfoTip>> &headerNodes() const;
|
const QHash<QString, QList<CodeInfoTip>> &headerNodes() const;
|
||||||
|
const QHash<QString, QList<CodeInfoTip>> &enumsNodes() const;
|
||||||
|
|
||||||
const QList<CodeInfoTip> &keywordNodes() const;
|
const QList<CodeInfoTip> &keywordNodes() const;
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ private:
|
||||||
private:
|
private:
|
||||||
// <namespace, content>
|
// <namespace, content>
|
||||||
QHash<QString, QList<CodeInfoTip>> _headerNodes;
|
QHash<QString, QList<CodeInfoTip>> _headerNodes;
|
||||||
|
QHash<QString, QList<CodeInfoTip>> _enumsNodes;
|
||||||
QList<CodeInfoTip> _keywordNode;
|
QList<CodeInfoTip> _keywordNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString name;
|
QString name;
|
||||||
|
bool dontAddGlobal = false;
|
||||||
Type type = Type::Unknown;
|
Type type = Type::Unknown;
|
||||||
QString nameSpace;
|
QString nameSpace;
|
||||||
CodeInfoVisibility visualpo = CodeInfoVisibility::VISIBILITY_DEFAULT;
|
CodeInfoVisibility visualpo = CodeInfoVisibility::VISIBILITY_DEFAULT;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,7 +47,6 @@ public:
|
||||||
Function, // a function
|
Function, // a function
|
||||||
TypeDef, // a typedef
|
TypeDef, // a typedef
|
||||||
FnDef, // a funcdef
|
FnDef, // a funcdef
|
||||||
VarsDecl, // global variable decalration
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Visiblity { Public, Private, Protected };
|
enum class Visiblity { Public, Private, Protected };
|
||||||
|
@ -57,22 +56,34 @@ public:
|
||||||
*/
|
*/
|
||||||
struct CodeSegment {
|
struct CodeSegment {
|
||||||
QByteArrayList scope;
|
QByteArrayList scope;
|
||||||
QString name;
|
QByteArray name;
|
||||||
SymbolType type = QAsCodeParser::SymbolType::Invalid;
|
SymbolType type = QAsCodeParser::SymbolType::Invalid;
|
||||||
int offset = -1;
|
qsizetype offset = -1;
|
||||||
QString codes;
|
QByteArray codes;
|
||||||
|
|
||||||
QByteArrayList additonalInfos; // for other additonal infos
|
QByteArrayList additonalInfos; // for other additonal infos
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isValid() const { return type != SymbolType::Invalid; }
|
inline bool isValid() const {
|
||||||
bool hasCodes() const { return !codes.isEmpty(); }
|
return offset >= 0 && type != SymbolType::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline qsizetype end() const {
|
||||||
|
if (offset < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return offset + codes.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline qsizetype length() const { return codes.length(); }
|
||||||
|
|
||||||
|
inline bool hasCodes() const { return !codes.isEmpty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
SymbolType symtype = QAsCodeParser::SymbolType::Invalid;
|
SymbolType symtype = QAsCodeParser::SymbolType::Invalid;
|
||||||
QByteArrayList scope;
|
QByteArrayList scope;
|
||||||
QString name;
|
QByteArray name;
|
||||||
QByteArray type;
|
QByteArray type;
|
||||||
int offset = -1;
|
int offset = -1;
|
||||||
Visiblity vis = QAsCodeParser::Visiblity::Public;
|
Visiblity vis = QAsCodeParser::Visiblity::Public;
|
||||||
|
@ -95,16 +106,15 @@ public:
|
||||||
private:
|
private:
|
||||||
QList<QAsCodeParser::CodeSegment> parseScript(bool inBlock);
|
QList<QAsCodeParser::CodeSegment> parseScript(bool inBlock);
|
||||||
|
|
||||||
void appendValidSeg(QList<QAsCodeParser::CodeSegment> &container,
|
|
||||||
QAsCodeParser::CodeSegment seg);
|
|
||||||
|
|
||||||
void skipCodeBlock();
|
void skipCodeBlock();
|
||||||
QByteArray getSymbolString(const sToken &t);
|
QByteArray getSymbolString(const sToken &t);
|
||||||
QByteArrayList getRealNamespace(const QByteArrayList &ns);
|
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
sToken superficiallyParseVarInit();
|
void superficiallyParseVarInit();
|
||||||
sToken superficiallyParseStatementBlock();
|
sToken superficiallyParseStatementBlock();
|
||||||
|
void superficiallyParseExpression();
|
||||||
|
void superficiallyParseTemplateList();
|
||||||
|
|
||||||
void parseMethodAttributes();
|
void parseMethodAttributes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -131,12 +141,24 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// deep parsing
|
// deep parsing
|
||||||
void parseStatementBlock();
|
QList<Symbol> parseEnumerationContent(const QByteArrayList &ns,
|
||||||
void parseStatement();
|
const QByteArray &name,
|
||||||
|
const QByteArray &code);
|
||||||
|
Symbol parseTypedefContent(const QByteArrayList &ns,
|
||||||
|
const QByteArray &code);
|
||||||
|
|
||||||
|
QList<Symbol> parseGlobalVarDecls(const QByteArrayList &ns,
|
||||||
|
const QByteArray &code);
|
||||||
|
|
||||||
|
QByteArrayList parseOptionalScope();
|
||||||
|
|
||||||
|
QList<Symbol> parseDeclaration(const QByteArrayList &ns,
|
||||||
|
bool isClassProp = false,
|
||||||
|
bool isGlobalVar = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseEnumerationContent();
|
void parseStatementBlock();
|
||||||
void parseTypedefContent();
|
void parseStatement();
|
||||||
void parseClassContent();
|
void parseClassContent();
|
||||||
void parseMixinContent();
|
void parseMixinContent();
|
||||||
void parseInterfaceContent();
|
void parseInterfaceContent();
|
||||||
|
@ -166,8 +188,6 @@ private:
|
||||||
void ParseExprPostOp();
|
void ParseExprPostOp();
|
||||||
void ParseExprValue();
|
void ParseExprValue();
|
||||||
|
|
||||||
QByteArrayList ParseOptionalScope();
|
|
||||||
|
|
||||||
Symbol parseVirtualPropertyDecl(bool isMethod, bool isInterface);
|
Symbol parseVirtualPropertyDecl(bool isMethod, bool isInterface);
|
||||||
QList<Symbol> parseParameterListContent();
|
QList<Symbol> parseParameterListContent();
|
||||||
|
|
||||||
|
@ -192,20 +212,17 @@ private:
|
||||||
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 isPrimType(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);
|
|
||||||
|
|
||||||
void parseArgList(bool withParenthesis = true);
|
void parseArgList(bool withParenthesis = true);
|
||||||
|
|
||||||
void superficiallyParseExpression();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool findTokenAfterType(sToken &nextToken);
|
bool findTokenAfterType(sToken &nextToken);
|
||||||
bool findIdentifierAfterScope(sToken &nextToken);
|
bool findIdentifierAfterScope(sToken &nextToken);
|
||||||
|
@ -219,28 +236,25 @@ private:
|
||||||
|
|
||||||
Symbol parseFunctionDefinition();
|
Symbol parseFunctionDefinition();
|
||||||
|
|
||||||
QList<Symbol> parseDeclaration(bool isClassProp = false,
|
|
||||||
bool isGlobalVar = false);
|
|
||||||
|
|
||||||
Symbol parseInterfaceMethod();
|
Symbol parseInterfaceMethod();
|
||||||
|
|
||||||
void ParseStringConstant();
|
void ParseStringConstant();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool errorWhileParsing;
|
bool _errorWhileParsing;
|
||||||
bool isSyntaxError;
|
bool _isSyntaxError;
|
||||||
bool checkValidTypes;
|
bool _checkValidTypes;
|
||||||
bool isParsingAppInterface;
|
bool _isParsingAppInterface;
|
||||||
|
|
||||||
asCScriptEngine *engine;
|
asCScriptEngine *engine;
|
||||||
|
|
||||||
// size_t _curscope = 0;
|
// size_t _curscope = 0;
|
||||||
|
|
||||||
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;
|
QByteArrayList currentNs;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue