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