QmlJS: Improve handling of user defined enums

Improves handling of Qml based enums inside qml documents.

 * completion of enums
 * follow the enum
 * highlighting values inside the declaration
 * displaying the enum declaration inside the outline
 * minor static checks

Task-number: QTCREATORBUG-19226
Change-Id: Ia07fd9a8b7fa3106f2ea53198bfdcc50eecb7307
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Christian Stenger
2024-04-08 15:30:05 +02:00
parent ee8245d8aa
commit e1d90a7965
13 changed files with 184 additions and 4 deletions

View File

@@ -599,6 +599,17 @@ protected:
return true;
}
bool visit(UiEnumDeclaration *node) override
{
if (containsOffset(node->identifierToken)) {
_name = node->name.toString();
_scope = _doc->bind()->findQmlObject(_objectNode);
_targetValue = _scopeChain->context()->lookupType(_doc.data(), QStringList(_name));
return false;
}
return true;
}
bool visit(FunctionDeclaration *node) override
{
return visit(static_cast<FunctionExpression *>(node));

View File

@@ -108,10 +108,6 @@ void QmlJSHighlighter::highlightBlock(const QString &text)
break;
}
}
if (QStringView(text).mid(token.offset, token.length) == QLatin1String("enum")) {
setFormat(token.offset, token.length, formatForCategory(C_KEYWORD));
break;
}
} else if (index > 0 && maybeQmlBuiltinType(spell)) {
const Token &previousToken = tokens.at(index - 1);
if (previousToken.is(Token::Identifier)

View File

@@ -348,6 +348,13 @@ protected:
return visit(static_cast<FunctionExpression *>(ast));
}
bool visit(UiEnumMemberList *ast) override
{
for (auto it = ast; it; it = it->next)
addUse(it->memberToken, SemanticHighlighter::FieldType);
return true;
}
bool visit(PatternElement *ast) override
{
if (ast->isVariableDeclaration())

View File

@@ -233,6 +233,19 @@ private:
m_model->leavePublicMember();
}
bool visit(AST::UiEnumDeclaration *enumDecl) override
{
QModelIndex index = m_model->enterEnumDeclaration(enumDecl);
m_nodeToIndex.insert(enumDecl, index);
return true;
}
void endVisit(AST::UiEnumDeclaration *) override
{
m_model->leavePublicMember();
}
bool visit(AST::FunctionDeclaration *functionDeclaration) override
{
QModelIndex index = m_model->enterFunctionDeclaration(functionDeclaration);
@@ -576,6 +589,33 @@ void QmlOutlineModel::leavePublicMember()
leaveNode();
}
QModelIndex QmlOutlineModel::enterEnumDeclaration(AST::UiEnumDeclaration *enumDecl)
{
QMap<int, QVariant> objectData;
if (!enumDecl->name.isEmpty())
objectData.insert(Qt::DisplayRole, enumDecl->name.toString());
objectData.insert(ItemTypeRole, ElementBindingType);
QmlOutlineItem *item = enterNode(objectData, enumDecl, nullptr, Icons::enumMemberIcon());
for (auto member = enumDecl->members; member; member = member->next) {
QMap<int, QVariant> memberData;
if (!member->member.isEmpty())
memberData.insert(Qt::DisplayRole, member->member.toString());
memberData.insert(ItemTypeRole, ElementBindingType);
memberData.insert(AnnotationRole, QString::number(member->value));
enterNode(memberData, member, nullptr, Icons::publicMemberIcon());
leaveNode();
}
return item->index();
}
void QmlOutlineModel::leaveEnumDeclaration()
{
leaveNode();
}
static QString functionDisplayName(QStringView name, AST::FormalParameterList *formals)
{
QString display;

View File

@@ -91,6 +91,9 @@ private:
QModelIndex enterPublicMember(QmlJS::AST::UiPublicMember *publicMember);
void leavePublicMember();
QModelIndex enterEnumDeclaration(QmlJS::AST::UiEnumDeclaration *enumDecl);
void leaveEnumDeclaration();
QModelIndex enterFunctionDeclaration(QmlJS::AST::FunctionDeclaration *functionDeclaration);
void leaveFunctionDeclaration();