diff options
239 files changed, 12742 insertions, 5834 deletions
diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index eea59c5806..54ecae36bc 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -5,7 +5,7 @@ \title Qt Creator Manual - \section1 Version 1.3.0 + \section1 Version 1.3.80 The goal of Qt Creator is to provide a cross-platform, complete Integrated Development Environment (IDE) to develop Qt projects. It is available for @@ -1472,7 +1472,7 @@ specified in the \c CMake project file. Known issues for the current version can be found - \l{Known Issues of Version 1.3.0}{here}. + \l{Known Issues of Version 1.2.93}{here}. */ @@ -1964,7 +1964,7 @@ There are some known issues with Qt Creator. The development team is aware of those, there is no need to report them as bug. - \section1 Known Issues of Version 1.3.0 + \section1 Known Issues of Version 1.3.80 \list \o Debugging Helper do not work while doing On Device Debugging. diff --git a/doc/qtcreator.qdocconf b/doc/qtcreator.qdocconf index 6d4f4b5883..a0c46705fa 100644 --- a/doc/qtcreator.qdocconf +++ b/doc/qtcreator.qdocconf @@ -19,16 +19,16 @@ sources.fileextensions = "qtcreator.qdoc addressbook-sdk.qdoc" qhp.projects = QtCreator qhp.QtCreator.file = qtcreator.qhp -qhp.QtCreator.namespace = com.nokia.qtcreator.130 +qhp.QtCreator.namespace = com.nokia.qtcreator.1380 qhp.QtCreator.virtualFolder = doc qhp.QtCreator.indexTitle = Qt Creator qhp.QtCreator.indexRoot = qhp.QtCreator.extraFiles = classic.css \ images/qt-logo.png \ images/qtcreator-screenshots.png -qhp.QtCreator.filterAttributes = qtcreator 1.3.0 -qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 1.3.0 -qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 1.3.0 +qhp.QtCreator.filterAttributes = qtcreator 1.3.80 +qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 1.3.80 +qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 1.3.80 # macros.qdocconf @@ -211,5 +211,5 @@ HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ "<td width=\"40%\" align=\"left\">Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \ "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \ - "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt Creator 1.3.0</div></td>\n" \ + "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt Creator 1.3.80</div></td>\n" \ "</tr></table></div></address>" diff --git a/src/app/Info.plist b/src/app/Info.plist index db2eab7ca8..6aebaef9cc 100644 --- a/src/app/Info.plist +++ b/src/app/Info.plist @@ -184,8 +184,8 @@ <key>CFBundleIdentifier</key> <string>com.nokia.qtcreator</string> <key>CFBundleVersion</key> - <string>1.3.0</string> + <string>1.3.80</string> <key>CFBundleShortVersionString</key> - <string>1.3.0</string> + <string>1.3.80</string> </dict> </plist> diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp index 7f1f6cdfe6..46fb15efe4 100644 --- a/src/libs/cplusplus/BackwardsScanner.cpp +++ b/src/libs/cplusplus/BackwardsScanner.cpp @@ -40,6 +40,7 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suf { _tokenize.setQtMocRunEnabled(true); _tokenize.setSkipComments(true); + _tokenize.setObjCEnabled(true); _text = _block.text().left(cursor.position() - cursor.block().position()); if (! suffix.isEmpty()) diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp index 5f0b6b2d27..5d996579ee 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp +++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp @@ -103,8 +103,8 @@ bool CheckUndefinedSymbols::isType(const QByteArray &name) const for (int i = _templateDeclarationStack.size() - 1; i != - 1; --i) { TemplateDeclarationAST *templateDeclaration = _templateDeclarationStack.at(i); - for (DeclarationListAST *it = templateDeclaration->template_parameters; it; it = it->next) { - DeclarationAST *templateParameter = it->declaration; + for (DeclarationListAST *it = templateDeclaration->template_parameter_list; it; it = it->next) { + DeclarationAST *templateParameter = it->value; if (templateParameterName(templateParameter) == name) return true; @@ -244,9 +244,8 @@ void CheckUndefinedSymbols::endVisit(FunctionDeclaratorAST *) _functionDeclaratorStack.removeLast(); } -bool CheckUndefinedSymbols::visit(TypeofSpecifierAST *ast) +bool CheckUndefinedSymbols::visit(TypeofSpecifierAST *) { - accept(ast->next); return false; } @@ -286,11 +285,6 @@ void CheckUndefinedSymbols::endVisit(TemplateDeclarationAST *) bool CheckUndefinedSymbols::visit(ClassSpecifierAST *ast) { - if (ast->base_clause) { - unsigned line, col; - getTokenStartPosition(ast->firstToken(), &line, &col); - } - bool hasQ_OBJECT_CHECK = false; if (ast->symbol) { @@ -380,15 +374,8 @@ bool CheckUndefinedSymbols::visit(BaseSpecifierAST *base) resolvedBaseClassName = true; } - if (! resolvedBaseClassName) { - const char *token = "after `:'"; - - if (base->comma_token) - token = "after `,'"; - - translationUnit()->warning(nameAST->firstToken(), - "expected class-name %s token", token); - } + if (! resolvedBaseClassName) + translationUnit()->warning(nameAST->firstToken(), "expected class-name"); } return true; @@ -437,9 +424,9 @@ bool CheckUndefinedSymbols::visit(CastExpressionAST *ast) { if (ast->lparen_token && ast->type_id && ast->rparen_token && ast->expression) { if (TypeIdAST *cast_type_id = ast->type_id->asTypeId()) { - SpecifierAST *type_specifier = cast_type_id->type_specifier; + SpecifierListAST *type_specifier = cast_type_id->type_specifier_list; if (! cast_type_id->declarator && type_specifier && ! type_specifier->next && - type_specifier->asNamedTypeSpecifier() && ast->expression && + type_specifier->value->asNamedTypeSpecifier() && ast->expression && ast->expression->asUnaryExpression()) { // this ast node is ambigious, e.g. // (a) + b @@ -460,17 +447,17 @@ bool CheckUndefinedSymbols::visit(SizeofExpressionAST *ast) { if (ast->lparen_token && ast->expression && ast->rparen_token) { if (TypeIdAST *type_id = ast->expression->asTypeId()) { - SpecifierAST *type_specifier = type_id->type_specifier; + SpecifierListAST *type_specifier = type_id->type_specifier_list; if (! type_id->declarator && type_specifier && ! type_specifier->next && - type_specifier->asNamedTypeSpecifier()) { + type_specifier->value->asNamedTypeSpecifier()) { // this sizeof expression is ambiguos, e.g. // sizeof (a) // `a' can be a typeid or a nested-expression. return false; } else if (type_id->declarator - && type_id->declarator->postfix_declarators - && ! type_id->declarator->postfix_declarators->next - && type_id->declarator->postfix_declarators->asArrayDeclarator() != 0) { + && type_id->declarator->postfix_declarator_list + && ! type_id->declarator->postfix_declarator_list->next + && type_id->declarator->postfix_declarator_list->value->asArrayDeclarator() != 0) { // this sizeof expression is ambiguos, e.g. // sizeof(a[10]) // `a' can be a typeid or an expression. @@ -505,8 +492,8 @@ bool CheckUndefinedSymbols::visit(ObjCClassDeclarationAST *ast) bool CheckUndefinedSymbols::visit(ObjCProtocolRefsAST *ast) { - for (IdentifierListAST *iter = ast->identifier_list; iter; iter = iter->next) { - if (NameAST *nameAST = iter->name) { + for (ObjCIdentifierListAST *iter = ast->identifier_list; iter; iter = iter->next) { + if (NameAST *nameAST = iter->value) { bool resolvedProtocolName = false; if (Name *name = nameAST->name) { @@ -531,3 +518,16 @@ bool CheckUndefinedSymbols::visit(ObjCProtocolRefsAST *ast) return false; } + +bool CheckUndefinedSymbols::visit(ObjCPropertyDeclarationAST *ast) +{ + for (List<ObjCPropertyDeclaration *> *iter = ast->symbols; iter; iter = iter->next) { + if (Name *getterName = iter->value->getterName()) + ; // FIXME: resolve the symbol for the name, and check its signature. + + if (Name *setterName = iter->value->setterName()) + ; // FIXME: resolve the symbol for the name, and check its signature. + } + + return false; +} diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.h b/src/libs/cplusplus/CheckUndefinedSymbols.h index fbdca0f94e..4a13b6ee2d 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.h +++ b/src/libs/cplusplus/CheckUndefinedSymbols.h @@ -96,6 +96,7 @@ protected: virtual bool visit(ObjCClassDeclarationAST *ast); virtual bool visit(ObjCProtocolRefsAST *ast); + virtual bool visit(ObjCPropertyDeclarationAST *ast); private: Document::Ptr _doc; diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index f0c6665a46..bd86eecaae 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -414,8 +414,8 @@ void Document::check(CheckMode mode) return; // nothing to do. if (TranslationUnitAST *ast = _translationUnit->ast()->asTranslationUnit()) { - for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) { - semantic.check(decl->declaration, globals); + for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) { + semantic.check(decl->value, globals); } } else if (ExpressionAST *ast = _translationUnit->ast()->asExpression()) { semantic.check(ast, globals); diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp index 995eeace37..3bfec589c8 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.cpp +++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp @@ -106,6 +106,45 @@ int ExpressionUnderCursor::startOfExpression_helper(BackwardsScanner &tk, int in return startOfExpression(tk, index - 2); } else if (tk[index - 2].is(T_DOT_STAR) || tk[index - 2].is(T_ARROW_STAR)) { return startOfExpression(tk, index - 2); + } else if (tk[index - 2].is(T_LBRACKET)) { + // array subscription: + // array[i + return index - 1; + } else if (tk[index - 2].is(T_COLON)) { + // either of: + // cond ? expr1 : id + // or: + // [receiver messageParam:id + // and in both cases, the id (and only the id) is what we want, so: + return index - 1; + } else if (tk[index - 2].is(T_IDENTIFIER) && tk[index - 3].is(T_LBRACKET)) { + // Very common Objective-C case: + // [receiver message + // which we handle immediately: + return index - 3; + } else { + // See if we are handling an Objective-C messaging expression in the form of: + // [receiver messageParam1:expression messageParam2 + // or: + // [receiver messageParam1:expression messageParam2:expression messageParam3 + // ... etc + int i = index - 1; + while (tk[i].isNot(T_EOF_SYMBOL)) { + if (tk[i].is(T_LBRACKET)) + break; + if (tk[i].is(T_LBRACE) || tk[i].is(T_RBRACE)) + break; + else if (tk[i].is(T_RBRACKET)) + i = tk.startOfMatchingBrace(i + 1) - 1; + else + --i; + } + + int j = i; + while (tk[j].is(T_LBRACKET)) + ++j; + if (tk[j].is(T_IDENTIFIER) && tk[j + 1].is(T_IDENTIFIER)) + return i; } return index - 1; } else if (tk[index - 1].is(T_RPAREN)) { diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index b74e85995f..8d50162501 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -287,8 +287,8 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken) bool FindUsages::visit(QualifiedNameAST *ast) { - for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier; - nested_name_specifier; nested_name_specifier = nested_name_specifier->next) { + for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) { + NestedNameSpecifierAST *nested_name_specifier = it->value; if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) { SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName(); @@ -298,9 +298,8 @@ bool FindUsages::visit(QualifiedNameAST *ast) template_id = class_or_namespace_name->asTemplateId(); if (template_id) { - for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; - template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); + for (TemplateArgumentListAST *arg_it = template_id->template_argument_list; arg_it; arg_it = arg_it->next) { + accept(arg_it->value); } } } @@ -332,9 +331,9 @@ bool FindUsages::visit(QualifiedNameAST *ast) if (template_id) { identifier_token = template_id->identifier_token; - for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; + for (TemplateArgumentListAST *template_arguments = template_id->template_argument_list; template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); + accept(template_arguments->value); } } } @@ -392,9 +391,9 @@ bool FindUsages::visit(TemplateIdAST *ast) reportResult(ast->identifier_token, candidates); } - for (TemplateArgumentListAST *template_arguments = ast->template_arguments; + for (TemplateArgumentListAST *template_arguments = ast->template_argument_list; template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); + accept(template_arguments->value); } return false; @@ -402,24 +401,24 @@ bool FindUsages::visit(TemplateIdAST *ast) bool FindUsages::visit(ParameterDeclarationAST *ast) { - for (SpecifierAST *spec = ast->type_specifier; spec; spec = spec->next) - accept(spec); + for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) + accept(it->value); if (DeclaratorAST *declarator = ast->declarator) { - for (SpecifierAST *attr = declarator->attributes; attr; attr = attr->next) - accept(attr); + for (SpecifierListAST *it = declarator->attribute_list; it; it = it->next) + accept(it->value); - for (PtrOperatorAST *ptr_op = declarator->ptr_operators; ptr_op; ptr_op = ptr_op->next) - accept(ptr_op); + for (PtrOperatorListAST *it = declarator->ptr_operator_list; it; it = it->next) + accept(it->value); if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration. accept(declarator->core_declarator); - for (PostfixDeclaratorAST *fx_op = declarator->postfix_declarators; fx_op; fx_op = fx_op->next) - accept(fx_op); + for (PostfixDeclaratorListAST *it = declarator->postfix_declarator_list; it; it = it->next) + accept(it->value); - for (SpecifierAST *spec = declarator->post_attributes; spec; spec = spec->next) - accept(spec); + for (SpecifierListAST *it = declarator->post_attribute_list; it; it = it->next) + accept(it->value); accept(declarator->initializer); } @@ -438,8 +437,8 @@ bool FindUsages::visit(FunctionDeclaratorAST *ast) { accept(ast->parameters); - for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next) - accept(spec); + for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) + accept(it->value); accept(ast->exception_specification); diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 4d3ed93275..653d86b0d0 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -89,8 +89,10 @@ bool LookupContext::maybeValidSymbol(Symbol *symbol, ResolveMode mode, const QList<Symbol *> &candidates) { - if (((mode & ResolveNamespace) && symbol->isNamespace()) || - ((mode & ResolveClass) && symbol->isClass()) || + if (((mode & ResolveNamespace) && symbol->isNamespace()) || + ((mode & ResolveClass) && symbol->isClass()) || + ((mode & ResolveObjCClass) && symbol->isObjCClass()) || + ((mode & ResolveObjCProtocol) && symbol->isObjCProtocol()) || (mode & ResolveSymbol)) { return ! candidates.contains(symbol); } @@ -527,6 +529,69 @@ void LookupContext::expandObjCMethod(ObjCMethod *method, expandedScopes->append(method->arguments()); } +void LookupContext::expandObjCClass(ObjCClass *klass, + const QList<Scope *> &visibleScopes, + QList<Scope *> *expandedScopes) const +{ + {// expand other @interfaces, @implementations and categories for this class: + const QList<Symbol *> classList = resolveObjCClass(klass->name(), visibleScopes); + foreach (Symbol *otherClass, classList) { + if (otherClass == klass) + continue; + expand(otherClass->asObjCClass()->members(), visibleScopes, expandedScopes); + } + } + + // expand definitions in the currect class: + for (unsigned i = 0; i < klass->memberCount(); ++i) { + Symbol *symbol = klass->memberAt(i); + if (Class *nestedClass = symbol->asClass()) { + if (! nestedClass->name()) { + expand(nestedClass->members(), visibleScopes, expandedScopes); + } + } else if (Enum *e = symbol->asEnum()) { + expand(e->members(), visibleScopes, expandedScopes); + } + } + + // expand the base class: + if (ObjCBaseClass *baseClass = klass->baseClass()) { + Name *baseClassName = baseClass->name(); + const QList<Symbol *> baseClassCandidates = resolveObjCClass(baseClassName, + visibleScopes); + + for (int j = 0; j < baseClassCandidates.size(); ++j) { + if (ObjCClass *baseClassSymbol = baseClassCandidates.at(j)->asObjCClass()) + expand(baseClassSymbol->members(), visibleScopes, expandedScopes); + } + } + + // expand the protocols: + for (unsigned i = 0; i < klass->protocolCount(); ++i) { + Name *protocolName = klass->protocolAt(i)->name(); + const QList<Symbol *> protocolCandidates = resolveObjCProtocol(protocolName, visibleScopes); + for (int j = 0; j < protocolCandidates.size(); ++j) { + if (ObjCProtocol *protocolSymbol = protocolCandidates.at(j)->asObjCProtocol()) + expandObjCProtocol(protocolSymbol, visibleScopes, expandedScopes); + } + } +} + +void LookupContext::expandObjCProtocol(ObjCProtocol *protocol, const QList<Scope *> &visibleScopes, QList<Scope *> *expandedScopes) const +{ + // First expand the protocol itself + expand(protocol->members(), visibleScopes, expandedScopes); + + // Then do the same for any incorporated protocol + for (unsigned i = 0; i < protocol->protocolCount(); ++i) { + ObjCBaseProtocol *baseProtocol = protocol->protocolAt(i); + const QList<Symbol *> protocolList = resolveObjCProtocol(baseProtocol->name(), visibleScopes); + foreach (Symbol *symbol, protocolList) + if (ObjCProtocol *protocolSymbol = symbol->asObjCProtocol()) + expandObjCProtocol(protocolSymbol, visibleScopes, expandedScopes); + } +} + void LookupContext::expand(Scope *scope, const QList<Scope *> &visibleScopes, QList<Scope *> *expandedScopes) const @@ -546,6 +611,8 @@ void LookupContext::expand(Scope *scope, expandFunction(fun, visibleScopes, expandedScopes); } else if (ObjCMethod *meth = scope->owner()->asObjCMethod()) { expandObjCMethod(meth, visibleScopes, expandedScopes); + } else if (ObjCClass *objcKlass = scope->owner()->asObjCClass()) { + expandObjCClass(objcKlass, visibleScopes, expandedScopes); } } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index e9d84c83ae..6a69b3330b 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -75,12 +75,20 @@ public: QList<Symbol *> resolveClassOrNamespace(Name *name) const { return resolveClassOrNamespace(name, visibleScopes()); } + QList<Symbol *> resolveObjCClass(Name *name) const + { return resolveObjCClass(name, visibleScopes()); } + + QList<Symbol *> resolveObjCProtocol(Name *name) const + { return resolveObjCProtocol(name, visibleScopes()); } + enum ResolveMode { ResolveSymbol = 0x01, ResolveClass = 0x02, ResolveNamespace = 0x04, ResolveClassOrNamespace = ResolveClass | ResolveNamespace, - ResolveAll = ResolveSymbol | ResolveClassOrNamespace + ResolveObjCClass = 0x08, + ResolveObjCProtocol = 0x10, + ResolveAll = ResolveSymbol | ResolveClassOrNamespace | ResolveObjCClass | ResolveObjCProtocol }; QList<Symbol *> resolve(Name *name, const QList<Scope *> &visibleScopes, @@ -95,6 +103,12 @@ public: QList<Symbol *> resolveClassOrNamespace(Name *name, const QList<Scope *> &visibleScopes) const { return resolve(name, visibleScopes, ResolveClassOrNamespace); } + QList<Symbol *> resolveObjCClass(Name *name, const QList<Scope *> &visibleScopes) const + { return resolve(name, visibleScopes, ResolveObjCClass); } + + QList<Symbol *> resolveObjCProtocol(Name *name, const QList<Scope *> &visibleScopes) const + { return resolve(name, visibleScopes, ResolveObjCProtocol); } + QList<Scope *> visibleScopes() const { return _visibleScopes; } @@ -128,6 +142,14 @@ public: const QList<Scope *> &visibleScopes, QList<Scope *> *expandedScopes) const; + void expandObjCClass(ObjCClass *klass, + const QList<Scope *> &visibleScopes, + QList<Scope *> *expandedScopes) const; + + void expandObjCProtocol(ObjCProtocol *protocol, + const QList<Scope *> &visibleScopes, + QList<Scope *> *expandedScopes) const; + void expandEnumOrAnonymousSymbol(ScopedSymbol *scopedSymbol, QList<Scope *> *expandedScopes) const; diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 9333d064e9..ba6952e7bf 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -118,12 +118,6 @@ void ResolveExpression::addResult(const Result &r) QList<Scope *> ResolveExpression::visibleScopes(const Result &result) const { return _context.visibleScopes(result); } -bool ResolveExpression::visit(ExpressionListAST *) -{ - // nothing to do. - return false; -} - bool ResolveExpression::visit(BinaryExpressionAST *ast) { accept(ast->left_expression); @@ -176,8 +170,8 @@ bool ResolveExpression::visit(NewExpressionAST *ast) { if (ast->new_type_id) { Scope *scope = _context.expressionDocument()->globalSymbols(); - FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier, scope); - ty = sem.check(ast->new_type_id->ptr_operators, ty, scope); + FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, scope); + ty = sem.check(ast->new_type_id->ptr_operator_list, ty, scope); FullySpecifiedType ptrTy(control()->pointerType(ty)); addResult(ptrTy); } @@ -214,8 +208,8 @@ bool ResolveExpression::visit(PostfixExpressionAST *ast) { accept(ast->base_expression); - for (PostfixAST *fx = ast->postfix_expressions; fx; fx = fx->next) { - accept(fx); + for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next) { + accept(it->value); } return false; @@ -744,11 +738,67 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass, } +QList<ResolveExpression::Result> +ResolveExpression::resolveMember(Name *memberName, ObjCClass *klass) const +{ + QList<Result> results; + + if (!memberName || !klass) + return results; + + QList<Scope *> scopes; + _context.expand(klass->members(), _context.visibleScopes(), &scopes); + + QList<Symbol *> candidates = _context.resolve(memberName, scopes); + + foreach (Symbol *candidate, candidates) { + FullySpecifiedType ty = candidate->type(); + + results.append(Result(ty, candidate)); + } + + return removeDuplicates(results); +} + bool ResolveExpression::visit(PostIncrDecrAST *) { return false; } +bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) +{ + QList<Result> receiverResults = operator()(ast->receiver_expression); + + if (!receiverResults.isEmpty()) { + Result result = receiverResults.first(); + FullySpecifiedType ty = result.first.simplified(); + Name *klassName = 0; + + if (const ObjCClass *classTy = ty->asObjCClassType()) { + // static access, e.g.: + // [NSObject description]; + klassName = classTy->name(); + } else if (const PointerType *ptrTy = ty->asPointerType()) { + const FullySpecifiedType pointeeTy = ptrTy->elementType(); + if (pointeeTy && pointeeTy->isNamedType()) { + // dynamic access, e.g.: + // NSObject *obj = ...; [obj release]; + klassName = pointeeTy->asNamedType()->name(); + } + } + + if (klassName&&ast->selector && ast->selector->selector_name) { + ResolveObjCClass resolveObjCClass; + QList<Symbol *> resolvedSymbols = resolveObjCClass(klassName, result, _context); + foreach (Symbol *resolvedSymbol, resolvedSymbols) + if (ObjCClass *klass = resolvedSymbol->asObjCClass()) + _results.append(resolveMember(ast->selector->selector_name, klass)); + } + } + + return false; +} + //////////////////////////////////////////////////////////////////////////////// ResolveClass::ResolveClass() { } @@ -817,3 +867,35 @@ QList<Symbol *> ResolveClass::resolveClass(Name *name, return resolvedSymbols; } + +ResolveObjCClass::ResolveObjCClass() +{} + +QList<Symbol *> ResolveObjCClass::operator ()(Name *name, + const ResolveExpression::Result &p, + const LookupContext &context) +{ + QList<Symbol *> resolvedSymbols; + + const QList<Symbol *> candidates = + context.resolve(name, context.visibleScopes(p)); + + foreach (Symbol *candidate, candidates) { + if (ObjCClass *klass = candidate->asObjCClass()) { + if (resolvedSymbols.contains(klass)) + continue; // we already know about `klass' + resolvedSymbols.append(klass); + } else if (candidate->isTypedef()) { + if (Declaration *decl = candidate->asDeclaration()) { + if (decl->type()->isObjCClassType()) { + ObjCClass *klass = decl->type()->asObjCClassType(); + if (resolvedSymbols.contains(klass)) + continue; + resolvedSymbols.append(klass); + } + } + } + } + + return resolvedSymbols; +} diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h index 0e0b637c22..adda2716c3 100644 --- a/src/libs/cplusplus/ResolveExpression.h +++ b/src/libs/cplusplus/ResolveExpression.h @@ -61,6 +61,8 @@ public: QList<Result> resolveMember(Name *memberName, Class *klass, Name *className = 0) const; + QList<Result> resolveMember(Name *memberName, ObjCClass *klass) const; + protected: QList<Result> switchResults(const QList<Result> &symbols); @@ -72,7 +74,6 @@ protected: using ASTVisitor::visit; - virtual bool visit(ExpressionListAST *ast); virtual bool visit(BinaryExpressionAST *ast); virtual bool visit(CastExpressionAST *ast); virtual bool visit(ConditionAST *ast); @@ -110,6 +111,9 @@ protected: virtual bool visit(PostIncrDecrAST *ast); virtual bool visit(MemberAccessAST *ast); + // Objective-C expressions + virtual bool visit(ObjCMessageExpressionAST *ast); + QList<Scope *> visibleScopes(const Result &result) const; private: @@ -137,6 +141,16 @@ private: QList<ResolveExpression::Result> _blackList; }; +class CPLUSPLUS_EXPORT ResolveObjCClass +{ +public: + ResolveObjCClass(); + + QList<Symbol *> operator()(Name *name, + const ResolveExpression::Result &p, + const LookupContext &context); +}; + } // end of namespace CPlusPlus diff --git a/src/libs/cplusplus/SimpleLexer.cpp b/src/libs/cplusplus/SimpleLexer.cpp index 2934804f09..f9549d3ca1 100644 --- a/src/libs/cplusplus/SimpleLexer.cpp +++ b/src/libs/cplusplus/SimpleLexer.cpp @@ -27,6 +27,7 @@ ** **************************************************************************/ +#include "ObjectiveCTypeQualifiers.h" #include "SimpleLexer.h" #include <Lexer.h> @@ -83,7 +84,6 @@ SimpleLexer::SimpleLexer() _qtMocRunEnabled(true), _objCEnabled(false) { - setObjCEnabled(true); } SimpleLexer::~SimpleLexer() @@ -156,6 +156,9 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state) simpleTk.text() == QLatin1String("include")) lex.setScanAngleStringLiteralTokens(true); + if (_objCEnabled && tk.is(T_IDENTIFIER)) + simpleTk.f._objcTypeQualifier = (classifyObjectiveCTypeQualifiers(firstChar + tk.offset, tk.f.length) != Token_identifier); + tokens.append(simpleTk); } diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h index 0775eccb1c..c9b831a1d0 100644 --- a/src/libs/cplusplus/SimpleLexer.h +++ b/src/libs/cplusplus/SimpleLexer.h @@ -83,6 +83,7 @@ public: bool isKeyword() const; bool isComment() const; bool isObjCAtKeyword() const; + bool isObjCTypeQualifier() const { return f._objcTypeQualifier; } const char *name() const; @@ -102,6 +103,7 @@ public: struct { short _newline: 1; short _whitespace: 1; + short _objcTypeQualifier: 1; } f; }; diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 11f52f2eda..e60dece350 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -34,6 +34,7 @@ #include "iplugin_p.h" #include "pluginmanager.h" +#include <QtCore/QDir> #include <QtCore/QFile> #include <QtCore/QFileInfo> #include <QtCore/QXmlStreamReader> @@ -787,7 +788,8 @@ bool PluginSpecPrivate::loadLibrary() PluginLoader loader(libName); if (!loader.load()) { hasError = true; - errorString = libName + QString::fromLatin1(": ") + loader.errorString(); + errorString = QDir::toNativeSeparators(libName) + + QString::fromLatin1(": ") + loader.errorString(); return false; } IPlugin *pluginObject = qobject_cast<IPlugin*>(loader.instance()); diff --git a/src/libs/utils/detailswidget.cpp b/src/libs/utils/detailswidget.cpp index 00be0f70f2..b0b9db7724 100644 --- a/src/libs/utils/detailswidget.cpp +++ b/src/libs/utils/detailswidget.cpp @@ -154,6 +154,13 @@ QWidget *DetailsWidget::toolWidget() const return m_toolWidget; } +// This function works around a qt limitation. +// In a deeply nested widget structure, nested layouts +// tell their parents per a delayed invocation that they +// need to repaint. Thus hiding a widget triggers +// one relayout (and repaint) for each level of widget +// nesting. We circumvent that, by forcing a update() +// activate() on the widget after hiding. void DetailsWidget::fixUpLayout() { if (!m_widget) diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp index 4e7d31c3fc..ecb5b389f5 100644 --- a/src/libs/utils/winutils.cpp +++ b/src/libs/utils/winutils.cpp @@ -55,6 +55,17 @@ QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error) return rc; } + +static inline QString msgCannotLoad(const char *lib, const QString &why) +{ + return QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(lib), why); +} + +static inline QString msgCannotResolve(const char *lib) +{ + return QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(lib)); +} + QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, const QString &name, QString *errorMessage) @@ -67,7 +78,7 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, const char *versionDLLC = "version.dll"; QLibrary versionLib(QLatin1String(versionDLLC), 0); if (!versionLib.load()) { - *errorMessage = QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(versionDLLC), versionLib.errorString()); + *errorMessage = msgCannotLoad(versionDLLC, versionLib.errorString()); return QString(); } // MinGW requires old-style casts @@ -75,7 +86,7 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, GetFileVersionInfoWProtoType getFileVersionInfoW = (GetFileVersionInfoWProtoType)(versionLib.resolve("GetFileVersionInfoW")); VerQueryValueWProtoType verQueryValueW = (VerQueryValueWProtoType)(versionLib.resolve("VerQueryValueW")); if (!getFileVersionInfoSizeW || !getFileVersionInfoW || !verQueryValueW) { - *errorMessage = QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(versionDLLC)); + *errorMessage = msgCannotResolve(versionDLLC); return QString(); } @@ -111,4 +122,37 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, return rc; } +QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name, QString *errorMessage) +{ + typedef DWORD (APIENTRY *GetShortPathNameProtoType)(LPCTSTR, LPTSTR, DWORD); + + if (name.isEmpty()) + return name; + + const char *kernel32DLLC = "kernel32.dll"; + + QLibrary kernel32Lib(kernel32DLLC, 0); + if (!kernel32Lib.isLoaded() && !kernel32Lib.load()) { + *errorMessage = msgCannotLoad(kernel32DLLC, kernel32Lib.errorString()); + return QString(); + } + + // MinGW requires old-style casts + GetShortPathNameProtoType getShortPathNameW = (GetShortPathNameProtoType)(kernel32Lib.resolve("GetShortPathNameW")); + if (!getShortPathNameW) { + *errorMessage = msgCannotResolve(kernel32DLLC); + return QString(); + } + // Determine length, then convert. + const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGW + const DWORD length = (*getShortPathNameW)(nameC, NULL, 0); + if (length == 0) + return name; + TCHAR *buffer = new TCHAR[length]; + (*getShortPathNameW)(nameC, buffer, length); + const QString rc = QString::fromUtf16(reinterpret_cast<const ushort *>(buffer), length); + delete [] buffer; + return rc; +} + } // namespace Utils diff --git a/src/libs/utils/winutils.h b/src/libs/utils/winutils.h index 8a73961ce3..12dea87fc8 100644 --- a/src/libs/utils/winutils.h +++ b/src/libs/utils/winutils.h @@ -47,5 +47,10 @@ enum WinDLLVersionType { WinDLLFileVersion, WinDLLProductVersion }; QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, const QString &name, QString *errorMessage); + +// Return the short (8.3) file name +QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name, + QString *errorMessage); + } // namespace Utils #endif // WINUTILS_H diff --git a/src/plugins/bineditor/BinEditor.pluginspec b/src/plugins/bineditor/BinEditor.pluginspec index 9e857208f4..76f17ee19e 100644 --- a/src/plugins/bineditor/BinEditor.pluginspec +++ b/src/plugins/bineditor/BinEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="BinEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="BinEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,7 +19,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Binary editor component.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/bookmarks/Bookmarks.pluginspec b/src/plugins/bookmarks/Bookmarks.pluginspec index 387d0f878c..b730c65312 100644 --- a/src/plugins/bookmarks/Bookmarks.pluginspec +++ b/src/plugins/bookmarks/Bookmarks.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Bookmarks" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Bookmarks" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Bookmarks in text editors.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec index 9fdc870109..e8ab42f731 100644 --- a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec +++ b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec @@ -1,4 +1,4 @@ -<plugin name="CMakeProjectManager" version="1.3.0" compatVersion="1.3.0"> +<plugin name="CMakeProjectManager" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>CMake support</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="CppTools" version="1.3.0"/> - <dependency name="CppEditor" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> + <dependency name="CppEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index a799cf7265..883e1451dd 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -394,7 +394,7 @@ QString CMakeProject::buildParser(BuildConfiguration *configuration) const if (!m_toolChain) return QString::null; if (m_toolChain->type() == ProjectExplorer::ToolChain::GCC - || m_toolChain->type() == ProjectExplorer::ToolChain::LinuxICC + //|| m_toolChain->type() == ProjectExplorer::ToolChain::LinuxICC || m_toolChain->type() == ProjectExplorer::ToolChain::MinGW) { return ProjectExplorer::Constants::BUILD_PARSER_GCC; } else if (m_toolChain->type() == ProjectExplorer::ToolChain::MSVC diff --git a/src/plugins/coreplugin/Core.pluginspec b/src/plugins/coreplugin/Core.pluginspec index 4da75e3997..d615d59dba 100644 --- a/src/plugins/coreplugin/Core.pluginspec +++ b/src/plugins/coreplugin/Core.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Core" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Core" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index 5db89731a0..a803affd71 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -35,7 +35,7 @@ namespace Constants { #define IDE_VERSION_MAJOR 1 #define IDE_VERSION_MINOR 3 -#define IDE_VERSION_RELEASE 0 +#define IDE_VERSION_RELEASE 80 #define STRINGIFY_INTERNAL(x) #x #define STRINGIFY(x) STRINGIFY_INTERNAL(x) diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index be053c171f..bcb75b6dc7 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -136,6 +136,14 @@ QSize FancyToolButton::minimumSizeHint() const return QSize(8, 8); } +void FancyToolButton::actionChanged() +{ + // the default action changed in some way, e.g. it might got hidden + // since we inherit a tool button we won't get invisible, so do this here + if (QAction* action = defaultAction()) + setVisible(action->isVisible()); +} + FancyActionBar::FancyActionBar(QWidget *parent) : QWidget(parent) { @@ -152,6 +160,8 @@ void FancyActionBar::insertAction(int index, QAction *action, QMenu *menu) { FancyToolButton *toolButton = new FancyToolButton(this); toolButton->setDefaultAction(action); + connect(action, SIGNAL(changed()), toolButton, SLOT(actionChanged())); + if (menu) { toolButton->setMenu(menu); toolButton->setPopupMode(QToolButton::DelayedPopup); diff --git a/src/plugins/coreplugin/fancyactionbar.h b/src/plugins/coreplugin/fancyactionbar.h index 4c49f61c5b..0f4f853e3a 100644 --- a/src/plugins/coreplugin/fancyactionbar.h +++ b/src/plugins/coreplugin/fancyactionbar.h @@ -43,6 +43,8 @@ namespace Internal { class FancyToolButton : public QToolButton { + Q_OBJECT + public: FancyToolButton(QWidget *parent = 0); @@ -50,6 +52,9 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; +private slots: + void actionChanged(); + private: const QMap<QString, QPicture> &m_buttonElements; }; diff --git a/src/plugins/cpaster/CodePaster.pluginspec b/src/plugins/cpaster/CodePaster.pluginspec index 595b93ef31..bcdeeac1e8 100644 --- a/src/plugins/cpaster/CodePaster.pluginspec +++ b/src/plugins/cpaster/CodePaster.pluginspec @@ -1,4 +1,4 @@ -<plugin name="CodePaster" version="1.3.0" compatVersion="1.3.0"> +<plugin name="CodePaster" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Codepaster plugin for pushing/fetching diff from server</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/cppeditor/CppEditor.pluginspec b/src/plugins/cppeditor/CppEditor.pluginspec index d9d308a237..47ddc69810 100644 --- a/src/plugins/cppeditor/CppEditor.pluginspec +++ b/src/plugins/cppeditor/CppEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="CppEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="CppEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>C/C++ editor component.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="CppTools" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 53a471bae0..1bbbf5a12b 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -239,8 +239,8 @@ protected: return; else if (TemplateIdAST *template_id = name->asTemplateId()) { - for (TemplateArgumentListAST *it = template_id->template_arguments; it; it = it->next) { - accept(it->template_argument); + for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) { + accept(it->value); } } } @@ -276,8 +276,8 @@ protected: virtual bool visit(TemplateIdAST *ast) { - for (TemplateArgumentListAST *arg = ast->template_arguments; arg; arg = arg->next) - accept(arg->template_argument); + for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next) + accept(arg->value); unsigned line, column; getTokenStartPosition(ast->firstToken(), &line, &column); @@ -308,8 +308,8 @@ protected: virtual bool visit(QualifiedNameAST *ast) { - for (NestedNameSpecifierAST *it = ast->nested_name_specifier; it; it = it->next) - searchUsesInTemplateArguments(it->class_or_namespace_name); + for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) + searchUsesInTemplateArguments(it->value->class_or_namespace_name); searchUsesInTemplateArguments(ast->unqualified_name); return false; @@ -318,10 +318,11 @@ protected: virtual bool visit(PostfixExpressionAST *ast) { accept(ast->base_expression); - for (PostfixAST *it = ast->postfix_expressions; it; it = it->next) { - if (it->asMemberAccess() != 0) + for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next) { + PostfixAST *fx = it->value; + if (fx->asMemberAccess() != 0) continue; // skip members - accept(it); + accept(fx); } return false; } @@ -365,8 +366,8 @@ protected: { accept(ast->parameters); - for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next) - accept(spec); + for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) + accept(it->value); accept(ast->exception_specification); @@ -438,7 +439,7 @@ public: if (ast) { if (ast->declarator) { _visitFunctionDeclarator = true; - accept(ast->declarator->postfix_declarators); + accept(ast->declarator->postfix_declarator_list); } _visitFunctionDeclarator = false; diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index b2db7a8e42..00f307f7e0 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -61,6 +61,7 @@ void CppHighlighter::highlightBlock(const QString &text) SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); + tokenize.setObjCEnabled(true); int initialState = state; const QList<SimpleToken> tokens = tokenize(text, initialState); @@ -157,7 +158,7 @@ void CppHighlighter::highlightBlock(const QString &text) initialState = 0; } - } else if (tk.isKeyword() || isQtKeyword(tk.text()) || tk.isObjCAtKeyword()) + } else if (tk.isKeyword() || isQtKeyword(tk.text()) || tk.isObjCAtKeyword() || tk.isObjCTypeQualifier()) setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]); else if (tk.isOperator()) diff --git a/src/plugins/cpptools/CppTools.pluginspec b/src/plugins/cpptools/CppTools.pluginspec index 16501b9347..5ffdb91cad 100644 --- a/src/plugins/cpptools/CppTools.pluginspec +++ b/src/plugins/cpptools/CppTools.pluginspec @@ -1,4 +1,4 @@ -<plugin name="CppTools" version="1.3.0" compatVersion="1.3.0"> +<plugin name="CppTools" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Tools for analyzing C/C++ code.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Locator" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Locator" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index b27bfcf7af..12d846b774 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -30,6 +30,7 @@ #include "cppcodecompletion.h" #include "cppmodelmanager.h" #include "cppdoxygen.h" +#include "cpptoolsconstants.h" #include "cpptoolseditorsupport.h" #include <Control.h> @@ -53,6 +54,7 @@ #include <cplusplus/TokenUnderCursor.h> #include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> #include <coreplugin/editormanager/editormanager.h> #include <texteditor/itexteditor.h> #include <texteditor/itexteditable.h> @@ -523,7 +525,8 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager) m_autoInsertBrackets(true), m_partialCompletionEnabled(true), m_forcedCompletion(false), - m_completionOperator(T_EOF_SYMBOL) + m_completionOperator(T_EOF_SYMBOL), + m_objcEnabled(true) { } @@ -1069,8 +1072,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpressi if (doc->parse(Document::ParseDeclaration)) { doc->check(); if (SimpleDeclarationAST *sd = doc->translationUnit()->ast()->asSimpleDeclaration()) { - if (sd->declarators->declarator->postfix_declarators - && sd->declarators->declarator->postfix_declarators->asFunctionDeclarator()) { + if (sd->declarator_list && sd->declarator_list->value->postfix_declarator_list + && sd->declarator_list->value->postfix_declarator_list->value->asFunctionDeclarator()) { autocompleteSignature = true; } } @@ -1184,8 +1187,12 @@ bool CppCodeCompletion::completeScope(const QList<TypeOfExpression::Result> &res void CppCodeCompletion::addKeywords() { + int keywordLimit = T_FIRST_OBJC_AT_KEYWORD; + if (objcKeywordsWanted()) + keywordLimit = T_LAST_OBJC_AT_KEYWORD + 1; + // keyword completion items. - for (int i = T_FIRST_KEYWORD; i < T_FIRST_OBJC_AT_KEYWORD; ++i) { + for (int i = T_FIRST_KEYWORD; i < keywordLimit; ++i) { TextEditor::CompletionItem item(this); item.text = QLatin1String(Token::name(i)); item.icon = m_icons.keywordIcon(); @@ -1651,4 +1658,16 @@ int CppCodeCompletion::findStartOfName(int pos) const return pos + 1; } +bool CppCodeCompletion::objcKeywordsWanted() const +{ + if (!m_objcEnabled) + return false; + + Core::IFile *file = m_editor->file(); + QString fileName = file->fileName(); + + const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase(); + return mdb->findByFile(fileName).type() == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE; +} + #include "cppcodecompletion.moc" diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h index ad77070754..cbf9322059 100644 --- a/src/plugins/cpptools/cppcodecompletion.h +++ b/src/plugins/cpptools/cppcodecompletion.h @@ -82,6 +82,9 @@ class CppCodeCompletion : public TextEditor::ICompletionCollector public: explicit CppCodeCompletion(CppModelManager *manager); + void setObjcEnabled(bool objcEnabled) + { m_objcEnabled = objcEnabled; } + bool supportsEditor(TextEditor::ITextEditable *editor); bool triggersCompletion(TextEditor::ITextEditable *editor); int startCompletion(TextEditor::ITextEditable *editor); @@ -147,6 +150,8 @@ private: int findStartOfName(int pos = -1) const; private: + bool objcKeywordsWanted() const; + CppModelManager *m_manager; TextEditor::ITextEditable *m_editor; int m_startPosition; // Position of the cursor from which completion started @@ -156,11 +161,13 @@ private: bool m_partialCompletionEnabled; bool m_forcedCompletion; unsigned m_completionOperator; + bool m_objcEnabled; CPlusPlus::Icons m_icons; CPlusPlus::Overview overview; CPlusPlus::TypeOfExpression typeOfExpression; QPointer<FunctionArgumentWidget> m_functionArgumentWidget; + QList<TextEditor::CompletionItem> m_completions; }; diff --git a/src/plugins/cvs/CVS.pluginspec b/src/plugins/cvs/CVS.pluginspec index c585278375..968225dd46 100644 --- a/src/plugins/cvs/CVS.pluginspec +++ b/src/plugins/cvs/CVS.pluginspec @@ -1,4 +1,4 @@ -<plugin name="CVS" version="1.3.0" compatVersion="1.3.0"> +<plugin name="CVS" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>CVS integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> - <dependency name="VCSBase" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="VCSBase" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec index 6addf1113f..0d0e35f82c 100644 --- a/src/plugins/debugger/Debugger.pluginspec +++ b/src/plugins/debugger/Debugger.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Debugger" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Debugger" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,10 +19,10 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Debugger integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="CppEditor" version="1.3.0"/><!-- Debugger plugin adds items to the editor's context menu --> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> - <dependency name="Find" version="1.3.0"/> + <dependency name="CppEditor" version="1.3.80"/><!-- Debugger plugin adds items to the editor's context menu --> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="Find" version="1.3.80"/> </dependencyList> <argumentList> <argument name="-disable-cdb">Disable Cdb debugger engine</argument> diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 204be58845..380852c7b4 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -454,6 +454,16 @@ bool StartRemoteDialog::useServerStartScript() const return m_ui->useServerStartScriptCheckBox->isChecked(); } +void StartRemoteDialog::setSysroot(const QString &sysroot) +{ + m_ui->sysrootPathChooser->setPath(sysroot); +} + +const QString StartRemoteDialog::sysroot() const +{ + return m_ui->sysrootPathChooser->path(); +} + void StartRemoteDialog::updateState() { bool enabled = m_ui->useServerStartScriptCheckBox->isChecked(); diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index a70fe106b1..03c323259a 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -140,6 +140,8 @@ public: QString serverStartScript() const; void setUseServerStartScript(bool on); bool useServerStartScript() const; + void setSysroot(const QString &sysroot); + const QString sysroot() const; private slots: void updateState(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f14d10723e..62139d7d48 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -225,20 +225,7 @@ DebuggerStartParameters::DebuggerStartParameters() void DebuggerStartParameters::clear() { - executable.clear(); - coreFile.clear(); - processArgs.clear(); - environment.clear(); - workingDir.clear(); - buildDir.clear(); - attachPID = -1; - useTerminal = false; - crashParameter.clear(); - remoteChannel.clear(); - remoteArchitecture.clear(); - serverStartScript.clear(); - toolChainType = ProjectExplorer::ToolChain::UNKNOWN; - startMode = NoStartMode; + *this = DebuggerStartParameters(); } @@ -861,7 +848,7 @@ static IDebuggerEngine *debuggerEngineForToolChain(ProjectExplorer::ToolChain::T { IDebuggerEngine *rc = 0; switch (tc) { - case ProjectExplorer::ToolChain::LinuxICC: + //case ProjectExplorer::ToolChain::LinuxICC: case ProjectExplorer::ToolChain::MinGW: case ProjectExplorer::ToolChain::GCC: rc = gdbEngine; @@ -1739,7 +1726,7 @@ bool DebuggerManager::checkDebugConfiguration(int toolChain, bool success = true; switch(toolChain) { case ProjectExplorer::ToolChain::GCC: - case ProjectExplorer::ToolChain::LinuxICC: + //case ProjectExplorer::ToolChain::LinuxICC: case ProjectExplorer::ToolChain::MinGW: case ProjectExplorer::ToolChain::WINCE: // S60 case ProjectExplorer::ToolChain::WINSCW: diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 05639618b2..bcc21ba4b8 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -117,7 +117,10 @@ public: QString remoteArchitecture; QString symbolFileName; QString serverStartScript; + QString sysRoot; + QString debuggerCommand; int toolChainType; + QString remoteDumperLib; QString qtInstallPath; QString dumperLibrary; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 9cbf5d3c64..9243f88ce6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -510,6 +510,7 @@ void DebuggerPlugin::shutdown() delete m_locationMark; m_locationMark = 0; + removeObject(m_manager); delete m_manager; m_manager = 0; } @@ -604,6 +605,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess } m_manager = new DebuggerManager; + ExtensionSystem::PluginManager::instance()->addObject(m_manager); const QList<Core::IOptionsPage *> engineOptionPages = m_manager->initializeEngines(m_cmdLineEnabledEngines); @@ -1233,15 +1235,6 @@ void DebuggerPlugin::showSettingsDialog() QLatin1String(Debugger::Constants::DEBUGGER_COMMON_SETTINGS_PAGE)); } -static RunConfigurationPtr activeRunConfiguration() -{ - ProjectExplorer::Project *project = - ProjectExplorerPlugin::instance()->currentProject(); - if (project) - return project->activeRunConfiguration(); - return RunConfigurationPtr(); -} - void DebuggerPlugin::startExternalApplication() { const DebuggerStartParametersPtr sp(new DebuggerStartParameters); @@ -1265,13 +1258,8 @@ void DebuggerPlugin::startExternalApplication() if (dlg.breakAtMain()) m_manager->breakByFunctionMain(); - RunConfigurationPtr rc = activeRunConfiguration(); - if (rc.isNull()) - rc = DebuggerRunControlFactory::createDefaultRunConfiguration(sp->executable); - - if (RunControl *runControl = m_debuggerRunControlFactory - ->create(rc, ProjectExplorer::Constants::DEBUGMODE, sp)) - runControl->start(); + if (RunControl *runControl = m_debuggerRunControlFactory->create(sp, ProjectExplorer::Constants::DEBUGMODE)) + ProjectExplorerPlugin::instance()->startRunControl(runControl, ProjectExplorer::Constants::DEBUGMODE); } void DebuggerPlugin::attachExternalApplication() @@ -1291,12 +1279,8 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP sp->attachPID = pid; sp->crashParameter = crashParameter; sp->startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal; - RunConfigurationPtr rc = activeRunConfiguration(); - if (rc.isNull()) - rc = DebuggerRunControlFactory::createDefaultRunConfiguration(); - if (RunControl *runControl = m_debuggerRunControlFactory - ->create(rc, ProjectExplorer::Constants::DEBUGMODE, sp)) - runControl->start(); + if (RunControl *runControl = m_debuggerRunControlFactory->create(sp, ProjectExplorer::Constants::DEBUGMODE)) + ProjectExplorerPlugin::instance()->startRunControl(runControl, ProjectExplorer::Constants::DEBUGMODE); } void DebuggerPlugin::attachCmdLineCore() @@ -1327,12 +1311,9 @@ void DebuggerPlugin::attachCore(const QString &core, const QString &exe) sp->executable = exe; sp->coreFile = core; sp->startMode = AttachCore; - RunConfigurationPtr rc = activeRunConfiguration(); - if (rc.isNull()) - rc = DebuggerRunControlFactory::createDefaultRunConfiguration(); if (RunControl *runControl = m_debuggerRunControlFactory - ->create(rc, ProjectExplorer::Constants::DEBUGMODE, sp)) - runControl->start(); + ->create(sp, ProjectExplorer::Constants::DEBUGMODE)) + ProjectExplorerPlugin::instance()->startRunControl(runControl, ProjectExplorer::Constants::DEBUGMODE); } void DebuggerPlugin::startRemoteApplication() @@ -1351,24 +1332,23 @@ void DebuggerPlugin::startRemoteApplication() configValue(_("LastServerStartScript")).toString()); dlg.setUseServerStartScript( configValue(_("LastUseServerStartScript")).toBool()); + dlg.setSysroot(configValue(_("LastSysroot")).toString()); if (dlg.exec() != QDialog::Accepted) return; setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel()); setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture()); setConfigValue(_("LastServerStartScript"), dlg.serverStartScript()); setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript()); + setConfigValue(_("LastSysroot"), dlg.sysroot()); sp->remoteChannel = dlg.remoteChannel(); sp->remoteArchitecture = dlg.remoteArchitecture(); sp->startMode = StartRemote; if (dlg.useServerStartScript()) sp->serverStartScript = dlg.serverStartScript(); + sp->sysRoot = dlg.sysroot(); - RunConfigurationPtr rc = activeRunConfiguration(); - if (rc.isNull()) - rc = DebuggerRunControlFactory::createDefaultRunConfiguration(); - if (RunControl *runControl = m_debuggerRunControlFactory - ->create(rc, ProjectExplorer::Constants::DEBUGMODE, sp)) - runControl->start(); + if (RunControl *runControl = m_debuggerRunControlFactory->create(sp, ProjectExplorer::Constants::DEBUGMODE)) + ProjectExplorerPlugin::instance()->startRunControl(runControl, ProjectExplorer::Constants::DEBUGMODE); } #include "debuggerplugin.moc" diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 64b9f310f8..796684a5ad 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -52,12 +52,6 @@ using ProjectExplorer::RunConfiguration; using ProjectExplorer::RunControl; using ProjectExplorer::LocalApplicationRunConfiguration; -DefaultLocalApplicationRunConfiguration::DefaultLocalApplicationRunConfiguration(const QString &executable) : - ProjectExplorer::LocalApplicationRunConfiguration(0), - m_executable(executable) -{ -} - //////////////////////////////////////////////////////////////////////// // // DebuggerRunControlFactory @@ -80,28 +74,19 @@ QString DebuggerRunControlFactory::displayName() const return tr("Debug"); } -RunConfigurationPtr DebuggerRunControlFactory::createDefaultRunConfiguration(const QString &executable) +RunControl *DebuggerRunControlFactory::create(const DebuggerStartParametersPtr &sp, const QString &mode) { - return RunConfigurationPtr(new DefaultLocalApplicationRunConfiguration(executable)); + return new DebuggerRunControl(m_manager, sp); } RunControl *DebuggerRunControlFactory::create(const RunConfigurationPtr &runConfiguration, - const QString &mode, - const DebuggerStartParametersPtr &sp) + const QString &mode) { QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0); LocalApplicationRunConfigurationPtr rc = runConfiguration.objectCast<LocalApplicationRunConfiguration>(); QTC_ASSERT(!rc.isNull(), return 0); - return new DebuggerRunControl(m_manager, sp, rc); -} - -RunControl *DebuggerRunControlFactory::create(const RunConfigurationPtr &runConfiguration, - const QString &mode) -{ - const DebuggerStartParametersPtr sp(new DebuggerStartParameters); - sp->startMode = StartInternal; - return create(runConfiguration, mode, sp); + return new DebuggerRunControl(m_manager, rc); } QWidget *DebuggerRunControlFactory::configurationWidget(const RunConfigurationPtr &runConfiguration) @@ -121,38 +106,22 @@ QWidget *DebuggerRunControlFactory::configurationWidget(const RunConfigurationPt DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, - const DebuggerStartParametersPtr &startParameters, QSharedPointer<LocalApplicationRunConfiguration> runConfiguration) : RunControl(runConfiguration), - m_startParameters(startParameters), + m_startParameters(new DebuggerStartParameters()), m_manager(manager), m_running(false) { - connect(m_manager, SIGNAL(debuggingFinished()), - this, SLOT(debuggingFinished()), - Qt::QueuedConnection); - connect(m_manager, SIGNAL(applicationOutputAvailable(QString)), - this, SLOT(slotAddToOutputWindowInline(QString)), - Qt::QueuedConnection); - connect(m_manager, SIGNAL(inferiorPidChanged(qint64)), - this, SLOT(bringApplicationToForeground(qint64)), - Qt::QueuedConnection); - connect(this, SIGNAL(stopRequested()), - m_manager, SLOT(exitDebugger())); - + init(); if (!runConfiguration) return; - // Enhance parameters by info from the project, but do not clobber - // arguments given in the dialogs - if (m_startParameters->executable.isEmpty()) - m_startParameters->executable = runConfiguration->executable(); - if (m_startParameters->environment.empty()) - m_startParameters->environment = runConfiguration->environment().toStringList(); - if (m_startParameters->workingDir.isEmpty()) - m_startParameters->workingDir = runConfiguration->workingDirectory(); - if (m_startParameters->startMode != StartExternal) - m_startParameters->processArgs = runConfiguration->commandLineArguments(); + m_startParameters->startMode = StartInternal; + m_startParameters->executable = runConfiguration->executable(); + m_startParameters->environment = runConfiguration->environment().toStringList(); + m_startParameters->workingDir = runConfiguration->workingDirectory(); + m_startParameters->processArgs = runConfiguration->commandLineArguments(); + switch (m_startParameters->toolChainType) { case ProjectExplorer::ToolChain::UNKNOWN: case ProjectExplorer::ToolChain::INVALID: @@ -188,6 +157,34 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, } +DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, const DebuggerStartParametersPtr &startParameters) + : RunControl(RunConfigurationPtr(0)), + m_startParameters(startParameters), + m_manager(manager), + m_running(false) +{ + init(); + + if (m_startParameters->environment.empty()) + m_startParameters->environment = ProjectExplorer::Environment::Environment().toStringList(); + m_startParameters->useTerminal = false; +} + +void DebuggerRunControl::init() +{ + connect(m_manager, SIGNAL(debuggingFinished()), + this, SLOT(debuggingFinished()), + Qt::QueuedConnection); + connect(m_manager, SIGNAL(applicationOutputAvailable(QString)), + this, SLOT(slotAddToOutputWindowInline(QString)), + Qt::QueuedConnection); + connect(m_manager, SIGNAL(inferiorPidChanged(qint64)), + this, SLOT(bringApplicationToForeground(qint64)), + Qt::QueuedConnection); + connect(this, SIGNAL(stopRequested()), + m_manager, SLOT(exitDebugger())); +} + void DebuggerRunControl::start() { m_running = true; diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h index 196d7ee123..641ec41467 100644 --- a/src/plugins/debugger/debuggerrunner.h +++ b/src/plugins/debugger/debuggerrunner.h @@ -67,11 +67,7 @@ public: virtual QWidget *configurationWidget(const RunConfigurationPtr &runConfiguration); - virtual ProjectExplorer::RunControl *create(const RunConfigurationPtr &runConfiguration, - const QString &mode, - const DebuggerStartParametersPtr &sp); - - static RunConfigurationPtr createDefaultRunConfiguration(const QString &executable = QString()); + ProjectExplorer::RunControl *create(const DebuggerStartParametersPtr &sp, const QString &mode); private: DebuggerStartParametersPtr m_startParameters; @@ -86,8 +82,8 @@ class DebuggerRunControl public: DebuggerRunControl(DebuggerManager *manager, - const DebuggerStartParametersPtr &startParamters, LocalApplicationRunConfigurationPtr runConfiguration); + DebuggerRunControl(DebuggerManager *manager, const DebuggerStartParametersPtr &startParameters); // ProjectExplorer::RunControl virtual void start(); @@ -104,36 +100,12 @@ private slots: void slotAddToOutputWindowInline(const QString &output); private: + void init(); DebuggerStartParametersPtr m_startParameters; DebuggerManager *m_manager; bool m_running; }; -// A default run configuration for external executables or attaching to -// running processes by id. -class DefaultLocalApplicationRunConfiguration - : public ProjectExplorer::LocalApplicationRunConfiguration -{ - Q_OBJECT -public: - explicit DefaultLocalApplicationRunConfiguration(const QString &executable = QString()); - - virtual QString executable() const { return m_executable; } - virtual RunMode runMode() const { return Gui; } - virtual QString workingDirectory() const { return QString(); } - virtual QStringList commandLineArguments() const { return QStringList(); } - virtual ProjectExplorer::Environment environment() const - { return ProjectExplorer::Environment(); } - virtual QString dumperLibrary() const { return QString(); } - virtual QStringList dumperLibraryLocations() const { return QStringList(); } - virtual ProjectExplorer::ToolChain::ToolChainType toolChainType() const - { return ProjectExplorer::ToolChain::UNKNOWN; } - virtual QWidget *configurationWidget() { return 0; } - -private: - const QString m_executable; -}; - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2c33f40e1d..1665061aad 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1095,6 +1095,14 @@ void GdbEngine::handleAqcuiredInferior() } #endif +#ifdef Q_OS_UNIX +# define STOP_SIGNAL "SIGINT" +# define CROSS_STOP_SIGNAL "SIGTRAP" +#else +# define STOP_SIGNAL "SIGTRAP" +# define CROSS_STOP_SIGNAL "SIGINT" +#endif + void GdbEngine::handleStopResponse(const GdbMi &data) { // This is gdb 7+'s initial *stopped in response to attach. @@ -1244,9 +1252,13 @@ void GdbEngine::handleStopResponse(const GdbMi &data) || m_debuggingHelperState == DebuggingHelperLoadTried; // Don't load helpers on stops triggered by signals unless it's // an intentional trap. - if (initHelpers && reason == "signal-received" - && data.findChild("signal-name").data() != "SIGTRAP") - initHelpers = false; + if (initHelpers && reason == "signal-received") { + QByteArray name = data.findChild("signal-name").data(); + if (name != STOP_SIGNAL + && (startParameters().startMode != StartRemote + || name != CROSS_STOP_SIGNAL)) + initHelpers = false; + } if (isSynchroneous()) initHelpers = false; if (initHelpers) { @@ -1279,9 +1291,11 @@ void GdbEngine::handleStop1(const GdbMi &data) if (reason == "signal-received" && theDebuggerBoolSetting(UseMessageBoxForSignals)) { QByteArray name = data.findChild("signal-name").data(); - // Ignore SIGTRAP as they are showing up regularily when + // Ignore these as they are showing up regularly when // stopping debugging. - if (name != "SIGTRAP") { + if (name != STOP_SIGNAL + && (startParameters().startMode != StartRemote + || name != CROSS_STOP_SIGNAL)) { QByteArray meaning = data.findChild("signal-meaning").data(); QString msg = tr("<p>The inferior stopped because it received a " "signal from the Operating System.<p>" @@ -3958,45 +3972,54 @@ void GdbEngine::tryLoadDebuggingHelpers() return; m_debuggingHelperState = DebuggingHelperLoadTried; - const QString lib = manager()->qtDumperLibraryName(); + const QString dlopenLib = + (startParameters().startMode == StartRemote) + ? startParameters().remoteDumperLib : manager()->qtDumperLibraryName(); #if defined(Q_OS_WIN) if (m_dumperInjectionLoad) { /// Launch asynchronous remote thread to load. SharedLibraryInjector injector(inferiorPid()); QString errorMessage; - if (injector.remoteInject(lib, false, &errorMessage)) { - debugMessage(_("Dumper injection loading triggered (%1)...").arg(lib)); + if (injector.remoteInject(dlopenLib, false, &errorMessage)) { + debugMessage(_("Dumper injection loading triggered (%1)..."). + arg(dlopenLib)); } else { - debugMessage(_("Dumper loading (%1) failed: %2").arg(lib, errorMessage)); + debugMessage(_("Dumper loading (%1) failed: %2"). + arg(dlopenLib, errorMessage)); + debugMessage(errorMessage); manager()->showQtDumperLibraryWarning(errorMessage); m_debuggingHelperState = DebuggingHelperUnavailable; return; } } else { - debugMessage(_("Loading dumpers via debugger call (%1)...").arg(lib)); + debugMessage(_("Loading dumpers via debugger call (%1)..."). + arg(dlopenLib)); postCommand(_("sharedlibrary .*")); // for LoadLibraryA //postCommand(_("handle SIGSEGV pass stop print")); //postCommand(_("set unwindonsignal off")); - postCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(lib) + _("\")"), + postCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(dlopenLib) + _("\")"), CB(handleDebuggingHelperSetup)); - postCommand(_("sharedlibrary ") + dotEscape(lib)); + postCommand(_("sharedlibrary ") + dotEscape(dlopenLib)); } #elif defined(Q_OS_MAC) //postCommand(_("sharedlibrary libc")); // for malloc //postCommand(_("sharedlibrary libdl")); // for dlopen - postCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"), + postCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(dlopenLib) + + _("\", " STRINGIFY(RTLD_NOW) ")"), CB(handleDebuggingHelperSetup)); - //postCommand(_("sharedlibrary ") + dotEscape(lib)); + //postCommand(_("sharedlibrary ") + dotEscape(dlopenLib)); #else //postCommand(_("p dlopen")); postCommand(_("sharedlibrary libc")); // for malloc postCommand(_("sharedlibrary libdl")); // for dlopen - postCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"), + postCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(dlopenLib) + + _("\", " STRINGIFY(RTLD_NOW) ")"), CB(handleDebuggingHelperSetup)); // some older systems like CentOS 4.6 prefer this: - postCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"), + postCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(dlopenLib) + + _("\", " STRINGIFY(RTLD_NOW) ")"), CB(handleDebuggingHelperSetup)); - postCommand(_("sharedlibrary ") + dotEscape(lib)); + postCommand(_("sharedlibrary ") + dotEscape(dlopenLib)); #endif if (!m_dumperInjectionLoad) tryQueryDebuggingHelpers(); diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp index 4550359956..a18aba05b4 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp @@ -74,6 +74,7 @@ AbstractGdbAdapter::DumperHandling RemoteGdbAdapter::dumperHandling() const case ProjectExplorer::ToolChain::GCCE: case ProjectExplorer::ToolChain::RVCT_ARMV5: case ProjectExplorer::ToolChain::RVCT_ARMV6: + case ProjectExplorer::ToolChain::GCC_MAEMO: return DumperLoadedByGdb; default: break; @@ -97,7 +98,7 @@ void RemoteGdbAdapter::startAdapter() m_uploadProc.waitForStarted(); } - if (!m_engine->startGdb()) + if (!m_engine->startGdb(QStringList(), startParameters().debuggerCommand)) // FIXME: cleanup missing return; @@ -156,37 +157,28 @@ void RemoteGdbAdapter::startInferior() m_engine->postCommand(_("set architecture %1") .arg(startParameters().remoteArchitecture)); + m_engine->postCommand(_("set sysroot %1").arg(startParameters().sysRoot)); + m_engine->postCommand(_("set solib-search-path %1"). + arg(QFileInfo(startParameters().dumperLibrary).path())); if (!startParameters().processArgs.isEmpty()) m_engine->postCommand(_("-exec-arguments ") + startParameters().processArgs.join(_(" "))); -#if 0 m_engine->postCommand(_("set target-async on"), CB(handleSetTargetAsync)); -#else + QFileInfo fi(startParameters().executable); QString fileName = fi.absoluteFilePath(); m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), CB(handleFileExecAndSymbols)); -#endif } -#if 0 void RemoteGdbAdapter::handleSetTargetAsync(const GdbResponse &response) { QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); - if (response.resultClass == GdbResultDone) { - //qq->breakHandler()->setAllPending(); - QFileInfo fi(startParameters().executable); - QString fileName = fi.absoluteFilePath(); - m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), - CB(handleFileExecAndSymbols)); - } else { - QString msg = tr("Adapter too old: does not support asynchronous mode."); - emit inferiorStartFailed(msg); - } + if (response.resultClass == GdbResultError) + qDebug() << "Adapter too old: does not support asynchronous mode."; } -#endif void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) { diff --git a/src/plugins/debugger/gdb/remotegdbadapter.h b/src/plugins/debugger/gdb/remotegdbadapter.h index fd435caeab..dd960930f6 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.h +++ b/src/plugins/debugger/gdb/remotegdbadapter.h @@ -61,9 +61,7 @@ private: Q_SLOT void readUploadStandardError(); Q_SLOT void uploadProcError(QProcess::ProcessError error); -#if 0 void handleSetTargetAsync(const GdbResponse &response); -#endif void handleFileExecAndSymbols(const GdbResponse &response); void handleTargetRemote(const GdbResponse &response); diff --git a/src/plugins/debugger/procinterrupt.cpp b/src/plugins/debugger/procinterrupt.cpp index a65cdcb823..98d4232e25 100644 --- a/src/plugins/debugger/procinterrupt.cpp +++ b/src/plugins/debugger/procinterrupt.cpp @@ -61,7 +61,7 @@ bool Debugger::Internal::interruptProcess(int pID) bool Debugger::Internal::interruptProcess(int pID) { if (pID > 0) { - if (kill(pID, SIGTRAP) == 0) + if (kill(pID, SIGINT) == 0) return true; } return false; diff --git a/src/plugins/debugger/startremotedialog.ui b/src/plugins/debugger/startremotedialog.ui index 4bfc215190..5d596e17e7 100644 --- a/src/plugins/debugger/startremotedialog.ui +++ b/src/plugins/debugger/startremotedialog.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>310</width> + <width>439</width> <height>224</height> </rect> </property> @@ -49,26 +49,36 @@ <item row="1" column="1"> <widget class="QComboBox" name="architectureComboBox"/> </item> - <item row="2" column="1"> + <item row="4" column="1"> <widget class="QCheckBox" name="useServerStartScriptCheckBox"/> </item> - <item row="2" column="0"> + <item row="5" column="1"> + <widget class="Utils::PathChooser" name="serverStartScript"/> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="serverStartScriptLabel"> + <property name="text"> + <string>Server start script:</string> + </property> + </widget> + </item> + <item row="4" column="0"> <widget class="QLabel" name="useServerStartScriptLabel"> <property name="text"> <string>Use server start script:</string> </property> </widget> </item> - <item row="3" column="1"> - <widget class="Utils::PathChooser" name="serverStartScript" native="true"/> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="serverStartScriptLabel"> + <item row="2" column="0"> + <widget class="QLabel" name="sysrootLabel"> <property name="text"> - <string>Server start script:</string> + <string>Sysroot:</string> </property> </widget> </item> + <item row="2" column="1"> + <widget class="Utils::PathChooser" name="sysrootPathChooser"/> + </item> </layout> </item> <item> diff --git a/src/plugins/designer/Designer.pluginspec b/src/plugins/designer/Designer.pluginspec index cefb179682..16be5eb505 100644 --- a/src/plugins/designer/Designer.pluginspec +++ b/src/plugins/designer/Designer.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Designer" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Designer" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Qt Designer integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> <!-- For compiling with CPP support enabled --> - <dependency name="CppEditor" version="1.3.0"/> + <dependency name="CppEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/fakevim/FakeVim.pluginspec b/src/plugins/fakevim/FakeVim.pluginspec index c5d2f2b799..ace4d2c803 100644 --- a/src/plugins/fakevim/FakeVim.pluginspec +++ b/src/plugins/fakevim/FakeVim.pluginspec @@ -1,4 +1,4 @@ -<plugin name="FakeVim" version="1.3.0" compatVersion="1.3.0"> +<plugin name="FakeVim" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>VI-style keyboard navigation.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="CppEditor" version="1.3.0"/><!-- Plugin adds items to the editor's context menu --> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> + <dependency name="CppEditor" version="1.3.80"/><!-- Plugin adds items to the editor's context menu --> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/find/Find.pluginspec b/src/plugins/find/Find.pluginspec index 13f4dbd49c..602150876d 100644 --- a/src/plugins/find/Find.pluginspec +++ b/src/plugins/find/Find.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Find" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Find" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Provides the find widget and the hooks for find implementations.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/find/findplugin.cpp b/src/plugins/find/findplugin.cpp index 518ced182f..03a51a94a9 100644 --- a/src/plugins/find/findplugin.cpp +++ b/src/plugins/find/findplugin.cpp @@ -135,6 +135,8 @@ void FindPlugin::openFindFilter() QAction *action = qobject_cast<QAction*>(sender()); QTC_ASSERT(action, return); IFindFilter *filter = action->data().value<IFindFilter *>(); + if (m_currentDocumentFind->candidateIsEnabled()) + m_currentDocumentFind->acceptCandidate(); QString currentFindString = (m_currentDocumentFind->isEnabled() ? m_currentDocumentFind->currentFindString() : ""); if (!currentFindString.isEmpty()) m_findDialog->setFindText(currentFindString); diff --git a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec index 44dbc2ad72..3224d71b55 100644 --- a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec +++ b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec @@ -1,4 +1,4 @@ -<plugin name="GenericProjectManager" version="1.3.0" compatVersion="1.3.0"> +<plugin name="GenericProjectManager" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Generic support</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="CppTools" version="1.3.0"/> - <dependency name="CppEditor" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> + <dependency name="CppEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index bc7c96138b..d6d9d0a8c1 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -413,7 +413,7 @@ QString GenericProject::buildParser(BuildConfiguration *configuration) const if (m_toolChain) { switch (m_toolChain->type()) { case ProjectExplorer::ToolChain::GCC: - case ProjectExplorer::ToolChain::LinuxICC: + //case ProjectExplorer::ToolChain::LinuxICC: case ProjectExplorer::ToolChain::MinGW: return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC); diff --git a/src/plugins/git/ScmGit.pluginspec b/src/plugins/git/ScmGit.pluginspec index f279c598bc..59b11df0c2 100644 --- a/src/plugins/git/ScmGit.pluginspec +++ b/src/plugins/git/ScmGit.pluginspec @@ -1,4 +1,4 @@ -<plugin name="ScmGit" version="1.3.0" compatVersion="1.3.0"> +<plugin name="ScmGit" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Git integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> - <dependency name="VCSBase" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="VCSBase" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/helloworld/HelloWorld.pluginspec b/src/plugins/helloworld/HelloWorld.pluginspec index 672394fad3..158e4f0de7 100644 --- a/src/plugins/helloworld/HelloWorld.pluginspec +++ b/src/plugins/helloworld/HelloWorld.pluginspec @@ -1,4 +1,4 @@ -<plugin name="HelloWorld" version="1.3.0" compatVersion="1.3.0"> +<plugin name="HelloWorld" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Hello World sample plugin.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/help/Help.pluginspec b/src/plugins/help/Help.pluginspec index aa124ceba1..bc77b73581 100644 --- a/src/plugins/help/Help.pluginspec +++ b/src/plugins/help/Help.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Help" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Help" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Help system.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="Find" version="1.3.0"/> - <dependency name="Locator" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="Find" version="1.3.80"/> + <dependency name="Locator" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 968b6af970..da93cd6795 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -639,6 +639,16 @@ void HelpPlugin::extensionsInitialized() needsSetup = true; } + QString addedDocs = m_helpEngine->customValue(QLatin1String("AddedDocs")).toString(); + if (!addedDocs.isEmpty()) { + QStringList documentationToAdd = addedDocs.split(";"); + foreach(QString item, documentationToAdd) { + needsSetup = true; + m_helpEngine->registerDocumentation(item); + } + m_helpEngine->removeCustomValue(QLatin1String("AddedDocs")); + } + if (needsSetup) m_helpEngine->setupData(); diff --git a/src/plugins/locator/Locator.pluginspec b/src/plugins/locator/Locator.pluginspec index c55391924c..e0de95fd28 100644 --- a/src/plugins/locator/Locator.pluginspec +++ b/src/plugins/locator/Locator.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Locator" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Locator" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Provides the Locator widget and the hooks for Locator filter implementations.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/mercurial/Mercurial.pluginspec b/src/plugins/mercurial/Mercurial.pluginspec new file mode 100644 index 0000000000..74e5782d74 --- /dev/null +++ b/src/plugins/mercurial/Mercurial.pluginspec @@ -0,0 +1,27 @@ +<plugin name="Mercurial" version="1.3.80" compatVersion="1.3.80"> + <vendor>Brian McGillion</vendor> + <copyright>(C) 2008-2009 Brian McGillion</copyright> + <license> +Commercial Usage + +Licensees holding valid Qt Commercial licenses may use this plugin in +accordance with the Qt Commercial License Agreement provided with the +Software or, alternatively, in accordance with the terms contained in +a written agreement between you and Nokia. + +GNU Lesser General Public License Usage + +Alternatively, this plugin may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation. Please review the following information to +ensure the GNU Lesser General Public License version 2.1 requirements +will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> + <description>Mercurial integration.</description> + <url>http://qt.nokia.com</url> + <dependencyList> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="VCSBase" version="1.3.80"/> + </dependencyList> +</plugin> diff --git a/src/plugins/mercurial/annotationhighlighter.cpp b/src/plugins/mercurial/annotationhighlighter.cpp new file mode 100644 index 0000000000..00b8765d32 --- /dev/null +++ b/src/plugins/mercurial/annotationhighlighter.cpp @@ -0,0 +1,48 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "annotationhighlighter.h" +#include "constants.h" + +using namespace Mercurial::Internal; +using namespace Mercurial; + +MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const ChangeNumbers &changeNumbers, + QTextDocument *document) + : VCSBase::BaseAnnotationHighlighter(changeNumbers, document), + changeset(QLatin1String(Constants::CHANGESETID12)) +{ +} + +QString MercurialAnnotationHighlighter::changeNumber(const QString &block) const +{ + if (changeset.indexIn(block) != -1) + return changeset.cap(1); + return QString(); +} diff --git a/src/plugins/mercurial/annotationhighlighter.h b/src/plugins/mercurial/annotationhighlighter.h new file mode 100644 index 0000000000..541932445b --- /dev/null +++ b/src/plugins/mercurial/annotationhighlighter.h @@ -0,0 +1,52 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef ANNOTATIONHIGHLIGHTER_H +#define ANNOTATIONHIGHLIGHTER_H + +#include <vcsbase/baseannotationhighlighter.h> +#include <QtCore/QRegExp> + +namespace Mercurial { +namespace Internal { + +class MercurialAnnotationHighlighter : public VCSBase::BaseAnnotationHighlighter +{ +public: + explicit MercurialAnnotationHighlighter(const ChangeNumbers &changeNumbers, + QTextDocument *document = 0); + +private: + virtual QString changeNumber(const QString &block) const; + QRegExp changeset; +}; + +} //namespace Internal +}// namespace Mercurial +#endif // ANNOTATIONHIGHLIGHTER_H diff --git a/src/plugins/mercurial/clonewizard.cpp b/src/plugins/mercurial/clonewizard.cpp new file mode 100644 index 0000000000..6dc14b532e --- /dev/null +++ b/src/plugins/mercurial/clonewizard.cpp @@ -0,0 +1,90 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "clonewizard.h" +#include "clonewizardpage.h" +#include "mercurialplugin.h" +#include "mercurialsettings.h" + +#include <vcsbase/checkoutjobs.h> + +#include <QtCore/QDebug> + +using namespace Mercurial::Internal; + +CloneWizard::CloneWizard(QObject *parent) + : VCSBase::BaseCheckoutWizard(parent), + m_icon(QIcon(QLatin1String(":/mercurial/images/hg.png"))) +{ +} + +QIcon CloneWizard::icon() const +{ + return m_icon; +} + +QString CloneWizard::description() const +{ + return tr("Clone a Mercurial repository"); +} + +QString CloneWizard::name() const +{ + return tr("Mercurial Clone"); +} + +QList<QWizardPage*> CloneWizard::createParameterPages(const QString &path) +{ + QList<QWizardPage*> wizardPageList; + CloneWizardPage *page = new CloneWizardPage; + page->setPath(path); + wizardPageList.push_back(page); + return wizardPageList; +} + +QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<QWizardPage *> ¶meterPages, + QString *checkoutPath) +{ + const CloneWizardPage *page = qobject_cast<const CloneWizardPage *>(parameterPages.front()); + + if (!page) + return QSharedPointer<VCSBase::AbstractCheckoutJob>(); + + const MercurialSettings &settings = MercurialPlugin::instance()->settings(); + + QStringList args = settings.standardArguments(); + QString path = page->path(); + QString directory = page->directory(); + + args << QLatin1String("clone") << page->repository() << directory; + *checkoutPath = path + QLatin1Char('/') + directory; + + return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings.binary(), + args, path)); +} diff --git a/src/plugins/mercurial/clonewizard.h b/src/plugins/mercurial/clonewizard.h new file mode 100644 index 0000000000..54a91bfb57 --- /dev/null +++ b/src/plugins/mercurial/clonewizard.h @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef CLONEWIZARD_H +#define CLONEWIZARD_H + +#include <vcsbase/basecheckoutwizard.h> + +#include <QtGui/QIcon> + +namespace Mercurial { +namespace Internal { + +class CloneWizard : public VCSBase::BaseCheckoutWizard +{ +public: + CloneWizard(QObject *parent = 0); + + QIcon icon() const; + QString description() const; + QString name() const; + +protected: + QList<QWizardPage *> createParameterPages(const QString &path); + QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QList<QWizardPage *> ¶meterPages, + QString *checkoutPath); + +private: + const QIcon m_icon; +}; + +} //namespace Internal +} //namespace Mercurial + +#endif // CLONEWIZARD_H diff --git a/src/plugins/mercurial/clonewizardpage.cpp b/src/plugins/mercurial/clonewizardpage.cpp new file mode 100644 index 0000000000..c410299266 --- /dev/null +++ b/src/plugins/mercurial/clonewizardpage.cpp @@ -0,0 +1,51 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "clonewizardpage.h" + +using namespace Mercurial::Internal; + +CloneWizardPage::CloneWizardPage(QWidget *parent) + : VCSBase::BaseCheckoutWizardPage(parent) +{ + setRepositoryLabel(tr("Clone URL:")); +} + +QString CloneWizardPage::directoryFromRepository(const QString &repository) const +{ + //mercurial repositories are generally of the form protocol://repositoryUrl/repository/ + //we are just looking for repository. + const QChar slash = QLatin1Char('/'); + QString repo = repository.trimmed(); + if (repo.endsWith(slash)) + repo.truncate(repo.size() - 1); + + //Take the basename or the repository url + return repo.mid(repo.lastIndexOf(slash) + 1); +} diff --git a/src/plugins/mercurial/clonewizardpage.h b/src/plugins/mercurial/clonewizardpage.h new file mode 100644 index 0000000000..b28b121a2c --- /dev/null +++ b/src/plugins/mercurial/clonewizardpage.h @@ -0,0 +1,51 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef CLONEWIZARDPAGE_H +#define CLONEWIZARDPAGE_H + +#include <vcsbase/basecheckoutwizardpage.h> + +namespace Mercurial { +namespace Internal { + +class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage +{ + Q_OBJECT +public: + CloneWizardPage(QWidget *parent = 0); + +protected: + QString directoryFromRepository(const QString &rrepository) const; +}; + +} //namespace Internal +} //namespace Mercurial + +#endif // CLONEWIZARDPAGE_H diff --git a/src/plugins/mercurial/commiteditor.cpp b/src/plugins/mercurial/commiteditor.cpp new file mode 100644 index 0000000000..80e0511aa4 --- /dev/null +++ b/src/plugins/mercurial/commiteditor.cpp @@ -0,0 +1,97 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "commiteditor.h" +#include "mercurialcommitwidget.h" + +#include <vcsbase/submitfilemodel.h> + +#include <QtCore/QDebug> + +#include <QDir> //TODO REMOVE WHEN BASE FILE CHANGES ARE PULLED + +using namespace Mercurial::Internal; + +CommitEditor::CommitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent) + : VCSBase::VCSBaseSubmitEditor(parameters, new MercurialCommitWidget(parent)), + fileModel(0) +{ + setDisplayName(tr("Commit Editor")); +} + +MercurialCommitWidget *CommitEditor::commitWidget() +{ + return static_cast<MercurialCommitWidget *>(widget()); +} + +void CommitEditor::setFields(const QFileInfo &repositoryRoot, const QString &branch, + const QString &userName, const QString &email, + const QList<QPair<QString, QString> > &repoStatus) +{ + MercurialCommitWidget *mercurialWidget = commitWidget(); + if (!mercurialWidget) + return; + + mercurialWidget->setFields(repositoryRoot.absoluteFilePath(), branch, userName, email); + + fileModel = new VCSBase::SubmitFileModel(this); + + //TODO Messy tidy this up + typedef QPair<QString, QString> StringStringPair; + QStringList shouldTrack; + + foreach (const StringStringPair &status, repoStatus) { + if (status.first == QLatin1String("Untracked")) + shouldTrack.append(status.second); + else + fileModel->addFile(status.second, status.first, false); + } + + VCSBase::VCSBaseSubmitEditor::filterUntrackedFilesOfProject(repositoryRoot.absoluteFilePath(), + &shouldTrack); + + foreach (const QString &track, shouldTrack) { + foreach (const StringStringPair &status, repoStatus) { + if (status.second == track) + fileModel->addFile(status.second, status.first, false); + } + } + + setFileModel(fileModel); +} + +QString CommitEditor::committerInfo() +{ + return commitWidget()->committer(); +} + +QString CommitEditor::repoRoot() +{ + return commitWidget()->repoRoot(); +} diff --git a/src/plugins/mercurial/commiteditor.h b/src/plugins/mercurial/commiteditor.h new file mode 100644 index 0000000000..0fa3eb78e4 --- /dev/null +++ b/src/plugins/mercurial/commiteditor.h @@ -0,0 +1,69 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef COMMITEDITOR_H +#define COMMITEDITOR_H + +#include <vcsbase/vcsbasesubmiteditor.h> + +#include <QtCore/QFileInfo> + +namespace VCSBase { +class SubmitFileModel; +} + +namespace Mercurial { +namespace Internal { + +class MercurialCommitWidget; + +class CommitEditor : public VCSBase::VCSBaseSubmitEditor +{ + Q_OBJECT +public: + explicit CommitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, + QWidget *parent); + + void setFields(const QFileInfo &repositoryRoot, const QString &branch, + const QString &userName, const QString &email, + const QList<QPair<QString, QString> > &repoStatus); + + QString committerInfo(); + QString repoRoot(); + + +private: + inline MercurialCommitWidget *commitWidget(); + VCSBase::SubmitFileModel *fileModel; + +}; + +} +} +#endif // COMMITEDITOR_H diff --git a/src/plugins/mercurial/constants.h b/src/plugins/mercurial/constants.h new file mode 100644 index 0000000000..5e8c8879eb --- /dev/null +++ b/src/plugins/mercurial/constants.h @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +namespace Mercurial { +namespace Constants { + +enum { debug = 0 }; +const char * const MERCURIAL = "mercurial"; +const char * const MECURIALREPO = ".hg"; +const char * const MERCURIALDEFAULT = "hg"; + +//options page items +const char * const MERCURIALPATH = "Mercurial_Path"; +const char * const MERCURIALUSERNAME = "Mercurial_Username"; +const char * const MERCURIALEMAIL = "Mercurial_Email"; +const char * const MERCURIALLOGCOUNT = "Mercurial_LogCount"; +const char * const MERCURIALTIMEOUT = "Mercurial_Timeout"; +const char * const MERCURIALPROMPTSUBMIT = "Mercurial_PromptOnSubmit"; + +//changeset identifiers +const char * const CHANGESETID12 = " ([a-f0-9]{12,12}) "; //match 12 hex chars and capture +const char * const CHANGESETID40 = " ([a-f0-9]{40,40}) "; +const char * const CHANGEIDEXACT12 = "[a-f0-9]{12,12}"; //match 12 hex chars a +const char * const CHANGEIDEXACT40 = "[a-f0-9]{40,40}"; +const char * const DIFFIDENTIFIER = "^[-+]{3,3} [ab]{1,1}.*"; // match e.g. +++ b/filename + +//BaseEditorParameters +const char * const COMMANDLOG = "Mercurial Command Log Editor"; +const char * const COMMANDAPP = "application/vnd.nokia.text.scs_mercurial_commandlog"; +const char * const COMMANDEXT = "vcsMercurialCommand"; + +const char * const FILELOG = "Mercurial File Log Editor"; +const char * const LOGAPP = "application/vnd.nokia.text.scs_mercurial_log"; +const char * const LOGEXT = "vcsMercurialLog"; + +const char * const ANNOTATELOG = "Mercurial Annotation Editor"; +const char * const ANNOTATEAPP = "application/vnd.nokia.text.scs_mercurial_annotatelog"; +const char * const ANNOTATEEXT = "vcsMercurialAnnotate"; + +const char * const DIFFLOG = "Mercurial Diff Editor"; +const char * const DIFFAPP = "text/x-patch"; +const char * const DIFFEXT = "diff"; + +//SubmitEditorParameters +const char * const COMMITKIND = "Mercurial Commit Log Editor"; +const char * const COMMITMIMETYPE = "application/vnd.nokia.text.scs_mercurial_commitlog"; + +//menu items +//File menu actions +const char * const ANNOTATE = "Mercurial.Annotate"; +const char * const DIFF = "Mercurial.DiffSingleFile"; +const char * const LOG = "Mercurial.LogSingleFile"; +const char * const REVERT = "Mercurial.RevertSingleFile"; +const char * const STATUS = "Mercurial.Status"; + +//directory menu Actions +const char * const DIFFMULTI = "Mercurial.Action.DiffMulti"; +const char * const REVERTMULTI = "Mercurial.Action.RevertMulti"; +const char * const STATUSMULTI = "Mercurial.Action.StatusMulti"; +const char * const LOGMULTI = "Mercurial.Action.Logmulti"; + +//repository menu actions +const char * const PULL = "Mercurial.Action.Pull"; +const char * const PUSH = "Mercurial.Action.Push"; +const char * const UPDATE = "Mercurial.Action.Update"; +const char * const IMPORT = "Mercurial.Action.Import"; +const char * const INCOMING = "Mercurial.Action.Incoming"; +const char * const OUTGOING = "Mercurial.Action.Outgoing"; +const char * const COMMIT = "Mercurial.Action.Commit"; + +//Repository Management +const char * const MERGE = "Mercurial.Action.Merge"; +const char * const BRANCH = "Mercurial.Action.Branch"; +const char * const HEADS = "Mercurial.Action.Heads"; +const char * const PARENTS = "Mercurial.Action.Parents"; +const char * const TAGS = "Mercurial.Action.Tags"; +const char * const TIP = "Mercurial.Action.TIP"; +const char * const PATHS = "Mercurial.Action.Paths"; + +//Less commonly used menu actions +const char * const CLONE = "Mercurial.Action.Clone"; +const char * const INIT = "Mercurial.Action.Init"; +const char * const SERVE = "Mercurial.Action.Serve"; + +//submit editor actions +const char * const COMMITEDITOR = "Mercurial.Action.Editor.Commit"; +const char * const DIFFEDITOR = "Mercurial.Action.Editor.Diff"; + +} // namespace Constants +} // namespace mercurial + +#endif // CONSTANTS_H diff --git a/src/plugins/mercurial/images/hg.png b/src/plugins/mercurial/images/hg.png Binary files differnew file mode 100644 index 0000000000..59a238c222 --- /dev/null +++ b/src/plugins/mercurial/images/hg.png diff --git a/src/plugins/mercurial/mercurial.pro b/src/plugins/mercurial/mercurial.pro new file mode 100644 index 0000000000..9b52048b32 --- /dev/null +++ b/src/plugins/mercurial/mercurial.pro @@ -0,0 +1,39 @@ +TARGET = Mercurial +TEMPLATE = lib +include(../../qtcreatorplugin.pri) +include(mercurial_dependencies.pri) +SOURCES += mercurialplugin.cpp \ + optionspage.cpp \ + mercurialcontrol.cpp \ + mercurialclient.cpp \ + mercurialjobrunner.cpp \ + annotationhighlighter.cpp \ + mercurialeditor.cpp \ + revertdialog.cpp \ + srcdestdialog.cpp \ + mercurialcommitwidget.cpp \ + commiteditor.cpp \ + clonewizardpage.cpp \ + clonewizard.cpp \ + mercurialsettings.cpp +HEADERS += mercurialplugin.h \ + constants.h \ + optionspage.h \ + mercurialcontrol.h \ + mercurialclient.h \ + mercurialjobrunner.h \ + annotationhighlighter.h \ + mercurialeditor.h \ + revertdialog.h \ + srcdestdialog.h \ + mercurialcommitwidget.h \ + commiteditor.h \ + clonewizardpage.h \ + clonewizard.h \ + mercurialsettings.h +OTHER_FILES += Mercurial.pluginspec +FORMS += optionspage.ui \ + revertdialog.ui \ + srcdestdialog.ui \ + mercurialcommitpanel.ui +RESOURCES += mercurial.qrc diff --git a/src/plugins/mercurial/mercurial.qrc b/src/plugins/mercurial/mercurial.qrc new file mode 100644 index 0000000000..b001b7e60b --- /dev/null +++ b/src/plugins/mercurial/mercurial.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/mercurial" > + <file>images/hg.png</file> + </qresource> +</RCC> diff --git a/src/plugins/mercurial/mercurial_dependencies.pri b/src/plugins/mercurial/mercurial_dependencies.pri new file mode 100644 index 0000000000..9e7c28e9e1 --- /dev/null +++ b/src/plugins/mercurial/mercurial_dependencies.pri @@ -0,0 +1,5 @@ +include(../../plugins/projectexplorer/projectexplorer.pri) +include(../../plugins/texteditor/texteditor.pri) +include(../../plugins/coreplugin/coreplugin.pri) +include(../../plugins/vcsbase/vcsbase.pri) +include(../../libs/utils/utils.pri) diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp new file mode 100644 index 0000000000..aa54e07925 --- /dev/null +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -0,0 +1,453 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialclient.h" +#include "mercurialjobrunner.h" +#include "constants.h" +#include "mercurialsettings.h" +#include "mercurialplugin.h" + +#include <coreplugin/icore.h> +#include <coreplugin/editormanager/editormanager.h> + +#include <utils/qtcassert.h> +#include <vcsbase/vcsbaseeditor.h> +#include <vcsbase/vcsbaseoutputwindow.h> + +#include <QtCore/QStringList> +#include <QtCore/QSharedPointer> +#include <QtCore/QDir> +#include <QtCore/QProcess> +#include <QtCore/QTextCodec> +#include <QtCore/QtDebug> +#include <QtCore/QFileInfo> +#include <QtCore/QByteArray> + +using namespace Mercurial::Internal; +using namespace Mercurial; + +inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property, const QString &entry) +{ + foreach (Core::IEditor *ed, core->editorManager()->openedEditors()) + if (ed->file()->property(property).toString() == entry) + return ed; + return 0; +} + +MercurialClient::MercurialClient() : + jobManager(0), + core(Core::ICore::instance()) +{ +} + +MercurialClient::~MercurialClient() +{ + if (jobManager) { + delete jobManager; + jobManager = 0; + } +} + +bool MercurialClient::add(const QString &filename) +{ + QFileInfo file(filename); + QStringList args; + args << QLatin1String("add") << file.absoluteFilePath(); + + return executeHgSynchronously(file, args); +} + +bool MercurialClient::remove(const QString &filename) +{ + QFileInfo file(filename); + QStringList args; + args << QLatin1String("remove") << file.absoluteFilePath(); + + return executeHgSynchronously(file, args); +} + +bool MercurialClient::manifestSync(const QString &filename) +{ + QFileInfo file(filename); + QStringList args(QLatin1String("manifest")); + + QByteArray output; + executeHgSynchronously(file, args, &output); + + const QStringList files = QString::fromLocal8Bit(output).split(QLatin1Char('\n')); + + foreach (const QString &fileName, files) { + const QFileInfo managedFile(fileName); + if (file == managedFile) + return true; + } + + return false; +} + +bool MercurialClient::executeHgSynchronously(const QFileInfo &file, const QStringList &args, + QByteArray *output) const +{ + QProcess hgProcess; + hgProcess.setWorkingDirectory(file.isDir() ? file.absoluteFilePath() : file.absolutePath()); + + const MercurialSettings &settings = MercurialPlugin::instance()->settings(); + const QString binary = settings.binary(); + const QStringList arguments = settings.standardArguments() + args; + + VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); + outputWindow->appendCommand(MercurialJobRunner::msgExecute(binary, arguments)); + + hgProcess.start(binary, arguments); + + if (!hgProcess.waitForStarted()) { + outputWindow->appendError(MercurialJobRunner::msgStartFailed(binary, hgProcess.errorString())); + return false; + } + + hgProcess.closeWriteChannel(); + + if (!hgProcess.waitForFinished(settings.timeoutMilliSeconds())) { + hgProcess.terminate(); + outputWindow->appendError(MercurialJobRunner::msgTimeout(settings.timeoutSeconds())); + return false; + } + + if ((hgProcess.exitStatus() == QProcess::NormalExit) && (hgProcess.exitCode() == 0)) { + if (output) + *output = hgProcess.readAllStandardOutput(); + return true; + } + + return false; +} + +QString MercurialClient::branchQuerySync(const QFileInfo &repositoryRoot) +{ + QByteArray output; + if (executeHgSynchronously(repositoryRoot, QStringList(QLatin1String("branch")), &output)) + return QTextCodec::codecForLocale()->toUnicode(output).trimmed(); + + return QLatin1String("Unknown Branch"); +} + +void MercurialClient::annotate(const QFileInfo &file) +{ + QStringList args; + args << QLatin1String("annotate") << QLatin1String("-u") << QLatin1String("-c") << QLatin1String("-d") << file.absoluteFilePath(); + + const QString kind = QLatin1String(Constants::ANNOTATELOG); + const QString title = tr("Hg Annotate %1").arg(file.fileName()); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, file.absolutePath(), true, + "annotate", file.absoluteFilePath()); + + QSharedPointer<HgTask> job(new HgTask(file.absolutePath(), args, editor)); + enqueueJob(job); +} + +void MercurialClient::diff(const QFileInfo &fileOrDir) +{ + QStringList args; + QString id; + QString workingPath; + + args << QLatin1String("diff") << QLatin1String("-g") << QLatin1String("-p") + << QLatin1String("-U 8"); + + if (!fileOrDir.isDir()) { + args.append(fileOrDir.absoluteFilePath()); + id = fileOrDir.absoluteFilePath(); + workingPath = fileOrDir.absolutePath(); + } else { + id = MercurialPlugin::instance()->currentProjectName(); + workingPath = fileOrDir.absoluteFilePath(); + } + + const QString kind = QLatin1String(Constants::DIFFLOG); + const QString title = tr("Hg diff %1").arg(fileOrDir.isDir() ? id : fileOrDir.fileName()); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingPath, true, + "diff", id); + + QSharedPointer<HgTask> job(new HgTask(workingPath, args, editor)); + enqueueJob(job); +} + +void MercurialClient::log(const QFileInfo &fileOrDir) +{ + QStringList args(QLatin1String("log")); + QString id; + QString workingDir; + + if (!fileOrDir.isDir()) { + args.append(fileOrDir.absoluteFilePath()); + id = fileOrDir.absoluteFilePath(); + workingDir = fileOrDir.absolutePath(); + } else { + id = MercurialPlugin::instance()->currentProjectName(); + workingDir = fileOrDir.absoluteFilePath(); + } + + const QString kind = QLatin1String(Constants::FILELOG); + const QString title = tr("Hg log %1").arg(fileOrDir.isDir() ? id : fileOrDir.fileName()); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingDir, true, + "log", id); + + QSharedPointer<HgTask> job(new HgTask(workingDir, args, editor)); + enqueueJob(job); +} + +void MercurialClient::revert(const QFileInfo &fileOrDir, const QString &revision) +{ + QStringList args(QLatin1String("revert")); + + if (!revision.isEmpty()) + args << QLatin1String("-r") << revision; + if (!fileOrDir.isDir()) + args.append(fileOrDir.absoluteFilePath()); + else + args.append(QLatin1String("--all")); + + QSharedPointer<HgTask> job(new HgTask(fileOrDir.isDir() ? fileOrDir.absoluteFilePath() : + fileOrDir.absolutePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::status(const QFileInfo &fileOrDir) +{ + QStringList args(QLatin1String("status")); + if (!fileOrDir.isDir()) + args.append(fileOrDir.absoluteFilePath()); + + QSharedPointer<HgTask> job(new HgTask(fileOrDir.isDir() ? fileOrDir.absoluteFilePath() : + fileOrDir.absolutePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::statusWithSignal(const QFileInfo &repositoryRoot) +{ + const QStringList args(QLatin1String("status")); + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, true)); + connect(job.data(), SIGNAL(rawData(QByteArray)), + this, SLOT(statusParser(QByteArray))); + + enqueueJob(job); +} + +void MercurialClient::statusParser(const QByteArray &data) +{ + QList<QPair<QString, QString> > statusList; + + QStringList rawStatusList = QTextCodec::codecForLocale()->toUnicode(data).split(QLatin1Char('\n')); + + foreach (const QString &string, rawStatusList) { + QPair<QString, QString> status; + + if (string.startsWith(QLatin1Char('M'))) + status.first = QLatin1String("Modified"); + else if (string.startsWith(QLatin1Char('A'))) + status.first = QLatin1String("Added"); + else if (string.startsWith(QLatin1Char('R'))) + status.first = QLatin1String("Removed"); + else if (string.startsWith(QLatin1Char('!'))) + status.first = QLatin1String("Deleted"); + else if (string.startsWith(QLatin1Char('?'))) + status.first = QLatin1String("Untracked"); + else + continue; + + //the status string should be similar to "M file_with_Changes" + //so just should take the file name part and store it + status.second = string.mid(2); + statusList.append(status); + } + + emit parsedStatus(statusList); +} + +void MercurialClient::import(const QFileInfo &repositoryRoot, const QStringList &files) +{ + QStringList args; + args << QLatin1String("import") << QLatin1String("--no-commit"); + args += files; + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::pull(const QFileInfo &repositoryRoot, const QString &repository) +{ + QStringList args(QLatin1String("pull")); + if (!repository.isEmpty()) + args.append(repository); + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::push(const QFileInfo &repositoryRoot, const QString &repository) +{ + QStringList args(QLatin1String("push")); + if (!repository.isEmpty()) + args.append(repository); + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::incoming(const QFileInfo &repositoryRoot, const QString &repository) +{ + QStringList args; + args << QLatin1String("incoming") << QLatin1String("-g") << QLatin1String("-p"); + if (!repository.isEmpty()) + args.append(repository); + + QString id = MercurialPlugin::instance()->currentProjectName(); + + const QString kind = QLatin1String(Constants::DIFFLOG); + const QString title = tr("Hg incoming %1").arg(id); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, repositoryRoot.absoluteFilePath(), + true, "incoming", id); + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, editor)); + enqueueJob(job); +} + +void MercurialClient::outgoing(const QFileInfo &repositoryRoot) +{ + QStringList args; + args << QLatin1String("outgoing") << QLatin1String("-g") << QLatin1String("-p"); + + QString id = MercurialPlugin::instance()->currentProjectName(); + + const QString kind = QLatin1String(Constants::DIFFLOG); + const QString title = tr("Hg outgoing %1").arg(id); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, repositoryRoot.absoluteFilePath(), true, + "outgoing", id); + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, editor)); + enqueueJob(job); +} + +void MercurialClient::view(const QString &source, const QString &id) +{ + QStringList args; + args << QLatin1String("log") << QLatin1String("-p") << QLatin1String("-g") + << QLatin1String("-r") << id; + + const QString kind = QLatin1String(Constants::DIFFLOG); + const QString title = tr("Hg log %1").arg(id); + + VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, source, + true, "view", id); + + QSharedPointer<HgTask> job(new HgTask(source, args, editor)); + enqueueJob(job); +} + +void MercurialClient::update(const QFileInfo &repositoryRoot, const QString &revision) +{ + QStringList args(QLatin1String("update")); + if (!revision.isEmpty()) + args << revision; + + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false)); + enqueueJob(job); +} + +void MercurialClient::commit(const QFileInfo &repositoryRoot, const QStringList &files, + const QString &committerInfo, const QString &commitMessageFile) +{ + QStringList args(QLatin1String("commit")); + if (!committerInfo.isEmpty()) + args << QLatin1String("-u") << committerInfo; + args << QLatin1String("-l") << commitMessageFile << files; + QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false)); + enqueueJob(job); +} + +QString MercurialClient::findTopLevelForFile(const QFileInfo &file) +{ + const QString repositoryTopDir = QLatin1String(Constants::MECURIALREPO); + QDir dir = file.isDir() ? QDir(file.absoluteFilePath()) : QDir(file.absolutePath()); + + do { + if (QFileInfo(dir, repositoryTopDir).exists()) + return dir.absolutePath(); + } while (dir.cdUp()); + + return QString(); +} + +void MercurialClient::settingsChanged() +{ + if (jobManager) + jobManager->restart(); +} + +VCSBase::VCSBaseEditor *MercurialClient::createVCSEditor(const QString &kind, QString title, + const QString &source, bool setSourceCodec, + const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const +{ + VCSBase::VCSBaseEditor *baseEditor = 0; + Core::IEditor* outputEditor = locateEditor(core, registerDynamicProperty, dynamicPropertyValue); + const QString progressMsg = tr("Working..."); + if (outputEditor) { + // Exists already + outputEditor->createNew(progressMsg); + baseEditor = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); + QTC_ASSERT(baseEditor, return 0); + } else { + outputEditor = core->editorManager()->openEditorWithContents(kind, &title, progressMsg); + outputEditor->file()->setProperty(registerDynamicProperty, dynamicPropertyValue); + baseEditor = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); + QTC_ASSERT(baseEditor, return 0); + baseEditor->setSource(source); + if (setSourceCodec) + baseEditor->setCodec(VCSBase::VCSBaseEditor::getCodec(source)); + } + + core->editorManager()->activateEditor(outputEditor); + return baseEditor; +} + +void MercurialClient::enqueueJob(const QSharedPointer<HgTask> &job) +{ + if (!jobManager) { + jobManager = new MercurialJobRunner(); + jobManager->start(); + } + jobManager->enqueueJob(job); +} diff --git a/src/plugins/mercurial/mercurialclient.h b/src/plugins/mercurial/mercurialclient.h new file mode 100644 index 0000000000..bd0c9f8771 --- /dev/null +++ b/src/plugins/mercurial/mercurialclient.h @@ -0,0 +1,109 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALCLIENT_H +#define MERCURIALCLIENT_H + +#include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QSharedPointer> + +QT_BEGIN_NAMESPACE +class QFileInfo; +QT_END_NAMESPACE + +namespace Core { +class ICore; +} + +namespace VCSBase{ +class VCSBaseEditor; +} + +namespace Mercurial { +namespace Internal { + +class MercurialJobRunner; +class HgTask; + +class MercurialClient : public QObject +{ + Q_OBJECT +public: + MercurialClient(); + ~MercurialClient(); + bool add(const QString &fileName); + bool remove(const QString &fileName); + bool manifestSync(const QString &filename); + QString branchQuerySync(const QFileInfo &repositoryRoot); + void annotate(const QFileInfo &file); + void diff(const QFileInfo &fileOrDir); + void log(const QFileInfo &fileOrDir); + void import(const QFileInfo &repositoryRoot, const QStringList &files); + void pull(const QFileInfo &repositoryRoot, const QString &repository); + void push(const QFileInfo &repositoryRoot, const QString &repository); + void incoming(const QFileInfo &repositoryRoot, const QString &repository); + void outgoing(const QFileInfo &repositoryRoot); + void status(const QFileInfo &fileOrDir); + void statusWithSignal(const QFileInfo &fileOrDir); + void revert(const QFileInfo &fileOrDir, const QString &revision); + void update(const QFileInfo &repositoryRoot, const QString &revision); + void commit(const QFileInfo &repositoryRoot, const QStringList &files, + const QString &commiterInfo, const QString &commitMessageFile); + + static QString findTopLevelForFile(const QFileInfo &file); + +signals: + void parsedStatus(const QList<QPair<QString, QString> > &statusList); + +public slots: + void view(const QString &source, const QString &id); + void settingsChanged(); + +private slots: + void statusParser(const QByteArray &data); + +private: + bool executeHgSynchronously(const QFileInfo &file, const QStringList &args, + QByteArray *output=0) const; + void enqueueJob(const QSharedPointer<HgTask> &); + + MercurialJobRunner *jobManager; + Core::ICore *core; + + VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind, QString title, + const QString &source, bool setSourceCodec, + const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const; +}; + +} //namespace Internal +} //namespace Mercurial + +#endif // MERCURIALCLIENT_H diff --git a/src/plugins/mercurial/mercurialcommitpanel.ui b/src/plugins/mercurial/mercurialcommitpanel.ui new file mode 100644 index 0000000000..eadd4953e0 --- /dev/null +++ b/src/plugins/mercurial/mercurialcommitpanel.ui @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Mercurial::Internal::MercurialCommitPanel</class> + <widget class="QWidget" name="Mercurial::Internal::MercurialCommitPanel"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>374</width> + <height>229</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QGroupBox" name="infoGroup"> + <property name="title"> + <string>General Information</string> + </property> + <layout class="QFormLayout" name="infoFormLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="repositoryLabelLabel"> + <property name="text"> + <string>Repository:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="repositoryLabel"> + <property name="text"> + <string>repository</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="branchLabelLabel"> + <property name="text"> + <string>Branch:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="branchLabel"> + <property name="text"> + <string>branch</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="editGroup"> + <property name="title"> + <string>Commit Information</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="authorLabel"> + <property name="text"> + <string>Author:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="authorLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="emailLabel"> + <property name="text"> + <string>Email:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="emailLineEdit"/> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>161</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/mercurial/mercurialcommitwidget.cpp b/src/plugins/mercurial/mercurialcommitwidget.cpp new file mode 100644 index 0000000000..d3e6c7d0a1 --- /dev/null +++ b/src/plugins/mercurial/mercurialcommitwidget.cpp @@ -0,0 +1,155 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialcommitwidget.h" + +#include <texteditor/texteditorsettings.h> +#include <texteditor/fontsettings.h> +#include <texteditor/texteditorconstants.h> + +#include <QtGui/QSyntaxHighlighter> +#include <QtGui/QTextEdit> + +#include <QtCore/QDebug> +#include <QtCore/QRegExp> + +//see the git submit widget for details of the syntax Highlighter + +//TODO Check to see when the Highlighter has been moved to a base class and use that instead + +namespace Mercurial { +namespace Internal { + +// Retrieve the comment char format from the text editor. +static QTextCharFormat commentFormat() +{ + const TextEditor::FontSettings settings = TextEditor::TextEditorSettings::instance()->fontSettings(); + return settings.toTextCharFormat(QLatin1String(TextEditor::Constants::C_COMMENT)); +} + +// Highlighter for Mercurial submit messages. Make the first line bold, indicates +// comments as such (retrieving the format from the text editor) and marks up +// keywords (words in front of a colon as in 'Task: <bla>'). +class MercurialSubmitHighlighter : QSyntaxHighlighter +{ +public: + explicit MercurialSubmitHighlighter(QTextEdit *parent); + virtual void highlightBlock(const QString &text); + +private: + enum State { Header, Comment, Other }; + const QTextCharFormat m_commentFormat; + const QRegExp m_keywordPattern; + const QChar m_hashChar; +}; + +MercurialSubmitHighlighter::MercurialSubmitHighlighter(QTextEdit * parent) : + QSyntaxHighlighter(parent), + m_commentFormat(commentFormat()), + m_keywordPattern(QLatin1String("^\\w+:")), + m_hashChar(QLatin1Char('#')) +{ + Q_ASSERT(m_keywordPattern.isValid()); +} + +void MercurialSubmitHighlighter::highlightBlock(const QString &text) +{ + // figure out current state + State state = Other; + const QTextBlock block = currentBlock(); + if (block.position() == 0) { + state = Header; + } else { + if (text.startsWith(m_hashChar)) + state = Comment; + } + // Apply format. + switch (state) { + case Header: { + QTextCharFormat charFormat = format(0); + charFormat.setFontWeight(QFont::Bold); + setFormat(0, text.size(), charFormat); + } + break; + case Comment: + setFormat(0, text.size(), m_commentFormat); + break; + case Other: + // Format key words ("Task:") italic + if (m_keywordPattern.indexIn(text, 0, QRegExp::CaretAtZero) == 0) { + QTextCharFormat charFormat = format(0); + charFormat.setFontItalic(true); + setFormat(0, m_keywordPattern.matchedLength(), charFormat); + } + break; + } +} + + +MercurialCommitWidget::MercurialCommitWidget(QWidget *parent) : + Utils::SubmitEditorWidget(parent), + mercurialCommitPanel(new QWidget) +{ + mercurialCommitPanelUi.setupUi(mercurialCommitPanel); + insertTopWidget(mercurialCommitPanel); + new MercurialSubmitHighlighter(descriptionEdit()); +} + +void MercurialCommitWidget::setFields(const QString &repositoryRoot, const QString &branch, + const QString &userName, const QString &email) +{ + mercurialCommitPanelUi.repositoryLabel->setText(repositoryRoot); + mercurialCommitPanelUi.branchLabel->setText(branch); + mercurialCommitPanelUi.authorLineEdit->setText(userName); + mercurialCommitPanelUi.emailLineEdit->setText(email); +} + +QString MercurialCommitWidget::committer() +{ + const QString author = mercurialCommitPanelUi.authorLineEdit->text(); + const QString email = mercurialCommitPanelUi.emailLineEdit->text(); + if (author.isEmpty()) + return QString(); + + QString user = author; + if (!email.isEmpty()) { + user += QLatin1String(" <"); + user += email; + user += QLatin1Char('>'); + } + return user; +} + +QString MercurialCommitWidget::repoRoot() +{ + return mercurialCommitPanelUi.repositoryLabel->text(); +} + +} // namespace Internal +} // namespace Mercurial diff --git a/src/plugins/mercurial/mercurialcommitwidget.h b/src/plugins/mercurial/mercurialcommitwidget.h new file mode 100644 index 0000000000..c5e3337e26 --- /dev/null +++ b/src/plugins/mercurial/mercurialcommitwidget.h @@ -0,0 +1,64 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALCOMMITWIDGET_H +#define MERCURIALCOMMITWIDGET_H + +#include "ui_mercurialcommitpanel.h" + +#include <utils/submiteditorwidget.h> + +namespace Mercurial { +namespace Internal { + +/*submit editor widget based on git SubmitEditor + Some extra fields have been added to the standard SubmitEditorWidget, + to help to conform to the commit style that is used by both git and Mercurial*/ + +class MercurialCommitWidget : public Utils::SubmitEditorWidget +{ + +public: + explicit MercurialCommitWidget(QWidget *parent = 0); + + void setFields(const QString &repositoryRoot, const QString &branch, + const QString &userName, const QString &email); + + QString committer(); + QString repoRoot(); + +private: + QWidget *mercurialCommitPanel; + Ui::MercurialCommitPanel mercurialCommitPanelUi; +}; + +} // namespace Internal +} // namespace Mercurial + +#endif // MERCURIALCOMMITWIDGET_H diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp new file mode 100644 index 0000000000..a2303e0200 --- /dev/null +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -0,0 +1,109 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialcontrol.h" +#include "mercurialclient.h" + +#include <QtCore/QFileInfo> + +using namespace Mercurial::Internal; + +MercurialControl::MercurialControl(MercurialClient *client) + : mercurialClient(client), + mercurialEnabled(true) +{ +} + +QString MercurialControl::name() const +{ + return tr("Mercurial"); +} + +bool MercurialControl::isEnabled() const +{ + return mercurialEnabled; +} + +void MercurialControl::setEnabled(bool enabled) +{ + if (mercurialEnabled != enabled) { + mercurialEnabled = enabled; + emit enabledChanged(mercurialEnabled); + } +} + +bool MercurialControl::managesDirectory(const QString &directory) const +{ + QFileInfo dir(directory); + return !mercurialClient->findTopLevelForFile(dir).isEmpty(); +} + +QString MercurialControl::findTopLevelForDirectory(const QString &directory) const +{ + QFileInfo dir(directory); + return mercurialClient->findTopLevelForFile(dir); +} + +bool MercurialControl::supportsOperation(Operation operation) const +{ + bool supported = true; + + switch (operation) { + case Core::IVersionControl::AddOperation: + case Core::IVersionControl::DeleteOperation: + break; + case Core::IVersionControl::OpenOperation: + default: + supported = false; + break; + } + + return supported; +} + +bool MercurialControl::vcsOpen(const QString &filename) +{ + Q_UNUSED(filename) + return true; +} + +bool MercurialControl::vcsAdd(const QString &filename) +{ + return mercurialClient->add(filename); +} + +bool MercurialControl::vcsDelete(const QString &filename) +{ + return mercurialClient->remove(filename); +} + +bool MercurialControl::sccManaged(const QString &filename) +{ + return mercurialClient->manifestSync(filename); +} diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h new file mode 100644 index 0000000000..2085a27d77 --- /dev/null +++ b/src/plugins/mercurial/mercurialcontrol.h @@ -0,0 +1,70 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALCONTROL_H +#define MERCURIALCONTROL_H + +#include <coreplugin/iversioncontrol.h> + +namespace Mercurial { +namespace Internal { + +class MercurialClient; + +//Implements just the basics of the Version Control Interface +//MercurialClient handles all the work +class MercurialControl: public Core::IVersionControl +{ + Q_OBJECT +public: + explicit MercurialControl(MercurialClient *mercurialClient); + + QString name() const; + bool isEnabled() const; + void setEnabled(bool enabled); + bool managesDirectory(const QString &filename) const; + QString findTopLevelForDirectory(const QString &directory) const; + bool supportsOperation(Operation operation) const; + bool vcsOpen(const QString &fileName); + bool vcsAdd(const QString &filename); + bool vcsDelete(const QString &filename); + bool sccManaged(const QString &filename); + +signals: + void enabledChanged(bool); + +private: + MercurialClient *mercurialClient; + bool mercurialEnabled; +}; + +} //namespace Internal +} //namespace Mercurial + +#endif // MERCURIALCONTROL_H diff --git a/src/plugins/mercurial/mercurialeditor.cpp b/src/plugins/mercurial/mercurialeditor.cpp new file mode 100644 index 0000000000..ba6989db51 --- /dev/null +++ b/src/plugins/mercurial/mercurialeditor.cpp @@ -0,0 +1,114 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialeditor.h" +#include "annotationhighlighter.h" +#include "constants.h" +#include "mercurialclient.h" + +#include <coreplugin/editormanager/editormanager.h> +#include <vcsbase/diffhighlighter.h> + +#include <QtCore/QString> +#include <QtGui/QTextCursor> +#include <QtGui/QTextBlock> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> +#include <QtCore/QDebug> + +using namespace Mercurial::Internal; +using namespace Mercurial; + +MercurialEditor::MercurialEditor(const VCSBase::VCSBaseEditorParameters *type, QWidget *parent) + : VCSBase::VCSBaseEditor(type, parent), + exactIdentifier12(QLatin1String(Constants::CHANGEIDEXACT12)), + exactIdentifier40(QLatin1String(Constants::CHANGEIDEXACT40)), + changesetIdentifier12(QLatin1String(Constants::CHANGESETID12)), + changesetIdentifier40(QLatin1String(Constants::CHANGESETID40)), + diffIdentifier(QLatin1String(Constants::DIFFIDENTIFIER)) +{ +} + +QSet<QString> MercurialEditor::annotationChanges() const +{ + QSet<QString> changes; + const QString data = toPlainText(); + if (data.isEmpty()) + return changes; + + int position = 0; + while ((position = changesetIdentifier12.indexIn(data, position)) != -1) { + changes.insert(changesetIdentifier12.cap(1)); + position += changesetIdentifier12.matchedLength(); + } + + return changes; +} + +QString MercurialEditor::changeUnderCursor(const QTextCursor &cursorIn) const +{ + QTextCursor cursor = cursorIn; + cursor.select(QTextCursor::WordUnderCursor); + if (cursor.hasSelection()) { + const QString change = cursor.selectedText(); + if (exactIdentifier12.exactMatch(change)) + return change; + if (exactIdentifier40.exactMatch(change)) + return change; + } + return QString(); +} + +VCSBase::DiffHighlighter *MercurialEditor::createDiffHighlighter() const +{ + return new VCSBase::DiffHighlighter(diffIdentifier); +} + +VCSBase::BaseAnnotationHighlighter *MercurialEditor::createAnnotationHighlighter(const QSet<QString> &changes) const +{ + return new MercurialAnnotationHighlighter(changes); +} + +QString MercurialEditor::fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const +{ + const QString filechangeId(QLatin1String("+++ b/")); + QTextBlock::iterator iterator; + for (iterator = diffFileSpec.begin(); !(iterator.atEnd()); iterator++) { + QTextFragment fragment = iterator.fragment(); + if(fragment.isValid()) { + if (fragment.text().startsWith(filechangeId)) { + const QFileInfo sourceFile(source()); + const QDir repository(MercurialClient::findTopLevelForFile(sourceFile)); + const QString filename = fragment.text().remove(0, filechangeId.size()); + return repository.absoluteFilePath(filename); + } + } + } + return QString(); +} diff --git a/src/plugins/mercurial/mercurialeditor.h b/src/plugins/mercurial/mercurialeditor.h new file mode 100644 index 0000000000..ac5c357338 --- /dev/null +++ b/src/plugins/mercurial/mercurialeditor.h @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALEDITOR_H +#define MERCURIALEDITOR_H + +#include <vcsbase/vcsbaseeditor.h> + +#include <QtCore/QRegExp> + +namespace Mercurial { +namespace Internal { + +class MercurialEditor : public VCSBase::VCSBaseEditor +{ +public: + explicit MercurialEditor(const VCSBase::VCSBaseEditorParameters *type, QWidget *parent); + +private: + virtual QSet<QString> annotationChanges() const; + virtual QString changeUnderCursor(const QTextCursor &cursor) const; + virtual VCSBase::DiffHighlighter *createDiffHighlighter() const; + virtual VCSBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes) const; + virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const; + + const QRegExp exactIdentifier12; + const QRegExp exactIdentifier40; + const QRegExp changesetIdentifier12; + const QRegExp changesetIdentifier40; + const QRegExp diffIdentifier; +}; + +} // namespace Internal +} // namespace Mercurial +#endif // MERCURIALEDITOR_H diff --git a/src/plugins/mercurial/mercurialjobrunner.cpp b/src/plugins/mercurial/mercurialjobrunner.cpp new file mode 100644 index 0000000000..3b27594f33 --- /dev/null +++ b/src/plugins/mercurial/mercurialjobrunner.cpp @@ -0,0 +1,217 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialjobrunner.h" +#include "mercurialplugin.h" +#include "constants.h" +#include "mercurialsettings.h" + +#include <vcsbase/vcsbaseoutputwindow.h> +#include <vcsbase/vcsbaseeditor.h> + +#include <QtCore/QProcess> +#include <QtCore/QString> +#include <QtCore/QDebug> + +using namespace Mercurial::Internal; +using namespace Mercurial; + +HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, bool emitRaw) + : m_repositoryRoot(repositoryRoot), + arguments(arguments), + emitRaw(emitRaw), + editor(0) +{ +} + +HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, VCSBase::VCSBaseEditor *editor) + : m_repositoryRoot(repositoryRoot), + arguments(arguments), + emitRaw(false), + editor(editor) + +{ +} + +MercurialJobRunner::MercurialJobRunner() : + plugin(MercurialPlugin::instance()), + keepRunning(true) +{ + VCSBase::VCSBaseOutputWindow *ow = VCSBase::VCSBaseOutputWindow::instance(); + connect(this, SIGNAL(error(QString)), ow, SLOT(appendError(QString)), Qt::QueuedConnection); + connect(this, SIGNAL(commandStarted(QString)), ow, SLOT(appendCommand(QString)), Qt::QueuedConnection); +} + +MercurialJobRunner::~MercurialJobRunner() +{ + stop(); +} + +void MercurialJobRunner::stop() +{ + mutex.lock(); + keepRunning = false; + //Create a dummy task to break the cycle + QSharedPointer<HgTask> job(0); + jobs.enqueue(job); + waiter.wakeAll(); + mutex.unlock(); + + wait(); +} + +void MercurialJobRunner::restart() +{ + stop(); + mutex.lock(); + keepRunning = true; + mutex.unlock(); + start(); +} + +void MercurialJobRunner::getSettings() +{ + const MercurialSettings &settings = MercurialPlugin::instance()->settings(); + binary = settings.binary(); + timeout = settings.timeoutMilliSeconds(); + standardArguments = settings.standardArguments(); +} + +void MercurialJobRunner::enqueueJob(const QSharedPointer<HgTask> &job) +{ + mutex.lock(); + jobs.enqueue(job); + waiter.wakeAll(); + mutex.unlock(); +} + +void MercurialJobRunner::run() +{ + getSettings(); + forever { + mutex.lock(); + while (jobs.count() == 0) + waiter.wait(&mutex); + + if (!keepRunning) { + jobs.clear(); + mutex.unlock(); + return; + } + + QSharedPointer<HgTask> job = jobs.dequeue(); + mutex.unlock(); + + task(job); + } +} + +QString MercurialJobRunner::msgExecute(const QString &binary, const QStringList &args) +{ + return tr("Executing: %1 %2\n").arg(binary, args.join(QString(QLatin1Char(' ')))); +} + +QString MercurialJobRunner::msgStartFailed(const QString &binary, const QString &why) +{ + return tr("Unable to start mercurial process '%1': %2").arg(binary, why); +} + +QString MercurialJobRunner::msgTimeout(int timeoutSeconds) +{ + return tr("Timed out after %1s waiting for mercurial process to finish.").arg(timeoutSeconds); +} + +void MercurialJobRunner::task(const QSharedPointer<HgTask> &job) +{ + HgTask *taskData = job.data(); + + VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); + + if (taskData->shouldEmit()) { + //Call the job's signal so the Initator of the job can process the data + //Because the QSharedPointer that holds the HgTask will go out of scope and hence be deleted + //we have to block and wait until the signal is delivered + connect(this, SIGNAL(output(QByteArray)), taskData, SIGNAL(rawData(QByteArray)), + Qt::BlockingQueuedConnection); + } else if (taskData->displayEditor()) { + //An editor has been created to display the data so send it there + connect(this, SIGNAL(output(QByteArray)), + taskData->displayEditor(), SLOT(setPlainTextData(QByteArray)), + Qt::QueuedConnection); + } else { + //Just output the data to the Mercurial output window + connect(this, SIGNAL(output(QByteArray)), outputWindow, SLOT(appendData(QByteArray)), + Qt::QueuedConnection); + } + + const QStringList args = standardArguments + taskData->args(); + emit commandStarted(msgExecute(binary, args)); + //infom the user of what we are going to try and perform + + if (Constants::debug) + qDebug() << Q_FUNC_INFO << "Repository root is " << taskData->repositoryRoot(); + + QProcess hgProcess; + hgProcess.setWorkingDirectory(taskData->repositoryRoot()); + + + hgProcess.start(binary, args); + + if (!hgProcess.waitForStarted()) { + emit error(msgStartFailed(binary, hgProcess.errorString())); + return; + } + + hgProcess.closeWriteChannel(); + + if (!hgProcess.waitForFinished(timeout)) { + hgProcess.terminate(); + emit error(msgTimeout(timeout / 1000)); + return; + } + + if ((hgProcess.exitStatus() == QProcess::NormalExit) && (hgProcess.exitCode() == 0)) { + QByteArray stdOutput= hgProcess.readAllStandardOutput(); + /* + * sometimes success means output is actually on error channel (stderr) + * e.g. "hg revert" outputs "no changes needed to 'file'" on stderr if file has not changed + * from revision specified + */ + if (stdOutput.isEmpty()) + stdOutput = hgProcess.readAllStandardError(); + emit output(stdOutput); + } else { + emit error(QString::fromLocal8Bit(hgProcess.readAllStandardError())); + } + + hgProcess.close(); + //the signal connection is to last only for the duration of a job/task. next time a new + //output signal connection must be made + disconnect(this, SIGNAL(output(QByteArray)), 0, 0); +} diff --git a/src/plugins/mercurial/mercurialjobrunner.h b/src/plugins/mercurial/mercurialjobrunner.h new file mode 100644 index 0000000000..bac9c650d5 --- /dev/null +++ b/src/plugins/mercurial/mercurialjobrunner.h @@ -0,0 +1,113 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALJOBRUNNER_H +#define MERCURIALJOBRUNNER_H + +#include <QtCore/QThread> +#include <QtCore/QQueue> +#include <QtCore/QMutex> +#include <QtCore/QWaitCondition> +#include <QtCore/QStringList> +#include <QtCore/QSharedPointer> +#include <QtCore/QString> + +namespace VCSBase { +class VCSBaseEditor; +} + +namespace Mercurial { +namespace Internal { + +class MercurialPlugin; + +class HgTask : public QObject +{ + Q_OBJECT +public: + HgTask(const QString &workingDir, const QStringList &arguments, bool emitRaw=false); + HgTask(const QString &workingDir, const QStringList &arguments, + VCSBase::VCSBaseEditor *editor); + + bool shouldEmit() { return emitRaw; } + VCSBase::VCSBaseEditor* displayEditor() { return editor; } + QStringList args() { return arguments; } + QString repositoryRoot() { return m_repositoryRoot; } + +signals: + void rawData(const QByteArray &data); + +private: + const QString m_repositoryRoot; + const QStringList arguments; + const bool emitRaw; + VCSBase::VCSBaseEditor *editor; +}; + +/* A job queue running in a separate thread, executing commands + * and emitting status/log signals. */ +class MercurialJobRunner : public QThread +{ + Q_OBJECT +public: + MercurialJobRunner(); + ~MercurialJobRunner(); + void enqueueJob(const QSharedPointer<HgTask> &job); + void restart(); + + static QString msgExecute(const QString &binary, const QStringList &args); + static QString msgStartFailed(const QString &binary, const QString &why); + static QString msgTimeout(int timeoutSeconds); + +protected: + void run(); + +signals: + void commandStarted(const QString ¬ice); + void error(const QString &error); + void output(const QByteArray &output); + +private: + void task(const QSharedPointer<HgTask> &job); + void stop(); + void getSettings(); + + QQueue<QSharedPointer<HgTask> > jobs; + QMutex mutex; + QWaitCondition waiter; + MercurialPlugin *plugin; + bool keepRunning; + QString binary; + QStringList standardArguments; + int timeout; +}; + +} //namespace Internal +} //namespace Mercurial +#endif // MERCURIALJOBRUNNER_H diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp new file mode 100644 index 0000000000..97f8df9437 --- /dev/null +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -0,0 +1,696 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialplugin.h" +#include "optionspage.h" +#include "constants.h" +#include "mercurialclient.h" +#include "mercurialcontrol.h" +#include "mercurialeditor.h" +#include "revertdialog.h" +#include "srcdestdialog.h" +#include "commiteditor.h" +#include "clonewizard.h" +#include "mercurialsettings.h" + +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/basemode.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/icore.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/filemanager.h> +#include <coreplugin/editormanager/editormanager.h> + + +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/project.h> +#include <utils/parameteraction.h> + +#include <vcsbase/basevcseditorfactory.h> +#include <vcsbase/basevcssubmiteditorfactory.h> +#include <vcsbase/vcsbaseeditor.h> +#include <vcsbase/vcsbaseoutputwindow.h> + +#include <QtCore/QtPlugin> +#include <QtGui/QAction> +#include <QtGui/QMenu> +#include <QtGui/QMainWindow> +#include <QtCore/QtDebug> +#include <QtCore/QtGlobal> +#include <QtCore/QDir> +#include <QtGui/QDialog> +#include <QtGui/QFileDialog> +#include <QtCore/QTemporaryFile> + + +using namespace Mercurial::Internal; +using namespace Mercurial; + +bool ListenForClose::editorAboutToClose(Core::IEditor *editor) +{ + return MercurialPlugin::instance()->closeEditor(editor); +} + +static const VCSBase::VCSBaseEditorParameters editorParameters[] = { +{ + VCSBase::RegularCommandOutput, //type + Constants::COMMANDLOG, // kind + Constants::COMMANDLOG, // context + Constants::COMMANDAPP, // mime type + Constants::COMMANDEXT}, //extension + +{ VCSBase::LogOutput, + Constants::FILELOG, + Constants::FILELOG, + Constants::LOGAPP, + Constants::LOGEXT}, + +{ VCSBase::AnnotateOutput, + Constants::ANNOTATELOG, + Constants::ANNOTATELOG, + Constants::ANNOTATEAPP, + Constants::ANNOTATEEXT}, + +{ VCSBase::DiffOutput, + Constants::DIFFLOG, + Constants::DIFFLOG, + Constants::DIFFAPP, + Constants::DIFFEXT} +}; + +static const VCSBase::VCSBaseSubmitEditorParameters submitEditorParameters = { + Constants::COMMITMIMETYPE, + Constants::COMMITKIND, + Constants::COMMITKIND +}; + +// Utility to find a parameter set by type +static inline const VCSBase::VCSBaseEditorParameters *findType(int ie) +{ + const VCSBase::EditorContentType et = static_cast<VCSBase::EditorContentType>(ie); + return VCSBase::VCSBaseEditor::findType(editorParameters, + sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters), et); +} + +MercurialPlugin *MercurialPlugin::m_instance = 0; + +MercurialPlugin::MercurialPlugin() : + optionsPage(0), + client(0), + mercurialVC(0), + projectExplorer(0), + changeLog(0) +{ + m_instance = this; +} + +MercurialPlugin::~MercurialPlugin() +{ + if (client) { + delete client; + client = 0; + } + + deleteCommitLog(); + + m_instance = 0; +} + +bool MercurialPlugin::initialize(const QStringList &arguments, QString *error_message) +{ + Q_UNUSED(arguments) + Q_UNUSED(error_message) + + typedef VCSBase::VCSEditorFactory<MercurialEditor> MercurialEditorFactory; + + core = Core::ICore::instance(); + actionManager = core->actionManager(); + + optionsPage = new OptionsPage(); + addAutoReleasedObject(optionsPage); + mercurialSettings.readSettings(core->settings()); + + client = new MercurialClient(); + connect(optionsPage, SIGNAL(settingsChanged()), client, SLOT(settingsChanged())); + + mercurialVC = new MercurialControl(client); + addAutoReleasedObject(mercurialVC); + + static const char *describeSlot = SLOT(view(QString,QString)); + const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters); + for (int i = 0; i < editorCount; i++) + addAutoReleasedObject(new MercurialEditorFactory(editorParameters + i, client, describeSlot)); + + addAutoReleasedObject(new VCSBase::VCSSubmitEditorFactory<CommitEditor>(&submitEditorParameters)); + + addAutoReleasedObject(new CloneWizard); + + addAutoReleasedObject(new ListenForClose); + + createMenu(); + + createSubmitEditorActions(); + + return true; +} + +void MercurialPlugin::extensionsInitialized() +{ + projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (projectExplorer) + connect(projectExplorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project *)), + this, SLOT(currentProjectChanged(ProjectExplorer::Project *))); +} + +const MercurialSettings &MercurialPlugin::settings() const +{ + return mercurialSettings; +} + +void MercurialPlugin::setSettings(const MercurialSettings &settings) +{ + if (settings != mercurialSettings) { + mercurialSettings = settings; + } +} + +QStringList MercurialPlugin::standardArguments() const +{ + return mercurialSettings.standardArguments(); +} + +void MercurialPlugin::createMenu() +{ + QList<int> context = QList<int>()<< core->uniqueIDManager()->uniqueIdentifier(QLatin1String(Core::Constants::C_GLOBAL)); + + // Create menu item for Mercurial + mercurialContainer = actionManager->createMenu(QLatin1String("Mercurial.MercurialMenu")); + QMenu *menu = mercurialContainer->menu(); + menu->setTitle(tr("Mercurial")); + + if (QAction *visibleAction = menu->menuAction()) { + visibleAction->setEnabled(mercurialVC->isEnabled()); + connect(mercurialVC, SIGNAL(enabledChanged(bool)), visibleAction, SLOT(setVisible(bool))); + } + + createFileActions(context); + createSeparator(context, QLatin1String("FileDirSeperator")); + createDirectoryActions(context); + createSeparator(context, QLatin1String("DirRepoSeperator")); + createRepositoryActions(context); + createSeparator(context, QLatin1String("Repository Management")); + createRepositoryManagementActions(context); + createSeparator(context, QLatin1String("LessUsedfunctionality")); + createLessUsedActions(context); + + // Request the Tools menu and add the Mercurial menu to it + Core::ActionContainer *toolsMenu = actionManager->actionContainer(QLatin1String(Core::Constants::M_TOOLS)); + toolsMenu->addMenu(mercurialContainer); + + connect(core, SIGNAL(contextChanged(Core::IContext *)), this, SLOT(updateActions())); + connect(core->fileManager(), SIGNAL(currentFileChanged(const QString &)), + this, SLOT(updateActions())); + +} + +void MercurialPlugin::createFileActions(const QList<int> &context) +{ + Core::Command *command; + + annotateFile = new Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); + command = actionManager->registerAction(annotateFile, QLatin1String(Constants::ANNOTATE), context); + command->setAttribute(Core::Command::CA_UpdateText); + connect(annotateFile, SIGNAL(triggered()), this, SLOT(annotateCurrentFile())); + mercurialContainer->addAction(command); + + diffFile = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); + command = actionManager->registerAction(diffFile, QLatin1String(Constants::DIFF), context); + command->setAttribute(Core::Command::CA_UpdateText); + command->setDefaultKeySequence(QKeySequence(tr("Alt+H,Alt+D"))); + connect(diffFile, SIGNAL(triggered()), this, SLOT(diffCurrentFile())); + mercurialContainer->addAction(command); + + logFile = new Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); + command = actionManager->registerAction(logFile, QLatin1String(Constants::LOG), context); + command->setAttribute(Core::Command::CA_UpdateText); + command->setDefaultKeySequence(QKeySequence(tr("Alt+H,Alt+L"))); + connect(logFile, SIGNAL(triggered()), this, SLOT(logCurrentFile())); + mercurialContainer->addAction(command); + + revertFile = new Utils::ParameterAction(tr("Revert Current File"), tr("Revert \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); + command = actionManager->registerAction(revertFile, QLatin1String(Constants::REVERT), context); + command->setAttribute(Core::Command::CA_UpdateText); + connect(revertFile, SIGNAL(triggered()), this, SLOT(revertCurrentFile())); + mercurialContainer->addAction(command); + + statusFile = new Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); + command = actionManager->registerAction(statusFile, QLatin1String(Constants::STATUS), context); + command->setAttribute(Core::Command::CA_UpdateText); + command->setDefaultKeySequence(QKeySequence(tr("Alt+H,Alt+S"))); + connect(statusFile, SIGNAL(triggered()), this, SLOT(statusCurrentFile())); + mercurialContainer->addAction(command); +} + +void MercurialPlugin::annotateCurrentFile() +{ + client->annotate(currentFile()); +} + +void MercurialPlugin::diffCurrentFile() +{ + client->diff(currentFile()); +} + +void MercurialPlugin::logCurrentFile() +{ + client->log(currentFile()); +} + +void MercurialPlugin::revertCurrentFile() +{ + RevertDialog reverter; + if (reverter.exec() != QDialog::Accepted) + return; + client->revert(currentFile(), reverter.revision()); +} + +void MercurialPlugin::statusCurrentFile() +{ + client->status(currentFile()); +} + +void MercurialPlugin::createDirectoryActions(const QList<int> &context) +{ + QAction *action; + Core::Command *command; + + action = new QAction(tr("Diff"), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::DIFFMULTI), context); + connect(action, SIGNAL(triggered()), this, SLOT(diffRepository())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Log"), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::LOGMULTI), context); + connect(action, SIGNAL(triggered()), this, SLOT(logRepository())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Revert..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::REVERTMULTI), context); + connect(action, SIGNAL(triggered()), this, SLOT(revertMulti())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Status"), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::STATUSMULTI), context); + connect(action, SIGNAL(triggered()), this, SLOT(statusMulti())); + mercurialContainer->addAction(command); +} + +void MercurialPlugin::diffRepository() +{ + client->diff(currentProjectRoot()); +} + +void MercurialPlugin::logRepository() +{ + client->log(currentProjectRoot()); +} + +void MercurialPlugin::revertMulti() +{ + RevertDialog reverter; + if (reverter.exec() != QDialog::Accepted) + return; + client->revert(currentProjectRoot(), reverter.revision()); +} + +void MercurialPlugin::statusMulti() +{ + client->status(currentProjectRoot()); +} + +void MercurialPlugin::createRepositoryActions(const QList<int> &context) +{ + QAction *action = new QAction(tr("Pull..."), this); + actionList.append(action); + Core::Command *command = actionManager->registerAction(action, QLatin1String(Constants::PULL), context); + connect(action, SIGNAL(triggered()), this, SLOT(pull())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Push..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::PUSH), context); + connect(action, SIGNAL(triggered()), this, SLOT(push())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Update..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::UPDATE), context); + connect(action, SIGNAL(triggered()), this, SLOT(update())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Import..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::IMPORT), context); + connect(action, SIGNAL(triggered()), this, SLOT(import())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Incoming..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::INCOMING), context); + connect(action, SIGNAL(triggered()), this, SLOT(incoming())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Outgoing..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::OUTGOING), context); + connect(action, SIGNAL(triggered()), this, SLOT(outgoing())); + mercurialContainer->addAction(command); + + action = new QAction(tr("Commit..."), this); + actionList.append(action); + command = actionManager->registerAction(action, QLatin1String(Constants::COMMIT), context); + command->setDefaultKeySequence(QKeySequence(tr("Alt+H,Alt+C"))); + connect(action, SIGNAL(triggered()), this, SLOT(commit())); + mercurialContainer->addAction(command); +} + +void MercurialPlugin::pull() +{ + SrcDestDialog dialog; + dialog.setWindowTitle(tr("Pull Source")); + if (dialog.exec() != QDialog::Accepted) + return; + QString repository = dialog.getRepositoryString(); + client->pull(currentProjectRoot(), repository); +} + +void MercurialPlugin::push() +{ + SrcDestDialog dialog; + dialog.setWindowTitle(tr("Push Destination")); + if (dialog.exec() != QDialog::Accepted) + return; + QString repository = dialog.getRepositoryString(); + client->push(currentProjectRoot(), repository); +} + +void MercurialPlugin::update() +{ + RevertDialog updateDialog; + updateDialog.setWindowTitle(tr("Update")); + if (updateDialog.exec() != QDialog::Accepted) + return; + client->update(currentProjectRoot(), updateDialog.revision()); +} + +void MercurialPlugin::import() +{ + QFileDialog importDialog; + importDialog.setFileMode(QFileDialog::ExistingFiles); + importDialog.setViewMode(QFileDialog::Detail); + + if (importDialog.exec() != QDialog::Accepted) + return; + + const QStringList fileNames = importDialog.selectedFiles(); + client->import(currentProjectRoot(), fileNames); +} + +void MercurialPlugin::incoming() +{ + SrcDestDialog dialog; + dialog.setWindowTitle(tr("Incoming Source")); + if (dialog.exec() != QDialog::Accepted) + return; + QString repository = dialog.getRepositoryString(); + client->incoming(currentProjectRoot(), repository); +} + +void MercurialPlugin::outgoing() +{ + client->outgoing(currentProjectRoot()); +} + +void MercurialPlugin::createSubmitEditorActions() +{ + QList<int> context = QList<int>()<< core->uniqueIDManager()->uniqueIdentifier(QLatin1String(Constants::COMMITKIND)); + Core::Command *command; + + editorCommit = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); + command = actionManager->registerAction(editorCommit, QLatin1String(Constants::COMMIT), context); + connect(editorCommit, SIGNAL(triggered()), this, SLOT(commitFromEditor())); + + editorDiff = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); + command = actionManager->registerAction(editorDiff, QLatin1String(Constants::DIFFEDITOR), context); + + editorUndo = new QAction(tr("&Undo"), this); + command = actionManager->registerAction(editorUndo, QLatin1String(Core::Constants::UNDO), context); + + editorRedo = new QAction(tr("&Redo"), this); + command = actionManager->registerAction(editorRedo, QLatin1String(Core::Constants::REDO), context); +} + +void MercurialPlugin::commit() +{ + if (VCSBase::VCSBaseSubmitEditor::raiseSubmitEditor()) + return; + + connect(client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), + this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); + client->statusWithSignal(currentProjectRoot()); +} + +void MercurialPlugin::showCommitWidget(const QList<QPair<QString, QString> > &status) +{ + + VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); + //Once we receive our data release the connection so it can be reused elsewhere + disconnect(client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), + this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); + + if (status.isEmpty()) { + outputWindow->appendError(tr("There are no changes to commit.")); + return; + } + + deleteCommitLog(); + + changeLog = new QTemporaryFile(this); + if (!changeLog->open()) { + outputWindow->appendError(tr("Unable to generate a temporary file for the commit editor.")); + return; + } + + Core::IEditor *editor = core->editorManager()->openEditor(changeLog->fileName(), + QLatin1String(Constants::COMMITKIND)); + if (!editor) { + outputWindow->appendError(tr("Unable to create an editor for the commit.")); + return; + } + + core->editorManager()->ensureEditorManagerVisible(); + + CommitEditor *commitEditor = qobject_cast<CommitEditor *>(editor); + + if (!commitEditor) { + outputWindow->appendError(tr("Unable to create a commit editor.")); + return; + } + const QString msg = tr("Commit changes for \"%1\".").arg(currentProjectName()); + commitEditor->setDisplayName(msg); + + QString branch = client->branchQuerySync(currentProjectRoot()); + + commitEditor->setFields(currentProjectRoot(), branch, mercurialSettings.userName(), + mercurialSettings.email(), status); + + commitEditor->registerActions(editorUndo, editorRedo, editorCommit, editorDiff); + connect(commitEditor, SIGNAL(diffSelectedFiles(const QStringList &)), + this, SLOT(diffFromEditorSelected(const QStringList &))); +} + +void MercurialPlugin::diffFromEditorSelected(const QStringList &files) +{ + foreach (const QString &file, files) { + const QFileInfo toDiff(QDir(currentProjectRoot().absoluteFilePath()).absoluteFilePath(file)); + client->diff(toDiff); + } +} + +void MercurialPlugin::commitFromEditor() +{ + if (!changeLog) + return; + + //use the same functionality than if the user closes the file without completing the commit + core->editorManager()->closeEditors(core->editorManager()->editorsForFileName(changeLog->fileName())); +} + +bool MercurialPlugin::closeEditor(Core::IEditor *editor) +{ + if (!changeLog || !editor || qstrcmp(editor->kind(), Constants::COMMITKIND)) + return true; + Core::IFile *editorFile = editor->file(); + CommitEditor *commitEditor = qobject_cast<CommitEditor *>(editor); + if (!editorFile || !commitEditor) + return true; + + bool dummyPrompt = mercurialSettings.prompt(); + const VCSBase::VCSBaseSubmitEditor::PromptSubmitResult response = + commitEditor->promptSubmit(tr("Close commit editor"), tr("Do you want to commit the changes?"), + tr("Message check failed. Do you want to proceed?"), + &dummyPrompt, mercurialSettings.prompt()); + + switch (response) { + case VCSBase::VCSBaseSubmitEditor::SubmitCanceled: + return false; + case VCSBase::VCSBaseSubmitEditor::SubmitDiscarded: + deleteCommitLog(); + return true; + default: + break; + } + + const QStringList files = commitEditor->checkedFiles(); + if (!files.empty()) { + //save the commit message + core->fileManager()->blockFileChange(editorFile); + editorFile->save(); + core->fileManager()->unblockFileChange(editorFile); + + const QFileInfo repoRoot(commitEditor->repoRoot()); + client->commit(repoRoot, files, commitEditor->committerInfo(), + editorFile->fileName()); + } + return true; +} +void MercurialPlugin::deleteCommitLog() +{ + if (changeLog) { + delete changeLog; + changeLog = 0; + } +} + +void MercurialPlugin::createRepositoryManagementActions(const QList<int> &context) +{ + //TODO create menu for these options + Q_UNUSED(context); + return; + // QAction *action = new QAction(tr("Branch"), this); + // actionList.append(action); + // Core::Command *command = actionManager->registerAction(action, Constants::BRANCH, context); + // // connect(action, SIGNAL(triggered()), this, SLOT(branch())); + // mercurialContainer->addAction(command); +} + +void MercurialPlugin::createLessUsedActions(const QList<int> &context) +{ + //TODO create menue for these options + Q_UNUSED(context); + return; +} + +void MercurialPlugin::createSeparator(const QList<int> &context, const QString &id) +{ + QAction *action = new QAction(this); + action->setSeparator(true); + mercurialContainer->addAction(actionManager->registerAction(action, id, context)); +} + +void MercurialPlugin::updateActions() +{ + const QFileInfo file = currentFile(); + const QString filename = file.fileName(); + const QString repoRoot = client->findTopLevelForFile(file); + bool enable = false; + + //File menu Items should only be enabled for files that are below a mercurial repository + enable = !repoRoot.isEmpty(); + annotateFile->setParameter(filename); + annotateFile->setEnabled(enable); + diffFile->setParameter(filename); + diffFile->setEnabled(enable); + logFile->setParameter(filename); + logFile->setEnabled(enable); + revertFile->setParameter(filename); + revertFile->setEnabled(enable); + statusFile->setParameter(filename); + statusFile->setEnabled(enable); + + //repository actions + if (projectMapper.contains(currentProjectName())) + enable = true; + else + enable = false; + + foreach (QAction *action, actionList) + action->setEnabled(enable); +} + +QFileInfo MercurialPlugin::currentFile() +{ + QString fileName = core->fileManager()->currentFile(); + QFileInfo fileInfo(fileName); + return fileInfo; +} + +QString MercurialPlugin::currentProjectName() +{ + if (projectExplorer) + if (projectExplorer->currentProject()) + return projectExplorer->currentProject()->name(); + return QString(); +} + +void MercurialPlugin::currentProjectChanged(ProjectExplorer::Project *project) +{ + if (!project) + return; + + if (projectMapper.contains(project->name())) + return; + + QString repoRoot = client->findTopLevelForFile(QFileInfo(project->file()->fileName())); + + if (!repoRoot.isEmpty()) + projectMapper.insert(project->name(), QFileInfo(repoRoot)); +} + +QFileInfo MercurialPlugin::currentProjectRoot() +{ + return projectMapper.value(currentProjectName()); +} + +Q_EXPORT_PLUGIN(MercurialPlugin) diff --git a/src/plugins/mercurial/mercurialplugin.h b/src/plugins/mercurial/mercurialplugin.h new file mode 100644 index 0000000000..84654eb1f9 --- /dev/null +++ b/src/plugins/mercurial/mercurialplugin.h @@ -0,0 +1,193 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALPLUGIN_H +#define MERCURIALPLUGIN_H + +#include "mercurialsettings.h" + +#include <extensionsystem/iplugin.h> +#include <coreplugin/icorelistener.h> + +#include <QtCore/QFileInfo> +#include <QtCore/QHash> +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE +class QAction; +class QTemporaryFile; +QT_END_NAMESPACE + +namespace Core { +class ActionManager; +class ActionContainer; +class ICore; +class IVersionControl; +class IEditorFactory; +class IEditor; +} // namespace Core + +namespace Utils { +class ParameterAction; +} //namespace Utils + +namespace ProjectExplorer { +class ProjectExplorerPlugin; +class Project; +} + +namespace Mercurial { +namespace Internal { + +class OptionsPage; +class MercurialClient; +class MercurialControl; +class MercurialEditor; +class MercurialSettings; + +class MercurialPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT + +public: + MercurialPlugin(); + virtual ~MercurialPlugin(); + bool initialize(const QStringList &arguments, QString *error_message); + void extensionsInitialized(); + static MercurialPlugin *instance() { return m_instance; } + QFileInfo currentFile(); + QString currentProjectName(); + QFileInfo currentProjectRoot(); + bool closeEditor(Core::IEditor *editor); + QStringList standardArguments() const; + + const MercurialSettings &settings() const; + void setSettings(const MercurialSettings &settings); + +private slots: + // File menu action Slots + void annotateCurrentFile(); + void diffCurrentFile(); + void logCurrentFile(); + void revertCurrentFile(); + void statusCurrentFile(); + + //Directory menu Action slots + void diffRepository(); + void logRepository(); + void revertMulti(); + void statusMulti(); + + //repository menu action slots + void pull(); + void push(); + void update(); + void import(); + void incoming(); + void outgoing(); + void commit(); + void showCommitWidget(const QList<QPair<QString, QString> > &status); + void commitFromEditor(); + void diffFromEditorSelected(const QStringList &files); + + //TODO implement + /* //repository management action slots + void merge(); + void branch(); + void heads(); + void parents(); + void tags(); + void tip(); + void paths(); + + //less used repository action + void init(); + void serve();*/ + + //change the sates of the actions in the Mercurial Menu i.e. 2 be context sensitive + void updateActions(); + void currentProjectChanged(ProjectExplorer::Project *project); + + +private: + //methods + void createMenu(); + void createSubmitEditorActions(); + void createSeparator(const QList<int> &context, const QString &id); + void createFileActions(const QList<int> &context); + void createDirectoryActions(const QList<int> &context); + void createRepositoryActions(const QList<int> &context); + void createRepositoryManagementActions(const QList<int> &context); + void createLessUsedActions(const QList<int> &context); + void deleteCommitLog(); + + //Variables + static MercurialPlugin *m_instance; + MercurialSettings mercurialSettings; + OptionsPage *optionsPage; + MercurialClient *client; + + Core::IVersionControl *mercurialVC; + Core::ICore *core; + Core::ActionManager *actionManager; + Core::ActionContainer *mercurialContainer; + ProjectExplorer::ProjectExplorerPlugin *projectExplorer; + + //provide a mapping of projectName -> repositoryRoot for each project + QHash<QString, QFileInfo> projectMapper; + QList<QAction *> actionList; + QTemporaryFile *changeLog; + + //Menu Items (file actions) + Utils::ParameterAction *annotateFile; + Utils::ParameterAction *diffFile; + Utils::ParameterAction *logFile; + Utils::ParameterAction *renameFile; + Utils::ParameterAction *revertFile; + Utils::ParameterAction *statusFile; + + //submit editor actions + QAction *editorCommit; + QAction *editorDiff; + QAction *editorUndo; + QAction *editorRedo; +}; + +class ListenForClose : public Core::ICoreListener +{ + Q_OBJECT +public: + ListenForClose(QObject *parent=0) : Core::ICoreListener(parent) {} + bool editorAboutToClose(Core::IEditor *editor); +}; + +} //namespace Internal +} //namespace Mercurial + +#endif // MERCURIALPLUGIN_H diff --git a/src/plugins/mercurial/mercurialsettings.cpp b/src/plugins/mercurial/mercurialsettings.cpp new file mode 100644 index 0000000000..1105b308f4 --- /dev/null +++ b/src/plugins/mercurial/mercurialsettings.cpp @@ -0,0 +1,149 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "mercurialsettings.h" +#include "constants.h" + +#include <QtCore/QSettings> + +using namespace Mercurial::Internal; + +enum { timeOutDefaultSeconds = 30 }; + +MercurialSettings::MercurialSettings() : + m_binary(QLatin1String(Constants::MERCURIALDEFAULT)), + m_logCount(0), + m_timeoutSeconds(timeOutDefaultSeconds), + m_prompt(true) +{ +} + +QString MercurialSettings::binary() const +{ + return m_binary; +} + +void MercurialSettings::setBinary(const QString &b) +{ + m_binary = b; +} + +QStringList MercurialSettings::standardArguments() const +{ + return m_standardArguments; +} + +QString MercurialSettings::userName() const +{ + return m_user; +} + +void MercurialSettings::setUserName(const QString &u) +{ + m_user = u; +} + +QString MercurialSettings::email() const +{ + return m_mail; +} + +void MercurialSettings::setEmail(const QString &m) +{ + m_mail = m; +} + +int MercurialSettings::logCount() const +{ + return m_logCount; +} + +void MercurialSettings::setLogCount(int l) +{ + m_logCount = l; +} + +int MercurialSettings::timeoutMilliSeconds() const +{ + //return timeout is in Ms + return m_timeoutSeconds * 1000; +} + +int MercurialSettings::timeoutSeconds() const +{ + //return timeout in seconds (as the user specifies on the options page + return m_timeoutSeconds; +} + +void MercurialSettings::setTimeoutSeconds(int s) +{ + m_timeoutSeconds = s; +} + +bool MercurialSettings::prompt() const +{ + return m_prompt; +} + +void MercurialSettings::setPrompt(bool b) +{ + m_prompt = b; +} + +void MercurialSettings::writeSettings(QSettings *settings) const +{ + settings->beginGroup(QLatin1String("Mercurial")); + settings->setValue(QLatin1String(Constants::MERCURIALPATH), m_binary); + settings->setValue(QLatin1String(Constants::MERCURIALUSERNAME), m_user); + settings->setValue(QLatin1String(Constants::MERCURIALEMAIL), m_mail); + settings->setValue(QLatin1String(Constants::MERCURIALLOGCOUNT), m_logCount); + settings->setValue(QLatin1String(Constants::MERCURIALTIMEOUT), m_timeoutSeconds); + settings->setValue(QLatin1String(Constants::MERCURIALPROMPTSUBMIT), m_prompt); + settings->endGroup(); +} + +void MercurialSettings::readSettings(const QSettings *settings) +{ + const QString keyRoot = QLatin1String("Mercurial/"); + m_binary = settings->value(keyRoot + QLatin1String(Constants::MERCURIALPATH), + QLatin1String(Constants::MERCURIALDEFAULT)).toString(); + m_user = settings->value(keyRoot + QLatin1String(Constants::MERCURIALUSERNAME), QString()).toString(); + m_mail = settings->value(keyRoot + QLatin1String(Constants::MERCURIALEMAIL), QString()).toString(); + m_logCount = settings->value(keyRoot + QLatin1String(Constants::MERCURIALLOGCOUNT), 0).toInt(); + m_timeoutSeconds = settings->value(keyRoot + QLatin1String(Constants::MERCURIALTIMEOUT), timeOutDefaultSeconds).toInt(); + m_prompt = settings->value(keyRoot + QLatin1String(Constants::MERCURIALPROMPTSUBMIT), true).toBool(); +} + +bool MercurialSettings::equals(const MercurialSettings &rhs) const +{ + return m_binary == rhs.m_binary && m_standardArguments == rhs.m_standardArguments + && m_user == rhs.m_user && m_mail == rhs.m_mail + && m_logCount == rhs.m_logCount && m_timeoutSeconds == rhs.m_timeoutSeconds + && m_prompt == rhs.m_prompt; +} diff --git a/src/plugins/mercurial/mercurialsettings.h b/src/plugins/mercurial/mercurialsettings.h new file mode 100644 index 0000000000..57304fa781 --- /dev/null +++ b/src/plugins/mercurial/mercurialsettings.h @@ -0,0 +1,96 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MERCURIALSETTINGS_H +#define MERCURIALSETTINGS_H + +#include <QtCore/QString> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace Mercurial { +namespace Internal { + +class MercurialSettings +{ +public: + MercurialSettings(); + + QString binary() const; + void setBinary(const QString &); + + // Calculated. + QStringList standardArguments() const; + + QString userName() const; + void setUserName(const QString &); + + QString email() const; + void setEmail(const QString &); + + int logCount() const; + void setLogCount(int l); + + int timeoutMilliSeconds() const; + int timeoutSeconds() const; + void setTimeoutSeconds(int s); + + bool prompt() const; + void setPrompt(bool b); + + void writeSettings(QSettings *settings) const; + void readSettings(const QSettings *settings); + + bool equals(const MercurialSettings &rhs) const; + +private: + + void readSettings(); + + QString m_binary; + QStringList m_standardArguments; + QString m_user; + QString m_mail; + int m_logCount; + int m_timeoutSeconds; + bool m_prompt; +}; + +inline bool operator==(const MercurialSettings &s1, const MercurialSettings &s2) +{ return s1.equals(s2); } +inline bool operator!=(const MercurialSettings &s1, const MercurialSettings &s2) +{ return !s1.equals(s2); } + +} //namespace Internal +} //namespace Mercurial + +#endif // MERCURIALSETTINGS_H diff --git a/src/plugins/mercurial/optionspage.cpp b/src/plugins/mercurial/optionspage.cpp new file mode 100644 index 0000000000..538dd77275 --- /dev/null +++ b/src/plugins/mercurial/optionspage.cpp @@ -0,0 +1,116 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "optionspage.h" +#include "mercurialsettings.h" +#include "mercurialplugin.h" + +#include <coreplugin/icore.h> +#include <utils/pathchooser.h> +#include <vcsbase/vcsbaseconstants.h> + +using namespace Mercurial::Internal; +using namespace Mercurial; + +OptionsPageWidget::OptionsPageWidget(QWidget *parent) : + QWidget(parent) +{ + m_ui.setupUi(this); + m_ui.commandChooser->setExpectedKind(Utils::PathChooser::Command); + m_ui.commandChooser->setPromptDialogTitle(tr("Mercurial Command")); +} + +MercurialSettings OptionsPageWidget::settings() const +{ + MercurialSettings rc; + rc.setBinary(m_ui.commandChooser->path()); + rc.setUserName(m_ui.defaultUsernameLineEdit->text().trimmed()); + rc.setEmail(m_ui.defaultEmailLineEdit->text().trimmed()); + rc.setLogCount(m_ui.logEntriesCount->value()); + rc.setTimeoutSeconds(m_ui.timeout->value()); + rc.setPrompt(m_ui.promptOnSubmitCheckBox->isChecked()); + return rc; +} + +void OptionsPageWidget::setSettings(const MercurialSettings &s) +{ + m_ui.commandChooser->setPath(s.binary()); + m_ui.defaultUsernameLineEdit->setText(s.userName()); + m_ui.defaultEmailLineEdit->setText(s.email()); + m_ui.logEntriesCount->setValue(s.logCount()); + m_ui.timeout->setValue(s.timeoutSeconds()); + m_ui.promptOnSubmitCheckBox->setChecked(s.prompt()); +} + +OptionsPage::OptionsPage() +{ +} + +QString OptionsPage::id() const +{ + return QLatin1String("Mercurial"); +} + +QString OptionsPage::trName() const +{ + return tr("Mercurial"); +} + +QString OptionsPage::category() const +{ + return QLatin1String(VCSBase::Constants::VCS_SETTINGS_CATEGORY); +} + +QString OptionsPage::trCategory() const +{ + return QCoreApplication::translate("VCSBase", VCSBase::Constants::VCS_SETTINGS_CATEGORY); +} + +QWidget *OptionsPage::createPage(QWidget *parent) +{ + if (!optionsPageWidget) + optionsPageWidget = new OptionsPageWidget(parent); + optionsPageWidget->setSettings(MercurialPlugin::instance()->settings()); + return optionsPageWidget; +} + +void OptionsPage::apply() +{ + if (!optionsPageWidget) + return; + MercurialPlugin *plugin = MercurialPlugin::instance(); + const MercurialSettings newSettings = optionsPageWidget->settings(); + if (newSettings != plugin->settings()) { + //assume success and emit signal that settings are changed; + plugin->setSettings(newSettings); + newSettings.writeSettings(Core::ICore::instance()->settings()); + emit settingsChanged(); + } +} + diff --git a/src/plugins/mercurial/optionspage.h b/src/plugins/mercurial/optionspage.h new file mode 100644 index 0000000000..362a435a07 --- /dev/null +++ b/src/plugins/mercurial/optionspage.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef OPTIONSPAGE_H +#define OPTIONSPAGE_H + +#include "ui_optionspage.h" + +#include <coreplugin/dialogs/ioptionspage.h> + +#include <QtGui/QWidget> +#include <QtCore/QPointer> + +namespace Mercurial { +namespace Internal { + +class MercurialSettings; + +class OptionsPageWidget : public QWidget +{ + Q_OBJECT +public: + explicit OptionsPageWidget(QWidget *parent = 0); + + MercurialSettings settings() const; + void setSettings(const MercurialSettings &s); + +private: + Ui::OptionsPage m_ui; +}; + + +class OptionsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + OptionsPage(); + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + + QWidget *createPage(QWidget *parent); + void apply(); + void finish() { } + +signals: + void settingsChanged(); + +private: + QPointer<OptionsPageWidget> optionsPageWidget; +}; + +} // namespace Internal +} // namespace Mercurial + +#endif // OPTIONSPAGE_H diff --git a/src/plugins/mercurial/optionspage.ui b/src/plugins/mercurial/optionspage.ui new file mode 100644 index 0000000000..591aa03e7c --- /dev/null +++ b/src/plugins/mercurial/optionspage.ui @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Mercurial::Internal::OptionsPage</class> + <widget class="QWidget" name="Mercurial::Internal::OptionsPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="mercurialCommandLabel"> + <property name="text"> + <string>Mercurial Command:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="Utils::PathChooser" name="commandChooser" native="true"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="showLogEntriesLabel"> + <property name="text"> + <string>Show Log Entries:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSpinBox" name="logEntriesCount"> + <property name="toolTip"> + <string>The number of recent commit logs to show, choose 0 to see all enteries</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="timeoutSecondsLabel"> + <property name="text"> + <string>Timeout (Seconds):</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QSpinBox" name="timeout"> + <property name="value"> + <number>30</number> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="promptOnSubmitLabel"> + <property name="text"> + <string>Prompt On Submit</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QCheckBox" name="promptOnSubmitCheckBox"> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="defaultUsernameLabel"> + <property name="toolTip"> + <string>Username to use by default on commit.</string> + </property> + <property name="text"> + <string>Default Username:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="defaultUsernameLineEdit"> + <property name="toolTip"> + <string>Username to use by default on commit.</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="defaultEmailLabel"> + <property name="toolTip"> + <string>Email to use by default on commit.</string> + </property> + <property name="text"> + <string>Default Email:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="defaultEmailLineEdit"> + <property name="toolTip"> + <string>Email to use by default on commit.</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/mercurial/revertdialog.cpp b/src/plugins/mercurial/revertdialog.cpp new file mode 100644 index 0000000000..2a667c8095 --- /dev/null +++ b/src/plugins/mercurial/revertdialog.cpp @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "revertdialog.h" + +using namespace Mercurial::Internal; + +RevertDialog::RevertDialog(QWidget *parent) : + QDialog(parent), + m_ui(new Ui::RevertDialog) +{ + m_ui->setupUi(this); +} + +RevertDialog::~RevertDialog() +{ + delete m_ui; +} + +void RevertDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + m_ui->retranslateUi(this); + break; + default: + break; + } +} + +QString RevertDialog::revision() const +{ + return m_ui->revisionLineEdit->text(); +} diff --git a/src/plugins/mercurial/revertdialog.h b/src/plugins/mercurial/revertdialog.h new file mode 100644 index 0000000000..c77822dd61 --- /dev/null +++ b/src/plugins/mercurial/revertdialog.h @@ -0,0 +1,59 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef REVERTDIALOG_H +#define REVERTDIALOG_H + +#include "ui_revertdialog.h" + +#include <QtGui/QDialog> + + +namespace Mercurial { +namespace Internal { + +class RevertDialog : public QDialog +{ + Q_OBJECT +public: + RevertDialog(QWidget *parent = 0); + ~RevertDialog(); + + QString revision() const; + +protected: + void changeEvent(QEvent *e); + +private: + Ui::RevertDialog *m_ui; +}; + +} // namespace Internal +} // namespace Mercurial +#endif // REVERTDIALOG_H diff --git a/src/plugins/mercurial/revertdialog.ui b/src/plugins/mercurial/revertdialog.ui new file mode 100644 index 0000000000..66876dc6f9 --- /dev/null +++ b/src/plugins/mercurial/revertdialog.ui @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Mercurial::Internal::RevertDialog</class> + <widget class="QDialog" name="Mercurial::Internal::RevertDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>162</height> + </rect> + </property> + <property name="windowTitle"> + <string>Revert</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Specify a revision other than the default?</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <widget class="QWidget" name="formLayoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>30</y> + <width>361</width> + <height>51</height> + </rect> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="revisionLabel"> + <property name="text"> + <string>Revision:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="revisionLineEdit"/> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Mercurial::Internal::RevertDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Mercurial::Internal::RevertDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/plugins/mercurial/srcdestdialog.cpp b/src/plugins/mercurial/srcdestdialog.cpp new file mode 100644 index 0000000000..e3d3e956b8 --- /dev/null +++ b/src/plugins/mercurial/srcdestdialog.cpp @@ -0,0 +1,74 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "srcdestdialog.h" +#include "ui_srcdestdialog.h" + + +using namespace Mercurial::Internal; + +SrcDestDialog::SrcDestDialog(QWidget *parent) : + QDialog(parent), + m_ui(new Ui::SrcDestDialog) +{ + m_ui->setupUi(this); + m_ui->localPathChooser->setExpectedKind(Utils::PathChooser::Directory); +} + +SrcDestDialog::~SrcDestDialog() +{ + delete m_ui; +} + +void SrcDestDialog::setPathChooserKind(Utils::PathChooser::Kind kind) +{ + m_ui->localPathChooser->setExpectedKind(kind); +} + +QString SrcDestDialog::getRepositoryString() const +{ + if (m_ui->defaultButton->isChecked()) + return QString(); + else if (m_ui->localButton->isChecked()) + return m_ui->localPathChooser->path(); + else + return m_ui->urlLineEdit->text(); +} + +void SrcDestDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + m_ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/plugins/mercurial/srcdestdialog.h b/src/plugins/mercurial/srcdestdialog.h new file mode 100644 index 0000000000..1dd40bf3cb --- /dev/null +++ b/src/plugins/mercurial/srcdestdialog.h @@ -0,0 +1,62 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Brian McGillion +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef SRCDESTDIALOG_H +#define SRCDESTDIALOG_H + +#include <QtGui/QDialog> +#include <utils/pathchooser.h> + +namespace Mercurial { +namespace Internal { + +namespace Ui { +class SrcDestDialog; +} + +class SrcDestDialog : public QDialog +{ + Q_OBJECT +public: + + SrcDestDialog(QWidget *parent = 0); + ~SrcDestDialog(); + void setPathChooserKind(Utils::PathChooser::Kind kind); + QString getRepositoryString() const; + +protected: + void changeEvent(QEvent *e); + +private: + Ui::SrcDestDialog *m_ui; +}; + +} // namespace Internal +} // namespace Mercurial +#endif // SRCDESTDIALOG_H diff --git a/src/plugins/mercurial/srcdestdialog.ui b/src/plugins/mercurial/srcdestdialog.ui new file mode 100644 index 0000000000..b72790bf37 --- /dev/null +++ b/src/plugins/mercurial/srcdestdialog.ui @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Mercurial::Internal::SrcDestDialog</class> + <widget class="QDialog" name="Mercurial::Internal::SrcDestDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>187</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QRadioButton" name="defaultButton"> + <property name="text"> + <string>Default Location:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="localButton"> + <property name="text"> + <string>Local filesystem:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QRadioButton" name="urlButton"> + <property name="toolTip"> + <string>e.g. https://[user[:pass]@]host[:port]/[path]</string> + </property> + <property name="text"> + <string>Specify Url:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="Utils::PathChooser" name="localPathChooser" native="true"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="urlLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>e.g. https://[user[:pass]@]host[:port]/[path]</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Mercurial::Internal::SrcDestDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>257</x> + <y>177</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Mercurial::Internal::SrcDestDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>325</x> + <y>177</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>urlButton</sender> + <signal>toggled(bool)</signal> + <receiver>urlLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>80</x> + <y>121</y> + </hint> + <hint type="destinationlabel"> + <x>332</x> + <y>123</y> + </hint> + </hints> + </connection> + <connection> + <sender>localButton</sender> + <signal>toggled(bool)</signal> + <receiver>localPathChooser</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>112</x> + <y>81</y> + </hint> + <hint type="destinationlabel"> + <x>346</x> + <y>81</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/plugins/perforce/Perforce.pluginspec b/src/plugins/perforce/Perforce.pluginspec index 2fdb241f3d..6bea51279a 100644 --- a/src/plugins/perforce/Perforce.pluginspec +++ b/src/plugins/perforce/Perforce.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Perforce" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Perforce" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Perforce integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> - <dependency name="VCSBase" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="VCSBase" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index c74bda15a2..77cf85e11d 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -34,6 +34,7 @@ SUBDIRS = plugin_coreplugin \ plugin_genericprojectmanager \ plugin_qmleditor \ plugin_qmlprojectmanager \ + plugin_mercurial \ debugger/dumper.pro plugin_coreplugin.subdir = coreplugin @@ -178,3 +179,9 @@ plugin_qmlprojectmanager.depends = plugin_texteditor plugin_qmlprojectmanager.depends += plugin_projectexplorer plugin_qmlprojectmanager.depends += plugin_help plugin_qmlprojectmanager.depends += plugin_qmleditor + +plugin_mercurial.subdir = mercurial +plugin_mercurial.depends = plugin_texteditor +plugin_mercurial.depends = plugin_vcsbase +plugin_mercurial.depends += plugin_projectexplorer +plugin_mercurial.depends += plugin_coreplugin diff --git a/src/plugins/projectexplorer/ProjectExplorer.pluginspec b/src/plugins/projectexplorer/ProjectExplorer.pluginspec index d4224a2790..26626faacd 100644 --- a/src/plugins/projectexplorer/ProjectExplorer.pluginspec +++ b/src/plugins/projectexplorer/ProjectExplorer.pluginspec @@ -1,4 +1,4 @@ -<plugin name="ProjectExplorer" version="1.3.0" compatVersion="1.3.0"> +<plugin name="ProjectExplorer" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>ProjectExplorer framework that can be extended with different kind of project types.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="Find" version="1.3.0"/> - <dependency name="Locator" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="Find" version="1.3.80"/> + <dependency name="Locator" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 14ecc4bfd0..9267103556 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -86,6 +86,8 @@ BuildManager::BuildManager(ProjectExplorerPlugin *parent) m_taskWindow = new TaskWindow; pm->addObject(m_taskWindow); + m_taskWindow->addCategory(Constants::TASK_CATEGORY_COMPILE, tr("Compile", "Category for compiler isses listened under 'Build Issues'")); + connect(m_taskWindow, SIGNAL(tasksChanged()), this, SIGNAL(tasksChanged())); @@ -179,7 +181,7 @@ void BuildManager::toggleTaskWindow() bool BuildManager::tasksAvailable() const { - return m_taskWindow->numberOfTasks() > 0; + return m_taskWindow->taskCount() > 0; } void BuildManager::gotoTaskWindow() @@ -210,7 +212,7 @@ void BuildManager::startBuildQueue() m_canceling = false; m_progressFutureInterface->reportStarted(); m_outputWindow->clearContents(); - m_taskWindow->clearContents(); + m_taskWindow->clearTasks(Constants::TASK_CATEGORY_COMPILE); nextStep(); } else { // Already running @@ -221,7 +223,7 @@ void BuildManager::startBuildQueue() void BuildManager::showBuildResults() { - if (m_taskWindow->numberOfTasks() != 0) + if (m_taskWindow->taskCount() != 0) toggleTaskWindow(); else toggleOutputWindow(); @@ -230,7 +232,9 @@ void BuildManager::showBuildResults() void BuildManager::addToTaskWindow(const QString &file, int type, int line, const QString &description) { - m_taskWindow->addItem(BuildParserInterface::PatternType(type), description, file, line); + TaskWindow::Task task(TaskWindow::TaskType(type), description, file, line, + Constants::TASK_CATEGORY_COMPILE); + m_taskWindow->addTask(task); } void BuildManager::addToOutputWindow(const QString &string) diff --git a/src/plugins/projectexplorer/buildmanager.h b/src/plugins/projectexplorer/buildmanager.h index f201015e58..58795ee5e1 100644 --- a/src/plugins/projectexplorer/buildmanager.h +++ b/src/plugins/projectexplorer/buildmanager.h @@ -42,10 +42,10 @@ namespace ProjectExplorer { namespace Internal { class CompileOutputWindow; - class TaskWindow; class BuildProgressFuture; } +class TaskWindow; class BuildStep; class Project; class ProjectExplorerPlugin; @@ -55,7 +55,7 @@ class PROJECTEXPLORER_EXPORT BuildManager { Q_OBJECT - //NBS TODO this class has to many different variables which hold state: + //NBS TODO this class has too many different variables which hold state: // m_buildQueue, m_running, m_canceled, m_progress, m_maxProgress, m_activeBuildSteps and ... // I might need to reduce that @@ -109,7 +109,7 @@ private: void decrementActiveBuildSteps(Project *pro); Internal::CompileOutputWindow *m_outputWindow; - Internal::TaskWindow *m_taskWindow; + TaskWindow *m_taskWindow; QList<BuildStep *> m_buildQueue; QStringList m_configurations; // the corresponding configuration to the m_buildQueue diff --git a/src/plugins/projectexplorer/buildparserinterface.h b/src/plugins/projectexplorer/buildparserinterface.h index 8a15c6d469..7b1a55e6e2 100644 --- a/src/plugins/projectexplorer/buildparserinterface.h +++ b/src/plugins/projectexplorer/buildparserinterface.h @@ -41,8 +41,6 @@ class PROJECTEXPLORER_EXPORT BuildParserInterface : public QObject { Q_OBJECT public: - enum PatternType { Unknown, Warning, Error }; - virtual ~BuildParserInterface() {} virtual QString name() const = 0; diff --git a/src/plugins/projectexplorer/buildprogress.cpp b/src/plugins/projectexplorer/buildprogress.cpp index edc3576b71..c97ce2c87a 100644 --- a/src/plugins/projectexplorer/buildprogress.cpp +++ b/src/plugins/projectexplorer/buildprogress.cpp @@ -36,6 +36,7 @@ #include <QtGui/QFont> #include <QtGui/QPixmap> +using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; BuildProgress::BuildProgress(TaskWindow *taskWindow) @@ -82,12 +83,12 @@ void BuildProgress::updateState() { if (!m_taskWindow) return; - int errors = m_taskWindow->numberOfErrors(); + int errors = m_taskWindow->errorTaskCount(); bool haveErrors = (errors > 0); m_errorIcon->setEnabled(haveErrors); m_errorLabel->setEnabled(haveErrors); m_errorLabel->setText(QString("%1").arg(errors)); - int warnings = m_taskWindow->numberOfTasks()-errors; + int warnings = m_taskWindow->taskCount()-errors; bool haveWarnings = (warnings > 0); m_warningIcon->setEnabled(haveWarnings); m_warningLabel->setEnabled(haveWarnings); diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h index 336e844282..b410fd28d6 100644 --- a/src/plugins/projectexplorer/buildstep.h +++ b/src/plugins/projectexplorer/buildstep.h @@ -130,7 +130,6 @@ Q_SIGNALS: void addToOutputWindow(const QString &string); private: - QList<BuildConfiguration *> buildConfigurations(); void addBuildConfiguration(const QString & name); void removeBuildConfiguration(const QString & name); BuildConfiguration *getBuildConfiguration(const QString & name) const; diff --git a/src/plugins/projectexplorer/cesdkhandler.cpp b/src/plugins/projectexplorer/cesdkhandler.cpp index 96c2b12df8..d0ca7202d9 100644 --- a/src/plugins/projectexplorer/cesdkhandler.cpp +++ b/src/plugins/projectexplorer/cesdkhandler.cpp @@ -56,53 +56,6 @@ CeSdkHandler::CeSdkHandler() { } -static void readMkSpec(const QString &qtpath, QString *ceSdk, QString *ceArch) -{ - QFile f(qtpath); - if (f.exists() && f.open(QIODevice::ReadOnly)) { - while (!f.atEnd()) { - QByteArray line = f.readLine(); - if (line.startsWith("CE_SDK")) { - int index = line.indexOf('='); - if (index >= 0) { - *ceSdk = line.mid(index + 1).trimmed(); - } - } else if (line.startsWith("CE_ARCH")) { - int index = line.indexOf('='); - if (index >= 0) { - *ceArch = line.mid(index + 1).trimmed(); - } - } else if (line.startsWith("include(")) { - int startIndex = line.indexOf('('); - int endIndex = line.indexOf(')'); - if (startIndex >= 0 && endIndex >= 0) { - QString path = line.mid(startIndex + 1, endIndex - startIndex - 1).trimmed(); - - int index = qtpath.lastIndexOf('/'); - if (index >= 0) - readMkSpec(qtpath.left(index + 1) + path, ceSdk, ceArch); - else - readMkSpec(path, ceSdk, ceArch); - } - } - } - } -} - -QString CeSdkHandler::platformName(const QString &qtpath) -{ - QString platformName; - QString CE_SDK; - QString CE_ARCH; - - readMkSpec(qtpath, &CE_SDK, &CE_ARCH); - - if (!CE_SDK.isEmpty() && !CE_ARCH.isEmpty()) - platformName = CE_SDK + " (" + CE_ARCH + ")"; - - return platformName; -} - bool CeSdkHandler::parse(const QString &vsdir) { // look at the file at %VCInstallDir%/vcpackages/WCE.VCPlatform.config diff --git a/src/plugins/projectexplorer/debugginghelper.cpp b/src/plugins/projectexplorer/debugginghelper.cpp index 61c5b4538d..de4c5abb09 100644 --- a/src/plugins/projectexplorer/debugginghelper.cpp +++ b/src/plugins/projectexplorer/debugginghelper.cpp @@ -80,22 +80,34 @@ QString DebuggingHelperLibrary::qtInstallDataDir(const QString &qmakePath) // Debugging Helper Library -static inline QString helperFilePath(const QString &directory) +static inline bool getHelperFileInfoFor(const QString &directory, QFileInfo* info) { -#if defined(Q_OS_WIN) - return directory + QLatin1String("debug/gdbmacros.dll"); -#elif defined(Q_OS_MAC) - return directory + QLatin1String("libgdbmacros.dylib"); -#else // generic UNIX - return directory + QLatin1String("libgdbmacros.so"); -#endif + if (!info) + return false; + + info->setFile(directory + QLatin1String("debug/gdbmacros.dll")); + if (info->exists()) + return true; + + info->setFile(directory + QLatin1String("libgdbmacros.dylib")); + if (info->exists()) + return true; + + info->setFile(directory + QLatin1String("libgdbmacros.so")); + if (info->exists()) + return true; + + return false; } QStringList DebuggingHelperLibrary::debuggingHelperLibraryLocationsByInstallData(const QString &qtInstallData) { QStringList result; - foreach(const QString &directory, debuggingHelperLibraryDirectories(qtInstallData)) - result << QFileInfo(helperFilePath(directory)).filePath(); + QFileInfo fileInfo; + foreach(const QString &directory, debuggingHelperLibraryDirectories(qtInstallData)) { + if (getHelperFileInfoFor(directory, &fileInfo)) + result << fileInfo.filePath(); + } return result; } @@ -104,10 +116,12 @@ QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QStrin const QString dumperSourcePath = Core::ICore::instance()->resourcePath() + QLatin1String("/gdbmacros/"); QDateTime lastModified = QFileInfo(dumperSourcePath + "gdbmacros.cpp").lastModified(); + QFileInfo fileInfo; foreach(const QString &directory, debuggingHelperLibraryDirectories(qtInstallData)) { - const QFileInfo fi(helperFilePath(directory)); - if (fi.exists() && fi.lastModified() >= lastModified) - return fi.filePath(); + if (getHelperFileInfoFor(directory, &fileInfo)) { + if (fileInfo.lastModified() >= lastModified) + return fileInfo.filePath(); + } } return QString(); } diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp index c47b25521d..e046324467 100644 --- a/src/plugins/projectexplorer/gccparser.cpp +++ b/src/plugins/projectexplorer/gccparser.cpp @@ -29,8 +29,7 @@ #include "gccparser.h" #include "projectexplorerconstants.h" - -#include <QDebug> +#include "taskwindow.h" using namespace ProjectExplorer; @@ -70,40 +69,44 @@ void GccParser::stdOutput(const QString & line) void GccParser::stdError(const QString & line) { QString lne = line.trimmed(); - if (m_regExpLinker.indexIn(lne) > -1) { + if (m_regExpLinker.indexIn(lne) > -1) { QString description = m_regExpLinker.cap(2); emit addToTaskWindow( - m_regExpLinker.cap(1), //filename - ProjectExplorer::BuildParserInterface::Error, - -1, //linenumber - description); + m_regExpLinker.cap(1), //filename + TaskWindow::Error, + -1, //linenumber + description); //qDebug()<<"m_regExpLinker"<<m_regExpLinker.cap(2); } else if (m_regExp.indexIn(lne) > -1) { - ProjectExplorer::BuildParserInterface::PatternType type; + TaskWindow::TaskType type; if (m_regExp.cap(5) == "warning") - type = ProjectExplorer::BuildParserInterface::Warning; + type = TaskWindow::Warning; else if (m_regExp.cap(5) == "error") - type = ProjectExplorer::BuildParserInterface::Error; + type = TaskWindow::Error; else - type = ProjectExplorer::BuildParserInterface::Unknown; + type = TaskWindow::Unknown; QString description = m_regExp.cap(6); - //qDebug()<<"m_regExp"<<m_regExp.cap(1)<<m_regExp.cap(2)<<m_regExp.cap(5); - emit addToTaskWindow( - m_regExp.cap(1), //filename - type, - m_regExp.cap(2).toInt(), //line number - description); + m_regExp.cap(1), //filename + type, + m_regExp.cap(2).toInt(), //line number + description); } else if (m_regExpIncluded.indexIn(lne) > -1) { emit addToTaskWindow( - m_regExpIncluded.cap(1), //filename - ProjectExplorer::BuildParserInterface::Unknown, - m_regExpIncluded.cap(2).toInt(), //linenumber - lne //description - ); - //qDebug()<<"m_regExpInclude"<<m_regExpIncluded.cap(1)<<m_regExpIncluded.cap(2); + m_regExpIncluded.cap(1), //filename + TaskWindow::Unknown, + m_regExpIncluded.cap(2).toInt(), //linenumber + lne //description + ); } else if (lne.startsWith(QLatin1String("collect2:"))) { - emit addToTaskWindow("", ProjectExplorer::BuildParserInterface::Error, -1, lne); - }} + emit addToTaskWindow("", TaskWindow::Error, -1, lne); + } else if (lne.startsWith(QLatin1String("ERROR:"))) { + // Triggered by cpp on windows. + emit addToTaskWindow(QString(), TaskWindow::Error, -1, lne); + } else if (lne == QLatin1String("* cpp failed")) { + // Triggered by cpp/make on windows. + emit addToTaskWindow(QString(), TaskWindow::Error, -1, lne); + } +} diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp index f4e7c71550..c840158c02 100644 --- a/src/plugins/projectexplorer/msvcparser.cpp +++ b/src/plugins/projectexplorer/msvcparser.cpp @@ -79,12 +79,12 @@ void MsvcParser::stdOutput(const QString & line) } } -ProjectExplorer::BuildParserInterface::PatternType MsvcParser::toType(int number) +TaskWindow::TaskType MsvcParser::toType(int number) { if (number == 0) - return ProjectExplorer::BuildParserInterface::Unknown; + return TaskWindow::Unknown; else if (number > 4000 && number < 5000) - return ProjectExplorer::BuildParserInterface::Warning; + return TaskWindow::Warning; else - return ProjectExplorer::BuildParserInterface::Error; + return TaskWindow::Error; } diff --git a/src/plugins/projectexplorer/msvcparser.h b/src/plugins/projectexplorer/msvcparser.h index 4ef8b5cb90..c6aed2886a 100644 --- a/src/plugins/projectexplorer/msvcparser.h +++ b/src/plugins/projectexplorer/msvcparser.h @@ -31,6 +31,7 @@ #define MSVCPARSER_H #include "buildparserinterface.h" +#include "taskwindow.h" #include <QtCore/QRegExp> @@ -47,7 +48,7 @@ public: virtual void stdOutput(const QString & line); virtual void stdError(const QString & line); private: - ProjectExplorer::BuildParserInterface::PatternType toType(int number); + TaskWindow::TaskType toType(int number); QRegExp m_compileRegExp; QRegExp m_linkRegExp; }; diff --git a/src/plugins/projectexplorer/outputwindow.cpp b/src/plugins/projectexplorer/outputwindow.cpp index 45bdbad743..bfca5742ab 100644 --- a/src/plugins/projectexplorer/outputwindow.cpp +++ b/src/plugins/projectexplorer/outputwindow.cpp @@ -212,7 +212,11 @@ void OutputPane::createNewOutputWindow(RunControl *rc) agg->add(ow); agg->add(new Find::BaseTextFind(ow)); m_outputWindows.insert(rc, ow); - m_tabWidget->addTab(ow, rc->runConfiguration()->name()); + // TODO add a displayName to RunControl, can't rely on there always beeing a runconfiguration + QString name = "External Application"; + if (rc->runConfiguration()) + name = rc->runConfiguration()->name(); + m_tabWidget->addTab(ow, name); } } @@ -244,7 +248,7 @@ void OutputPane::insertLine() void OutputPane::reRunRunControl() { RunControl *rc = runControlForTab(m_tabWidget->currentIndex()); - if (rc->runConfiguration()->project() != 0) + if (rc->runConfiguration() && rc->runConfiguration()->project() != 0) rc->start(); } @@ -283,7 +287,7 @@ void OutputPane::tabChanged(int i) } else { RunControl *rc = runControlForTab(i); m_stopAction->setEnabled(rc->isRunning()); - m_reRunButton->setEnabled(!rc->isRunning() && rc->runConfiguration()->project()); + m_reRunButton->setEnabled(!rc->isRunning() && rc->runConfiguration() && rc->runConfiguration()->project()); } } @@ -300,7 +304,7 @@ void OutputPane::runControlFinished() { RunControl *rc = runControlForTab(m_tabWidget->currentIndex()); if (rc == qobject_cast<RunControl *>(sender())) { - m_reRunButton->setEnabled(rc->runConfiguration()->project()); + m_reRunButton->setEnabled(rc->runConfiguration() && rc->runConfiguration()->project()); m_stopAction->setEnabled(false); } } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 5a0814a9f0..9821118e87 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1232,29 +1232,34 @@ void ProjectExplorerPlugin::executeRunConfiguration(const QSharedPointer<RunConf emit aboutToExecuteProject(runConfiguration->project()); RunControl *control = runControlFactory->create(runConfiguration, runMode); - d->m_outputPane->createNewOutputWindow(control); - if (runMode == ProjectExplorer::Constants::RUNMODE) - d->m_outputPane->popup(false); - d->m_outputPane->showTabFor(control); - - connect(control, SIGNAL(addToOutputWindow(RunControl *, const QString &)), - this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &))); - connect(control, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)), - this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &))); - connect(control, SIGNAL(error(RunControl *, const QString &)), - this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &))); - connect(control, SIGNAL(finished()), - this, SLOT(runControlFinished())); - - if (runMode == ProjectExplorer::Constants::DEBUGMODE) - d->m_debuggingRunControl = control; - - control->start(); - updateRunAction(); + startRunControl(control, runMode); } } +void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QString &runMode) +{ + d->m_outputPane->createNewOutputWindow(runControl); + if (runMode == ProjectExplorer::Constants::RUNMODE) + d->m_outputPane->popup(false); + d->m_outputPane->showTabFor(runControl); + + connect(runControl, SIGNAL(addToOutputWindow(RunControl *, const QString &)), + this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &))); + connect(runControl, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)), + this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &))); + connect(runControl, SIGNAL(error(RunControl *, const QString &)), + this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &))); + connect(runControl, SIGNAL(finished()), + this, SLOT(runControlFinished())); + + if (runMode == ProjectExplorer::Constants::DEBUGMODE) + d->m_debuggingRunControl = runControl; + + runControl->start(); + updateRunAction(); +} + void ProjectExplorerPlugin::buildQueueFinished(bool success) { if (debug) diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 1d0d49afb8..1077ad2d36 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -134,6 +134,8 @@ public: void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes); Internal::ProjectExplorerSettings projectExplorerSettings() const; + void startRunControl(RunControl *runControl, const QString &mode); + signals: void aboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node); diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 222f830536..5f01e40482 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -177,13 +177,21 @@ const char * const FORM_MIMETYPE = "application/x-designer"; const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource"; // build parsers -const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC"; -const char * const BUILD_PARSER_GCC = "BuildParser.Gcc"; +const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC"; +const char * const BUILD_PARSER_GCC = "BuildParser.Gcc"; +const char * const BUILD_PARSER_RVCT = "BuildParser.Rvct"; +const char * const BUILD_PARSER_WINSCW = "BuildParser.Winscw"; +const char * const BUILD_PARSER_ABLD_GCCE = "BuildParser.ABLD.Gcce"; +const char * const BUILD_PARSER_ABLD_WINSCW = "BuildParser.ABLD.Winscw"; +const char * const BUILD_PARSER_ABLD_RVCT = "BuildParser.ABLD.Rvct"; // settings page const char * const PROJECTEXPLORER_CATEGORY = "ProjectExplorer"; const char * const PROJECTEXPLORER_PAGE = "ProjectExplorer.ProjectExplorer"; +// task categories +const char * const TASK_CATEGORY_COMPILE = "Task.Category.Compile"; + } // namespace Constants } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp index a3ce68b585..187253e532 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -91,6 +91,8 @@ void ProjectExplorerSettingsPage::apply() pes.showCompilerOutput = m_ui.showCompileOutputCheckBox->isChecked(); #ifdef Q_OS_WIN pes.useJom = m_ui.jomCheckbox->isChecked(); +#else + pes.useJom = false; #endif ProjectExplorerPlugin::instance()->setProjectExplorerSettings(pes); } diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 1194211018..2772516841 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -29,44 +29,69 @@ #include "taskwindow.h" -#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/actionmanager/actionmanager.h> -#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> #include <coreplugin/uniqueidmanager.h> -#include <extensionsystem/pluginmanager.h> -#include <texteditor/itexteditor.h> #include <texteditor/basetexteditor.h> -#include <projectexplorerconstants.h> +#include <texteditor/itexteditor.h> #include <QtCore/QDir> +#include <QtCore/QFileInfo> +#include <QtGui/QApplication> +#include <QtGui/QClipboard> #include <QtGui/QKeyEvent> -#include <QtGui/QHeaderView> #include <QtGui/QListView> #include <QtGui/QPainter> -#include <QtCore/QAbstractItemModel> +#include <QtGui/QStyledItemDelegate> #include <QtGui/QSortFilterProxyModel> -#include <QtGui/QApplication> -#include <QtGui/QClipboard> -#include <QtGui/QFont> -#include <QtGui/QFontMetrics> -#include <QtGui/QTextLayout> + #include <QDebug> -using namespace ProjectExplorer::Internal; +namespace ProjectExplorer { +namespace Internal { + +class TaskView : public QListView +{ +public: + TaskView(QWidget *parent = 0); + ~TaskView(); + void resizeEvent(QResizeEvent *e); + void keyPressEvent(QKeyEvent *e); +}; + +class TaskDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + TaskDelegate(QObject * parent = 0); + ~TaskDelegate(); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + // TaskView uses this method if the size of the taskview changes + void emitSizeHintChanged(const QModelIndex &index); + +public slots: + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + +private: + void generateGradientPixmap(int width, int height, QColor color, bool selected) const; +}; -// Internal Struct for TaskModel -struct TaskItem +class TaskWindowContext : public Core::IContext { - QString description; - QString file; - int line; - bool fileNotFound; - ProjectExplorer::BuildParserInterface::PatternType type; +public: + TaskWindowContext(QWidget *widget); + virtual QList<int> context() const; + virtual QWidget *widget(); +private: + QWidget *m_taskList; + QList<int> m_context; }; -class ProjectExplorer::Internal::TaskModel : public QAbstractItemModel +class TaskModel : public QAbstractItemModel { public: // Model stuff @@ -76,25 +101,36 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - void clear(); - void addTask(ProjectExplorer::BuildParserInterface::PatternType type, - const QString &description, const QString &file, int line); + + QStringList categoryIds() const; + QString categoryDisplayName(const QString &categoryId) const; + void addCategory(const QString &categoryId, const QString &categoryName); + + QList<TaskWindow::Task> tasks(const QString &categoryId = QString()) const; + void addTask(const TaskWindow::Task &task); + void clearTasks(const QString &categoryId = QString()); + int sizeOfFile(); int sizeOfLineNumber(); void setFileNotFound(const QModelIndex &index, bool b); - enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type }; + enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type, Category }; + + QIcon iconFor(TaskWindow::TaskType type); - QIcon iconFor(ProjectExplorer::BuildParserInterface::PatternType type); private: - QList<TaskItem> m_items; + QHash<QString,QString> m_categories; // category id -> display name + QList<TaskWindow::Task> m_tasks; // all tasks (in order of insertion) + QMap<QString,QList<TaskWindow::Task> > m_tasksInCategory; // categoryId->tasks + + QHash<QString,bool> m_fileNotFound; int m_maxSizeOfFileName; QIcon m_errorIcon; QIcon m_warningIcon; QIcon m_unspecifiedIcon; }; -class ProjectExplorer::Internal::TaskFilterModel : public QSortFilterProxyModel +class TaskFilterModel : public QSortFilterProxyModel { public: TaskFilterModel(TaskModel *sourceModel, QObject *parent = 0); @@ -110,6 +146,9 @@ public: bool filterIncludesErrors() const { return m_includeErrors; } void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); } + QStringList filteredCategories() const { return m_categoryIds; } + void setFilteredCategories(const QStringList &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); } + protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; @@ -118,8 +157,17 @@ private: bool m_includeUnknowns; bool m_includeWarnings; bool m_includeErrors; + QStringList m_categoryIds; }; +} // Internal +} // ProjectExplorer + + +using namespace ProjectExplorer; +using namespace ProjectExplorer::Internal; + + //// // TaskView //// @@ -164,17 +212,31 @@ TaskModel::TaskModel() } -void TaskModel::addTask(ProjectExplorer::BuildParserInterface::PatternType type, const QString &description, const QString &file, int line) +void TaskModel::addCategory(const QString &categoryId, const QString &categoryName) +{ + Q_ASSERT(!categoryId.isEmpty()); + m_categories.insert(categoryId, categoryName); +} + +QList<TaskWindow::Task> TaskModel::tasks(const QString &categoryId) const +{ + if (categoryId.isEmpty()) { + return m_tasks; + } else { + return m_tasksInCategory.value(categoryId); + } +} + +void TaskModel::addTask(const TaskWindow::Task &task) { - TaskItem task; - task.description = description; - task.file = file; - task.line = line; - task.type = type; - task.fileNotFound = false; + Q_ASSERT(m_categories.keys().contains(task.category)); - beginInsertRows(QModelIndex(), m_items.size(), m_items.size()); - m_items.append(task); + QList<TaskWindow::Task> tasksInCategory = m_tasksInCategory.value(task.category); + tasksInCategory.append(task); + m_tasksInCategory.insert(task.category, tasksInCategory); + + beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size()); + m_tasks.append(task); endInsertRows(); QFont font; @@ -182,18 +244,48 @@ void TaskModel::addTask(ProjectExplorer::BuildParserInterface::PatternType type, QString filename = task.file; int pos = filename.lastIndexOf("/"); if (pos != -1) - filename = file.mid(pos +1); + filename = task.file.mid(pos +1); + m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename)); } +// +//void TaskModel::removeTask(const ITaskWindow::Task &task) +//{ +// Q_ASSERT(m_tasks.contains(task)); +// int index = m_tasks.indexOf(task); +// beginRemoveRows(QModelIndex(), index, index); +// m_tasks.removeAt(index); +// endRemoveRows(); +//} + +void TaskModel::clearTasks(const QString &categoryId) +{ + if (categoryId.isEmpty()) { + if (m_tasks.size() == 0) + return; + beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1); + m_tasks.clear(); + m_tasksInCategory.clear(); + endRemoveRows(); + m_maxSizeOfFileName = 0; + } else { + // TODO: Optimize this for consecutive rows + foreach (const TaskWindow::Task &task, m_tasksInCategory.value(categoryId)) { + int index = m_tasks.indexOf(task); + Q_ASSERT(index >= 0); + beginRemoveRows(QModelIndex(), index, index); -void TaskModel::clear() -{ - if (m_items.isEmpty()) - return; - beginRemoveRows(QModelIndex(), 0, m_items.size() -1); - m_items.clear(); - endRemoveRows(); - m_maxSizeOfFileName = 0; + m_tasks.removeAt(index); + + QList<TaskWindow::Task> tasksInCategory = m_tasksInCategory.value(categoryId); + tasksInCategory.removeOne(task); + m_tasksInCategory.insert(categoryId, tasksInCategory); + + endRemoveRows(); + } + + // what to do with m_maxSizeOfFileName ? + } } @@ -212,7 +304,7 @@ QModelIndex TaskModel::parent(const QModelIndex &child) const int TaskModel::rowCount(const QModelIndex &parent) const { - return parent.isValid() ? 0 : m_items.count(); + return parent.isValid() ? 0 : m_tasks.count(); } int TaskModel::columnCount(const QModelIndex &parent) const @@ -222,27 +314,43 @@ int TaskModel::columnCount(const QModelIndex &parent) const QVariant TaskModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_items.size() || index.column() != 0) + if (!index.isValid() || index.row() >= m_tasks.size() || index.column() != 0) return QVariant(); - if (role == TaskModel::File) - return m_items.at(index.row()).file; - else if (role == TaskModel::Line) - return m_items.at(index.row()).line; - else if (role == TaskModel::Description) - return m_items.at(index.row()).description; - else if (role == TaskModel::FileNotFound) - return m_items.at(index.row()).fileNotFound; - else if (role == TaskModel::Type) - return (int)m_items.at(index.row()).type; + if (role == TaskModel::File) { + return m_tasks.at(index.row()).file; + } else if (role == TaskModel::Line) { + if (m_tasks.at(index.row()).line <= 0) + return QVariant(); + else + return m_tasks.at(index.row()).line; + } else if (role == TaskModel::Description) { + return m_tasks.at(index.row()).description; + } else if (role == TaskModel::FileNotFound) { + return m_fileNotFound.value(m_tasks.at(index.row()).file); + } else if (role == TaskModel::Type) { + return (int)m_tasks.at(index.row()).type; + } else if (role == TaskModel::Category) { + return m_tasks.at(index.row()).category; + } return QVariant(); } -QIcon TaskModel::iconFor(ProjectExplorer::BuildParserInterface::PatternType type) +QStringList TaskModel::categoryIds() const { - if (type == ProjectExplorer::BuildParserInterface::Error) + return m_categories.keys(); +} + +QString TaskModel::categoryDisplayName(const QString &categoryId) const +{ + return m_categories.value(categoryId); +} + +QIcon TaskModel::iconFor(TaskWindow::TaskType type) +{ + if (type == TaskWindow::Error) return m_errorIcon; - else if (type == ProjectExplorer::BuildParserInterface::Warning) + else if (type == TaskWindow::Warning) return m_warningIcon; else return m_unspecifiedIcon; @@ -262,8 +370,8 @@ int TaskModel::sizeOfLineNumber() void TaskModel::setFileNotFound(const QModelIndex &idx, bool b) { - if (idx.isValid() && idx.row() < m_items.size()) { - m_items[idx.row()].fileNotFound = b; + if (idx.isValid() && idx.row() < m_tasks.size()) { + m_fileNotFound.insert(m_tasks[idx.row()].file, b); emit dataChanged(idx, idx); } } @@ -287,28 +395,34 @@ TaskModel *TaskFilterModel::taskModel() const bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + bool accept = true; + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); - ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt()); + TaskWindow::TaskType type = TaskWindow::TaskType(index.data(TaskModel::Type).toInt()); switch (type) { - case ProjectExplorer::BuildParserInterface::Unknown: - return m_includeUnknowns; - - case ProjectExplorer::BuildParserInterface::Warning: - return m_includeWarnings; - - case ProjectExplorer::BuildParserInterface::Error: - return m_includeErrors; + case TaskWindow::Unknown: + accept = m_includeUnknowns; + break; + case TaskWindow::Warning: + accept = m_includeWarnings; + break; + case TaskWindow::Error: + accept = m_includeErrors; + break; } - // Not one of the three supported types -- shouldn't happen, but we'll let it slide. - return true; + const QString &categoryId = index.data(TaskModel::Category).toString(); + if (m_categoryIds.contains(categoryId)) + accept = false; + + return accept; } ///// // TaskWindow ///// -static QToolButton *createFilterButton(ProjectExplorer::BuildParserInterface::PatternType type, +static QToolButton *createFilterButton(TaskWindow::TaskType type, const QString &toolTip, TaskModel *model, QObject *receiver, const char *slot) { @@ -359,12 +473,22 @@ TaskWindow::TaskWindow() connect(m_copyAction, SIGNAL(triggered()), SLOT(copy())); - m_filterWarningsButton = createFilterButton(ProjectExplorer::BuildParserInterface::Warning, + m_filterWarningsButton = createFilterButton(TaskWindow::Warning, tr("Show Warnings"), m_model, this, SLOT(setShowWarnings(bool))); - m_errorCount = 0; - m_currentTask = -1; + m_categoriesMenu = new QMenu; + connect(m_categoriesMenu, SIGNAL(aboutToShow()), this, SLOT(updateCategoriesMenu())); + connect(m_categoriesMenu, SIGNAL(triggered(QAction*)), this, SLOT(filterCategoryTriggered(QAction*))); + + m_categoriesButton = new QToolButton; + m_categoriesButton->setText(tr("categories")); + m_categoriesButton->setToolTip(tr("Filter by categories")); + m_categoriesButton->setAutoRaise(true); + m_categoriesButton->setPopupMode(QToolButton::InstantPopup); + m_categoriesButton->setMenu(m_categoriesMenu); + + updateActions(); } TaskWindow::~TaskWindow() @@ -378,7 +502,7 @@ TaskWindow::~TaskWindow() QList<QWidget*> TaskWindow::toolBarWidgets() const { - return QList<QWidget*>() << m_filterWarningsButton; + return QList<QWidget*>() << m_filterWarningsButton << m_categoriesButton; } QWidget *TaskWindow::outputWidget(QWidget *) @@ -386,12 +510,11 @@ QWidget *TaskWindow::outputWidget(QWidget *) return m_listview; } -void TaskWindow::clearContents() +void TaskWindow::clearTasks(const QString &categoryId) { - m_errorCount = 0; - m_currentTask = -1; - m_model->clear(); - m_copyAction->setEnabled(false); + m_model->clearTasks(categoryId); + + updateActions(); emit tasksChanged(); navigateStateChanged(); } @@ -400,16 +523,19 @@ void TaskWindow::visibilityChanged(bool /* b */) { } -void TaskWindow::addItem(ProjectExplorer::BuildParserInterface::PatternType type, - const QString &description, const QString &file, int line) +void TaskWindow::addCategory(const QString &categoryId, const QString &displayName) +{ + Q_ASSERT(!categoryId.isEmpty()); + m_model->addCategory(categoryId, displayName); +} + +void TaskWindow::addTask(const Task &task) { - m_model->addTask(type, description, file, line); - if (type == ProjectExplorer::BuildParserInterface::Error) - ++m_errorCount; - m_copyAction->setEnabled(true); + m_model->addTask(task); + + updateActions(); emit tasksChanged(); - if (m_model->rowCount() == 1) - navigateStateChanged(); + navigateStateChanged(); } void TaskWindow::showTaskInFile(const QModelIndex &index) @@ -440,10 +566,10 @@ void TaskWindow::copy() QString description = index.data(TaskModel::Description).toString(); QString type; switch (index.data(TaskModel::Type).toInt()) { - case ProjectExplorer::BuildParserInterface::Error: + case TaskWindow::Error: type = "error: "; break; - case ProjectExplorer::BuildParserInterface::Warning: + case TaskWindow::Warning: type = "warning: "; break; } @@ -457,14 +583,57 @@ void TaskWindow::setShowWarnings(bool show) m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings } -int TaskWindow::numberOfTasks() const +void TaskWindow::updateCategoriesMenu() +{ + m_categoriesMenu->clear(); + + const QStringList filteredCategories = m_filter->filteredCategories(); + + foreach (const QString &categoryId, m_model->categoryIds()) { + const QString categoryName = m_model->categoryDisplayName(categoryId); + + QAction *action = new QAction(m_categoriesMenu); + action->setCheckable(true); + action->setText(categoryName); + action->setData(categoryId); + action->setChecked(!filteredCategories.contains(categoryId)); + + m_categoriesMenu->addAction(action); + } +} + +void TaskWindow::filterCategoryTriggered(QAction *action) +{ + QString categoryId = action->data().toString(); + Q_ASSERT(!categoryId.isEmpty()); + + QStringList categories = m_filter->filteredCategories(); + Q_ASSERT(m_filter->filteredCategories().contains(categoryId) == action->isChecked()); + + if (action->isChecked()) { + categories.removeOne(categoryId); + } else { + categories.append(categoryId); + } + + m_filter->setFilteredCategories(categories); +} + +int TaskWindow::taskCount(const QString &categoryId) const { - return m_model->rowCount(QModelIndex()); + return m_model->tasks(categoryId).count(); } -int TaskWindow::numberOfErrors() const +int TaskWindow::errorTaskCount(const QString &categoryId) const { - return m_errorCount; + int errorTaskCount = 0; + + foreach (const Task &task, m_model->tasks(categoryId)) { + if (task.type == TaskWindow::Error) + ++ errorTaskCount; + } + + return errorTaskCount; } int TaskWindow::priorityInStatusBar() const @@ -472,6 +641,11 @@ int TaskWindow::priorityInStatusBar() const return 90; } +void TaskWindow::clearContents() +{ + clearTasks(); +} + bool TaskWindow::hasFocus() { return m_listview->hasFocus(); @@ -541,6 +715,11 @@ bool TaskWindow::canNavigate() return true; } +void TaskWindow::updateActions() +{ + m_copyAction->setEnabled(m_model->tasks().count() > 0); +} + ///// // Delegate ///// @@ -636,7 +815,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->setPen(textColor); TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel(); - ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt()); + TaskWindow::TaskType type = TaskWindow::TaskType(index.data(TaskModel::Type).toInt()); QIcon icon = model->iconFor(type); painter->drawPixmap(2, opt.rect.top() + 2, icon.pixmap(16, 16)); @@ -727,3 +906,22 @@ QWidget *TaskWindowContext::widget() return m_taskList; } + +// +// functions +// +bool ProjectExplorer::operator==(const TaskWindow::Task &t1, const TaskWindow::Task &t2) +{ + return t1.type == t2.type + && t1.line == t2.line + && t1.description == t2.description + && t1.file == t2.file + && t1.category == t2.category; +} + +uint ProjectExplorer::qHash(const TaskWindow::Task &task) +{ + return qHash(task.file) + task.line; +} + +#include "taskwindow.moc" diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index d7e7d702c6..7fddbcbfba 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -32,15 +32,15 @@ #include "buildparserinterface.h" -#include <coreplugin/ioutputpane.h> #include <coreplugin/icontext.h> +#include <coreplugin/ioutputpane.h> -#include <QtGui/QTreeWidget> -#include <QtGui/QStyledItemDelegate> -#include <QtGui/QListView> +#include <QtCore/QModelIndex> +#include <QtGui/QAction> #include <QtGui/QToolButton> namespace ProjectExplorer { + namespace Internal { class TaskModel; @@ -48,7 +48,9 @@ class TaskFilterModel; class TaskView; class TaskWindowContext; -class TaskWindow : public Core::IOutputPane +} // namespace Internal + +class PROJECTEXPLORER_EXPORT TaskWindow : public Core::IOutputPane { Q_OBJECT @@ -56,6 +58,35 @@ public: TaskWindow(); ~TaskWindow(); + enum TaskType { + Unknown, + Error, + Warning + }; + + struct Task { + Task(TaskType type_, const QString &description_, + const QString &file_, int line_, const QString &category_) : + type(type_), description(description_), file(file_), line(line_), category(category_) + { } + + TaskType type; + QString description; + QString file; + int line; + QString category; + }; + + void addCategory(const QString &categoryId, const QString &displayName); + + void addTask(const Task &task); + void clearTasks(const QString &categoryId = QString()); + + int taskCount(const QString &categoryId = QString()) const; + int errorTaskCount(const QString &categoryId = QString()) const; + + + // IOutputPane QWidget *outputWidget(QWidget *); QList<QWidget*> toolBarWidgets() const; @@ -64,21 +95,15 @@ public: void clearContents(); void visibilityChanged(bool visible); - void addItem(BuildParserInterface::PatternType type, - const QString &description, const QString &file, int line); - - int numberOfTasks() const; - int numberOfErrors() const; - bool canFocus(); bool hasFocus(); void setFocus(); + bool canNavigate(); bool canNext(); bool canPrevious(); void goToNext(); void goToPrev(); - bool canNavigate(); signals: void tasksChanged(); @@ -87,61 +112,26 @@ private slots: void showTaskInFile(const QModelIndex &index); void copy(); void setShowWarnings(bool); + void updateCategoriesMenu(); + void filterCategoryTriggered(QAction *action); private: + void updateActions(); int sizeHintForColumn(int column) const; - int m_errorCount; - int m_currentTask; - - TaskModel *m_model; - TaskFilterModel *m_filter; - TaskView *m_listview; - TaskWindowContext *m_taskWindowContext; + Internal::TaskModel *m_model; + Internal::TaskFilterModel *m_filter; + Internal::TaskView *m_listview; + Internal::TaskWindowContext *m_taskWindowContext; QAction *m_copyAction; QToolButton *m_filterWarningsButton; + QToolButton *m_categoriesButton; + QMenu *m_categoriesMenu; }; -class TaskView : public QListView -{ -public: - TaskView(QWidget *parent = 0); - ~TaskView(); - void resizeEvent(QResizeEvent *e); - void keyPressEvent(QKeyEvent *e); -}; - -class TaskDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - TaskDelegate(QObject * parent = 0); - ~TaskDelegate(); - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; - - // TaskView uses this method if the size of the taskview changes - void emitSizeHintChanged(const QModelIndex &index); - -public slots: - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - -private: - void generateGradientPixmap(int width, int height, QColor color, bool selected) const; -}; - -class TaskWindowContext : public Core::IContext -{ -public: - TaskWindowContext(QWidget *widget); - virtual QList<int> context() const; - virtual QWidget *widget(); -private: - QWidget *m_taskList; - QList<int> m_context; -}; +bool operator==(const TaskWindow::Task &t1, const TaskWindow::Task &t2); +uint qHash(const TaskWindow::Task &task); -} //namespace Internal } //namespace ProjectExplorer #endif // TASKWINDOW_H diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 6c3236d28f..a5b91c006b 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -111,8 +111,8 @@ QString ToolChain::toolChainName(ToolChainType tc) switch (tc) { case GCC: return QCoreApplication::translate("ToolChain", "GCC"); - case LinuxICC: - return QCoreApplication::translate("ToolChain", "Intel C++ Compiler (Linux)"); +// case LinuxICC: +// return QCoreApplication::translate("ToolChain", "Intel C++ Compiler (Linux)"); case MinGW: return QString::fromLatin1("MinGW"); case MSVC: @@ -127,6 +127,8 @@ QString ToolChain::toolChainName(ToolChainType tc) return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)"); case RVCT_ARMV6: return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)"); + case GCC_MAEMO: + return QCoreApplication::translate("ToolChain", "GCC for Maemo"); case OTHER: return QCoreApplication::translate("ToolChain", "Other"); case INVALID: diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index b3a11cb7be..2492b5a417 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -75,7 +75,7 @@ public: enum ToolChainType { GCC = 0, - LinuxICC = 1, + // LINUX_ICC = 1, MinGW = 2, MSVC = 3, WINCE = 4, @@ -83,7 +83,8 @@ public: GCCE = 6, RVCT_ARMV5 = 7, RVCT_ARMV6 = 8, - LAST_VALID = 9, + GCC_MAEMO = 9, + LAST_VALID = 10, OTHER = 200, UNKNOWN = 201, INVALID = 202 diff --git a/src/plugins/qmleditor/QmlEditor.pluginspec b/src/plugins/qmleditor/QmlEditor.pluginspec index 09ae2cb80c..7b1a91c8ce 100644 --- a/src/plugins/qmleditor/QmlEditor.pluginspec +++ b/src/plugins/qmleditor/QmlEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="QmlEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="QmlEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Editor for QML.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="Help" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="Help" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/qmleditor/idcollector.cpp b/src/plugins/qmleditor/idcollector.cpp index 8677d540fd..c98019587f 100644 --- a/src/plugins/qmleditor/idcollector.cpp +++ b/src/plugins/qmleditor/idcollector.cpp @@ -1,3 +1,5 @@ +#include <QDebug> + #include "idcollector.h" #include "qmljsast_p.h" #include "qmljsengine_p.h" @@ -7,36 +9,39 @@ using namespace QmlJS::AST; using namespace QmlEditor; using namespace QmlEditor::Internal; -QMap<QString, QmlIdSymbol*> IdCollector::operator()(const QString &fileName, QmlJS::AST::UiProgram *ast) +QMap<QString, QmlIdSymbol*> IdCollector::operator()(QmlDocument *doc) { - _fileName = fileName; + _doc = doc; _ids.clear(); + _currentSymbol = 0; - Node::accept(ast, this); + Node::accept(doc->program(), this); return _ids; } -bool IdCollector::visit(QmlJS::AST::UiObjectBinding *ast) -{ - _scopes.push(ast); - return true; -} - -bool IdCollector::visit(QmlJS::AST::UiObjectDefinition *ast) +bool IdCollector::visit(UiArrayBinding *ast) { - _scopes.push(ast); - return true; + QmlSymbolFromFile *oldSymbol = switchSymbol(ast); + Node::accept(ast->members, this); + _currentSymbol = oldSymbol; + return false; } -void IdCollector::endVisit(QmlJS::AST::UiObjectBinding *) +bool IdCollector::visit(QmlJS::AST::UiObjectBinding *ast) { - _scopes.pop(); + QmlSymbolFromFile *oldSymbol = switchSymbol(ast); + Node::accept(ast->initializer, this); + _currentSymbol = oldSymbol; + return false; } -void IdCollector::endVisit(QmlJS::AST::UiObjectDefinition *) +bool IdCollector::visit(QmlJS::AST::UiObjectDefinition *ast) { - _scopes.pop(); + QmlSymbolFromFile *oldSymbol = switchSymbol(ast); + Node::accept(ast->initializer, this); + _currentSymbol = oldSymbol; + return false; } bool IdCollector::visit(QmlJS::AST::UiScriptBinding *ast) @@ -44,21 +49,40 @@ bool IdCollector::visit(QmlJS::AST::UiScriptBinding *ast) if (!(ast->qualifiedId->next) && ast->qualifiedId->name->asString() == "id") if (ExpressionStatement *e = cast<ExpressionStatement*>(ast->statement)) if (IdentifierExpression *i = cast<IdentifierExpression*>(e->expression)) - addId(i->name->asString(), ast); + if (i->name) + addId(i->name->asString(), ast); return false; } +QmlSymbolFromFile *IdCollector::switchSymbol(QmlJS::AST::UiObjectMember *node) +{ + QmlSymbolFromFile *newSymbol = 0; + + if (_currentSymbol == 0) { + newSymbol = _doc->findSymbol(node); + } else { + newSymbol = _currentSymbol->findMember(node); + } + + QmlSymbolFromFile *oldSymbol = _currentSymbol; + + if (newSymbol) { + _currentSymbol = newSymbol; + } else { + QString filename = _doc->fileName(); + qWarning() << "Scope without symbol @"<<filename<<":"<<node->firstSourceLocation().startLine<<":"<<node->firstSourceLocation().startColumn; + } + + return oldSymbol; +} + void IdCollector::addId(const QString &id, QmlJS::AST::UiScriptBinding *ast) { - if (!_ids.contains(id)) { - Node *parent = _scopes.top(); - - if (UiObjectBinding *binding = cast<UiObjectBinding*>(parent)) - _ids[id] = new QmlIdSymbol(_fileName, ast, QmlSymbolFromFile(_fileName, binding)); - else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(parent)) - _ids[id] = new QmlIdSymbol(_fileName, ast, QmlSymbolFromFile(_fileName, definition)); - else - Q_ASSERT(!"Unknown parent for id"); + if (!_ids.contains(id) && _currentSymbol) { + QmlSymbolFromFile *symbol = _currentSymbol->findMember(ast); + + if (QmlIdSymbol *idSymbol = symbol->asIdSymbol()) + _ids[id] = idSymbol; } } diff --git a/src/plugins/qmleditor/idcollector.h b/src/plugins/qmleditor/idcollector.h index e4c7e7bf29..8a02b4c355 100644 --- a/src/plugins/qmleditor/idcollector.h +++ b/src/plugins/qmleditor/idcollector.h @@ -6,6 +6,7 @@ #include <QStack> #include <QString> +#include "qmldocument.h" #include "qmljsastvisitor_p.h" #include "qmlsymbol.h" @@ -15,23 +16,22 @@ namespace Internal { class IdCollector: protected QmlJS::AST::Visitor { public: - QMap<QString, QmlIdSymbol*> operator()(const QString &fileName, QmlJS::AST::UiProgram *ast); + QMap<QString, QmlIdSymbol*> operator()(QmlDocument *doc); protected: + virtual bool visit(QmlJS::AST::UiArrayBinding *ast); virtual bool visit(QmlJS::AST::UiObjectBinding *ast); virtual bool visit(QmlJS::AST::UiObjectDefinition *ast); virtual bool visit(QmlJS::AST::UiScriptBinding *ast); - virtual void endVisit(QmlJS::AST::UiObjectBinding *); - virtual void endVisit(QmlJS::AST::UiObjectDefinition *); - private: + QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node); void addId(const QString &id, QmlJS::AST::UiScriptBinding *ast); private: - QString _fileName; + QmlDocument *_doc; QMap<QString, QmlIdSymbol*> _ids; - QStack<QmlJS::AST::Node *> _scopes; + QmlSymbolFromFile *_currentSymbol; }; } // namespace Internal diff --git a/src/plugins/qmleditor/qmlcodecompletion.cpp b/src/plugins/qmleditor/qmlcodecompletion.cpp index c0b69213d3..7b6bf6a295 100644 --- a/src/plugins/qmleditor/qmlcodecompletion.cpp +++ b/src/plugins/qmleditor/qmlcodecompletion.cpp @@ -1,18 +1,26 @@ -#include "qmlcompletionvisitor.h" #include "qmlcodecompletion.h" #include "qmleditor.h" +#include "qmlmodelmanagerinterface.h" +#include "qmlexpressionundercursor.h" +#include "qmllookupcontext.h" +#include "qmlresolveexpression.h" +#include "qmlsymbol.h" + #include <texteditor/basetexteditor.h> #include <QtDebug> using namespace QmlEditor; using namespace QmlEditor::Internal; -QmlCodeCompletion::QmlCodeCompletion(QObject *parent) +QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent) : TextEditor::ICompletionCollector(parent), + m_modelManager(modelManager), m_editor(0), m_startPosition(0), m_caseSensitivity(Qt::CaseSensitive) -{ } +{ + Q_ASSERT(modelManager); +} QmlCodeCompletion::~QmlCodeCompletion() { } @@ -50,26 +58,55 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) m_startPosition = pos; m_completions.clear(); - foreach (const QString &word, edit->keywords()) { - TextEditor::CompletionItem item(this); - item.text = word; - m_completions.append(item); - } - - foreach (const QString &word, edit->words()) { - TextEditor::CompletionItem item(this); - item.text = word; - m_completions.append(item); - } +// foreach (const QString &word, edit->keywords()) { +// TextEditor::CompletionItem item(this); +// item.m_text = word; +// m_completions.append(item); +// } +// +// foreach (const QString &word, edit->words()) { +// TextEditor::CompletionItem item(this); +// item.m_text = word; +// m_completions.append(item); +// } QmlDocument::Ptr qmlDocument = edit->qmlDocument(); - if (!qmlDocument.isNull()) { - QmlJS::AST::UiProgram *program = qmlDocument->program(); - - if (program) { - QmlCompletionVisitor visitor; - - foreach (const QString &word, visitor(program, m_startPosition)) { +// qDebug() << "*** document:" << qmlDocument; + if (qmlDocument.isNull()) + return pos; + + if (!qmlDocument->program()) + qmlDocument = m_modelManager->snapshot().value(qmlDocument->fileName()); + + // FIXME: this completion strategy is not going to work when the document was never parsed correctly. + if (qmlDocument && qmlDocument->program()) { + QmlJS::AST::UiProgram *program = qmlDocument->program(); +// qDebug() << "*** program:" << program; + + if (program) { + QmlExpressionUnderCursor expressionUnderCursor; + QTextCursor cursor(edit->document()); + cursor.setPosition(pos); + expressionUnderCursor(cursor, qmlDocument); + + QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot()); + QmlResolveExpression resolver(context); +// qDebug()<<"*** expression under cursor:"<<expressionUnderCursor.expressionNode(); + QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode()); +// qDebug()<<"***"<<symbols.size()<<"visible symbols"; + + foreach (QmlSymbol *symbol, symbols) { + QString word; + + if (symbol->isIdSymbol()) { + word = symbol->asIdSymbol()->id(); + } else { + word = symbol->name(); + } + + if (word.isEmpty()) + continue; + TextEditor::CompletionItem item(this); item.text = word; m_completions.append(item); diff --git a/src/plugins/qmleditor/qmlcodecompletion.h b/src/plugins/qmleditor/qmlcodecompletion.h index fd5e4b1ba6..8ed9aaf05a 100644 --- a/src/plugins/qmleditor/qmlcodecompletion.h +++ b/src/plugins/qmleditor/qmlcodecompletion.h @@ -8,6 +8,9 @@ class ITextEditable; } namespace QmlEditor { + +class QmlModelManagerInterface; + namespace Internal { class QmlCodeCompletion: public TextEditor::ICompletionCollector @@ -15,7 +18,7 @@ class QmlCodeCompletion: public TextEditor::ICompletionCollector Q_OBJECT public: - QmlCodeCompletion(QObject *parent = 0); + QmlCodeCompletion(QmlModelManagerInterface *modelManager, QObject *parent = 0); virtual ~QmlCodeCompletion(); Qt::CaseSensitivity caseSensitivity() const; @@ -30,6 +33,7 @@ public: virtual void cleanup(); private: + QmlModelManagerInterface *m_modelManager; TextEditor::ITextEditable *m_editor; int m_startPosition; QList<TextEditor::CompletionItem> m_completions; diff --git a/src/plugins/qmleditor/qmldocument.cpp b/src/plugins/qmleditor/qmldocument.cpp index d89e69609f..13cbe2895e 100644 --- a/src/plugins/qmleditor/qmldocument.cpp +++ b/src/plugins/qmleditor/qmldocument.cpp @@ -32,8 +32,8 @@ #include "qmljsast_p.h" #include "qmljslexer_p.h" #include "qmljsparser_p.h" -#include "qmljsengine_p.h" #include "qmljsnodepool_p.h" +#include "qmljsastfwd_p.h" using namespace QmlEditor; using namespace QmlJS; @@ -61,7 +61,7 @@ QmlDocument::~QmlDocument() if (_pool) delete _pool; - qDeleteAll(_ids.values()); + qDeleteAll(_symbols); } QmlDocument::Ptr QmlDocument::create(const QString &fileName) @@ -109,14 +109,28 @@ bool QmlDocument::parse() _program = parser.ast(); _diagnosticMessages = parser.diagnosticMessages(); - if (_parsedCorrectly && _program) { - Internal::IdCollector collect; - _ids = collect(_fileName, _program); + if (_program) { + for (QmlJS::AST::UiObjectMemberList *iter = _program->members; iter; iter = iter->next) + if (iter->member) + _symbols.append(new QmlSymbolFromFile(_fileName, iter->member)); + + Internal::IdCollector collect; + _ids = collect(this); } return _parsedCorrectly; } +QmlSymbolFromFile *QmlDocument::findSymbol(QmlJS::AST::Node *node) const +{ + foreach (QmlSymbol *symbol, _symbols) + if (symbol->isSymbolFromFile()) + if (symbol->asSymbolFromFile()->node() == node) + return symbol->asSymbolFromFile(); + + return 0; +} + Snapshot::Snapshot() { } @@ -127,6 +141,9 @@ Snapshot::~Snapshot() void Snapshot::insert(const QmlDocument::Ptr &document) { + if (!document || !document->program()) + return; + QMap<QString, QmlDocument::Ptr>::insert(document->fileName(), document); } diff --git a/src/plugins/qmleditor/qmldocument.h b/src/plugins/qmleditor/qmldocument.h index 7639d1b25a..4f9420ebaa 100644 --- a/src/plugins/qmleditor/qmldocument.h +++ b/src/plugins/qmleditor/qmldocument.h @@ -35,10 +35,9 @@ #include <QtCore/QSharedPointer> #include <QtCore/QString> -#include "qmleditor_global.h" -#include "qmljsengine_p.h" -#include "qmljsastfwd_p.h" -#include "qmlsymbol.h" +#include <qmleditor/qmleditor_global.h> +#include <qmleditor/parser/qmljsengine_p.h> +#include <qmleditor/qmlsymbol.h> namespace QmlEditor { @@ -74,6 +73,10 @@ public: QString path() const { return _path; } QString componentName() const { return _componentName; } + QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const; + QmlSymbol::List symbols() const + { return _symbols; } + private: QmlJS::Engine *_engine; QmlJS::NodePool *_pool; @@ -85,6 +88,7 @@ private: QString _source; bool _parsedCorrectly; IdTable _ids; + QmlSymbol::List _symbols; }; class QMLEDITOR_EXPORT Snapshot: public QMap<QString, QmlDocument::Ptr> diff --git a/src/plugins/qmleditor/qmleditor.cpp b/src/plugins/qmleditor/qmleditor.cpp index 3790a27c73..2819b87f68 100644 --- a/src/plugins/qmleditor/qmleditor.cpp +++ b/src/plugins/qmleditor/qmleditor.cpp @@ -398,8 +398,8 @@ ScriptEditor::ScriptEditor(QWidget *parent) : m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>(); if (m_modelManager) { - connect(m_modelManager, SIGNAL(documentUpdated(QmlDocument::Ptr)), - this, SLOT(onDocumentUpdated(QmlDocument::Ptr))); + connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)), + this, SLOT(onDocumentUpdated(QmlEditor::QmlDocument::Ptr))); } } @@ -447,7 +447,7 @@ void ScriptEditor::updateDocumentNow() m_modelManager->updateSourceFiles(QStringList() << fileName); } -void ScriptEditor::onDocumentUpdated(QmlDocument::Ptr doc) +void ScriptEditor::onDocumentUpdated(QmlEditor::QmlDocument::Ptr doc) { if (file()->fileName() != doc->fileName()) return; @@ -721,12 +721,28 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur if (!doc) return link; + QTextCursor expressionCursor(cursor); + { + // correct the position by moving to the end of an identifier (if we're hovering over one): + const QString txt = cursor.block().text(); + int pos = cursor.position(); + forever { + const QChar ch = characterAt(pos); + + if (ch.isLetterOrNumber() || ch == QLatin1Char('_')) + ++pos; + else + break; + } + expressionCursor.setPosition(pos); + } + QmlExpressionUnderCursor expressionUnderCursor; - expressionUnderCursor(cursor, doc->program()); + expressionUnderCursor(expressionCursor, doc); QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot); - QmlResolveExpression resolve(context); - QmlSymbol *symbol = resolve(expressionUnderCursor.expressionNode()); + QmlResolveExpression resolver(context); + QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode()); if (!symbol) return link; diff --git a/src/plugins/qmleditor/qmleditor.h b/src/plugins/qmleditor/qmleditor.h index d6a1026e71..ac4692bc4d 100644 --- a/src/plugins/qmleditor/qmleditor.h +++ b/src/plugins/qmleditor/qmleditor.h @@ -113,7 +113,7 @@ public slots: virtual void setFontSettings(const TextEditor::FontSettings &); private slots: - void onDocumentUpdated(QmlDocument::Ptr doc); + void onDocumentUpdated(QmlEditor::QmlDocument::Ptr doc); void updateDocument(); void updateDocumentNow(); diff --git a/src/plugins/qmleditor/qmleditor.pro b/src/plugins/qmleditor/qmleditor.pro index 415acf8f52..8f71e4ffc6 100644 --- a/src/plugins/qmleditor/qmleditor.pro +++ b/src/plugins/qmleditor/qmleditor.pro @@ -4,6 +4,7 @@ include(../../qtcreatorplugin.pri) include(qmleditor_dependencies.pri) include(parser/parser.pri) include(rewriter/rewriter.pri) +CONFIG += help DEFINES += QMLEDITOR_LIBRARY \ QT_CREATOR INCLUDEPATH += parser \ @@ -17,7 +18,6 @@ HEADERS += qmleditor.h \ qmleditorconstants.h \ qmlhoverhandler.h \ qmldocument.h \ - qmlcompletionvisitor.h \ qmlmodelmanagerinterface.h \ qmleditor_global.h \ qmlmodelmanager.h \ @@ -36,7 +36,6 @@ SOURCES += qmleditor.cpp \ qmlcodecompletion.cpp \ qmlhoverhandler.cpp \ qmldocument.cpp \ - qmlcompletionvisitor.cpp \ qmlmodelmanagerinterface.cpp \ qmlmodelmanager.cpp \ qmlcodeformatter.cpp \ diff --git a/src/plugins/qmleditor/qmleditorplugin.cpp b/src/plugins/qmleditor/qmleditorplugin.cpp index 5958ab469a..078e88a719 100644 --- a/src/plugins/qmleditor/qmleditorplugin.cpp +++ b/src/plugins/qmleditor/qmleditorplugin.cpp @@ -121,7 +121,7 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION); contextMenu->addAction(cmd); - m_completion = new QmlCodeCompletion(); + m_completion = new QmlCodeCompletion(m_modelManager); addAutoReleasedObject(m_completion); addAutoReleasedObject(new QmlHoverHandler()); diff --git a/src/plugins/qmleditor/qmlexpressionundercursor.cpp b/src/plugins/qmleditor/qmlexpressionundercursor.cpp index 133ab2bac6..4bb17bdeb6 100644 --- a/src/plugins/qmleditor/qmlexpressionundercursor.cpp +++ b/src/plugins/qmleditor/qmlexpressionundercursor.cpp @@ -1,124 +1,277 @@ +#include <QDebug> + #include "qmljsast_p.h" +#include "qmljsastvisitor_p.h" #include "qmljsengine_p.h" - +#include "qmljslexer_p.h" +#include "qmljsnodepool_p.h" +#include "qmljsparser_p.h" #include "qmlexpressionundercursor.h" -using namespace QmlEditor; -using namespace QmlEditor::Internal; using namespace QmlJS; using namespace QmlJS::AST; -QmlExpressionUnderCursor::QmlExpressionUnderCursor() - : _expressionNode(0), - _pos(0) -{ -} +namespace QmlEditor { + namespace Internal { + class PositionCalculator: protected Visitor + { + public: + Node *operator()(Node *ast, int pos) + { + _pos = pos; + _expression = 0; + _offset = -1; + _length = -1; -void QmlExpressionUnderCursor::operator()(const QTextCursor &cursor, - QmlJS::AST::UiProgram *program) -{ - _pos = cursor.position(); - _expressionNode = 0; - _expressionOffset = -1; - _expressionLength = -1; - _scopes.clear(); + Node::accept(ast, this); - if (program) - program->accept(this); -} + return _expression; + } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::Block *ast) -{ - _scopes.push(ast); + int offset() const + { return _offset; } - return true; -} + int length() const + { return _length; } -void QmlExpressionUnderCursor::endVisit(QmlJS::AST::Block *) -{ - _scopes.pop(); -} + protected: + bool visit(FieldMemberExpression *ast) + { + if (ast->identifierToken.offset <= _pos && _pos <= ast->identifierToken.end()) { + _expression = ast; + _offset = ast->identifierToken.offset; + _length = ast->identifierToken.length; + } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::FieldMemberExpression *ast) -{ - if (ast->identifierToken.offset <= _pos && _pos <= ast->identifierToken.end()) { - _expressionNode = ast; - _expressionOffset = ast->identifierToken.offset; - _expressionLength = ast->identifierToken.length; - _expressionScopes = _scopes; - } + return true; + } - return true; -} + bool visit(IdentifierExpression *ast) + { + if (ast->firstSourceLocation().offset <= _pos && _pos <= ast->lastSourceLocation().end()) { + _expression = ast; + _offset = ast->firstSourceLocation().offset; + _length = ast->lastSourceLocation().end() - _offset; + } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::IdentifierExpression *ast) -{ - if (ast->firstSourceLocation().offset <= _pos && _pos <= ast->lastSourceLocation().end()) { - _expressionNode = ast; - _expressionOffset = ast->firstSourceLocation().offset; - _expressionLength = ast->lastSourceLocation().end() - _expressionOffset; - _expressionScopes = _scopes; - } + return false; + } - return false; -} + bool visit(UiImport * /*ast*/) + { + return false; + } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiObjectBinding *ast) -{ - Node::accept(ast->qualifiedId, this); - Node::accept(ast->qualifiedTypeNameId, this); + bool visit(UiQualifiedId *ast) + { + if (ast->identifierToken.offset <= _pos) { + for (UiQualifiedId *iter = ast; iter; iter = iter->next) { + if (_pos <= iter->identifierToken.end()) { + // found it + _expression = ast; + _offset = ast->identifierToken.offset; + + for (UiQualifiedId *iter2 = ast; iter2; iter2 = iter2->next) { + _length = iter2->identifierToken.end() - _offset; + } + + break; + } + } + } + + return false; + } + + private: + quint32 _pos; + Node *_expression; + int _offset; + int _length; + }; + + class ScopeCalculator: protected Visitor + { + public: + QStack<QmlSymbol*> operator()(const QmlDocument::Ptr &doc, int pos) + { + _doc = doc; + _pos = pos; + _scopes.clear(); + _currentSymbol = 0; + Node::accept(doc->program(), this); + return _scopes; + } - _scopes.push(ast); + protected: + virtual bool visit(Block *ast) + { + // TODO +// if (_pos > ast->lbraceToken.end() && _pos < ast->rbraceToken.offset) { +// push(ast); +// Node::accept(ast->statements, this); +// } - Node::accept(ast->initializer, this); + return false; + } + + virtual bool visit(UiObjectBinding *ast) + { + if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) { + push(ast); + Node::accept(ast->initializer, this); + } + + return false; + } - return false; + virtual bool visit(UiObjectDefinition *ast) + { + if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) { + push(ast); + Node::accept(ast->initializer, this); + } + + return false; + } + + virtual bool visit(UiArrayBinding *ast) + { + if (ast->lbracketToken.offset < _pos && _pos <= ast->rbracketToken.end()) { + push(ast); + Node::accept(ast->members, this); + } + + return false; + } + + private: + void push(Node *node) + { + QmlSymbolFromFile* symbol; + + if (_currentSymbol) { + symbol = _currentSymbol->findMember(node); + } else { + symbol = _doc->findSymbol(node); + } + + if (symbol) { + _currentSymbol = symbol; + + if (!cast<UiArrayBinding*>(node)) + _scopes.push(symbol); + } + } + + private: + QmlDocument::Ptr _doc; + quint32 _pos; + QStack<QmlSymbol*> _scopes; + QmlSymbolFromFile* _currentSymbol; + }; + } +} + +using namespace QmlEditor; +using namespace QmlEditor::Internal; + +QmlExpressionUnderCursor::QmlExpressionUnderCursor() + : _expressionNode(0), + _pos(0), _engine(0), _nodePool(0) +{ } -void QmlExpressionUnderCursor::endVisit(QmlJS::AST::UiObjectBinding *) +QmlExpressionUnderCursor::~QmlExpressionUnderCursor() { - _scopes.pop(); + if (_engine) { delete _engine; _engine = 0; } + if (_nodePool) { delete _nodePool; _nodePool = 0; } } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiObjectDefinition *ast) +void QmlExpressionUnderCursor::operator()(const QTextCursor &cursor, + const QmlDocument::Ptr &doc) { - Node::accept(ast->qualifiedTypeNameId, this); + if (_engine) { delete _engine; _engine = 0; } + if (_nodePool) { delete _nodePool; _nodePool = 0; } - _scopes.push(ast); + _pos = cursor.position(); + _expressionNode = 0; + _expressionOffset = -1; + _expressionLength = -1; + _expressionScopes.clear(); - Node::accept(ast->initializer, this); + const QTextBlock block = cursor.block(); + parseExpression(block); - return false; + if (_expressionOffset != -1) { + ScopeCalculator calculator; + _expressionScopes = calculator(doc, _expressionOffset); + } } -void QmlExpressionUnderCursor::endVisit(QmlJS::AST::UiObjectDefinition *) +void QmlExpressionUnderCursor::parseExpression(const QTextBlock &block) { - _scopes.pop(); -} + int textPosition = _pos - block.position(); + const QString blockText = block.text(); + if (textPosition > 0) { + if (blockText.at(textPosition - 1) == QLatin1Char('.')) + --textPosition; + } else { + textPosition = 0; + } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiQualifiedId *ast) -{ - if (ast->identifierToken.offset <= _pos) { - for (UiQualifiedId *iter = ast; iter; iter = iter->next) { - if (_pos <= iter->identifierToken.end()) { - // found it - _expressionNode = ast; - _expressionOffset = ast->identifierToken.offset; - - for (UiQualifiedId *iter2 = ast; iter2; iter2 = iter2->next) { - _expressionLength = iter2->identifierToken.end() - _expressionOffset; - } + const QString text = blockText.left(textPosition); - _expressionScopes = _scopes; - break; - } - } + Node *node = 0; + + if (UiObjectMember *binding = tryBinding(text)) { +// qDebug() << "**** binding"; + node = binding; + } else if (Statement *stmt = tryStatement(text)) { +// qDebug() << "**** statement"; + node = stmt; + } else { +// qDebug() << "**** none"; } - return false; + if (node) { + PositionCalculator calculator; + _expressionNode = calculator(node, textPosition); + _expressionOffset = calculator.offset() + block.position(); + _expressionLength = calculator.length(); + } } -bool QmlExpressionUnderCursor::visit(QmlJS::AST::UiImport * /*ast*/) +Statement *QmlExpressionUnderCursor::tryStatement(const QString &text) { - return false; + _engine = new Engine(); + _nodePool = new NodePool("", _engine); + Lexer lexer(_engine); + Parser parser(_engine); + lexer.setCode(text, /*line = */ 1); + + if (parser.parseStatement()) + return parser.statement(); + else + return 0; +} + +UiObjectMember *QmlExpressionUnderCursor::tryBinding(const QString &text) +{ + _engine = new Engine(); + _nodePool = new NodePool("", _engine); + Lexer lexer(_engine); + Parser parser(_engine); + lexer.setCode(text, /*line = */ 1); + + if (parser.parseUiObjectMember()) { + UiObjectMember *member = parser.uiObjectMember(); + + if (cast<UiObjectBinding*>(member) || cast<UiArrayBinding*>(member) || cast<UiScriptBinding*>(member)) + return member; + else + return 0; + } else { + return 0; + } } diff --git a/src/plugins/qmleditor/qmlexpressionundercursor.h b/src/plugins/qmleditor/qmlexpressionundercursor.h index a891dc8968..28e8d87d64 100644 --- a/src/plugins/qmleditor/qmlexpressionundercursor.h +++ b/src/plugins/qmleditor/qmlexpressionundercursor.h @@ -2,21 +2,30 @@ #define QMLEXPRESSIONUNDERCURSOR_H #include <QStack> +#include <QTextBlock> #include <QTextCursor> -#include "qmljsastvisitor_p.h" +#include "qmldocument.h" +#include "qmljsastfwd_p.h" +#include "qmlsymbol.h" + +namespace QmlJS { + class Engine; + class NodePool; +} namespace QmlEditor { namespace Internal { -class QmlExpressionUnderCursor: protected QmlJS::AST::Visitor +class QmlExpressionUnderCursor { public: QmlExpressionUnderCursor(); + virtual ~QmlExpressionUnderCursor(); - void operator()(const QTextCursor &cursor, QmlJS::AST::UiProgram *program); + void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc); - QStack<QmlJS::AST::Node *> expressionScopes() const + QStack<QmlSymbol *> expressionScopes() const { return _expressionScopes; } QmlJS::AST::Node *expressionNode() const @@ -28,26 +37,20 @@ public: int expressionLength() const { return _expressionLength; } -protected: - virtual bool visit(QmlJS::AST::Block *ast); - virtual bool visit(QmlJS::AST::FieldMemberExpression *ast); - virtual bool visit(QmlJS::AST::IdentifierExpression *ast); - virtual bool visit(QmlJS::AST::UiImport *ast); - virtual bool visit(QmlJS::AST::UiObjectBinding *ast); - virtual bool visit(QmlJS::AST::UiObjectDefinition *ast); - virtual bool visit(QmlJS::AST::UiQualifiedId *ast); +private: + void parseExpression(const QTextBlock &block); - virtual void endVisit(QmlJS::AST::Block *); - virtual void endVisit(QmlJS::AST::UiObjectBinding *); - virtual void endVisit(QmlJS::AST::UiObjectDefinition *); + QmlJS::AST::Statement *tryStatement(const QString &text); + QmlJS::AST::UiObjectMember *tryBinding(const QString &text); private: - QStack<QmlJS::AST::Node *> _scopes; - QStack<QmlJS::AST::Node *> _expressionScopes; + QStack<QmlSymbol *> _expressionScopes; QmlJS::AST::Node *_expressionNode; int _expressionOffset; int _expressionLength; quint32 _pos; + QmlJS::Engine *_engine; + QmlJS::NodePool *_nodePool; }; } // namespace Internal diff --git a/src/plugins/qmleditor/qmlhoverhandler.cpp b/src/plugins/qmleditor/qmlhoverhandler.cpp index 890a4167fe..4c155a571f 100644 --- a/src/plugins/qmleditor/qmlhoverhandler.cpp +++ b/src/plugins/qmleditor/qmlhoverhandler.cpp @@ -27,8 +27,12 @@ ** **************************************************************************/ -#include "qmlhoverhandler.h" #include "qmleditor.h" +#include "qmlexpressionundercursor.h" +#include "qmlhoverhandler.h" +#include "qmllookupcontext.h" +#include "qmlresolveexpression.h" +#include "qmlsymbol.h" #include <coreplugin/icore.h> #include <coreplugin/uniqueidmanager.h> @@ -47,13 +51,30 @@ #include <QtGui/QTextBlock> #include <QtHelp/QHelpEngineCore> -using namespace QmlEditor::Internal; using namespace Core; +using namespace QmlEditor; +using namespace QmlEditor::Internal; QmlHoverHandler::QmlHoverHandler(QObject *parent) : QObject(parent) + , m_helpEngineNeedsSetup(false) { + m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>(); + ICore *core = ICore::instance(); + QFileInfo fi(core->settings()->fileName()); + // FIXME shouldn't the help engine create the directory if it doesn't exist? + QDir directory(fi.absolutePath()+"/qtcreator"); + if (!directory.exists()) + directory.mkpath(directory.absolutePath()); + + m_helpEngine = new QHelpEngineCore(directory.absolutePath() + + QLatin1String("/helpcollection.qhc"), this); + //m_helpEngine->setAutoSaveFilter(false); + if (!m_helpEngine->setupData()) + qWarning() << "Could not initialize help engine:" << m_helpEngine->error(); + m_helpEngine->setCurrentFilter(tr("Unfiltered")); + m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0; // Listen for editor opened events in order to connect to tooltip/helpid requests connect(core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), @@ -78,26 +99,13 @@ void QmlHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint if (! editor) return; - ScriptEditor *ed = qobject_cast<ScriptEditor *>(editor->widget()); - ICore *core = ICore::instance(); const int dbgcontext = core->uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER); if (core->hasContext(dbgcontext)) return; - m_toolTip.clear(); - - QTextCursor tc = ed->textCursor(); - tc.setPosition(pos); - const unsigned line = tc.block().blockNumber() + 1; - - foreach (const QmlJS::DiagnosticMessage &m, ed->diagnosticMessages()) { - if (m.loc.startLine == line) { - m_toolTip.append(m.message); - break; - } - } + updateHelpIdAndTooltip(editor, pos); if (m_toolTip.isEmpty()) QToolTip::hideText(); @@ -114,7 +122,97 @@ void QmlHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint } } -void QmlHoverHandler::updateContextHelpId(TextEditor::ITextEditor *, int) +void QmlHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos) +{ + updateHelpIdAndTooltip(editor, pos); +} + +static QString buildHelpId(QmlSymbol *symbol) { + if (!symbol) + return QString(); + + const QString idTemplate(QLatin1String("QML.%1")); + + return idTemplate.arg(symbol->name()); } +void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos) +{ + m_helpId.clear(); + m_toolTip.clear(); + + if (!m_modelManager) + return; + + ScriptEditor *scriptEditor = qobject_cast<ScriptEditor *>(editor->widget()); + if (!scriptEditor) + return; + + const Snapshot documents = m_modelManager->snapshot(); + const QString fileName = editor->file()->fileName(); + QmlDocument::Ptr doc = documents.value(fileName); + if (!doc) + return; // nothing to do + + QTextCursor tc(scriptEditor->document()); + tc.setPosition(pos); + const unsigned lineNumber = tc.block().blockNumber() + 1; + + // We only want to show F1 if the tooltip matches the help id + bool showF1 = true; + + foreach (const QmlJS::DiagnosticMessage &m, scriptEditor->diagnosticMessages()) { + if (m.loc.startLine == lineNumber) { + m_toolTip = m.message; + showF1 = false; + break; + } + } + + if (m_helpId.isEmpty()) { + // Move to the end of a qualified name + bool stop = false; + while (!stop) { + const QChar ch = editor->characterAt(tc.position()); + if (ch.isLetterOrNumber() || ch == QLatin1Char('_') || ch == QLatin1Char('.')) { + tc.setPosition(tc.position() + 1); + } else { + stop = true; + } + } + + // Fetch the expression's code + QmlExpressionUnderCursor expressionUnderCursor; + expressionUnderCursor(tc, doc); + + QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot()); + QmlResolveExpression resolver(context); + QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode()); + + if (resolvedSymbol) { + m_helpId = buildHelpId(resolvedSymbol); + } + } + + if (m_helpEngineNeedsSetup && m_helpEngine->registeredDocumentations().count() > 0) { + m_helpEngine->setupData(); + m_helpEngineNeedsSetup = false; + } + + if (!m_toolTip.isEmpty()) + m_toolTip = Qt::escape(m_toolTip); + + if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) { + if (showF1) { + m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>" + "<td><img src=\":/cppeditor/images/f1.svg\"></td></tr></table>")) + .arg(m_toolTip); + } + editor->setContextHelpId(m_helpId); + } else if (!m_toolTip.isEmpty()) { + m_toolTip = QString(QLatin1String("<nobr>%1")).arg(m_toolTip); + } else if (!m_helpId.isEmpty()) { + m_toolTip = QString(QLatin1String("<nobr>No help available for \"%1\"")).arg(m_helpId); + } +} diff --git a/src/plugins/qmleditor/qmlhoverhandler.h b/src/plugins/qmleditor/qmlhoverhandler.h index 13cca4a57a..b2050702e4 100644 --- a/src/plugins/qmleditor/qmlhoverhandler.h +++ b/src/plugins/qmleditor/qmlhoverhandler.h @@ -30,9 +30,12 @@ #ifndef QMLHOVERHANDLER_H #define QMLHOVERHANDLER_H +#include "qmlmodelmanagerinterface.h" + #include <QtCore/QObject> QT_BEGIN_NAMESPACE +class QHelpEngineCore; class QPoint; QT_END_NAMESPACE @@ -62,7 +65,14 @@ private slots: void editorOpened(Core::IEditor *editor); private: + void updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos); + +private: + QmlModelManagerInterface *m_modelManager; + QHelpEngineCore *m_helpEngine; + QString m_helpId; QString m_toolTip; + bool m_helpEngineNeedsSetup; }; } // namespace Internal diff --git a/src/plugins/qmleditor/qmllookupcontext.cpp b/src/plugins/qmleditor/qmllookupcontext.cpp index 6e2ca83ea8..5bbc044899 100644 --- a/src/plugins/qmleditor/qmllookupcontext.cpp +++ b/src/plugins/qmleditor/qmllookupcontext.cpp @@ -1,3 +1,4 @@ +#include <QDebug> #include "qmljsast_p.h" #include "qmljsengine_p.h" @@ -10,7 +11,7 @@ using namespace QmlEditor::Internal; using namespace QmlJS; using namespace QmlJS::AST; -QmlLookupContext::QmlLookupContext(const QStack<QmlJS::AST::Node *> &scopes, +QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes, const QmlDocument::Ptr &doc, const Snapshot &snapshot): _scopes(scopes), @@ -19,28 +20,49 @@ QmlLookupContext::QmlLookupContext(const QStack<QmlJS::AST::Node *> &scopes, { } -QmlLookupContext::~QmlLookupContext() +static inline int findFirstQmlObjectScope(const QStack<QmlSymbol*> &scopes, int startIdx) { - qDeleteAll(_temporarySymbols); + if (startIdx < 0 || startIdx >= scopes.size()) + return -1; + + for (int i = startIdx; i >= 0; --i) { + QmlSymbol *current = scopes.at(i); + + if (current->isSymbolFromFile()) { + Node *node = current->asSymbolFromFile()->node(); + + if (cast<UiObjectBinding*>(node) || cast<UiObjectDefinition*>(node)) { + return i; + } + } + } + + return -1; +} + +static inline QmlSymbol *resolveParent(const QStack<QmlSymbol*> &scopes) +{ + int idx = findFirstQmlObjectScope(scopes, scopes.size() - 1); + if (idx < 1) + return 0; + + idx = findFirstQmlObjectScope(scopes, idx - 1); + + if (idx < 0) + return 0; + else + return scopes.at(idx); } QmlSymbol *QmlLookupContext::resolve(const QString &name) { // look at property definitions - if (QmlSymbol *propertySymbol = resolveProperty(name, _scopes.top(), _doc->fileName())) - return propertySymbol; + if (!_scopes.isEmpty()) + if (QmlSymbol *propertySymbol = resolveProperty(name, _scopes.top(), _doc->fileName())) + return propertySymbol; if (name == "parent") { - for (int i = _scopes.size() - 2; i >= 0; --i) { - Node *scope = _scopes.at(i); - - if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(scope)) - return createSymbol(_doc->fileName(), definition); - else if (UiObjectBinding *binding = cast<UiObjectBinding*>(scope)) - return createSymbol(_doc->fileName(), binding); - } - - return 0; + return resolveParent(_scopes); } // look at the ids. @@ -49,14 +71,7 @@ QmlSymbol *QmlLookupContext::resolve(const QString &name) if (ids.contains(name)) return ids[name]; else - return 0; -} - -QmlSymbol *QmlLookupContext::createSymbol(const QString &fileName, QmlJS::AST::UiObjectMember *node) -{ - QmlSymbol *symbol = new QmlSymbolFromFile(fileName, node); - _temporarySymbols.append(symbol); - return symbol; + return resolveType(name); } QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fileName) @@ -79,6 +94,8 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fil if (!import) continue; + // TODO: handle Qt imports + if (!(import->fileName)) continue; @@ -88,66 +105,142 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fil if (importedTypes.contains(name)) { QmlDocument::Ptr importedDoc = importedTypes.value(name); - UiProgram *importedProgram = importedDoc->program(); - if (importedProgram && importedProgram->members && importedProgram->members->member) - return createSymbol(importedDoc->fileName(), importedProgram->members->member); + return importedDoc->symbols().at(0); } } - return 0; + // TODO: handle Qt imports, hack for now: + return resolveBuildinType(name); } -QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, Node *scope, const QString &fileName) +// FIXME: use a REAL mete-type system here! +static QSet<QString> qmlMetaTypes = QSet<QString>() + << QLatin1String("AnchorChanges") + << QLatin1String("AnimatedImage") + << QLatin1String("Animation") + << QLatin1String("Behavior") + << QLatin1String("Binding") + << QLatin1String("BorderImage") + << QLatin1String("ColorAnimation") + << QLatin1String("Column") + << QLatin1String("Component") + << QLatin1String("Connection") + << QLatin1String("DateTimeFormatter") + << QLatin1String("EaseFollow") + << QLatin1String("Flickable") + << QLatin1String("Flipable") + << QLatin1String("FocusPanel") + << QLatin1String("FocusScope") + << QLatin1String("FolderListModel") + << QLatin1String("FontLoader") + << QLatin1String("Gradient") + << QLatin1String("GradientStop") + << QLatin1String("GraphicsObjectContainer") + << QLatin1String("Grid") + << QLatin1String("GridView") + << QLatin1String("Image") + << QLatin1String("Item") + << QLatin1String("KeyEvent") + << QLatin1String("Keys") + << QLatin1String("LayoutItem") + << QLatin1String("ListModel") + << QLatin1String("ListView") + << QLatin1String("Loader") + << QLatin1String("MouseEvent") + << QLatin1String("MouseRegion") + << QLatin1String("NumberAnimation") + << QLatin1String("NumberFormatter") + << QLatin1String("ParallelAnimation") + << QLatin1String("ParentAction") + << QLatin1String("ParentChange") + << QLatin1String("ParticleMotionGravity") + << QLatin1String("ParticleMotionLinear") + << QLatin1String("ParticleMotionWander") + << QLatin1String("Particles") + << QLatin1String("Path") + << QLatin1String("PathAttribute") + << QLatin1String("PathCubic") + << QLatin1String("PathElement") + << QLatin1String("PathLine") + << QLatin1String("PathPercent") + << QLatin1String("PathQuad") + << QLatin1String("PathView") + << QLatin1String("PauseAnimation") + << QLatin1String("PropertyAction") + << QLatin1String("PropertyAnimation") + << QLatin1String("PropertyChanges") + << QLatin1String("Rectangle") + << QLatin1String("Repeater") + << QLatin1String("Rotation") + << QLatin1String("Row") + << QLatin1String("Scale") + << QLatin1String("Script") + << QLatin1String("ScriptAction") + << QLatin1String("SequentialAnimation") + << QLatin1String("SpringFollow") + << QLatin1String("SqlBind") + << QLatin1String("SqlConnection") + << QLatin1String("SqlQuery") + << QLatin1String("State") + << QLatin1String("StateChangeScript") + << QLatin1String("SystemPalette") + << QLatin1String("Text") + << QLatin1String("TextEdit") + << QLatin1String("TextInput") + << QLatin1String("Timer") + << QLatin1String("Transform") + << QLatin1String("Transition") + << QLatin1String("VisualItemModel") + << QLatin1String("WebView") + << QLatin1String("XmlListModel") + << QLatin1String("XmlRole"); + +QmlSymbol *QmlLookupContext::resolveBuildinType(const QString &name) { - UiQualifiedId *typeName = 0; + // FIXME: use a REAL mete-type system here! + + if (name == "Rectangle") { + QmlBuildInSymbol *rectSymbol = new QmlBuildInSymbol(name); + rectSymbol->addMember(new QmlBuildInSymbol("x")); + rectSymbol->addMember(new QmlBuildInSymbol("y")); + rectSymbol->addMember(new QmlBuildInSymbol("height")); + rectSymbol->addMember(new QmlBuildInSymbol("width")); + return rectSymbol; + } else if (qmlMetaTypes.contains(name)) { + return new QmlBuildInSymbol(name); + } else { + return 0; + } +} - if (UiObjectBinding *binding = cast<UiObjectBinding*>(scope)) { - if (QmlSymbol *symbol = resolveProperty(name, binding->initializer, fileName)) +QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName) +{ + foreach (QmlSymbol *symbol, scope->members()) + if (symbol->name() == name) return symbol; - else + + UiQualifiedId *typeName = 0; + + if (scope->isSymbolFromFile()) { + Node *ast = scope->asSymbolFromFile()->node(); + + if (UiObjectBinding *binding = cast<UiObjectBinding*>(ast)) { typeName = binding->qualifiedTypeNameId; - } else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(scope)) { - if (QmlSymbol *symbol = resolveProperty(name, definition->initializer, fileName)) - return symbol; - else + } else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(ast)) { typeName = definition->qualifiedTypeNameId; - } // TODO: extend this to handle (JavaScript) block scopes. + } // TODO: extend this to handle (JavaScript) block scopes. + } if (typeName == 0) return 0; QmlSymbol *typeSymbol = resolveType(toString(typeName), fileName); - if (typeSymbol && typeSymbol->isSymbolFromFile()) { - return resolveProperty(name, typeSymbol->asSymbolFromFile()->node(), typeSymbol->asSymbolFromFile()->fileName()); - } - - return 0; -} - -QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlJS::AST::UiObjectInitializer *initializer, const QString &fileName) -{ - if (!initializer) + if (!typeSymbol) return 0; - for (UiObjectMemberList *iter = initializer->members; iter; iter = iter->next) { - UiObjectMember *member = iter->member; - if (!member) - continue; - - if (UiPublicMember *publicMember = cast<UiPublicMember*>(member)) { - if (name == publicMember->name->asString()) - return createSymbol(fileName, publicMember); - } else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) { - if (name == toString(objectBinding->qualifiedId)) - return createSymbol(fileName, objectBinding); - } else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) { - if (name == toString(arrayBinding->qualifiedId)) - return createSymbol(fileName, arrayBinding); - } else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) { - if (name == toString(scriptBinding->qualifiedId)) - return createSymbol(fileName, scriptBinding); - } - } + if (typeSymbol->isSymbolFromFile()) { + return resolveProperty(name, typeSymbol->asSymbolFromFile(), typeSymbol->asSymbolFromFile()->fileName()); + } // TODO: internal types return 0; } @@ -169,10 +262,17 @@ QString QmlLookupContext::toString(UiQualifiedId *id) return str; } -QList<QmlSymbol*> QmlLookupContext::visibleSymbols(QmlJS::AST::Node * /* scope */) +QList<QmlSymbol*> QmlLookupContext::visibleSymbolsInScope() { - // FIXME - return QList<QmlSymbol*>(); + QList<QmlSymbol*> result; + + if (!_scopes.isEmpty()) { + QmlSymbol *scope = _scopes.top(); + + result.append(scope->members()); + } + + return result; } QList<QmlSymbol*> QmlLookupContext::visibleTypes() @@ -196,13 +296,13 @@ QList<QmlSymbol*> QmlLookupContext::visibleTypes() const QMap<QString, QmlDocument::Ptr> types = _snapshot.componentsDefinedByImportedDocuments(_doc, path); foreach (const QmlDocument::Ptr typeDoc, types) { - UiProgram *typeProgram = typeDoc->program(); - - if (typeProgram && typeProgram->members && typeProgram->members->member) { - result.append(createSymbol(typeDoc->fileName(), typeProgram->members->member)); - } + result.append(typeDoc->symbols().at(0)); } } + // TODO: handle Qt imports, hack for now: + foreach (const QString &name, qmlMetaTypes) + result.append(resolveBuildinType(name)); + return result; } diff --git a/src/plugins/qmleditor/qmllookupcontext.h b/src/plugins/qmleditor/qmllookupcontext.h index 80635c0393..d1c64dc711 100644 --- a/src/plugins/qmleditor/qmllookupcontext.h +++ b/src/plugins/qmleditor/qmllookupcontext.h @@ -13,10 +13,9 @@ namespace Internal { class QmlLookupContext { public: - QmlLookupContext(const QStack<QmlJS::AST::Node *> &scopes, + QmlLookupContext(const QStack<QmlSymbol *> &scopes, const QmlDocument::Ptr &doc, const Snapshot &snapshot); - ~QmlLookupContext(); QmlSymbol *resolve(const QString &name); QmlSymbol *resolveType(const QString &name) @@ -27,23 +26,20 @@ public: QmlDocument::Ptr document() const { return _doc; } - QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *scope); + QList<QmlSymbol*> visibleSymbolsInScope(); QList<QmlSymbol*> visibleTypes(); private: - QmlSymbol *createSymbol(const QString &fileName, QmlJS::AST::UiObjectMember *node); - QmlSymbol *resolveType(const QString &name, const QString &fileName); - QmlSymbol *resolveProperty(const QString &name, QmlJS::AST::Node *scope, const QString &fileName); - QmlSymbol *resolveProperty(const QString &name, QmlJS::AST::UiObjectInitializer *initializer, const QString &fileName); + QmlSymbol *resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName); + QmlSymbol *resolveBuildinType(const QString &name); static QString toString(QmlJS::AST::UiQualifiedId *id); private: - QStack<QmlJS::AST::Node *> _scopes; + QStack<QmlSymbol *> _scopes; QmlDocument::Ptr _doc; Snapshot _snapshot; - QList<QmlSymbol*> _temporarySymbols; }; } // namespace Internal diff --git a/src/plugins/qmleditor/qmlmodelmanager.cpp b/src/plugins/qmleditor/qmlmodelmanager.cpp index b7b09adecb..ae4e309fcb 100644 --- a/src/plugins/qmleditor/qmlmodelmanager.cpp +++ b/src/plugins/qmleditor/qmlmodelmanager.cpp @@ -52,9 +52,10 @@ QmlModelManager::QmlModelManager(QObject *parent): { m_synchronizer.setCancelOnWait(true); - qRegisterMetaType<QmlDocument::Ptr>("QmlDocument::Ptr"); + qRegisterMetaType<QmlEditor::QmlDocument::Ptr>("QmlEditor::QmlDocument::Ptr"); - connect(this, SIGNAL(documentUpdated(QmlDocument::Ptr)), this, SLOT(onDocumentUpdated(QmlDocument::Ptr))); + connect(this, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)), + this, SLOT(onDocumentUpdated(QmlEditor::QmlDocument::Ptr))); } Snapshot QmlModelManager::snapshot() const @@ -122,7 +123,7 @@ QMap<QString, QString> QmlModelManager::buildWorkingCopyList() void QmlModelManager::emitDocumentUpdated(QmlDocument::Ptr doc) { emit documentUpdated(doc); } -void QmlModelManager::onDocumentUpdated(QmlDocument::Ptr doc) +void QmlModelManager::onDocumentUpdated(QmlEditor::QmlDocument::Ptr doc) { QMutexLocker locker(&m_mutex); diff --git a/src/plugins/qmleditor/qmlmodelmanager.h b/src/plugins/qmleditor/qmlmodelmanager.h index 4eb1f408b6..cada51871d 100644 --- a/src/plugins/qmleditor/qmlmodelmanager.h +++ b/src/plugins/qmleditor/qmlmodelmanager.h @@ -58,13 +58,11 @@ public: Q_SIGNALS: void projectPathChanged(const QString &projectPath); - - void documentUpdated(QmlDocument::Ptr doc); void aboutToRemoveFiles(const QStringList &files); private Q_SLOTS: // this should be executed in the GUI thread. - void onDocumentUpdated(QmlDocument::Ptr doc); + void onDocumentUpdated(QmlEditor::QmlDocument::Ptr doc); protected: QFuture<void> refreshSourceFiles(const QStringList &sourceFiles); diff --git a/src/plugins/qmleditor/qmlmodelmanagerinterface.h b/src/plugins/qmleditor/qmlmodelmanagerinterface.h index 4adcf91bd0..f348b30bc9 100644 --- a/src/plugins/qmleditor/qmlmodelmanagerinterface.h +++ b/src/plugins/qmleditor/qmlmodelmanagerinterface.h @@ -32,8 +32,10 @@ #include <QObject> #include <QStringList> +#include <QSharedPointer> #include <qmleditor/qmleditor_global.h> +#include <qmleditor/qmldocument.h> namespace QmlEditor { @@ -49,6 +51,9 @@ public: virtual Snapshot snapshot() const = 0; virtual void updateSourceFiles(const QStringList &files) = 0; + +signals: + void documentUpdated(QmlEditor::QmlDocument::Ptr doc); }; } diff --git a/src/plugins/qmleditor/qmlresolveexpression.cpp b/src/plugins/qmleditor/qmlresolveexpression.cpp index 89c7090a4d..1b464147aa 100644 --- a/src/plugins/qmleditor/qmlresolveexpression.cpp +++ b/src/plugins/qmleditor/qmlresolveexpression.cpp @@ -12,11 +12,6 @@ QmlResolveExpression::QmlResolveExpression(const QmlLookupContext &context) { } -QmlResolveExpression::~QmlResolveExpression() -{ - qDeleteAll(_temporarySymbols); -} - QmlSymbol *QmlResolveExpression::typeOf(Node *node) { QmlSymbol *previousValue = switchValue(0); @@ -25,6 +20,30 @@ QmlSymbol *QmlResolveExpression::typeOf(Node *node) return switchValue(previousValue); } +QList<QmlSymbol*> QmlResolveExpression::visibleSymbols(Node *node) +{ + QList<QmlSymbol*> result; + + QmlSymbol *symbol = typeOf(node); + if (symbol) { + if (symbol->isIdSymbol()) + symbol = symbol->asIdSymbol()->parentNode(); + result.append(symbol->members()); + + // TODO: also add symbols from super-types + } else { + result.append(_context.visibleTypes()); + } + + if (node) { + foreach (QmlIdSymbol *idSymbol, _context.document()->ids().values()) + result.append(idSymbol); + } + + result.append(_context.visibleSymbolsInScope()); + + return result; +} QmlSymbol *QmlResolveExpression::switchValue(QmlSymbol *value) { @@ -58,52 +77,19 @@ bool QmlResolveExpression::visit(FieldMemberExpression *ast) { const QString memberName = ast->name->asString(); - const QmlSymbol *base = typeOf(ast->base); + QmlSymbol *base = typeOf(ast->base); if (!base) return false; if (base->isIdSymbol()) base = base->asIdSymbol()->parentNode(); - UiObjectMemberList *members = 0; - - if (const QmlSymbolFromFile *symbol = base->asSymbolFromFile()) { - Node *node = symbol->node(); - - if (UiObjectBinding *binding = cast<UiObjectBinding*>(node)) { - if (binding->initializer) - members = binding->initializer->members; - } else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(node)) { - if (definition->initializer) - members = definition->initializer->members; - } - } + if (!base) + return false; - for (UiObjectMemberList *it = members; it; it = it->next) { - UiObjectMember *member = it->member; - - if (UiPublicMember *publicMember = cast<UiPublicMember *>(member)) { - if (publicMember->name && publicMember->name->asString() == memberName) { - _value = createPropertyDefinitionSymbol(publicMember); - break; // we're done. - } - } else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) { - if (matches(objectBinding->qualifiedId, memberName)) { - _value = createSymbolFromFile(objectBinding); - break; // we're done - } - } else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) { - if (matches(scriptBinding->qualifiedId, memberName)) { - _value = createSymbolFromFile(scriptBinding); - break; // we're done - } - } else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) { - if (matches(arrayBinding->qualifiedId, memberName)) { - _value = createSymbolFromFile(arrayBinding); - break; // we're done - } - } - } + foreach (QmlSymbol *memberSymbol, base->members()) + if (memberSymbol->name() == memberName) + _value = memberSymbol; return false; } @@ -114,17 +100,3 @@ bool QmlResolveExpression::visit(QmlJS::AST::UiQualifiedId *ast) return false; } - -QmlPropertyDefinitionSymbol *QmlResolveExpression::createPropertyDefinitionSymbol(QmlJS::AST::UiPublicMember *ast) -{ - QmlPropertyDefinitionSymbol *symbol = new QmlPropertyDefinitionSymbol(_context.document()->fileName(), ast); - _temporarySymbols.append(symbol); - return symbol; -} - -QmlSymbolFromFile *QmlResolveExpression::createSymbolFromFile(QmlJS::AST::UiObjectMember *ast) -{ - QmlSymbolFromFile *symbol = new QmlSymbolFromFile(_context.document()->fileName(), ast); - _temporarySymbols.append(symbol); - return symbol; -} diff --git a/src/plugins/qmleditor/qmlresolveexpression.h b/src/plugins/qmleditor/qmlresolveexpression.h index b756887f4a..41e44e8853 100644 --- a/src/plugins/qmleditor/qmlresolveexpression.h +++ b/src/plugins/qmleditor/qmlresolveexpression.h @@ -12,15 +12,13 @@ class QmlResolveExpression: protected QmlJS::AST::Visitor { public: QmlResolveExpression(const QmlLookupContext &context); - ~QmlResolveExpression(); - QmlSymbol *operator()(QmlJS::AST::Node *node) - { return typeOf(node); } + QmlSymbol *typeOf(QmlJS::AST::Node *node); + QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node); protected: using QmlJS::AST::Visitor::visit; - QmlSymbol *typeOf(QmlJS::AST::Node *node); QmlSymbol *switchValue(QmlSymbol *symbol); virtual bool visit(QmlJS::AST::FieldMemberExpression *ast); @@ -28,12 +26,7 @@ protected: virtual bool visit(QmlJS::AST::UiQualifiedId *ast); private: - QmlPropertyDefinitionSymbol *createPropertyDefinitionSymbol(QmlJS::AST::UiPublicMember *ast); - QmlSymbolFromFile *createSymbolFromFile(QmlJS::AST::UiObjectMember *ast); - -private: QmlLookupContext _context; - QList<QmlSymbol*> _temporarySymbols; QmlSymbol *_value; }; diff --git a/src/plugins/qmleditor/qmlsymbol.cpp b/src/plugins/qmleditor/qmlsymbol.cpp index 21271fb709..afd0f7e719 100644 --- a/src/plugins/qmleditor/qmlsymbol.cpp +++ b/src/plugins/qmleditor/qmlsymbol.cpp @@ -1,4 +1,5 @@ #include "qmljsast_p.h" +#include "qmljsengine_p.h" #include "qmlsymbol.h" using namespace QmlEditor; @@ -7,41 +8,68 @@ using namespace QmlJS::AST; QmlSymbol::~QmlSymbol() { + qDeleteAll(_members); } -bool QmlSymbol::isBuildInSymbol() const +bool QmlSymbol::isBuildInSymbol() { return asBuildInSymbol() != 0; } -bool QmlSymbol::isSymbolFromFile() const +bool QmlSymbol::isSymbolFromFile() { return asSymbolFromFile() != 0; } -bool QmlSymbol::isIdSymbol() const +bool QmlSymbol::isIdSymbol() { return asIdSymbol() != 0; } -QmlBuildInSymbol const *QmlSymbol::asBuildInSymbol() const +bool QmlSymbol::isPropertyDefinitionSymbol() +{ return asPropertyDefinitionSymbol() != 0; } + +QmlBuildInSymbol *QmlSymbol::asBuildInSymbol() +{ return 0; } + +QmlSymbolFromFile *QmlSymbol::asSymbolFromFile() { return 0; } -QmlSymbolFromFile const *QmlSymbol::asSymbolFromFile() const +QmlIdSymbol *QmlSymbol::asIdSymbol() { return 0; } -QmlIdSymbol const *QmlSymbol::asIdSymbol() const +QmlPropertyDefinitionSymbol *QmlSymbol::asPropertyDefinitionSymbol() { return 0; } +const QmlSymbol::List QmlSymbol::members() +{ return _members; } + QmlBuildInSymbol::~QmlBuildInSymbol() {} -QmlBuildInSymbol const* QmlBuildInSymbol::asBuildInSymbol() const +QmlBuildInSymbol *QmlBuildInSymbol::asBuildInSymbol() { return this; } + QmlSymbolFromFile::QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node): _fileName(fileName), _node(node) -{} +{ + if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(_node)) { + if (objectBinding->initializer) + for (UiObjectMemberList *iter = objectBinding->initializer->members; iter; iter = iter->next) + if (iter->member) + todo.append(iter->member); + } else if (UiObjectDefinition *objectDefinition = cast<UiObjectDefinition*>(_node)) { + if (objectDefinition->initializer) + for (UiObjectMemberList *iter = objectDefinition->initializer->members; iter; iter = iter->next) + if (iter->member) + todo.append(iter->member); + } else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(_node)) { + for (UiArrayMemberList *iter = arrayBinding->members; iter; iter = iter->next) + if (iter->member) + todo.append(iter->member); + } +} QmlSymbolFromFile::~QmlSymbolFromFile() {} -const QmlSymbolFromFile *QmlSymbolFromFile::asSymbolFromFile() const +QmlSymbolFromFile *QmlSymbolFromFile::asSymbolFromFile() { return this; } int QmlSymbolFromFile::line() const @@ -50,7 +78,76 @@ int QmlSymbolFromFile::line() const int QmlSymbolFromFile::column() const { return _node->firstSourceLocation().startColumn; } -QmlIdSymbol::QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *idNode, const QmlSymbolFromFile &parentNode): +static inline QString toString(UiQualifiedId *qId) +{ + QString result; + + for (UiQualifiedId *iter = qId; iter; iter = iter->next) { + if (!iter->name) + continue; + + result += iter->name->asString(); + + if (iter->next) + result += '.'; + } + + return result; +} + +const QString QmlSymbolFromFile::name() const +{ + if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(_node)) + return toString(objectBinding->qualifiedId); + else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(_node)) + return toString(scriptBinding->qualifiedId); + else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(_node)) + return toString(arrayBinding->qualifiedId); + else if (UiObjectDefinition *objectDefinition = cast<UiObjectDefinition*>(_node)) + return toString(objectDefinition->qualifiedTypeNameId); + else + return QString::null; +} + +const QmlSymbol::List QmlSymbolFromFile::members() +{ + if (!todo.isEmpty()) { + foreach (Node *node, todo) { + if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(node)) + _members.append(new QmlSymbolFromFile(fileName(), objectBinding)); + else if (UiObjectDefinition *objectDefinition = cast<UiObjectDefinition*>(node)) + _members.append(new QmlSymbolFromFile(fileName(), objectDefinition)); + else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(node)) + _members.append(new QmlSymbolFromFile(fileName(), arrayBinding)); + else if (UiPublicMember *publicMember = cast<UiPublicMember*>(node)) + _members.append(new QmlPropertyDefinitionSymbol(fileName(), publicMember)); + else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(node)) { + if (scriptBinding->qualifiedId && scriptBinding->qualifiedId->name && scriptBinding->qualifiedId->name->asString() == QLatin1String("id") && !scriptBinding->qualifiedId->next) + _members.append(new QmlIdSymbol(fileName(), scriptBinding, this)); + else + _members.append(new QmlSymbolFromFile(fileName(), scriptBinding)); + } + } + + todo.clear(); + } + + return _members; +} + +QmlSymbolFromFile *QmlSymbolFromFile::findMember(QmlJS::AST::Node *memberNode) +{ + List symbols = members(); + + foreach (QmlSymbol *symbol, symbols) + if (symbol->isSymbolFromFile()) + if (memberNode == symbol->asSymbolFromFile()->node()) + return symbol->asSymbolFromFile(); + + return 0; +} + +QmlIdSymbol::QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *idNode, QmlSymbolFromFile *parentNode): QmlSymbolFromFile(fileName, idNode), _parentNode(parentNode) {} @@ -58,7 +155,7 @@ QmlIdSymbol::QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *i QmlIdSymbol::~QmlIdSymbol() {} -QmlIdSymbol const *QmlIdSymbol::asIdSymbol() const +QmlIdSymbol *QmlIdSymbol::asIdSymbol() { return this; } int QmlIdSymbol::line() const @@ -67,6 +164,16 @@ int QmlIdSymbol::line() const int QmlIdSymbol::column() const { return idNode()->statement->firstSourceLocation().startColumn; } +const QString QmlIdSymbol::id() const +{ + if (ExpressionStatement *e = cast<ExpressionStatement*>(idNode()->statement)) + if (IdentifierExpression *i = cast<IdentifierExpression*>(e->expression)) + if (i->name) + return i->name->asString(); + + return QString(); +} + QmlJS::AST::UiScriptBinding *QmlIdSymbol::idNode() const { return cast<UiScriptBinding*>(node()); } @@ -77,6 +184,9 @@ QmlPropertyDefinitionSymbol::QmlPropertyDefinitionSymbol(const QString &fileName QmlPropertyDefinitionSymbol::~QmlPropertyDefinitionSymbol() {} +QmlPropertyDefinitionSymbol *QmlPropertyDefinitionSymbol::asPropertyDefinitionSymbol() +{ return this; } + int QmlPropertyDefinitionSymbol::line() const { return propertyNode()->identifierToken.startLine; } @@ -85,3 +195,6 @@ int QmlPropertyDefinitionSymbol::column() const QmlJS::AST::UiPublicMember *QmlPropertyDefinitionSymbol::propertyNode() const { return cast<UiPublicMember*>(node()); } + +const QString QmlPropertyDefinitionSymbol::name() const +{ return propertyNode()->name->asString(); } diff --git a/src/plugins/qmleditor/qmlsymbol.h b/src/plugins/qmleditor/qmlsymbol.h index be827faea2..4b9f213be6 100644 --- a/src/plugins/qmleditor/qmlsymbol.h +++ b/src/plugins/qmleditor/qmlsymbol.h @@ -1,34 +1,54 @@ #ifndef QMLSYMBOL_H #define QMLSYMBOL_H +#include <QList> #include <QString> -#include "qmljsastfwd_p.h" +#include <qmleditor/parser/qmljsastfwd_p.h> namespace QmlEditor { class QmlSymbol { public: - virtual ~QmlSymbol() = 0; + typedef QList<QmlSymbol*> List; - bool isBuildInSymbol() const; - bool isSymbolFromFile() const; - bool isIdSymbol() const; +public: + virtual ~QmlSymbol(); + + virtual const QString name() const = 0; + virtual const List members(); + + bool isBuildInSymbol(); + bool isSymbolFromFile(); + bool isIdSymbol(); + bool isPropertyDefinitionSymbol(); + + virtual class QmlBuildInSymbol *asBuildInSymbol(); + virtual class QmlSymbolFromFile *asSymbolFromFile(); + virtual class QmlIdSymbol *asIdSymbol(); + virtual class QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol(); - virtual class QmlBuildInSymbol const *asBuildInSymbol() const; - virtual class QmlSymbolFromFile const *asSymbolFromFile() const; - virtual class QmlIdSymbol const *asIdSymbol() const; +protected: + List _members; }; class QmlBuildInSymbol: public QmlSymbol { public: + QmlBuildInSymbol(const QString &name): _name(name) {} virtual ~QmlBuildInSymbol(); - virtual QmlBuildInSymbol const *asBuildInSymbol() const; + virtual QmlBuildInSymbol *asBuildInSymbol(); + + virtual const QString name() const + { return _name; } + + void addMember(QmlBuildInSymbol *symbol) + { _members.append(symbol); } private: + QString _name; }; class QmlSymbolFromFile: public QmlSymbol @@ -37,7 +57,7 @@ public: QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node); virtual ~QmlSymbolFromFile(); - virtual QmlSymbolFromFile const *asSymbolFromFile() const; + virtual QmlSymbolFromFile *asSymbolFromFile(); QString fileName() const { return _fileName; } @@ -48,30 +68,43 @@ public: QmlJS::AST::UiObjectMember *node() const { return _node; } + virtual const QString name() const; + virtual const List members(); + virtual QmlSymbolFromFile *findMember(QmlJS::AST::Node *memberNode); + +private: + void fillTodo(QmlJS::AST::UiObjectMemberList *members); + private: QString _fileName; QmlJS::AST::UiObjectMember *_node; + QList<QmlJS::AST::Node*> todo; }; class QmlIdSymbol: public QmlSymbolFromFile { public: - QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *idNode, const QmlSymbolFromFile &parentNode); + QmlIdSymbol(const QString &fileName, QmlJS::AST::UiScriptBinding *idNode, QmlSymbolFromFile *parentNode); virtual ~QmlIdSymbol(); - QmlIdSymbol const *asIdSymbol() const; + QmlIdSymbol *asIdSymbol(); virtual int line() const; virtual int column() const; - QmlSymbolFromFile const *parentNode() const - { return &_parentNode; } + QmlSymbolFromFile *parentNode() const + { return _parentNode; } + + virtual const QString name() const + { return "id"; } + + virtual const QString id() const; private: QmlJS::AST::UiScriptBinding *idNode() const; private: - QmlSymbolFromFile _parentNode; + QmlSymbolFromFile *_parentNode; }; class QmlPropertyDefinitionSymbol: public QmlSymbolFromFile @@ -80,9 +113,13 @@ public: QmlPropertyDefinitionSymbol(const QString &fileName, QmlJS::AST::UiPublicMember *propertyNode); virtual ~QmlPropertyDefinitionSymbol(); + QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol(); + virtual int line() const; virtual int column() const; + virtual const QString name() const; + private: QmlJS::AST::UiPublicMember *propertyNode() const; }; diff --git a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec index 4fe8907b25..bc83968cac 100644 --- a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec +++ b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec @@ -1,4 +1,4 @@ -<plugin name="QmlProjectManager" version="1.3.0" compatVersion="1.3.0"> +<plugin name="QmlProjectManager" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,10 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Qml support</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="CppTools" version="1.3.0"/> - <dependency name="CppEditor" version="1.3.0"/> - <dependency name="Help" version="1.3.0"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="QmlEditor" version="1.3.80"/> + <dependency name="Help" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h index 77c2290e6e..38611e657c 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectconstants.h +++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h @@ -49,6 +49,8 @@ const char *const PROJECT_KIND = "QML"; const char *const FILES_EDITOR = ".qmlproject Editor"; const char *const FILES_MIMETYPE = QMLMIMETYPE; +const char *const TASK_CATEGORY_QML = "Task.Category.Qml"; + } // namespace Constants } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro index 354c07800e..9f41b40d85 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro @@ -10,6 +10,7 @@ HEADERS = qmlproject.h \ qmlprojectwizard.h \ qmlnewprojectwizard.h \ qmlprojectfileseditor.h \ + qmltaskmanager.h \ qmlmakestep.h SOURCES = qmlproject.cpp \ qmlprojectplugin.cpp \ @@ -18,6 +19,7 @@ SOURCES = qmlproject.cpp \ qmlprojectwizard.cpp \ qmlnewprojectwizard.cpp \ qmlprojectfileseditor.cpp \ + qmltaskmanager.cpp \ qmlmakestep.cpp RESOURCES += qmlproject.qrc diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 5d21971a35..a41f3ad78d 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -35,19 +35,26 @@ #include "qmlprojectfileseditor.h" #include "qmlproject.h" #include "qmlmakestep.h" +#include "qmltaskmanager.h" + +#include <extensionsystem/pluginmanager.h> #include <coreplugin/icore.h> #include <coreplugin/mimedatabase.h> #include <texteditor/texteditoractionhandler.h> +#include <projectexplorer/taskwindow.h> +#include <qmleditor/qmlmodelmanagerinterface.h> + #include <QtCore/QtPlugin> using namespace QmlProjectManager; using namespace QmlProjectManager::Internal; -QmlProjectPlugin::QmlProjectPlugin() - : m_projectFilesEditorFactory(0) +QmlProjectPlugin::QmlProjectPlugin() : + m_projectFilesEditorFactory(0), + m_qmlTaskManager(0) { } QmlProjectPlugin::~QmlProjectPlugin() @@ -76,6 +83,8 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) m_projectFilesEditorFactory = new ProjectFilesFactory(manager, actionHandler); addObject(m_projectFilesEditorFactory); + m_qmlTaskManager = new QmlTaskManager(this); + addAutoReleasedObject(manager); addAutoReleasedObject(new QmlRunConfigurationFactory); addAutoReleasedObject(new QmlNewProjectWizard); @@ -86,6 +95,15 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) } void QmlProjectPlugin::extensionsInitialized() -{ } +{ + ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); + ProjectExplorer::TaskWindow *taskWindow = pluginManager->getObject<ProjectExplorer::TaskWindow>(); + m_qmlTaskManager->setTaskWindow(taskWindow); + + QmlEditor::QmlModelManagerInterface *modelManager = pluginManager->getObject<QmlEditor::QmlModelManagerInterface>(); + Q_ASSERT(modelManager); + connect(modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)), + m_qmlTaskManager, SLOT(documentUpdated(QmlEditor::QmlDocument::Ptr))); +} Q_EXPORT_PLUGIN(QmlProjectPlugin) diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.h b/src/plugins/qmlprojectmanager/qmlprojectplugin.h index 29ac7db5e4..ab5d13a57a 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.h +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.h @@ -38,6 +38,7 @@ namespace QmlProjectManager { namespace Internal { class ProjectFilesFactory; +class QmlTaskManager; class QmlProjectPlugin: public ExtensionSystem::IPlugin { @@ -52,6 +53,7 @@ public: private: ProjectFilesFactory *m_projectFilesEditorFactory; + QmlTaskManager *m_qmlTaskManager; }; } // namespace Internal diff --git a/src/plugins/qmlprojectmanager/qmltaskmanager.cpp b/src/plugins/qmlprojectmanager/qmltaskmanager.cpp new file mode 100644 index 0000000000..2a76c425ce --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmltaskmanager.cpp @@ -0,0 +1,38 @@ +#include "qmltaskmanager.h" +#include "qmlprojectconstants.h" +#include <QDebug> + +namespace QmlProjectManager { +namespace Internal { + +QmlTaskManager::QmlTaskManager(QObject *parent) : + QObject(parent), + m_taskWindow(0) +{ +} + +void QmlTaskManager::setTaskWindow(ProjectExplorer::TaskWindow *taskWindow) +{ + Q_ASSERT(taskWindow); + m_taskWindow = taskWindow; + + m_taskWindow->addCategory(Constants::TASK_CATEGORY_QML, "Qml"); +} + +void QmlTaskManager::documentUpdated(QmlEditor::QmlDocument::Ptr doc) +{ + m_taskWindow->clearTasks(Constants::TASK_CATEGORY_QML); + + foreach (const QmlJS::DiagnosticMessage &msg, doc->diagnosticMessages()) { + ProjectExplorer::TaskWindow::TaskType type + = msg.isError() ? ProjectExplorer::TaskWindow::Error + : ProjectExplorer::TaskWindow::Warning; + + ProjectExplorer::TaskWindow::Task task(type, msg.message, doc->fileName(), msg.loc.startLine, + Constants::TASK_CATEGORY_QML); + m_taskWindow->addTask(task); + } +} + +} // Internal +} // QmlEditor diff --git a/src/plugins/qmlprojectmanager/qmltaskmanager.h b/src/plugins/qmlprojectmanager/qmltaskmanager.h new file mode 100644 index 0000000000..0f95261076 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmltaskmanager.h @@ -0,0 +1,29 @@ +#ifndef QMLTASKMANAGER_H +#define QMLTASKMANAGER_H + +#include <projectexplorer/taskwindow.h> +#include <qmleditor/qmldocument.h> +#include <QtCore/QObject> + + +namespace QmlProjectManager { +namespace Internal { + +class QmlTaskManager : public QObject +{ + Q_OBJECT +public: + QmlTaskManager(QObject *parent = 0); + void setTaskWindow(ProjectExplorer::TaskWindow *taskWindow); + +public slots: + void documentUpdated(QmlEditor::QmlDocument::Ptr doc); + +private: + ProjectExplorer::TaskWindow *m_taskWindow; +}; + +} // Internal +} // QmlProjectManager + +#endif // QMLTASKMANAGER_H diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec index 6b44e5f4ba..a39d5609fa 100644 --- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec +++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Qt4ProjectManager" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Qt4ProjectManager" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,11 +19,12 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Provides project type for Qt 4 pro files and tools.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="CppTools" version="1.3.0"/> - <dependency name="CppEditor" version="1.3.0"/> - <dependency name="Help" version="1.3.0"/> - <dependency name="Designer" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> + <dependency name="CppEditor" version="1.3.80"/> + <dependency name="Help" version="1.3.80"/> + <dependency name="Designer" version="1.3.80"/> + <dependency name="Debugger" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp index 049d327c11..65b5f4a278 100644 --- a/src/plugins/qt4projectmanager/makestep.cpp +++ b/src/plugins/qt4projectmanager/makestep.cpp @@ -115,6 +115,13 @@ bool MakeStep::init(const QString &name) if (type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE) setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_MSVC); + else if (ProjectExplorer::ToolChain::GCCE == type) + setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE); + else if (ProjectExplorer::ToolChain::WINSCW == type) + setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW); + else if (ProjectExplorer::ToolChain::RVCT_ARMV5 == type || + ProjectExplorer::ToolChain::RVCT_ARMV6 == type) + setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT); else setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_GCC); @@ -248,9 +255,6 @@ void MakeStepConfigWidget::init(const QString &buildConfiguration) { m_buildConfiguration = buildConfiguration; - Qt4Project *pro = qobject_cast<Qt4Project *>(m_makeStep->project()); - Q_ASSERT(pro); - if (!m_makeStep->value(buildConfiguration, "cleanConfig").isValid() && m_makeStep->value("clean").isValid() && m_makeStep->value("clean").toBool()) { // Import old settings m_makeStep->setValue(buildConfiguration, "cleanConfig", true); diff --git a/src/plugins/qt4projectmanager/profilereader.cpp b/src/plugins/qt4projectmanager/profilereader.cpp index 333f43ff27..826f44c469 100644 --- a/src/plugins/qt4projectmanager/profilereader.cpp +++ b/src/plugins/qt4projectmanager/profilereader.cpp @@ -45,7 +45,8 @@ ProFileReader::~ProFileReader() delete pf; } -void ProFileReader::setQtVersion(QtVersion *qtVersion) { +void ProFileReader::setQtVersion(const QtVersion *qtVersion) +{ if (qtVersion) m_option.properties = qtVersion->versionInfo(); else diff --git a/src/plugins/qt4projectmanager/profilereader.h b/src/plugins/qt4projectmanager/profilereader.h index 2640b80606..09782a0b38 100644 --- a/src/plugins/qt4projectmanager/profilereader.h +++ b/src/plugins/qt4projectmanager/profilereader.h @@ -47,7 +47,7 @@ public: ProFileReader(); ~ProFileReader(); - void setQtVersion(QtVersion *qtVersion); + void setQtVersion(const QtVersion *qtVersion); bool readProFile(const QString &fileName); QList<ProFile*> includeFiles() const; diff --git a/src/plugins/qt4projectmanager/projectloadwizard.cpp b/src/plugins/qt4projectmanager/projectloadwizard.cpp index c60f53e47d..ffad329b3f 100644 --- a/src/plugins/qt4projectmanager/projectloadwizard.cpp +++ b/src/plugins/qt4projectmanager/projectloadwizard.cpp @@ -66,23 +66,17 @@ ProjectLoadWizard::ProjectLoadWizard(Qt4Project *project, QWidget *parent, Qt::W QPair<QtVersion::QmakeBuildConfig, QStringList> result = QtVersionManager::scanMakeFile(directory, m_importVersion->defaultBuildConfig()); m_importBuildConfig = result.first; - m_additionalArguments = result.second; + m_additionalArguments = Qt4Project::removeSpecFromArgumentList(result.second); - QString versionSpec = m_importVersion->sourcePath() + "/mkspecs/" + m_importVersion->mkspec(); - QString parsedSpec = Qt4Project::extractSpecFromArgumentList(m_additionalArguments); + QString parsedSpec = Qt4Project::extractSpecFromArgumentList(result.second, directory, m_importVersion); + QString versionSpec = m_importVersion->mkspec(); // Compare mkspecs and add to additional arguments - if (parsedSpec.isEmpty()) { + if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") { // using the default spec, don't modify additional arguments } else { - QString parsedSpecOrginal = parsedSpec; - if (QFileInfo(parsedSpec).isRelative()) - parsedSpec = QDir::cleanPath(directory + "/" + parsedSpec); - m_additionalArguments = Qt4Project::removeSpecFromArgumentList(m_additionalArguments); - if (parsedSpec != versionSpec) { - m_additionalArguments.prepend(parsedSpecOrginal); - m_additionalArguments.prepend("-spec"); - } + m_additionalArguments.prepend(parsedSpec); + m_additionalArguments.prepend("-spec"); } } diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 92dc312a3a..ba8b57f75d 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -62,11 +62,16 @@ QStringList QMakeStep::arguments(const QString &buildConfiguration) ProjectExplorer::BuildConfiguration *bc = m_pro->buildConfiguration(buildConfiguration); QStringList arguments; arguments << project()->file()->fileName(); - if (!additonalArguments.contains("-spec")) { + arguments << "-r"; + + if (!additonalArguments.contains("-spec")) arguments << "-spec" << m_pro->qtVersion(bc)->mkspec(); - } - arguments << "-r"; +#ifdef Q_OS_WIN + ToolChain::ToolChainType type = m_pro->toolChainType(bc); + if (type == ToolChain::GCC_MAEMO) + arguments << QLatin1String("-unix"); +#endif if (bc->value("buildConfiguration").isValid()) { QStringList configarguments; @@ -273,6 +278,9 @@ void QMakeStepConfigWidget::buildConfigurationChanged() static_cast<Qt4Project *>(m_step->project())->invalidateCachedTargetInformation(); updateTitleLabel(); updateEffectiveQMakeCall(); + // TODO if exact parsing is the default, we need to update the code model + // and all the Qt4ProFileNodes + //static_cast<Qt4Project *>(m_step->project())->update(); } QString QMakeStepConfigWidget::displayName() const diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png Binary files differnew file mode 100644 index 0000000000..dc4f5190a2 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png Binary files differnew file mode 100644 index 0000000000..53d0663d6e --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf b/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf Binary files differnew file mode 100644 index 0000000000..226dd2b30a --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp new file mode 100644 index 0000000000..2d1049ee5d --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp @@ -0,0 +1,158 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "maemomanager.h" + +#include "maemotoolchain.h" +#include "maemorunconfiguration.h" + +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/icore.h> +#include <coreplugin/modemanager.h> +#include <extensionsystem/pluginmanager.h> + +#include <QtCore/QList> +#include <QtCore/QMutexLocker> + +#include <QtGui/QAction> + +namespace Qt4ProjectManager { + namespace Internal { + + +QMutex MaemoManager::m_mutex; +MaemoManager *MaemoManager::m_instance = 0; + +const QSize iconSize = QSize(24, 20); + +MaemoManager::MaemoManager() + : QObject(0) + , m_runControlFactory(new MaemoRunControlFactory(this)) + , m_runConfigurationFactory(new MaemoRunConfigurationFactory(this)) + , m_qemuCommand(0) +{ + + icon.addFile(":/qt-maemo/images/qemu-run.png", iconSize); + icon.addFile(":/qt-maemo/images/qemu-stop.png", iconSize, QIcon::Normal, + QIcon::On); + + ExtensionSystem::PluginManager::instance()->addObject(m_runControlFactory); + ExtensionSystem::PluginManager::instance()->addObject(m_runConfigurationFactory); +} + +MaemoManager::~MaemoManager() +{ + ExtensionSystem::PluginManager::instance()->removeObject(m_runControlFactory); + ExtensionSystem::PluginManager::instance()->removeObject(m_runConfigurationFactory); +} + +MaemoManager *MaemoManager::instance() +{ + if (!m_instance) { + QMutexLocker _(&m_mutex); + if (!m_instance) + m_instance = new MaemoManager; + } + return m_instance; +} + +ProjectExplorer::ToolChain* +MaemoManager::maemoToolChain(const QtVersion *version) const +{ + return new MaemoToolChain(version); +} + +void +MaemoManager::addQemuSimulatorStarter(Project *project) +{ + projects.insert(project); + + if (m_qemuCommand) { + m_qemuCommand->action()->setVisible(true); + return; + } + + Core::ICore *core = Core::ICore::instance(); + Core::ModeManager *modeManager = core->modeManager(); + Core::ActionManager *actionManager = core->actionManager(); + + QAction *action = new QAction("Qemu", this); + action->setIcon(icon.pixmap(iconSize)); + action->setToolTip(tr("Start Qemu")); + m_qemuCommand = actionManager->registerAction(action, "qemu", + QList<int>() << Core::Constants::C_GLOBAL_ID); + modeManager->addAction(m_qemuCommand, 1); + m_qemuCommand->action()->setEnabled(true); + m_qemuCommand->setAttribute(Core::Command::CA_UpdateText); + m_qemuCommand->setAttribute(Core::Command::CA_UpdateIcon); + + connect(m_qemuCommand->action(), SIGNAL(triggered()), this, SLOT(triggered())); +} + +void +MaemoManager::removeQemuSimulatorStarter(Project *project) +{ + projects.remove(project); + if (projects.isEmpty() && m_qemuCommand) + m_qemuCommand->action()->setVisible(false); +} + +void +MaemoManager::setQemuSimulatorStarterEnabled(bool enable) +{ + if (m_qemuCommand) + m_qemuCommand->action()->setEnabled(enable); +} + +void +MaemoManager::triggered() +{ + emit startStopQemu(); +} + +void +MaemoManager::updateQemuSimulatorStarter(bool running) +{ + if (m_qemuCommand) { + QIcon::State state = QIcon::Off; + QString toolTip(tr("Start Qemu")); + if (running) { + state = QIcon::On; + toolTip = tr("Stop Qemu"); + } + + QAction *action = m_qemuCommand->action(); + action->setToolTip(toolTip); + action->setIcon(icon.pixmap(iconSize, QIcon::Normal, state)); + } +} + + } // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h new file mode 100644 index 0000000000..f76c83346a --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h @@ -0,0 +1,103 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef MAEMOMANAGER_H +#define MAEMOMANAGER_H + +#include "qtversionmanager.h" + +#include <coreplugin/actionmanager/command.h> + +#include <QtCore/QMutex> +#include <QtCore/QObject> +#include <QtCore/QSet> + +#include <QtGui/QIcon> + +QT_BEGIN_NAMESPACE +class QAction; +QT_END_NAMESPACE + +namespace ProjectExplorer { + class Project; + class ToolChain; +} +using ProjectExplorer::Project; +using ProjectExplorer::ToolChain; + +namespace Qt4ProjectManager { + class QtVersion; + namespace Internal { + +class MaemoRunControlFactory; +class MaemoRunConfigurationFactory; + +class MaemoManager : public QObject +{ + Q_OBJECT + +public: + static MaemoManager *instance(); + + void addVersion(const Qt4ProjectManager::QtVersion *version) { Q_UNUSED(version); } + ToolChain *maemoToolChain(const Qt4ProjectManager::QtVersion *version) const; + + void addQemuSimulatorStarter(Project *project); + void removeQemuSimulatorStarter(Project *project); + + void setQemuSimulatorStarterEnabled(bool state); + +public slots: + void triggered(); + void updateQemuSimulatorStarter(bool running); + +signals: + void startStopQemu(); + +private: + MaemoManager(); + ~MaemoManager(); + +private: + static QMutex m_mutex; + static MaemoManager *m_instance; + + MaemoRunControlFactory *m_runControlFactory; + MaemoRunConfigurationFactory *m_runConfigurationFactory; + + QIcon icon; + int m_runCount; + QSet<Project*> projects; + Core::Command *m_qemuCommand; +}; + + } // namespace Internal +} // namespace Qt4ProjectManager + +#endif // MAEMOMANAGER_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp new file mode 100644 index 0000000000..8dad9734be --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp @@ -0,0 +1,1608 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "maemorunconfiguration.h" + +#include "maemomanager.h" +#include "maemotoolchain.h" +#include "profilereader.h" +#include "qt4project.h" + +#include <coreplugin/icore.h> +#include <coreplugin/messagemanager.h> +#include <debugger/debuggermanager.h> +#include <extensionsystem/pluginmanager.h> +#include <utils/pathchooser.h> +#include <utils/qtcassert.h> +#include <projectexplorer/persistentsettings.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/session.h> + +#include <QtCore/QDebug> +#include <QtCore/QProcess> +#include <QtCore/QSharedPointer> + +#include <QtGui/QCheckBox> +#include <QtGui/QFormLayout> +#include <QtGui/QFrame> +#include <QtGui/QHBoxLayout> +#include <QtGui/QLabel> +#include <QtGui/QLineEdit> +#include <QtGui/QRadioButton> +#include <QtGui/QToolButton> + +using namespace ProjectExplorer; + +namespace Qt4ProjectManager { +namespace Internal { + +class MaemoRunConfigurationWidget : public QWidget +{ + Q_OBJECT +public: + MaemoRunConfigurationWidget( + MaemoRunConfiguration *runConfiguration, QWidget *parent = 0); + +private slots: + void configNameEdited(const QString &text); + void argumentsEdited(const QString &args); + void hostNameEdited(const QString &name); + void userNameEdited(const QString &name); + void portEdited(const QString &port); + void hostTypeChanged(); + +#if USE_SSL_PASSWORD + void passwordUseChanged(); + void passwordEdited(const QString &password); +#endif + + void updateTargetInformation(); + + void updateSimulatorPath(); + void updateVisibleSimulatorParameter(); + +private: + QLineEdit *m_configNameLineEdit; + QLineEdit *m_argsLineEdit; + QLineEdit *m_hostNameLineEdit; + QLineEdit *m_userLineEdit; + QLineEdit *m_passwordLineEdit; + QLineEdit *m_portLineEdit; + QLabel *m_executableLabel; + QLabel *m_debuggerLabel; + QLabel *m_simParamsValueLabel; + QLabel *m_chooseSimPathLabel; + QLabel *m_simParamsNameLabel; + QCheckBox *m_passwordCheckBox; + QRadioButton *m_hwButton; + QRadioButton *m_simButton; + QToolButton *m_resetButton; + Utils::PathChooser *m_simPathChooser; + MaemoRunConfiguration *m_runConfiguration; +}; + +class AbstractMaemoRunControl : public ProjectExplorer::RunControl +{ + Q_OBJECT + +public: + AbstractMaemoRunControl(RunConfig runConfig); + virtual ~AbstractMaemoRunControl() {} + +protected: + void startDeployment(bool forDebugging); + void stopDeployment(); + bool isDeploying() const; + const QString executableOnHost() const; + const QString executableOnTarget() const; + const QString executableFileName() const; + const QString port() const; + const QString targetCmdLinePrefix() const; + virtual void deploymentFinished(bool success)=0; + virtual bool setProcessEnvironment(QProcess &process); + +private slots: + void readStandardError(); + void readStandardOutput(); + void deployProcessFinished(); + +protected: + ErrorDumper dumper; + const QSharedPointer<MaemoRunConfiguration> runConfig; + +private: + QProcess deployProcess; + bool deployingExecutable; + bool deployingDumperLib; +}; + +class MaemoRunControl : public AbstractMaemoRunControl +{ + Q_OBJECT +public: + MaemoRunControl(RunConfig runConfiguration); + ~MaemoRunControl(); + void start(); + void stop(); + bool isRunning() const; + +private slots: + void executionFinished(); + +private: + void deploymentFinished(bool success); + void startExecution(); + + QProcess sshProcess; + QProcess stopProcess; + bool stoppedByUser; +}; + +class MaemoDebugRunControl : public AbstractMaemoRunControl +{ + Q_OBJECT +public: + MaemoDebugRunControl(RunConfig runConfiguration); + ~MaemoDebugRunControl(); + void start(); + void stop(); + bool isRunning() const; + Q_SLOT void debuggingFinished(); + +signals: + void stopRequested(); + +private slots: + void gdbServerStarted(); + void debuggerOutput(const QString &output); + +private: + void deploymentFinished(bool success); + + void startGdbServer(); + void gdbServerStartFailed(const QString &reason); + void startDebugging(); + + QProcess gdbServer; + QProcess stopProcess; + const QString gdbServerPort; + Debugger::DebuggerManager *debuggerManager; + QSharedPointer<Debugger::DebuggerStartParameters> startParams; + int inferiorPid; +}; + +void ErrorDumper::printToStream(QProcess::ProcessError error) +{ + QString reason; + switch (error) { + case QProcess::FailedToStart: + reason = "The process failed to start. Either the invoked program is" + " missing, or you may have insufficient permissions to invoke " + "the program."; + break; + + case QProcess::Crashed: + reason = "The process crashed some time after starting successfully."; + break; + + case QProcess::Timedout: + reason = "The last waitFor...() function timed out. The state of " + "QProcess is unchanged, and you can try calling waitFor...() " + "again."; + break; + + case QProcess::WriteError: + reason = "An error occurred when attempting to write to the process." + " For example, the process may not be running, or it may have " + "closed its input channel."; + break; + + case QProcess::ReadError: + reason = "An error occurred when attempting to read from the process." + " For example, the process may not be running."; + break; + + default: + reason = "QProcess::UnknownError"; + break; + } + qWarning() << "Failed to run emulator. Reason:" << reason; +} + + +// #pragma mark -- MaemoRunConfiguration + + +static const QLatin1String RemoteHostIsSimulatorKey("RemoteHostIsSimulator"); +static const QLatin1String ArgumentsKeySim("ArgumentsSim"); +static const QLatin1String RemoteHostNameKeySim("RemoteHostNameSim"); +static const QLatin1String RemoteUserNameKeySim("RemoteUserNameSim"); +static const QLatin1String RemotePortKeySim("RemotePortSim"); + +static const QLatin1String ArgumentsKeyDevice("ArgumentsDevice"); +static const QLatin1String RemoteHostNameKeyDevice("RemoteHostNameDevice"); +static const QLatin1String RemoteUserNameKeyDevice("RemoteUserNameDevice"); +static const QLatin1String RemotePortKeyDevice("RemotePortDevice"); + +static const QLatin1String LastDeployedKey("LastDeployed"); +static const QLatin1String DebuggingHelpersLastDeployedKey( + "DebuggingHelpersLastDeployed"); + +static const QLatin1String SimulatorPath("SimulatorPath"); +static const QLatin1String IsUserSetSimulator("IsUserSetSimulator"); + +#if USE_SSL_PASSWORD +static const QLatinString RemoteUserPasswordKey("RemoteUserPassword"); +static const QLatinString RemoteHostRequiresPasswordKey( + "RemoteHostRequiresPassword"); +#endif + +MaemoRunConfiguration::MaemoRunConfiguration(Project *project, + const QString &proFilePath) + : RunConfiguration(project) + , m_proFilePath(proFilePath) + , m_cachedTargetInformationValid(false) + , m_cachedSimulatorInformationValid(false) + , m_isUserSetSimulator(false) + , m_remotePortSim(22) + , m_remotePortDevice(22) + , qemu(0) +{ + if (!m_proFilePath.isEmpty()) { + setName(tr("%1 on Maemo device").arg(QFileInfo(m_proFilePath) + .completeBaseName())); + } else { + setName(tr("MaemoRunConfiguration")); + } + + connect(project, SIGNAL(targetInformationChanged()), this, + SLOT(invalidateCachedTargetInformation())); + connect(project, SIGNAL(activeBuildConfigurationChanged()), this, + SLOT(invalidateCachedTargetInformation())); + + connect(project, SIGNAL(targetInformationChanged()), this, + SLOT(invalidateCachedSimulatorInformation())); + connect(project, SIGNAL(activeBuildConfigurationChanged()), this, + SLOT(invalidateCachedSimulatorInformation())); + + qemu = new QProcess(this); + connect(qemu, SIGNAL(error(QProcess::ProcessError)), &dumper, + SLOT(printToStream(QProcess::ProcessError))); + connect(qemu, SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(qemuProcessFinished())); +} + +MaemoRunConfiguration::~MaemoRunConfiguration() +{ + if (qemu && qemu->state() != QProcess::NotRunning) { + qemu->terminate(); + qemu->kill(); + } + delete qemu; + qemu = NULL; +} + +QString MaemoRunConfiguration::type() const +{ + return QLatin1String("Qt4ProjectManager.MaemoRunConfiguration"); +} + +Qt4Project *MaemoRunConfiguration::project() const +{ + Qt4Project *pro = qobject_cast<Qt4Project *>(RunConfiguration::project()); + Q_ASSERT(pro != 0); + return pro; +} + +bool MaemoRunConfiguration::isEnabled() const +{ + Qt4Project *qt4Project = qobject_cast<Qt4Project*>(project()); + QTC_ASSERT(qt4Project, return false); + ToolChain::ToolChainType type = + qt4Project->toolChainType(qt4Project->activeBuildConfiguration()); + return type == ToolChain::GCC_MAEMO; +} + +QWidget *MaemoRunConfiguration::configurationWidget() +{ + return new MaemoRunConfigurationWidget(this); +} + +void MaemoRunConfiguration::save(PersistentSettingsWriter &writer) const +{ + writer.saveValue(RemoteHostIsSimulatorKey, m_remoteHostIsSimulator); + writer.saveValue(ArgumentsKeySim, m_argumentsSim); + writer.saveValue(RemoteHostNameKeySim, m_remoteHostNameSim); + writer.saveValue(RemoteUserNameKeySim, m_remoteUserNameSim); + writer.saveValue(RemotePortKeySim, m_remotePortSim); + + writer.saveValue(ArgumentsKeyDevice, m_argumentsDevice); + writer.saveValue(RemoteHostNameKeyDevice, m_remoteHostNameDevice); + writer.saveValue(RemoteUserNameKeyDevice, m_remoteUserNameDevice); + writer.saveValue(RemotePortKeyDevice, m_remotePortDevice); + +#if USE_SSL_PASSWORD + writer.saveValue(RemoteUserPasswordKey, m_remoteUserPassword); + writer.saveValue(RemoteHostRequiresPasswordKey, m_remoteHostRequiresPassword); +#endif + + writer.saveValue(LastDeployedKey, m_lastDeployed); + writer.saveValue(DebuggingHelpersLastDeployedKey, + m_debuggingHelpersLastDeployed); + + writer.saveValue(SimulatorPath, m_simulatorPath); + writer.saveValue(IsUserSetSimulator, m_isUserSetSimulator); + + const QDir &dir = QFileInfo(project()->file()->fileName()).absoluteDir(); + writer.saveValue("ProFile", dir.relativeFilePath(m_proFilePath)); + + RunConfiguration::save(writer); +} + +void MaemoRunConfiguration::restore(const PersistentSettingsReader &reader) +{ + RunConfiguration::restore(reader); + + m_remoteHostIsSimulator = reader.restoreValue(RemoteHostIsSimulatorKey) + .toBool(); + m_argumentsSim = reader.restoreValue(ArgumentsKeySim).toStringList(); + m_remoteHostNameSim = reader.restoreValue(RemoteHostNameKeySim).toString(); + m_remoteUserNameSim = reader.restoreValue(RemoteUserNameKeySim).toString(); + m_remotePortSim = reader.restoreValue(RemotePortKeySim).toInt(); + + m_argumentsDevice = reader.restoreValue(ArgumentsKeyDevice).toStringList(); + m_remoteHostNameDevice = reader.restoreValue(RemoteHostNameKeyDevice) + .toString(); + m_remoteUserNameDevice = reader.restoreValue(RemoteUserNameKeyDevice) + .toString(); + m_remotePortDevice = reader.restoreValue(RemotePortKeyDevice).toInt(); + +#if USE_SSL_PASSWORD + m_remoteUserPassword = reader.restoreValue(RemoteUserPasswordKey).toString(); + m_remoteHostRequiresPassword = + reader.restoreValue(RemoteHostRequiresPasswordKey).toBool(); +#endif + + m_lastDeployed = reader.restoreValue(LastDeployedKey).toDateTime(); + m_debuggingHelpersLastDeployed = + reader.restoreValue(DebuggingHelpersLastDeployedKey).toDateTime(); + + m_simulatorPath = reader.restoreValue(SimulatorPath).toString(); + m_isUserSetSimulator = reader.restoreValue(IsUserSetSimulator).toBool(); + + const QDir &dir = QFileInfo(project()->file()->fileName()).absoluteDir(); + m_proFilePath = dir.filePath(reader.restoreValue("ProFile").toString()); +} + +bool MaemoRunConfiguration::currentlyNeedsDeployment() const +{ + return fileNeedsDeployment(executable(), m_lastDeployed); +} + +void MaemoRunConfiguration::wasDeployed() +{ + m_lastDeployed = QDateTime::currentDateTime(); +} + +bool MaemoRunConfiguration::hasDebuggingHelpers() const +{ + return project()->qtVersion(project()->activeBuildConfiguration()) + ->hasDebuggingHelper(); +} + +bool MaemoRunConfiguration::debuggingHelpersNeedDeployment() const +{ + if (hasDebuggingHelpers()) + return fileNeedsDeployment(dumperLib(), m_debuggingHelpersLastDeployed); + return false; +} + +void MaemoRunConfiguration::debuggingHelpersDeployed() +{ + m_debuggingHelpersLastDeployed = QDateTime::currentDateTime(); +} + +bool MaemoRunConfiguration::fileNeedsDeployment(const QString &path, + const QDateTime &lastDeployed) const +{ + return !lastDeployed.isValid() + || QFileInfo(path).lastModified() > lastDeployed; +} + +const QString MaemoRunConfiguration::remoteHostName() const +{ + return m_remoteHostIsSimulator ? m_remoteHostNameSim + : m_remoteHostNameDevice; +} + +const QString MaemoRunConfiguration::remoteUserName() const +{ + return m_remoteHostIsSimulator ? m_remoteUserNameSim + : m_remoteUserNameDevice; +} + +int MaemoRunConfiguration::remotePort() const +{ + int port = m_remoteHostIsSimulator ? m_remotePortSim : m_remotePortDevice; + return port > 0 ? port : 22; +} + +const QString MaemoRunConfiguration::remoteDir() const +{ + return remoteUserName() == QString::fromLocal8Bit("root") + ? QString::fromLocal8Bit("/root") + : QString::fromLocal8Bit("/home/") + remoteUserName(); +} + +const QString MaemoRunConfiguration::sshCmd() const +{ + return cmd(QString::fromLocal8Bit("ssh")); +} + +const QString MaemoRunConfiguration::scpCmd() const +{ + return cmd(QString::fromLocal8Bit("scp")); +} + +const QString MaemoRunConfiguration::cmd(const QString &cmdName) const +{ + QString command(cmdName); +#ifdef Q_OS_WIN + command = maddeRoot() + QLatin1String("/bin/") + command + + QLatin1String(".exe"); +#endif + return command; +} + +const MaemoToolChain *MaemoRunConfiguration::toolchain() const +{ + Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project()); + QTC_ASSERT(qt4Project != 0, return 0); + MaemoToolChain *tc = dynamic_cast<MaemoToolChain *>( + qt4Project->toolChain(qt4Project->activeBuildConfiguration()) ); + QTC_ASSERT(tc != 0, return 0); + return tc; +} + +const QString MaemoRunConfiguration::gdbCmd() const +{ + return toolchain() != 0 + ? toolchain()->targetRoot() + "/bin/gdb" + : QString(); +} + +QString MaemoRunConfiguration::maddeRoot() const +{ + return toolchain() != 0 ? toolchain()->maddeRoot() : QString(); +} + +const QString MaemoRunConfiguration::sysRoot() const +{ + return toolchain() != 0 ? toolchain()->sysrootRoot() : QString(); +} + +const QStringList MaemoRunConfiguration::arguments() const +{ + return m_remoteHostIsSimulator ? m_argumentsSim : m_argumentsDevice; +} + +const QString MaemoRunConfiguration::dumperLib() const +{ + return project()->qtVersion(project()->activeBuildConfiguration())-> + debuggingHelperLibrary(); +} + +QString MaemoRunConfiguration::executable() const +{ + const_cast<MaemoRunConfiguration*> (this)->updateTarget(); + return m_executable; +} + +QString MaemoRunConfiguration::simulatorPath() const +{ + qDebug("MaemoRunConfiguration::simulatorPath() called, %s", + qPrintable(m_simulatorPath)); + + const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation(); + return m_simulatorPath; +} + +QString MaemoRunConfiguration::visibleSimulatorParameter() const +{ + qDebug("MaemoRunConfiguration::visibleSimulatorParameter() called"); + + const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation(); + return m_visibleSimulatorParameter; +} + +QString MaemoRunConfiguration::simulator() const +{ + const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation(); + return m_simulator; +} + +QString MaemoRunConfiguration::simulatorArgs() const +{ + const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation(); + return m_simulatorArgs; +} + +void MaemoRunConfiguration::setArguments(const QStringList &args) +{ + if (m_remoteHostIsSimulator) + m_argumentsSim = args; + else + m_argumentsDevice = args; +} + +void MaemoRunConfiguration::setRemoteHostIsSimulator(bool isSimulator) +{ + m_remoteHostIsSimulator = isSimulator; +} + +void MaemoRunConfiguration::setRemoteHostName(const QString &hostName) +{ + m_lastDeployed = QDateTime(); + m_debuggingHelpersLastDeployed = QDateTime(); + + if (m_remoteHostIsSimulator) + m_remoteHostNameSim = hostName; + else + m_remoteHostNameDevice = hostName; +} + +void MaemoRunConfiguration::setRemoteUserName(const QString &userName) +{ + m_lastDeployed = QDateTime(); + m_debuggingHelpersLastDeployed = QDateTime(); + + if (m_remoteHostIsSimulator) + m_remoteUserNameSim = userName; + else + m_remoteUserNameDevice = userName; +} + +void MaemoRunConfiguration::setRemotePort(int port) +{ + m_lastDeployed = QDateTime(); + m_debuggingHelpersLastDeployed = QDateTime(); + + if (m_remoteHostIsSimulator) + m_remotePortSim = port; + else + m_remotePortDevice = port; +} + +#if USE_SSL_PASSWORD +void MaemoRunConfiguration::setRemotePassword(const QString &password) +{ + Q_ASSERT(remoteHostRequiresPassword()); + m_remoteUserPassword = password; +} + +void MaemoRunConfiguration::setRemoteHostRequiresPassword(bool requiresPassword) +{ + m_remoteHostRequiresPassword = requiresPassword; +} +#endif + +bool MaemoRunConfiguration::isQemuRunning() const +{ + return (qemu && qemu->state() != QProcess::NotRunning); +} + +void MaemoRunConfiguration::invalidateCachedTargetInformation() +{ + m_cachedTargetInformationValid = false; + emit targetInformationChanged(); +} + +void MaemoRunConfiguration::setUserSimulatorPath(const QString &path) +{ + qDebug("MaemoRunConfiguration::setUserSimulatorPath() called, " + "m_simulatorPath: %s, new path: %s", qPrintable(m_simulatorPath), + qPrintable(path)); + + m_isUserSetSimulator = true; + if (m_userSimulatorPath != path) + m_cachedSimulatorInformationValid = false; + + m_userSimulatorPath = path; + emit cachedSimulatorInformationChanged(); +} + +void MaemoRunConfiguration::invalidateCachedSimulatorInformation() +{ + qDebug("MaemoRunConfiguration::invalidateCachedSimulatorInformation() " + "called"); + + m_cachedSimulatorInformationValid = false; + emit cachedSimulatorInformationChanged(); +} + +void MaemoRunConfiguration::resetCachedSimulatorInformation() +{ + m_userSimulatorPath.clear(); + m_isUserSetSimulator = false; + + m_cachedSimulatorInformationValid = false; + emit cachedSimulatorInformationChanged(); +} + +void MaemoRunConfiguration::updateTarget() +{ + if (m_cachedTargetInformationValid) + return; + + m_executable = QString::null; + m_cachedTargetInformationValid = true; + + if (Qt4Project *qt4Project = static_cast<Qt4Project *>(project())) { + Qt4PriFileNode * priFileNode = qt4Project->rootProjectNode() + ->findProFileFor(m_proFilePath); + if (!priFileNode) { + emit targetInformationChanged(); + return; + } + + QtVersion *qtVersion = + qt4Project->qtVersion(qt4Project->activeBuildConfiguration()); + ProFileReader *reader = priFileNode->createProFileReader(); + reader->setCumulative(false); + reader->setQtVersion(qtVersion); + + // Find out what flags we pass on to qmake, this code is duplicated in + // the qmake step + QtVersion::QmakeBuildConfig defaultBuildConfiguration = + qtVersion->defaultBuildConfig(); + QtVersion::QmakeBuildConfig projectBuildConfiguration = + QtVersion::QmakeBuildConfig(qt4Project->activeBuildConfiguration() + ->value("buildConfiguration").toInt()); + + QStringList addedUserConfigArguments; + QStringList removedUserConfigArguments; + if ((defaultBuildConfiguration & QtVersion::BuildAll) + && !(projectBuildConfiguration & QtVersion::BuildAll)) + removedUserConfigArguments << "debug_and_release"; + + if (!(defaultBuildConfiguration & QtVersion::BuildAll) + && (projectBuildConfiguration & QtVersion::BuildAll)) + addedUserConfigArguments << "debug_and_release"; + + if ((defaultBuildConfiguration & QtVersion::DebugBuild) + && !(projectBuildConfiguration & QtVersion::DebugBuild)) + addedUserConfigArguments << "release"; + + if (!(defaultBuildConfiguration & QtVersion::DebugBuild) + && (projectBuildConfiguration & QtVersion::DebugBuild)) + addedUserConfigArguments << "debug"; + + reader->setUserConfigCmdArgs(addedUserConfigArguments, + removedUserConfigArguments); + + if (!reader->readProFile(m_proFilePath)) { + delete reader; + Core::ICore::instance()->messageManager()->printToOutputPane(tr( + "Could not parse %1. The Maemo run configuration %2 " + "can not be started.").arg(m_proFilePath).arg(name())); + emit targetInformationChanged(); + return; + } + + // Extract data + QDir baseProjectDirectory = + QFileInfo(project()->file()->fileName()).absoluteDir(); + QString relSubDir = + baseProjectDirectory.relativeFilePath(QFileInfo(m_proFilePath).path()); + QDir baseBuildDirectory = + project()->buildDirectory(project()->activeBuildConfiguration()); + QString baseDir = baseBuildDirectory.absoluteFilePath(relSubDir); + + if (!reader->contains("DESTDIR")) { +#if 0 // TODO: fix this, seems to be wrong on windows + if (reader->values("CONFIG").contains("debug_and_release_target")) { + QString qmakeBuildConfig = "release"; + if (projectBuildConfiguration & QtVersion::DebugBuild) + qmakeBuildConfig = "debug"; + baseDir += QLatin1Char('/') + qmakeBuildConfig; + } +#endif + } else { + const QString &destDir = reader->value("DESTDIR"); + if (QDir::isRelativePath(destDir)) + baseDir += QLatin1Char('/') + destDir; + else + baseDir = destDir; + } + + QString target = reader->value("TARGET"); + if (target.isEmpty()) + target = QFileInfo(m_proFilePath).baseName(); + + m_executable = QDir::cleanPath(baseDir + QLatin1Char('/') + target); + delete reader; + } + + emit targetInformationChanged(); +} + +void MaemoRunConfiguration::updateSimulatorInformation() +{ + if (m_cachedSimulatorInformationValid) + return; + + m_simulator = QString::null; + m_simulatorArgs == QString::null; + m_cachedSimulatorInformationValid = true; + m_simulatorPath = QDir::toNativeSeparators(m_userSimulatorPath); + m_visibleSimulatorParameter = tr("Could not autodetect target simulator, " + "please choose one on your own."); + + if (!m_isUserSetSimulator) + m_simulatorPath = QDir::toNativeSeparators(toolchain()->simulatorRoot()); + + if (!m_simulatorPath.isEmpty()) { + m_visibleSimulatorParameter = tr("'%1' is not a valid Maemo simulator.") + .arg(m_simulatorPath); + } + + QDir dir(m_simulatorPath); + if (dir.exists(m_simulatorPath)) { + const QStringList &files = dir.entryList(QDir::Files | QDir::NoSymLinks + | QDir::NoDotAndDotDot); + if (files.count() >= 2) { + const QLatin1String info("information"); + if (files.contains(info)) { + QFile file(m_simulatorPath + QLatin1Char('/') + info); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMap<QString, QString> map; + QTextStream stream(&file); + while (!stream.atEnd()) { + const QString &line = stream.readLine().trimmed(); + const int index = line.indexOf(QLatin1Char('=')); + map.insert(line.mid(0, index).remove(QLatin1Char('\'')), + line.mid(index + 1).remove(QLatin1Char('\''))); + } + + m_simulator = map.value(QLatin1String("runcommand")); + m_simulatorArgs = map.value(QLatin1String("runcommand_args")); + + m_visibleSimulatorParameter = m_simulator +#ifdef Q_OS_WIN + + QLatin1String(".exe") +#endif + + QLatin1Char(' ') + m_simulatorArgs; + } + } + } + } else { + m_visibleSimulatorParameter = tr("'%1' could not be found. Please " + "choose a simulator on your own.").arg(m_simulatorPath); + } + + emit cachedSimulatorInformationChanged(); +} + +void MaemoRunConfiguration::startStopQemu() +{ + if (qemu->state() != QProcess::NotRunning) { + if (qemu->state() == QProcess::Running) { + qemu->terminate(); + qemu->kill(); + emit qemuProcessStatus(false); + } + return; + } + + QString root = maddeRoot(); + if (root.isEmpty() || simulator().isEmpty()) + return; + + const QLatin1Char colon(';'); + const QString path = QDir::toNativeSeparators(root + QLatin1Char('/')); + + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("PATH", env.value("Path") + colon + path + QLatin1String("bin")); + env.insert("PATH", env.value("Path") + colon + path + QLatin1String("madlib")); + + qemu->setProcessEnvironment(env); + qemu->setWorkingDirectory(simulatorPath()); + + QString app = root + QLatin1String("/madlib/") + simulator() +#ifdef Q_OS_WIN + + QLatin1String(".exe") +#endif + ; // keep + + qemu->start(app + QLatin1Char(' ') + simulatorArgs(), QIODevice::ReadWrite); + emit qemuProcessStatus(qemu->waitForStarted()); +} + +void MaemoRunConfiguration::qemuProcessFinished() +{ + emit qemuProcessStatus(false); +} + +void MaemoRunConfiguration::enabledStateChanged() +{ + MaemoManager::instance()->setQemuSimulatorStarterEnabled(isEnabled()); +} + + +// #pragma mark -- MaemoRunConfigurationWidget + + +MaemoRunConfigurationWidget::MaemoRunConfigurationWidget( + MaemoRunConfiguration *runConfiguration, QWidget *parent) + : QWidget(parent) + , m_runConfiguration(runConfiguration) +{ + QFormLayout *mainLayout = new QFormLayout; + setLayout(mainLayout); + mainLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_configNameLineEdit = new QLineEdit(m_runConfiguration->name()); + mainLayout->addRow(tr("Run configuration name:"), m_configNameLineEdit); + m_executableLabel = new QLabel(m_runConfiguration->executable()); + mainLayout->addRow(tr("Executable:"), m_executableLabel); + m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" ")); + mainLayout->addRow(tr("Arguments:"), m_argsLineEdit); + m_debuggerLabel = new QLabel(m_runConfiguration->gdbCmd()); + mainLayout->addRow(tr("Debugger:"), m_debuggerLabel); + mainLayout->addItem(new QSpacerItem(10, 10)); + + QHBoxLayout *hostTypeLayout = new QHBoxLayout; + m_hwButton = new QRadioButton(tr("Physical device")); + hostTypeLayout->addWidget(m_hwButton); + m_simButton = new QRadioButton(tr("Simulator")); + hostTypeLayout->addWidget(m_simButton); + hostTypeLayout->addStretch(1); + mainLayout->addRow(tr("Remote host type:"), hostTypeLayout); + + m_chooseSimPathLabel = new QLabel(tr("Choose simulator:")); + m_simPathChooser = new Utils::PathChooser; + m_simPathChooser->setPath(m_runConfiguration->simulatorPath()); + + QHBoxLayout *pathLayout = new QHBoxLayout; + pathLayout->addWidget(m_simPathChooser); + + m_resetButton = new QToolButton(); + m_resetButton->setToolTip(tr("Reset to default")); + m_resetButton->setIcon(QIcon(":/core/images/reset.png")); + pathLayout->addWidget(m_resetButton); + + mainLayout->addRow(m_chooseSimPathLabel, pathLayout); + m_simParamsNameLabel = new QLabel(tr("Simulator command line:")); + m_simParamsValueLabel= new QLabel(m_runConfiguration->visibleSimulatorParameter()); + mainLayout->addRow(m_simParamsNameLabel, m_simParamsValueLabel); + + connect(m_simPathChooser, SIGNAL(changed(QString)), m_runConfiguration, + SLOT(setUserSimulatorPath(QString))); + connect(m_runConfiguration, SIGNAL(cachedSimulatorInformationChanged()), + this, SLOT(updateSimulatorPath())); + connect(m_runConfiguration, SIGNAL(cachedSimulatorInformationChanged()), + this, SLOT(updateVisibleSimulatorParameter())); + connect(m_resetButton, SIGNAL(clicked()), m_runConfiguration, + SLOT(resetCachedSimulatorInformation())); + + m_hostNameLineEdit = new QLineEdit(m_runConfiguration->remoteHostName()); + mainLayout->addRow(tr("Remote host name:"), m_hostNameLineEdit); + m_userLineEdit = new QLineEdit(m_runConfiguration->remoteUserName()); + mainLayout->addRow(tr("Remote user name:"), m_userLineEdit); + m_portLineEdit = new QLineEdit(QString::number(m_runConfiguration->remotePort())); + mainLayout->addRow(tr("Remote SSH port:"), m_portLineEdit); + + // Unlikely to ever work: ssh uses /dev/tty directly instead of stdin/out +#if USE_SSL_PASSWORD + m_passwordCheckBox = new QCheckBox(tr("Remote password:")); + m_passwordCheckBox->setToolTip(tr("Uncheck for passwordless login")); + m_passwordCheckBox->setChecked(m_runConfiguration + ->remoteHostRequiresPassword()); + m_passwordLineEdit = new QLineEdit(m_runConfiguration->remoteUserPassword()); + m_passwordLineEdit->setEchoMode(QLineEdit::Password); + m_passwordLineEdit->setEnabled(m_passwordCheckBox->isChecked()); + mainLayout->addRow(m_passwordCheckBox, m_passwordLineEdit); + + connect(m_passwordCheckBox, SIGNAL(stateChanged(int)), this, + SLOT(passwordUseChanged())); + connect(m_passwordLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(passwordEdited(QString))); +#endif + + connect(m_configNameLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(configNameEdited(QString))); + connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(argumentsEdited(QString))); + connect(m_runConfiguration, SIGNAL(targetInformationChanged()), this, + SLOT(updateTargetInformation())); + connect(m_hwButton, SIGNAL(toggled(bool)), this, SLOT(hostTypeChanged())); + connect(m_simButton, SIGNAL(toggled(bool)), this, SLOT(hostTypeChanged())); + connect(m_hostNameLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(hostNameEdited(QString))); + connect(m_userLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(userNameEdited(QString))); + connect(m_portLineEdit, SIGNAL(textEdited(QString)), this, + SLOT(portEdited(QString))); + if (m_runConfiguration->remoteHostIsSimulator()) + m_simButton->setChecked(true); + else + m_hwButton->setChecked(true); +} + +void MaemoRunConfigurationWidget::configNameEdited(const QString &text) +{ + m_runConfiguration->setName(text); +} + +void MaemoRunConfigurationWidget::argumentsEdited(const QString &text) +{ + m_runConfiguration->setArguments(text.split(' ', QString::SkipEmptyParts)); +} + +void MaemoRunConfigurationWidget::updateTargetInformation() +{ + m_executableLabel->setText(m_runConfiguration->executable()); +} + +void MaemoRunConfigurationWidget::updateSimulatorPath() +{ + m_simPathChooser->setPath(m_runConfiguration->simulatorPath()); +} + +void MaemoRunConfigurationWidget::updateVisibleSimulatorParameter() +{ + m_simParamsValueLabel->setText(m_runConfiguration->visibleSimulatorParameter()); +} + +void MaemoRunConfigurationWidget::hostTypeChanged() +{ + const bool isSimulator = m_simButton->isChecked(); + + m_chooseSimPathLabel->setVisible(isSimulator); + m_simPathChooser->setVisible(isSimulator); + m_simParamsNameLabel->setVisible(isSimulator); + m_simParamsValueLabel->setVisible(isSimulator); + m_resetButton->setVisible(isSimulator); + + m_runConfiguration->setRemoteHostIsSimulator(isSimulator); + m_argsLineEdit->setText(m_runConfiguration->arguments().join(" ")); + m_hostNameLineEdit->setText(m_runConfiguration->remoteHostName()); + m_userLineEdit->setText(m_runConfiguration->remoteUserName()); + m_portLineEdit->setText(QString::number(m_runConfiguration->remotePort())); +} + +void MaemoRunConfigurationWidget::hostNameEdited(const QString &hostName) +{ + m_runConfiguration->setRemoteHostName(hostName); +} + +void MaemoRunConfigurationWidget::userNameEdited(const QString &userName) +{ + m_runConfiguration->setRemoteUserName(userName); +} + +#if USE_SSL_PASSWORD +void MaemoRunConfigurationWidget::passwordUseChanged() +{ + const bool usePassword = m_passwordCheckBox->checkState() == Qt::Checked; + m_passwordLineEdit->setEnabled(usePassword); + m_runConfiguration->setRemoteHostRequiresPassword(usePassword); +} + +void MaemoRunConfigurationWidget::passwordEdited(const QString &password) +{ + m_runConfiguration->setRemotePassword(password); +} +#endif + +void MaemoRunConfigurationWidget::portEdited(const QString &portString) +{ + bool isValidString; + int port = portString.toInt(&isValidString); + if (isValidString) + m_runConfiguration->setRemotePort(port); + else + m_portLineEdit->setText(QString::number(m_runConfiguration->remotePort())); +} + + +// #pragma mark -- MaemoRunConfigurationFactory + + +MaemoRunConfigurationFactory::MaemoRunConfigurationFactory(QObject* parent) + : IRunConfigurationFactory(parent) +{ +} + +MaemoRunConfigurationFactory::~MaemoRunConfigurationFactory() +{ +} + +bool MaemoRunConfigurationFactory::canRestore(const QString &type) const +{ + return type == "Qt4ProjectManager.MaemoRunConfiguration"; +} + +QStringList MaemoRunConfigurationFactory::availableCreationTypes( + Project *pro) const +{ + Qt4Project *qt4project = qobject_cast<Qt4Project *>(pro); + if (qt4project) { + QStringList applicationProFiles; + QList<Qt4ProFileNode *> list = qt4project->applicationProFiles(); + foreach (Qt4ProFileNode * node, list) { + applicationProFiles.append("MaemoRunConfiguration." + node->path()); + } + return applicationProFiles; + } + return QStringList(); +} + +QString MaemoRunConfigurationFactory::displayNameForType( + const QString &type) const +{ + const int size = QString::fromLocal8Bit("MaemoRunConfiguration.").size(); + return tr("%1 on Maemo Device").arg(QFileInfo(type.mid(size)) + .completeBaseName()); +} + +RunConfig MaemoRunConfigurationFactory::create(Project *project, + const QString &type) +{ + Qt4Project *qt4project = qobject_cast<Qt4Project *>(project); + Q_ASSERT(qt4project); + + connect(project, SIGNAL(addedRunConfiguration(ProjectExplorer::Project*, + QString)), this, SLOT(addedRunConfiguration(ProjectExplorer::Project*))); + connect(project, SIGNAL(removedRunConfiguration(ProjectExplorer::Project*, + QString)), this, SLOT(removedRunConfiguration(ProjectExplorer::Project*))); + + RunConfig rc; + const QLatin1String prefix("MaemoRunConfiguration."); + if (type.startsWith(prefix)) { + rc = RunConfig(new MaemoRunConfiguration(qt4project, + type.mid(QString(prefix).size()))); + } else { + Q_ASSERT(type == "Qt4ProjectManager.MaemoRunConfiguration"); + rc = RunConfig(new MaemoRunConfiguration(qt4project, + QString::null)); + } + + if (rc.data()) { + connect(project, SIGNAL(runConfigurationsEnabledStateChanged()), + rc.data(), SLOT(enabledStateChanged())); + connect(MaemoManager::instance(), SIGNAL(startStopQemu()), rc.data(), + SLOT(startStopQemu())); + connect(rc.data(), SIGNAL(qemuProcessStatus(bool)), + MaemoManager::instance(), SLOT(updateQemuSimulatorStarter(bool))); + } + + ProjectExplorerPlugin *explorer = ProjectExplorerPlugin::instance(); + connect(explorer->session(), SIGNAL(projectAdded(ProjectExplorer::Project*)), + this, SLOT(projectAdded(ProjectExplorer::Project*))); + connect(explorer->session(), SIGNAL(projectRemoved(ProjectExplorer::Project*)), + this, SLOT(projectRemoved(ProjectExplorer::Project*))); + connect(explorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), + this, SLOT(currentProjectChanged(ProjectExplorer::Project*))); + + return rc; +} + +bool hasMaemoRunConfig(ProjectExplorer::Project* project) +{ + if (Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project)) { + QList<RunConfig> list = qt4Project->runConfigurations(); + foreach (const RunConfig &rc, list) { + if (!rc.dynamicCast<MaemoRunConfiguration>().isNull()) + return true; + } + } + return false; +} + +void MaemoRunConfigurationFactory::addedRunConfiguration( + ProjectExplorer::Project* project) +{ + if (hasMaemoRunConfig(project)) + MaemoManager::instance()->addQemuSimulatorStarter(project); +} + +void MaemoRunConfigurationFactory::removedRunConfiguration( + ProjectExplorer::Project* project) +{ + if (!hasMaemoRunConfig(project)) + MaemoManager::instance()->removeQemuSimulatorStarter(project); +} + +void MaemoRunConfigurationFactory::projectAdded( + ProjectExplorer::Project* project) +{ + if (hasMaemoRunConfig(project)) + MaemoManager::instance()->addQemuSimulatorStarter(project); +} + +void MaemoRunConfigurationFactory::projectRemoved( + ProjectExplorer::Project* project) +{ + if (hasMaemoRunConfig(project)) + MaemoManager::instance()->removeQemuSimulatorStarter(project); +} + +void MaemoRunConfigurationFactory::currentProjectChanged( + ProjectExplorer::Project* project) +{ + bool hasRunConfig = hasMaemoRunConfig(project); + MaemoManager::instance()->setQemuSimulatorStarterEnabled(hasRunConfig); + + bool isRunning = false; + if (Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project)) { + const RunConfig &rc = qt4Project->activeRunConfiguration(); + if (!rc.dynamicCast<MaemoRunConfiguration>().isNull()) + isRunning = rc.dynamicCast<MaemoRunConfiguration>()->isQemuRunning(); + } + MaemoManager::instance()->updateQemuSimulatorStarter(isRunning); +} + + +// #pragma mark -- MaemoRunControlFactory + + +MaemoRunControlFactory::MaemoRunControlFactory(QObject *parent) + : IRunControlFactory(parent) +{ +} + +bool MaemoRunControlFactory::canRun(const RunConfig &runConfiguration, + const QString &mode) const +{ + return !runConfiguration.dynamicCast<MaemoRunConfiguration>().isNull() + && (mode == ProjectExplorer::Constants::RUNMODE + || mode == ProjectExplorer::Constants::DEBUGMODE); +} + +RunControl* MaemoRunControlFactory::create(const RunConfig &runConfig, + const QString &mode) +{ + QSharedPointer<MaemoRunConfiguration> rc = runConfig + .dynamicCast<MaemoRunConfiguration>(); + Q_ASSERT(!rc.isNull()); + Q_ASSERT(mode == ProjectExplorer::Constants::RUNMODE + || mode == ProjectExplorer::Constants::DEBUGMODE); + if (mode == ProjectExplorer::Constants::RUNMODE) + return new MaemoRunControl(rc); + return new MaemoDebugRunControl(rc); +} + +QString MaemoRunControlFactory::displayName() const +{ + return tr("Run on device"); +} + +QWidget* MaemoRunControlFactory::configurationWidget(const RunConfig &config) +{ + Q_UNUSED(config) + return 0; +} + + +// #pragma mark -- AbstractMaemoRunControl + + +AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfig rc) + : RunControl(rc) + , runConfig(rc.objectCast<MaemoRunConfiguration>()) +{ + setProcessEnvironment(deployProcess); + + connect(&deployProcess, SIGNAL(readyReadStandardError()), this, + SLOT(readStandardError())); + connect(&deployProcess, SIGNAL(readyReadStandardOutput()), this, + SLOT(readStandardOutput())); + connect(&deployProcess, SIGNAL(error(QProcess::ProcessError)), &dumper, + SLOT(printToStream(QProcess::ProcessError))); + connect(&deployProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(deployProcessFinished())); +} + +void AbstractMaemoRunControl::startDeployment(bool forDebugging) +{ + QTC_ASSERT(!runConfig.isNull(), return); + QStringList deployables; + if (runConfig->currentlyNeedsDeployment()) { + deployingExecutable = true; + deployables << executableFileName(); + } else { + deployingExecutable = false; + } + if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) { + deployables << runConfig->dumperLib(); + deployingDumperLib = true; + } else { + deployingDumperLib = false; + } + if (!deployables.isEmpty()) { + emit addToOutputWindow(this, tr("Files to deploy: %1.") + .arg(deployables.join(" "))); + QStringList cmdArgs; + cmdArgs << "-P" << port() << deployables << (runConfig->remoteUserName() + + "@" + runConfig->remoteHostName() + ":" + runConfig->remoteDir()); + deployProcess.setWorkingDirectory(QFileInfo(executableOnHost()).absolutePath()); + deployProcess.start(runConfig->scpCmd(), cmdArgs); + if (!deployProcess.waitForStarted()) { + emit error(this, tr("Could not start scp. Deployment failed.")); + deployProcess.kill(); + } else { + emit started(); + } + } else { + deploymentFinished(true); + } +} + +void AbstractMaemoRunControl::stopDeployment() +{ + deployProcess.kill(); +} + +bool AbstractMaemoRunControl::isDeploying() const +{ + return deployProcess.state() != QProcess::NotRunning; +} + +void AbstractMaemoRunControl::deployProcessFinished() +{ + bool success; + if (deployProcess.exitCode() == 0) { + emit addToOutputWindow(this, tr("Target deployed.")); + success = true; + if (deployingExecutable) + runConfig->wasDeployed(); + if (deployingDumperLib) + runConfig->debuggingHelpersDeployed(); + } else { + emit error(this, tr("Deployment failed.")); + success = false; + } + deploymentFinished(success); +} + +const QString AbstractMaemoRunControl::executableOnHost() const +{ + return runConfig->executable(); +} + +const QString AbstractMaemoRunControl::port() const +{ + return QString::number(runConfig->remotePort()); +} + +const QString AbstractMaemoRunControl::executableFileName() const +{ + return QFileInfo(executableOnHost()).fileName(); +} + +const QString AbstractMaemoRunControl::executableOnTarget() const +{ + return QString::fromLocal8Bit("%1/%2").arg(runConfig->remoteDir()). + arg(executableFileName()); +} + +const QString AbstractMaemoRunControl::targetCmdLinePrefix() const +{ + return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; "). + arg(executableOnTarget()); +} + +bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process) +{ + QTC_ASSERT(!runConfig.isNull(), return false); + Qt4Project *qt4Project = qobject_cast<Qt4Project *>(runConfig->project()); + QTC_ASSERT(runConfig, return false); + Environment env = Environment::systemEnvironment(); + qt4Project->toolChain(qt4Project->activeBuildConfiguration()) + ->addToEnvironment(env); + process.setEnvironment(env.toStringList()); + + return true; +} + +void AbstractMaemoRunControl::readStandardError() +{ + QProcess *process = static_cast<QProcess *>(sender()); + const QByteArray &data = process->readAllStandardError(); + emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(), + data.length())); +} + +void AbstractMaemoRunControl::readStandardOutput() +{ + QProcess *process = static_cast<QProcess *>(sender()); + const QByteArray &data = process->readAllStandardOutput(); + emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(), + data.length())); +} + + +// #pragma mark -- MaemoRunControl + + +MaemoRunControl::MaemoRunControl(RunConfig runConfiguration) + : AbstractMaemoRunControl(runConfiguration) +{ + setProcessEnvironment(sshProcess); + setProcessEnvironment(stopProcess); + + connect(&sshProcess, SIGNAL(readyReadStandardError()), this, + SLOT(readStandardError())); + connect(&sshProcess, SIGNAL(readyReadStandardOutput()), this, + SLOT(readStandardOutput())); + connect(&sshProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(executionFinished())); + connect(&sshProcess, SIGNAL(error(QProcess::ProcessError)), &dumper, + SLOT(printToStream(QProcess::ProcessError))); +} + +MaemoRunControl::~MaemoRunControl() +{ + stop(); + stopProcess.waitForFinished(5000); +} + +void MaemoRunControl::start() +{ + stoppedByUser = false; + startDeployment(false); +} + +void MaemoRunControl::deploymentFinished(bool success) +{ + if (success) + startExecution(); + else + emit finished(); +} + +void MaemoRunControl::startExecution() +{ + const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3") + .arg(targetCmdLinePrefix()).arg(executableOnTarget()) + .arg(runConfig->arguments().join(" ")); + + QStringList cmdArgs; + cmdArgs << "-n" << "-p" << port() << "-l" << runConfig->remoteUserName() + << runConfig->remoteHostName() << remoteCall; + sshProcess.start(runConfig->sshCmd(), cmdArgs); + + sshProcess.start(runConfig->sshCmd(), cmdArgs); + emit addToOutputWindow(this, tr("Starting remote application.")); + if (sshProcess.waitForStarted()) { + emit started(); + } else { + emit error(this, tr("Could not start ssh!")); + sshProcess.kill(); + } +} + +void MaemoRunControl::executionFinished() +{ + if (stoppedByUser) + emit addToOutputWindow(this, tr("Remote process stopped by user.")); + else if (sshProcess.exitCode() != 0) + emit addToOutputWindow(this, tr("Remote process exited with error.")); + else + emit addToOutputWindow(this, tr("Remote process finished successfully.")); + emit finished(); +} + +void MaemoRunControl::stop() +{ + stoppedByUser = true; + if (isDeploying()) { + stopDeployment(); + } else { + stopProcess.kill(); + QStringList cmdArgs; + const QString remoteCall = QString::fromLocal8Bit("pkill -f %1; " + "sleep 1; pkill -9 -f %1").arg(executableFileName()); + cmdArgs << "-n" << "-p" << port() << "-l" << runConfig->remoteUserName() + << runConfig->remoteHostName() << remoteCall; + stopProcess.start(runConfig->sshCmd(), cmdArgs); + } +} + +bool MaemoRunControl::isRunning() const +{ + return isDeploying() || sshProcess.state() != QProcess::NotRunning; +} + + +// #pragma mark -- MaemoDebugRunControl + + +MaemoDebugRunControl::MaemoDebugRunControl(RunConfig runConfiguration) + : AbstractMaemoRunControl(runConfiguration) + , gdbServerPort("10000"), debuggerManager(0) + , startParams(new Debugger::DebuggerStartParameters) +{ + setProcessEnvironment(gdbServer); + setProcessEnvironment(stopProcess); + + qDebug("Maemo Debug run controls started"); + debuggerManager = ExtensionSystem::PluginManager::instance() + ->getObject<Debugger::DebuggerManager>(); + + QTC_ASSERT(debuggerManager != 0, return); + startParams->startMode = Debugger::StartRemote; + startParams->executable = executableOnHost(); + startParams->remoteChannel = runConfig->remoteHostName() + ":" + + gdbServerPort; + startParams->remoteArchitecture = "arm"; + startParams->sysRoot = runConfig->sysRoot(); + startParams->toolChainType = ToolChain::GCC_MAEMO; + startParams->debuggerCommand = runConfig->gdbCmd(); + startParams->dumperLibrary = runConfig->dumperLib(); + startParams->remoteDumperLib = QString::fromLocal8Bit("%1/%2") + .arg(runConfig->remoteDir()).arg(QFileInfo(runConfig->dumperLib()) + .fileName()); + + connect(this, SIGNAL(stopRequested()), debuggerManager, SLOT(exitDebugger())); + connect(debuggerManager, SIGNAL(debuggingFinished()), this, + SLOT(debuggingFinished()), Qt::QueuedConnection); + connect(debuggerManager, SIGNAL(applicationOutputAvailable(QString)), + this, SLOT(debuggerOutput(QString)), Qt::QueuedConnection); +} + +MaemoDebugRunControl::~MaemoDebugRunControl() +{ + disconnect(SIGNAL(addToOutputWindow(RunControl*,QString))); + disconnect(SIGNAL(addToOutputWindowInline(RunControl*,QString))); + stop(); + debuggingFinished(); +} + +void MaemoDebugRunControl::start() +{ + startDeployment(true); +} + +void MaemoDebugRunControl::deploymentFinished(bool success) +{ + if (success) { + startGdbServer(); + } else { + emit finished(); + } +} + +void MaemoDebugRunControl::startGdbServer() +{ + const QString remoteCall(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4"). + arg(targetCmdLinePrefix()).arg(gdbServerPort). arg(executableOnTarget()) + .arg(runConfig->arguments().join(" "))); + QStringList sshArgs; + sshArgs << "-t" << "-n" << "-l" << runConfig->remoteUserName() << "-p" + << port() << runConfig->remoteHostName() << remoteCall; + inferiorPid = -1; + disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0); + connect(&gdbServer, SIGNAL(readyReadStandardError()), this, + SLOT(gdbServerStarted())); + gdbServer.start(runConfig->sshCmd(), sshArgs); + qDebug("Maemo: started gdb server, ssh arguments were %s", qPrintable(sshArgs.join(" "))); +} + +void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason) +{ + emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason)); + emit stopRequested(); + emit finished(); +} + +void MaemoDebugRunControl::gdbServerStarted() +{ + const QByteArray output = gdbServer.readAllStandardError(); + qDebug("gdbserver's stderr output: %s", output.data()); + + const QByteArray searchString("pid = "); + const int searchStringLength = searchString.length(); + + int pidStartPos = output.indexOf(searchString); + const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength); + if (pidStartPos == -1 || pidEndPos == -1) { + gdbServerStartFailed(output.data()); + return; + } + + pidStartPos += searchStringLength; + QByteArray pidString = output.mid(pidStartPos, pidEndPos - pidStartPos); + qDebug("pidString = %s", pidString.data()); + + bool ok; + const int pid = pidString.toInt(&ok); + if (!ok) { + gdbServerStartFailed(tr("Debugging failed, could not parse gdb " + "server pid!")); + return; + } + + inferiorPid = pid; + qDebug("inferiorPid = %d", inferiorPid); + + disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0); + connect(&gdbServer, SIGNAL(readyReadStandardError()), this, + SLOT(readStandardError())); + startDebugging(); +} + +void MaemoDebugRunControl::startDebugging() +{ + debuggerManager->startNewDebugger(startParams); +} + +void MaemoDebugRunControl::stop() +{ + if (!isRunning()) + return; + emit addToOutputWindow(this, tr("Stopping debugging operation ...")); + if (isDeploying()) { + stopDeployment(); + } else { + emit stopRequested(); + } +} + +bool MaemoDebugRunControl::isRunning() const +{ + return isDeploying() || gdbServer.state() != QProcess::NotRunning + || debuggerManager->state() != Debugger::DebuggerNotReady; +} + +void MaemoDebugRunControl::debuggingFinished() +{ + if (gdbServer.state() != QProcess::NotRunning) { + stopProcess.kill(); + const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; " + "kill -9 %1; pkill -9 -f gdbserver").arg(inferiorPid); + QStringList sshArgs; + sshArgs << "-n" << "-l" << runConfig->remoteUserName() << "-p" << port() + << runConfig->remoteHostName() << remoteCall; + stopProcess.start(runConfig->sshCmd(), sshArgs); + } + qDebug("ssh return code is %d", gdbServer.exitCode()); + emit addToOutputWindow(this, tr("Debugging finished.")); + emit finished(); +} + +void MaemoDebugRunControl::debuggerOutput(const QString &output) +{ + emit addToOutputWindowInline(this, output); +} + +} // namespace Internal +} // namespace Qt4ProjectManager + +#include "maemorunconfiguration.moc" diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h new file mode 100644 index 0000000000..def8fd4aa7 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h @@ -0,0 +1,228 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MAEMORUNCONFIGURATION_H +#define MAEMORUNCONFIGURATION_H + +#include <QtCore/QDateTime> +#include <QtGui/QWidget> + +#include <debugger/debuggermanager.h> +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/applicationlauncher.h> + +namespace Qt4ProjectManager { +class Qt4Project; + +namespace Internal { + +class MaemoManager; +class MaemoToolChain; +using namespace ProjectExplorer; +typedef QSharedPointer<RunConfiguration> RunConfig; + +#define USE_SSL_PASSWORD 0 + +class ErrorDumper : public QObject +{ + Q_OBJECT +public: + ErrorDumper(QObject *parent = 0) + : QObject(parent) {} + +public slots: + void printToStream(QProcess::ProcessError error); +}; + + +class MaemoRunConfiguration : public RunConfiguration +{ + Q_OBJECT +public: + MaemoRunConfiguration(Project *project, const QString &proFilePath); + ~MaemoRunConfiguration(); + + QString type() const; + bool isEnabled() const; + QWidget *configurationWidget(); + Qt4Project *project() const; + + void save(ProjectExplorer::PersistentSettingsWriter &writer) const; + void restore(const ProjectExplorer::PersistentSettingsReader &reader); + + bool currentlyNeedsDeployment() const; + void wasDeployed(); + + bool hasDebuggingHelpers() const; + bool debuggingHelpersNeedDeployment() const; + void debuggingHelpersDeployed(); + + QString maddeRoot() const; + QString executable() const; + const QString sysRoot() const; + const QStringList arguments() const; + void setArguments(const QStringList &args); + + QString simulator() const; + QString simulatorArgs() const; + QString simulatorPath() const; + QString visibleSimulatorParameter() const; + + bool remoteHostIsSimulator() const { return m_remoteHostIsSimulator; } + const QString remoteHostName() const; + const QString remoteUserName() const; + int remotePort() const; + + const QString remoteDir() const; + const QString sshCmd() const; + const QString scpCmd() const; + const QString gdbCmd() const; + const QString dumperLib() const; + + void setRemoteHostIsSimulator(bool isSimulator); + void setRemoteHostName(const QString &hostName); + void setRemoteUserName(const QString &userName); + void setRemotePort(int port); + + bool isQemuRunning() const; + +#if USE_SSL_PASSWORD + // Only valid if remoteHostRequiresPassword() == true. + void setRemotePassword(const QString &password); + const QString remoteUserPassword() const { return m_remoteUserPassword; } + + void setRemoteHostRequiresPassword(bool requiresPassword); + bool remoteHostRequiresPassword() const { return m_remoteHostRequiresPassword; } +#endif + +signals: + void targetInformationChanged(); + void cachedSimulatorInformationChanged(); + void qemuProcessStatus(bool running); + +private slots: + void invalidateCachedTargetInformation(); + + void setUserSimulatorPath(const QString &path); + void invalidateCachedSimulatorInformation(); + void resetCachedSimulatorInformation(); + + void startStopQemu(); + void qemuProcessFinished(); + + void enabledStateChanged(); + +private: + void updateTarget(); + void updateSimulatorInformation(); + const QString cmd(const QString &cmdName) const; + const MaemoToolChain *toolchain() const; + bool fileNeedsDeployment(const QString &path, const QDateTime &lastDeployed) const; + +private: + // Keys for saving/loading attributes. + QString m_executable; + QString m_proFilePath; + bool m_cachedTargetInformationValid; + + QString m_simulator; + QString m_simulatorArgs; + QString m_simulatorPath; + QString m_visibleSimulatorParameter; + bool m_cachedSimulatorInformationValid; + + bool m_isUserSetSimulator; + QString m_userSimulatorPath; + + QString m_gdbPath; + + // Information about the remote host. + bool m_remoteHostIsSimulator; + + QStringList m_argumentsSim; + QString m_remoteHostNameSim; + QString m_remoteUserNameSim; + int m_remotePortSim; + + QStringList m_argumentsDevice; + QString m_remoteHostNameDevice; + QString m_remoteUserNameDevice; + int m_remotePortDevice; + + QDateTime m_lastDeployed; + QDateTime m_debuggingHelpersLastDeployed; + + QProcess *qemu; + ErrorDumper dumper; + +#if USE_SSL_PASSWORD + QString m_remoteUserPassword; + bool m_remoteHostRequiresPassword; +#endif +}; + + +class MaemoRunConfigurationFactory : public IRunConfigurationFactory +{ + Q_OBJECT +public: + MaemoRunConfigurationFactory(QObject *parent); + ~MaemoRunConfigurationFactory(); + + bool canRestore(const QString &type) const; + QStringList availableCreationTypes(Project *project) const; + QString displayNameForType(const QString &type) const; + RunConfig create(Project *project, const QString &type); + +private slots: + void addedRunConfiguration(ProjectExplorer::Project* project); + void removedRunConfiguration(ProjectExplorer::Project* project); + + void projectAdded(ProjectExplorer::Project* project); + void projectRemoved(ProjectExplorer::Project* project); + void currentProjectChanged(ProjectExplorer::Project* project); +}; + + +class MaemoRunControlFactory : public IRunControlFactory +{ + Q_OBJECT +public: + MaemoRunControlFactory(QObject *parent = 0); + bool canRun(const RunConfig &runConfiguration, const QString &mode) const; + RunControl* create(const RunConfig &runConfiguration, const QString &mode); + QString displayName() const; + QWidget *configurationWidget(const RunConfig &runConfiguration); +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + + +#endif // MAEMORUNCONFIGURATION_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp new file mode 100644 index 0000000000..6c029e5b0d --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp @@ -0,0 +1,220 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "maemotoolchain.h" +#include "qtversionmanager.h" + +#include <QtCore/QDir> +#include <QtCore/QtDebug> + +using namespace ProjectExplorer; +using namespace Qt4ProjectManager::Internal; + +#ifdef Q_OS_WIN32 +#define EXEC_SUFFIX ".exe" +#else +#define EXEC_SUFFIX "" +#endif + +namespace { + const char *GCC_MAEMO_COMMAND = "arm-none-linux-gnueabi-gcc" EXEC_SUFFIX; +} + +MaemoToolChain::MaemoToolChain(const Qt4ProjectManager::QtVersion *version) + : GccToolChain(QLatin1String(GCC_MAEMO_COMMAND)) + , m_maddeInitialized(false) + , m_sysrootInitialized(false) + , m_simulatorInitialized(false) + , m_targetInitialized(false) + , m_toolchainInitialized(false) + , m_version(version) +{ +} + +MaemoToolChain::~MaemoToolChain() +{ +} + +ToolChain::ToolChainType MaemoToolChain::type() const +{ + return ToolChain::GCC_MAEMO; +} + +QList<HeaderPath> MaemoToolChain::systemHeaderPaths() +{ + if (m_systemHeaderPaths.isEmpty()) { + GccToolChain::systemHeaderPaths(); + m_systemHeaderPaths + .append(HeaderPath(QString("%1/usr/include").arg(sysrootRoot()), + HeaderPath::GlobalHeaderPath)); + } + return m_systemHeaderPaths; +} + +void MaemoToolChain::addToEnvironment(ProjectExplorer::Environment &env) +{ + if (m_version) { + env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin") + .arg(maddeRoot()))); + env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin") + .arg(targetRoot()))); + env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin") + .arg(toolchainRoot()))); +#ifdef Q_OS_WIN + env.set("HOME", QDir::toNativeSeparators(maddeRoot() + + QLatin1String("/home/") + QDir::home().dirName())); +#endif + } +} + +QString MaemoToolChain::makeCommand() const +{ + return QLatin1String("make" EXEC_SUFFIX); +} + +bool MaemoToolChain::equals(ToolChain *other) const +{ + MaemoToolChain *toolChain = static_cast<MaemoToolChain*> (other); + return (other->type() == type() + && toolChain->sysrootRoot() == sysrootRoot() + && toolChain->simulatorRoot() == simulatorRoot() + && toolChain->targetRoot() == targetRoot() + && toolChain->toolchainRoot() == toolchainRoot()); +} + +QString MaemoToolChain::maddeRoot() const +{ + if (!m_maddeInitialized) + (const_cast<MaemoToolChain*> (this))->setMaddeRoot(); + return m_maddeRoot; +} + +QString MaemoToolChain::targetRoot() const +{ + if (!m_targetInitialized) + (const_cast<MaemoToolChain*> (this))->setTargetRoot(); + return m_targetRoot; +} + +QString MaemoToolChain::sysrootRoot() const +{ + if (!m_sysrootInitialized) + (const_cast<MaemoToolChain*> (this))->setSysrootAndToolchain(); + return m_sysrootRoot; +} + +QString MaemoToolChain::simulatorRoot() const +{ + if (!m_simulatorInitialized) + (const_cast<MaemoToolChain*> (this))->setSimulatorRoot(); + return m_simulatorRoot; +} + +QString MaemoToolChain::toolchainRoot() const +{ + if (!m_toolchainInitialized) + (const_cast<MaemoToolChain*> (this))->setSysrootAndToolchain(); + return m_toolchainRoot; +} + +void MaemoToolChain::setTargetRoot() +{ + m_targetInitialized = true; + QString qmake = QDir::cleanPath(m_version->qmakeCommand()); + m_targetRoot = qmake.remove(QLatin1String("/bin/qmake" EXEC_SUFFIX)); +} + +void MaemoToolChain::setMaddeRoot() +{ + QDir dir(targetRoot()); + dir.cdUp(); dir.cdUp(); + + m_maddeInitialized = true; + m_maddeRoot = dir.absolutePath(); +} + +void MaemoToolChain::setSimulatorRoot() +{ + QString target = QDir::cleanPath(targetRoot()); + target = target.mid(target.lastIndexOf(QLatin1Char('/')) + 1); + + QFile file(maddeRoot() + QLatin1String("/cache/madde.conf")); + if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream stream(&file); + while (!stream.atEnd()) { + QString line = stream.readLine().trimmed(); + if (!line.startsWith(QLatin1String("target"))) + continue; + + const QStringList &list = line.split(QLatin1Char(' ')); + if (list.count() <= 1 || list.at(1) != target) + continue; + + line = stream.readLine().trimmed(); + while (!stream.atEnd() && line != QLatin1String("end")) { + if (line.startsWith(QLatin1String("runtime"))) { + const QStringList &list = line.split(QLatin1Char(' ')); + if (list.count() > 1) { + m_simulatorRoot = maddeRoot() + + QLatin1String("/runtimes/") + list.at(1).trimmed(); + } + break; + } + line = stream.readLine().trimmed(); + } + } + } + + m_simulatorInitialized = true; +} + +void MaemoToolChain::setSysrootAndToolchain() +{ + QFile file(QDir::cleanPath(targetRoot()) + QLatin1String("/information")); + if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream stream(&file); + while (!stream.atEnd()) { + const QString &line = stream.readLine().trimmed(); + const QStringList &list = line.split(QLatin1Char(' ')); + if (list.count() <= 1) + continue; + if (list.at(0) == QLatin1String("sysroot")) { + m_sysrootRoot = maddeRoot() + QLatin1String("/sysroots/") + + list.at(1); + } + if (list.at(0) == QLatin1String("toolchain")) { + m_toolchainRoot = maddeRoot() + QLatin1String("/toolchains/") + + list.at(1); + } + } + } + + m_sysrootInitialized = true; + m_toolchainInitialized = true; +} diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h new file mode 100644 index 0000000000..1ed3d52af2 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h @@ -0,0 +1,87 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MAEMOTOOLCHAIN_H +#define MAEMOTOOLCHAIN_H + +#include <projectexplorer/toolchain.h> + +namespace Qt4ProjectManager { + class QtVersion; + namespace Internal { + +class MaemoToolChain : public ProjectExplorer::GccToolChain +{ +public: + MaemoToolChain(const Qt4ProjectManager::QtVersion *version); + virtual ~MaemoToolChain(); + + QList<ProjectExplorer::HeaderPath> systemHeaderPaths(); + void addToEnvironment(ProjectExplorer::Environment &env); + ProjectExplorer::ToolChain::ToolChainType type() const; + QString makeCommand() const; + + QString maddeRoot() const; + QString targetRoot() const; + QString sysrootRoot() const; + QString simulatorRoot() const; + QString toolchainRoot() const; + +protected: + bool equals(ToolChain *other) const; + +private: + void setMaddeRoot(); + void setTargetRoot(); + void setSimulatorRoot(); + void setSysrootAndToolchain(); + +private: + QString m_maddeRoot; + bool m_maddeInitialized; + + QString m_sysrootRoot; + bool m_sysrootInitialized; + + QString m_simulatorRoot; + bool m_simulatorInitialized; + + QString m_targetRoot; + bool m_targetInitialized; + + QString m_toolchainRoot; + bool m_toolchainInitialized; + + const Qt4ProjectManager::QtVersion *m_version; +}; + + } // namespace Internal +} // namespace Qt4ProjectManager + +#endif // MAEMOTOOLCHAIN_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri new file mode 100644 index 0000000000..31d800c74a --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri @@ -0,0 +1,14 @@ +SUPPORT_QT_MAEMO = $$(QTCREATOR_WITH_MAEMO) +!isEmpty(SUPPORT_QT_MAEMO) { + message("Adding experimental support for Qt/Maemo applications.") + DEFINES += QTCREATOR_WITH_MAEMO + HEADERS += \ + $$PWD/maemorunconfiguration.h \ + $$PWD/maemomanager.h \ + $$PWD/maemotoolchain.h + SOURCES += \ + $$PWD/maemorunconfiguration.cpp \ + $$PWD/maemomanager.cpp \ + $$PWD/maemotoolchain.cpp + RESOURCES += $$PWD/qt-maemo.qrc +} diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc new file mode 100644 index 0000000000..354fe64d1b --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/qt-maemo"> + <file>images/qemu-run.png</file> + <file>images/qemu-stop.png</file> + </qresource> +</RCC> diff --git a/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp b/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp new file mode 100644 index 0000000000..db831deedf --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp @@ -0,0 +1,214 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "abldparser.h" +#include <utils/qtcassert.h> + +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/buildparserinterface.h> +#include <projectexplorer/taskwindow.h> + +#include <extensionsystem/pluginmanager.h> + +using namespace Qt4ProjectManager; +using namespace ProjectExplorer; + +AbldParser::AbldParser(const QString &name) : + m_name(name), + m_currentLine(-1), + m_waitingForStdErrContinuation(false), + m_waitingForStdOutContinuation(false) +{ + m_perlIssue.setPattern("^(WARNING|ERROR):\\s([^\\(\\)]+[^\\d])\\((\\d+)\\) : (.+)$"); + m_perlIssue.setMinimal(true); + + // Now look for new parser + QList<IBuildParserFactory *> buildParserFactories = + ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); + + QString subparser_name; + + if ((m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE))) + subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC); + else if ((m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW))) + subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW); + else if (m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT)) + subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT); + + QTC_ASSERT(!subparser_name.isNull(), return); + + foreach (IBuildParserFactory * factory, buildParserFactories) { + if (factory->canCreate(subparser_name)) { + m_subparser = factory->create(subparser_name); + break; + } + } + QTC_ASSERT(0 != m_subparser, return); + + connect(m_subparser, SIGNAL(enterDirectory(const QString &)), + this, SIGNAL(enterDirectory(const QString &))); + connect(m_subparser, SIGNAL(leaveDirectory(const QString &)), + this, SIGNAL(leaveDirectory(const QString &))); + connect(m_subparser, SIGNAL(addToOutputWindow(const QString &)), + this, SIGNAL(addToOutputWindow(const QString &))); + connect(m_subparser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), + this, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &))); +} + +AbldParser::~AbldParser() +{ + delete m_subparser; +} + +QString AbldParser::name() const +{ + return m_name; +} + +void AbldParser::stdOutput(const QString &line) +{ + m_waitingForStdErrContinuation = false; + + QString lne = line.trimmed(); + // possible ABLD.bat errors: + if (lne.startsWith("Is Perl, version ")) { + emit addToTaskWindow( + QString(), //filename + TaskWindow::Error, + -1, //linenumber + lne); + return; + } + if (lne.startsWith("FATAL ERROR:")) { + emit addToTaskWindow(QString(), TaskWindow::Error, + -1, lne.mid(12)); + m_waitingForStdOutContinuation = false; + return; + } + + if (m_perlIssue.indexIn(lne) > -1) { + m_waitingForStdOutContinuation = true; + TaskWindow::TaskType type; + if (m_perlIssue.cap(1) == QLatin1String("WARNING")) + type = TaskWindow::Warning; + else if (m_perlIssue.cap(1) == QLatin1String("ERROR")) + type = TaskWindow::Error; + else + type = TaskWindow::Unknown; + + m_currentFile = m_perlIssue.cap(2); + m_currentLine = m_perlIssue.cap(3).toInt(); + + emit addToTaskWindow(m_currentFile, type, + m_currentLine, m_perlIssue.cap(4)); + return; + } + + if (lne.isEmpty()) { + m_waitingForStdOutContinuation = false; + return; + } + + if (m_waitingForStdOutContinuation) { + emit addToTaskWindow(m_currentFile, + TaskWindow::Unknown, + m_currentLine, lne); + m_waitingForStdOutContinuation = true; + return; + } + + QTC_ASSERT(0 != m_subparser, return); + // pass on to compiler output parser: + m_subparser->stdOutput(lne); +} + +void AbldParser::stdError(const QString &line) +{ + m_waitingForStdOutContinuation = false; + + QString lne = line.trimmed(); + + // possible abld.pl errors: + if (lne.startsWith("ABLD ERROR:") || + lne.startsWith("This project does not support ") || + lne.startsWith("Platform ")) { + emit addToTaskWindow( + QString(), // filename, + TaskWindow::Error, + -1, // linenumber + lne); + return; + } + + if (lne.startsWith("Died at ")) { + emit addToTaskWindow(QString(), + TaskWindow::Error, + -1, lne); + m_waitingForStdErrContinuation = false; + return; + } + + if (lne.startsWith("MMPFILE \"")) { + m_currentFile = lne.mid(9, lne.size() - 10); + m_waitingForStdErrContinuation = false; + return; + } + if (lne.isEmpty()) { + m_waitingForStdErrContinuation = false; + return; + } + if (lne.startsWith("WARNING: ")) { + QString description = lne.mid(9); + emit addToTaskWindow(m_currentFile, + TaskWindow::Warning, + -1, description); + m_waitingForStdErrContinuation = true; + return; + } + if (lne.startsWith("ERROR: ")) { + QString description = lne.mid(7); + emit addToTaskWindow(m_currentFile, + TaskWindow::Error, + -1, description); + m_waitingForStdErrContinuation = true; + return; + } + if (m_waitingForStdErrContinuation) + { + emit addToTaskWindow(m_currentFile, + TaskWindow::Unknown, + -1, lne); + m_waitingForStdErrContinuation = true; + return; + } + + QTC_ASSERT(0 != m_subparser, return); + // pass on to compiler output parser: + m_subparser->stdError(lne); +} diff --git a/src/plugins/qt4projectmanager/qt-s60/abldparser.h b/src/plugins/qt4projectmanager/qt-s60/abldparser.h new file mode 100644 index 0000000000..2a5f616ac1 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/abldparser.h @@ -0,0 +1,65 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef ABLDPARSER_H +#define ABLDPARSER_H + +#include <projectexplorer/buildparserinterface.h> + +#include <QtCore/QRegExp> + +namespace Qt4ProjectManager { + +class AbldParser : public ProjectExplorer::BuildParserInterface +{ + Q_OBJECT + +public: + AbldParser(const QString & name); + ~AbldParser(); + + QString name() const; + virtual void stdOutput(const QString & line); + virtual void stdError(const QString & line); +private: + ProjectExplorer::BuildParserInterface * m_subparser; + const QString m_name; + + QRegExp m_perlIssue; + + QString m_currentFile; + int m_currentLine; + + bool m_waitingForStdErrContinuation; + bool m_waitingForStdOutContinuation; +}; + +} // namespace Qt4ProjectExplorer + +#endif // ABLDPARSER_H diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri index c1f2e85765..c0fd1d72f8 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri @@ -1,4 +1,4 @@ -!isEmpty(SUPPORT_QT_S60) { +!isEmpty(SUPPORT_QT_S60) { message("Adding experimental support for Qt/S60 applications.") DEFINES += QTCREATOR_WITH_S60 SOURCES += $$PWD/s60devices.cpp \ @@ -11,8 +11,11 @@ $$PWD/s60devicerunconfigurationwidget.cpp \ $$PWD/serialdevicelister.cpp \ $$PWD/rvcttoolchain.cpp \ - $$PWD/s60runconfigbluetoothstarter.cpp - + $$PWD/s60runconfigbluetoothstarter.cpp \ + $$PWD/s60buildparserfactory.cpp \ + $$PWD/abldparser.cpp \ + $$PWD/rvctparser.cpp \ + $$PWD/winscwparser.cpp HEADERS += $$PWD/s60devices.h \ $$PWD/s60devicespreferencepane.h \ $$PWD/s60manager.h \ @@ -23,8 +26,11 @@ $$PWD/s60devicerunconfigurationwidget.h \ $$PWD/serialdevicelister.h \ $$PWD/rvcttoolchain.h \ - $$PWD/s60runconfigbluetoothstarter.h - + $$PWD/s60runconfigbluetoothstarter.h \ + $$PWD/s60buildparserfactory.h \ + $$PWD/abldparser.h \ + $$PWD/rvctparser.h \ + $$PWD/winscwparser.h FORMS += $$PWD/s60devicespreferencepane.ui OTHER_FILES += $$PWD/qt-s60-todo.txt include(../../../shared/trk/trk.pri)||error("could not include trk.pri") diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp new file mode 100644 index 0000000000..07d56ebc70 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp @@ -0,0 +1,117 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "rvctparser.h" +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/taskwindow.h> + +using namespace ProjectExplorer; +using namespace Qt4ProjectManager; + +RvctParser::RvctParser() : + m_additionalInfo(false) +{ + // Start of a error or warning: + m_warningOrError.setPattern("^\"([^\\(\\)]+[^\\d])\", line (\\d+):(\\s(Warning|Error):)\\s(.+)$"); + m_warningOrError.setMinimal(true); + + // Last message for any file with warnings/errors. + m_doneWithFile.setPattern("^([^\\(\\)]+[^\\d]):\\s(\\d+) warnings?,\\s(\\d+) errors?$"); + m_doneWithFile.setMinimal(true); + + // linker problems: + m_linkerProblem.setPattern("^(\\S*)\\(\\S+\\):\\s(.+)$"); + m_linkerProblem.setMinimal(true); + + //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor' + m_makeDir.setPattern("^make.*: (\\w+) directory .(.+).$"); + m_makeDir.setMinimal(true); +} + +QString RvctParser::name() const +{ + return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT); +} + +void RvctParser::stdOutput(const QString &line) +{ + QString lne = line.trimmed(); + + if (m_makeDir.indexIn(lne) > -1) { + if (m_makeDir.cap(1) == "Leaving") + emit leaveDirectory(m_makeDir.cap(2)); + else + emit enterDirectory(m_makeDir.cap(2)); + } +} + +void RvctParser::stdError(const QString &line) +{ + QString lne = line.trimmed(); + + if (m_linkerProblem.indexIn(lne) > -1) { + QString description = m_linkerProblem.cap(2); + emit addToTaskWindow( + m_linkerProblem.cap(1), //filename + TaskWindow::Error, + -1, //linenumber + description); + } else if (m_warningOrError.indexIn(lne) > -1) { + TaskWindow::TaskType type; + if (m_warningOrError.cap(4) == "Warning") + type = TaskWindow::Warning; + else if (m_warningOrError.cap(4) == "Error") + type = TaskWindow::Error; + else + type = TaskWindow::Unknown; + + QString description = m_warningOrError.cap(5); + + m_additionalInfo = true; + m_lastFile = m_warningOrError.cap(1); + m_lastLine = m_warningOrError.cap(2).toInt(); + + emit addToTaskWindow( + m_lastFile, //filename + type, + m_lastLine, //line number + description); + } else if (m_doneWithFile.indexIn(lne) > -1) { + m_additionalInfo = false; + } else if (m_additionalInfo) { + // Report any lines after a error/warning message as these contain + // additional information on the problem. + emit addToTaskWindow( + m_lastFile, //filesname + TaskWindow::Unknown, + m_lastLine, //linenumber + lne //description + ); + } +} diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.h b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h new file mode 100644 index 0000000000..9f71c19e01 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef RVCTPARSER_H +#define RVCTPARSER_H + +#include <projectexplorer/buildparserinterface.h> + +#include <QtCore/QRegExp> + +namespace Qt4ProjectManager { + +class RvctParser : public ProjectExplorer::BuildParserInterface +{ + Q_OBJECT + +public: + RvctParser(); + QString name() const; + virtual void stdOutput(const QString & line); + virtual void stdError(const QString & line); +private: + QRegExp m_warningOrError; + QRegExp m_doneWithFile; + QRegExp m_linkerProblem; + QRegExp m_makeDir; + + bool m_additionalInfo; + QString m_lastFile; + int m_lastLine; +}; + +} // namespace Qt4ProjectManager + +#endif // RVCTPARSER_H diff --git a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp b/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp new file mode 100644 index 0000000000..06e650e394 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp @@ -0,0 +1,61 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "s60buildparserfactory.h" +#include "abldparser.h" +#include "rvctparser.h" +#include "winscwparser.h" + +#include <projectexplorer/projectexplorerconstants.h> + +using namespace Qt4ProjectManager::Internal; + +S60ParserFactory::~S60ParserFactory() +{ +} + +bool S60ParserFactory::canCreate(const QString & name) const +{ + return ((name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE)) || + (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW)) || + (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT)) || + (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT)) || + (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW))); +} + +ProjectExplorer::BuildParserInterface * S60ParserFactory::create(const QString & name) const +{ + if (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT)) + return new RvctParser(); + if (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW)) + return new WinscwParser(); + + return new AbldParser(name); +} + diff --git a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h b/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h new file mode 100644 index 0000000000..b3ea2e6606 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h @@ -0,0 +1,51 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef S60BUILDPARSERFACTORY_H +#define S60BUILDPARSERFACTORY_H + +#include <projectexplorer/buildparserinterface.h> + +namespace Qt4ProjectManager { +namespace Internal { + +class S60ParserFactory : public ProjectExplorer::IBuildParserFactory +{ + Q_OBJECT +public: + S60ParserFactory() {} + virtual ~S60ParserFactory(); + virtual bool canCreate(const QString & name) const; + virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const; +}; + +} // namespace Internal +} // namespace ProjectExplorer + +#endif // S60BUILDPARSERFACTORY_H diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index 74e9ceb0b6..fece8f8237 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -36,6 +36,7 @@ #include "rvcttoolchain.h" #include "s60emulatorrunconfiguration.h" #include "s60devicerunconfiguration.h" +#include "s60buildparserfactory.h" #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> @@ -117,6 +118,9 @@ S60Manager::S60Manager(QObject *parent) (QLatin1String(ProjectExplorer::Constants::RUNMODE), tr("Run on Device"), parent)); + // Build parsers + addAutoReleasedObject(new S60ParserFactory); + if (Debugger::DebuggerManager::instance()) addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl, S60DeviceRunConfiguration> diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp b/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp new file mode 100644 index 0000000000..6c8156370b --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp @@ -0,0 +1,96 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "winscwparser.h" +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/taskwindow.h> + +using namespace Qt4ProjectManager; +using namespace ProjectExplorer; + +WinscwParser::WinscwParser() +{ + // linker problems: + m_linkerProblem.setPattern("^(\\S*)\\(\\S+\\):\\s(.+)$"); + m_linkerProblem.setMinimal(true); + + // WINSCW issue: + m_compilerProblem.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):\\s(.+)$"); + m_compilerProblem.setMinimal(true); + + //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor' + m_makeDir.setPattern("^make.*: (\\w+) directory .(.+).$"); + m_makeDir.setMinimal(true); +} + +QString WinscwParser::name() const +{ + return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW); +} + +void WinscwParser::stdOutput(const QString &line) +{ + QString lne = line.trimmed(); + + if (m_makeDir.indexIn(lne) > -1) { + if (m_makeDir.cap(1) == "Leaving") + emit leaveDirectory(m_makeDir.cap(2)); + else + emit enterDirectory(m_makeDir.cap(2)); + return; + } + + if (m_compilerProblem.indexIn(lne) > -1) { + QString fileName(m_compilerProblem.cap(1)); + int lineNumber(m_compilerProblem.cap(2).toInt()); + QString description(m_compilerProblem.cap(3)); + TaskWindow::TaskType type(TaskWindow::Error); + + if (description.startsWith("warning: ")) { + type = TaskWindow::Warning; + description = description.mid(9); + } + + emit addToTaskWindow(fileName, type, lineNumber, description); + } +} + +void WinscwParser::stdError(const QString &line) +{ + QString lne = line.trimmed(); + + if (m_linkerProblem.indexIn(lne) > -1) { + QString description = m_linkerProblem.cap(2); + emit addToTaskWindow( + m_linkerProblem.cap(1), //filename + TaskWindow::Error, + -1, //linenumber + description); + } +} diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwparser.h b/src/plugins/qt4projectmanager/qt-s60/winscwparser.h new file mode 100644 index 0000000000..2e4e55de46 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/winscwparser.h @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef WINSCWPARSER_H +#define WINSCWPARSER_H + +#include <projectexplorer/buildparserinterface.h> + +#include <QtCore/QRegExp> + +namespace Qt4ProjectManager { + +class WinscwParser : public ProjectExplorer::BuildParserInterface +{ + Q_OBJECT + +public: + WinscwParser(); + QString name() const; + virtual void stdOutput(const QString & line); + virtual void stdError(const QString & line); +private: + QRegExp m_compilerProblem; + QRegExp m_linkerProblem; + QRegExp m_makeDir; +}; + +} // namespace Qt4ProjectManager + +#endif // WINSCWPARSER_H diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index b188b7855a..2ab7642014 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -309,8 +309,7 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) : m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)), m_fileInfo(new Qt4ProjectFile(this, fileName, this)), m_isApplication(true), - m_projectFiles(new Qt4ProjectFiles), - m_toolChain(0) + m_projectFiles(new Qt4ProjectFiles) { m_manager->registerProject(this); @@ -323,7 +322,6 @@ Qt4Project::~Qt4Project() { m_manager->unregisterProject(this); delete m_projectFiles; - delete m_toolChain; } void Qt4Project::defaultQtVersionChanged() @@ -497,17 +495,8 @@ void Qt4Project::scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFile ProjectExplorer::ToolChain *Qt4Project::toolChain(BuildConfiguration *configuration) const { - ProjectExplorer::ToolChain *tempToolChain; - tempToolChain = qtVersion(configuration)->createToolChain(toolChainType(configuration)); - if (!ProjectExplorer::ToolChain::equals(m_toolChain, tempToolChain)) { - if (m_toolChain) - delete m_toolChain; - m_toolChain = tempToolChain; - } else { - delete tempToolChain; - } - - return m_toolChain; + ToolChain::ToolChainType tct = toolChainType(configuration); + return qtVersion(configuration)->toolChain(tct); } QString Qt4Project::makeCommand(BuildConfiguration *configuration) const @@ -578,7 +567,6 @@ void Qt4Project::updateCodeModel() const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo(); const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS")); - const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS")); predefinedIncludePaths.append(newQtIncludePath); QDir dir(newQtIncludePath); @@ -598,6 +586,7 @@ void Qt4Project::updateCodeModel() QStringList allFrameworkPaths = predefinedFrameworkPaths; #ifdef Q_OS_MAC + const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS")); allFrameworkPaths.append(newQtLibsPath); // put QtXXX.framework/Headers directories in include path since that qmake's behavior QDir frameworkDir(newQtLibsPath); @@ -1002,9 +991,8 @@ void Qt4Project::updateActiveRunConfiguration() ProjectExplorer::ToolChain::ToolChainType Qt4Project::toolChainType(BuildConfiguration *configuration) const { - const ProjectExplorer::ToolChain::ToolChainType originalType = - (ProjectExplorer::ToolChain::ToolChainType)configuration->value("ToolChain").toInt(); - ProjectExplorer::ToolChain::ToolChainType type = originalType; + ToolChain::ToolChainType originalType = ToolChain::ToolChainType(configuration->value("ToolChain").toInt()); + ToolChain::ToolChainType type = originalType; const QtVersion *version = qtVersion(configuration); if (!version->possibleToolChainTypes().contains(type)) // use default tool chain type = version->defaultToolchainType(); @@ -1013,6 +1001,58 @@ ProjectExplorer::ToolChain::ToolChainType Qt4Project::toolChainType(BuildConfigu return type; } +QString Qt4Project::extractSpecFromArgumentList(const QStringList &list, QString directory, QtVersion *version) +{ + int index = list.indexOf("-spec"); + if (index == -1) + index = list.indexOf("-platform"); + if (index == -1) + return QString(); + + ++index; + + if (index >= list.length()) + return QString(); + + QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS"); + if (baseMkspecDir.isEmpty()) + baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs"; + + QString parsedSpec = QDir::cleanPath(list.at(index)); + // if the path is relative it can be + // relative to the working directory (as found in the Makefiles) + // or relatively to the mkspec directory + // if it is the former we need to get the canonical form + // for the other one we don't need to do anything + if (QFileInfo(parsedSpec).isRelative()) { + if(QFileInfo(directory + "/" + parsedSpec).exists()) { + parsedSpec = QDir::cleanPath(directory + "/" + parsedSpec); + } else { + parsedSpec = baseMkspecDir + "/" + parsedSpec; + } + } + + QFileInfo f2(parsedSpec); + while (f2.isSymLink()) { + parsedSpec = f2.symLinkTarget(); + f2.setFile(parsedSpec); + } + + if (parsedSpec.startsWith(baseMkspecDir)) { + parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1); + } else { + QString sourceMkSpecPath = version->sourcePath() + "/mkspecs"; + if (parsedSpec.startsWith(sourceMkSpecPath)) { + parsedSpec = sourceMkSpecPath.mid(sourceMkSpecPath.length() + 1); + } + } +#ifdef Q_OS_WIN + parsedSpec = parsedSpec.toLower(); +#endif + return parsedSpec; + +} + BuildConfigWidget *Qt4Project::createConfigWidget() { return new Qt4ProjectConfigWidget(this); @@ -1231,19 +1271,6 @@ QStringList Qt4Project::removeSpecFromArgumentList(const QStringList &old) return newList; } -QString Qt4Project::extractSpecFromArgumentList(const QStringList &list) -{ - int index = list.indexOf("-spec"); - if (index == -1) - index = list.indexOf("-platform"); - if (index == -1) - return QString(); - if (index + 1 < list.length()) - return list.at(index +1); - else - return QString(); -} - // returns true if both are equal bool Qt4Project::compareBuildConfigurationToImportFrom(BuildConfiguration *configuration, const QString &workingDirectory) { @@ -1260,52 +1287,31 @@ bool Qt4Project::compareBuildConfigurationToImportFrom(BuildConfiguration *confi // now compare arguments lists // we have to compare without the spec/platform cmd argument // and compare that on its own - QString actualSpec = extractSpecFromArgumentList(qs->value(configuration->name(), "qmakeArgs").toStringList()); - if (actualSpec.isEmpty()) + QString actualSpec = extractSpecFromArgumentList(qs->value(configuration->name(), "qmakeArgs").toStringList(), workingDirectory, version); + if (actualSpec.isEmpty()) { + // Easy one the user has choosen not to override the settings actualSpec = version->mkspec(); - - // Now to convert the actualSpec to a absolute path, we go through a few hops - if (QFileInfo(actualSpec).isRelative()) { - QString path = version->sourcePath() + "/mkspecs/" + actualSpec; - if (QFileInfo(path).exists()) { - actualSpec = QDir::cleanPath(path); - } else { - path = version->versionInfo().value("QMAKE_MKSPECS") + "/" + actualSpec; - if (QFileInfo(path).exists()) { - actualSpec = QDir::cleanPath(path); - } else { - path = workingDirectory + "/" + actualSpec; - if (QFileInfo(path).exists()) - actualSpec = QDir::cleanPath(path); - } - } } - - QString parsedSpec = extractSpecFromArgumentList(result.second); - // if the MakeFile did not contain a mkspec, then it is the default for that qmake - if (parsedSpec.isEmpty()) - parsedSpec = version->sourcePath() + "/mkspecs/" + version->mkspec(); - if (QFileInfo(parsedSpec).isRelative()) - parsedSpec = QDir::cleanPath(workingDirectory + "/" + parsedSpec); - + QString parsedSpec = extractSpecFromArgumentList(result.second, workingDirectory, version); QStringList actualArgs = removeSpecFromArgumentList(qs->value(configuration->name(), "qmakeArgs").toStringList()); QStringList parsedArgs = removeSpecFromArgumentList(result.second); -#ifdef Q_OS_WIN - actualSpec = actualSpec.toLower(); - parsedSpec = parsedSpec.toLower(); -#endif - - if (debug) { +// if (debug) { qDebug()<<"Actual args:"<<actualArgs; qDebug()<<"Parsed args:"<<parsedArgs; qDebug()<<"Actual spec:"<<actualSpec; qDebug()<<"Parsed spec:"<<parsedSpec; +// } + + if (actualArgs == parsedArgs) { + // Specs match exactly + if (actualSpec == parsedSpec) + return true; + // Actual spec is the default one + if (actualSpec == version->mkspec() && (parsedSpec == "default" || parsedSpec.isEmpty())) + return true; } - - if (actualArgs == parsedArgs && actualSpec == parsedSpec) - return true; } } } diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index 95f2c79b4d..aac7ac8cba 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -199,6 +199,7 @@ public: //returns the name of the qt version, might be QString::Null, which means default qt version // qtVersion is in general the better method to use QString qtVersionName(ProjectExplorer::BuildConfiguration *configuration) const; + ProjectExplorer::ToolChain *toolChain(ProjectExplorer::BuildConfiguration *configuration) const; void setToolChainType(ProjectExplorer::BuildConfiguration *configuration, ProjectExplorer::ToolChain::ToolChainType type); ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const; @@ -235,7 +236,7 @@ public: bool compareBuildConfigurationToImportFrom(ProjectExplorer::BuildConfiguration *configuration, const QString &workingDirectory); static QStringList removeSpecFromArgumentList(const QStringList &old); - static QString extractSpecFromArgumentList(const QStringList &list); + static QString extractSpecFromArgumentList(const QStringList &list, QString directory, QtVersion *version); signals: void targetInformationChanged(); void qtVersionChanged(ProjectExplorer::BuildConfiguration *); @@ -299,8 +300,6 @@ private: QList<Qt4ProjectManager::Internal::Qt4ProFileNode *> m_proFilesForCodeModelUpdate; QMap<QString, Internal::CodeModelInfo> m_codeModelInfo; - mutable ProjectExplorer::ToolChain *m_toolChain; - friend class Qt4ProjectFile; friend class Internal::Qt4ProjectConfigWidget; }; diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp index 80572bc68d..aa3cd231ed 100644 --- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp +++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp @@ -72,6 +72,30 @@ Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(Qt4Project *project) m_ui->shadowBuildDirEdit->setExpectedKind(Utils::PathChooser::Directory); m_ui->invalidQtWarningLabel->setVisible(false); + connect(m_ui->nameLineEdit, SIGNAL(textEdited(QString)), + this, SLOT(changeConfigName(QString))); + + connect(m_ui->shadowBuildCheckBox, SIGNAL(clicked(bool)), + this, SLOT(shadowBuildCheckBoxClicked(bool))); + + connect(m_ui->shadowBuildDirEdit, SIGNAL(beforeBrowsing()), + this, SLOT(onBeforeBeforeShadowBuildDirBrowsed())); + + connect(m_ui->shadowBuildDirEdit, SIGNAL(changed(QString)), + this, SLOT(shadowBuildLineEditTextChanged())); + + connect(m_ui->qtVersionComboBox, SIGNAL(currentIndexChanged(QString)), + this, SLOT(qtVersionComboBoxCurrentIndexChanged(QString))); + + connect(m_ui->toolChainComboBox, SIGNAL(activated(int)), + this, SLOT(selectToolChain(int))); + + connect(m_ui->importLabel, SIGNAL(linkActivated(QString)), + this, SLOT(importLabelClicked())); + + connect(m_ui->manageQtVersionPushButtons, SIGNAL(clicked()), + this, SLOT(manageQtVersions())); + QtVersionManager *vm = QtVersionManager::instance(); connect(vm, SIGNAL(qtVersionsChanged()), @@ -123,31 +147,6 @@ void Qt4ProjectConfigWidget::init(const QString &buildConfiguration) if (debug) qDebug() << "Qt4ProjectConfigWidget::init() for"<<buildConfiguration; - disconnect(m_ui->nameLineEdit, SIGNAL(textEdited(QString)), - this, SLOT(changeConfigName(QString))); - - disconnect(m_ui->shadowBuildCheckBox, SIGNAL(clicked(bool)), - this, SLOT(shadowBuildCheckBoxClicked(bool))); - - disconnect(m_ui->shadowBuildDirEdit, SIGNAL(beforeBrowsing()), - this, SLOT(onBeforeBeforeShadowBuildDirBrowsed())); - - disconnect(m_ui->shadowBuildDirEdit, SIGNAL(changed(QString)), - this, SLOT(shadowBuildLineEditTextChanged())); - - disconnect(m_ui->qtVersionComboBox, SIGNAL(currentIndexChanged(QString)), - this, SLOT(qtVersionComboBoxCurrentIndexChanged(QString))); - - disconnect(m_ui->toolChainComboBox, SIGNAL(activated(int)), - this, SLOT(selectToolChain(int))); - - disconnect(m_ui->importLabel, SIGNAL(linkActivated(QString)), - this, SLOT(importLabelClicked())); - - disconnect(m_ui->manageQtVersionPushButtons, SIGNAL(clicked()), - this, SLOT(manageQtVersions())); - - m_buildConfiguration = buildConfiguration; ProjectExplorer::BuildConfiguration *bc = m_pro->buildConfiguration(buildConfiguration); m_ui->nameLineEdit->setText(bc->displayName()); @@ -162,31 +161,6 @@ void Qt4ProjectConfigWidget::init(const QString &buildConfiguration) updateImportLabel(); updateToolChainCombo(); updateDetails(); - - connect(m_ui->nameLineEdit, SIGNAL(textEdited(QString)), - this, SLOT(changeConfigName(QString))); - - connect(m_ui->shadowBuildCheckBox, SIGNAL(clicked(bool)), - this, SLOT(shadowBuildCheckBoxClicked(bool))); - - connect(m_ui->shadowBuildDirEdit, SIGNAL(beforeBrowsing()), - this, SLOT(onBeforeBeforeShadowBuildDirBrowsed())); - - connect(m_ui->shadowBuildDirEdit, SIGNAL(changed(QString)), - this, SLOT(shadowBuildLineEditTextChanged())); - - connect(m_ui->qtVersionComboBox, SIGNAL(currentIndexChanged(QString)), - this, SLOT(qtVersionComboBoxCurrentIndexChanged(QString))); - - connect(m_ui->toolChainComboBox, SIGNAL(activated(int)), - this, SLOT(selectToolChain(int))); - - connect(m_ui->importLabel, SIGNAL(linkActivated(QString)), - this, SLOT(importLabelClicked())); - - connect(m_ui->manageQtVersionPushButtons, SIGNAL(clicked()), - this, SLOT(manageQtVersions())); - } void Qt4ProjectConfigWidget::changeConfigName(const QString &newName) @@ -248,8 +222,8 @@ void Qt4ProjectConfigWidget::shadowBuildCheckBoxClicked(bool checked) bc->setValue("buildDirectory", m_ui->shadowBuildDirEdit->path()); else bc->setValue("buildDirectory", QVariant(QString::null)); - m_pro->buildDirectoryChanged(); updateDetails(); + m_pro->invalidateCachedTargetInformation(); updateImportLabel(); } @@ -289,11 +263,9 @@ void Qt4ProjectConfigWidget::shadowBuildLineEditTextChanged() // if the directory already exists // check if we have a build in there and // offer to import it + updateImportLabel(); - m_pro->buildDirectoryChanged(); m_pro->invalidateCachedTargetInformation(); - - updateImportLabel(); updateDetails(); } @@ -316,22 +288,14 @@ void Qt4ProjectConfigWidget::importLabelClicked() QPair<QtVersion::QmakeBuildConfig, QStringList> result = QtVersionManager::scanMakeFile(directory, version->defaultBuildConfig()); QtVersion::QmakeBuildConfig qmakeBuildConfig = result.first; - QStringList additionalArguments = result.second; - - QString versionSpec = version->sourcePath() + "/mkspecs/" + version->mkspec(); - QString parsedSpec = Qt4Project::extractSpecFromArgumentList(additionalArguments); - - if (parsedSpec.isEmpty()) { + QStringList additionalArguments = Qt4Project::removeSpecFromArgumentList(result.second); + QString parsedSpec = Qt4Project::extractSpecFromArgumentList(result.second, directory, version); + QString versionSpec = version->mkspecPath(); + if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") { // using the default spec, don't modify additional arguments } else { - QString parsedSpecOrginal = parsedSpec; - if (QFileInfo(parsedSpec).isRelative()) - parsedSpec = QDir::cleanPath(directory + "/" + parsedSpec); - additionalArguments = Qt4Project::removeSpecFromArgumentList(additionalArguments); - if (parsedSpec != versionSpec) { - additionalArguments.prepend(parsedSpecOrginal); - additionalArguments.prepend("-spec"); - } + additionalArguments.prepend(parsedSpec); + additionalArguments.prepend("-spec"); } // So we got all the information now apply it... @@ -382,7 +346,6 @@ void Qt4ProjectConfigWidget::qtVersionComboBoxCurrentIndexChanged(const QString m_pro->update(); } updateDetails(); - updateImportLabel(); } void Qt4ProjectConfigWidget::updateToolChainCombo() diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro index a85ffcef01..de942dadbe 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.pro +++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro @@ -88,6 +88,7 @@ RESOURCES += qt4projectmanager.qrc \ wizards/wizards.qrc include(../../shared/proparser/proparser.pri) include(qt-s60/qt-s60.pri) +include(qt-maemo/qt-maemo.pri) include(customwidgetwizard/customwidgetwizard.pri) DEFINES += QT_NO_CAST_TO_ASCII OTHER_FILES += Qt4ProjectManager.pluginspec diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp index 468e9a260a..9471e3d1f3 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp @@ -51,6 +51,10 @@ #include "qt-s60/s60manager.h" #endif +#ifdef QTCREATOR_WITH_MAEMO +#include "qt-maemo/maemomanager.h" +#endif + #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/buildmanager.h> @@ -160,6 +164,10 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString * addAutoReleasedObject(new S60Manager); #endif +#ifdef QTCREATOR_WITH_MAEMO + addAutoReleasedObject(MaemoManager::instance()); +#endif + // TODO reenable //m_embeddedPropertiesPage = new EmbeddedPropertiesPage; //addObject(m_embeddedPropertiesPage); diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp index 586e894ba9..bcfd15cf37 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp @@ -95,18 +95,25 @@ QString Qt4RunConfiguration::type() const bool Qt4RunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const { -#ifdef QTCREATOR_WITH_S60 +#if defined(QTCREATOR_WITH_S60) || defined(QTCREATOR_WITH_MAEMO) Qt4Project *pro = qobject_cast<Qt4Project*>(project()); QTC_ASSERT(pro, return false); ProjectExplorer::ToolChain::ToolChainType type = pro->toolChainType(configuration); - return type != ProjectExplorer::ToolChain::WINSCW - && type != ProjectExplorer::ToolChain::GCCE - && type != ProjectExplorer::ToolChain::RVCT_ARMV5 - && type != ProjectExplorer::ToolChain::RVCT_ARMV6; +#ifdef QTCREATOR_WITH_S60 + if (type == ProjectExplorer::ToolChain::WINSCW + || type == ProjectExplorer::ToolChain::GCCE + || type == ProjectExplorer::ToolChain::RVCT_ARMV5 + || type == ProjectExplorer::ToolChain::RVCT_ARMV6) + return false; +#endif +#ifdef QTCREATOR_WITH_MAEMO + if (type == ProjectExplorer::ToolChain::GCC_MAEMO) + return false; +#endif #else Q_UNUSED(configuration); - return true; #endif + return true; } ////// diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index b1fc6a0bd3..a03f7f0bec 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -35,6 +35,9 @@ #ifdef QTCREATOR_WITH_S60 #include "qt-s60/s60manager.h" #endif +#ifdef QTCREATOR_WITH_MAEMO +#include "qt-maemo/maemomanager.h" +#endif #include <projectexplorer/debugginghelper.h> #include <projectexplorer/projectexplorer.h> @@ -418,7 +421,7 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, int id, m_isAutodetected(isAutodetected), m_autodetectionSource(autodetectionSource), m_hasDebuggingHelper(false), - m_mkspecUpToDate(false), + m_toolChainUpToDate(false), m_versionInfoUpToDate(false), m_notInstalled(false), m_defaultConfigIsDebug(true), @@ -440,7 +443,7 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, m_isAutodetected(isAutodetected), m_autodetectionSource(autodetectionSource), m_hasDebuggingHelper(false), - m_mkspecUpToDate(false), + m_toolChainUpToDate(false), m_versionInfoUpToDate(false), m_notInstalled(false), m_defaultConfigIsDebug(true), @@ -458,7 +461,7 @@ QtVersion::QtVersion(const QString &qmakeCommand, bool isAutodetected, const QSt : m_isAutodetected(isAutodetected), m_autodetectionSource(autodetectionSource), m_hasDebuggingHelper(false), - m_mkspecUpToDate(false), + m_toolChainUpToDate(false), m_versionInfoUpToDate(false), m_notInstalled(false), m_defaultConfigIsDebug(true), @@ -477,7 +480,7 @@ QtVersion::QtVersion() m_id(-1), m_isAutodetected(false), m_hasDebuggingHelper(false), - m_mkspecUpToDate(false), + m_toolChainUpToDate(false), m_versionInfoUpToDate(false), m_notInstalled(false), m_defaultConfigIsDebug(true), @@ -508,7 +511,7 @@ QString QtVersion::toHtml() const << "</b></td><td>" << mkspec() << "</td></tr>"; str << "<tr><td><b>" << QtVersionManager::tr("qmake:") << "</b></td><td>" << m_qmakeCommand << "</td></tr>"; - updateVersionInfo(); + updateToolChainAndMkspec(); if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) { str << "<tr><td><b>" << QtVersionManager::tr("Default:") << "</b></td><td>" << (m_defaultConfigIsDebug ? "debug" : "release"); @@ -516,9 +519,6 @@ QString QtVersion::toHtml() const str << " debug_and_release"; str << "</td></tr>"; } // default config. - if (!qmakeCXX().isEmpty()) - str << "<tr><td><b>" << QtVersionManager::tr("Compiler:") - << "</b></td><td>" << qmakeCXX() << "</td></tr>"; str << "<tr><td><b>" << QtVersionManager::tr("Version:") << "</b></td><td>" << qtVersionString() << "</td></tr>"; if (hasDebuggingHelper()) @@ -551,13 +551,13 @@ QString QtVersion::sourcePath() const QString QtVersion::mkspec() const { - updateMkSpec(); + updateToolChainAndMkspec(); return m_mkspec; } QString QtVersion::mkspecPath() const { - updateMkSpec(); + updateToolChainAndMkspec(); return m_mkspecFullPath; } @@ -572,13 +572,6 @@ QHash<QString,QString> QtVersion::versionInfo() const return m_versionInfo; } -QString QtVersion::qmakeCXX() const -{ - updateQMakeCXX(); - return m_qmakeCXX; -} - - void QtVersion::setName(const QString &name) { m_name = name; @@ -591,9 +584,7 @@ void QtVersion::setQMakeCommand(const QString& qmakeCommand) m_qmakeCommand = m_qmakeCommand.toLower(); #endif m_designerCommand = m_linguistCommand = m_uicCommand = QString::null; - m_mkspecUpToDate = false; - m_qmakeCXX = QString::null; - m_qmakeCXXUpToDate = false; + m_toolChainUpToDate = false; // TODO do i need to optimize this? m_versionInfoUpToDate = false; m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty(); @@ -629,6 +620,9 @@ void QtVersion::updateSourcePath() } } m_sourcePath = QDir::cleanPath(m_sourcePath); +#ifdef Q_OS_WIN + m_sourcePath = m_sourcePath.toLower(); +#endif } // Returns the version that was used to build the project in that directory @@ -835,7 +829,6 @@ void QtVersionManager::parseParts(const QStringList &parts, QList<QMakeAssignmen #endif } - /// This function extracts all the CONFIG+=debug, CONFIG+=release QtVersion::QmakeBuildConfig QtVersionManager::qmakeBuildConfigFromCmdArgs(QList<QMakeAssignment> *assignments, QtVersion::QmakeBuildConfig defaultBuildConfig) { @@ -950,29 +943,6 @@ void QtVersion::updateVersionInfo() const if (fi.exists()) m_hasDemos = true; } - - // Parse qconfigpri - QString baseDir = m_versionInfo.value("QT_INSTALL_DATA"); - QFile qconfigpri(baseDir + QLatin1String("/mkspecs/qconfig.pri")); - if (qconfigpri.exists()) { - qconfigpri.open(QIODevice::ReadOnly | QIODevice::Text); - QTextStream stream(&qconfigpri); - while (!stream.atEnd()) { - QString line = stream.readLine().trimmed(); - if (line.startsWith(QLatin1String("CONFIG"))) { - m_defaultConfigIsDebugAndRelease = false; - QStringList values = line.split(QLatin1Char('=')).at(1).trimmed().split(" "); - foreach(const QString &value, values) { - if (value == "debug") - m_defaultConfigIsDebug = true; - else if (value == "release") - m_defaultConfigIsDebug = false; - else if (value == "build_all") - m_defaultConfigIsDebugAndRelease = true; - } - } - } - } } m_versionInfoUpToDate = true; } @@ -983,141 +953,6 @@ bool QtVersion::isInstalled() const return !m_notInstalled; } -void QtVersion::updateMkSpec() const -{ - if (m_mkspecUpToDate) - return; - //qDebug()<<"Finding mkspec for"<<path(); - - QString mkspec; - // no .qmake.cache so look at the default mkspec - QString mkspecPath = versionInfo().value("QMAKE_MKSPECS"); - if (mkspecPath.isEmpty()) - mkspecPath = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/default"; - else - mkspecPath = mkspecPath + "/default"; -// qDebug() << "default mkspec is located at" << mkspecPath; -#ifdef Q_OS_WIN - QFile f2(mkspecPath + "/qmake.conf"); - if (f2.exists() && f2.open(QIODevice::ReadOnly)) { - while (!f2.atEnd()) { - QByteArray line = f2.readLine(); - if (line.startsWith("QMAKESPEC_ORIGINAL")) { - const QList<QByteArray> &temp = line.split('='); - if (temp.size() == 2) { - mkspec = temp.at(1).trimmed(); - } - break; - } - } - f2.close(); - } -#elif defined(Q_OS_MAC) - QFile f2(mkspecPath + "/qmake.conf"); - if (f2.exists() && f2.open(QIODevice::ReadOnly)) { - while (!f2.atEnd()) { - QByteArray line = f2.readLine(); - if (line.startsWith("MAKEFILE_GENERATOR")) { - const QList<QByteArray> &temp = line.split('='); - if (temp.size() == 2) { - const QByteArray &value = temp.at(1); - if (value.contains("XCODE")) { - // we don't want to generate xcode projects... -// qDebug() << "default mkspec is xcode, falling back to g++"; - mkspec = "macx-g++"; - } else { - //resolve mkspec link - QFileInfo f3(mkspecPath); - if (f3.isSymLink()) { - mkspec = f3.symLinkTarget(); - } - } - } - break; - } - } - f2.close(); - } -#else - QFileInfo f2(mkspecPath); - if (f2.isSymLink()) { - mkspec = f2.symLinkTarget(); - } -#endif - - m_mkspecFullPath = mkspec; - int index = mkspec.lastIndexOf('/'); - if (index == -1) - index = mkspec.lastIndexOf('\\'); - QString mkspecDir = QDir(versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/").canonicalPath(); - if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == mkspecDir) - mkspec = mkspec.mid(index+1).trimmed(); - - m_mkspec = mkspec; - m_mkspecUpToDate = true; -// qDebug()<<"mkspec for "<<versionInfo().value("QT_INSTALL_DATA")<<" is "<<mkspec; -} - -void QtVersion::updateQMakeCXX() const -{ - if (m_qmakeCXXUpToDate) - return; - ProFileReader *reader = new ProFileReader(); - reader->setCumulative(false); - reader->setParsePreAndPostFiles(false); - reader->readProFile(mkspecPath() + "/qmake.conf"); - m_qmakeCXX = reader->value("QMAKE_CXX"); - - delete reader; - m_qmakeCXXUpToDate = true; -} - -ProjectExplorer::ToolChain *QtVersion::createToolChain(ProjectExplorer::ToolChain::ToolChainType type) const -{ - ProjectExplorer::ToolChain *tempToolchain = 0; - if (type == ProjectExplorer::ToolChain::MinGW) { - QString qmake_cxx = qmakeCXX(); - ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); - //addToEnvironment(env); - env.prependOrSetPath(mingwDirectory()+"/bin"); - qmake_cxx = env.searchInPath(qmake_cxx); - tempToolchain = ProjectExplorer::ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory()); - //qDebug()<<"Mingw ToolChain"; - } else if(type == ProjectExplorer::ToolChain::MSVC) { - tempToolchain = ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit()); - //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")"; - } else if(type == ProjectExplorer::ToolChain::WINCE) { - tempToolchain = ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatform()); - //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")"; - } else if(type == ProjectExplorer::ToolChain::GCC || type == ProjectExplorer::ToolChain::LinuxICC) { - QString qmake_cxx = qmakeCXX(); - ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); - //addToEnvironment(env); - qmake_cxx = env.searchInPath(qmake_cxx); - if (qmake_cxx.isEmpty()) { - // macx-xcode mkspec resets the value of QMAKE_CXX. - // Unfortunately, we need a valid QMAKE_CXX to configure the parser. - qmake_cxx = QLatin1String("cc"); - } - tempToolchain = ProjectExplorer::ToolChain::createGccToolChain(qmake_cxx); - //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")"; -#ifdef QTCREATOR_WITH_S60 - } else if (type == ProjectExplorer::ToolChain::WINSCW) { - tempToolchain = S60Manager::instance()->createWINSCWToolChain(this); - } else if (type == ProjectExplorer::ToolChain::GCCE) { - tempToolchain = S60Manager::instance()->createGCCEToolChain(this); - } else if (type == ProjectExplorer::ToolChain::RVCT_ARMV5 - || type == ProjectExplorer::ToolChain::RVCT_ARMV6) { - tempToolchain = S60Manager::instance()->createRVCTToolChain(this, type); -#endif - } else { - qDebug()<<"Could not create ToolChain for"<<mkspec(); - qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines."; - } - return tempToolchain; -} - - QString QtVersion::findQtBinary(const QStringList &possibleCommands) const { const QString qtdirbin = versionInfo().value(QLatin1String("QT_INSTALL_BINS")) + QLatin1Char('/'); @@ -1181,37 +1016,203 @@ QString QtVersion::linguistCommand() const return m_linguistCommand; } +QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const +{ + updateToolChainAndMkspec(); + return m_toolChains; +} + +ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::ToolChainType type) const +{ + foreach(QSharedPointer<ProjectExplorer::ToolChain> tcptr, toolChains()) + if (tcptr->type() == type) + return tcptr.data(); + return 0; +} + QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const { - QList<ProjectExplorer::ToolChain::ToolChainType> toolChains; - if (!isValid()) - return toolChains << ProjectExplorer::ToolChain::INVALID; - const QString &spec = mkspec(); - if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc"))) - toolChains << ProjectExplorer::ToolChain::MSVC; - else if (spec.contains("win32-g++")) - toolChains << ProjectExplorer::ToolChain::MinGW; - else if (spec == QString::null) - toolChains << ProjectExplorer::ToolChain::INVALID; - else if (spec.contains("wince")) - toolChains << ProjectExplorer::ToolChain::WINCE; - else if (spec.contains("linux-icc")) - toolChains << ProjectExplorer::ToolChain::LinuxICC; -#ifdef QTCREATOR_WITH_S60 - else if (spec.contains("symbian-abld")) - toolChains << ProjectExplorer::ToolChain::GCCE - << ProjectExplorer::ToolChain::RVCT_ARMV5 - << ProjectExplorer::ToolChain::RVCT_ARMV6 - << ProjectExplorer::ToolChain::WINSCW; -#endif - else - toolChains << ProjectExplorer::ToolChain::GCC; - return toolChains; + QList<ProjectExplorer::ToolChain::ToolChainType> types; + foreach(QSharedPointer<ProjectExplorer::ToolChain> tc, toolChains()) + types << tc->type(); + return types; } ProjectExplorer::ToolChain::ToolChainType QtVersion::defaultToolchainType() const { - return possibleToolChainTypes().at(0); + const QList<ProjectExplorer::ToolChain::ToolChainType> & list = possibleToolChainTypes(); + if (list.isEmpty()) + return ProjectExplorer::ToolChain::INVALID; + return list.first(); +} + +// if none, then it's INVALID everywhere this function is called +void QtVersion::updateToolChainAndMkspec() const +{ + if (m_toolChainUpToDate) + return; + + if (!isValid()) + return; + + m_toolChains.clear(); + + qDebug()<<"Finding mkspec for"<<qmakeCommand(); + + // no .qmake.cache so look at the default mkspec + + QString baseMkspecDir = versionInfo().value("QMAKE_MKSPECS"); + if (baseMkspecDir.isEmpty()) + baseMkspecDir = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs"; + + QString mkspecFullPath = baseMkspecDir + "/default"; + + // qDebug() << "default mkspec is located at" << mkspecFullPath; + +#ifdef Q_OS_WIN + QFile f2(mkspecFullPath + "/qmake.conf"); + if (f2.exists() && f2.open(QIODevice::ReadOnly)) { + while (!f2.atEnd()) { + QByteArray line = f2.readLine(); + if (line.startsWith("QMAKESPEC_ORIGINAL")) { + const QList<QByteArray> &temp = line.split('='); + if (temp.size() == 2) { + mkspecFullPath = temp.at(1).trimmed(); + } + break; + } + } + f2.close(); + } +#elif defined(Q_OS_MAC) + QFile f2(mkspecFullPath + "/qmake.conf"); + if (f2.exists() && f2.open(QIODevice::ReadOnly)) { + while (!f2.atEnd()) { + QByteArray line = f2.readLine(); + if (line.startsWith("MAKEFILE_GENERATOR")) { + const QList<QByteArray> &temp = line.split('='); + if (temp.size() == 2) { + const QByteArray &value = temp.at(1); + if (value.contains("XCODE")) { + // we don't want to generate xcode projects... +// qDebug() << "default mkspec is xcode, falling back to g++"; + mkspecFullPath = baseMkspecDir + "/macx-g++"; + } + //resolve mkspec link + QFileInfo f3(mkspecFullPath); + while (f3.isSymLink()) { + mkspecFullPath = f3.symLinkTarget(); + f3.setFile(mkspecFullPath); + } + } + break; + } + } + f2.close(); + } +#else + QFileInfo f2(mkspecFullPath); + while (f2.isSymLink()) { + mkspecFullPath = f2.symLinkTarget(); + f2.setFile(mkspecFullPath); + } +#endif + +#ifdef Q_OS_WIN + m_mkspecFullPath = m_mkspecFullPath.toLower(); +#endif + + m_mkspecFullPath = mkspecFullPath; + QString mkspec = m_mkspecFullPath; + + if (mkspec.startsWith(baseMkspecDir)) { + mkspec = mkspec.mid(baseMkspecDir.length() + 1); + qDebug() << "Setting mkspec to"<<mkspec; + } else { + QString sourceMkSpecPath = sourcePath() + "/mkspecs"; + if (mkspec.startsWith(sourceMkSpecPath)) { + mkspec = mkspec.mid(sourceMkSpecPath.length() + 1); + } else { + // Do nothing + } + } + + m_mkspec = mkspec; + + qDebug()<<"mkspec for "<<qmakeCommand()<<" is "<<m_mkspec<<m_mkspecFullPath; + + ProFileReader *reader = new ProFileReader(); + reader->setQtVersion(this); + reader->setCumulative(false); + reader->setParsePreAndPostFiles(false); + reader->readProFile(m_mkspecFullPath + "/qmake.conf"); + QString qmakeCXX = reader->value("QMAKE_CXX"); + QString makefileGenerator = reader->value("MAKEFILE_GENERATOR"); + QString ce_sdk = reader->values("CE_SDK").join(QLatin1String(" ")); + QString ce_arch = reader->value("CE_ARCH"); + QString qt_arch = reader->value("QT_ARCH"); + if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) { + QString wincePlatformName = ce_sdk + " (" + ce_arch + ")"; + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName)); + } else if (makefileGenerator == "SYMBIAN_ABLD") { +#ifdef QTCREATOR_WITH_S60 + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + S60Manager::instance()->createGCCEToolChain(this)); + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5)); + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6)); + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + S60Manager::instance()->createWINSCWToolChain(this)); +#endif + } else if (qt_arch == "arm") { +#ifdef QTCREATOR_WITH_MAEMO + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + MaemoManager::instance()->maemoToolChain(this)); +#endif + } else if (qmakeCXX == "cl" || qmakeCXX == "icl") { + // TODO proper support for intel cl + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit())); + } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") { + ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); + //addToEnvironment(env); + env.prependOrSetPath(mingwDirectory() + "/bin"); + qmakeCXX = env.searchInPath(qmakeCXX); + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory())); + } else if (qmakeCXX == "g++" || qmakeCXX == "icc") { + ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); + //addToEnvironment(env); + qmakeCXX = env.searchInPath(qmakeCXX); + if (qmakeCXX.isEmpty()) { + // macx-xcode mkspec resets the value of QMAKE_CXX. + // Unfortunately, we need a valid QMAKE_CXX to configure the parser. + qmakeCXX = QLatin1String("cc"); + } + m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( + ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX)); + } + + if (m_toolChains.isEmpty()) { + qDebug()<<"Could not create ToolChain for"<<m_mkspecFullPath<<qmakeCXX; + qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines."; + } + + QStringList configValues = reader->values("CONFIG"); + m_defaultConfigIsDebugAndRelease = false; + foreach(const QString &value, configValues) { + if (value == "debug") + m_defaultConfigIsDebug = true; + else if (value == "release") + m_defaultConfigIsDebug = false; + else if (value == "build_all") + m_defaultConfigIsDebugAndRelease = true; + } + + delete reader; + m_toolChainUpToDate = true; } QString QtVersion::mwcDirectory() const @@ -1251,6 +1252,7 @@ QString QtVersion::mingwDirectory() const void QtVersion::setMingwDirectory(const QString &directory) { m_mingwDirectory = directory; + m_toolChainUpToDate = false; } QString QtVersion::msvcVersion() const @@ -1258,15 +1260,10 @@ QString QtVersion::msvcVersion() const return m_msvcVersion; } -QString QtVersion::wincePlatform() const -{ -// qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf"); - return ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf"); -} - void QtVersion::setMsvcVersion(const QString &version) { m_msvcVersion = version; + m_toolChainUpToDate = false; } void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) const @@ -1288,12 +1285,14 @@ int QtVersion::getUniqueId() bool QtVersion::isValid() const { - return (!(m_id == -1 || m_qmakeCommand == QString::null || m_name == QString::null || mkspec() == QString::null) && !m_notInstalled); + updateVersionInfo(); + return (!(m_id == -1 || qmakeCommand() == QString::null + || name() == QString::null) && !m_notInstalled); } QtVersion::QmakeBuildConfig QtVersion::defaultBuildConfig() const { - updateVersionInfo(); + updateToolChainAndMkspec(); QtVersion::QmakeBuildConfig result = QtVersion::QmakeBuildConfig(0); if (m_defaultConfigIsDebugAndRelease) result = QtVersion::BuildAll; @@ -1389,8 +1388,8 @@ QString QtVersion::buildDebuggingHelperLibrary() addToEnvironment(env); // TODO: the debugging helper doesn't comply to actual tool chain yet - - ProjectExplorer::ToolChain *tc = createToolChain(defaultToolchainType()); + QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains(); + ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data(); if (!tc) return QApplication::tr("The Qt Version has no toolchain."); tc->addToEnvironment(env); @@ -1399,7 +1398,6 @@ QString QtVersion::buildDebuggingHelperLibrary() if (!directory.isEmpty()) output += DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, tc->makeCommand(), qmakeCommand(), mkspec(), env); m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty(); - delete tc; return output; } diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h index df9cf0fd36..bbcdb51484 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.h +++ b/src/plugins/qt4projectmanager/qtversionmanager.h @@ -36,6 +36,10 @@ #include <QtCore/QSharedPointer> #include <QtCore/QHash> +namespace ProjectExplorer { + class ToolChain; +} + namespace Qt4ProjectManager { namespace Internal { @@ -65,16 +69,21 @@ public: QString name() const; QString sourcePath() const; - QString mkspecPath() const; QString qmakeCommand() const; QString uicCommand() const; QString designerCommand() const; QString linguistCommand() const; QList<ProjectExplorer::ToolChain::ToolChainType> possibleToolChainTypes() const; - QString mkspec() const; ProjectExplorer::ToolChain::ToolChainType defaultToolchainType() const; - ProjectExplorer::ToolChain *createToolChain(ProjectExplorer::ToolChain::ToolChainType type) const; + ProjectExplorer::ToolChain *toolChain(ProjectExplorer::ToolChain::ToolChainType type) const; + + /// @returns the name of the mkspec, which is generally not enough + /// to pass to qmake. + QString mkspec() const; + /// @returns the full path to the default directory + /// specifally not the directory the symlink/ORIGINAL_QMAKESPEC points to + QString mkspecPath() const; void setName(const QString &name); void setQMakeCommand(const QString &path); @@ -93,7 +102,6 @@ public: QString mingwDirectory() const; void setMingwDirectory(const QString &directory); QString msvcVersion() const; - QString wincePlatform() const; void setMsvcVersion(const QString &version); void addToEnvironment(ProjectExplorer::Environment &env) const; @@ -129,14 +137,13 @@ public: QString toHtml() const; private: + QList<QSharedPointer<ProjectExplorer::ToolChain> > toolChains() const; static int getUniqueId(); // Also used by QtOptionsPageWidget void updateSourcePath(); - void updateMkSpec() const; void updateVersionInfo() const; - void updateQMakeCXX() const; - QString qmakeCXX() const; QString findQtBinary(const QStringList &possibleName) const; + void updateToolChainAndMkspec() const; QString m_name; QString m_sourcePath; QString m_mingwDirectory; @@ -150,9 +157,10 @@ private: QString m_s60SDKDirectory; QString m_gcceDirectory; - mutable bool m_mkspecUpToDate; + mutable bool m_toolChainUpToDate; mutable QString m_mkspec; // updated lazily mutable QString m_mkspecFullPath; + mutable QList<QSharedPointer<ProjectExplorer::ToolChain> > m_toolChains; mutable bool m_versionInfoUpToDate; mutable QHash<QString,QString> m_versionInfo; // updated lazily @@ -168,9 +176,6 @@ private: mutable QString m_uicCommand; mutable QString m_designerCommand; mutable QString m_linguistCommand; - - mutable bool m_qmakeCXXUpToDate; - mutable QString m_qmakeCXX; }; struct QMakeAssignment diff --git a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec index 5f68421995..4abc8f5741 100644 --- a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec +++ b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="QtScriptEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="QtScriptEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,7 +19,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Editor for QtScript.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/regexp/RegExp.pluginspec b/src/plugins/regexp/RegExp.pluginspec index 9f9aafcc58..b42e70f4d2 100644 --- a/src/plugins/regexp/RegExp.pluginspec +++ b/src/plugins/regexp/RegExp.pluginspec @@ -1,4 +1,4 @@ -<plugin name="RegExp" version="1.3.0" compatVersion="1.3.0"> +<plugin name="RegExp" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Regular Expression test widget.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/resourceeditor/ResourceEditor.pluginspec b/src/plugins/resourceeditor/ResourceEditor.pluginspec index 535b514a97..0e2ddb86b6 100644 --- a/src/plugins/resourceeditor/ResourceEditor.pluginspec +++ b/src/plugins/resourceeditor/ResourceEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="ResourceEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="ResourceEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Editor for qrc files.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/snippets/Snippets.pluginspec b/src/plugins/snippets/Snippets.pluginspec index 5f08f6e474..28d1262c45 100644 --- a/src/plugins/snippets/Snippets.pluginspec +++ b/src/plugins/snippets/Snippets.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Snippets" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Snippets" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Code snippet plugin.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/subversion/Subversion.pluginspec b/src/plugins/subversion/Subversion.pluginspec index 8612e89ffa..bfb22237ff 100644 --- a/src/plugins/subversion/Subversion.pluginspec +++ b/src/plugins/subversion/Subversion.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Subversion" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Subversion" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Subversion integration.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> - <dependency name="Core" version="1.3.0"/> - <dependency name="VCSBase" version="1.3.0"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="VCSBase" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/texteditor/TextEditor.pluginspec b/src/plugins/texteditor/TextEditor.pluginspec index 9443481dd8..b28a6b5d9c 100644 --- a/src/plugins/texteditor/TextEditor.pluginspec +++ b/src/plugins/texteditor/TextEditor.pluginspec @@ -1,4 +1,4 @@ -<plugin name="TextEditor" version="1.3.0" compatVersion="1.3.0"> +<plugin name="TextEditor" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Text editor framework and the implementation of the basic text editor.</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="Find" version="1.3.0"/> - <dependency name="Locator" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="Find" version="1.3.80"/> + <dependency name="Locator" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/vcsbase/VCSBase.pluginspec b/src/plugins/vcsbase/VCSBase.pluginspec index b73163edd9..0f113b6e7d 100644 --- a/src/plugins/vcsbase/VCSBase.pluginspec +++ b/src/plugins/vcsbase/VCSBase.pluginspec @@ -1,4 +1,4 @@ -<plugin name="VCSBase" version="1.3.0" compatVersion="1.3.0"> +<plugin name="VCSBase" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Version Control System Base Plugin</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> - <dependency name="TextEditor" version="1.3.0"/> - <dependency name="ProjectExplorer" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> + <dependency name="TextEditor" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.ui b/src/plugins/vcsbase/basecheckoutwizardpage.ui index 7be84e63cb..6dc045d498 100644 --- a/src/plugins/vcsbase/basecheckoutwizardpage.ui +++ b/src/plugins/vcsbase/basecheckoutwizardpage.ui @@ -29,6 +29,9 @@ </property> </widget> </item> + <item row="1" column="1"> + <widget class="Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/> + </item> <item row="2" column="0"> <widget class="QLabel" name="pathLabel"> <property name="text"> @@ -39,9 +42,6 @@ <item row="2" column="1"> <widget class="Utils::PathChooser" name="pathChooser"/> </item> - <item row="1" column="1"> - <widget class="Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/> - </item> </layout> </item> </layout> diff --git a/src/plugins/welcome/Welcome.pluginspec b/src/plugins/welcome/Welcome.pluginspec index 4911982551..206f3052da 100644 --- a/src/plugins/welcome/Welcome.pluginspec +++ b/src/plugins/welcome/Welcome.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Welcome" version="1.3.0" compatVersion="1.3.0"> +<plugin name="Welcome" version="1.3.80" compatVersion="1.3.80"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008-2009 Nokia Corporation</copyright> <license> @@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <description>Default Welcome Screen Plugin</description> <url>http://qt.nokia.com</url> <dependencyList> - <dependency name="Core" version="1.3.0"/> + <dependency name="Core" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/welcome/welcomemode.ui b/src/plugins/welcome/welcomemode.ui index e1c18bde91..ae3fd53c5f 100644 --- a/src/plugins/welcome/welcomemode.ui +++ b/src/plugins/welcome/welcomemode.ui @@ -175,7 +175,7 @@ QToolButton:pressed, QPushButton:pressed{ <property name="minimumSize"> <size> <width>0</width> - <height>10</height> + <height>25</height> </size> </property> <property name="font"> diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index babf8380c5..38f3050b00 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -80,8 +80,8 @@ unsigned AttributeSpecifierAST::lastToken() const return second_rparen_token + 1; else if (first_rparen_token) return first_rparen_token + 1; - else if (attributes) - return attributes->lastToken(); + else if (attribute_list) + return attribute_list->lastToken(); else if (second_lparen_token) return second_lparen_token + 1; else if (first_lparen_token) @@ -100,17 +100,13 @@ unsigned AttributeAST::lastToken() const if (rparen_token) return rparen_token + 1; - for (ExpressionListAST *it = expression_list; - it->expression && it->next; it = it->next) { - if (! it->next && it->expression) { - return it->expression->lastToken(); - } - } + else if (expression_list) + return expression_list->lastToken(); - if (tag_token) + else if (tag_token) return tag_token + 1; - if (lparen_token) + else if (lparen_token) return lparen_token + 1; return identifier_token + 1; @@ -173,10 +169,8 @@ unsigned ArrayInitializerAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - for (ExpressionListAST *it = expression_list; it; it = it->next) { - if (! it->next && it->expression) - return it->expression->lastToken(); - } + else if (expression_list) + return expression_list->lastToken(); return lbrace_token + 1; } @@ -303,10 +297,10 @@ unsigned CallAST::lastToken() const { if (rparen_token) return rparen_token + 1; - for (ExpressionListAST *it = expression_list; it; it = it->next) { - if (! it->next && it->expression) - return it->expression->lastToken(); - } + + else if (expression_list) + return expression_list->lastToken(); + return lparen_token + 1; } @@ -375,49 +369,27 @@ unsigned ClassSpecifierAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - for (DeclarationListAST *it = member_specifiers; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (member_specifier_list) + return member_specifier_list->lastToken(); - if (lbrace_token) + else if (lbrace_token) return lbrace_token + 1; - for (BaseSpecifierAST *it = base_clause; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (base_clause_list) + return base_clause_list->lastToken(); - if (colon_token) + else if (colon_token) return colon_token + 1; - if (name) + else if (name) return name->lastToken(); - for (SpecifierAST *it = attributes; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (attribute_list) + return attribute_list->lastToken(); return classkey_token + 1; } - -unsigned StatementListAST::firstToken() const -{ - return statement->firstToken(); -} - -unsigned StatementListAST::lastToken() const -{ - for (const StatementListAST *it = this; it; it = it->next) { - if (! it->next) - return it->statement->lastToken(); - } - - return 0; -} - unsigned CompoundStatementAST::firstToken() const { return lbrace_token; @@ -428,10 +400,8 @@ unsigned CompoundStatementAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - for (StatementListAST *it = statements; it; it = it->next) { - if (! it->next) - return it->statement->lastToken(); - } + else if (statement_list) + return statement_list->lastToken(); return lbrace_token + 1; } @@ -439,8 +409,8 @@ unsigned CompoundStatementAST::lastToken() const unsigned ConditionAST::firstToken() const { - if (type_specifier) - return type_specifier->firstToken(); + if (type_specifier_list) + return type_specifier_list->firstToken(); return declarator->firstToken(); } @@ -450,10 +420,8 @@ unsigned ConditionAST::lastToken() const if (declarator) return declarator->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (type_specifier_list) + return type_specifier_list->lastToken(); // ### assert? return 0; @@ -502,15 +470,11 @@ unsigned ConversionFunctionIdAST::firstToken() const unsigned ConversionFunctionIdAST::lastToken() const { - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (ptr_operator_list) + return ptr_operator_list->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (type_specifier_list) + return type_specifier_list->lastToken(); return operator_token + 1; } @@ -546,40 +510,23 @@ unsigned CtorInitializerAST::firstToken() const unsigned CtorInitializerAST::lastToken() const { - for (MemInitializerAST *it = member_initializers; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (member_initializer_list) + return member_initializer_list->lastToken(); return colon_token + 1; } -unsigned DeclarationListAST::firstToken() const -{ - return declaration->firstToken(); -} - -unsigned DeclarationListAST::lastToken() const -{ - for (const DeclarationListAST *it = this; it; it = it->next) { - if (! it->next) - return it->declaration->lastToken(); - } - - return 0; -} - unsigned DeclaratorAST::firstToken() const { - if (attributes) - return attributes->firstToken(); - if (ptr_operators) - return ptr_operators->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); + if (ptr_operator_list) + return ptr_operator_list->firstToken(); else if (core_declarator) return core_declarator->firstToken(); - else if (postfix_declarators) - return postfix_declarators->firstToken(); - else if (attributes) - return attributes->firstToken(); + else if (postfix_declarator_list) + return postfix_declarator_list->firstToken(); + else if (attribute_list) + return attribute_list->firstToken(); else if (initializer) return initializer->firstToken(); // ### assert? @@ -591,28 +538,20 @@ unsigned DeclaratorAST::lastToken() const if (initializer) return initializer->lastToken(); - for (SpecifierAST *it = post_attributes; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (post_attribute_list) + return post_attribute_list->lastToken(); - for (PostfixDeclaratorAST *it = postfix_declarators; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (postfix_declarator_list) + return postfix_declarator_list->lastToken(); - if (core_declarator) + else if (core_declarator) return core_declarator->lastToken(); - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (ptr_operator_list) + return ptr_operator_list->lastToken(); - for (SpecifierAST *it = attributes; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (attribute_list) + return attribute_list->lastToken(); // ### assert? return 0; @@ -640,30 +579,6 @@ unsigned DeclaratorIdAST::lastToken() const return name->lastToken(); } - -unsigned DeclaratorListAST::firstToken() const -{ - if (comma_token) - return comma_token; - - return declarator->firstToken(); -} - -unsigned DeclaratorListAST::lastToken() const -{ - for (const DeclaratorListAST *it = this; it; it = it->next) { - if (! it->next) { - if (it->declarator) - return it->declarator->lastToken(); - else if (it->comma_token) - return it->comma_token + 1; - } - } - - return 0; -} - - unsigned DeleteExpressionAST::firstToken() const { if (scope_token) @@ -755,10 +670,8 @@ unsigned EnumSpecifierAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - for (EnumeratorAST *it = enumerators; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (enumerator_list) + return enumerator_list->lastToken(); if (lbrace_token) return lbrace_token + 1; @@ -786,8 +699,8 @@ unsigned EnumeratorAST::lastToken() const unsigned ExceptionDeclarationAST::firstToken() const { - if (type_specifier) - return type_specifier->firstToken(); + if (type_specifier_list) + return type_specifier_list->firstToken(); if (declarator) return declarator->firstToken(); return dot_dot_dot_token; @@ -797,12 +710,13 @@ unsigned ExceptionDeclarationAST::lastToken() const { if (dot_dot_dot_token) return dot_dot_dot_token + 1; + else if (declarator) return declarator->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + + else if (type_specifier_list) + return type_specifier_list->lastToken(); + return 0; } @@ -817,35 +731,18 @@ unsigned ExceptionSpecificationAST::lastToken() const if (rparen_token) return rparen_token + 1; - for (ExpressionListAST *it = type_ids; it; it = it->next) { - if (! it->next && it->expression) - return it->expression->lastToken(); - } + else if (type_id_list) + return type_id_list->lastToken(); - if (dot_dot_dot_token) + else if (dot_dot_dot_token) return dot_dot_dot_token + 1; + else if (lparen_token) return lparen_token + 1; return throw_token + 1; } - -unsigned ExpressionListAST::firstToken() const -{ - return expression->firstToken(); -} - -unsigned ExpressionListAST::lastToken() const -{ - for (const ExpressionListAST *it = this; it; it = it->next) { - if (! it->next) - return it->expression->lastToken(); - } - return 0; -} - - unsigned ExpressionOrDeclarationStatementAST::firstToken() const { return declaration->firstToken(); @@ -929,13 +826,12 @@ unsigned FunctionDeclaratorAST::lastToken() const if (exception_specification) return exception_specification->lastToken(); - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (cv_qualifier_list) + return cv_qualifier_list->lastToken(); - if (rparen_token) + else if (rparen_token) return rparen_token + 1; + else if (parameters) return parameters->lastToken(); @@ -945,8 +841,8 @@ unsigned FunctionDeclaratorAST::lastToken() const unsigned FunctionDefinitionAST::firstToken() const { - if (decl_specifier_seq) - return decl_specifier_seq->firstToken(); + if (decl_specifier_list) + return decl_specifier_list->firstToken(); else if (declarator) return declarator->firstToken(); else if (ctor_initializer) @@ -958,15 +854,15 @@ unsigned FunctionDefinitionAST::lastToken() const { if (function_body) return function_body->lastToken(); + else if (ctor_initializer) return ctor_initializer->lastToken(); - if (declarator) + + else if (declarator) return declarator->lastToken(); - for (SpecifierAST *it = decl_specifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (decl_specifier_list) + return decl_specifier_list->lastToken(); // ### assert return 0; @@ -1038,10 +934,8 @@ unsigned LinkageBodyAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - for (DeclarationListAST *it = declarations; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (declaration_list) + return declaration_list->lastToken(); return lbrace_token + 1; } @@ -1116,12 +1010,10 @@ unsigned NamespaceAST::lastToken() const if (linkage_body) return linkage_body->lastToken(); - for (SpecifierAST *it = attributes; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (attribute_list) + return attribute_list->lastToken(); - if (identifier_token) + else if (identifier_token) return identifier_token + 1; return namespace_token + 1; @@ -1248,23 +1140,19 @@ unsigned NewInitializerAST::lastToken() const unsigned NewTypeIdAST::firstToken() const { - return type_specifier->firstToken(); + return type_specifier_list->firstToken(); } unsigned NewTypeIdAST::lastToken() const { - for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (new_array_declarator_list) + return new_array_declarator_list->lastToken(); - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) { - if (it->next) - return it->lastToken(); - } + else if (ptr_operator_list) + return ptr_operator_list->lastToken(); - if (type_specifier) - return type_specifier->lastToken(); + else if (type_specifier_list) + return type_specifier_list->lastToken(); // ### assert? return 0; @@ -1312,21 +1200,23 @@ unsigned OperatorFunctionIdAST::lastToken() const unsigned ParameterDeclarationAST::firstToken() const { - return type_specifier->firstToken(); + return type_specifier_list->firstToken(); } unsigned ParameterDeclarationAST::lastToken() const { if (expression) return expression->lastToken(); + else if (equal_token) return equal_token + 1; + else if (declarator) return declarator->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + + else if (type_specifier_list) + return type_specifier_list->lastToken(); + // ### assert? return 0; } @@ -1334,8 +1224,8 @@ unsigned ParameterDeclarationAST::lastToken() const unsigned ParameterDeclarationClauseAST::firstToken() const { - if (parameter_declarations) - return parameter_declarations->firstToken(); + if (parameter_declaration_list) + return parameter_declaration_list->firstToken(); return dot_dot_dot_token; } @@ -1343,7 +1233,7 @@ unsigned ParameterDeclarationClauseAST::lastToken() const { if (dot_dot_dot_token) return dot_dot_dot_token + 1; - return parameter_declarations->lastToken(); + return parameter_declaration_list->lastToken(); } @@ -1354,10 +1244,9 @@ unsigned PointerAST::firstToken() const unsigned PointerAST::lastToken() const { - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (cv_qualifier_list) + return cv_qualifier_list->lastToken(); + return star_token + 1; } @@ -1366,29 +1255,26 @@ unsigned PointerToMemberAST::firstToken() const { if (global_scope_token) return global_scope_token; - else if (nested_name_specifier) - return nested_name_specifier->firstToken(); + else if (nested_name_specifier_list) + return nested_name_specifier_list->firstToken(); return star_token; } unsigned PointerToMemberAST::lastToken() const { - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (cv_qualifier_list) + return cv_qualifier_list->lastToken(); - if (star_token) + else if (star_token) return star_token + 1; - for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (nested_name_specifier_list) + return nested_name_specifier_list->lastToken(); - if (global_scope_token) + else if (global_scope_token) return global_scope_token + 1; + // ### assert(0); return 0; } @@ -1411,10 +1297,8 @@ unsigned PostfixExpressionAST::firstToken() const unsigned PostfixExpressionAST::lastToken() const { - for (PostfixAST *it = postfix_expressions; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (postfix_expression_list) + return postfix_expression_list->lastToken(); return base_expression->lastToken(); } @@ -1423,8 +1307,8 @@ unsigned QualifiedNameAST::firstToken() const { if (global_scope_token) return global_scope_token; - else if (nested_name_specifier) - return nested_name_specifier->firstToken(); + else if (nested_name_specifier_list) + return nested_name_specifier_list->firstToken(); return unqualified_name->firstToken(); } @@ -1433,10 +1317,8 @@ unsigned QualifiedNameAST::lastToken() const if (unqualified_name) return unqualified_name->lastToken(); - for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (nested_name_specifier_list) + return nested_name_specifier_list->lastToken(); if (global_scope_token) return global_scope_token + 1; @@ -1473,10 +1355,10 @@ unsigned ReturnStatementAST::lastToken() const unsigned SimpleDeclarationAST::firstToken() const { - if (decl_specifier_seq) - return decl_specifier_seq->firstToken(); - else if (declarators) - return declarators->firstToken(); + if (decl_specifier_list) + return decl_specifier_list->firstToken(); + else if (declarator_list) + return declarator_list->firstToken(); return semicolon_token; } @@ -1485,18 +1367,16 @@ unsigned SimpleDeclarationAST::lastToken() const if (semicolon_token) return semicolon_token + 1; - if (declarators) - return declarators->lastToken(); + else if (declarator_list) + return declarator_list->lastToken(); - for (SpecifierAST *it = decl_specifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (decl_specifier_list) + return decl_specifier_list->lastToken(); + // ### assert(0); return 0; } - unsigned SimpleNameAST::firstToken() const { return identifier_token; @@ -1567,35 +1447,24 @@ unsigned SwitchStatementAST::lastToken() const { if (statement) return statement->lastToken(); + else if (rparen_token) return rparen_token + 1; + else if (condition) return condition->lastToken(); + else if (lparen_token) return lparen_token + 1; - return switch_token + 1; -} - - -unsigned TemplateArgumentListAST::firstToken() const -{ - return template_argument->firstToken(); -} -unsigned TemplateArgumentListAST::lastToken() const -{ - for (const TemplateArgumentListAST *it = this; it; it = it->next) { - if (! it->next && it->template_argument) - return it->template_argument->lastToken(); - } - return 0; + return switch_token + 1; } - unsigned TemplateDeclarationAST::firstToken() const { if (export_token) return export_token; + return template_token; } @@ -1603,21 +1472,23 @@ unsigned TemplateDeclarationAST::lastToken() const { if (declaration) return declaration->lastToken(); + else if (greater_token) return greater_token + 1; - for (DeclarationListAST *it = template_parameters; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (template_parameter_list) + return template_parameter_list->lastToken(); - if (less_token) + else if (less_token) return less_token + 1; + else if (template_token) return template_token + 1; + else if (export_token) return export_token + 1; + // ### assert(0); return 0; } @@ -1632,12 +1503,10 @@ unsigned TemplateIdAST::lastToken() const if (greater_token) return greater_token + 1; - for (TemplateArgumentListAST *it = template_arguments; it; it = it->next) { - if (! it->next && it->template_argument) - return it->template_argument->lastToken(); - } + else if (template_argument_list) + return template_argument_list->lastToken(); - if (less_token) + else if (less_token) return less_token + 1; return identifier_token + 1; @@ -1653,21 +1522,23 @@ unsigned TemplateTypeParameterAST::lastToken() const { if (type_id) return type_id->lastToken(); + else if (equal_token) return equal_token + 1; + else if (name) return name->lastToken(); + else if (class_token) return class_token + 1; + else if (greater_token) return greater_token + 1; - for (DeclarationListAST *it = template_parameters; it; it = it->next) { - if (! it->next) - return it->declaration->lastToken(); - } + else if (template_parameter_list) + return template_parameter_list->lastToken(); - if (less_token) + else if (less_token) return less_token + 1; return template_token + 1; @@ -1697,22 +1568,20 @@ unsigned ThrowExpressionAST::lastToken() const return throw_token + 1; } - unsigned TranslationUnitAST::firstToken() const { - return declarations->firstToken(); + return declaration_list->firstToken(); } unsigned TranslationUnitAST::lastToken() const { - for (DeclarationListAST *it = declarations; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (declaration_list) + return declaration_list->lastToken(); + + // ### assert(0); return 0; } - unsigned TryBlockStatementAST::firstToken() const { return try_token; @@ -1720,12 +1589,10 @@ unsigned TryBlockStatementAST::firstToken() const unsigned TryBlockStatementAST::lastToken() const { - for (CatchClauseAST *it = catch_clause_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + if (catch_clause_list) + return catch_clause_list->lastToken(); - if (statement) + else if (statement) return statement->lastToken(); return try_token + 1; @@ -1734,7 +1601,7 @@ unsigned TryBlockStatementAST::lastToken() const unsigned TypeConstructorCallAST::firstToken() const { - return type_specifier->firstToken(); + return type_specifier_list->firstToken(); } unsigned TypeConstructorCallAST::lastToken() const @@ -1742,27 +1609,23 @@ unsigned TypeConstructorCallAST::lastToken() const if (rparen_token) return rparen_token + 1; - for (ExpressionListAST *it = expression_list; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (expression_list) + return expression_list->lastToken(); - if (lparen_token) + else if (lparen_token) return lparen_token + 1; + else if (type_specifier_list) + return type_specifier_list->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } - + // ### assert(0); return 0; } unsigned TypeIdAST::firstToken() const { - return type_specifier->firstToken(); + return type_specifier_list->firstToken(); } unsigned TypeIdAST::lastToken() const @@ -1770,11 +1633,10 @@ unsigned TypeIdAST::lastToken() const if (declarator) return declarator->lastToken(); - for (SpecifierAST *it = type_specifier; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (type_specifier_list) + return type_specifier_list->lastToken(); + // ### assert(0); return 0; } @@ -1807,13 +1669,12 @@ unsigned TypenameCallExpressionAST::lastToken() const if (rparen_token) return rparen_token + 1; - for (ExpressionListAST *it = expression_list; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (expression_list) + return expression_list->lastToken(); - if (lparen_token) + else if (lparen_token) return lparen_token + 1; + else if (name) return name->lastToken(); @@ -1894,40 +1755,25 @@ unsigned WhileStatementAST::lastToken() const { if (statement) return statement->lastToken(); + else if (rparen_token) return rparen_token + 1; + else if (condition) return condition->lastToken(); + else if (lparen_token) return lparen_token + 1; + return while_token + 1; } // ObjC++ -unsigned IdentifierListAST::firstToken() const -{ - if (name) - return name->firstToken(); - else - return comma_token; -} - -unsigned IdentifierListAST::lastToken() const -{ - for (const IdentifierListAST *it = this; it; it = it->next) { - if (! it->next && it->name) { - return it->name->lastToken(); - } - } - // ### assert? - return 0; -} - - unsigned ObjCClassForwardDeclarationAST::firstToken() const { - if (attributes) - return attributes->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); + return class_token; } @@ -1936,18 +1782,17 @@ unsigned ObjCClassForwardDeclarationAST::lastToken() const if (semicolon_token) return semicolon_token + 1; - for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->name) - return it->name->lastToken(); - } + else if (identifier_list) + return identifier_list->lastToken(); return class_token + 1; } unsigned ObjCProtocolForwardDeclarationAST::firstToken() const { - if (attributes) - return attributes->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); + return protocol_token; } @@ -1956,18 +1801,16 @@ unsigned ObjCProtocolForwardDeclarationAST::lastToken() const if (semicolon_token) return semicolon_token + 1; - for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->name) - return it->name->lastToken(); - } + else if (identifier_list) + return identifier_list->lastToken(); return protocol_token + 1; } unsigned ObjCClassDeclarationAST::firstToken() const { - if (attributes) - return attributes->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); if (interface_token) return interface_token; @@ -1978,7 +1821,7 @@ unsigned ObjCClassDeclarationAST::firstToken() const unsigned ObjCClassDeclarationAST::lastToken() const { if (end_token) return end_token + 1; - if (member_declarations) return member_declarations->lastToken(); + if (member_declaration_list) return member_declaration_list->lastToken(); if (inst_vars_decl) return inst_vars_decl->lastToken(); if (protocol_refs) return protocol_refs->lastToken(); @@ -2001,8 +1844,8 @@ unsigned ObjCClassDeclarationAST::lastToken() const unsigned ObjCProtocolDeclarationAST::firstToken() const { - if (attributes) - return attributes->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); return protocol_token; } @@ -2011,19 +1854,17 @@ unsigned ObjCProtocolDeclarationAST::lastToken() const if (end_token) return end_token + 1; - if (member_declarations) - return member_declarations->lastToken(); + else if (member_declaration_list) + return member_declaration_list->lastToken(); - if (protocol_refs) + else if (protocol_refs) return protocol_refs->lastToken(); - if (name) + else if (name) return name->lastToken(); - for (SpecifierAST *it = attributes; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } + else if (attribute_list) + return attribute_list->lastToken(); return protocol_token + 1; } @@ -2035,12 +1876,11 @@ unsigned ObjCProtocolRefsAST::firstToken() const unsigned ObjCProtocolRefsAST::lastToken() const { - if (greater_token) return greater_token + 1; + if (greater_token) + return greater_token + 1; - for (IdentifierListAST *it = identifier_list; it; it = it->next) { - if (! it->next && it->name) - return it->name->lastToken(); - } + else if (identifier_list) + return identifier_list->lastToken(); return less_token + 1; } @@ -2067,25 +1907,6 @@ unsigned ObjCMessageExpressionAST::lastToken() const return lbracket_token + 1; } -unsigned ObjCMessageArgumentListAST::firstToken() const -{ - if (arg) - return arg->firstToken(); - // ### assert? - return 0; -} - -unsigned ObjCMessageArgumentListAST::lastToken() const -{ - for (const ObjCMessageArgumentListAST *it = this; it; it = it->next) { - if (! it->next && it->arg) { - return it->arg->lastToken(); - } - } - // ### assert? - return 0; -} - unsigned ObjCMessageArgumentAST::firstToken() const { return parameter_value_expression->firstToken(); @@ -2174,33 +1995,14 @@ unsigned ObjCSelectorArgumentAST::lastToken() const return name_token + 1; } -unsigned ObjCSelectorArgumentListAST::firstToken() const -{ - if (argument) - return argument->firstToken(); - - // ### assert? - return 0; -} - -unsigned ObjCSelectorArgumentListAST::lastToken() const -{ - for (const ObjCSelectorArgumentListAST *it = this; it; it = it->next) - if (!it->next && it->argument) - return it->argument->lastToken(); - - // ### assert? - return 0; -} - unsigned ObjCSelectorWithArgumentsAST::firstToken() const { - return selector_arguments->firstToken(); + return selector_argument_list->firstToken(); } unsigned ObjCSelectorWithArgumentsAST::lastToken() const { - return selector_arguments->lastToken(); + return selector_argument_list->lastToken(); } unsigned ObjCSelectorExpressionAST::firstToken() const @@ -2229,8 +2031,8 @@ unsigned ObjCInstanceVariablesDeclarationAST::lastToken() const if (rbrace_token) return rbrace_token + 1; - if (instance_variables) - return instance_variables->lastToken(); + if (instance_variable_list) + return instance_variable_list->lastToken(); return lbrace_token + 1; } @@ -2260,37 +2062,10 @@ unsigned ObjCPropertyAttributeAST::lastToken() const return attribute_identifier_token + 1; } -unsigned ObjCPropertyAttributeListAST::firstToken() const -{ - if (attr) - return attr->firstToken(); - else if (comma_token) - return comma_token; - else if (next) - return next->lastToken(); - else - // ### Assert? - return 0; -} - -unsigned ObjCPropertyAttributeListAST::lastToken() const -{ - for (const ObjCPropertyAttributeListAST *it = this; it; it = it->next) { - if (! it->next && (comma_token || it->attr)) { - if (comma_token) - return comma_token + 1; - else - return it->attr->lastToken(); - } - } - // ### assert? - return 0; -} - unsigned ObjCPropertyDeclarationAST::firstToken() const { - if (attributes) - return attributes->firstToken(); + if (attribute_list) + return attribute_list->firstToken(); return property_token; } @@ -2301,12 +2076,12 @@ unsigned ObjCPropertyDeclarationAST::lastToken() const return simple_declaration->lastToken(); else if (rparen_token) return rparen_token + 1; - else if (property_attributes) - return property_attributes->lastToken(); + else if (property_attribute_list) + return property_attribute_list->lastToken(); else if (lparen_token) return lparen_token + 1; - else - return property_token + 1; + + return property_token + 1; } unsigned ObjCMessageArgumentDeclarationAST::firstToken() const @@ -2328,28 +2103,6 @@ unsigned ObjCMessageArgumentDeclarationAST::lastToken() const return 0; } -unsigned ObjCMessageArgumentDeclarationListAST::firstToken() const -{ - if (argument_declaration) - return argument_declaration->firstToken(); - else if (next) - return next->firstToken(); - else - // ### Assert? - return 0; -} - -unsigned ObjCMessageArgumentDeclarationListAST::lastToken() const -{ - for (const ObjCMessageArgumentDeclarationListAST *it = this; it; it = it->next) { - if (! it->next && it->argument_declaration) { - return it->argument_declaration->lastToken(); - } - } - // ### assert? - return 0; -} - unsigned ObjCMethodPrototypeAST::firstToken() const { return method_type_token; @@ -2357,16 +2110,15 @@ unsigned ObjCMethodPrototypeAST::firstToken() const unsigned ObjCMethodPrototypeAST::lastToken() const { - if (attributes) - return attributes->lastToken(); + if (attribute_list) + return attribute_list->lastToken(); else if (dot_dot_dot_token) return dot_dot_dot_token + 1; - else if (arguments) - return arguments->lastToken(); + else if (argument_list) + return argument_list->lastToken(); else if (type_name) return type_name->lastToken(); - else - return method_type_token + 1; + return method_type_token + 1; } unsigned ObjCMethodDeclarationAST::firstToken() const @@ -2403,25 +2155,6 @@ unsigned ObjCSynthesizedPropertyAST::lastToken() const return property_identifier + 1; } -unsigned ObjCSynthesizedPropertyListAST::firstToken() const -{ - if (synthesized_property) - return synthesized_property->firstToken(); - else - return comma_token; -} - -unsigned ObjCSynthesizedPropertyListAST::lastToken() const -{ - for (const ObjCSynthesizedPropertyListAST *it = this; it; it = it->next) { - if (! it->next && it->synthesized_property) { - return it->synthesized_property->lastToken(); - } - } - // ### assert? - return 0; -} - unsigned ObjCSynthesizedPropertiesDeclarationAST::firstToken() const { return synthesized_token; @@ -2431,8 +2164,8 @@ unsigned ObjCSynthesizedPropertiesDeclarationAST::lastToken() const { if (semicolon_token) return semicolon_token + 1; - else if (property_identifiers) - return property_identifiers->lastToken(); + else if (property_identifier_list) + return property_identifier_list->lastToken(); else return synthesized_token + 1; } @@ -2446,8 +2179,8 @@ unsigned ObjCDynamicPropertiesDeclarationAST::lastToken() const { if (semicolon_token) return semicolon_token + 1; - else if (property_identifiers) - return property_identifiers->lastToken(); + else if (property_identifier_list) + return property_identifier_list->lastToken(); else return dynamic_token + 1; } @@ -2471,8 +2204,8 @@ unsigned ObjCFastEnumerationAST::lastToken() const return initializer->lastToken(); else if (declarator) return declarator->lastToken(); - else if (type_specifiers) - return type_specifiers->lastToken(); + else if (type_specifier_list) + return type_specifier_list->lastToken(); else if (lparen_token) return lparen_token + 1; else diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 6dced425a7..2a1c2d6ef0 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -53,11 +53,10 @@ #include "ASTfwd.h" #include "MemoryPool.h" - namespace CPlusPlus { template <typename _Tp> -class List: public Managed +class CPLUSPLUS_EXPORT List: public Managed { List(const List &other); void operator =(const List &other); @@ -67,6 +66,35 @@ public: : value(_Tp()), next(0) { } + List(const _Tp &value) + : value(value), next(0) + { } + + unsigned firstToken() const + { + if (value) + return value->firstToken(); + + // ### assert(0); + return 0; + } + + unsigned lastToken() const + { + _Tp lastValue = 0; + + for (const List *it = this; it; it = it->next) { + if (it->value) + lastValue = it->value; + } + + if (lastValue) + return lastValue->lastToken(); + + // ### assert(0); + return 0; + } + _Tp value; List *next; }; @@ -85,6 +113,13 @@ public: static void accept(AST *ast, ASTVisitor *visitor) { if (ast) ast->accept(visitor); } + template <typename _Tp> + static void accept(List<_Tp> *it, ASTVisitor *visitor) + { + for (; it; it = it->next) + accept(it->value, visitor); + } + virtual unsigned firstToken() const = 0; virtual unsigned lastToken() const = 0; @@ -96,7 +131,6 @@ public: virtual AttributeAST *asAttribute() { return 0; } virtual AttributeSpecifierAST *asAttributeSpecifier() { return 0; } virtual BaseSpecifierAST *asBaseSpecifier() { return 0; } - virtual QtMethodAST *asQtMethod() { return 0; } virtual BinaryExpressionAST *asBinaryExpression() { return 0; } virtual BoolLiteralAST *asBoolLiteral() { return 0; } virtual BreakStatementAST *asBreakStatement() { return 0; } @@ -118,7 +152,6 @@ public: virtual DeclarationStatementAST *asDeclarationStatement() { return 0; } virtual DeclaratorAST *asDeclarator() { return 0; } virtual DeclaratorIdAST *asDeclaratorId() { return 0; } - virtual DeclaratorListAST *asDeclaratorList() { return 0; } virtual DeleteExpressionAST *asDeleteExpression() { return 0; } virtual DestructorNameAST *asDestructorName() { return 0; } virtual DoStatementAST *asDoStatement() { return 0; } @@ -129,11 +162,10 @@ public: virtual ExceptionDeclarationAST *asExceptionDeclaration() { return 0; } virtual ExceptionSpecificationAST *asExceptionSpecification() { return 0; } virtual ExpressionAST *asExpression() { return 0; } - virtual ExpressionListAST *asExpressionList() { return 0; } virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; } virtual ExpressionStatementAST *asExpressionStatement() { return 0; } - virtual ForeachStatementAST *asForeachStatement() { return 0; } virtual ForStatementAST *asForStatement() { return 0; } + virtual ForeachStatementAST *asForeachStatement() { return 0; } virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; } virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; } virtual GotoStatementAST *asGotoStatement() { return 0; } @@ -150,12 +182,39 @@ public: virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; } virtual NestedExpressionAST *asNestedExpression() { return 0; } virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; } - virtual NewPlacementAST *asNewPlacement() { return 0; } virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; } virtual NewExpressionAST *asNewExpression() { return 0; } virtual NewInitializerAST *asNewInitializer() { return 0; } + virtual NewPlacementAST *asNewPlacement() { return 0; } virtual NewTypeIdAST *asNewTypeId() { return 0; } virtual NumericLiteralAST *asNumericLiteral() { return 0; } + virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; } + virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return 0; } + virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return 0; } + virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return 0; } + virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return 0; } + virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return 0; } + virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return 0; } + virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return 0; } + virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return 0; } + virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return 0; } + virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return 0; } + virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return 0; } + virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return 0; } + virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; } + virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return 0; } + virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return 0; } + virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return 0; } + virtual ObjCSelectorAST *asObjCSelector() { return 0; } + virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return 0; } + virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return 0; } + virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return 0; } + virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return 0; } + virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return 0; } + virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; } + virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; } + virtual ObjCTypeNameAST *asObjCTypeName() { return 0; } + virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return 0; } virtual OperatorAST *asOperator() { return 0; } virtual OperatorFunctionIdAST *asOperatorFunctionId() { return 0; } virtual ParameterDeclarationAST *asParameterDeclaration() { return 0; } @@ -167,6 +226,7 @@ public: virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; } virtual PostfixExpressionAST *asPostfixExpression() { return 0; } virtual PtrOperatorAST *asPtrOperator() { return 0; } + virtual QtMethodAST *asQtMethod() { return 0; } virtual QualifiedNameAST *asQualifiedName() { return 0; } virtual ReferenceAST *asReference() { return 0; } virtual ReturnStatementAST *asReturnStatement() { return 0; } @@ -178,7 +238,6 @@ public: virtual StatementAST *asStatement() { return 0; } virtual StringLiteralAST *asStringLiteral() { return 0; } virtual SwitchStatementAST *asSwitchStatement() { return 0; } - virtual TemplateArgumentListAST *asTemplateArgumentList() { return 0; } virtual TemplateDeclarationAST *asTemplateDeclaration() { return 0; } virtual TemplateIdAST *asTemplateId() { return 0; } virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return 0; } @@ -196,42 +255,6 @@ public: virtual UsingAST *asUsing() { return 0; } virtual UsingDirectiveAST *asUsingDirective() { return 0; } virtual WhileStatementAST *asWhileStatement() { return 0; } - virtual IdentifierListAST *asIdentifierList() { return 0; } - - virtual ObjCClassForwardDeclarationAST *asObjCClassForwarDeclaration() { return 0; } - virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; } - virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return 0; } - virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; } - virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return 0; } - virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return 0; } - virtual ObjCMessageArgumentListAST *asObjCMessageArgumentList() { return 0; } - virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return 0; } - virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return 0; } - virtual ObjCTypeNameAST *asObjCTypeName() { return 0; } - virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return 0; } - virtual ObjCSelectorAST *asObjCSelector() { return 0; } - virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return 0; } - virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return 0; } - virtual ObjCSelectorArgumentListAST *asObjCSelectorArgumentList() { return 0; } - virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return 0; } - virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return 0; } - virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return 0; } - virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return 0; } - virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return 0; } - virtual ObjCPropertyAttributeListAST *asObjCPropertyAttributeList() { return 0; } - virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return 0; } - virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return 0; } - virtual ObjCMessageArgumentDeclarationListAST *asObjCMessageArgumentDeclarationList() { return 0; } - virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return 0; } - virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return 0; } - virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; } - virtual ObjCSynthesizedPropertyListAST *asObjCSynthesizedPropertyList() { return 0; } - virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; } - virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return 0; } - virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return 0; } - - virtual AST *clone(MemoryPool *pool) const = 0; - protected: virtual void accept0(ASTVisitor *visitor) = 0; }; @@ -239,13 +262,7 @@ protected: class CPLUSPLUS_EXPORT SpecifierAST: public AST { public: - SpecifierAST *next; - -public: - virtual SpecifierAST *asSpecifier() - { return this; } - - virtual SpecifierAST *clone(MemoryPool *pool) const = 0; + virtual SpecifierAST *asSpecifier() { return this; } }; class CPLUSPLUS_EXPORT SimpleSpecifierAST: public SpecifierAST @@ -254,14 +271,11 @@ public: unsigned specifier_token; public: - virtual SimpleSpecifierAST *asSimpleSpecifier() - { return this; } + virtual SimpleSpecifierAST *asSimpleSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual SimpleSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -272,19 +286,16 @@ public: unsigned attribute_token; unsigned first_lparen_token; unsigned second_lparen_token; - AttributeAST *attributes; + AttributeListAST *attribute_list; unsigned first_rparen_token; unsigned second_rparen_token; public: - virtual AttributeSpecifierAST *asAttributeSpecifier() - { return this; } + virtual AttributeSpecifierAST *asAttributeSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual AttributeSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -297,18 +308,13 @@ public: unsigned tag_token; ExpressionListAST *expression_list; unsigned rparen_token; - AttributeAST *next; - unsigned comma_token; public: - virtual AttributeAST *asAttribute() - { return this; } + virtual AttributeAST *asAttribute() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual AttributeAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -322,14 +328,11 @@ public: unsigned rparen_token; public: - virtual TypeofSpecifierAST *asTypeofSpecifier() - { return this; } + virtual TypeofSpecifierAST *asTypeofSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypeofSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -337,110 +340,50 @@ protected: class CPLUSPLUS_EXPORT StatementAST: public AST { public: - virtual StatementAST *asStatement() - { return this; } - - virtual StatementAST *clone(MemoryPool *pool) const = 0; + virtual StatementAST *asStatement() { return this; } }; class CPLUSPLUS_EXPORT ExpressionAST: public AST { public: - virtual ExpressionAST *asExpression() - { return this; } - - virtual ExpressionAST *clone(MemoryPool *pool) const = 0; + virtual ExpressionAST *asExpression() { return this; } }; class CPLUSPLUS_EXPORT DeclarationAST: public AST { public: - virtual DeclarationAST *asDeclaration() - { return this; } - - virtual DeclarationAST *clone(MemoryPool *pool) const = 0; -}; - -class CPLUSPLUS_EXPORT DeclarationListAST: public AST -{ -public: - DeclarationAST *declaration; - DeclarationListAST *next; - -public: - virtual DeclarationListAST *asDeclarationList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual DeclarationListAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); + virtual DeclarationAST *asDeclaration() { return this; } }; class CPLUSPLUS_EXPORT CoreDeclaratorAST: public AST { public: - virtual CoreDeclaratorAST *asCoreDeclarator() - { return this; } - - virtual CoreDeclaratorAST *clone(MemoryPool *pool) const = 0; + virtual CoreDeclaratorAST *asCoreDeclarator() { return this; } }; class CPLUSPLUS_EXPORT PostfixDeclaratorAST: public AST { public: - PostfixDeclaratorAST *next; - -public: - virtual PostfixDeclaratorAST *asPostfixDeclarator() - { return this; } - - virtual PostfixDeclaratorAST *clone(MemoryPool *pool) const = 0; + virtual PostfixDeclaratorAST *asPostfixDeclarator() { return this; } }; class CPLUSPLUS_EXPORT DeclaratorAST: public AST { public: - SpecifierAST *attributes; - PtrOperatorAST *ptr_operators; + SpecifierListAST *attribute_list; + PtrOperatorListAST *ptr_operator_list; CoreDeclaratorAST *core_declarator; - PostfixDeclaratorAST *postfix_declarators; - SpecifierAST *post_attributes; + PostfixDeclaratorListAST *postfix_declarator_list; + SpecifierListAST *post_attribute_list; unsigned equals_token; ExpressionAST *initializer; public: - virtual DeclaratorAST *asDeclarator() - { return this; } + virtual DeclaratorAST *asDeclarator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DeclaratorAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ExpressionListAST: public AST -{ -public: - unsigned comma_token; - ExpressionAST *expression; - ExpressionListAST *next; - -public: - virtual ExpressionListAST *asExpressionList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ExpressionListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -449,22 +392,19 @@ class CPLUSPLUS_EXPORT SimpleDeclarationAST: public DeclarationAST { public: unsigned qt_invokable_token; - SpecifierAST *decl_specifier_seq; - DeclaratorListAST *declarators; + SpecifierListAST *decl_specifier_list; + DeclaratorListAST *declarator_list; unsigned semicolon_token; public: List<Declaration *> *symbols; public: - virtual SimpleDeclarationAST *asSimpleDeclaration() - { return this; } + virtual SimpleDeclarationAST *asSimpleDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual SimpleDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -475,14 +415,11 @@ public: unsigned semicolon_token; public: - virtual EmptyDeclarationAST *asEmptyDeclaration() - { return this; } + virtual EmptyDeclarationAST *asEmptyDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual EmptyDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -495,14 +432,11 @@ public: unsigned colon_token; public: - virtual AccessDeclarationAST *asAccessDeclaration() - { return this; } + virtual AccessDeclarationAST *asAccessDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual AccessDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -519,14 +453,11 @@ public: unsigned semicolon_token; public: - virtual AsmDefinitionAST *asAsmDefinition() - { return this; } + virtual AsmDefinitionAST *asAsmDefinition() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual AsmDefinitionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -534,24 +465,19 @@ protected: class CPLUSPLUS_EXPORT BaseSpecifierAST: public AST { public: - unsigned comma_token; unsigned virtual_token; unsigned access_specifier_token; NameAST *name; - BaseSpecifierAST *next; public: // annotations BaseClass *symbol; public: - virtual BaseSpecifierAST *asBaseSpecifier() - { return this; } + virtual BaseSpecifierAST *asBaseSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual BaseSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -565,14 +491,11 @@ public: ExpressionAST *initializer; public: - virtual CompoundLiteralAST *asCompoundLiteral() - { return this; } + virtual CompoundLiteralAST *asCompoundLiteral() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CompoundLiteralAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -586,14 +509,11 @@ public: unsigned rparen_token; public: - virtual QtMethodAST *asQtMethod() - { return this; } + virtual QtMethodAST *asQtMethod() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual QtMethodAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -606,14 +526,11 @@ public: ExpressionAST *right_expression; public: - virtual BinaryExpressionAST *asBinaryExpression() - { return this; } + virtual BinaryExpressionAST *asBinaryExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual BinaryExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -627,14 +544,11 @@ public: ExpressionAST *expression; public: - virtual CastExpressionAST *asCastExpression() - { return this; } + virtual CastExpressionAST *asCastExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CastExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -643,26 +557,23 @@ class CPLUSPLUS_EXPORT ClassSpecifierAST: public SpecifierAST { public: unsigned classkey_token; - SpecifierAST *attributes; + SpecifierListAST *attribute_list; NameAST *name; unsigned colon_token; - BaseSpecifierAST *base_clause; + BaseSpecifierListAST *base_clause_list; unsigned lbrace_token; - DeclarationListAST *member_specifiers; + DeclarationListAST *member_specifier_list; unsigned rbrace_token; public: // annotations Class *symbol; public: - virtual ClassSpecifierAST *asClassSpecifier() - { return this; } + virtual ClassSpecifierAST *asClassSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ClassSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -676,33 +587,11 @@ public: StatementAST *statement; public: - virtual CaseStatementAST *asCaseStatement() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual CaseStatementAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT StatementListAST: public AST -{ -public: - StatementAST *statement; - StatementListAST *next; - -public: - virtual StatementListAST *asStatementList() - { return this; } + virtual CaseStatementAST *asCaseStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual StatementListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -711,21 +600,18 @@ class CPLUSPLUS_EXPORT CompoundStatementAST: public StatementAST { public: unsigned lbrace_token; - StatementListAST *statements; + StatementListAST *statement_list; unsigned rbrace_token; public: // annotations Block *symbol; public: - virtual CompoundStatementAST *asCompoundStatement() - { return this; } + virtual CompoundStatementAST *asCompoundStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CompoundStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -733,18 +619,15 @@ protected: class CPLUSPLUS_EXPORT ConditionAST: public ExpressionAST { public: - SpecifierAST *type_specifier; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; public: - virtual ConditionAST *asCondition() - { return this; } + virtual ConditionAST *asCondition() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ConditionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -759,14 +642,11 @@ public: ExpressionAST *right_expression; public: - virtual ConditionalExpressionAST *asConditionalExpression() - { return this; } + virtual ConditionalExpressionAST *asConditionalExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ConditionalExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -783,14 +663,11 @@ public: unsigned rparen_token; public: - virtual CppCastExpressionAST *asCppCastExpression() - { return this; } + virtual CppCastExpressionAST *asCppCastExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CppCastExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -799,17 +676,14 @@ class CPLUSPLUS_EXPORT CtorInitializerAST: public AST { public: unsigned colon_token; - MemInitializerAST *member_initializers; + MemInitializerListAST *member_initializer_list; public: - virtual CtorInitializerAST *asCtorInitializer() - { return this; } + virtual CtorInitializerAST *asCtorInitializer() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CtorInitializerAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -820,14 +694,11 @@ public: DeclarationAST *declaration; public: - virtual DeclarationStatementAST *asDeclarationStatement() - { return this; } + virtual DeclarationStatementAST *asDeclarationStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DeclarationStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -838,14 +709,11 @@ public: NameAST *name; public: - virtual DeclaratorIdAST *asDeclaratorId() - { return this; } + virtual DeclaratorIdAST *asDeclaratorId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DeclaratorIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -858,14 +726,11 @@ public: unsigned rparen_token; public: - virtual NestedDeclaratorAST *asNestedDeclarator() - { return this; } + virtual NestedDeclaratorAST *asNestedDeclarator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NestedDeclaratorAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -876,7 +741,7 @@ public: unsigned lparen_token; ParameterDeclarationClauseAST *parameters; unsigned rparen_token; - SpecifierAST *cv_qualifier_seq; + SpecifierListAST *cv_qualifier_list; ExceptionSpecificationAST *exception_specification; ExpressionAST *as_cpp_initializer; @@ -884,14 +749,11 @@ public: // annotations Function *symbol; public: - virtual FunctionDeclaratorAST *asFunctionDeclarator() - { return this; } + virtual FunctionDeclaratorAST *asFunctionDeclarator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual FunctionDeclaratorAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -904,34 +766,11 @@ public: unsigned rbracket_token; public: - virtual ArrayDeclaratorAST *asArrayDeclarator() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ArrayDeclaratorAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT DeclaratorListAST: public AST -{ -public: - unsigned comma_token; - DeclaratorAST *declarator; - DeclaratorListAST *next; - -public: - virtual DeclaratorListAST *asDeclaratorList() - { return this; } + virtual ArrayDeclaratorAST *asArrayDeclarator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DeclaratorListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -946,14 +785,11 @@ public: ExpressionAST *expression; public: - virtual DeleteExpressionAST *asDeleteExpression() - { return this; } + virtual DeleteExpressionAST *asDeleteExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DeleteExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -970,14 +806,11 @@ public: unsigned semicolon_token; public: - virtual DoStatementAST *asDoStatement() - { return this; } + virtual DoStatementAST *asDoStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DoStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -988,14 +821,11 @@ public: NameAST *name; public: - virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() - { return this; } + virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NamedTypeSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1007,14 +837,11 @@ public: NameAST *name; public: - virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() - { return this; } + virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ElaboratedTypeSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1025,18 +852,15 @@ public: unsigned enum_token; NameAST *name; unsigned lbrace_token; - EnumeratorAST *enumerators; + EnumeratorListAST *enumerator_list; unsigned rbrace_token; public: - virtual EnumSpecifierAST *asEnumSpecifier() - { return this; } + virtual EnumSpecifierAST *asEnumSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual EnumSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1044,21 +868,16 @@ protected: class CPLUSPLUS_EXPORT EnumeratorAST: public AST { public: - unsigned comma_token; unsigned identifier_token; unsigned equal_token; ExpressionAST *expression; - EnumeratorAST *next; public: - virtual EnumeratorAST *asEnumerator() - { return this; } + virtual EnumeratorAST *asEnumerator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual EnumeratorAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1066,19 +885,16 @@ protected: class CPLUSPLUS_EXPORT ExceptionDeclarationAST: public DeclarationAST { public: - SpecifierAST *type_specifier; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; unsigned dot_dot_dot_token; public: - virtual ExceptionDeclarationAST *asExceptionDeclaration() - { return this; } + virtual ExceptionDeclarationAST *asExceptionDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ExceptionDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1089,18 +905,15 @@ public: unsigned throw_token; unsigned lparen_token; unsigned dot_dot_dot_token; - ExpressionListAST *type_ids; + ExpressionListAST *type_id_list; unsigned rparen_token; public: - virtual ExceptionSpecificationAST *asExceptionSpecification() - { return this; } + virtual ExceptionSpecificationAST *asExceptionSpecification() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ExceptionSpecificationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1112,14 +925,11 @@ public: StatementAST *declaration; public: - virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() - { return this; } + virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ExpressionOrDeclarationStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1131,14 +941,11 @@ public: unsigned semicolon_token; public: - virtual ExpressionStatementAST *asExpressionStatement() - { return this; } + virtual ExpressionStatementAST *asExpressionStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ExpressionStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1147,7 +954,7 @@ class CPLUSPLUS_EXPORT FunctionDefinitionAST: public DeclarationAST { public: unsigned qt_invokable_token; - SpecifierAST *decl_specifier_seq; + SpecifierListAST *decl_specifier_list; DeclaratorAST *declarator; CtorInitializerAST *ctor_initializer; StatementAST *function_body; @@ -1156,14 +963,11 @@ public: // annotations Function *symbol; public: - virtual FunctionDefinitionAST *asFunctionDefinition() - { return this; } + virtual FunctionDefinitionAST *asFunctionDefinition() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual FunctionDefinitionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1174,7 +978,7 @@ public: unsigned foreach_token; unsigned lparen_token; // declaration - SpecifierAST *type_specifiers; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; // or an expression ExpressionAST *initializer; @@ -1187,14 +991,11 @@ public: // annotations Block *symbol; public: - virtual ForeachStatementAST *asForeachStatement() - { return this; } + virtual ForeachStatementAST *asForeachStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ForeachStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1215,14 +1016,11 @@ public: // annotations Block *symbol; public: - virtual ForStatementAST *asForStatement() - { return this; } + virtual ForStatementAST *asForStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ForStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1242,14 +1040,11 @@ public: // annotations Block *symbol; public: - virtual IfStatementAST *asIfStatement() - { return this; } + virtual IfStatementAST *asIfStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual IfStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1262,14 +1057,11 @@ public: unsigned rbrace_token; public: - virtual ArrayInitializerAST *asArrayInitializer() - { return this; } + virtual ArrayInitializerAST *asArrayInitializer() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ArrayInitializerAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1282,14 +1074,11 @@ public: StatementAST *statement; public: - virtual LabeledStatementAST *asLabeledStatement() - { return this; } + virtual LabeledStatementAST *asLabeledStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual LabeledStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1298,15 +1087,14 @@ class CPLUSPLUS_EXPORT LinkageBodyAST: public DeclarationAST { public: unsigned lbrace_token; - DeclarationListAST *declarations; + DeclarationListAST *declaration_list; unsigned rbrace_token; public: + virtual LinkageBodyAST *asLinkageBody() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual LinkageBodyAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1319,14 +1107,11 @@ public: DeclarationAST *declaration; public: - virtual LinkageSpecificationAST *asLinkageSpecification() - { return this; } + virtual LinkageSpecificationAST *asLinkageSpecification() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual LinkageSpecificationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1334,22 +1119,17 @@ protected: class CPLUSPLUS_EXPORT MemInitializerAST: public AST { public: - unsigned comma_token; NameAST *name; unsigned lparen_token; ExpressionAST *expression; unsigned rparen_token; - MemInitializerAST *next; public: - virtual MemInitializerAST *asMemInitializer() - { return this; } + virtual MemInitializerAST *asMemInitializer() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual MemInitializerAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1359,10 +1139,9 @@ class CPLUSPLUS_EXPORT NameAST: public ExpressionAST public: // annotations Name *name; - virtual NameAST *asName() { return this; } public: - virtual NameAST *clone(MemoryPool *pool) const = 0; + virtual NameAST *asName() { return this; } }; class CPLUSPLUS_EXPORT NestedNameSpecifierAST: public AST @@ -1370,17 +1149,13 @@ class CPLUSPLUS_EXPORT NestedNameSpecifierAST: public AST public: NameAST *class_or_namespace_name; unsigned scope_token; - NestedNameSpecifierAST *next; public: - virtual NestedNameSpecifierAST *asNestedNameSpecifier() - { return this; } + virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NestedNameSpecifierAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1389,18 +1164,15 @@ class CPLUSPLUS_EXPORT QualifiedNameAST: public NameAST { public: unsigned global_scope_token; - NestedNameSpecifierAST *nested_name_specifier; + NestedNameSpecifierListAST *nested_name_specifier_list; NameAST *unqualified_name; public: - virtual QualifiedNameAST *asQualifiedName() - { return this; } + virtual QualifiedNameAST *asQualifiedName() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual QualifiedNameAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1412,14 +1184,11 @@ public: OperatorAST *op; public: - virtual OperatorFunctionIdAST *asOperatorFunctionId() - { return this; } + virtual OperatorFunctionIdAST *asOperatorFunctionId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual OperatorFunctionIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1428,18 +1197,15 @@ class CPLUSPLUS_EXPORT ConversionFunctionIdAST: public NameAST { public: unsigned operator_token; - SpecifierAST *type_specifier; - PtrOperatorAST *ptr_operators; + SpecifierListAST *type_specifier_list; + PtrOperatorListAST *ptr_operator_list; public: - virtual ConversionFunctionIdAST *asConversionFunctionId() - { return this; } + virtual ConversionFunctionIdAST *asConversionFunctionId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ConversionFunctionIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1450,14 +1216,11 @@ public: unsigned identifier_token; public: - virtual SimpleNameAST *asSimpleName() - { return this; } + virtual SimpleNameAST *asSimpleName() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual SimpleNameAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1469,14 +1232,11 @@ public: unsigned identifier_token; public: - virtual DestructorNameAST *asDestructorName() - { return this; } + virtual DestructorNameAST *asDestructorName() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual DestructorNameAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1486,18 +1246,15 @@ class CPLUSPLUS_EXPORT TemplateIdAST: public NameAST public: unsigned identifier_token; unsigned less_token; - TemplateArgumentListAST *template_arguments; + TemplateArgumentListAST *template_argument_list; unsigned greater_token; public: - virtual TemplateIdAST *asTemplateId() - { return this; } + virtual TemplateIdAST *asTemplateId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TemplateIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1507,21 +1264,18 @@ class CPLUSPLUS_EXPORT NamespaceAST: public DeclarationAST public: unsigned namespace_token; unsigned identifier_token; - SpecifierAST *attributes; + SpecifierListAST *attribute_list; DeclarationAST *linkage_body; public: // annotations Namespace *symbol; public: - virtual NamespaceAST *asNamespace() - { return this; } + virtual NamespaceAST *asNamespace() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NamespaceAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1536,14 +1290,11 @@ public: unsigned semicolon_token; public: - virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() - { return this; } + virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NamespaceAliasDefinitionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1556,14 +1307,11 @@ public: unsigned rparen_token; public: - virtual NewPlacementAST *asNewPlacement() - { return this; } + virtual NewPlacementAST *asNewPlacement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewPlacementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1574,17 +1322,13 @@ public: unsigned lbracket_token; ExpressionAST *expression; unsigned rbracket_token; - NewArrayDeclaratorAST *next; public: - virtual NewArrayDeclaratorAST *asNewArrayDeclarator() - { return this; } + virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewArrayDeclaratorAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1605,14 +1349,11 @@ public: NewInitializerAST *new_initializer; public: - virtual NewExpressionAST *asNewExpression() - { return this; } + virtual NewExpressionAST *asNewExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1625,14 +1366,11 @@ public: unsigned rparen_token; public: - virtual NewInitializerAST *asNewInitializer() - { return this; } + virtual NewInitializerAST *asNewInitializer() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewInitializerAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1640,19 +1378,16 @@ protected: class CPLUSPLUS_EXPORT NewTypeIdAST: public AST { public: - SpecifierAST *type_specifier; - PtrOperatorAST *ptr_operators; - NewArrayDeclaratorAST *new_array_declarators; + SpecifierListAST *type_specifier_list; + PtrOperatorListAST *ptr_operator_list; + NewArrayDeclaratorListAST *new_array_declarator_list; public: - virtual NewTypeIdAST *asNewTypeId() - { return this; } + virtual NewTypeIdAST *asNewTypeId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NewTypeIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1665,14 +1400,11 @@ public: unsigned close_token; public: - virtual OperatorAST *asOperator() - { return this; } + virtual OperatorAST *asOperator() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual OperatorAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1680,7 +1412,7 @@ protected: class CPLUSPLUS_EXPORT ParameterDeclarationAST: public DeclarationAST { public: - SpecifierAST *type_specifier; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; unsigned equal_token; ExpressionAST *expression; @@ -1689,14 +1421,11 @@ public: // annotations Argument *symbol; public: - virtual ParameterDeclarationAST *asParameterDeclaration() - { return this; } + virtual ParameterDeclarationAST *asParameterDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ParameterDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1704,18 +1433,15 @@ protected: class CPLUSPLUS_EXPORT ParameterDeclarationClauseAST: public AST { public: - DeclarationListAST *parameter_declarations; + DeclarationListAST *parameter_declaration_list; unsigned dot_dot_dot_token; public: - virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() - { return this; } + virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ParameterDeclarationClauseAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1723,13 +1449,7 @@ protected: class CPLUSPLUS_EXPORT PostfixAST: public AST { public: - PostfixAST *next; - -public: - virtual PostfixAST *asPostfix() - { return this; } - - virtual PostfixAST *clone(MemoryPool *pool) const = 0; + virtual PostfixAST *asPostfix() { return this; } }; class CPLUSPLUS_EXPORT CallAST: public PostfixAST @@ -1740,14 +1460,11 @@ public: unsigned rparen_token; public: - virtual CallAST *asCall() - { return this; } + virtual CallAST *asCall() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CallAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1760,14 +1477,11 @@ public: unsigned rbracket_token; public: - virtual ArrayAccessAST *asArrayAccess() - { return this; } + virtual ArrayAccessAST *asArrayAccess() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ArrayAccessAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1778,14 +1492,11 @@ public: unsigned incr_decr_token; public: - virtual PostIncrDecrAST *asPostIncrDecr() - { return this; } + virtual PostIncrDecrAST *asPostIncrDecr() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual PostIncrDecrAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1798,14 +1509,11 @@ public: NameAST *member_name; public: - virtual MemberAccessAST *asMemberAccess() - { return this; } + virtual MemberAccessAST *asMemberAccess() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual MemberAccessAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1819,14 +1527,11 @@ public: unsigned rparen_token; public: - virtual TypeidExpressionAST *asTypeidExpression() - { return this; } + virtual TypeidExpressionAST *asTypeidExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypeidExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1841,14 +1546,11 @@ public: unsigned rparen_token; public: - virtual TypenameCallExpressionAST *asTypenameCallExpression() - { return this; } + virtual TypenameCallExpressionAST *asTypenameCallExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypenameCallExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1856,20 +1558,17 @@ protected: class CPLUSPLUS_EXPORT TypeConstructorCallAST: public ExpressionAST { public: - SpecifierAST *type_specifier; + SpecifierListAST *type_specifier_list; unsigned lparen_token; ExpressionListAST *expression_list; unsigned rparen_token; public: - virtual TypeConstructorCallAST *asTypeConstructorCall() - { return this; } + virtual TypeConstructorCallAST *asTypeConstructorCall() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypeConstructorCallAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1878,17 +1577,14 @@ class CPLUSPLUS_EXPORT PostfixExpressionAST: public ExpressionAST { public: ExpressionAST *base_expression; - PostfixAST *postfix_expressions; + PostfixListAST *postfix_expression_list; public: - virtual PostfixExpressionAST *asPostfixExpression() - { return this; } + virtual PostfixExpressionAST *asPostfixExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual PostfixExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1896,32 +1592,23 @@ protected: class CPLUSPLUS_EXPORT PtrOperatorAST: public AST { public: - PtrOperatorAST *next; - -public: - virtual PtrOperatorAST *asPtrOperator() - { return this; } - - virtual PtrOperatorAST *clone(MemoryPool *pool) const = 0; + virtual PtrOperatorAST *asPtrOperator() { return this; } }; class CPLUSPLUS_EXPORT PointerToMemberAST: public PtrOperatorAST { public: unsigned global_scope_token; - NestedNameSpecifierAST *nested_name_specifier; + NestedNameSpecifierListAST *nested_name_specifier_list; unsigned star_token; - SpecifierAST *cv_qualifier_seq; + SpecifierListAST *cv_qualifier_list; public: - virtual PointerToMemberAST *asPointerToMember() - { return this; } + virtual PointerToMemberAST *asPointerToMember() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual PointerToMemberAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1930,17 +1617,14 @@ class CPLUSPLUS_EXPORT PointerAST: public PtrOperatorAST { public: unsigned star_token; - SpecifierAST *cv_qualifier_seq; + SpecifierListAST *cv_qualifier_list; public: - virtual PointerAST *asPointer() - { return this; } + virtual PointerAST *asPointer() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual PointerAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1951,14 +1635,11 @@ public: unsigned amp_token; public: - virtual ReferenceAST *asReference() - { return this; } + virtual ReferenceAST *asReference() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ReferenceAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1970,14 +1651,11 @@ public: unsigned semicolon_token; public: - virtual BreakStatementAST *asBreakStatement() - { return this; } + virtual BreakStatementAST *asBreakStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual BreakStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -1989,14 +1667,11 @@ public: unsigned semicolon_token; public: - virtual ContinueStatementAST *asContinueStatement() - { return this; } + virtual ContinueStatementAST *asContinueStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ContinueStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2009,14 +1684,11 @@ public: unsigned semicolon_token; public: - virtual GotoStatementAST *asGotoStatement() - { return this; } + virtual GotoStatementAST *asGotoStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual GotoStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2029,14 +1701,11 @@ public: unsigned semicolon_token; public: - virtual ReturnStatementAST *asReturnStatement() - { return this; } + virtual ReturnStatementAST *asReturnStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ReturnStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2050,14 +1719,11 @@ public: unsigned rparen_token; public: - virtual SizeofExpressionAST *asSizeofExpression() - { return this; } + virtual SizeofExpressionAST *asSizeofExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual SizeofExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2068,14 +1734,11 @@ public: unsigned literal_token; public: - virtual NumericLiteralAST *asNumericLiteral() - { return this; } + virtual NumericLiteralAST *asNumericLiteral() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NumericLiteralAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2086,14 +1749,11 @@ public: unsigned literal_token; public: - virtual BoolLiteralAST *asBoolLiteral() - { return this; } + virtual BoolLiteralAST *asBoolLiteral() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual BoolLiteralAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2104,14 +1764,11 @@ public: unsigned this_token; public: - virtual ThisExpressionAST *asThisExpression() - { return this; } + virtual ThisExpressionAST *asThisExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ThisExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2124,14 +1781,11 @@ public: unsigned rparen_token; public: - virtual NestedExpressionAST *asNestedExpression() - { return this; } + virtual NestedExpressionAST *asNestedExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual NestedExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2143,14 +1797,11 @@ public: StringLiteralAST *next; public: - virtual StringLiteralAST *asStringLiteral() - { return this; } + virtual StringLiteralAST *asStringLiteral() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual StringLiteralAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2168,34 +1819,11 @@ public: // annotations Block *symbol; public: - virtual SwitchStatementAST *asSwitchStatement() - { return this; } + virtual SwitchStatementAST *asSwitchStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual SwitchStatementAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT TemplateArgumentListAST: public AST -{ -public: - unsigned comma_token; - ExpressionAST *template_argument; - TemplateArgumentListAST *next; - -public: - virtual TemplateArgumentListAST *asTemplateArgumentList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual TemplateArgumentListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2206,19 +1834,16 @@ public: unsigned export_token; unsigned template_token; unsigned less_token; - DeclarationListAST *template_parameters; + DeclarationListAST *template_parameter_list; unsigned greater_token; DeclarationAST *declaration; public: - virtual TemplateDeclarationAST *asTemplateDeclaration() - { return this; } + virtual TemplateDeclarationAST *asTemplateDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TemplateDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2230,14 +1855,11 @@ public: ExpressionAST *expression; public: - virtual ThrowExpressionAST *asThrowExpression() - { return this; } + virtual ThrowExpressionAST *asThrowExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ThrowExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2245,17 +1867,14 @@ protected: class CPLUSPLUS_EXPORT TranslationUnitAST: public AST { public: - DeclarationListAST *declarations; + DeclarationListAST *declaration_list; public: - virtual TranslationUnitAST *asTranslationUnit() - { return this; } + virtual TranslationUnitAST *asTranslationUnit() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TranslationUnitAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2265,17 +1884,14 @@ class CPLUSPLUS_EXPORT TryBlockStatementAST: public StatementAST public: unsigned try_token; StatementAST *statement; - CatchClauseAST *catch_clause_seq; + CatchClauseListAST *catch_clause_list; public: - virtual TryBlockStatementAST *asTryBlockStatement() - { return this; } + virtual TryBlockStatementAST *asTryBlockStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TryBlockStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2288,20 +1904,16 @@ public: ExceptionDeclarationAST *exception_declaration; unsigned rparen_token; StatementAST *statement; - CatchClauseAST *next; public: // annotations Block *symbol; public: - virtual CatchClauseAST *asCatchClause() - { return this; } + virtual CatchClauseAST *asCatchClause() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual CatchClauseAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2309,18 +1921,15 @@ protected: class CPLUSPLUS_EXPORT TypeIdAST: public ExpressionAST { public: - SpecifierAST *type_specifier; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; public: - virtual TypeIdAST *asTypeId() - { return this; } + virtual TypeIdAST *asTypeId() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypeIdAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2337,14 +1946,11 @@ public: // annotations Argument *symbol; public: - virtual TypenameTypeParameterAST *asTypenameTypeParameter() - { return this; } + virtual TypenameTypeParameterAST *asTypenameTypeParameter() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TypenameTypeParameterAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2354,7 +1960,7 @@ class CPLUSPLUS_EXPORT TemplateTypeParameterAST: public DeclarationAST public: unsigned template_token; unsigned less_token; - DeclarationListAST *template_parameters; + DeclarationListAST *template_parameter_list; unsigned greater_token; unsigned class_token; NameAST *name; @@ -2365,14 +1971,11 @@ public: Argument *symbol; public: - virtual TemplateTypeParameterAST *asTemplateTypeParameter() - { return this; } + virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual TemplateTypeParameterAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2384,14 +1987,11 @@ public: ExpressionAST *expression; public: - virtual UnaryExpressionAST *asUnaryExpression() - { return this; } + virtual UnaryExpressionAST *asUnaryExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual UnaryExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2408,14 +2008,11 @@ public: // annotations UsingDeclaration *symbol; public: - virtual UsingAST *asUsing() - { return this; } + virtual UsingAST *asUsing() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual UsingAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2432,14 +2029,11 @@ public: UsingNamespaceDirective *symbol; public: - virtual UsingDirectiveAST *asUsingDirective() - { return this; } + virtual UsingDirectiveAST *asUsingDirective() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual UsingDirectiveAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2457,36 +2051,11 @@ public: // annotations Block *symbol; public: - virtual WhileStatementAST *asWhileStatement() - { return this; } + virtual WhileStatementAST *asWhileStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual WhileStatementAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - - -// ObjC++ -class CPLUSPLUS_EXPORT IdentifierListAST: public AST -{ -public: - NameAST *name; - unsigned comma_token; - IdentifierListAST *next; - -public: - virtual IdentifierListAST *asIdentifierList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual IdentifierListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2494,23 +2063,20 @@ protected: class CPLUSPLUS_EXPORT ObjCClassForwardDeclarationAST: public DeclarationAST { public: - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned class_token; - IdentifierListAST *identifier_list; + ObjCIdentifierListAST *identifier_list; unsigned semicolon_token; public: // annotations List<ObjCForwardClassDeclaration *> *symbols; public: - virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() - { return this; } + virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCClassForwardDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2518,7 +2084,7 @@ protected: class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST { public: - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned interface_token; unsigned implementation_token; NameAST *class_name; @@ -2529,21 +2095,18 @@ public: NameAST *superclass; ObjCProtocolRefsAST *protocol_refs; ObjCInstanceVariablesDeclarationAST *inst_vars_decl; - DeclarationListAST *member_declarations; + DeclarationListAST *member_declaration_list; unsigned end_token; public: // annotations ObjCClass *symbol; public: - virtual ObjCClassDeclarationAST *asObjCClassDeclaration() - { return this; } + virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCClassDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2551,23 +2114,20 @@ protected: class CPLUSPLUS_EXPORT ObjCProtocolForwardDeclarationAST: public DeclarationAST { public: - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned protocol_token; - IdentifierListAST *identifier_list; + ObjCIdentifierListAST *identifier_list; unsigned semicolon_token; public: // annotations List<ObjCForwardProtocolDeclaration *> *symbols; public: - virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() - { return this; } + virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCProtocolForwardDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2575,25 +2135,22 @@ protected: class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST { public: - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned protocol_token; NameAST *name; ObjCProtocolRefsAST *protocol_refs; - DeclarationListAST *member_declarations; + DeclarationListAST *member_declaration_list; unsigned end_token; public: // annotations ObjCProtocol *symbol; public: - virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() - { return this; } + virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCProtocolDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2602,18 +2159,15 @@ class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST { public: unsigned less_token; - IdentifierListAST *identifier_list; + ObjCIdentifierListAST *identifier_list; unsigned greater_token; public: - virtual ObjCProtocolRefsAST *asObjCProtocolRefs() - { return this; } + virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCProtocolRefsAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2624,33 +2178,11 @@ public: ExpressionAST *parameter_value_expression; public: - virtual ObjCMessageArgumentAST *asObjCMessageArgument() - { return this; } + virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCMessageArgumentAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ObjCMessageArgumentListAST: public AST -{ -public: - ObjCMessageArgumentAST *arg; - ObjCMessageArgumentListAST *next; - -public: - virtual ObjCMessageArgumentListAST *asObjCMessageArgumentList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ObjCMessageArgumentListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2665,14 +2197,11 @@ public: unsigned rbracket_token; public: - virtual ObjCMessageExpressionAST *asObjCMessageExpression() - { return this; } + virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCMessageExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2686,14 +2215,11 @@ public: unsigned rparen_token; public: - virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() - { return this; } + virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCProtocolExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2707,14 +2233,11 @@ public: unsigned rparen_token; public: - virtual ObjCTypeNameAST *asObjCTypeName() - { return this; } + virtual ObjCTypeNameAST *asObjCTypeName() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCTypeNameAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2726,14 +2249,11 @@ public: ObjCTypeNameAST *type_name; public: - virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() - { return this; } + virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCEncodeExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2744,10 +2264,8 @@ public: // annotation Name *selector_name; public: - virtual ObjCSelectorAST *asObjCSelector() - { return this; } + virtual ObjCSelectorAST *asObjCSelector() { return this; } - virtual ObjCSelectorAST *clone(MemoryPool *pool) const = 0; }; class CPLUSPLUS_EXPORT ObjCSelectorWithoutArgumentsAST: public ObjCSelectorAST @@ -2756,14 +2274,11 @@ public: unsigned name_token; public: - virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() - { return this; } + virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSelectorWithoutArgumentsAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2775,33 +2290,11 @@ public: unsigned colon_token; public: - virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ObjCSelectorArgumentAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ObjCSelectorArgumentListAST: public AST -{ -public: - ObjCSelectorArgumentAST *argument; - ObjCSelectorArgumentListAST *next; - -public: - virtual ObjCSelectorArgumentListAST *asObjCSelectorArgumentList() - { return this; } + virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSelectorArgumentListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2809,17 +2302,14 @@ protected: class CPLUSPLUS_EXPORT ObjCSelectorWithArgumentsAST: public ObjCSelectorAST { public: - ObjCSelectorArgumentListAST *selector_arguments; + ObjCSelectorArgumentListAST *selector_argument_list; public: - virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() - { return this; } + virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSelectorWithArgumentsAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2833,14 +2323,11 @@ public: unsigned rparen_token; public: - virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() - { return this; } + virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSelectorExpressionAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2849,18 +2336,15 @@ class CPLUSPLUS_EXPORT ObjCInstanceVariablesDeclarationAST: public AST { public: unsigned lbrace_token; - DeclarationListAST *instance_variables; + DeclarationListAST *instance_variable_list; unsigned rbrace_token; public: - virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() - { return this; } + virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCInstanceVariablesDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2871,14 +2355,11 @@ public: unsigned visibility_token; public: - virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() - { return this; } + virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCVisibilityDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2891,34 +2372,11 @@ public: ObjCSelectorAST *method_selector; public: - virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ObjCPropertyAttributeAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ObjCPropertyAttributeListAST: public AST -{ -public: - ObjCPropertyAttributeAST *attr; - unsigned comma_token; - ObjCPropertyAttributeListAST *next; - -public: - virtual ObjCPropertyAttributeListAST *asObjCPropertyAttributeList() - { return this; } + virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCPropertyAttributeListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2926,22 +2384,22 @@ protected: class CPLUSPLUS_EXPORT ObjCPropertyDeclarationAST: public DeclarationAST { public: - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned property_token; unsigned lparen_token; - ObjCPropertyAttributeListAST *property_attributes; + ObjCPropertyAttributeListAST *property_attribute_list; unsigned rparen_token; DeclarationAST *simple_declaration; +public: // annotations + List<ObjCPropertyDeclaration *> *symbols; + public: - virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() - { return this; } + virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCPropertyDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2950,40 +2408,18 @@ class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public NameAST { public: ObjCTypeNameAST* type_name; - SpecifierAST *attributes; + SpecifierListAST *attribute_list; unsigned param_name_token; public: // annotations Argument *argument; public: - virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ObjCMessageArgumentDeclarationAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationListAST: public AST -{ -public: - ObjCMessageArgumentDeclarationAST *argument_declaration; - ObjCMessageArgumentDeclarationListAST *next; - -public: - virtual ObjCMessageArgumentDeclarationListAST *asObjCMessageArgumentDeclarationList() - { return this; } + virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCMessageArgumentDeclarationListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -2994,22 +2430,19 @@ public: unsigned method_type_token; ObjCTypeNameAST *type_name; ObjCSelectorAST *selector; - ObjCMessageArgumentDeclarationListAST *arguments; + ObjCMessageArgumentDeclarationListAST *argument_list; unsigned dot_dot_dot_token; - SpecifierAST *attributes; + SpecifierListAST *attribute_list; public: // annotations ObjCMethod *symbol; public: - virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() - { return this; } + virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCMethodPrototypeAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3022,14 +2455,11 @@ public: unsigned semicolon_token; public: - virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() - { return this; } + virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCMethodDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3042,34 +2472,11 @@ public: unsigned property_alias_identifier; public: - virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() - { return this; } + virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSynthesizedPropertyAST *clone(MemoryPool *pool) const; - -protected: - virtual void accept0(ASTVisitor *visitor); -}; - -class CPLUSPLUS_EXPORT ObjCSynthesizedPropertyListAST: public AST -{ -public: - ObjCSynthesizedPropertyAST *synthesized_property; - unsigned comma_token; - ObjCSynthesizedPropertyListAST *next; - -public: - virtual ObjCSynthesizedPropertyListAST *asObjCSynthesizedPropertyList() - { return this; } - - virtual unsigned firstToken() const; - virtual unsigned lastToken() const; - - virtual ObjCSynthesizedPropertyListAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3078,18 +2485,15 @@ class CPLUSPLUS_EXPORT ObjCSynthesizedPropertiesDeclarationAST: public Declarati { public: unsigned synthesized_token; - ObjCSynthesizedPropertyListAST *property_identifiers; + ObjCSynthesizedPropertyListAST *property_identifier_list; unsigned semicolon_token; public: - virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() - { return this; } + virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSynthesizedPropertiesDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3098,18 +2502,15 @@ class CPLUSPLUS_EXPORT ObjCDynamicPropertiesDeclarationAST: public DeclarationAS { public: unsigned dynamic_token; - IdentifierListAST *property_identifiers; + ObjCIdentifierListAST *property_identifier_list; unsigned semicolon_token; public: - virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() - { return this; } + virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCDynamicPropertiesDeclarationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3121,7 +2522,7 @@ public: unsigned lparen_token; // declaration - SpecifierAST *type_specifiers; + SpecifierListAST *type_specifier_list; DeclaratorAST *declarator; // or an expression ExpressionAST *initializer; @@ -3135,14 +2536,11 @@ public: // annotations Block *symbol; public: - virtual ObjCFastEnumerationAST *asObjCFastEnumeration() - { return this; } + virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCFastEnumerationAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; @@ -3157,14 +2555,11 @@ public: StatementAST *statement; public: - virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() - { return this; } + virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return this; } virtual unsigned firstToken() const; virtual unsigned lastToken() const; - virtual ObjCSynchronizedStatementAST *clone(MemoryPool *pool) const; - protected: virtual void accept0(ASTVisitor *visitor); }; diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp deleted file mode 100644 index 3c17829292..0000000000 --- a/src/shared/cplusplus/ASTClone.cpp +++ /dev/null @@ -1,1563 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "AST.h" -#include "ASTVisitor.h" - -using namespace CPlusPlus; - -SimpleSpecifierAST *SimpleSpecifierAST::clone(MemoryPool *pool) const -{ - SimpleSpecifierAST *ast = new (pool) SimpleSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy SimpleSpecifierAST - ast->specifier_token = specifier_token; - return ast; -} - -AttributeSpecifierAST *AttributeSpecifierAST::clone(MemoryPool *pool) const -{ - AttributeSpecifierAST *ast = new (pool) AttributeSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy AttributeSpecifierAST - ast->attribute_token = attribute_token; - ast->first_lparen_token = first_lparen_token; - ast->second_lparen_token = second_lparen_token; - if (attributes) ast->attributes = attributes->clone(pool); - ast->first_rparen_token = first_rparen_token; - ast->second_rparen_token = second_rparen_token; - return ast; -} - -AttributeAST *AttributeAST::clone(MemoryPool *pool) const -{ - AttributeAST *ast = new (pool) AttributeAST; - // copy AttributeAST - ast->identifier_token = identifier_token; - ast->lparen_token = lparen_token; - ast->tag_token = tag_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rparen_token = rparen_token; - if (next) ast->next = next->clone(pool); - ast->comma_token = comma_token; - return ast; -} - -TypeofSpecifierAST *TypeofSpecifierAST::clone(MemoryPool *pool) const -{ - TypeofSpecifierAST *ast = new (pool) TypeofSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy TypeofSpecifierAST - ast->typeof_token = typeof_token; - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -DeclarationListAST *DeclarationListAST::clone(MemoryPool *pool) const -{ - DeclarationListAST *ast = new (pool) DeclarationListAST; - // copy DeclarationListAST - if (declaration) ast->declaration = declaration->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -DeclaratorAST *DeclaratorAST::clone(MemoryPool *pool) const -{ - DeclaratorAST *ast = new (pool) DeclaratorAST; - // copy DeclaratorAST - if (attributes) ast->attributes = attributes->clone(pool); - if (ptr_operators) ast->ptr_operators = ptr_operators->clone(pool); - if (core_declarator) ast->core_declarator = core_declarator->clone(pool); - if (postfix_declarators) ast->postfix_declarators = postfix_declarators->clone(pool); - if (post_attributes) ast->post_attributes = post_attributes->clone(pool); - ast->equals_token = equals_token; - if (initializer) ast->initializer = initializer->clone(pool); - return ast; -} - -ExpressionListAST *ExpressionListAST::clone(MemoryPool *pool) const -{ - ExpressionListAST *ast = new (pool) ExpressionListAST; - // copy ExpressionListAST - ast->comma_token = comma_token; - if (expression) ast->expression = expression->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -SimpleDeclarationAST *SimpleDeclarationAST::clone(MemoryPool *pool) const -{ - SimpleDeclarationAST *ast = new (pool) SimpleDeclarationAST; - // copy DeclarationAST - // copy SimpleDeclarationAST - ast->qt_invokable_token = qt_invokable_token; - if (decl_specifier_seq) ast->decl_specifier_seq = decl_specifier_seq->clone(pool); - if (declarators) ast->declarators = declarators->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -EmptyDeclarationAST *EmptyDeclarationAST::clone(MemoryPool *pool) const -{ - EmptyDeclarationAST *ast = new (pool) EmptyDeclarationAST; - // copy DeclarationAST - // copy EmptyDeclarationAST - ast->semicolon_token = semicolon_token; - return ast; -} - -AccessDeclarationAST *AccessDeclarationAST::clone(MemoryPool *pool) const -{ - AccessDeclarationAST *ast = new (pool) AccessDeclarationAST; - // copy DeclarationAST - // copy AccessDeclarationAST - ast->access_specifier_token = access_specifier_token; - ast->slots_token = slots_token; - ast->colon_token = colon_token; - return ast; -} - -AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const -{ - AsmDefinitionAST *ast = new (pool) AsmDefinitionAST; - // copy DeclarationAST - // copy AsmDefinitionAST - ast->asm_token = asm_token; - ast->volatile_token = volatile_token; - ast->lparen_token = lparen_token; - ast->rparen_token = rparen_token; - ast->semicolon_token = semicolon_token; - return ast; -} - -BaseSpecifierAST *BaseSpecifierAST::clone(MemoryPool *pool) const -{ - BaseSpecifierAST *ast = new (pool) BaseSpecifierAST; - // copy BaseSpecifierAST - ast->comma_token = comma_token; - ast->virtual_token = virtual_token; - ast->access_specifier_token = access_specifier_token; - if (name) ast->name = name->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -CompoundLiteralAST *CompoundLiteralAST::clone(MemoryPool *pool) const -{ - CompoundLiteralAST *ast = new (pool) CompoundLiteralAST; - // copy ExpressionAST - // copy CompoundLiteralAST - ast->lparen_token = lparen_token; - if (type_id) ast->type_id = type_id->clone(pool); - ast->rparen_token = rparen_token; - if (initializer) ast->initializer = initializer->clone(pool); - return ast; -} - -QtMethodAST *QtMethodAST::clone(MemoryPool *pool) const -{ - QtMethodAST *ast = new (pool) QtMethodAST; - // copy ExpressionAST - // copy QtMethodAST - ast->method_token = method_token; - ast->lparen_token = lparen_token; - if (declarator) ast->declarator = declarator->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -BinaryExpressionAST *BinaryExpressionAST::clone(MemoryPool *pool) const -{ - BinaryExpressionAST *ast = new (pool) BinaryExpressionAST; - // copy ExpressionAST - // copy BinaryExpressionAST - if (left_expression) ast->left_expression = left_expression->clone(pool); - ast->binary_op_token = binary_op_token; - if (right_expression) ast->right_expression = right_expression->clone(pool); - return ast; -} - -CastExpressionAST *CastExpressionAST::clone(MemoryPool *pool) const -{ - CastExpressionAST *ast = new (pool) CastExpressionAST; - // copy ExpressionAST - // copy CastExpressionAST - ast->lparen_token = lparen_token; - if (type_id) ast->type_id = type_id->clone(pool); - ast->rparen_token = rparen_token; - if (expression) ast->expression = expression->clone(pool); - return ast; -} - -ClassSpecifierAST *ClassSpecifierAST::clone(MemoryPool *pool) const -{ - ClassSpecifierAST *ast = new (pool) ClassSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy ClassSpecifierAST - ast->classkey_token = classkey_token; - if (attributes) ast->attributes = attributes->clone(pool); - if (name) ast->name = name->clone(pool); - ast->colon_token = colon_token; - if (base_clause) ast->base_clause = base_clause->clone(pool); - ast->lbrace_token = lbrace_token; - if (member_specifiers) ast->member_specifiers = member_specifiers->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -CaseStatementAST *CaseStatementAST::clone(MemoryPool *pool) const -{ - CaseStatementAST *ast = new (pool) CaseStatementAST; - // copy StatementAST - // copy CaseStatementAST - ast->case_token = case_token; - if (expression) ast->expression = expression->clone(pool); - ast->colon_token = colon_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -StatementListAST *StatementListAST::clone(MemoryPool *pool) const -{ - StatementListAST *ast = new (pool) StatementListAST; - // copy StatementListAST - if (statement) ast->statement = statement->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -CompoundStatementAST *CompoundStatementAST::clone(MemoryPool *pool) const -{ - CompoundStatementAST *ast = new (pool) CompoundStatementAST; - // copy StatementAST - // copy CompoundStatementAST - ast->lbrace_token = lbrace_token; - if (statements) ast->statements = statements->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -ConditionAST *ConditionAST::clone(MemoryPool *pool) const -{ - ConditionAST *ast = new (pool) ConditionAST; - // copy ExpressionAST - // copy ConditionAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - return ast; -} - -ConditionalExpressionAST *ConditionalExpressionAST::clone(MemoryPool *pool) const -{ - ConditionalExpressionAST *ast = new (pool) ConditionalExpressionAST; - // copy ExpressionAST - // copy ConditionalExpressionAST - if (condition) ast->condition = condition->clone(pool); - ast->question_token = question_token; - if (left_expression) ast->left_expression = left_expression->clone(pool); - ast->colon_token = colon_token; - if (right_expression) ast->right_expression = right_expression->clone(pool); - return ast; -} - -CppCastExpressionAST *CppCastExpressionAST::clone(MemoryPool *pool) const -{ - CppCastExpressionAST *ast = new (pool) CppCastExpressionAST; - // copy ExpressionAST - // copy CppCastExpressionAST - ast->cast_token = cast_token; - ast->less_token = less_token; - if (type_id) ast->type_id = type_id->clone(pool); - ast->greater_token = greater_token; - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -CtorInitializerAST *CtorInitializerAST::clone(MemoryPool *pool) const -{ - CtorInitializerAST *ast = new (pool) CtorInitializerAST; - // copy CtorInitializerAST - ast->colon_token = colon_token; - if (member_initializers) ast->member_initializers = member_initializers->clone(pool); - return ast; -} - -DeclarationStatementAST *DeclarationStatementAST::clone(MemoryPool *pool) const -{ - DeclarationStatementAST *ast = new (pool) DeclarationStatementAST; - // copy StatementAST - // copy DeclarationStatementAST - if (declaration) ast->declaration = declaration->clone(pool); - return ast; -} - -DeclaratorIdAST *DeclaratorIdAST::clone(MemoryPool *pool) const -{ - DeclaratorIdAST *ast = new (pool) DeclaratorIdAST; - // copy CoreDeclaratorAST - // copy DeclaratorIdAST - if (name) ast->name = name->clone(pool); - return ast; -} - -NestedDeclaratorAST *NestedDeclaratorAST::clone(MemoryPool *pool) const -{ - NestedDeclaratorAST *ast = new (pool) NestedDeclaratorAST; - // copy CoreDeclaratorAST - // copy NestedDeclaratorAST - ast->lparen_token = lparen_token; - if (declarator) ast->declarator = declarator->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -FunctionDeclaratorAST *FunctionDeclaratorAST::clone(MemoryPool *pool) const -{ - FunctionDeclaratorAST *ast = new (pool) FunctionDeclaratorAST; - // copy PostfixDeclaratorAST - if (next) ast->next = next->clone(pool); - // copy FunctionDeclaratorAST - ast->lparen_token = lparen_token; - if (parameters) ast->parameters = parameters->clone(pool); - ast->rparen_token = rparen_token; - if (cv_qualifier_seq) ast->cv_qualifier_seq = cv_qualifier_seq->clone(pool); - if (exception_specification) ast->exception_specification = exception_specification->clone(pool); - if (as_cpp_initializer) ast->as_cpp_initializer = as_cpp_initializer->clone(pool); - return ast; -} - -ArrayDeclaratorAST *ArrayDeclaratorAST::clone(MemoryPool *pool) const -{ - ArrayDeclaratorAST *ast = new (pool) ArrayDeclaratorAST; - // copy PostfixDeclaratorAST - if (next) ast->next = next->clone(pool); - // copy ArrayDeclaratorAST - ast->lbracket_token = lbracket_token; - if (expression) ast->expression = expression->clone(pool); - ast->rbracket_token = rbracket_token; - return ast; -} - -DeclaratorListAST *DeclaratorListAST::clone(MemoryPool *pool) const -{ - DeclaratorListAST *ast = new (pool) DeclaratorListAST; - // copy DeclaratorListAST - ast->comma_token = comma_token; - if (declarator) ast->declarator = declarator->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -DeleteExpressionAST *DeleteExpressionAST::clone(MemoryPool *pool) const -{ - DeleteExpressionAST *ast = new (pool) DeleteExpressionAST; - // copy ExpressionAST - // copy DeleteExpressionAST - ast->scope_token = scope_token; - ast->delete_token = delete_token; - ast->lbracket_token = lbracket_token; - ast->rbracket_token = rbracket_token; - if (expression) ast->expression = expression->clone(pool); - return ast; -} - -DoStatementAST *DoStatementAST::clone(MemoryPool *pool) const -{ - DoStatementAST *ast = new (pool) DoStatementAST; - // copy StatementAST - // copy DoStatementAST - ast->do_token = do_token; - if (statement) ast->statement = statement->clone(pool); - ast->while_token = while_token; - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - ast->semicolon_token = semicolon_token; - return ast; -} - -NamedTypeSpecifierAST *NamedTypeSpecifierAST::clone(MemoryPool *pool) const -{ - NamedTypeSpecifierAST *ast = new (pool) NamedTypeSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy NamedTypeSpecifierAST - if (name) ast->name = name->clone(pool); - return ast; -} - -ElaboratedTypeSpecifierAST *ElaboratedTypeSpecifierAST::clone(MemoryPool *pool) const -{ - ElaboratedTypeSpecifierAST *ast = new (pool) ElaboratedTypeSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy ElaboratedTypeSpecifierAST - ast->classkey_token = classkey_token; - if (name) ast->name = name->clone(pool); - return ast; -} - -EnumSpecifierAST *EnumSpecifierAST::clone(MemoryPool *pool) const -{ - EnumSpecifierAST *ast = new (pool) EnumSpecifierAST; - // copy SpecifierAST - if (next) ast->next = next->clone(pool); - // copy EnumSpecifierAST - ast->enum_token = enum_token; - if (name) ast->name = name->clone(pool); - ast->lbrace_token = lbrace_token; - if (enumerators) ast->enumerators = enumerators->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -EnumeratorAST *EnumeratorAST::clone(MemoryPool *pool) const -{ - EnumeratorAST *ast = new (pool) EnumeratorAST; - // copy EnumeratorAST - ast->comma_token = comma_token; - ast->identifier_token = identifier_token; - ast->equal_token = equal_token; - if (expression) ast->expression = expression->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -ExceptionDeclarationAST *ExceptionDeclarationAST::clone(MemoryPool *pool) const -{ - ExceptionDeclarationAST *ast = new (pool) ExceptionDeclarationAST; - // copy DeclarationAST - // copy ExceptionDeclarationAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - ast->dot_dot_dot_token = dot_dot_dot_token; - return ast; -} - -ExceptionSpecificationAST *ExceptionSpecificationAST::clone(MemoryPool *pool) const -{ - ExceptionSpecificationAST *ast = new (pool) ExceptionSpecificationAST; - // copy ExceptionSpecificationAST - ast->throw_token = throw_token; - ast->lparen_token = lparen_token; - ast->dot_dot_dot_token = dot_dot_dot_token; - if (type_ids) ast->type_ids = type_ids->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -ExpressionOrDeclarationStatementAST *ExpressionOrDeclarationStatementAST::clone(MemoryPool *pool) const -{ - ExpressionOrDeclarationStatementAST *ast = new (pool) ExpressionOrDeclarationStatementAST; - // copy StatementAST - // copy ExpressionOrDeclarationStatementAST - if (expression) ast->expression = expression->clone(pool); - if (declaration) ast->declaration = declaration->clone(pool); - return ast; -} - -ExpressionStatementAST *ExpressionStatementAST::clone(MemoryPool *pool) const -{ - ExpressionStatementAST *ast = new (pool) ExpressionStatementAST; - // copy StatementAST - // copy ExpressionStatementAST - if (expression) ast->expression = expression->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -FunctionDefinitionAST *FunctionDefinitionAST::clone(MemoryPool *pool) const -{ - FunctionDefinitionAST *ast = new (pool) FunctionDefinitionAST; - // copy DeclarationAST - // copy FunctionDefinitionAST - ast->qt_invokable_token = qt_invokable_token; - if (decl_specifier_seq) ast->decl_specifier_seq = decl_specifier_seq->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - if (ctor_initializer) ast->ctor_initializer = ctor_initializer->clone(pool); - if (function_body) ast->function_body = function_body->clone(pool); - return ast; -} - -ForeachStatementAST *ForeachStatementAST::clone(MemoryPool *pool) const -{ - ForeachStatementAST *ast = new (pool) ForeachStatementAST; - // copy StatementAST - // copy ForeachStatementAST - ast->foreach_token = foreach_token; - ast->lparen_token = lparen_token; - if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - if (initializer) ast->initializer = initializer->clone(pool); - ast->comma_token = comma_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -ForStatementAST *ForStatementAST::clone(MemoryPool *pool) const -{ - ForStatementAST *ast = new (pool) ForStatementAST; - // copy StatementAST - // copy ForStatementAST - ast->for_token = for_token; - ast->lparen_token = lparen_token; - if (initializer) ast->initializer = initializer->clone(pool); - if (condition) ast->condition = condition->clone(pool); - ast->semicolon_token = semicolon_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -IfStatementAST *IfStatementAST::clone(MemoryPool *pool) const -{ - IfStatementAST *ast = new (pool) IfStatementAST; - // copy StatementAST - // copy IfStatementAST - ast->if_token = if_token; - ast->lparen_token = lparen_token; - if (condition) ast->condition = condition->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - ast->else_token = else_token; - if (else_statement) ast->else_statement = else_statement->clone(pool); - return ast; -} - -ArrayInitializerAST *ArrayInitializerAST::clone(MemoryPool *pool) const -{ - ArrayInitializerAST *ast = new (pool) ArrayInitializerAST; - // copy ExpressionAST - // copy ArrayInitializerAST - ast->lbrace_token = lbrace_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -LabeledStatementAST *LabeledStatementAST::clone(MemoryPool *pool) const -{ - LabeledStatementAST *ast = new (pool) LabeledStatementAST; - // copy StatementAST - // copy LabeledStatementAST - ast->label_token = label_token; - ast->colon_token = colon_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -LinkageBodyAST *LinkageBodyAST::clone(MemoryPool *pool) const -{ - LinkageBodyAST *ast = new (pool) LinkageBodyAST; - // copy DeclarationAST - // copy LinkageBodyAST - ast->lbrace_token = lbrace_token; - if (declarations) ast->declarations = declarations->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -LinkageSpecificationAST *LinkageSpecificationAST::clone(MemoryPool *pool) const -{ - LinkageSpecificationAST *ast = new (pool) LinkageSpecificationAST; - // copy DeclarationAST - // copy LinkageSpecificationAST - ast->extern_token = extern_token; - ast->extern_type_token = extern_type_token; - if (declaration) ast->declaration = declaration->clone(pool); - return ast; -} - -MemInitializerAST *MemInitializerAST::clone(MemoryPool *pool) const -{ - MemInitializerAST *ast = new (pool) MemInitializerAST; - // copy MemInitializerAST - ast->comma_token = comma_token; - if (name) ast->name = name->clone(pool); - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -NestedNameSpecifierAST *NestedNameSpecifierAST::clone(MemoryPool *pool) const -{ - NestedNameSpecifierAST *ast = new (pool) NestedNameSpecifierAST; - // copy NestedNameSpecifierAST - if (class_or_namespace_name) ast->class_or_namespace_name = class_or_namespace_name->clone(pool); - ast->scope_token = scope_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -QualifiedNameAST *QualifiedNameAST::clone(MemoryPool *pool) const -{ - QualifiedNameAST *ast = new (pool) QualifiedNameAST; - // copy ExpressionAST - // copy NameAST - // copy QualifiedNameAST - ast->global_scope_token = global_scope_token; - if (nested_name_specifier) ast->nested_name_specifier = nested_name_specifier->clone(pool); - if (unqualified_name) ast->unqualified_name = unqualified_name->clone(pool); - return ast; -} - -OperatorFunctionIdAST *OperatorFunctionIdAST::clone(MemoryPool *pool) const -{ - OperatorFunctionIdAST *ast = new (pool) OperatorFunctionIdAST; - // copy ExpressionAST - // copy NameAST - // copy OperatorFunctionIdAST - ast->operator_token = operator_token; - if (op) ast->op = op->clone(pool); - return ast; -} - -ConversionFunctionIdAST *ConversionFunctionIdAST::clone(MemoryPool *pool) const -{ - ConversionFunctionIdAST *ast = new (pool) ConversionFunctionIdAST; - // copy ExpressionAST - // copy NameAST - // copy ConversionFunctionIdAST - ast->operator_token = operator_token; - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (ptr_operators) ast->ptr_operators = ptr_operators->clone(pool); - return ast; -} - -SimpleNameAST *SimpleNameAST::clone(MemoryPool *pool) const -{ - SimpleNameAST *ast = new (pool) SimpleNameAST; - // copy ExpressionAST - // copy NameAST - // copy SimpleNameAST - ast->identifier_token = identifier_token; - return ast; -} - -DestructorNameAST *DestructorNameAST::clone(MemoryPool *pool) const -{ - DestructorNameAST *ast = new (pool) DestructorNameAST; - // copy ExpressionAST - // copy NameAST - // copy DestructorNameAST - ast->tilde_token = tilde_token; - ast->identifier_token = identifier_token; - return ast; -} - -TemplateIdAST *TemplateIdAST::clone(MemoryPool *pool) const -{ - TemplateIdAST *ast = new (pool) TemplateIdAST; - // copy ExpressionAST - // copy NameAST - // copy TemplateIdAST - ast->identifier_token = identifier_token; - ast->less_token = less_token; - if (template_arguments) ast->template_arguments = template_arguments->clone(pool); - ast->greater_token = greater_token; - return ast; -} - -NamespaceAST *NamespaceAST::clone(MemoryPool *pool) const -{ - NamespaceAST *ast = new (pool) NamespaceAST; - // copy DeclarationAST - // copy NamespaceAST - ast->namespace_token = namespace_token; - ast->identifier_token = identifier_token; - if (attributes) ast->attributes = attributes->clone(pool); - if (linkage_body) ast->linkage_body = linkage_body->clone(pool); - return ast; -} - -NamespaceAliasDefinitionAST *NamespaceAliasDefinitionAST::clone(MemoryPool *pool) const -{ - NamespaceAliasDefinitionAST *ast = new (pool) NamespaceAliasDefinitionAST; - // copy DeclarationAST - // copy NamespaceAliasDefinitionAST - ast->namespace_token = namespace_token; - ast->namespace_name_token = namespace_name_token; - ast->equal_token = equal_token; - if (name) ast->name = name->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -NewPlacementAST *NewPlacementAST::clone(MemoryPool *pool) const -{ - NewPlacementAST *ast = new (pool) NewPlacementAST; - // copy NewPlacementAST - ast->lparen_token = lparen_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -NewArrayDeclaratorAST *NewArrayDeclaratorAST::clone(MemoryPool *pool) const -{ - NewArrayDeclaratorAST *ast = new (pool) NewArrayDeclaratorAST; - // copy NewArrayDeclaratorAST - ast->lbracket_token = lbracket_token; - if (expression) ast->expression = expression->clone(pool); - ast->rbracket_token = rbracket_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const -{ - NewExpressionAST *ast = new (pool) NewExpressionAST; - // copy ExpressionAST - // copy NewExpressionAST - ast->scope_token = scope_token; - ast->new_token = new_token; - if (new_placement) ast->new_placement = new_placement->clone(pool); - ast->lparen_token = lparen_token; - if (type_id) ast->type_id = type_id->clone(pool); - ast->rparen_token = rparen_token; - if (new_type_id) ast->new_type_id = new_type_id->clone(pool); - if (new_initializer) ast->new_initializer = new_initializer->clone(pool); - return ast; -} - -NewInitializerAST *NewInitializerAST::clone(MemoryPool *pool) const -{ - NewInitializerAST *ast = new (pool) NewInitializerAST; - // copy NewInitializerAST - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const -{ - NewTypeIdAST *ast = new (pool) NewTypeIdAST; - // copy NewTypeIdAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (ptr_operators) ast->ptr_operators = ptr_operators->clone(pool); - if (new_array_declarators) ast->new_array_declarators = new_array_declarators->clone(pool); - return ast; -} - -OperatorAST *OperatorAST::clone(MemoryPool *pool) const -{ - OperatorAST *ast = new (pool) OperatorAST; - // copy OperatorAST - ast->op_token = op_token; - ast->open_token = open_token; - ast->close_token = close_token; - return ast; -} - -ParameterDeclarationAST *ParameterDeclarationAST::clone(MemoryPool *pool) const -{ - ParameterDeclarationAST *ast = new (pool) ParameterDeclarationAST; - // copy DeclarationAST - // copy ParameterDeclarationAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - ast->equal_token = equal_token; - if (expression) ast->expression = expression->clone(pool); - return ast; -} - -ParameterDeclarationClauseAST *ParameterDeclarationClauseAST::clone(MemoryPool *pool) const -{ - ParameterDeclarationClauseAST *ast = new (pool) ParameterDeclarationClauseAST; - // copy ParameterDeclarationClauseAST - if (parameter_declarations) ast->parameter_declarations = parameter_declarations->clone(pool); - ast->dot_dot_dot_token = dot_dot_dot_token; - return ast; -} - -CallAST *CallAST::clone(MemoryPool *pool) const -{ - CallAST *ast = new (pool) CallAST; - // copy PostfixAST - if (next) ast->next = next->clone(pool); - // copy CallAST - ast->lparen_token = lparen_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -ArrayAccessAST *ArrayAccessAST::clone(MemoryPool *pool) const -{ - ArrayAccessAST *ast = new (pool) ArrayAccessAST; - // copy PostfixAST - if (next) ast->next = next->clone(pool); - // copy ArrayAccessAST - ast->lbracket_token = lbracket_token; - if (expression) ast->expression = expression->clone(pool); - ast->rbracket_token = rbracket_token; - return ast; -} - -PostIncrDecrAST *PostIncrDecrAST::clone(MemoryPool *pool) const -{ - PostIncrDecrAST *ast = new (pool) PostIncrDecrAST; - // copy PostfixAST - if (next) ast->next = next->clone(pool); - // copy PostIncrDecrAST - ast->incr_decr_token = incr_decr_token; - return ast; -} - -MemberAccessAST *MemberAccessAST::clone(MemoryPool *pool) const -{ - MemberAccessAST *ast = new (pool) MemberAccessAST; - // copy PostfixAST - if (next) ast->next = next->clone(pool); - // copy MemberAccessAST - ast->access_token = access_token; - ast->template_token = template_token; - if (member_name) ast->member_name = member_name->clone(pool); - return ast; -} - -TypeidExpressionAST *TypeidExpressionAST::clone(MemoryPool *pool) const -{ - TypeidExpressionAST *ast = new (pool) TypeidExpressionAST; - // copy ExpressionAST - // copy TypeidExpressionAST - ast->typeid_token = typeid_token; - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -TypenameCallExpressionAST *TypenameCallExpressionAST::clone(MemoryPool *pool) const -{ - TypenameCallExpressionAST *ast = new (pool) TypenameCallExpressionAST; - // copy ExpressionAST - // copy TypenameCallExpressionAST - ast->typename_token = typename_token; - if (name) ast->name = name->clone(pool); - ast->lparen_token = lparen_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -TypeConstructorCallAST *TypeConstructorCallAST::clone(MemoryPool *pool) const -{ - TypeConstructorCallAST *ast = new (pool) TypeConstructorCallAST; - // copy ExpressionAST - // copy TypeConstructorCallAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - ast->lparen_token = lparen_token; - if (expression_list) ast->expression_list = expression_list->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -PostfixExpressionAST *PostfixExpressionAST::clone(MemoryPool *pool) const -{ - PostfixExpressionAST *ast = new (pool) PostfixExpressionAST; - // copy ExpressionAST - // copy PostfixExpressionAST - if (base_expression) ast->base_expression = base_expression->clone(pool); - if (postfix_expressions) ast->postfix_expressions = postfix_expressions->clone(pool); - return ast; -} - -PointerToMemberAST *PointerToMemberAST::clone(MemoryPool *pool) const -{ - PointerToMemberAST *ast = new (pool) PointerToMemberAST; - // copy PtrOperatorAST - if (next) ast->next = next->clone(pool); - // copy PointerToMemberAST - ast->global_scope_token = global_scope_token; - if (nested_name_specifier) ast->nested_name_specifier = nested_name_specifier->clone(pool); - ast->star_token = star_token; - if (cv_qualifier_seq) ast->cv_qualifier_seq = cv_qualifier_seq->clone(pool); - return ast; -} - -PointerAST *PointerAST::clone(MemoryPool *pool) const -{ - PointerAST *ast = new (pool) PointerAST; - // copy PtrOperatorAST - if (next) ast->next = next->clone(pool); - // copy PointerAST - ast->star_token = star_token; - if (cv_qualifier_seq) ast->cv_qualifier_seq = cv_qualifier_seq->clone(pool); - return ast; -} - -ReferenceAST *ReferenceAST::clone(MemoryPool *pool) const -{ - ReferenceAST *ast = new (pool) ReferenceAST; - // copy PtrOperatorAST - if (next) ast->next = next->clone(pool); - // copy ReferenceAST - ast->amp_token = amp_token; - return ast; -} - -BreakStatementAST *BreakStatementAST::clone(MemoryPool *pool) const -{ - BreakStatementAST *ast = new (pool) BreakStatementAST; - // copy StatementAST - // copy BreakStatementAST - ast->break_token = break_token; - ast->semicolon_token = semicolon_token; - return ast; -} - -ContinueStatementAST *ContinueStatementAST::clone(MemoryPool *pool) const -{ - ContinueStatementAST *ast = new (pool) ContinueStatementAST; - // copy StatementAST - // copy ContinueStatementAST - ast->continue_token = continue_token; - ast->semicolon_token = semicolon_token; - return ast; -} - -GotoStatementAST *GotoStatementAST::clone(MemoryPool *pool) const -{ - GotoStatementAST *ast = new (pool) GotoStatementAST; - // copy StatementAST - // copy GotoStatementAST - ast->goto_token = goto_token; - ast->identifier_token = identifier_token; - ast->semicolon_token = semicolon_token; - return ast; -} - -ReturnStatementAST *ReturnStatementAST::clone(MemoryPool *pool) const -{ - ReturnStatementAST *ast = new (pool) ReturnStatementAST; - // copy StatementAST - // copy ReturnStatementAST - ast->return_token = return_token; - if (expression) ast->expression = expression->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -SizeofExpressionAST *SizeofExpressionAST::clone(MemoryPool *pool) const -{ - SizeofExpressionAST *ast = new (pool) SizeofExpressionAST; - // copy ExpressionAST - // copy SizeofExpressionAST - ast->sizeof_token = sizeof_token; - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -NumericLiteralAST *NumericLiteralAST::clone(MemoryPool *pool) const -{ - NumericLiteralAST *ast = new (pool) NumericLiteralAST; - // copy ExpressionAST - // copy NumericLiteralAST - ast->literal_token = literal_token; - return ast; -} - -BoolLiteralAST *BoolLiteralAST::clone(MemoryPool *pool) const -{ - BoolLiteralAST *ast = new (pool) BoolLiteralAST; - // copy ExpressionAST - // copy BoolLiteralAST - ast->literal_token = literal_token; - return ast; -} - -ThisExpressionAST *ThisExpressionAST::clone(MemoryPool *pool) const -{ - ThisExpressionAST *ast = new (pool) ThisExpressionAST; - // copy ExpressionAST - // copy ThisExpressionAST - ast->this_token = this_token; - return ast; -} - -NestedExpressionAST *NestedExpressionAST::clone(MemoryPool *pool) const -{ - NestedExpressionAST *ast = new (pool) NestedExpressionAST; - // copy ExpressionAST - // copy NestedExpressionAST - ast->lparen_token = lparen_token; - if (expression) ast->expression = expression->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -StringLiteralAST *StringLiteralAST::clone(MemoryPool *pool) const -{ - StringLiteralAST *ast = new (pool) StringLiteralAST; - // copy ExpressionAST - // copy StringLiteralAST - ast->literal_token = literal_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -SwitchStatementAST *SwitchStatementAST::clone(MemoryPool *pool) const -{ - SwitchStatementAST *ast = new (pool) SwitchStatementAST; - // copy StatementAST - // copy SwitchStatementAST - ast->switch_token = switch_token; - ast->lparen_token = lparen_token; - if (condition) ast->condition = condition->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -TemplateArgumentListAST *TemplateArgumentListAST::clone(MemoryPool *pool) const -{ - TemplateArgumentListAST *ast = new (pool) TemplateArgumentListAST; - // copy TemplateArgumentListAST - ast->comma_token = comma_token; - if (template_argument) ast->template_argument = template_argument->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -TemplateDeclarationAST *TemplateDeclarationAST::clone(MemoryPool *pool) const -{ - TemplateDeclarationAST *ast = new (pool) TemplateDeclarationAST; - // copy DeclarationAST - // copy TemplateDeclarationAST - ast->export_token = export_token; - ast->template_token = template_token; - ast->less_token = less_token; - if (template_parameters) ast->template_parameters = template_parameters->clone(pool); - ast->greater_token = greater_token; - if (declaration) ast->declaration = declaration->clone(pool); - return ast; -} - -ThrowExpressionAST *ThrowExpressionAST::clone(MemoryPool *pool) const -{ - ThrowExpressionAST *ast = new (pool) ThrowExpressionAST; - // copy ExpressionAST - // copy ThrowExpressionAST - ast->throw_token = throw_token; - if (expression) ast->expression = expression->clone(pool); - return ast; -} - -TranslationUnitAST *TranslationUnitAST::clone(MemoryPool *pool) const -{ - TranslationUnitAST *ast = new (pool) TranslationUnitAST; - // copy TranslationUnitAST - if (declarations) ast->declarations = declarations->clone(pool); - return ast; -} - -TryBlockStatementAST *TryBlockStatementAST::clone(MemoryPool *pool) const -{ - TryBlockStatementAST *ast = new (pool) TryBlockStatementAST; - // copy StatementAST - // copy TryBlockStatementAST - ast->try_token = try_token; - if (statement) ast->statement = statement->clone(pool); - if (catch_clause_seq) ast->catch_clause_seq = catch_clause_seq->clone(pool); - return ast; -} - -CatchClauseAST *CatchClauseAST::clone(MemoryPool *pool) const -{ - CatchClauseAST *ast = new (pool) CatchClauseAST; - // copy StatementAST - // copy CatchClauseAST - ast->catch_token = catch_token; - ast->lparen_token = lparen_token; - if (exception_declaration) ast->exception_declaration = exception_declaration->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -TypeIdAST *TypeIdAST::clone(MemoryPool *pool) const -{ - TypeIdAST *ast = new (pool) TypeIdAST; - // copy ExpressionAST - // copy TypeIdAST - if (type_specifier) ast->type_specifier = type_specifier->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - return ast; -} - -TypenameTypeParameterAST *TypenameTypeParameterAST::clone(MemoryPool *pool) const -{ - TypenameTypeParameterAST *ast = new (pool) TypenameTypeParameterAST; - // copy DeclarationAST - // copy TypenameTypeParameterAST - ast->classkey_token = classkey_token; - if (name) ast->name = name->clone(pool); - ast->equal_token = equal_token; - if (type_id) ast->type_id = type_id->clone(pool); - return ast; -} - -TemplateTypeParameterAST *TemplateTypeParameterAST::clone(MemoryPool *pool) const -{ - TemplateTypeParameterAST *ast = new (pool) TemplateTypeParameterAST; - // copy DeclarationAST - // copy TemplateTypeParameterAST - ast->template_token = template_token; - ast->less_token = less_token; - if (template_parameters) ast->template_parameters = template_parameters->clone(pool); - ast->greater_token = greater_token; - ast->class_token = class_token; - if (name) ast->name = name->clone(pool); - ast->equal_token = equal_token; - if (type_id) ast->type_id = type_id->clone(pool); - return ast; -} - -UnaryExpressionAST *UnaryExpressionAST::clone(MemoryPool *pool) const -{ - UnaryExpressionAST *ast = new (pool) UnaryExpressionAST; - // copy ExpressionAST - // copy UnaryExpressionAST - ast->unary_op_token = unary_op_token; - if (expression) ast->expression = expression->clone(pool); - return ast; -} - -UsingAST *UsingAST::clone(MemoryPool *pool) const -{ - UsingAST *ast = new (pool) UsingAST; - // copy DeclarationAST - // copy UsingAST - ast->using_token = using_token; - ast->typename_token = typename_token; - if (name) ast->name = name->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -UsingDirectiveAST *UsingDirectiveAST::clone(MemoryPool *pool) const -{ - UsingDirectiveAST *ast = new (pool) UsingDirectiveAST; - // copy DeclarationAST - // copy UsingDirectiveAST - ast->using_token = using_token; - ast->namespace_token = namespace_token; - if (name) ast->name = name->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -WhileStatementAST *WhileStatementAST::clone(MemoryPool *pool) const -{ - WhileStatementAST *ast = new (pool) WhileStatementAST; - // copy StatementAST - // copy WhileStatementAST - ast->while_token = while_token; - ast->lparen_token = lparen_token; - if (condition) ast->condition = condition->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} - -IdentifierListAST *IdentifierListAST::clone(MemoryPool *pool) const -{ - IdentifierListAST *ast = new (pool) IdentifierListAST; - // copy IdentifierListAST - if (name) ast->name = name->clone(pool); - ast->comma_token = comma_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCClassForwardDeclarationAST *ObjCClassForwardDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCClassForwardDeclarationAST *ast = new (pool) ObjCClassForwardDeclarationAST; - // copy DeclarationAST - // copy ObjCClassForwardDeclarationAST - if (attributes) ast->attributes = attributes->clone(pool); - ast->class_token = class_token; - if (identifier_list) ast->identifier_list = identifier_list->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCClassDeclarationAST *ast = new (pool) ObjCClassDeclarationAST; - // copy DeclarationAST - // copy ObjCClassDeclarationAST - if (attributes) ast->attributes = attributes->clone(pool); - ast->interface_token = interface_token; - ast->implementation_token = implementation_token; - if (class_name) ast->class_name = class_name->clone(pool); - ast->lparen_token = lparen_token; - if (category_name) ast->category_name = category_name->clone(pool); - ast->rparen_token = rparen_token; - ast->colon_token = colon_token; - if (superclass) ast->superclass = superclass->clone(pool); - if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool); - if (inst_vars_decl) ast->inst_vars_decl = inst_vars_decl->clone(pool); - if (member_declarations) ast->member_declarations = member_declarations->clone(pool); - ast->end_token = end_token; - return ast; -} - -ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCProtocolForwardDeclarationAST *ast = new (pool) ObjCProtocolForwardDeclarationAST; - // copy DeclarationAST - // copy ObjCProtocolForwardDeclarationAST - if (attributes) ast->attributes = attributes->clone(pool); - ast->protocol_token = protocol_token; - if (identifier_list) ast->identifier_list = identifier_list->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCProtocolDeclarationAST *ast = new (pool) ObjCProtocolDeclarationAST; - // copy DeclarationAST - // copy ObjCProtocolDeclarationAST - if (attributes) ast->attributes = attributes->clone(pool); - ast->protocol_token = protocol_token; - if (name) ast->name = name->clone(pool); - if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool); - if (member_declarations) ast->member_declarations = member_declarations->clone(pool); - ast->end_token = end_token; - return ast; -} - -ObjCProtocolRefsAST *ObjCProtocolRefsAST::clone(MemoryPool *pool) const -{ - ObjCProtocolRefsAST *ast = new (pool) ObjCProtocolRefsAST; - // copy ObjCProtocolRefsAST - ast->less_token = less_token; - if (identifier_list) ast->identifier_list = identifier_list->clone(pool); - ast->greater_token = greater_token; - return ast; -} - -ObjCMessageArgumentAST *ObjCMessageArgumentAST::clone(MemoryPool *pool) const -{ - ObjCMessageArgumentAST *ast = new (pool) ObjCMessageArgumentAST; - // copy ObjCMessageArgumentAST - if (parameter_value_expression) ast->parameter_value_expression = parameter_value_expression->clone(pool); - return ast; -} - -ObjCMessageArgumentListAST *ObjCMessageArgumentListAST::clone(MemoryPool *pool) const -{ - ObjCMessageArgumentListAST *ast = new (pool) ObjCMessageArgumentListAST; - // copy ObjCMessageArgumentListAST - if (arg) ast->arg = arg->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) const -{ - ObjCMessageExpressionAST *ast = new (pool) ObjCMessageExpressionAST; - // copy ExpressionAST - // copy ObjCMessageExpressionAST - ast->lbracket_token = lbracket_token; - if (receiver_expression) ast->receiver_expression = receiver_expression->clone(pool); - if (selector) ast->selector = selector->clone(pool); - if (argument_list) ast->argument_list = argument_list->clone(pool); - ast->rbracket_token = rbracket_token; - return ast; -} - -ObjCProtocolExpressionAST *ObjCProtocolExpressionAST::clone(MemoryPool *pool) const -{ - ObjCProtocolExpressionAST *ast = new (pool) ObjCProtocolExpressionAST; - // copy ExpressionAST - // copy ObjCProtocolExpressionAST - ast->protocol_token = protocol_token; - ast->lparen_token = lparen_token; - ast->identifier_token = identifier_token; - ast->rparen_token = rparen_token; - return ast; -} - -ObjCTypeNameAST *ObjCTypeNameAST::clone(MemoryPool *pool) const -{ - ObjCTypeNameAST *ast = new (pool) ObjCTypeNameAST; - // copy ObjCTypeNameAST - ast->lparen_token = lparen_token; - if (type_id) ast->type_id = type_id->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const -{ - ObjCEncodeExpressionAST *ast = new (pool) ObjCEncodeExpressionAST; - // copy ExpressionAST - // copy ObjCEncodeExpressionAST - ast->encode_token = encode_token; - if (type_name) ast->type_name = type_name->clone(pool); - return ast; -} - -ObjCSelectorWithoutArgumentsAST *ObjCSelectorWithoutArgumentsAST::clone(MemoryPool *pool) const -{ - ObjCSelectorWithoutArgumentsAST *ast = new (pool) ObjCSelectorWithoutArgumentsAST; - // copy ObjCSelectorAST - // copy ObjCSelectorWithoutArgumentsAST - ast->name_token = name_token; - return ast; -} - -ObjCSelectorArgumentAST *ObjCSelectorArgumentAST::clone(MemoryPool *pool) const -{ - ObjCSelectorArgumentAST *ast = new (pool) ObjCSelectorArgumentAST; - // copy ObjCSelectorArgumentAST - ast->name_token = name_token; - ast->colon_token = colon_token; - return ast; -} - -ObjCSelectorArgumentListAST *ObjCSelectorArgumentListAST::clone(MemoryPool *pool) const -{ - ObjCSelectorArgumentListAST *ast = new (pool) ObjCSelectorArgumentListAST; - // copy ObjCSelectorArgumentListAST - if (argument) ast->argument = argument->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCSelectorWithArgumentsAST *ObjCSelectorWithArgumentsAST::clone(MemoryPool *pool) const -{ - ObjCSelectorWithArgumentsAST *ast = new (pool) ObjCSelectorWithArgumentsAST; - // copy ObjCSelectorAST - // copy ObjCSelectorWithArgumentsAST - if (selector_arguments) ast->selector_arguments = selector_arguments->clone(pool); - return ast; -} - -ObjCSelectorExpressionAST *ObjCSelectorExpressionAST::clone(MemoryPool *pool) const -{ - ObjCSelectorExpressionAST *ast = new (pool) ObjCSelectorExpressionAST; - // copy ExpressionAST - // copy ObjCSelectorExpressionAST - ast->selector_token = selector_token; - ast->lparen_token = lparen_token; - if (selector) ast->selector = selector->clone(pool); - ast->rparen_token = rparen_token; - return ast; -} - -ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCInstanceVariablesDeclarationAST *ast = new (pool) ObjCInstanceVariablesDeclarationAST; - // copy ObjCInstanceVariablesDeclarationAST - ast->lbrace_token = lbrace_token; - if (instance_variables) ast->instance_variables = instance_variables->clone(pool); - ast->rbrace_token = rbrace_token; - return ast; -} - -ObjCVisibilityDeclarationAST *ObjCVisibilityDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCVisibilityDeclarationAST *ast = new (pool) ObjCVisibilityDeclarationAST; - // copy DeclarationAST - // copy ObjCVisibilityDeclarationAST - ast->visibility_token = visibility_token; - return ast; -} - -ObjCPropertyAttributeAST *ObjCPropertyAttributeAST::clone(MemoryPool *pool) const -{ - ObjCPropertyAttributeAST *ast = new (pool) ObjCPropertyAttributeAST; - // copy ObjCPropertyAttributeAST - ast->attribute_identifier_token = attribute_identifier_token; - ast->equals_token = equals_token; - if (method_selector) ast->method_selector = method_selector->clone(pool); - return ast; -} - -ObjCPropertyAttributeListAST *ObjCPropertyAttributeListAST::clone(MemoryPool *pool) const -{ - ObjCPropertyAttributeListAST *ast = new (pool) ObjCPropertyAttributeListAST; - // copy ObjCPropertyAttributeListAST - if (attr) ast->attr = attr->clone(pool); - ast->comma_token = comma_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCPropertyDeclarationAST *ast = new (pool) ObjCPropertyDeclarationAST; - // copy DeclarationAST - // copy ObjCPropertyDeclarationAST - if (attributes) ast->attributes = attributes->clone(pool); - ast->property_token = property_token; - ast->lparen_token = lparen_token; - if (property_attributes) ast->property_attributes = property_attributes->clone(pool); - ast->rparen_token = rparen_token; - if (simple_declaration) ast->simple_declaration = simple_declaration->clone(pool); - return ast; -} - -ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCMessageArgumentDeclarationAST *ast = new (pool) ObjCMessageArgumentDeclarationAST; - // copy ExpressionAST - // copy NameAST - // copy ObjCMessageArgumentDeclarationAST - if (type_name) ast->type_name = type_name->clone(pool); - if (attributes) ast->attributes = attributes->clone(pool); - ast->param_name_token = param_name_token; - return ast; -} - -ObjCMessageArgumentDeclarationListAST *ObjCMessageArgumentDeclarationListAST::clone(MemoryPool *pool) const -{ - ObjCMessageArgumentDeclarationListAST *ast = new (pool) ObjCMessageArgumentDeclarationListAST; - // copy ObjCMessageArgumentDeclarationListAST - if (argument_declaration) ast->argument_declaration = argument_declaration->clone(pool); - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const -{ - ObjCMethodPrototypeAST *ast = new (pool) ObjCMethodPrototypeAST; - // copy ObjCMethodPrototypeAST - ast->method_type_token = method_type_token; - if (type_name) ast->type_name = type_name->clone(pool); - if (selector) ast->selector = selector->clone(pool); - if (arguments) ast->arguments = arguments->clone(pool); - ast->dot_dot_dot_token = dot_dot_dot_token; - if (attributes) ast->attributes = attributes->clone(pool); - return ast; -} - -ObjCMethodDeclarationAST *ObjCMethodDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCMethodDeclarationAST *ast = new (pool) ObjCMethodDeclarationAST; - // copy DeclarationAST - // copy ObjCMethodDeclarationAST - if (method_prototype) ast->method_prototype = method_prototype->clone(pool); - if (function_body) ast->function_body = function_body->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -ObjCSynthesizedPropertyAST *ObjCSynthesizedPropertyAST::clone(MemoryPool *pool) const -{ - ObjCSynthesizedPropertyAST *ast = new (pool) ObjCSynthesizedPropertyAST; - // copy ObjCSynthesizedPropertyAST - ast->equals_token = equals_token; - return ast; -} - -ObjCSynthesizedPropertyListAST *ObjCSynthesizedPropertyListAST::clone(MemoryPool *pool) const -{ - ObjCSynthesizedPropertyListAST *ast = new (pool) ObjCSynthesizedPropertyListAST; - // copy ObjCSynthesizedPropertyListAST - if (synthesized_property) ast->synthesized_property = synthesized_property->clone(pool); - ast->comma_token = comma_token; - if (next) ast->next = next->clone(pool); - return ast; -} - -ObjCSynthesizedPropertiesDeclarationAST *ObjCSynthesizedPropertiesDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCSynthesizedPropertiesDeclarationAST *ast = new (pool) ObjCSynthesizedPropertiesDeclarationAST; - // copy DeclarationAST - // copy ObjCSynthesizedPropertiesDeclarationAST - ast->synthesized_token = synthesized_token; - if (property_identifiers) ast->property_identifiers = property_identifiers->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclarationAST::clone(MemoryPool *pool) const -{ - ObjCDynamicPropertiesDeclarationAST *ast = new (pool) ObjCDynamicPropertiesDeclarationAST; - // copy DeclarationAST - // copy ObjCDynamicPropertiesDeclarationAST - ast->dynamic_token = dynamic_token; - if (property_identifiers) ast->property_identifiers = property_identifiers->clone(pool); - ast->semicolon_token = semicolon_token; - return ast; -} - -ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const -{ - ObjCFastEnumerationAST *ast = new (pool) ObjCFastEnumerationAST; - // copy StatementAST - // copy ObjCFastEnumerationAST - ast->for_token = for_token; - ast->lparen_token = lparen_token; - if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool); - if (declarator) ast->declarator = declarator->clone(pool); - if (initializer) ast->initializer = initializer->clone(pool); - ast->in_token = in_token; - if (fast_enumeratable_expression) ast->fast_enumeratable_expression = fast_enumeratable_expression->clone(pool); - ast->rparen_token = rparen_token; - if (body_statement) ast->body_statement = body_statement->clone(pool); - return ast; -} - -ObjCSynchronizedStatementAST *ObjCSynchronizedStatementAST::clone(MemoryPool *pool) const -{ - ObjCSynchronizedStatementAST *ast = new (pool) ObjCSynchronizedStatementAST; - // copy StatementAST - // copy ObjCSynchronizedStatementAST - ast->synchronized_token = synchronized_token; - ast->lparen_token = lparen_token; - if (synchronized_object) ast->synchronized_object = synchronized_object->clone(pool); - ast->rparen_token = rparen_token; - if (statement) ast->statement = statement->clone(pool); - return ast; -} diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 7cd2075399..2d5d618dda 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -35,8 +35,6 @@ using namespace CPlusPlus; void SimpleSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit SimpleSpecifierAST - // visit SpecifierAST } visitor->endVisit(this); } @@ -44,10 +42,7 @@ void SimpleSpecifierAST::accept0(ASTVisitor *visitor) void AttributeSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit AttributeSpecifierAST - for (AttributeAST *it = attributes; it; it = it->next) - accept(it, visitor); - // visit SpecifierAST + accept(attribute_list, visitor); } visitor->endVisit(this); } @@ -55,9 +50,7 @@ void AttributeSpecifierAST::accept0(ASTVisitor *visitor) void AttributeAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit AttributeAST - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -65,18 +58,7 @@ void AttributeAST::accept0(ASTVisitor *visitor) void TypeofSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypeofSpecifierAST accept(expression, visitor); - // visit SpecifierAST - } - visitor->endVisit(this); -} - -void DeclarationListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit DeclarationListAST - accept(declaration, visitor); } visitor->endVisit(this); } @@ -84,39 +66,21 @@ void DeclarationListAST::accept0(ASTVisitor *visitor) void DeclaratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DeclaratorAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); + accept(ptr_operator_list, visitor); accept(core_declarator, visitor); - for (PostfixDeclaratorAST *it = postfix_declarators; it; it = it->next) - accept(it, visitor); - for (SpecifierAST *it = post_attributes; it; it = it->next) - accept(it, visitor); + accept(postfix_declarator_list, visitor); + accept(post_attribute_list, visitor); accept(initializer, visitor); } visitor->endVisit(this); } -void ExpressionListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ExpressionListAST - accept(expression, visitor); - } - visitor->endVisit(this); -} - void SimpleDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit SimpleDeclarationAST - for (SpecifierAST *it = decl_specifier_seq; it; it = it->next) - accept(it, visitor); - for (DeclaratorListAST *it = declarators; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(decl_specifier_list, visitor); + accept(declarator_list, visitor); } visitor->endVisit(this); } @@ -124,8 +88,6 @@ void SimpleDeclarationAST::accept0(ASTVisitor *visitor) void EmptyDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit EmptyDeclarationAST - // visit DeclarationAST } visitor->endVisit(this); } @@ -133,8 +95,6 @@ void EmptyDeclarationAST::accept0(ASTVisitor *visitor) void AccessDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit AccessDeclarationAST - // visit DeclarationAST } visitor->endVisit(this); } @@ -142,8 +102,6 @@ void AccessDeclarationAST::accept0(ASTVisitor *visitor) void AsmDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit AsmDefinitionAST - // visit DeclarationAST } visitor->endVisit(this); } @@ -151,7 +109,6 @@ void AsmDefinitionAST::accept0(ASTVisitor *visitor) void BaseSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit BaseSpecifierAST accept(name, visitor); } visitor->endVisit(this); @@ -160,10 +117,8 @@ void BaseSpecifierAST::accept0(ASTVisitor *visitor) void CompoundLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CompoundLiteralAST accept(type_id, visitor); accept(initializer, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -171,9 +126,7 @@ void CompoundLiteralAST::accept0(ASTVisitor *visitor) void QtMethodAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit QtMethodAST accept(declarator, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -181,10 +134,8 @@ void QtMethodAST::accept0(ASTVisitor *visitor) void BinaryExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit BinaryExpressionAST accept(left_expression, visitor); accept(right_expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -192,10 +143,8 @@ void BinaryExpressionAST::accept0(ASTVisitor *visitor) void CastExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CastExpressionAST accept(type_id, visitor); accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -203,15 +152,10 @@ void CastExpressionAST::accept0(ASTVisitor *visitor) void ClassSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ClassSpecifierAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); accept(name, visitor); - for (BaseSpecifierAST *it = base_clause; it; it = it->next) - accept(it, visitor); - for (DeclarationListAST *it = member_specifiers; it; it = it->next) - accept(it, visitor); - // visit SpecifierAST + accept(base_clause_list, visitor); + accept(member_specifier_list, visitor); } visitor->endVisit(this); } @@ -219,19 +163,8 @@ void ClassSpecifierAST::accept0(ASTVisitor *visitor) void CaseStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CaseStatementAST accept(expression, visitor); accept(statement, visitor); - // visit StatementAST - } - visitor->endVisit(this); -} - -void StatementListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit StatementListAST - accept(statement, visitor); } visitor->endVisit(this); } @@ -239,10 +172,7 @@ void StatementListAST::accept0(ASTVisitor *visitor) void CompoundStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CompoundStatementAST - for (StatementListAST *it = statements; it; it = it->next) - accept(it, visitor); - // visit StatementAST + accept(statement_list, visitor); } visitor->endVisit(this); } @@ -250,11 +180,8 @@ void CompoundStatementAST::accept0(ASTVisitor *visitor) void ConditionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ConditionAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -262,11 +189,9 @@ void ConditionAST::accept0(ASTVisitor *visitor) void ConditionalExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ConditionalExpressionAST accept(condition, visitor); accept(left_expression, visitor); accept(right_expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -274,10 +199,8 @@ void ConditionalExpressionAST::accept0(ASTVisitor *visitor) void CppCastExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CppCastExpressionAST accept(type_id, visitor); accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -285,9 +208,7 @@ void CppCastExpressionAST::accept0(ASTVisitor *visitor) void CtorInitializerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CtorInitializerAST - for (MemInitializerAST *it = member_initializers; it; it = it->next) - accept(it, visitor); + accept(member_initializer_list, visitor); } visitor->endVisit(this); } @@ -295,9 +216,7 @@ void CtorInitializerAST::accept0(ASTVisitor *visitor) void DeclarationStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DeclarationStatementAST accept(declaration, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -305,9 +224,7 @@ void DeclarationStatementAST::accept0(ASTVisitor *visitor) void DeclaratorIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DeclaratorIdAST accept(name, visitor); - // visit CoreDeclaratorAST } visitor->endVisit(this); } @@ -315,9 +232,7 @@ void DeclaratorIdAST::accept0(ASTVisitor *visitor) void NestedDeclaratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NestedDeclaratorAST accept(declarator, visitor); - // visit CoreDeclaratorAST } visitor->endVisit(this); } @@ -325,13 +240,10 @@ void NestedDeclaratorAST::accept0(ASTVisitor *visitor) void FunctionDeclaratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit FunctionDeclaratorAST accept(parameters, visitor); - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) - accept(it, visitor); + accept(cv_qualifier_list, visitor); accept(exception_specification, visitor); accept(as_cpp_initializer, visitor); - // visit PostfixDeclaratorAST } visitor->endVisit(this); } @@ -339,18 +251,7 @@ void FunctionDeclaratorAST::accept0(ASTVisitor *visitor) void ArrayDeclaratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ArrayDeclaratorAST accept(expression, visitor); - // visit PostfixDeclaratorAST - } - visitor->endVisit(this); -} - -void DeclaratorListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit DeclaratorListAST - accept(declarator, visitor); } visitor->endVisit(this); } @@ -358,9 +259,7 @@ void DeclaratorListAST::accept0(ASTVisitor *visitor) void DeleteExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DeleteExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -368,10 +267,8 @@ void DeleteExpressionAST::accept0(ASTVisitor *visitor) void DoStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DoStatementAST accept(statement, visitor); accept(expression, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -379,9 +276,7 @@ void DoStatementAST::accept0(ASTVisitor *visitor) void NamedTypeSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NamedTypeSpecifierAST accept(name, visitor); - // visit SpecifierAST } visitor->endVisit(this); } @@ -389,9 +284,7 @@ void NamedTypeSpecifierAST::accept0(ASTVisitor *visitor) void ElaboratedTypeSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ElaboratedTypeSpecifierAST accept(name, visitor); - // visit SpecifierAST } visitor->endVisit(this); } @@ -399,11 +292,8 @@ void ElaboratedTypeSpecifierAST::accept0(ASTVisitor *visitor) void EnumSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit EnumSpecifierAST accept(name, visitor); - for (EnumeratorAST *it = enumerators; it; it = it->next) - accept(it, visitor); - // visit SpecifierAST + accept(enumerator_list, visitor); } visitor->endVisit(this); } @@ -411,7 +301,6 @@ void EnumSpecifierAST::accept0(ASTVisitor *visitor) void EnumeratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit EnumeratorAST accept(expression, visitor); } visitor->endVisit(this); @@ -420,11 +309,8 @@ void EnumeratorAST::accept0(ASTVisitor *visitor) void ExceptionDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ExceptionDeclarationAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -432,9 +318,7 @@ void ExceptionDeclarationAST::accept0(ASTVisitor *visitor) void ExceptionSpecificationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ExceptionSpecificationAST - for (ExpressionListAST *it = type_ids; it; it = it->next) - accept(it, visitor); + accept(type_id_list, visitor); } visitor->endVisit(this); } @@ -442,10 +326,8 @@ void ExceptionSpecificationAST::accept0(ASTVisitor *visitor) void ExpressionOrDeclarationStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ExpressionOrDeclarationStatementAST accept(expression, visitor); accept(declaration, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -453,9 +335,7 @@ void ExpressionOrDeclarationStatementAST::accept0(ASTVisitor *visitor) void ExpressionStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ExpressionStatementAST accept(expression, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -463,13 +343,10 @@ void ExpressionStatementAST::accept0(ASTVisitor *visitor) void FunctionDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit FunctionDefinitionAST - for (SpecifierAST *it = decl_specifier_seq; it; it = it->next) - accept(it, visitor); + accept(decl_specifier_list, visitor); accept(declarator, visitor); accept(ctor_initializer, visitor); accept(function_body, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -477,14 +354,11 @@ void FunctionDefinitionAST::accept0(ASTVisitor *visitor) void ForeachStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ForeachStatementAST - for (SpecifierAST *it = type_specifiers; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); accept(initializer, visitor); accept(expression, visitor); accept(statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -492,12 +366,10 @@ void ForeachStatementAST::accept0(ASTVisitor *visitor) void ForStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ForStatementAST accept(initializer, visitor); accept(condition, visitor); accept(expression, visitor); accept(statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -505,11 +377,9 @@ void ForStatementAST::accept0(ASTVisitor *visitor) void IfStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit IfStatementAST accept(condition, visitor); accept(statement, visitor); accept(else_statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -517,10 +387,7 @@ void IfStatementAST::accept0(ASTVisitor *visitor) void ArrayInitializerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ArrayInitializerAST - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); - // visit ExpressionAST + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -528,9 +395,7 @@ void ArrayInitializerAST::accept0(ASTVisitor *visitor) void LabeledStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit LabeledStatementAST accept(statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -538,10 +403,7 @@ void LabeledStatementAST::accept0(ASTVisitor *visitor) void LinkageBodyAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit LinkageBodyAST - for (DeclarationListAST *it = declarations; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(declaration_list, visitor); } visitor->endVisit(this); } @@ -549,9 +411,7 @@ void LinkageBodyAST::accept0(ASTVisitor *visitor) void LinkageSpecificationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit LinkageSpecificationAST accept(declaration, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -559,7 +419,6 @@ void LinkageSpecificationAST::accept0(ASTVisitor *visitor) void MemInitializerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit MemInitializerAST accept(name, visitor); accept(expression, visitor); } @@ -569,7 +428,6 @@ void MemInitializerAST::accept0(ASTVisitor *visitor) void NestedNameSpecifierAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NestedNameSpecifierAST accept(class_or_namespace_name, visitor); } visitor->endVisit(this); @@ -578,12 +436,8 @@ void NestedNameSpecifierAST::accept0(ASTVisitor *visitor) void QualifiedNameAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit QualifiedNameAST - for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) - accept(it, visitor); + accept(nested_name_specifier_list, visitor); accept(unqualified_name, visitor); - // visit NameAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -591,10 +445,7 @@ void QualifiedNameAST::accept0(ASTVisitor *visitor) void OperatorFunctionIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit OperatorFunctionIdAST accept(op, visitor); - // visit NameAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -602,13 +453,8 @@ void OperatorFunctionIdAST::accept0(ASTVisitor *visitor) void ConversionFunctionIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ConversionFunctionIdAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) - accept(it, visitor); - // visit NameAST - // visit ExpressionAST + accept(type_specifier_list, visitor); + accept(ptr_operator_list, visitor); } visitor->endVisit(this); } @@ -616,9 +462,6 @@ void ConversionFunctionIdAST::accept0(ASTVisitor *visitor) void SimpleNameAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit SimpleNameAST - // visit NameAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -626,9 +469,6 @@ void SimpleNameAST::accept0(ASTVisitor *visitor) void DestructorNameAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit DestructorNameAST - // visit NameAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -636,11 +476,7 @@ void DestructorNameAST::accept0(ASTVisitor *visitor) void TemplateIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TemplateIdAST - for (TemplateArgumentListAST *it = template_arguments; it; it = it->next) - accept(it, visitor); - // visit NameAST - // visit ExpressionAST + accept(template_argument_list, visitor); } visitor->endVisit(this); } @@ -648,11 +484,8 @@ void TemplateIdAST::accept0(ASTVisitor *visitor) void NamespaceAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NamespaceAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); accept(linkage_body, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -660,9 +493,7 @@ void NamespaceAST::accept0(ASTVisitor *visitor) void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NamespaceAliasDefinitionAST accept(name, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -670,9 +501,7 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor) void NewPlacementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NewPlacementAST - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -680,7 +509,6 @@ void NewPlacementAST::accept0(ASTVisitor *visitor) void NewArrayDeclaratorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NewArrayDeclaratorAST accept(expression, visitor); } visitor->endVisit(this); @@ -689,12 +517,10 @@ void NewArrayDeclaratorAST::accept0(ASTVisitor *visitor) void NewExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NewExpressionAST accept(new_placement, visitor); accept(type_id, visitor); accept(new_type_id, visitor); accept(new_initializer, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -702,7 +528,6 @@ void NewExpressionAST::accept0(ASTVisitor *visitor) void NewInitializerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NewInitializerAST accept(expression, visitor); } visitor->endVisit(this); @@ -711,13 +536,9 @@ void NewInitializerAST::accept0(ASTVisitor *visitor) void NewTypeIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NewTypeIdAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); - for (PtrOperatorAST *it = ptr_operators; it; it = it->next) - accept(it, visitor); - for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); + accept(ptr_operator_list, visitor); + accept(new_array_declarator_list, visitor); } visitor->endVisit(this); } @@ -725,7 +546,6 @@ void NewTypeIdAST::accept0(ASTVisitor *visitor) void OperatorAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit OperatorAST } visitor->endVisit(this); } @@ -733,12 +553,9 @@ void OperatorAST::accept0(ASTVisitor *visitor) void ParameterDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ParameterDeclarationAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); accept(expression, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -746,9 +563,7 @@ void ParameterDeclarationAST::accept0(ASTVisitor *visitor) void ParameterDeclarationClauseAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ParameterDeclarationClauseAST - for (DeclarationListAST *it = parameter_declarations; it; it = it->next) - accept(it, visitor); + accept(parameter_declaration_list, visitor); } visitor->endVisit(this); } @@ -756,10 +571,7 @@ void ParameterDeclarationClauseAST::accept0(ASTVisitor *visitor) void CallAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CallAST - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); - // visit PostfixAST + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -767,9 +579,7 @@ void CallAST::accept0(ASTVisitor *visitor) void ArrayAccessAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ArrayAccessAST accept(expression, visitor); - // visit PostfixAST } visitor->endVisit(this); } @@ -777,8 +587,6 @@ void ArrayAccessAST::accept0(ASTVisitor *visitor) void PostIncrDecrAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit PostIncrDecrAST - // visit PostfixAST } visitor->endVisit(this); } @@ -786,9 +594,7 @@ void PostIncrDecrAST::accept0(ASTVisitor *visitor) void MemberAccessAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit MemberAccessAST accept(member_name, visitor); - // visit PostfixAST } visitor->endVisit(this); } @@ -796,9 +602,7 @@ void MemberAccessAST::accept0(ASTVisitor *visitor) void TypeidExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypeidExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -806,11 +610,8 @@ void TypeidExpressionAST::accept0(ASTVisitor *visitor) void TypenameCallExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypenameCallExpressionAST accept(name, visitor); - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); - // visit ExpressionAST + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -818,12 +619,8 @@ void TypenameCallExpressionAST::accept0(ASTVisitor *visitor) void TypeConstructorCallAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypeConstructorCallAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); - for (ExpressionListAST *it = expression_list; it; it = it->next) - accept(it, visitor); - // visit ExpressionAST + accept(type_specifier_list, visitor); + accept(expression_list, visitor); } visitor->endVisit(this); } @@ -831,11 +628,8 @@ void TypeConstructorCallAST::accept0(ASTVisitor *visitor) void PostfixExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit PostfixExpressionAST accept(base_expression, visitor); - for (PostfixAST *it = postfix_expressions; it; it = it->next) - accept(it, visitor); - // visit ExpressionAST + accept(postfix_expression_list, visitor); } visitor->endVisit(this); } @@ -843,12 +637,8 @@ void PostfixExpressionAST::accept0(ASTVisitor *visitor) void PointerToMemberAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit PointerToMemberAST - for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) - accept(it, visitor); - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) - accept(it, visitor); - // visit PtrOperatorAST + accept(nested_name_specifier_list, visitor); + accept(cv_qualifier_list, visitor); } visitor->endVisit(this); } @@ -856,10 +646,7 @@ void PointerToMemberAST::accept0(ASTVisitor *visitor) void PointerAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit PointerAST - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) - accept(it, visitor); - // visit PtrOperatorAST + accept(cv_qualifier_list, visitor); } visitor->endVisit(this); } @@ -867,8 +654,6 @@ void PointerAST::accept0(ASTVisitor *visitor) void ReferenceAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ReferenceAST - // visit PtrOperatorAST } visitor->endVisit(this); } @@ -876,8 +661,6 @@ void ReferenceAST::accept0(ASTVisitor *visitor) void BreakStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit BreakStatementAST - // visit StatementAST } visitor->endVisit(this); } @@ -885,8 +668,6 @@ void BreakStatementAST::accept0(ASTVisitor *visitor) void ContinueStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ContinueStatementAST - // visit StatementAST } visitor->endVisit(this); } @@ -894,8 +675,6 @@ void ContinueStatementAST::accept0(ASTVisitor *visitor) void GotoStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit GotoStatementAST - // visit StatementAST } visitor->endVisit(this); } @@ -903,9 +682,7 @@ void GotoStatementAST::accept0(ASTVisitor *visitor) void ReturnStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ReturnStatementAST accept(expression, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -913,9 +690,7 @@ void ReturnStatementAST::accept0(ASTVisitor *visitor) void SizeofExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit SizeofExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -923,8 +698,6 @@ void SizeofExpressionAST::accept0(ASTVisitor *visitor) void NumericLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NumericLiteralAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -932,8 +705,6 @@ void NumericLiteralAST::accept0(ASTVisitor *visitor) void BoolLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit BoolLiteralAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -941,8 +712,6 @@ void BoolLiteralAST::accept0(ASTVisitor *visitor) void ThisExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ThisExpressionAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -950,9 +719,7 @@ void ThisExpressionAST::accept0(ASTVisitor *visitor) void NestedExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit NestedExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -960,8 +727,6 @@ void NestedExpressionAST::accept0(ASTVisitor *visitor) void StringLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit StringLiteralAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -969,19 +734,8 @@ void StringLiteralAST::accept0(ASTVisitor *visitor) void SwitchStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit SwitchStatementAST accept(condition, visitor); accept(statement, visitor); - // visit StatementAST - } - visitor->endVisit(this); -} - -void TemplateArgumentListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit TemplateArgumentListAST - accept(template_argument, visitor); } visitor->endVisit(this); } @@ -989,11 +743,8 @@ void TemplateArgumentListAST::accept0(ASTVisitor *visitor) void TemplateDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TemplateDeclarationAST - for (DeclarationListAST *it = template_parameters; it; it = it->next) - accept(it, visitor); + accept(template_parameter_list, visitor); accept(declaration, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1001,9 +752,7 @@ void TemplateDeclarationAST::accept0(ASTVisitor *visitor) void ThrowExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ThrowExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -1011,9 +760,7 @@ void ThrowExpressionAST::accept0(ASTVisitor *visitor) void TranslationUnitAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TranslationUnitAST - for (DeclarationListAST *it = declarations; it; it = it->next) - accept(it, visitor); + accept(declaration_list, visitor); } visitor->endVisit(this); } @@ -1021,11 +768,8 @@ void TranslationUnitAST::accept0(ASTVisitor *visitor) void TryBlockStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TryBlockStatementAST accept(statement, visitor); - for (CatchClauseAST *it = catch_clause_seq; it; it = it->next) - accept(it, visitor); - // visit StatementAST + accept(catch_clause_list, visitor); } visitor->endVisit(this); } @@ -1033,10 +777,8 @@ void TryBlockStatementAST::accept0(ASTVisitor *visitor) void CatchClauseAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit CatchClauseAST accept(exception_declaration, visitor); accept(statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -1044,11 +786,8 @@ void CatchClauseAST::accept0(ASTVisitor *visitor) void TypeIdAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypeIdAST - for (SpecifierAST *it = type_specifier; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -1056,10 +795,8 @@ void TypeIdAST::accept0(ASTVisitor *visitor) void TypenameTypeParameterAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TypenameTypeParameterAST accept(name, visitor); accept(type_id, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1067,12 +804,9 @@ void TypenameTypeParameterAST::accept0(ASTVisitor *visitor) void TemplateTypeParameterAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit TemplateTypeParameterAST - for (DeclarationListAST *it = template_parameters; it; it = it->next) - accept(it, visitor); + accept(template_parameter_list, visitor); accept(name, visitor); accept(type_id, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1080,9 +814,7 @@ void TemplateTypeParameterAST::accept0(ASTVisitor *visitor) void UnaryExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit UnaryExpressionAST accept(expression, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -1090,9 +822,7 @@ void UnaryExpressionAST::accept0(ASTVisitor *visitor) void UsingAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit UsingAST accept(name, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1100,9 +830,7 @@ void UsingAST::accept0(ASTVisitor *visitor) void UsingDirectiveAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit UsingDirectiveAST accept(name, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1110,19 +838,8 @@ void UsingDirectiveAST::accept0(ASTVisitor *visitor) void WhileStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit WhileStatementAST accept(condition, visitor); accept(statement, visitor); - // visit StatementAST - } - visitor->endVisit(this); -} - -void IdentifierListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit IdentifierListAST - accept(name, visitor); } visitor->endVisit(this); } @@ -1130,12 +847,8 @@ void IdentifierListAST::accept0(ASTVisitor *visitor) void ObjCClassForwardDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCClassForwardDeclarationAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); - for (IdentifierListAST *it = identifier_list; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(attribute_list, visitor); + accept(identifier_list, visitor); } visitor->endVisit(this); } @@ -1143,17 +856,13 @@ void ObjCClassForwardDeclarationAST::accept0(ASTVisitor *visitor) void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCClassInterfaceDefinitionAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); accept(class_name, visitor); accept(category_name, visitor); accept(superclass, visitor); accept(protocol_refs, visitor); accept(inst_vars_decl, visitor); - for (DeclarationListAST *it = member_declarations; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(member_declaration_list, visitor); } visitor->endVisit(this); } @@ -1161,12 +870,8 @@ void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor) void ObjCProtocolForwardDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCProtocolDeclarationAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); - for (IdentifierListAST *it = identifier_list; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(attribute_list, visitor); + accept(identifier_list, visitor); } visitor->endVisit(this); } @@ -1174,14 +879,10 @@ void ObjCProtocolForwardDeclarationAST::accept0(ASTVisitor *visitor) void ObjCProtocolDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCProtocolDeclarationAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); accept(name, visitor); accept(protocol_refs, visitor); - for (DeclarationListAST *it = member_declarations; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(member_declaration_list, visitor); } visitor->endVisit(this); } @@ -1189,9 +890,7 @@ void ObjCProtocolDeclarationAST::accept0(ASTVisitor *visitor) void ObjCProtocolRefsAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCProtocolRefsAST - for (IdentifierListAST *it = identifier_list; it; it = it->next) - accept(it, visitor); + accept(identifier_list, visitor); } visitor->endVisit(this); } @@ -1199,30 +898,17 @@ void ObjCProtocolRefsAST::accept0(ASTVisitor *visitor) void ObjCMessageArgumentAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCMessageArgumentAST accept(parameter_value_expression, visitor); } visitor->endVisit(this); } -void ObjCMessageArgumentListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ObjCMessageArgumentListAST - accept(arg, visitor); - } - visitor->endVisit(this); -} - void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCMessageExpressionAST accept(receiver_expression, visitor); accept(selector, visitor); - for (ObjCMessageArgumentListAST *it = argument_list; it; it = it->next) - accept(it, visitor); - // visit ExpressionAST + accept(argument_list, visitor); } visitor->endVisit(this); } @@ -1230,8 +916,6 @@ void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor) void ObjCProtocolExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCProtocolExpressionAST - // visit ExpressionAST } visitor->endVisit(this); } @@ -1239,7 +923,6 @@ void ObjCProtocolExpressionAST::accept0(ASTVisitor *visitor) void ObjCTypeNameAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCTypeNameAST accept(type_id, visitor); } visitor->endVisit(this); @@ -1248,9 +931,7 @@ void ObjCTypeNameAST::accept0(ASTVisitor *visitor) void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCEncodeExpressionAST accept(type_name, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -1258,8 +939,6 @@ void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor) void ObjCSelectorWithoutArgumentsAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSelectorWithoutArgumentsAST - // visit ObjCSelectorAST } visitor->endVisit(this); } @@ -1267,16 +946,6 @@ void ObjCSelectorWithoutArgumentsAST::accept0(ASTVisitor *visitor) void ObjCSelectorArgumentAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSelectorArgumentAST - } - visitor->endVisit(this); -} - -void ObjCSelectorArgumentListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ObjCSelectorArgumentListAST - accept(argument, visitor); } visitor->endVisit(this); } @@ -1284,10 +953,7 @@ void ObjCSelectorArgumentListAST::accept0(ASTVisitor *visitor) void ObjCSelectorWithArgumentsAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSelectorWithArgumentsAST - for (ObjCSelectorArgumentListAST *it = selector_arguments; it; it = it->next) - accept(it, visitor); - // visit ObjCSelectorAST + accept(selector_argument_list, visitor); } visitor->endVisit(this); } @@ -1295,9 +961,7 @@ void ObjCSelectorWithArgumentsAST::accept0(ASTVisitor *visitor) void ObjCSelectorExpressionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSelectorExpressionAST accept(selector, visitor); - // visit ExpressionAST } visitor->endVisit(this); } @@ -1305,9 +969,7 @@ void ObjCSelectorExpressionAST::accept0(ASTVisitor *visitor) void ObjCInstanceVariablesDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCInstanceVariablesDeclarationAST - for (DeclarationListAST *it = instance_variables; it; it = it->next) - accept(it, visitor); + accept(instance_variable_list, visitor); } visitor->endVisit(this); } @@ -1315,8 +977,6 @@ void ObjCInstanceVariablesDeclarationAST::accept0(ASTVisitor *visitor) void ObjCVisibilityDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCVisibilityDeclarationAST - // visit DeclarationAST } visitor->endVisit(this); } @@ -1324,31 +984,17 @@ void ObjCVisibilityDeclarationAST::accept0(ASTVisitor *visitor) void ObjCPropertyAttributeAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCPropertyAttributeAST accept(method_selector, visitor); } visitor->endVisit(this); } -void ObjCPropertyAttributeListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ObjCPropertyAttributeListAST - accept(attr, visitor); - } - visitor->endVisit(this); -} - void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCPropertyDeclarationAST - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); - for (ObjCPropertyAttributeListAST *it = property_attributes; it; it = it->next) - accept(it, visitor); + accept(attribute_list, visitor); + accept(property_attribute_list, visitor); accept(simple_declaration, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1356,21 +1002,8 @@ void ObjCPropertyDeclarationAST::accept0(ASTVisitor *visitor) void ObjCMessageArgumentDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCMessageArgumentDeclarationAST accept(type_name, visitor); - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); - // visit NameAST - // visit ExpressionAST - } - visitor->endVisit(this); -} - -void ObjCMessageArgumentDeclarationListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ObjCMessageArgumentDeclarationListAST - accept(argument_declaration, visitor); + accept(attribute_list, visitor); } visitor->endVisit(this); } @@ -1378,13 +1011,10 @@ void ObjCMessageArgumentDeclarationListAST::accept0(ASTVisitor *visitor) void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCMethodPrototypeAST accept(type_name, visitor); accept(selector, visitor); - for (ObjCMessageArgumentDeclarationListAST *it = arguments; it; it = it->next) - accept(it, visitor); - for (SpecifierAST *it = attributes; it; it = it->next) - accept(it, visitor); + accept(argument_list, visitor); + accept(attribute_list, visitor); } visitor->endVisit(this); } @@ -1392,10 +1022,8 @@ void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor) void ObjCMethodDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCMethodDeclarationAST accept(method_prototype, visitor); accept(function_body, visitor); - // visit DeclarationAST } visitor->endVisit(this); } @@ -1403,16 +1031,6 @@ void ObjCMethodDeclarationAST::accept0(ASTVisitor *visitor) void ObjCSynthesizedPropertyAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSynthesizedPropertyAST - } - visitor->endVisit(this); -} - -void ObjCSynthesizedPropertyListAST::accept0(ASTVisitor *visitor) -{ - if (visitor->visit(this)) { - // visit ObjCSynthesizedPropertyListAST - accept(synthesized_property, visitor); } visitor->endVisit(this); } @@ -1420,10 +1038,7 @@ void ObjCSynthesizedPropertyListAST::accept0(ASTVisitor *visitor) void ObjCSynthesizedPropertiesDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSynthesizedPropertiesDeclarationAST - for (ObjCSynthesizedPropertyListAST *it = property_identifiers; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(property_identifier_list, visitor); } visitor->endVisit(this); } @@ -1431,10 +1046,7 @@ void ObjCSynthesizedPropertiesDeclarationAST::accept0(ASTVisitor *visitor) void ObjCDynamicPropertiesDeclarationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCDynamicPropertiesDeclarationAST - for (IdentifierListAST *it = property_identifiers; it; it = it->next) - accept(it, visitor); - // visit DeclarationAST + accept(property_identifier_list, visitor); } visitor->endVisit(this); } @@ -1442,14 +1054,11 @@ void ObjCDynamicPropertiesDeclarationAST::accept0(ASTVisitor *visitor) void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCFastEnumerationAST - for (SpecifierAST *it = type_specifiers; it; it = it->next) - accept(it, visitor); + accept(type_specifier_list, visitor); accept(declarator, visitor); accept(initializer, visitor); accept(fast_enumeratable_expression, visitor); accept(body_statement, visitor); - // visit StatementAST } visitor->endVisit(this); } @@ -1457,12 +1066,9 @@ void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor) void ObjCSynchronizedStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - // visit ObjCSynchronizedStatementAST accept(synchronized_object, visitor); accept(statement, visitor); - // visit StatementAST } visitor->endVisit(this); } - diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 7356e0f905..e1429fa2f6 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -91,6 +91,13 @@ public: void accept(AST *ast); + template <typename _Tp> + void accept(List<_Tp> *it) + { + for (; it; it = it->next) + accept(it->value); + } + virtual bool preVisit(AST *) { return true; } virtual void postVisit(AST *) {} @@ -121,7 +128,6 @@ public: virtual bool visit(DeclaratorAST *) { return true; } virtual bool visit(DeclarationStatementAST *) { return true; } virtual bool visit(DeclaratorIdAST *) { return true; } - virtual bool visit(DeclaratorListAST *) { return true; } virtual bool visit(DeleteExpressionAST *) { return true; } virtual bool visit(DestructorNameAST *) { return true; } virtual bool visit(DoStatementAST *) { return true; } @@ -131,7 +137,6 @@ public: virtual bool visit(EnumeratorAST *) { return true; } virtual bool visit(ExceptionDeclarationAST *) { return true; } virtual bool visit(ExceptionSpecificationAST *) { return true; } - virtual bool visit(ExpressionListAST *) { return true; } virtual bool visit(ExpressionOrDeclarationStatementAST *) { return true; } virtual bool visit(ExpressionStatementAST *) { return true; } virtual bool visit(ForeachStatementAST *) { return true; } @@ -172,10 +177,8 @@ public: virtual bool visit(SimpleNameAST *) { return true; } virtual bool visit(SimpleSpecifierAST *) { return true; } virtual bool visit(SizeofExpressionAST *) { return true; } - virtual bool visit(StatementListAST *) { return true; } virtual bool visit(StringLiteralAST *) { return true; } virtual bool visit(SwitchStatementAST *) { return true; } - virtual bool visit(TemplateArgumentListAST *) { return true; } virtual bool visit(TemplateDeclarationAST *) { return true; } virtual bool visit(TemplateIdAST *) { return true; } virtual bool visit(TemplateTypeParameterAST *) { return true; } @@ -196,42 +199,33 @@ public: virtual bool visit(QtMethodAST *) { return true; } // ObjC++ - virtual bool visit(IdentifierListAST *) { return true; } virtual bool visit(ObjCClassDeclarationAST *) { return true; } virtual bool visit(ObjCClassForwardDeclarationAST *) { return true; } virtual bool visit(ObjCProtocolDeclarationAST *) { return true; } virtual bool visit(ObjCProtocolForwardDeclarationAST *) { return true; } virtual bool visit(ObjCProtocolRefsAST *) { return true; } virtual bool visit(ObjCMessageExpressionAST *) { return true; } - virtual bool visit(ObjCMessageArgumentListAST *) { return true; } virtual bool visit(ObjCMessageArgumentAST *) { return true; } virtual bool visit(ObjCProtocolExpressionAST *) { return true; } virtual bool visit(ObjCTypeNameAST *) { return true; } virtual bool visit(ObjCEncodeExpressionAST *) { return true; } virtual bool visit(ObjCSelectorWithoutArgumentsAST *) { return true; } virtual bool visit(ObjCSelectorArgumentAST *) { return true; } - virtual bool visit(ObjCSelectorArgumentListAST *) { return true; } virtual bool visit(ObjCSelectorWithArgumentsAST *) { return true; } virtual bool visit(ObjCSelectorExpressionAST *) { return true; } virtual bool visit(ObjCInstanceVariablesDeclarationAST *) { return true; } virtual bool visit(ObjCVisibilityDeclarationAST *) { return true; } virtual bool visit(ObjCPropertyAttributeAST *) { return true; } - virtual bool visit(ObjCPropertyAttributeListAST *) { return true; } virtual bool visit(ObjCPropertyDeclarationAST *) { return true; } virtual bool visit(ObjCMethodPrototypeAST *) { return true; } virtual bool visit(ObjCMethodDeclarationAST *) { return true; } - virtual bool visit(ObjCMessageArgumentDeclarationListAST *) { return true; } virtual bool visit(ObjCMessageArgumentDeclarationAST *) { return true; } virtual bool visit(ObjCSynthesizedPropertyAST *) { return true; } - virtual bool visit(ObjCSynthesizedPropertyListAST *) { return true; } virtual bool visit(ObjCSynthesizedPropertiesDeclarationAST *) { return true; } virtual bool visit(ObjCDynamicPropertiesDeclarationAST *) { return true; } virtual bool visit(ObjCFastEnumerationAST *) { return true; } virtual bool visit(ObjCSynchronizedStatementAST *) { return true; } - virtual bool visit(DeclarationListAST *) { return true; } - virtual void endVisit(DeclarationListAST *) { } - virtual void endVisit(AccessDeclarationAST *) { } virtual void endVisit(ArrayAccessAST *) { } virtual void endVisit(ArrayDeclaratorAST *) { } @@ -259,7 +253,6 @@ public: virtual void endVisit(DeclaratorAST *) { } virtual void endVisit(DeclarationStatementAST *) { } virtual void endVisit(DeclaratorIdAST *) { } - virtual void endVisit(DeclaratorListAST *) { } virtual void endVisit(DeleteExpressionAST *) { } virtual void endVisit(DestructorNameAST *) { } virtual void endVisit(DoStatementAST *) { } @@ -269,7 +262,6 @@ public: virtual void endVisit(EnumeratorAST *) { } virtual void endVisit(ExceptionDeclarationAST *) { } virtual void endVisit(ExceptionSpecificationAST *) { } - virtual void endVisit(ExpressionListAST *) { } virtual void endVisit(ExpressionOrDeclarationStatementAST *) { } virtual void endVisit(ExpressionStatementAST *) { } virtual void endVisit(ForeachStatementAST *) { } @@ -310,10 +302,8 @@ public: virtual void endVisit(SimpleNameAST *) { } virtual void endVisit(SimpleSpecifierAST *) { } virtual void endVisit(SizeofExpressionAST *) { } - virtual void endVisit(StatementListAST *) { } virtual void endVisit(StringLiteralAST *) { } virtual void endVisit(SwitchStatementAST *) { } - virtual void endVisit(TemplateArgumentListAST *) { } virtual void endVisit(TemplateDeclarationAST *) { } virtual void endVisit(TemplateIdAST *) { } virtual void endVisit(TemplateTypeParameterAST *) { } @@ -334,34 +324,28 @@ public: virtual void endVisit(QtMethodAST *) { } // ObjC++ - virtual void endVisit(IdentifierListAST *) { } virtual void endVisit(ObjCClassDeclarationAST *) { } virtual void endVisit(ObjCClassForwardDeclarationAST *) { } virtual void endVisit(ObjCProtocolDeclarationAST *) { } virtual void endVisit(ObjCProtocolForwardDeclarationAST *) { } virtual void endVisit(ObjCProtocolRefsAST *) { } virtual void endVisit(ObjCMessageExpressionAST *) { } - virtual void endVisit(ObjCMessageArgumentListAST *) { } virtual void endVisit(ObjCMessageArgumentAST *) { } virtual void endVisit(ObjCProtocolExpressionAST *) { } virtual void endVisit(ObjCTypeNameAST *) { } virtual void endVisit(ObjCEncodeExpressionAST *) { } virtual void endVisit(ObjCSelectorWithoutArgumentsAST *) { } virtual void endVisit(ObjCSelectorArgumentAST *) { } - virtual void endVisit(ObjCSelectorArgumentListAST *) { } virtual void endVisit(ObjCSelectorWithArgumentsAST *) { } virtual void endVisit(ObjCSelectorExpressionAST *) { } virtual void endVisit(ObjCInstanceVariablesDeclarationAST *) { } virtual void endVisit(ObjCVisibilityDeclarationAST *) { } virtual void endVisit(ObjCPropertyAttributeAST *) { } - virtual void endVisit(ObjCPropertyAttributeListAST *) { } virtual void endVisit(ObjCPropertyDeclarationAST *) { } virtual void endVisit(ObjCMethodPrototypeAST *) { } virtual void endVisit(ObjCMethodDeclarationAST *) { } - virtual void endVisit(ObjCMessageArgumentDeclarationListAST *) { } virtual void endVisit(ObjCMessageArgumentDeclarationAST *) { } virtual void endVisit(ObjCSynthesizedPropertyAST *) { } - virtual void endVisit(ObjCSynthesizedPropertyListAST *) { } virtual void endVisit(ObjCSynthesizedPropertiesDeclarationAST *) { } virtual void endVisit(ObjCDynamicPropertiesDeclarationAST *) { } virtual void endVisit(ObjCFastEnumerationAST *) { } diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index e0a5c59d9a..aaeeed94ae 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -53,6 +53,8 @@ namespace CPlusPlus { +template <typename _Tp> class List; + class AST; class ASTVisitor; @@ -82,11 +84,9 @@ class CoreDeclaratorAST; class CppCastExpressionAST; class CtorInitializerAST; class DeclarationAST; -class DeclarationListAST; class DeclarationStatementAST; class DeclaratorAST; class DeclaratorIdAST; -class DeclaratorListAST; class DeleteExpressionAST; class DestructorNameAST; class DoStatementAST; @@ -97,11 +97,10 @@ class EnumeratorAST; class ExceptionDeclarationAST; class ExceptionSpecificationAST; class ExpressionAST; -class ExpressionListAST; class ExpressionOrDeclarationStatementAST; class ExpressionStatementAST; -class ForeachStatementAST; class ForStatementAST; +class ForeachStatementAST; class FunctionDeclaratorAST; class FunctionDefinitionAST; class GotoStatementAST; @@ -120,10 +119,37 @@ class NestedExpressionAST; class NestedNameSpecifierAST; class NewArrayDeclaratorAST; class NewExpressionAST; -class NewPlacementAST; class NewInitializerAST; +class NewPlacementAST; class NewTypeIdAST; class NumericLiteralAST; +class ObjCClassDeclarationAST; +class ObjCClassForwardDeclarationAST; +class ObjCDynamicPropertiesDeclarationAST; +class ObjCEncodeExpressionAST; +class ObjCFastEnumerationAST; +class ObjCInstanceVariablesDeclarationAST; +class ObjCMessageArgumentAST; +class ObjCMessageArgumentDeclarationAST; +class ObjCMessageExpressionAST; +class ObjCMethodDeclarationAST; +class ObjCMethodPrototypeAST; +class ObjCPropertyAttributeAST; +class ObjCPropertyDeclarationAST; +class ObjCProtocolDeclarationAST; +class ObjCProtocolExpressionAST; +class ObjCProtocolForwardDeclarationAST; +class ObjCProtocolRefsAST; +class ObjCSelectorAST; +class ObjCSelectorArgumentAST; +class ObjCSelectorExpressionAST; +class ObjCSelectorWithArgumentsAST; +class ObjCSelectorWithoutArgumentsAST; +class ObjCSynchronizedStatementAST; +class ObjCSynthesizedPropertiesDeclarationAST; +class ObjCSynthesizedPropertyAST; +class ObjCTypeNameAST; +class ObjCVisibilityDeclarationAST; class OperatorAST; class OperatorFunctionIdAST; class ParameterDeclarationAST; @@ -135,6 +161,7 @@ class PostfixAST; class PostfixDeclaratorAST; class PostfixExpressionAST; class PtrOperatorAST; +class QtMethodAST; class QualifiedNameAST; class ReferenceAST; class ReturnStatementAST; @@ -144,10 +171,8 @@ class SimpleSpecifierAST; class SizeofExpressionAST; class SpecifierAST; class StatementAST; -class StatementListAST; class StringLiteralAST; class SwitchStatementAST; -class TemplateArgumentListAST; class TemplateDeclarationAST; class TemplateIdAST; class TemplateTypeParameterAST; @@ -165,42 +190,31 @@ class UnaryExpressionAST; class UsingAST; class UsingDirectiveAST; class WhileStatementAST; -class QtMethodAST; -// ObjC++ -class IdentifierListAST; -class ObjCClassForwardDeclarationAST; -class ObjCClassDeclarationAST; -class ObjCProtocolForwardDeclarationAST; -class ObjCProtocolDeclarationAST; -class ObjCProtocolRefsAST; -class ObjCMessageExpressionAST; -class ObjCMessageArgumentListAST; -class ObjCMessageArgumentAST; -class ObjCProtocolExpressionAST; -class ObjCTypeNameAST; -class ObjCEncodeExpressionAST; -class ObjCSelectorAST; -class ObjCSelectorWithoutArgumentsAST; -class ObjCSelectorArgumentAST; -class ObjCSelectorArgumentListAST; -class ObjCSelectorWithArgumentsAST; -class ObjCSelectorExpressionAST; -class ObjCInstanceVariablesDeclarationAST; -class ObjCVisibilityDeclarationAST; -class ObjCPropertyDeclarationAST; -class ObjCPropertyAttributeListAST; -class ObjCPropertyAttributeAST; -class ObjCMethodPrototypeAST; -class ObjCMethodDeclarationAST; -class ObjCMessageArgumentDeclarationListAST; -class ObjCMessageArgumentDeclarationAST; -class ObjCSynthesizedPropertyAST; -class ObjCSynthesizedPropertyListAST; -class ObjCSynthesizedPropertiesDeclarationAST; -class ObjCDynamicPropertiesDeclarationAST; -class ObjCFastEnumerationAST; -class ObjCSynchronizedStatementAST; +typedef List<ExpressionAST *> ExpressionListAST; +typedef List<DeclarationAST *> DeclarationListAST; +typedef List<StatementAST *> StatementListAST; +typedef List<DeclaratorAST *> DeclaratorListAST; +typedef List<BaseSpecifierAST *> BaseSpecifierListAST; +typedef List<EnumeratorAST *> EnumeratorListAST; +typedef List<MemInitializerAST *> MemInitializerListAST; +typedef List<NewArrayDeclaratorAST *> NewArrayDeclaratorListAST; +typedef List<PostfixAST *> PostfixListAST; +typedef List<PostfixDeclaratorAST *> PostfixDeclaratorListAST; +typedef List<AttributeAST *> AttributeListAST; +typedef List<NestedNameSpecifierAST *> NestedNameSpecifierListAST; +typedef List<CatchClauseAST *> CatchClauseListAST; +typedef List<PtrOperatorAST *> PtrOperatorListAST; +typedef List<SpecifierAST *> SpecifierListAST; + +typedef List<NameAST *> ObjCIdentifierListAST; +typedef List<ObjCMessageArgumentAST *> ObjCMessageArgumentListAST; +typedef List<ObjCSelectorArgumentAST *> ObjCSelectorArgumentListAST; +typedef List<ObjCPropertyAttributeAST *> ObjCPropertyAttributeListAST; +typedef List<ObjCMessageArgumentDeclarationAST *> ObjCMessageArgumentDeclarationListAST; +typedef List<ObjCSynthesizedPropertyAST *> ObjCSynthesizedPropertyListAST; + +typedef ExpressionListAST TemplateArgumentListAST; } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h index 9616f51780..c21d0bbd0e 100644 --- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h @@ -130,6 +130,7 @@ class ObjCForwardClassDeclaration; class ObjCProtocol; class ObjCForwardProtocolDeclaration; class ObjCMethod; +class ObjCPropertyDeclaration; } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 1e7afdd166..04ee291aef 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -136,7 +136,7 @@ unsigned CheckDeclaration::locationOfDeclaratorId(DeclaratorAST *declarator) con bool CheckDeclaration::visit(SimpleDeclarationAST *ast) { - FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); + FullySpecifiedType ty = semantic()->check(ast->decl_specifier_list, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); if (_templateParameters && ty) { @@ -145,8 +145,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) } } - if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) { - if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) { + if (! ast->declarator_list && ast->decl_specifier_list && ! ast->decl_specifier_list->next) { + if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_list->value->asElaboratedTypeSpecifier()) { unsigned sourceLocation = elab_type_spec->firstToken(); @@ -171,15 +171,15 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; List<Declaration *> **decl_it = &ast->symbols; - for (DeclaratorListAST *it = ast->declarators; it; it = it->next) { + for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) { Name *name = 0; - FullySpecifiedType declTy = semantic()->check(it->declarator, qualTy, + FullySpecifiedType declTy = semantic()->check(it->value, qualTy, _scope, &name); - unsigned location = locationOfDeclaratorId(it->declarator); + unsigned location = locationOfDeclaratorId(it->value); if (! location) { - if (it->declarator) - location = it->declarator->firstToken(); + if (it->value) + location = it->value->firstToken(); else location = ast->firstToken(); } @@ -208,7 +208,7 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) symbol->setType(control()->integerType(IntegerType::Int)); symbol->setType(declTy); - if (_templateParameters && it == ast->declarators && ty && ! ty->isClassType()) + if (_templateParameters && it == ast->declarator_list && ty && ! ty->isClassType()) symbol->setTemplateParameters(_templateParameters); symbol->setVisibility(semantic()->currentVisibility()); @@ -226,8 +226,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) else if (ty.isTypedef()) symbol->setStorage(Symbol::Typedef); - if (it->declarator && it->declarator->initializer) { - FullySpecifiedType initTy = semantic()->check(it->declarator->initializer, _scope); + if (it->value && it->value->initializer) { + FullySpecifiedType initTy = semantic()->check(it->value->initializer, _scope); } *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>(); @@ -265,7 +265,7 @@ bool CheckDeclaration::visit(AsmDefinitionAST *) bool CheckDeclaration::visit(ExceptionDeclarationAST *ast) { - FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); + FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; @@ -291,7 +291,7 @@ bool CheckDeclaration::visit(ExceptionDeclarationAST *ast) bool CheckDeclaration::visit(FunctionDefinitionAST *ast) { - FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope); + FullySpecifiedType ty = semantic()->check(ast->decl_specifier_list, _scope); FullySpecifiedType qualTy = ty.qualifiedType(); Name *name = 0; FullySpecifiedType funTy = semantic()->check(ast->declarator, qualTy, @@ -362,8 +362,8 @@ bool CheckDeclaration::visit(MemInitializerAST *ast) bool CheckDeclaration::visit(LinkageBodyAST *ast) { - for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) { - semantic()->check(decl->declaration, _scope); + for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) { + semantic()->check(decl->value, _scope); } return false; } @@ -410,7 +410,7 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast) } Name *argName = 0; - FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); + FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), _scope, &argName); FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); @@ -427,8 +427,8 @@ bool CheckDeclaration::visit(TemplateDeclarationAST *ast) { Scope *scope = new Scope(_scope->owner()); - for (DeclarationListAST *param = ast->template_parameters; param; param = param->next) { - semantic()->check(param->declaration, scope); + for (DeclarationListAST *param = ast->template_parameter_list; param; param = param->next) { + semantic()->check(param->value, scope); } semantic()->check(ast->declaration, _scope, @@ -501,14 +501,14 @@ bool CheckDeclaration::visit(ObjCProtocolForwardDeclarationAST *ast) const unsigned sourceLocation = ast->firstToken(); List<ObjCForwardProtocolDeclaration *> **symbolIter = &ast->symbols; - for (IdentifierListAST *it = ast->identifier_list; it; it = it->next) { + for (ObjCIdentifierListAST *it = ast->identifier_list; it; it = it->next) { unsigned declarationLocation; - if (it->name) - declarationLocation = it->name->firstToken(); + if (it->value) + declarationLocation = it->value->firstToken(); else declarationLocation = sourceLocation; - Name *protocolName = semantic()->check(it->name, _scope); + Name *protocolName = semantic()->check(it->value, _scope); ObjCForwardProtocolDeclaration *fwdProtocol = control()->newObjCForwardProtocolDeclaration(sourceLocation, protocolName); fwdProtocol->setStartOffset(tokenAt(ast->firstToken()).offset); fwdProtocol->setEndOffset(tokenAt(ast->lastToken()).offset); @@ -537,8 +537,8 @@ bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast) protocol->setEndOffset(tokenAt(ast->lastToken()).offset); if (ast->protocol_refs && ast->protocol_refs->identifier_list) { - for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { - NameAST* name = iter->name; + for (ObjCIdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { + NameAST* name = iter->value; Name *protocolName = semantic()->check(name, _scope); ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); protocol->addProtocol(baseProtocol); @@ -546,8 +546,8 @@ bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast) } int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Public); - for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) { - semantic()->check(it->declaration, protocol->members()); + for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) { + semantic()->check(it->value, protocol->members()); } (void) semantic()->switchObjCVisibility(previousObjCVisibility); @@ -562,14 +562,14 @@ bool CheckDeclaration::visit(ObjCClassForwardDeclarationAST *ast) const unsigned sourceLocation = ast->firstToken(); List<ObjCForwardClassDeclaration *> **symbolIter = &ast->symbols; - for (IdentifierListAST *it = ast->identifier_list; it; it = it->next) { + for (ObjCIdentifierListAST *it = ast->identifier_list; it; it = it->next) { unsigned declarationLocation; - if (it->name) - declarationLocation = it->name->firstToken(); + if (it->value) + declarationLocation = it->value->firstToken(); else declarationLocation = sourceLocation; - Name *className = semantic()->check(it->name, _scope); + Name *className = semantic()->check(it->value, _scope); ObjCForwardClassDeclaration *fwdClass = control()->newObjCForwardClassDeclaration(sourceLocation, className); fwdClass->setStartOffset(tokenAt(ast->firstToken()).offset); fwdClass->setEndOffset(tokenAt(ast->lastToken()).offset); @@ -612,8 +612,8 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) } if (ast->protocol_refs && ast->protocol_refs->identifier_list) { - for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { - NameAST* name = iter->name; + for (ObjCIdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { + NameAST* name = iter->value; Name *protocolName = semantic()->check(name, _scope); ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); klass->addProtocol(baseProtocol); @@ -625,15 +625,15 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected); if (ast->inst_vars_decl) { - for (DeclarationListAST *it = ast->inst_vars_decl->instance_variables; it; it = it->next) { - semantic()->check(it->declaration, klass->members()); + for (DeclarationListAST *it = ast->inst_vars_decl->instance_variable_list; it; it = it->next) { + semantic()->check(it->value, klass->members()); } } (void) semantic()->switchObjCVisibility(Function::Public); - for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) { - semantic()->check(it->declaration, klass->members()); + for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) { + semantic()->check(it->value, klass->members()); } (void) semantic()->switchObjCVisibility(previousObjCVisibility); @@ -662,15 +662,13 @@ bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) Declaration *decl = control()->newDeclaration(ast->firstToken(), methodType->name()); decl->setType(methodType); symbol = decl; + symbol->setStorage(methodType->storage()); } symbol->setStartOffset(tokenAt(ast->firstToken()).offset); symbol->setEndOffset(tokenAt(ast->lastToken()).offset); symbol->setVisibility(semantic()->currentVisibility()); - if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token)) - symbol->setStorage(Symbol::Static); - _scope->enterSymbol(symbol); return false; @@ -684,21 +682,6 @@ bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast) return false; } -enum PropertyAttributes { - None = 0, - Assign = 1 << 0, - Retain = 1 << 1, - Copy = 1 << 2, - ReadOnly = 1 << 3, - ReadWrite = 1 << 4, - Getter = 1 << 5, - Setter = 1 << 6, - NonAtomic = 1 << 7, - - WritabilityMask = ReadOnly | ReadWrite, - SetterSemanticsMask = Assign | Retain | Copy, -}; - bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst, int &flags, int attr) @@ -716,54 +699,76 @@ bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst, bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast) { - int propAttrs = None; + semantic()->check(ast->simple_declaration, _scope); + SimpleDeclarationAST *simpleDecl = ast->simple_declaration->asSimpleDeclaration(); + + if (!simpleDecl) { + translationUnit()->warning(ast->simple_declaration->firstToken(), + "invalid type for property declaration"); + return false; + } - for (ObjCPropertyAttributeListAST *iter= ast->property_attributes; iter; iter = iter->next) { - ObjCPropertyAttributeAST *attrAst = iter->attr; + int propAttrs = ObjCPropertyDeclaration::None; + Name *getterName = 0, *setterName = 0; + + for (ObjCPropertyAttributeListAST *iter= ast->property_attribute_list; iter; iter = iter->next) { + ObjCPropertyAttributeAST *attrAst = iter->value; if (!attrAst) continue; Identifier *attrId = identifier(attrAst->attribute_identifier_token); if (attrId == control()->objcGetterId()) { - if (checkPropertyAttribute(attrAst, propAttrs, Getter)) { - // TODO: find method declaration for getter + if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Getter)) { + getterName = semantic()->check(attrAst->method_selector, _scope); } } else if (attrId == control()->objcSetterId()) { - if (checkPropertyAttribute(attrAst, propAttrs, Setter)) { - // TODO: find method declaration for setter + if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Setter)) { + setterName = semantic()->check(attrAst->method_selector, _scope); } } else if (attrId == control()->objcReadwriteId()) { - checkPropertyAttribute(attrAst, propAttrs, ReadWrite); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadWrite); } else if (attrId == control()->objcReadonlyId()) { - checkPropertyAttribute(attrAst, propAttrs, ReadOnly); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadOnly); } else if (attrId == control()->objcAssignId()) { - checkPropertyAttribute(attrAst, propAttrs, Assign); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Assign); } else if (attrId == control()->objcRetainId()) { - checkPropertyAttribute(attrAst, propAttrs, Retain); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Retain); } else if (attrId == control()->objcCopyId()) { - checkPropertyAttribute(attrAst, propAttrs, Copy); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Copy); } else if (attrId == control()->objcNonatomicId()) { - checkPropertyAttribute(attrAst, propAttrs, NonAtomic); + checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::NonAtomic); } } - if (propAttrs & ReadOnly && propAttrs & ReadWrite) + if (propAttrs & ObjCPropertyDeclaration::ReadOnly && + propAttrs & ObjCPropertyDeclaration::ReadWrite) // Should this be an error instead of only a warning? translationUnit()->warning(ast->property_token, "property can have at most one attribute \"readonly\" or \"readwrite\" specified"); - int setterSemAttrs = propAttrs & SetterSemanticsMask; + int setterSemAttrs = propAttrs & ObjCPropertyDeclaration::SetterSemanticsMask; if (setterSemAttrs - && setterSemAttrs != Assign - && setterSemAttrs != Retain - && setterSemAttrs != Copy) { + && setterSemAttrs != ObjCPropertyDeclaration::Assign + && setterSemAttrs != ObjCPropertyDeclaration::Retain + && setterSemAttrs != ObjCPropertyDeclaration::Copy) { // Should this be an error instead of only a warning? translationUnit()->warning(ast->property_token, "property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified"); } - // TODO: Check if the next line is correct (EV) - semantic()->check(ast->simple_declaration, _scope); + List<ObjCPropertyDeclaration *> **lastSymbols = &ast->symbols; + for (List<Declaration*> *iter = simpleDecl->symbols; iter; iter = iter->next) { + ObjCPropertyDeclaration *propDecl = control()->newObjCPropertyDeclaration(ast->firstToken(), + iter->value->name()); + propDecl->setType(iter->value->type()); + propDecl->setAttributes(propAttrs); + propDecl->setGetterName(getterName); + propDecl->setSetterName(setterName); + _scope->enterSymbol(propDecl); + + *lastSymbols = new (translationUnit()->memoryPool()) List<ObjCPropertyDeclaration *>(); + (*lastSymbols)->value = propDecl; + lastSymbols = &(*lastSymbols)->next; + } + return false; } - - diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp index b44c90f955..9f28381105 100644 --- a/src/shared/cplusplus/CheckDeclarator.cpp +++ b/src/shared/cplusplus/CheckDeclarator.cpp @@ -68,9 +68,9 @@ CheckDeclarator::~CheckDeclarator() { } FullySpecifiedType CheckDeclarator::check(DeclaratorAST *declarator, - FullySpecifiedType type, - Scope *scope, - Name **name) + const FullySpecifiedType &type, + Scope *scope, + Name **name) { FullySpecifiedType previousType = switchFullySpecifiedType(type); Scope *previousScope = switchScope(scope); @@ -83,9 +83,9 @@ FullySpecifiedType CheckDeclarator::check(DeclaratorAST *declarator, return switchFullySpecifiedType(previousType); } -FullySpecifiedType CheckDeclarator::check(PtrOperatorAST *ptrOperators, - FullySpecifiedType type, - Scope *scope) +FullySpecifiedType CheckDeclarator::check(PtrOperatorListAST *ptrOperators, + const FullySpecifiedType &type, + Scope *scope) { FullySpecifiedType previousType = switchFullySpecifiedType(type); Scope *previousScope = switchScope(scope); @@ -110,7 +110,7 @@ DeclaratorAST *CheckDeclarator::switchDeclarator(DeclaratorAST *declarator) return previousDeclarator; } -FullySpecifiedType CheckDeclarator::switchFullySpecifiedType(FullySpecifiedType type) +FullySpecifiedType CheckDeclarator::switchFullySpecifiedType(const FullySpecifiedType &type) { FullySpecifiedType previousType = _fullySpecifiedType; _fullySpecifiedType = type; @@ -133,8 +133,8 @@ Name **CheckDeclarator::switchName(Name **name) bool CheckDeclarator::visit(DeclaratorAST *ast) { - accept(ast->ptr_operators); - accept(ast->postfix_declarators); + accept(ast->ptr_operator_list); + accept(ast->postfix_declarator_list); accept(ast->core_declarator); if (ast->initializer) { @@ -172,9 +172,9 @@ bool CheckDeclarator::visit(FunctionDeclaratorAST *ast) fun->setVirtual(true); if (ast->parameters) { - DeclarationListAST *parameter_declarations = ast->parameters->parameter_declarations; + DeclarationListAST *parameter_declarations = ast->parameters->parameter_declaration_list; for (DeclarationListAST *decl = parameter_declarations; decl; decl = decl->next) { - semantic()->check(decl->declaration, fun->arguments()); + semantic()->check(decl->value, fun->arguments()); } if (ast->parameters->dot_dot_dot_token) @@ -196,16 +196,15 @@ bool CheckDeclarator::visit(FunctionDeclaratorAST *ast) FullySpecifiedType funTy(fun); _fullySpecifiedType = funTy; - for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) { - SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it); - int k = tokenKind(cv->specifier_token); + for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) { + SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it->value); + const int k = tokenKind(cv->specifier_token); if (k == T_CONST) fun->setConst(true); else if (k == T_VOLATILE) fun->setVolatile(true); } - accept(ast->next); return false; } @@ -215,18 +214,16 @@ bool CheckDeclarator::visit(ArrayDeclaratorAST *ast) FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); FullySpecifiedType arrTy(ty); _fullySpecifiedType = ty; - accept(ast->next); return false; } bool CheckDeclarator::visit(PointerToMemberAST *ast) { - Name *memberName = semantic()->check(ast->nested_name_specifier, _scope); + Name *memberName = semantic()->check(ast->nested_name_specifier_list, _scope); PointerToMemberType *ptrTy = control()->pointerToMemberType(memberName, _fullySpecifiedType); FullySpecifiedType ty(ptrTy); _fullySpecifiedType = ty; - applyCvQualifiers(ast->cv_qualifier_seq); - accept(ast->next); + applyCvQualifiers(ast->cv_qualifier_list); return false; } @@ -235,39 +232,48 @@ bool CheckDeclarator::visit(PointerAST *ast) PointerType *ptrTy = control()->pointerType(_fullySpecifiedType); FullySpecifiedType ty(ptrTy); _fullySpecifiedType = ty; - applyCvQualifiers(ast->cv_qualifier_seq); - accept(ast->next); + applyCvQualifiers(ast->cv_qualifier_list); return false; } -bool CheckDeclarator::visit(ReferenceAST *ast) +bool CheckDeclarator::visit(ReferenceAST *) { ReferenceType *refTy = control()->referenceType(_fullySpecifiedType); FullySpecifiedType ty(refTy); _fullySpecifiedType = ty; - accept(ast->next); return false; } bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast) { + if (!ast) + return false; + + if (!ast->selector) { + // TODO: (EV) this currently happens when parsing: + // + (id<NSSomeProtocol>) zoo; + // where the parser will start doing template magic. We'll need to disambiguate this case. + return false; + } + FullySpecifiedType returnType = semantic()->check(ast->type_name, _scope); unsigned location = ast->firstToken(); - Name *name = semantic()->check(ast->selector, _scope); + semantic()->check(ast->selector, _scope); - ObjCMethod *method = control()->newObjCMethod(location, name); + ObjCMethod *method = control()->newObjCMethod(location, ast->selector->selector_name); ast->symbol = method; method->setSourceLocation(location); method->setScope(_scope); method->setVisibility(semantic()->currentVisibility()); method->setReturnType(returnType); + if (semantic()->isObjCClassMethod(tokenKind(ast->method_type_token))) + method->setStorage(Symbol::Static); if (ast->selector && ast->selector->asObjCSelectorWithArguments()) { - // TODO: add arguments (EV) - for (ObjCMessageArgumentDeclarationListAST *it = ast->arguments; it; it = it->next) { - ObjCMessageArgumentDeclarationAST *argDecl = it->argument_declaration; + for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) { + ObjCMessageArgumentDeclarationAST *argDecl = it->value; semantic()->check(argDecl, method->arguments()); } @@ -278,14 +284,13 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast) _fullySpecifiedType = FullySpecifiedType(method); - // TODO: check which specifiers are allowed here (EV) - return false; } -void CheckDeclarator::applyCvQualifiers(SpecifierAST *cv) +void CheckDeclarator::applyCvQualifiers(SpecifierListAST *it) { - for (; cv; cv = cv->next) { + for (; it; it = it->next) { + SpecifierAST *cv = it->value; SimpleSpecifierAST *spec = static_cast<SimpleSpecifierAST *>(cv); switch (translationUnit()->tokenKind(spec->specifier_token)) { case T_VOLATILE: diff --git a/src/shared/cplusplus/CheckDeclarator.h b/src/shared/cplusplus/CheckDeclarator.h index b676abfacd..1b9e14cb81 100644 --- a/src/shared/cplusplus/CheckDeclarator.h +++ b/src/shared/cplusplus/CheckDeclarator.h @@ -63,20 +63,20 @@ public: virtual ~CheckDeclarator(); FullySpecifiedType check(DeclaratorAST *declarator, - FullySpecifiedType type, - Scope *scope, - Name **name); + const FullySpecifiedType &type, + Scope *scope, + Name **name); - FullySpecifiedType check(PtrOperatorAST *ptrOperators, - FullySpecifiedType type, - Scope *scope); + FullySpecifiedType check(PtrOperatorListAST *ptrOperators, + const FullySpecifiedType &type, + Scope *scope); FullySpecifiedType check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope); protected: DeclaratorAST *switchDeclarator(DeclaratorAST *declarator); - FullySpecifiedType switchFullySpecifiedType(FullySpecifiedType type); + FullySpecifiedType switchFullySpecifiedType(const FullySpecifiedType &type); Scope *switchScope(Scope *scope); Name **switchName(Name **name); @@ -97,7 +97,7 @@ protected: virtual bool visit(ObjCMethodPrototypeAST *ast); void checkMessageArgument(ObjCMessageArgumentDeclarationAST *arg); - void applyCvQualifiers(SpecifierAST *cv); + void applyCvQualifiers(SpecifierListAST *it); private: DeclaratorAST *_declarator; diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp index 02263d6b82..01259d3c2c 100644 --- a/src/shared/cplusplus/CheckExpression.cpp +++ b/src/shared/cplusplus/CheckExpression.cpp @@ -100,14 +100,6 @@ Scope *CheckExpression::switchScope(Scope *scope) return previousScope; } -bool CheckExpression::visit(ExpressionListAST *ast) -{ - for (ExpressionListAST *it = ast; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); - } - return false; -} - bool CheckExpression::visit(BinaryExpressionAST *ast) { FullySpecifiedType leftExprTy = semantic()->check(ast->left_expression, _scope); @@ -127,7 +119,7 @@ bool CheckExpression::visit(CastExpressionAST *ast) bool CheckExpression::visit(ConditionAST *ast) { - FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier, _scope); + FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); Name *name = 0; FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope, &name); @@ -161,7 +153,7 @@ bool CheckExpression::visit(DeleteExpressionAST *ast) bool CheckExpression::visit(ArrayInitializerAST *ast) { for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + FullySpecifiedType exprTy = semantic()->check(it->value, _scope); } return false; } @@ -206,17 +198,19 @@ bool CheckExpression::visit(NewExpressionAST *ast) { if (ast->new_placement) { for (ExpressionListAST *it = ast->new_placement->expression_list; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + FullySpecifiedType exprTy = semantic()->check(it->value, _scope); } } FullySpecifiedType typeIdTy = semantic()->check(ast->type_id, _scope); if (ast->new_type_id) { - FullySpecifiedType ty = semantic()->check(ast->new_type_id->type_specifier, _scope); + FullySpecifiedType ty = semantic()->check(ast->new_type_id->type_specifier_list, _scope); - for (NewArrayDeclaratorAST *it = ast->new_type_id->new_array_declarators; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + for (NewArrayDeclaratorListAST *it = ast->new_type_id->new_array_declarator_list; it; it = it->next) { + if (NewArrayDeclaratorAST *declarator = it->value) { + FullySpecifiedType exprTy = semantic()->check(declarator->expression, _scope); + } } } @@ -239,7 +233,7 @@ bool CheckExpression::visit(TypenameCallExpressionAST *ast) (void) semantic()->check(ast->name, _scope); for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + FullySpecifiedType exprTy = semantic()->check(it->value, _scope); (void) exprTy; } return false; @@ -247,9 +241,9 @@ bool CheckExpression::visit(TypenameCallExpressionAST *ast) bool CheckExpression::visit(TypeConstructorCallAST *ast) { - FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier, _scope); + FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + FullySpecifiedType exprTy = semantic()->check(it->value, _scope); } return false; } @@ -257,8 +251,8 @@ bool CheckExpression::visit(TypeConstructorCallAST *ast) bool CheckExpression::visit(PostfixExpressionAST *ast) { FullySpecifiedType exprTy = semantic()->check(ast->base_expression, _scope); - for (PostfixAST *fx = ast->postfix_expressions; fx; fx = fx->next) { - accept(fx); // ### not exactly. + for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next) { + accept(it->value); // ### not exactly. } return false; } @@ -307,7 +301,7 @@ bool CheckExpression::visit(ThrowExpressionAST *ast) bool CheckExpression::visit(TypeIdAST *ast) { - FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier, _scope); + FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope); FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope); _fullySpecifiedType = declTy; @@ -350,7 +344,7 @@ bool CheckExpression::visit(CompoundLiteralAST *ast) bool CheckExpression::visit(CallAST *ast) { for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { - FullySpecifiedType exprTy = semantic()->check(it->expression, _scope); + FullySpecifiedType exprTy = semantic()->check(it->value, _scope); } return false; } @@ -374,10 +368,10 @@ bool CheckExpression::visit(MemberAccessAST *ast) bool CheckExpression::visit(ObjCMessageExpressionAST *ast) { - semantic()->check(ast->receiver_expression, _scope); + (void) semantic()->check(ast->receiver_expression, _scope); (void) semantic()->check(ast->selector, _scope); - accept(ast->argument_list); + accept(ast->argument_list); // ### not necessary. return false; } diff --git a/src/shared/cplusplus/CheckExpression.h b/src/shared/cplusplus/CheckExpression.h index a61371db43..2ef3a62903 100644 --- a/src/shared/cplusplus/CheckExpression.h +++ b/src/shared/cplusplus/CheckExpression.h @@ -71,7 +71,6 @@ protected: using ASTVisitor::visit; - virtual bool visit(ExpressionListAST *ast); virtual bool visit(BinaryExpressionAST *ast); virtual bool visit(CastExpressionAST *ast); virtual bool visit(ConditionAST *ast); diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp index 19e2eedf98..6476b3295f 100644 --- a/src/shared/cplusplus/CheckName.cpp +++ b/src/shared/cplusplus/CheckName.cpp @@ -82,17 +82,19 @@ Name *CheckName::check(NameAST *name, Scope *scope) return switchName(previousName); } -Name *CheckName::check(NestedNameSpecifierAST *nested_name_specifier, Scope *scope) +Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_list, Scope *scope) { Name *previousName = switchName(0); Scope *previousScope = switchScope(scope); std::vector<Name *> names; - for (NestedNameSpecifierAST *it = nested_name_specifier; - it; it = it->next) { - names.push_back(semantic()->check(it->class_or_namespace_name, _scope)); + for (NestedNameSpecifierListAST *it = nested_name_specifier_list; it; it = it->next) { + NestedNameSpecifierAST *nested_name_specifier = it->value; + names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope)); } - _name = control()->qualifiedNameId(&names[0], names.size()); + + if (! names.empty()) + _name = control()->qualifiedNameId(&names[0], names.size()); (void) switchScope(previousScope); return switchName(previousName); @@ -137,9 +139,9 @@ Scope *CheckName::switchScope(Scope *scope) bool CheckName::visit(QualifiedNameAST *ast) { std::vector<Name *> names; - for (NestedNameSpecifierAST *it = ast->nested_name_specifier; - it; it = it->next) { - names.push_back(semantic()->check(it->class_or_namespace_name, _scope)); + for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) { + NestedNameSpecifierAST *nested_name_specifier = it->value; + names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope)); } names.push_back(semantic()->check(ast->unqualified_name, _scope)); _name = control()->qualifiedNameId(&names[0], names.size(), @@ -333,8 +335,8 @@ bool CheckName::visit(OperatorFunctionIdAST *ast) bool CheckName::visit(ConversionFunctionIdAST *ast) { - FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope); - ty = semantic()->check(ast->ptr_operators, ty, _scope); + FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); + ty = semantic()->check(ast->ptr_operator_list, ty, _scope); _name = control()->conversionNameId(ty); return false; } @@ -359,9 +361,9 @@ bool CheckName::visit(TemplateIdAST *ast) { Identifier *id = identifier(ast->identifier_token); std::vector<FullySpecifiedType> templateArguments; - for (TemplateArgumentListAST *it = ast->template_arguments; it; + for (TemplateArgumentListAST *it = ast->template_argument_list; it; it = it->next) { - ExpressionAST *arg = it->template_argument; + ExpressionAST *arg = it->value; FullySpecifiedType exprTy = semantic()->check(arg, _scope); templateArguments.push_back(exprTy); } @@ -377,8 +379,9 @@ bool CheckName::visit(TemplateIdAST *ast) bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast) { std::vector<Name *> names; - Identifier *id = identifier(ast->name_token); - names.push_back(control()->nameId(id)); + Identifier *id = control()->findOrInsertIdentifier(spell(ast->name_token)); + NameId *nameId = control()->nameId(id); + names.push_back(nameId); _name = control()->selectorNameId(&names[0], names.size(), false); ast->selector_name = _name; @@ -388,11 +391,10 @@ bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast) bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast) { std::vector<Name *> names; - for (ObjCSelectorArgumentListAST *it = ast->selector_arguments; it; it = it->next) { - Identifier *id = identifier(it->argument->name_token); - Name *name = control()->nameId(id); - - names.push_back(name); + for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) { + Identifier *id = control()->findOrInsertIdentifier(spell(it->value->name_token)); + NameId *nameId = control()->nameId(id); + names.push_back(nameId); } if (!names.empty()) { diff --git a/src/shared/cplusplus/CheckName.h b/src/shared/cplusplus/CheckName.h index ec2b97beea..7f86d75167 100644 --- a/src/shared/cplusplus/CheckName.h +++ b/src/shared/cplusplus/CheckName.h @@ -62,7 +62,7 @@ public: virtual ~CheckName(); Name *check(NameAST *name, Scope *scope); - Name *check(NestedNameSpecifierAST *name, Scope *scope); + Name *check(NestedNameSpecifierListAST *name, Scope *scope); Name *check(ObjCSelectorAST *args, Scope *scope); void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope); diff --git a/src/shared/cplusplus/CheckSpecifier.cpp b/src/shared/cplusplus/CheckSpecifier.cpp index 6baef4682e..c7604c5ee6 100644 --- a/src/shared/cplusplus/CheckSpecifier.cpp +++ b/src/shared/cplusplus/CheckSpecifier.cpp @@ -69,11 +69,11 @@ CheckSpecifier::CheckSpecifier(Semantic *semantic) CheckSpecifier::~CheckSpecifier() { } -FullySpecifiedType CheckSpecifier::check(SpecifierAST *specifier, Scope *scope) +FullySpecifiedType CheckSpecifier::check(SpecifierListAST *specifier, Scope *scope) { FullySpecifiedType previousType = switchFullySpecifiedType(FullySpecifiedType()); Scope *previousScope = switchScope(scope); - SpecifierAST *previousSpecifier = switchSpecifier(specifier); + SpecifierListAST *previousSpecifier = switchSpecifier(specifier); accept(specifier); (void) switchSpecifier(previousSpecifier); (void) switchScope(previousScope); @@ -91,14 +91,14 @@ FullySpecifiedType CheckSpecifier::check(ObjCTypeNameAST *typeName, Scope *scope return switchFullySpecifiedType(previousType); } -SpecifierAST *CheckSpecifier::switchSpecifier(SpecifierAST *specifier) +SpecifierListAST *CheckSpecifier::switchSpecifier(SpecifierListAST *specifier) { - SpecifierAST *previousSpecifier = _specifier; + SpecifierListAST *previousSpecifier = _specifier; _specifier = specifier; return previousSpecifier; } -FullySpecifiedType CheckSpecifier::switchFullySpecifiedType(FullySpecifiedType type) +FullySpecifiedType CheckSpecifier::switchFullySpecifiedType(const FullySpecifiedType &type) { FullySpecifiedType previousType = _fullySpecifiedType; _fullySpecifiedType = type; @@ -301,7 +301,7 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast) default: break; } // switch - accept(ast->next); + return false; } @@ -328,7 +328,8 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast) _scope->enterSymbol(klass); _fullySpecifiedType.setType(klass); - for (BaseSpecifierAST *base = ast->base_clause; base; base = base->next) { + for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) { + BaseSpecifierAST *base = it->value; Name *baseClassName = semantic()->check(base->name, _scope); BaseClass *baseClass = control()->newBaseClass(ast->firstToken(), baseClassName); base->symbol = baseClass; @@ -346,14 +347,13 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast) int previousVisibility = semantic()->switchVisibility(visibility); int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod); - for (DeclarationListAST *member = ast->member_specifiers; member; member = member->next) { - semantic()->check(member->declaration, klass->members()); + for (DeclarationListAST *member = ast->member_specifier_list; member; member = member->next) { + semantic()->check(member->value, klass->members()); } (void) semantic()->switchMethodKey(previousMethodKey); (void) semantic()->switchVisibility(previousVisibility); - accept(ast->next); return false; } @@ -361,7 +361,6 @@ bool CheckSpecifier::visit(NamedTypeSpecifierAST *ast) { Name *name = semantic()->check(ast->name, _scope); _fullySpecifiedType.setType(control()->namedType(name)); - accept(ast->next); return false; } @@ -369,7 +368,6 @@ bool CheckSpecifier::visit(ElaboratedTypeSpecifierAST *ast) { Name *name = semantic()->check(ast->name, _scope); _fullySpecifiedType.setType(control()->namedType(name)); - accept(ast->next); return false; } @@ -386,8 +384,8 @@ bool CheckSpecifier::visit(EnumSpecifierAST *ast) e->setVisibility(semantic()->currentVisibility()); _scope->enterSymbol(e); _fullySpecifiedType.setType(e); - for (EnumeratorAST *enumerator = ast->enumerators; enumerator; - enumerator = enumerator->next) { + for (EnumeratorListAST *it = ast->enumerator_list; it; it = it->next) { + EnumeratorAST *enumerator = it->value; Identifier *id = identifier(enumerator->identifier_token); if (! id) continue; @@ -396,20 +394,17 @@ bool CheckSpecifier::visit(EnumSpecifierAST *ast) enumeratorName); e->addMember(decl); } - accept(ast->next); return false; } bool CheckSpecifier::visit(TypeofSpecifierAST *ast) { semantic()->check(ast->expression, _scope); - accept(ast->next); return false; } bool CheckSpecifier::visit(AttributeSpecifierAST *ast) { - accept(ast->next); return false; } diff --git a/src/shared/cplusplus/CheckSpecifier.h b/src/shared/cplusplus/CheckSpecifier.h index 9f06a43771..4a46d90174 100644 --- a/src/shared/cplusplus/CheckSpecifier.h +++ b/src/shared/cplusplus/CheckSpecifier.h @@ -62,12 +62,12 @@ public: CheckSpecifier(Semantic *semantic); virtual ~CheckSpecifier(); - FullySpecifiedType check(SpecifierAST *specifier, Scope *scope); + FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope); FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope); protected: - SpecifierAST *switchSpecifier(SpecifierAST *specifier); - FullySpecifiedType switchFullySpecifiedType(FullySpecifiedType type); + SpecifierListAST *switchSpecifier(SpecifierListAST *specifier); + FullySpecifiedType switchFullySpecifiedType(const FullySpecifiedType &type); Scope *switchScope(Scope *scope); using ASTVisitor::visit; @@ -83,7 +83,7 @@ protected: virtual bool visit(ObjCTypeNameAST *ast); private: - SpecifierAST *_specifier; + SpecifierListAST *_specifier; FullySpecifiedType _fullySpecifiedType; Scope *_scope; }; diff --git a/src/shared/cplusplus/CheckStatement.cpp b/src/shared/cplusplus/CheckStatement.cpp index 79a4e2e33d..1273f81610 100644 --- a/src/shared/cplusplus/CheckStatement.cpp +++ b/src/shared/cplusplus/CheckStatement.cpp @@ -104,8 +104,8 @@ bool CheckStatement::visit(CompoundStatementAST *ast) ast->symbol = block; _scope->enterSymbol(block); Scope *previousScope = switchScope(block->members()); - for (StatementListAST *it = ast->statements; it; it = it->next) { - semantic()->check(it->statement, _scope); + for (StatementListAST *it = ast->statement_list; it; it = it->next) { + semantic()->check(it->value, _scope); } (void) switchScope(previousScope); return false; @@ -149,8 +149,8 @@ bool CheckStatement::visit(ForeachStatementAST *ast) ast->symbol = block; _scope->enterSymbol(block); Scope *previousScope = switchScope(block->members()); - if (ast->type_specifiers && ast->declarator) { - FullySpecifiedType ty = semantic()->check(ast->type_specifiers, _scope); + if (ast->type_specifier_list && ast->declarator) { + FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); Name *name = 0; ty = semantic()->check(ast->declarator, ty, _scope, &name); unsigned location = ast->declarator->firstToken(); @@ -178,8 +178,8 @@ bool CheckStatement::visit(ObjCFastEnumerationAST *ast) ast->symbol = block; _scope->enterSymbol(block); Scope *previousScope = switchScope(block->members()); - if (ast->type_specifiers && ast->declarator) { - FullySpecifiedType ty = semantic()->check(ast->type_specifiers, _scope); + if (ast->type_specifier_list && ast->declarator) { + FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); Name *name = 0; ty = semantic()->check(ast->declarator, ty, _scope, &name); unsigned location = ast->declarator->firstToken(); @@ -273,8 +273,8 @@ bool CheckStatement::visit(SwitchStatementAST *ast) bool CheckStatement::visit(TryBlockStatementAST *ast) { semantic()->check(ast->statement, _scope); - for (CatchClauseAST *c = ast->catch_clause_seq; c; c = c->next) { - semantic()->check(c, _scope); + for (CatchClauseListAST *it = ast->catch_clause_list; it; it = it->next) { + semantic()->check(it->value, _scope); } return false; } diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp index 249d671ae1..d2b91e14a2 100644 --- a/src/shared/cplusplus/Control.cpp +++ b/src/shared/cplusplus/Control.cpp @@ -129,6 +129,7 @@ public: delete_array_entries(objcForwardClassDeclarations); delete_array_entries(objcForwardProtocolDeclarations); delete_array_entries(objcMethods); + delete_array_entries(objcPropertyDeclarations); } NameId *findOrInsertNameId(Identifier *id) @@ -393,6 +394,13 @@ public: return method; } + ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name) + { + ObjCPropertyDeclaration *decl = new ObjCPropertyDeclaration(translationUnit, sourceLocation, name); + objcPropertyDeclarations.push_back(decl); + return decl; + } + Enum *newEnum(unsigned sourceLocation, Name *name) { Enum *e = new Enum(translationUnit, @@ -577,6 +585,7 @@ public: std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations; std::vector<ObjCForwardProtocolDeclaration *> objcForwardProtocolDeclarations; std::vector<ObjCMethod *> objcMethods; + std::vector<ObjCPropertyDeclaration *> objcPropertyDeclarations; // ObjC context keywords: Identifier *objcGetterId; @@ -787,6 +796,9 @@ ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsig ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, Name *name) { return d->newObjCMethod(sourceLocation, name); } +ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(unsigned sourceLocation, Name *name) +{ return d->newObjCPropertyDeclaration(sourceLocation, name); } + Identifier *Control::objcGetterId() const { return d->objcGetterId; } diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h index d4db273e43..6abeb8ef6d 100644 --- a/src/shared/cplusplus/Control.h +++ b/src/shared/cplusplus/Control.h @@ -169,6 +169,9 @@ public: /// Creates a new Objective-C method symbol. ObjCMethod *newObjCMethod(unsigned sourceLocation, Name *name = 0); + /// Creates a new Objective-C @property declaration symbol. + ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name); + // Objective-C specific context keywords. Identifier *objcGetterId() const; Identifier *objcSetterId() const; diff --git a/src/shared/cplusplus/Names.cpp b/src/shared/cplusplus/Names.cpp index 9e60804e77..973e8d8366 100644 --- a/src/shared/cplusplus/Names.cpp +++ b/src/shared/cplusplus/Names.cpp @@ -289,7 +289,9 @@ void SelectorNameId::accept0(NameVisitor *visitor) Identifier *SelectorNameId::identifier() const { - // FIXME: (EV) + if (! _nameCount) + return 0; + return nameAt(0)->identifier(); } diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp index 988076f3a7..654ce88104 100644 --- a/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp +++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp @@ -32,27 +32,88 @@ using namespace CPlusPlus; static inline int classify2(const char *s) { - if (s[0] == 'i') { - if (s[1] == 'n') { - return Token_in; + if (s[0] == 'N') { + if (s[1] == 'O') { + return Token_NO; + } } - } - return Token_identifier; + else if (s[0] == 'i') { + if (s[1] == 'd') { + return Token_id; + } + else if (s[1] == 'n') { + return Token_in; + } + } + return Token_identifier; } static inline int classify3(const char *s) { - if (s[0] == 'o') { - if (s[1] == 'u') { - if (s[2] == 't') { - return Token_out; - } + if (s[0] == 'I') { + if (s[1] == 'M') { + if (s[2] == 'P') { + return Token_IMP; + } + } } - } - return Token_identifier; + else if (s[0] == 'N') { + if (s[1] == 'i') { + if (s[2] == 'l') { + return Token_Nil; + } + } + } + else if (s[0] == 'S') { + if (s[1] == 'E') { + if (s[2] == 'L') { + return Token_SEL; + } + } + } + else if (s[0] == 'Y') { + if (s[1] == 'E') { + if (s[2] == 'S') { + return Token_YES; + } + } + } + else if (s[0] == 'n') { + if (s[1] == 'i') { + if (s[2] == 'l') { + return Token_nil; + } + } + } + else if (s[0] == 'o') { + if (s[1] == 'u') { + if (s[2] == 't') { + return Token_out; + } + } + } + return Token_identifier; } static inline int classify4(const char *s) { - if (s[0] == 'c') { + if (s[0] == '_') { + if (s[1] == 'c') { + if (s[2] == 'm') { + if (s[3] == 'd') { + return Token__cmd; + } + } + } + } + else if (s[0] == 'B') { + if (s[1] == 'O') { + if (s[2] == 'O') { + if (s[3] == 'L') { + return Token_BOOL; + } + } + } + } + else if (s[0] == 'c') { if (s[1] == 'o') { if (s[2] == 'p') { if (s[3] == 'y') { @@ -61,6 +122,15 @@ static inline int classify4(const char *s) { } } } + else if (s[0] == 's') { + if (s[1] == 'e') { + if (s[2] == 'l') { + if (s[3] == 'f') { + return Token_self; + } + } + } + } return Token_identifier; } @@ -87,6 +157,17 @@ static inline int classify5(const char *s) { } } } + else if (s[0] == 's') { + if (s[1] == 'u') { + if (s[2] == 'p') { + if (s[3] == 'e') { + if (s[4] == 'r') { + return Token_super; + } + } + } + } + } return Token_identifier; } diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.h b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h index d0db427461..731dd9c6af 100644 --- a/src/shared/cplusplus/ObjectiveCTypeQualifiers.h +++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h @@ -35,11 +35,22 @@ namespace CPlusPlus { enum { + Token_NO, + Token_id, Token_in, + Token_YES, + Token_IMP, + Token_Nil, + Token_SEL, + Token_nil, Token_out, + Token__cmd, + Token_BOOL, Token_copy, + Token_self, Token_byref, Token_inout, + Token_super, Token_assign, Token_bycopy, Token_getter, diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index ca26cb629e..89694bab59 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -334,7 +334,7 @@ bool Parser::parseTemplateId(NameAST *&node) ast->identifier_token = consumeToken(); ast->less_token = consumeToken(); if (LA() == T_GREATER || parseTemplateArgumentList( - ast->template_arguments)) { + ast->template_argument_list)) { if (LA() == T_GREATER) { ast->greater_token = consumeToken(); node = ast; @@ -348,28 +348,30 @@ bool Parser::parseTemplateId(NameAST *&node) return false; } -bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node, +bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool /*acceptTemplateId*/) { DEBUG_THIS_RULE(); - NestedNameSpecifierAST **nested_name_specifier = &node; + NestedNameSpecifierListAST **nested_name_specifier = &node; NameAST *class_or_namespace_name = 0; - if (parseClassOrNamespaceName(class_or_namespace_name) && - LA() == T_COLON_COLON) { + if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) { unsigned scope_token = consumeToken(); - *nested_name_specifier = new (_pool) NestedNameSpecifierAST; - (*nested_name_specifier)->class_or_namespace_name - = class_or_namespace_name; - (*nested_name_specifier)->scope_token = scope_token; + NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST; + name->class_or_namespace_name = class_or_namespace_name; + name->scope_token = scope_token; + + *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name); nested_name_specifier = &(*nested_name_specifier)->next; - while (parseClassOrNamespaceName(class_or_namespace_name) && - LA() == T_COLON_COLON) { + while (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) { scope_token = consumeToken(); - *nested_name_specifier = new (_pool) NestedNameSpecifierAST; - (*nested_name_specifier)->class_or_namespace_name = class_or_namespace_name; - (*nested_name_specifier)->scope_token = scope_token; + + name = new (_pool) NestedNameSpecifierAST; + name->class_or_namespace_name = class_or_namespace_name; + name->scope_token = scope_token; + + *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name); nested_name_specifier = &(*nested_name_specifier)->next; } @@ -382,8 +384,7 @@ bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node, return false; } -bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, - bool acceptTemplateId) +bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId) { DEBUG_THIS_RULE(); unsigned start = cursor(); @@ -399,7 +400,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId) if (LA() == T_COLON_COLON) global_scope_token = consumeToken(); - NestedNameSpecifierAST *nested_name_specifier = 0; + NestedNameSpecifierListAST *nested_name_specifier = 0; parseNestedNameSpecifierOpt(nested_name_specifier, /*acceptTemplateId=*/ true); @@ -413,7 +414,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId) QualifiedNameAST *ast = new (_pool) QualifiedNameAST; ast->global_scope_token = global_scope_token; - ast->nested_name_specifier = nested_name_specifier; + ast->nested_name_specifier_list = nested_name_specifier; ast->unqualified_name = unqualified_name; node = ast; return true; @@ -426,7 +427,7 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node) { DEBUG_THIS_RULE(); TranslationUnitAST *ast = new (_pool) TranslationUnitAST; - DeclarationListAST **decl = &ast->declarations; + DeclarationListAST **decl = &ast->declaration_list; while (LA()) { unsigned start_declaration = cursor(); @@ -435,7 +436,7 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node) if (parseDeclaration(declaration)) { *decl = new (_pool) DeclarationListAST; - (*decl)->declaration = declaration; + (*decl)->value = declaration; decl = &(*decl)->next; } else { rewind(start_declaration + 1); @@ -501,7 +502,7 @@ bool Parser::parseDeclaration(DeclarationAST *&node) default: { if (_objCEnabled && LA() == T___ATTRIBUTE__) { const unsigned start = cursor(); - SpecifierAST *attributes = 0, **attr = &attributes; + SpecifierListAST *attributes = 0, **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; if (LA() == T_AT_INTERFACE) @@ -552,7 +553,7 @@ bool Parser::parseLinkageBody(DeclarationAST *&node) if (LA() == T_LBRACE) { LinkageBodyAST *ast = new (_pool) LinkageBodyAST; ast->lbrace_token = consumeToken(); - DeclarationListAST **declaration_ptr = &ast->declarations; + DeclarationListAST **declaration_ptr = &ast->declaration_list; while (int tk = LA()) { if (tk == T_RBRACE) @@ -562,7 +563,7 @@ bool Parser::parseLinkageBody(DeclarationAST *&node) DeclarationAST *declaration = 0; if (parseDeclaration(declaration)) { *declaration_ptr = new (_pool) DeclarationListAST; - (*declaration_ptr)->declaration = declaration; + (*declaration_ptr)->value = declaration; declaration_ptr = &(*declaration_ptr)->next; } else { rewind(start_declaration + 1); @@ -601,7 +602,7 @@ bool Parser::parseNamespace(DeclarationAST *&node) ast->namespace_token = namespace_token; if (LA() == T_IDENTIFIER) ast->identifier_token = consumeToken(); - SpecifierAST **attr_ptr = &ast->attributes; + SpecifierListAST **attr_ptr = &ast->attribute_list; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attr_ptr); attr_ptr = &(*attr_ptr)->next; @@ -656,18 +657,18 @@ bool Parser::parseConversionFunctionId(NameAST *&node) if (LA() != T_OPERATOR) return false; unsigned operator_token = consumeToken(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (! parseTypeSpecifier(type_specifier)) { return false; } - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; ConversionFunctionIdAST *ast = new (_pool) ConversionFunctionIdAST; ast->operator_token = operator_token; - ast->type_specifier = type_specifier; - ast->ptr_operators = ptr_operators; + ast->type_specifier_list = type_specifier; + ast->ptr_operator_list = ptr_operators; node = ast; return true; } @@ -716,15 +717,14 @@ bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node) ExpressionAST *template_argument = 0; if (parseTemplateArgument(template_argument)) { *template_argument_ptr = new (_pool) TemplateArgumentListAST; - (*template_argument_ptr)->template_argument = template_argument; + (*template_argument_ptr)->value = template_argument; template_argument_ptr = &(*template_argument_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA if (parseTemplateArgument(template_argument)) { *template_argument_ptr = new (_pool) TemplateArgumentListAST; - (*template_argument_ptr)->comma_token = comma_token; - (*template_argument_ptr)->template_argument = template_argument; + (*template_argument_ptr)->value = template_argument; template_argument_ptr = &(*template_argument_ptr)->next; } } @@ -850,7 +850,7 @@ bool Parser::parseTemplateDeclaration(DeclarationAST *&node) if (LA() == T_LESS) { ast->less_token = consumeToken(); - if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameters)) + if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list)) match(T_GREATER, &ast->greater_token); } @@ -931,11 +931,13 @@ bool Parser::parseOperator(OperatorAST *&node) // ### FIXME return true; } -bool Parser::parseCvQualifiers(SpecifierAST *&node) +bool Parser::parseCvQualifiers(SpecifierListAST *&node) { DEBUG_THIS_RULE(); + unsigned start = cursor(); - SpecifierAST **ast = &node; + + SpecifierListAST **ast = &node; while (*ast) ast = &(*ast)->next; @@ -943,7 +945,7 @@ bool Parser::parseCvQualifiers(SpecifierAST *&node) if (tk == T_CONST || tk == T_VOLATILE) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *ast = spec; + *ast = new (_pool) SpecifierListAST(spec); ast = &(*ast)->next; } else if(LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*ast); @@ -956,19 +958,19 @@ bool Parser::parseCvQualifiers(SpecifierAST *&node) return start != cursor(); } -bool Parser::parsePtrOperator(PtrOperatorAST *&node) +bool Parser::parsePtrOperator(PtrOperatorListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_AMPER) { ReferenceAST *ast = new (_pool) ReferenceAST; ast->amp_token = consumeToken(); - node = ast; + node = new (_pool) PtrOperatorListAST(ast); return true; } else if (LA() == T_STAR) { PointerAST *ast = new (_pool) PointerAST; ast->star_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - node = ast; + parseCvQualifiers(ast->cv_qualifier_list); + node = new (_pool) PtrOperatorListAST(ast); return true; } else if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER) { unsigned scope_or_identifier_token = cursor(); @@ -977,16 +979,15 @@ bool Parser::parsePtrOperator(PtrOperatorAST *&node) if (LA() == T_COLON_COLON) global_scope_token = consumeToken(); - NestedNameSpecifierAST *nested_name_specifier = 0; - bool has_nested_name_specifier = parseNestedNameSpecifier( - nested_name_specifier, true); + NestedNameSpecifierListAST *nested_name_specifiers = 0; + bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true); if (has_nested_name_specifier && LA() == T_STAR) { PointerToMemberAST *ast = new (_pool) PointerToMemberAST; ast->global_scope_token = global_scope_token; - ast->nested_name_specifier = nested_name_specifier; + ast->nested_name_specifier_list = nested_name_specifiers; ast->star_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - node = ast; + parseCvQualifiers(ast->cv_qualifier_list); + node = new (_pool) PtrOperatorListAST(ast); return true; } rewind(scope_or_identifier_token); @@ -1008,24 +1009,24 @@ bool Parser::parseTemplateArgument(ExpressionAST *&node) return parsed; } -bool Parser::parseDeclSpecifierSeq(SpecifierAST *&decl_specifier_seq, +bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq, bool onlyTypeSpecifiers, bool simplified) { DEBUG_THIS_RULE(); bool has_type_specifier = false; NameAST *named_type_specifier = 0; - SpecifierAST **decl_specifier_seq_ptr = &decl_specifier_seq; + SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq; for (;;) { if (lookAtCVQualifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (! onlyTypeSpecifiers && lookAtStorageClassSpecifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (! named_type_specifier && lookAtBuiltinTypeSpecifier()) { parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr); @@ -1037,7 +1038,7 @@ bool Parser::parseDeclSpecifierSeq(SpecifierAST *&decl_specifier_seq, return false; NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; spec->name = named_type_specifier; - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; } else if (! simplified && ! has_type_specifier && (LA() == T_TYPENAME || @@ -1076,14 +1077,14 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) { DEBUG_THIS_RULE(); unsigned start = cursor(); - SpecifierAST *attributes = 0; - SpecifierAST **attribute_ptr = &attributes; + SpecifierListAST *attributes = 0; + SpecifierListAST **attribute_ptr = &attributes; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attribute_ptr); attribute_ptr = &(*attribute_ptr)->next; } - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; @@ -1094,8 +1095,8 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) DeclaratorIdAST *declarator_id = new (_pool) DeclaratorIdAST; declarator_id->name = name; DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->attributes = attributes; - ast->ptr_operators = ptr_operators; + ast->attribute_list = attributes; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = declarator_id; node = ast; return true; @@ -1112,7 +1113,7 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) nested_declarator->declarator = declarator; nested_declarator->rparen_token = consumeToken(); DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = nested_declarator; node = ast; return true; @@ -1128,7 +1129,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) if (! parseCoreDeclarator(node)) return false; - PostfixDeclaratorAST **postfix_ptr = &node->postfix_declarators; + PostfixDeclaratorListAST **postfix_ptr = &node->postfix_declarator_list; for (;;) { unsigned startOfPostDeclarator = cursor(); @@ -1156,7 +1157,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) ast->parameters = parameter_declaration_clause; ast->as_cpp_initializer = initializer; ast->rparen_token = rparen_token; - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; blockErrors(blocked); @@ -1184,9 +1185,9 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) } ast->rparen_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); + parseCvQualifiers(ast->cv_qualifier_list); parseExceptionSpecification(ast->exception_specification); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST; @@ -1194,7 +1195,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) { match(T_RBRACKET, &ast->rbracket_token); } - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; @@ -1208,7 +1209,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) consumeToken(); // skip T_RPAREN } - SpecifierAST **spec_ptr = &node->post_attributes; + SpecifierListAST **spec_ptr = &node->post_attribute_list; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*spec_ptr); spec_ptr = &(*spec_ptr)->next; @@ -1220,7 +1221,8 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) { DEBUG_THIS_RULE(); - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; @@ -1235,7 +1237,7 @@ bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) nested_declarator->declarator = declarator; nested_declarator->rparen_token = consumeToken(); DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = nested_declarator; node = ast; return true; @@ -1245,7 +1247,7 @@ bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) rewind(after_ptr_operators); if (ptr_operators) { DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; node = ast; } @@ -1258,7 +1260,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (! parseAbstractCoreDeclarator(node)) return false; - PostfixDeclaratorAST *postfix_declarators = 0, + PostfixDeclaratorListAST *postfix_declarators = 0, **postfix_ptr = &postfix_declarators; for (;;) { @@ -1269,9 +1271,9 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (LA() == T_RPAREN) ast->rparen_token = consumeToken(); } - parseCvQualifiers(ast->cv_qualifier_seq); + parseCvQualifiers(ast->cv_qualifier_list); parseExceptionSpecification(ast->exception_specification); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST; @@ -1280,7 +1282,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (LA() == T_RBRACKET) ast->rbracket_token = consumeToken(); } - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; @@ -1290,13 +1292,13 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (! node) node = new (_pool) DeclaratorAST; - node->postfix_declarators = postfix_declarators; + node->postfix_declarator_list = postfix_declarators; } return true; } -bool Parser::parseEnumSpecifier(SpecifierAST *&node) +bool Parser::parseEnumSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_ENUM) { @@ -1309,7 +1311,7 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) ast->name = name; ast->lbrace_token = consumeToken(); unsigned comma_token = 0; - EnumeratorAST **enumerator_ptr = &ast->enumerators; + EnumeratorListAST **enumerator_ptr = &ast->enumerator_list; while (int tk = LA()) { if (tk == T_RBRACE) break; @@ -1320,7 +1322,6 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) } if (parseEnumerator(*enumerator_ptr)) { - (*enumerator_ptr)->comma_token = comma_token; enumerator_ptr = &(*enumerator_ptr)->next; } @@ -1328,7 +1329,7 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) match(T_COMMA, &comma_token); } match(T_RBRACE, &ast->rbrace_token); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } } @@ -1342,7 +1343,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node) DeclarationAST *declaration = 0; if (parseTemplateParameter(declaration)) { *template_parameter_ptr = new (_pool) DeclarationListAST; - (*template_parameter_ptr)->declaration = declaration; + (*template_parameter_ptr)->value = declaration; template_parameter_ptr = &(*template_parameter_ptr)->next; while (LA() == T_COMMA) { @@ -1351,7 +1352,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node) declaration = 0; if (parseTemplateParameter(declaration)) { *template_parameter_ptr = new (_pool) DeclarationListAST; - (*template_parameter_ptr)->declaration = declaration; + (*template_parameter_ptr)->value = declaration; template_parameter_ptr = &(*template_parameter_ptr)->next; } } @@ -1396,7 +1397,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node) ast->template_token = consumeToken(); if (LA() == T_LESS) ast->less_token = consumeToken(); - parseTemplateParameterList(ast->template_parameters); + parseTemplateParameterList(ast->template_parameter_list); if (LA() == T_GREATER) ast->greater_token = consumeToken(); if (LA() == T_CLASS) @@ -1429,10 +1430,10 @@ bool Parser::parseTypeParameter(DeclarationAST *&node) bool Parser::parseTypeId(ExpressionAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { TypeIdAST *ast = new (_pool) TypeIdAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; parseAbstractDeclarator(ast->declarator); node = ast; return true; @@ -1464,7 +1465,7 @@ bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&nod if (parameter_declarations || dot_dot_dot_token) { ParameterDeclarationClauseAST *ast = new (_pool) ParameterDeclarationClauseAST; - ast->parameter_declarations = parameter_declarations; + ast->parameter_declaration_list = parameter_declarations; ast->dot_dot_dot_token = dot_dot_dot_token; node = ast; } @@ -1482,7 +1483,7 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) DeclarationAST *declaration = 0; if (parseParameterDeclaration(declaration)) { *parameter_declaration_ptr = new (_pool) DeclarationListAST; - (*parameter_declaration_ptr)->declaration = declaration; + (*parameter_declaration_ptr)->value = declaration; parameter_declaration_ptr = &(*parameter_declaration_ptr)->next; while (LA() == T_COMMA) { consumeToken(); @@ -1493,7 +1494,7 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) declaration = 0; if (parseParameterDeclaration(declaration)) { *parameter_declaration_ptr = new (_pool) DeclarationListAST; - (*parameter_declaration_ptr)->declaration = declaration; + (*parameter_declaration_ptr)->value = declaration; parameter_declaration_ptr = &(*parameter_declaration_ptr)->next; } } @@ -1505,10 +1506,10 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) bool Parser::parseParameterDeclaration(DeclarationAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *decl_specifier_seq = 0; + SpecifierListAST *decl_specifier_seq = 0; if (parseDeclSpecifierSeq(decl_specifier_seq)) { ParameterDeclarationAST *ast = new (_pool) ParameterDeclarationAST; - ast->type_specifier = decl_specifier_seq; + ast->type_specifier_list = decl_specifier_seq; parseDeclaratorOrAbstractDeclarator(ast->declarator); if (LA() == T_EQUAL) { ast->equal_token = consumeToken(); @@ -1521,7 +1522,7 @@ bool Parser::parseParameterDeclaration(DeclarationAST *&node) return false; } -bool Parser::parseClassSpecifier(SpecifierAST *&node) +bool Parser::parseClassSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (! lookAtClassKey()) @@ -1529,7 +1530,7 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) unsigned classkey_token = consumeToken(); - SpecifierAST *attributes = 0, **attr_ptr = &attributes; + SpecifierListAST *attributes = 0, **attr_ptr = &attributes; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attr_ptr); attr_ptr = &(*attr_ptr)->next; @@ -1552,17 +1553,23 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) unsigned colon_token = 0; if (LA() == T_COLON || LA() == T_LBRACE) { - BaseSpecifierAST *base_clause = 0; + BaseSpecifierListAST *base_clause_list = 0; + if (LA() == T_COLON) { colon_token = cursor(); - parseBaseClause(base_clause); + + parseBaseClause(base_clause_list); + if (LA() != T_LBRACE) { _translationUnit->error(cursor(), "expected `{' before `%s'", tok().spell()); - unsigned saved = cursor(); + + const unsigned saved = cursor(); + for (int n = 0; n < 3 && LA() != T_EOF_SYMBOL; ++n, consumeToken()) { if (LA() == T_LBRACE) break; } + if (LA() != T_LBRACE) rewind(saved); } @@ -1570,15 +1577,15 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST; ast->classkey_token = classkey_token; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->name = name; ast->colon_token = colon_token; - ast->base_clause = base_clause; + ast->base_clause_list = base_clause_list; if (LA() == T_LBRACE) ast->lbrace_token = consumeToken(); - DeclarationListAST **declaration_ptr = &ast->member_specifiers; + DeclarationListAST **declaration_ptr = &ast->member_specifier_list; while (int tk = LA()) { if (tk == T_RBRACE) { ast->rbrace_token = consumeToken(); @@ -1589,14 +1596,14 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) DeclarationAST *declaration = 0; if (parseMemberSpecification(declaration)) { *declaration_ptr = new (_pool) DeclarationListAST; - (*declaration_ptr)->declaration = declaration; + (*declaration_ptr)->value = declaration; declaration_ptr = &(*declaration_ptr)->next; } else { rewind(start_declaration + 1); skipUntilDeclaration(); } } - node = ast; + node = new (_pool) SpecifierListAST(ast); parsed = true; } @@ -1672,26 +1679,24 @@ bool Parser::parseCtorInitializer(CtorInitializerAST *&node) CtorInitializerAST *ast = new (_pool) CtorInitializerAST; ast->colon_token = colon_token; - parseMemInitializerList(ast->member_initializers); + parseMemInitializerList(ast->member_initializer_list); node = ast; return true; } return false; } -bool Parser::parseElaboratedTypeSpecifier(SpecifierAST *&node) +bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (lookAtClassKey() || LA() == T_ENUM || LA() == T_TYPENAME) { unsigned classkey_token = consumeToken(); NameAST *name = 0; if (parseName(name)) { - ElaboratedTypeSpecifierAST *ast = - new (_pool) ElaboratedTypeSpecifierAST; - + ElaboratedTypeSpecifierAST *ast = new (_pool) ElaboratedTypeSpecifierAST; ast->classkey_token = classkey_token; ast->name = name; - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } } @@ -1709,7 +1714,7 @@ bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) if (LA() == T_DOT_DOT_DOT) ast->dot_dot_dot_token = consumeToken(); else - parseTypeIdList(ast->type_ids); + parseTypeIdList(ast->type_id_list); if (LA() == T_RPAREN) ast->rparen_token = consumeToken(); node = ast; @@ -1718,7 +1723,7 @@ bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) return false; } -bool Parser::parseEnumerator(EnumeratorAST *&node) +bool Parser::parseEnumerator(EnumeratorListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_IDENTIFIER) { @@ -1729,7 +1734,9 @@ bool Parser::parseEnumerator(EnumeratorAST *&node) ast->equal_token = consumeToken(); parseConstantExpression(ast->expression); } - node = ast; + + node = new (_pool) EnumeratorListAST; + node->value = ast; return true; } return false; @@ -1756,7 +1763,7 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, } if (acceptStructDeclarator && node && - ! node->postfix_declarators && + ! node->postfix_declarator_list && node->core_declarator && node->core_declarator->asNestedDeclarator()) { rewind(start); @@ -1764,7 +1771,7 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, } if (acceptStructDeclarator && LA() == T_COLON - && (! node || ! node->postfix_declarators)) { + && (! node || ! node->postfix_declarator_list)) { unsigned colon_token = consumeToken(); ExpressionAST *expression = 0; if (parseConstantExpression(expression) && (LA() == T_COMMA || @@ -1780,23 +1787,22 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, return true; } -bool Parser::parseBaseClause(BaseSpecifierAST *&node) +bool Parser::parseBaseClause(BaseSpecifierListAST *&node) { DEBUG_THIS_RULE(); + if (LA() == T_COLON) { - consumeToken(); + consumeToken(); // ### remove me - BaseSpecifierAST **ast = &node; + BaseSpecifierListAST **ast = &node; if (parseBaseSpecifier(*ast)) { ast = &(*ast)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA - if (parseBaseSpecifier(*ast)) { - (*ast)->comma_token = comma_token; + if (parseBaseSpecifier(*ast)) ast = &(*ast)->next; - } } } @@ -1817,27 +1823,25 @@ bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token) return false; } -bool Parser::parseMemInitializerList(MemInitializerAST *&node) +bool Parser::parseMemInitializerList(MemInitializerListAST *&node) { DEBUG_THIS_RULE(); - MemInitializerAST **initializer = &node; + MemInitializerListAST **initializer = &node; if (parseMemInitializer(*initializer)) { initializer = &(*initializer)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA - if (parseMemInitializer(*initializer)) { - (*initializer)->comma_token = comma_token; + if (parseMemInitializer(*initializer)) initializer = &(*initializer)->next; - } } return true; } return false; } -bool Parser::parseMemInitializer(MemInitializerAST *&node) +bool Parser::parseMemInitializer(MemInitializerListAST *&node) { DEBUG_THIS_RULE(); NameAST *name = 0; @@ -1848,7 +1852,9 @@ bool Parser::parseMemInitializer(MemInitializerAST *&node) parseExpression(ast->expression); if (LA() == T_RPAREN) ast->rparen_token = consumeToken(); - node = ast; + + node = new (_pool) MemInitializerListAST; + node->value = ast; return true; } return false; @@ -1861,14 +1867,14 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node) ExpressionAST *typeId = 0; if (parseTypeId(typeId)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = typeId; + (*expression_list_ptr)->value = typeId; expression_list_ptr = &(*expression_list_ptr)->next; while (LA() == T_COMMA) { consumeToken(); if (parseTypeId(typeId)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = typeId; + (*expression_list_ptr)->value = typeId; expression_list_ptr = &(*expression_list_ptr)->next; } } @@ -1885,15 +1891,14 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) ExpressionAST *expression = 0; if (parseAssignmentExpression(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = expression; + (*expression_list_ptr)->value = expression; expression_list_ptr = &(*expression_list_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA if (parseExpression(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->comma_token = comma_token; - (*expression_list_ptr)->expression = expression; + (*expression_list_ptr)->value = expression; expression_list_ptr = &(*expression_list_ptr)->next; } } @@ -1902,7 +1907,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) return false; } -bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) +bool Parser::parseBaseSpecifier(BaseSpecifierListAST *&node) { DEBUG_THIS_RULE(); BaseSpecifierAST *ast = new (_pool) BaseSpecifierAST; @@ -1925,7 +1930,9 @@ bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) parseName(ast->name); if (! ast->name) _translationUnit->error(cursor(), "expected class-name"); - node = ast; + + node = new (_pool) BaseSpecifierListAST; + node->value = ast; return true; } @@ -1936,15 +1943,14 @@ bool Parser::parseInitializerList(ExpressionListAST *&node) ExpressionAST *initializer = 0; if (parseInitializerClause(initializer)) { *initializer_ptr = new (_pool) ExpressionListAST; - (*initializer_ptr)->expression = initializer; + (*initializer_ptr)->value = initializer; initializer_ptr = &(*initializer_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA initializer = 0; parseInitializerClause(initializer); *initializer_ptr = new (_pool) ExpressionListAST; - (*initializer_ptr)->comma_token = comma_token; - (*initializer_ptr)->expression = initializer; + (*initializer_ptr)->value = initializer; initializer_ptr = &(*initializer_ptr)->next; } } @@ -2163,11 +2169,11 @@ bool Parser::isPointerDeclaration(DeclarationStatementAST *ast) const return false; if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) { - if (SpecifierAST *spec = declaration->decl_specifier_seq) { - if (spec->asNamedTypeSpecifier() && ! spec->next) { - if (DeclaratorListAST *declarators = declaration->declarators) { - if (DeclaratorAST *declarator = declarators->declarator) { - if (declarator->ptr_operators && declarator->equals_token && declarator->initializer) { + if (SpecifierListAST *spec = declaration->decl_specifier_list) { + if (spec->value->asNamedTypeSpecifier() && ! spec->next) { + if (DeclaratorListAST *declarators = declaration->declarator_list) { + if (DeclaratorAST *declarator = declarators->value) { + if (declarator->ptr_operator_list && declarator->equals_token && declarator->initializer) { return true; } } @@ -2185,10 +2191,10 @@ bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast) const return false; if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) { - if (SpecifierAST *spec = declaration->decl_specifier_seq) { - if (spec->asNamedTypeSpecifier() && ! spec->next) { - if (DeclaratorListAST *declarators = declaration->declarators) { - if (DeclaratorAST *declarator = declarators->declarator) { + if (SpecifierListAST *spec = declaration->decl_specifier_list) { + if (spec->value->asNamedTypeSpecifier() && ! spec->next) { + if (DeclaratorListAST *declarators = declaration->declarator_list) { + if (DeclaratorAST *declarator = declarators->value) { if (declarator->core_declarator && declarator->core_declarator->asNestedDeclarator()) { // recognized name(id-expression) @@ -2198,10 +2204,10 @@ bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast) const } } - } else if (DeclaratorListAST *declarators = declaration->declarators) { + } else if (DeclaratorListAST *declarators = declaration->declarator_list) { // no decl_specifiers... - if (DeclaratorAST *declarator = declarators->declarator) { - if (declarator->postfix_declarators && declarator->postfix_declarators->asFunctionDeclarator() + if (DeclaratorAST *declarator = declarators->value) { + if (declarator->postfix_declarator_list && declarator->postfix_declarator_list->value->asFunctionDeclarator() && ! declarator->initializer) { return false; } @@ -2262,13 +2268,13 @@ bool Parser::parseCondition(ExpressionAST *&node) unsigned start = cursor(); bool blocked = blockErrors(true); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { DeclaratorAST *declarator = 0; if (parseInitDeclarator(declarator, /*acceptStructDeclarator=*/false)) { if (declarator->initializer) { ConditionAST *ast = new (_pool) ConditionAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; ast->declarator = declarator; node = ast; blockErrors(blocked); @@ -2327,11 +2333,11 @@ bool Parser::parseForeachStatement(StatementAST *&node) unsigned startOfTypeSpecifier = cursor(); bool blocked = blockErrors(true); - if (parseTypeSpecifier(ast->type_specifiers)) + if (parseTypeSpecifier(ast->type_specifier_list)) parseDeclarator(ast->declarator); - if (! ast->type_specifiers || ! ast->declarator) { - ast->type_specifiers = 0; + if (! ast->type_specifier_list || ! ast->declarator) { + ast->type_specifier_list = 0; ast->declarator = 0; blockErrors(blocked); @@ -2370,20 +2376,20 @@ bool Parser::parseForStatement(StatementAST *&node) ast->for_token = for_token; ast->lparen_token = lparen_token; - if (parseTypeSpecifier(ast->type_specifiers)) + if (parseTypeSpecifier(ast->type_specifier_list)) parseDeclarator(ast->declarator); - if ((ast->type_specifiers || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) { + if ((ast->type_specifier_list || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) { // woops, probably parsed too much: "in" got parsed as a declarator. Let's redo it: - ast->type_specifiers = 0; + ast->type_specifier_list = 0; ast->declarator = 0; rewind(startOfTypeSpecifier); parseDeclarator(ast->declarator); } - if (! ast->type_specifiers || ! ast->declarator) { - ast->type_specifiers = 0; + if (! ast->type_specifier_list || ! ast->declarator) { + ast->type_specifier_list = 0; ast->declarator = 0; rewind(startOfTypeSpecifier); @@ -2435,7 +2441,7 @@ bool Parser::parseCompoundStatement(StatementAST *&node) if (LA() == T_LBRACE) { CompoundStatementAST *ast = new (_pool) CompoundStatementAST; ast->lbrace_token = consumeToken(); - StatementListAST **statement_ptr = &ast->statements; + StatementListAST **statement_ptr = &ast->statement_list; while (int tk = LA()) { if (tk == T_RBRACE) break; @@ -2447,7 +2453,7 @@ bool Parser::parseCompoundStatement(StatementAST *&node) skipUntilStatement(); } else { *statement_ptr = new (_pool) StatementListAST; - (*statement_ptr)->statement = statement; + (*statement_ptr)->value = statement; statement_ptr = &(*statement_ptr)->next; } } @@ -2580,7 +2586,7 @@ bool Parser::parseDeclarationStatement(StatementAST *&node) return false; if (SimpleDeclarationAST *simpleDeclaration = declaration->asSimpleDeclaration()) { - if (! simpleDeclaration->decl_specifier_seq) { + if (! simpleDeclaration->decl_specifier_list) { rewind(start); return false; } @@ -2667,7 +2673,7 @@ bool Parser::lookAtClassKey() const } } -bool Parser::parseAttributeSpecifier(SpecifierAST *&node) +bool Parser::parseAttributeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() != T___ATTRIBUTE__) @@ -2677,45 +2683,35 @@ bool Parser::parseAttributeSpecifier(SpecifierAST *&node) ast->attribute_token = consumeToken(); match(T_LPAREN, &ast->first_lparen_token); match(T_LPAREN, &ast->second_lparen_token); - parseAttributeList(ast->attributes); + parseAttributeList(ast->attribute_list); match(T_RPAREN, &ast->first_rparen_token); match(T_RPAREN, &ast->second_rparen_token); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } -bool Parser::parseAttributeList(AttributeAST *&node) +bool Parser::parseAttributeList(AttributeListAST *&node) // ### create the AST { DEBUG_THIS_RULE(); - AttributeAST **attribute_ptr = &node; - while (LA() == T_IDENTIFIER || LA() == T_CONST) { - AttributeAST *ast = new (_pool) AttributeAST; - ast->identifier_token = consumeToken(); - if (LA() == T_LPAREN) { - ast->lparen_token = consumeToken(); - if (LA() == T_IDENTIFIER && (LA(2) == T_COMMA || LA(2) == T_RPAREN)) { - ast->tag_token = consumeToken(); - if (LA() == T_COMMA) { - ast->comma_token = consumeToken(); - parseExpressionList(ast->expression_list); - } - } else { - parseExpressionList(ast->expression_list); - } - match(T_RPAREN, &ast->rparen_token); + + while (LA() == T_CONST || LA() == T_IDENTIFIER) { + if (LA() == T_CONST) + consumeToken(); + else if (LA() == T_IDENTIFIER) { + ExpressionAST *expression = 0; + parseExpression(expression); } - *attribute_ptr = ast; if (LA() != T_COMMA) break; - consumeToken(); - attribute_ptr = &(*attribute_ptr)->next; + consumeToken(); // skip T_COMMA } + return true; } -bool Parser::parseBuiltinTypeSpecifier(SpecifierAST *&node) +bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T___ATTRIBUTE__) { @@ -2728,18 +2724,18 @@ bool Parser::parseBuiltinTypeSpecifier(SpecifierAST *&node) if (parseTypeId(ast->expression) && LA() == T_RPAREN) { ast->lparen_token = lparen_token; ast->rparen_token = consumeToken(); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } rewind(lparen_token); } parseUnaryExpression(ast->expression); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } else if (lookAtBuiltinTypeSpecifier()) { SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST; ast->specifier_token = consumeToken(); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } return false; @@ -2759,14 +2755,14 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, bool has_complex_type_specifier = false; unsigned startOfNamedTypeSpecifier = 0; NameAST *named_type_specifier = 0; - SpecifierAST *decl_specifier_seq = 0, + SpecifierListAST *decl_specifier_seq = 0, **decl_specifier_seq_ptr = &decl_specifier_seq; for (;;) { if (lookAtCVQualifier() || lookAtFunctionSpecifier() || lookAtStorageClassSpecifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*decl_specifier_seq_ptr); @@ -2781,7 +2777,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, if (parseName(named_type_specifier)) { NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; spec->name = named_type_specifier; - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; } else { @@ -2838,7 +2834,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, rewind(startOfNamedTypeSpecifier); named_type_specifier = 0; // pop the named type specifier from the decl-specifier-seq - SpecifierAST **spec_ptr = &decl_specifier_seq; + SpecifierListAST **spec_ptr = &decl_specifier_seq; for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) { if (! (*spec_ptr)->next) { *spec_ptr = 0; @@ -2859,25 +2855,25 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, if (declarator) { *declarator_ptr = new (_pool) DeclaratorListAST; - (*declarator_ptr)->declarator = declarator; + (*declarator_ptr)->value = declarator; declarator_ptr = &(*declarator_ptr)->next; } if (LA() == T_COMMA || LA() == T_SEMICOLON || has_complex_type_specifier) { while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA + declarator = 0; if (parseInitDeclarator(declarator, acceptStructDeclarator)) { *declarator_ptr = new (_pool) DeclaratorListAST; - (*declarator_ptr)->comma_token = comma_token; - (*declarator_ptr)->declarator = declarator; + (*declarator_ptr)->value = declarator; declarator_ptr = &(*declarator_ptr)->next; } } SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; - ast->declarators = declarator_list; + ast->decl_specifier_list = decl_specifier_seq; + ast->declarator_list = declarator_list; match(T_SEMICOLON, &ast->semicolon_token); node = ast; return true; @@ -2889,7 +2885,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, if (LA() == T_LBRACE) { FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; + ast->decl_specifier_list = decl_specifier_seq; ast->declarator = firstDeclarator; ast->ctor_initializer = ctor_initializer; parseFunctionBody(ast->function_body); @@ -2898,7 +2894,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, } else if (LA() == T_TRY) { FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; + ast->decl_specifier_list = decl_specifier_seq; ast->declarator = firstDeclarator; ast->ctor_initializer = ctor_initializer; parseTryBlockStatement(ast->function_body); @@ -2911,13 +2907,13 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, return false; } -bool Parser::maybeForwardOrClassDeclaration(SpecifierAST *decl_specifier_seq) const +bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const { // look at the decl_specifier for possible fwd or class declarations. - if (SpecifierAST *spec = decl_specifier_seq) { - if (! spec->next && (spec->asElaboratedTypeSpecifier() || - spec->asEnumSpecifier() || - spec->asClassSpecifier())) + if (SpecifierListAST *spec = decl_specifier_seq) { + if (! spec->next && (spec->value->asElaboratedTypeSpecifier() || + spec->value->asEnumSpecifier() || + spec->value->asClassSpecifier())) return true; } @@ -2954,7 +2950,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) TryBlockStatementAST *ast = new (_pool) TryBlockStatementAST; ast->try_token = consumeToken(); parseCompoundStatement(ast->statement); - CatchClauseAST **catch_clause_ptr = &ast->catch_clause_seq; + CatchClauseListAST **catch_clause_ptr = &ast->catch_clause_list; while (parseCatchClause(*catch_clause_ptr)) catch_clause_ptr = &(*catch_clause_ptr)->next; node = ast; @@ -2963,7 +2959,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) return false; } -bool Parser::parseCatchClause(CatchClauseAST *&node) +bool Parser::parseCatchClause(CatchClauseListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_CATCH) { @@ -2973,7 +2969,7 @@ bool Parser::parseCatchClause(CatchClauseAST *&node) parseExceptionDeclaration(ast->exception_declaration); match(T_RPAREN, &ast->rparen_token); parseCompoundStatement(ast->statement); - node = ast; + node = new (_pool) CatchClauseListAST(ast); return true; } return false; @@ -2989,10 +2985,10 @@ bool Parser::parseExceptionDeclaration(ExceptionDeclarationAST *&node) return true; } - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; parseDeclaratorOrAbstractDeclarator(ast->declarator); node = ast; return true; @@ -3189,17 +3185,17 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node) ObjCSelectorWithArgumentsAST *args = new (_pool) ObjCSelectorWithArgumentsAST; ast->selector = args; ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST; - args->selector_arguments = last; - last->argument = new (_pool) ObjCSelectorArgumentAST; - last->argument->name_token = identifier_token; - last->argument->colon_token = consumeToken(); + args->selector_argument_list = last; + last->value = new (_pool) ObjCSelectorArgumentAST; + last->value->name_token = identifier_token; + last->value->colon_token = consumeToken(); while (LA() != T_RPAREN) { last->next = new (_pool) ObjCSelectorArgumentListAST; last = last->next; - last->argument = new (_pool) ObjCSelectorArgumentAST; - match(T_IDENTIFIER, &(last->argument->name_token)); - match(T_COLON, &(last->argument->colon_token)); + last->value = new (_pool) ObjCSelectorArgumentAST; + match(T_IDENTIFIER, &(last->value->name_token)); + match(T_COLON, &(last->value->colon_token)); } } else { ObjCSelectorWithoutArgumentsAST *args = new (_pool) ObjCSelectorWithoutArgumentsAST; @@ -3263,26 +3259,26 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg if (parseObjCSelectorArg(selectorArgument, messageArgument)) { ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST; - selAst->argument = selectorArgument; + selAst->value = selectorArgument; ObjCSelectorArgumentListAST *lastSelector = selAst; ObjCMessageArgumentListAST *argAst = new (_pool) ObjCMessageArgumentListAST; - argAst->arg = messageArgument; + argAst->value = messageArgument; ObjCMessageArgumentListAST *lastArgument = argAst; while (parseObjCSelectorArg(selectorArgument, messageArgument)) { // accept the selector args. lastSelector->next = new (_pool) ObjCSelectorArgumentListAST; lastSelector = lastSelector->next; - lastSelector->argument = selectorArgument; + lastSelector->value = selectorArgument; lastArgument->next = new (_pool) ObjCMessageArgumentListAST; lastArgument = lastArgument->next; - lastArgument->arg = messageArgument; + lastArgument->value = messageArgument; } if (LA() == T_COMMA) { - ExpressionAST **lastExpression = &(lastArgument->arg->parameter_value_expression); + ExpressionAST **lastExpression = &(lastArgument->value->parameter_value_expression); while (LA() == T_COMMA) { BinaryExpressionAST *binaryExpression = new (_pool) BinaryExpressionAST; @@ -3294,7 +3290,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg } ObjCSelectorWithArgumentsAST *selWithArgs = new (_pool) ObjCSelectorWithArgumentsAST; - selWithArgs->selector_arguments = selAst; + selWithArgs->selector_argument_list = selAst; selNode = selWithArgs; argNode = argAst; @@ -3374,9 +3370,9 @@ bool Parser::parseNameId(NameAST *&name) else if (LA() == T_LPAREN) { // a template-id followed by a T_LPAREN - if (TemplateArgumentListAST *template_arguments = template_id->template_arguments) { - if (! template_arguments->next && template_arguments->template_argument && - template_arguments->template_argument->asBinaryExpression()) { + if (TemplateArgumentListAST *template_arguments = template_id->template_argument_list) { + if (! template_arguments->next && template_arguments->value && + template_arguments->value->asBinaryExpression()) { unsigned saved = cursor(); ExpressionAST *expr = 0; @@ -3543,7 +3539,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) default: { unsigned start = cursor(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; bool blocked = blockErrors(true); if (lookAtBuiltinTypeSpecifier() && parseSimpleTypeSpecifier(type_specifier) && @@ -3554,7 +3550,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) if (LA() == T_RPAREN) { unsigned rparen_token = consumeToken(); TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; ast->lparen_token = lparen_token; ast->expression_list = expression_list; ast->rparen_token = rparen_token; @@ -3596,7 +3592,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) { DEBUG_THIS_RULE(); if (parseCorePostfixExpression(node)) { - PostfixAST *postfix_expressions = 0, + PostfixListAST *postfix_expressions = 0, **postfix_ptr = &postfix_expressions; while (LA()) { if (LA() == T_LPAREN) { @@ -3604,19 +3600,19 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) ast->lparen_token = consumeToken(); parseExpressionList(ast->expression_list); match(T_RPAREN, &ast->rparen_token); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayAccessAST *ast = new (_pool) ArrayAccessAST; ast->lbracket_token = consumeToken(); parseExpression(ast->expression); match(T_RBRACKET, &ast->rbracket_token); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) { PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST; ast->incr_decr_token = consumeToken(); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_DOT || LA() == T_ARROW) { MemberAccessAST *ast = new (_pool) MemberAccessAST; @@ -3626,7 +3622,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) if (! parseNameId(ast->member_name)) _translationUnit->error(cursor(), "expected unqualified-id before token `%s'", tok().spell()); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; } // while @@ -3634,7 +3630,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) if (postfix_expressions) { PostfixExpressionAST *ast = new (_pool) PostfixExpressionAST; ast->base_expression = node; - ast->postfix_expressions = postfix_expressions; + ast->postfix_expression_list = postfix_expressions; node = ast; } return true; @@ -3798,24 +3794,27 @@ bool Parser::parseNewExpression(ExpressionAST *&node) bool Parser::parseNewTypeId(NewTypeIdAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *typeSpec = 0; + SpecifierListAST *typeSpec = 0; if (! parseTypeSpecifier(typeSpec)) return false; NewTypeIdAST *ast = new (_pool) NewTypeIdAST; - ast->type_specifier = typeSpec; - PtrOperatorAST **ptrop_it = &ast->ptr_operators; + ast->type_specifier_list = typeSpec; + + PtrOperatorListAST **ptrop_it = &ast->ptr_operator_list; while (parsePtrOperator(*ptrop_it)) ptrop_it = &(*ptrop_it)->next; - NewArrayDeclaratorAST **it = &ast->new_array_declarators; + + NewArrayDeclaratorListAST **it = &ast->new_array_declarator_list; while (parseNewArrayDeclarator(*it)) it = &(*it)->next; + node = ast; return true; } -bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node) +bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node) { DEBUG_THIS_RULE(); if (LA() != T_LBRACKET) @@ -3825,7 +3824,9 @@ bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node) ast->lbracket_token = consumeToken(); parseExpression(ast->expression); match(T_RBRACKET, &ast->rbracket_token); - node = ast; + + node = new (_pool) NewArrayDeclaratorListAST; + node->value = ast; return true; } @@ -4307,21 +4308,20 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node) unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4346,11 +4346,11 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node) // T_AT_END // bool Parser::parseObjCInterface(DeclarationAST *&node, - SpecifierAST *attributes) + SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (! attributes && LA() == T___ATTRIBUTE__) { - SpecifierAST **attr = &attributes; + SpecifierListAST **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; } @@ -4370,7 +4370,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, "invalid attributes for category interface declaration"); ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->interface_token = objc_interface_token; SimpleNameAST *class_name = new (_pool) SimpleNameAST; class_name->identifier_token= identifier_token; @@ -4387,11 +4387,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4402,7 +4402,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, } else { // a class interface declaration ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->interface_token = objc_interface_token; SimpleNameAST* class_name = new (_pool) SimpleNameAST; class_name->identifier_token = identifier_token; @@ -4418,11 +4418,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); parseObjClassInstanceVariables(ast->inst_vars_decl); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4436,11 +4436,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, // objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON // bool Parser::parseObjCProtocol(DeclarationAST *&node, - SpecifierAST *attributes) + SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (! attributes && LA() == T___ATTRIBUTE__) { - SpecifierAST **attr = &attributes; + SpecifierListAST **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; } @@ -4456,23 +4456,22 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, // a protocol forward declaration ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->protocol_token = protocol_token; - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4482,7 +4481,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, } else { // a protocol definition ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->protocol_token = protocol_token; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; @@ -4490,11 +4489,11 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4533,7 +4532,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node) ast->category_name = category_name; match(T_RPAREN, &(ast->rparen_token)); - parseObjCMethodDefinitionList(ast->member_declarations); + parseObjCMethodDefinitionList(ast->member_declaration_list); match(T_AT_END, &(ast->end_token)); node = ast; @@ -4553,7 +4552,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node) } parseObjClassInstanceVariables(ast->inst_vars_decl); - parseObjCMethodDefinitionList(ast->member_declarations); + parseObjCMethodDefinitionList(ast->member_declaration_list); match(T_AT_END, &(ast->end_token)); node = ast; @@ -4588,28 +4587,29 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST; ast->synthesized_token = consumeToken(); ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST; - ast->property_identifiers = last; - last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST; - match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); + ast->property_identifier_list = last; + last->value = new (_pool) ObjCSynthesizedPropertyAST; + match(T_IDENTIFIER, &(last->value->property_identifier)); if (LA() == T_EQUAL) { - last->synthesized_property->equals_token = consumeToken(); + last->value->equals_token = consumeToken(); - match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); + match(T_IDENTIFIER, &(last->value->property_alias_identifier)); } while (LA() == T_COMMA) { - last->comma_token = consumeToken(); + consumeToken(); // consume T_COMMA + last->next = new (_pool) ObjCSynthesizedPropertyListAST; last = last->next; - last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST; - match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); + last->value = new (_pool) ObjCSynthesizedPropertyAST; + match(T_IDENTIFIER, &(last->value->property_identifier)); if (LA() == T_EQUAL) { - last->synthesized_property->equals_token = consumeToken(); + last->value->equals_token = consumeToken(); - match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); + match(T_IDENTIFIER, &(last->value->property_alias_identifier)); } } @@ -4622,19 +4622,20 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) case T_AT_DYNAMIC: { ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST; ast->dynamic_token = consumeToken(); - ast->property_identifiers = new (_pool) IdentifierListAST; + ast->property_identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; match(T_IDENTIFIER, &(name->identifier_token)); - ast->property_identifiers->name = name; + ast->property_identifier_list->value = name; - IdentifierListAST *last = ast->property_identifiers; + ObjCIdentifierListAST *last = ast->property_identifier_list; while (LA() == T_COMMA) { - last->comma_token = consumeToken(); - last->next = new (_pool) IdentifierListAST; + consumeToken(); // consume T_COMMA + + last->next = new (_pool) ObjCIdentifierListAST; last = last->next; name = new (_pool) SimpleNameAST; - match(T_IDENTIFIER, &(name->identifier_token)); - last->name = name; + match(T_IDENTIFIER, &name->identifier_token); + last->value = name; } match(T_SEMICOLON, &(ast->semicolon_token)); @@ -4660,7 +4661,7 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) if (declaration) { *next = new (_pool) DeclarationListAST; - (*next)->declaration = declaration; + (*next)->value = declaration; next = &((*next)->next); } } @@ -4706,21 +4707,20 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node) unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4742,14 +4742,14 @@ bool Parser::parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST ObjCInstanceVariablesDeclarationAST *ast = new (_pool) ObjCInstanceVariablesDeclarationAST; match(T_LBRACE, &(ast->lbrace_token)); - for (DeclarationListAST **next = &(ast->instance_variables); LA(); next = &((*next)->next)) { + for (DeclarationListAST **next = &(ast->instance_variable_list); LA(); next = &((*next)->next)) { if (LA() == T_RBRACE) break; const unsigned start = cursor(); *next = new (_pool) DeclarationListAST; - parseObjCInstanceVariableDeclaration((*next)->declaration); + parseObjCInstanceVariableDeclaration((*next)->value); if (start == cursor()) { // skip stray token. @@ -4840,14 +4840,14 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node) // objc-property-declaration ::= // T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration // -bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes) +bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (LA() != T_AT_PROPERTY) return false; ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->property_token = consumeToken(); if (LA() == T_LPAREN) { @@ -4855,15 +4855,15 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a ObjCPropertyAttributeAST *property_attribute = 0; if (parseObjCPropertyAttribute(property_attribute)) { - ast->property_attributes = new (_pool) ObjCPropertyAttributeListAST; - ast->property_attributes->attr = property_attribute; - ObjCPropertyAttributeListAST *last = ast->property_attributes; + ast->property_attribute_list = new (_pool) ObjCPropertyAttributeListAST; + ast->property_attribute_list->value = property_attribute; + ObjCPropertyAttributeListAST *last = ast->property_attribute_list; while (LA() == T_COMMA) { - last->comma_token = consumeToken(); + consumeToken(); // consume T_COMMA last->next = new (_pool) ObjCPropertyAttributeListAST; last = last->next; - if (!parseObjCPropertyAttribute(last->attr)) { + if (!parseObjCPropertyAttribute(last->value)) { _translationUnit->error(_tokenIndex, "expected token `%s' got `%s'", Token::name(T_IDENTIFIER), tok().spell()); while (LA() != T_RPAREN) @@ -4906,21 +4906,21 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) ObjCSelectorWithArgumentsAST *sel = new (_pool) ObjCSelectorWithArgumentsAST; ast->selector = sel; ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST; - sel->selector_arguments = lastSel; - sel->selector_arguments->argument = argument; + sel->selector_argument_list = lastSel; + sel->selector_argument_list->value = argument; - ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; - ast->arguments->argument_declaration = declaration; - ObjCMessageArgumentDeclarationListAST *lastArg = ast->arguments; + ast->argument_list = new (_pool) ObjCMessageArgumentDeclarationListAST; + ast->argument_list->value = declaration; + ObjCMessageArgumentDeclarationListAST *lastArg = ast->argument_list; while (parseObjCKeywordDeclaration(argument, declaration)) { lastSel->next = new (_pool) ObjCSelectorArgumentListAST; lastSel = lastSel->next; - lastSel->argument = argument; + lastSel->value = argument; lastArg->next = new (_pool) ObjCMessageArgumentDeclarationListAST; lastArg = lastArg->next; - lastArg->argument_declaration = declaration; + lastArg->value = declaration; } while (LA() == T_COMMA) { @@ -4943,7 +4943,7 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) _translationUnit->error(cursor(), "expected a selector"); } - SpecifierAST **attr = &(ast->attributes); + SpecifierListAST **attr = &ast->attribute_list; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; @@ -4992,10 +4992,10 @@ bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node) node->attribute_identifier_token = consumeToken(); match(T_EQUAL, &(node->equals_token)); ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST; - selector->selector_arguments = new (_pool) ObjCSelectorArgumentListAST; - selector->selector_arguments->argument = new (_pool) ObjCSelectorArgumentAST; - match(T_IDENTIFIER, &(selector->selector_arguments->argument->name_token)); - match(T_COLON, &(selector->selector_arguments->argument->colon_token)); + selector->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST; + selector->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST; + match(T_IDENTIFIER, &(selector->selector_argument_list->value->name_token)); + match(T_COLON, &(selector->selector_argument_list->value->colon_token)); node->method_selector = selector; return true; } @@ -5050,7 +5050,7 @@ bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, Obj parseObjCTypeName(node->type_name); - SpecifierAST **attr = &(node->attributes); + SpecifierListAST **attr = &node->attribute_list; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index d9ccf6ab49..ba0785e7ea 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -84,12 +84,12 @@ public: bool parseAsmOperand(); bool parseAsmClobberList(); bool parseAssignmentExpression(ExpressionAST *&node); - bool parseBaseClause(BaseSpecifierAST *&node); - bool parseBaseSpecifier(BaseSpecifierAST *&node); + bool parseBaseClause(BaseSpecifierListAST *&node); + bool parseBaseSpecifier(BaseSpecifierListAST *&node); bool parseBlockDeclaration(DeclarationAST *&node); bool parseCppCastExpression(ExpressionAST *&node); bool parseCastExpression(ExpressionAST *&node); - bool parseClassSpecifier(SpecifierAST *&node); + bool parseClassSpecifier(SpecifierListAST *&node); bool parseCommaExpression(ExpressionAST *&node); bool parseCompoundStatement(StatementAST *&node); bool parseBreakStatement(StatementAST *&node); @@ -100,7 +100,7 @@ public: bool parseConditionalExpression(ExpressionAST *&node); bool parseConstantExpression(ExpressionAST *&node); bool parseCtorInitializer(CtorInitializerAST *&node); - bool parseCvQualifiers(SpecifierAST *&node); + bool parseCvQualifiers(SpecifierListAST *&node); bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node); bool parseDeclaration(DeclarationAST *&node); bool parseSimpleDeclaration(DeclarationAST *&node, bool acceptStructDeclarator = false); @@ -109,9 +109,9 @@ public: bool parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer = false); bool parseDeleteExpression(ExpressionAST *&node); bool parseDoStatement(StatementAST *&node); - bool parseElaboratedTypeSpecifier(SpecifierAST *&node); - bool parseEnumSpecifier(SpecifierAST *&node); - bool parseEnumerator(EnumeratorAST *&node); + bool parseElaboratedTypeSpecifier(SpecifierListAST *&node); + bool parseEnumSpecifier(SpecifierListAST *&node); + bool parseEnumerator(EnumeratorListAST *&node); bool parseEqualityExpression(ExpressionAST *&node); bool parseExceptionDeclaration(ExceptionDeclarationAST *&node); bool parseExceptionSpecification(ExceptionSpecificationAST *&node); @@ -134,19 +134,19 @@ public: bool parseLinkageSpecification(DeclarationAST *&node); bool parseLogicalAndExpression(ExpressionAST *&node); bool parseLogicalOrExpression(ExpressionAST *&node); - bool parseMemInitializer(MemInitializerAST *&node); - bool parseMemInitializerList(MemInitializerAST *&node); + bool parseMemInitializer(MemInitializerListAST *&node); + bool parseMemInitializerList(MemInitializerListAST *&node); bool parseMemberSpecification(DeclarationAST *&node); bool parseMultiplicativeExpression(ExpressionAST *&node); bool parseTemplateId(NameAST *&node); bool parseClassOrNamespaceName(NameAST *&node); bool parseNameId(NameAST *&node); bool parseName(NameAST *&node, bool acceptTemplateId = true); - bool parseNestedNameSpecifier(NestedNameSpecifierAST *&node, bool acceptTemplateId); - bool parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, bool acceptTemplateId); + bool parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool acceptTemplateId); + bool parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId); bool parseNamespace(DeclarationAST *&node); bool parseNamespaceAliasDefinition(DeclarationAST *&node); - bool parseNewArrayDeclarator(NewArrayDeclaratorAST *&node); + bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node); bool parseNewExpression(ExpressionAST *&node); bool parseNewPlacement(NewPlacementAST *&node); bool parseNewInitializer(NewInitializerAST *&node); @@ -165,7 +165,7 @@ public: bool parsePostfixExpressionInternal(ExpressionAST *&node); bool parsePrimaryExpression(ExpressionAST *&node); bool parseNestedExpression(ExpressionAST *&node); - bool parsePtrOperator(PtrOperatorAST *&node); + bool parsePtrOperator(PtrOperatorListAST *&node); bool parseRelationalExpression(ExpressionAST *&node); bool parseShiftExpression(ExpressionAST *&node); bool parseStatement(StatementAST *&node); @@ -181,24 +181,24 @@ public: bool parseTemplateParameterList(DeclarationListAST *&node); bool parseThrowExpression(ExpressionAST *&node); bool parseTryBlockStatement(StatementAST *&node); - bool parseCatchClause(CatchClauseAST *&node); + bool parseCatchClause(CatchClauseListAST *&node); bool parseTypeId(ExpressionAST *&node); bool parseTypeIdList(ExpressionListAST *&node); bool parseTypenameTypeParameter(DeclarationAST *&node); bool parseTemplateTypeParameter(DeclarationAST *&node); bool parseTypeParameter(DeclarationAST *&node); - bool parseBuiltinTypeSpecifier(SpecifierAST *&node); - bool parseAttributeSpecifier(SpecifierAST *&node); - bool parseAttributeList(AttributeAST *&node); + bool parseBuiltinTypeSpecifier(SpecifierListAST *&node); + bool parseAttributeSpecifier(SpecifierListAST *&node); + bool parseAttributeList(AttributeListAST *&node); - bool parseSimpleTypeSpecifier(SpecifierAST *&node) + bool parseSimpleTypeSpecifier(SpecifierListAST *&node) { return parseDeclSpecifierSeq(node, true, true); } - bool parseTypeSpecifier(SpecifierAST *&node) + bool parseTypeSpecifier(SpecifierListAST *&node) { return parseDeclSpecifierSeq(node, true); } - bool parseDeclSpecifierSeq(SpecifierAST *&node, + bool parseDeclSpecifierSeq(SpecifierListAST *&node, bool onlyTypeSpecifiers = false, bool simplified = false); bool parseUnaryExpression(ExpressionAST *&node); @@ -214,9 +214,9 @@ public: bool parseObjCExpression(ExpressionAST *&node); bool parseObjCClassForwardDeclaration(DeclarationAST *&node); bool parseObjCInterface(DeclarationAST *&node, - SpecifierAST *attributes = 0); + SpecifierListAST *attributes = 0); bool parseObjCProtocol(DeclarationAST *&node, - SpecifierAST *attributes = 0); + SpecifierListAST *attributes = 0); bool parseObjCSynchronizedStatement(StatementAST *&node); bool parseObjCEncodeExpression(ExpressionAST *&node); @@ -236,7 +236,7 @@ public: bool parseObjCInterfaceMemberDeclaration(DeclarationAST *&node); bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node); bool parseObjCPropertyDeclaration(DeclarationAST *&node, - SpecifierAST *attributes = 0); + SpecifierListAST *attributes = 0); bool parseObjCImplementation(DeclarationAST *&node); bool parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node); bool parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node); @@ -264,7 +264,7 @@ public: void match(int kind, unsigned *token); bool maybeAmbiguousStatement(DeclarationStatementAST *ast) const; - bool maybeForwardOrClassDeclaration(SpecifierAST *decl_specifier_seq) const; + bool maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const; bool isPointerDeclaration(DeclarationStatementAST *ast) const; private: diff --git a/src/shared/cplusplus/Scope.cpp b/src/shared/cplusplus/Scope.cpp index 16026f8060..2c4eea10f7 100644 --- a/src/shared/cplusplus/Scope.cpp +++ b/src/shared/cplusplus/Scope.cpp @@ -245,6 +245,9 @@ Symbol *Scope::lookat(Identifier *id) const break; } else if (identity->isQualifiedNameId()) { assert(0); + } else if (SelectorNameId *selectorNameId = identity->asSelectorNameId()) { + if (selectorNameId->identifier()->isEqualTo(id)) + break; } } return symbol; diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp index e3b4b0b7ca..8baf10d4b0 100644 --- a/src/shared/cplusplus/Semantic.cpp +++ b/src/shared/cplusplus/Semantic.cpp @@ -120,7 +120,7 @@ Semantic::~Semantic() Control *Semantic::control() const { return d->control; } -FullySpecifiedType Semantic::check(SpecifierAST *specifier, Scope *scope) +FullySpecifiedType Semantic::check(SpecifierListAST *specifier, Scope *scope) { return d->checkSpecifier->check(specifier, scope); } void Semantic::check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters) @@ -130,7 +130,7 @@ FullySpecifiedType Semantic::check(DeclaratorAST *declarator, FullySpecifiedType Scope *scope, Name **name) { return d->checkDeclarator->check(declarator, type, scope, name); } -FullySpecifiedType Semantic::check(PtrOperatorAST *ptrOperators, FullySpecifiedType type, +FullySpecifiedType Semantic::check(PtrOperatorListAST *ptrOperators, FullySpecifiedType type, Scope *scope) { return d->checkDeclarator->check(ptrOperators, type, scope); } @@ -152,7 +152,7 @@ void Semantic::check(StatementAST *statement, Scope *scope) Name *Semantic::check(NameAST *name, Scope *scope) { return d->checkName->check(name, scope); } -Name *Semantic::check(NestedNameSpecifierAST *name, Scope *scope) +Name *Semantic::check(NestedNameSpecifierListAST *name, Scope *scope) { return d->checkName->check(name, scope); } Name *Semantic::check(ObjCSelectorAST *args, Scope *scope) @@ -232,9 +232,7 @@ bool Semantic::isObjCClassMethod(int tokenKind) const case T_PLUS: return true; case T_MINUS: - return false; default: - // TODO EV: assert here? return false; } } diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h index b07883e847..391872d847 100644 --- a/src/shared/cplusplus/Semantic.h +++ b/src/shared/cplusplus/Semantic.h @@ -66,12 +66,12 @@ public: Control *control() const; - FullySpecifiedType check(SpecifierAST *specifier, Scope *scope); + FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope); FullySpecifiedType check(DeclaratorAST *declarator, FullySpecifiedType type, Scope *scope, Name **name = 0); // ### ugly - FullySpecifiedType check(PtrOperatorAST *ptrOperators, FullySpecifiedType type, + FullySpecifiedType check(PtrOperatorListAST *ptrOperators, FullySpecifiedType type, Scope *scope); FullySpecifiedType check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope); @@ -84,7 +84,7 @@ public: Name *check(NameAST *name, Scope *scope); - Name *check(NestedNameSpecifierAST *name, Scope *scope); + Name *check(NestedNameSpecifierListAST *name, Scope *scope); Name *check(ObjCSelectorAST *args, Scope *scope); FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope); diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp index c04df48baf..e8b80fdcae 100644 --- a/src/shared/cplusplus/Symbol.cpp +++ b/src/shared/cplusplus/Symbol.cpp @@ -104,6 +104,9 @@ protected: virtual void visit(QualifiedNameId *name) { _value = operator()(name->unqualifiedNameId()); } + virtual void visit(SelectorNameId *name) + { _value = name->identifier()->hashCode(); } + private: unsigned _value; }; @@ -151,6 +154,9 @@ protected: virtual void visit(QualifiedNameId *name) { _identity = name->unqualifiedNameId(); } + virtual void visit(SelectorNameId *name) + { _identity = name; } + private: Name *_identity; }; @@ -461,6 +467,12 @@ bool Symbol::isArgument() const bool Symbol::isBaseClass() const { return asBaseClass() != 0; } +bool Symbol::isObjCBaseClass() const +{ return asObjCBaseClass() != 0; } + +bool Symbol::isObjCBaseProtocol() const +{ return asObjCBaseProtocol() != 0; } + bool Symbol::isObjCClass() const { return asObjCClass() != 0; } @@ -476,4 +488,5 @@ bool Symbol::isObjCForwardProtocolDeclaration() const bool Symbol::isObjCMethod() const { return asObjCMethod() != 0; } - +bool Symbol::isObjCPropertyDeclaration() const +{ return asObjCPropertyDeclaration() != 0; } diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h index 93d730b0cf..61abe02c7e 100644 --- a/src/shared/cplusplus/Symbol.h +++ b/src/shared/cplusplus/Symbol.h @@ -228,6 +228,9 @@ public: /// Returns true if this Symbol is an Objective-C method declaration. bool isObjCMethod() const; + /// Returns true if this Symbol is an Objective-C @property declaration. + bool isObjCPropertyDeclaration() const; + virtual const ScopedSymbol *asScopedSymbol() const { return 0; } virtual const Enum *asEnum() const { return 0; } virtual const Function *asFunction() const { return 0; } @@ -247,6 +250,7 @@ public: virtual const ObjCProtocol *asObjCProtocol() const { return 0; } virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return 0; } virtual const ObjCMethod *asObjCMethod() const { return 0; } + virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return 0; } virtual ScopedSymbol *asScopedSymbol() { return 0; } virtual Enum *asEnum() { return 0; } @@ -267,6 +271,7 @@ public: virtual ObjCProtocol *asObjCProtocol() { return 0; } virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return 0; } virtual ObjCMethod *asObjCMethod() { return 0; } + virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return 0; } /// Returns this Symbol's type. virtual FullySpecifiedType type() const = 0; diff --git a/src/shared/cplusplus/SymbolVisitor.h b/src/shared/cplusplus/SymbolVisitor.h index 4bfa379430..0e6440b750 100644 --- a/src/shared/cplusplus/SymbolVisitor.h +++ b/src/shared/cplusplus/SymbolVisitor.h @@ -88,6 +88,7 @@ public: virtual bool visit(ObjCProtocol *) { return true; } virtual bool visit(ObjCForwardProtocolDeclaration *) { return true; } virtual bool visit(ObjCMethod *) { return true; } + virtual bool visit(ObjCPropertyDeclaration *) { return true; } }; } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index 8ddaf3ef5d..819c8730ed 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -820,4 +820,23 @@ void ObjCMethod::visitSymbol0(SymbolVisitor *visitor) } } +ObjCPropertyDeclaration::ObjCPropertyDeclaration(TranslationUnit *translationUnit, + unsigned sourceLocation, + Name *name): + Symbol(translationUnit, sourceLocation, name), + _propertyAttributes(None), + _getterName(0), + _setterName(0) +{} + +ObjCPropertyDeclaration::~ObjCPropertyDeclaration() +{} + +FullySpecifiedType ObjCPropertyDeclaration::type() const +{ return _type; } +void ObjCPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor) +{ + if (visitor->visit(this)) { + } +} diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index acd13085f5..88d8d521cd 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -729,6 +729,75 @@ private: Scope *_arguments; }; +class CPLUSPLUS_EXPORT ObjCPropertyDeclaration: public Symbol +{ +public: + enum PropertyAttributes { + None = 0, + Assign = 1 << 0, + Retain = 1 << 1, + Copy = 1 << 2, + ReadOnly = 1 << 3, + ReadWrite = 1 << 4, + Getter = 1 << 5, + Setter = 1 << 6, + NonAtomic = 1 << 7, + + WritabilityMask = ReadOnly | ReadWrite, + SetterSemanticsMask = Assign | Retain | Copy, + }; + +public: + ObjCPropertyDeclaration(TranslationUnit *translationUnit, + unsigned sourceLocation, + Name *name); + virtual ~ObjCPropertyDeclaration(); + + bool hasAttribute(int attribute) const + { return _propertyAttributes & attribute; } + + void setAttributes(int attributes) + { _propertyAttributes = attributes; } + + bool hasGetter() const + { return hasAttribute(Getter); } + + bool hasSetter() const + { return hasAttribute(Setter); } + + Name *getterName() const + { return _getterName; } + + void setGetterName(Name *getterName) + { _getterName = getterName; } + + Name *setterName() const + { return _setterName; } + + void setSetterName(Name *setterName) + { _setterName = setterName; } + + void setType(const FullySpecifiedType &type) + { _type = type; } + + // Symbol's interface + virtual FullySpecifiedType type() const; + + virtual const ObjCPropertyDeclaration *asOObjCPropertyDeclaration() const + { return this; } + + virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + +private: + FullySpecifiedType _type; + int _propertyAttributes; + Name *_getterName, *_setterName; +}; + } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/cplusplus.pri b/src/shared/cplusplus/cplusplus.pri index e6453870b5..ddb82afbcd 100644 --- a/src/shared/cplusplus/cplusplus.pri +++ b/src/shared/cplusplus/cplusplus.pri @@ -40,7 +40,6 @@ HEADERS += \ SOURCES += \ $$PWD/AST.cpp \ - $$PWD/ASTClone.cpp \ $$PWD/ASTVisit.cpp \ $$PWD/ASTVisitor.cpp \ $$PWD/Array.cpp \ diff --git a/src/shared/qscripthighlighter/qscripthighlighter.cpp b/src/shared/qscripthighlighter/qscripthighlighter.cpp index e96dd4146c..a028ac4d7b 100644 --- a/src/shared/qscripthighlighter/qscripthighlighter.cpp +++ b/src/shared/qscripthighlighter/qscripthighlighter.cpp @@ -31,92 +31,28 @@ #include <QtCore/QSet> #include <QtCore/QtAlgorithms> -#include <QtCore/QDebug> using namespace SharedTools; -QSet<QString> QScriptHighlighter::m_keywords; - QScriptHighlighter::QScriptHighlighter(bool duiEnabled, QTextDocument *parent): QSyntaxHighlighter(parent), - m_scanner(m_duiEnabled), m_duiEnabled(duiEnabled) { - setFormats(defaultFormats()); + QVector<QTextCharFormat> rc; + rc.resize(NumFormats); + rc[NumberFormat].setForeground(Qt::blue); + rc[StringFormat].setForeground(Qt::darkGreen); + rc[TypeFormat].setForeground(Qt::darkMagenta); + rc[KeywordFormat].setForeground(Qt::darkYellow); + rc[LabelFormat].setForeground(Qt::darkRed); + rc[CommentFormat].setForeground(Qt::red); rc[CommentFormat].setFontItalic(true); + rc[PreProcessorFormat].setForeground(Qt::darkBlue); + rc[VisualWhitespace].setForeground(Qt::lightGray); // for debug: rc[VisualWhitespace].setBackground(Qt::red); + setFormats(rc); m_scanner.setKeywords(keywords()); } -QSet<QString> QScriptHighlighter::keywords() -{ - if (m_keywords.isEmpty()) { - m_keywords << QLatin1String("Infinity"); - m_keywords << QLatin1String("NaN"); - m_keywords << QLatin1String("abstract"); - m_keywords << QLatin1String("boolean"); - m_keywords << QLatin1String("break"); - m_keywords << QLatin1String("byte"); - m_keywords << QLatin1String("case"); - m_keywords << QLatin1String("catch"); - m_keywords << QLatin1String("char"); - m_keywords << QLatin1String("class"); - m_keywords << QLatin1String("const"); - m_keywords << QLatin1String("constructor"); - m_keywords << QLatin1String("continue"); - m_keywords << QLatin1String("debugger"); - m_keywords << QLatin1String("default"); - m_keywords << QLatin1String("delete"); - m_keywords << QLatin1String("do"); - m_keywords << QLatin1String("double"); - m_keywords << QLatin1String("else"); - m_keywords << QLatin1String("enum"); - m_keywords << QLatin1String("export"); - m_keywords << QLatin1String("extends"); - m_keywords << QLatin1String("false"); - m_keywords << QLatin1String("final"); - m_keywords << QLatin1String("finally"); - m_keywords << QLatin1String("float"); - m_keywords << QLatin1String("for"); - m_keywords << QLatin1String("function"); - m_keywords << QLatin1String("goto"); - m_keywords << QLatin1String("if"); - m_keywords << QLatin1String("implements"); - m_keywords << QLatin1String("import"); - m_keywords << QLatin1String("in"); - m_keywords << QLatin1String("instanceof"); - m_keywords << QLatin1String("int"); - m_keywords << QLatin1String("interface"); - m_keywords << QLatin1String("long"); - m_keywords << QLatin1String("native"); - m_keywords << QLatin1String("new"); - m_keywords << QLatin1String("package"); - m_keywords << QLatin1String("private"); - m_keywords << QLatin1String("protected"); - m_keywords << QLatin1String("public"); - m_keywords << QLatin1String("return"); - m_keywords << QLatin1String("short"); - m_keywords << QLatin1String("static"); - m_keywords << QLatin1String("super"); - m_keywords << QLatin1String("switch"); - m_keywords << QLatin1String("synchronized"); - m_keywords << QLatin1String("this"); - m_keywords << QLatin1String("throw"); - m_keywords << QLatin1String("throws"); - m_keywords << QLatin1String("transient"); - m_keywords << QLatin1String("true"); - m_keywords << QLatin1String("try"); - m_keywords << QLatin1String("typeof"); - m_keywords << QLatin1String("undefined"); - m_keywords << QLatin1String("var"); - m_keywords << QLatin1String("void"); - m_keywords << QLatin1String("volatile"); - m_keywords << QLatin1String("while"); - m_keywords << QLatin1String("with"); - } - - return m_keywords; -} - bool QScriptHighlighter::isDuiEnabled() const { return m_duiEnabled; } @@ -125,30 +61,29 @@ void QScriptHighlighter::highlightBlock(const QString &text) m_scanner(onBlockStart(), text); QTextCharFormat emptyFormat; - foreach (const QScriptIncrementalScanner::Token &token, m_scanner.tokens()) { + int lastEnd = 0; + const QList<QScriptIncrementalScanner::Token> tokens = m_scanner.tokens(); + for (int i = 0; i < tokens.size(); ++i) { + const QScriptIncrementalScanner::Token token = tokens.at(i); + + if (token.offset != lastEnd) + setFormat(lastEnd, token.offset - lastEnd, m_formats[VisualWhitespace]); + switch (token.kind) { case QScriptIncrementalScanner::Token::Keyword: setFormat(token.offset, token.length, m_formats[KeywordFormat]); break; - case QScriptIncrementalScanner::Token::Type: - setFormat(token.offset, token.length, m_formats[TypeFormat]); - break; - - case QScriptIncrementalScanner::Token::Label: - setFormat(token.offset, token.length, m_formats[LabelFormat]); - break; - case QScriptIncrementalScanner::Token::String: - setFormat(token.offset, token.length, m_formats[StringFormat]); + highlightWhitespace(token, text, StringFormat); break; case QScriptIncrementalScanner::Token::Comment: - setFormat(token.offset, token.length, m_formats[CommentFormat]); + highlightWhitespace(token, text, CommentFormat); break; case QScriptIncrementalScanner::Token::Number: - setFormat(token.offset, token.length, m_formats[NumberFormat]); + highlightWhitespace(token, text, NumberFormat); break; case QScriptIncrementalScanner::Token::LeftParenthesis: @@ -175,44 +110,123 @@ void QScriptHighlighter::highlightBlock(const QString &text) onClosingParenthesis(']', token.offset); break; - case QScriptIncrementalScanner::Token::PreProcessor: - setFormat(token.offset, token.length, m_formats[PreProcessorFormat]); + case QScriptIncrementalScanner::Token::Identifier: + if (m_duiEnabled && (i + 1 != tokens.size()) && tokens.at(i + 1).kind == QScriptIncrementalScanner::Token::Colon) { + setFormat(token.offset, token.length, m_formats[LabelFormat]); + } else { + const QChar c = text.at(token.offset); + + if (m_duiEnabled && c.isUpper() || !m_duiEnabled && c == QLatin1Char('Q')) + setFormat(token.offset, token.length, m_formats[TypeFormat]); + else + setFormat(token.offset, token.length, emptyFormat); + } break; - case QScriptIncrementalScanner::Token::Empty: - default: + case QScriptIncrementalScanner::Token::Colon: + if (m_duiEnabled && i > 0 && tokens.at(i - 1).kind == QScriptIncrementalScanner::Token::Identifier) + setFormat(token.offset, token.length, m_formats[LabelFormat]); + else + setFormat(token.offset, token.length, emptyFormat); + break; + + case QScriptIncrementalScanner::Token::Operator: + case QScriptIncrementalScanner::Token::Dot: setFormat(token.offset, token.length, emptyFormat); break; + default: + break; } + + lastEnd = token.end(); } - onBlockEnd(m_scanner.endState(), m_scanner.firstNonSpace()); -} + const int firstNonSpace = m_scanner.firstNonSpace(); + if (firstNonSpace > lastEnd) + setFormat(lastEnd, firstNonSpace - lastEnd, m_formats[VisualWhitespace]); + else if (text.length() > lastEnd) + setFormat(lastEnd, text.length() - lastEnd, m_formats[VisualWhitespace]); -const QVector<QTextCharFormat> &QScriptHighlighter::defaultFormats() -{ - static QVector<QTextCharFormat> rc; - if (rc.empty()) { - rc.resize(NumFormats); - rc[NumberFormat].setForeground(Qt::blue); - rc[StringFormat].setForeground(Qt::darkGreen); - rc[TypeFormat].setForeground(Qt::darkMagenta); - rc[KeywordFormat].setForeground(Qt::darkYellow); - rc[LabelFormat].setForeground(Qt::darkRed); - rc[CommentFormat].setForeground(Qt::red); - rc[CommentFormat].setFontItalic(true); - rc[PreProcessorFormat].setForeground(Qt::darkBlue); - rc[VisualWhitespace].setForeground(Qt::lightGray); - } - return rc; + onBlockEnd(m_scanner.endState(), firstNonSpace); } void QScriptHighlighter::setFormats(const QVector<QTextCharFormat> &s) { + Q_ASSERT(s.size() == NumFormats); qCopy(s.constBegin(), s.constEnd(), m_formats); } +QSet<QString> QScriptHighlighter::keywords() +{ + QSet<QString> keywords; + + keywords << QLatin1String("Infinity"); + keywords << QLatin1String("NaN"); + keywords << QLatin1String("abstract"); + keywords << QLatin1String("boolean"); + keywords << QLatin1String("break"); + keywords << QLatin1String("byte"); + keywords << QLatin1String("case"); + keywords << QLatin1String("catch"); + keywords << QLatin1String("char"); + keywords << QLatin1String("class"); + keywords << QLatin1String("const"); + keywords << QLatin1String("constructor"); + keywords << QLatin1String("continue"); + keywords << QLatin1String("debugger"); + keywords << QLatin1String("default"); + keywords << QLatin1String("delete"); + keywords << QLatin1String("do"); + keywords << QLatin1String("double"); + keywords << QLatin1String("else"); + keywords << QLatin1String("enum"); + keywords << QLatin1String("export"); + keywords << QLatin1String("extends"); + keywords << QLatin1String("false"); + keywords << QLatin1String("final"); + keywords << QLatin1String("finally"); + keywords << QLatin1String("float"); + keywords << QLatin1String("for"); + keywords << QLatin1String("function"); + keywords << QLatin1String("goto"); + keywords << QLatin1String("if"); + keywords << QLatin1String("implements"); + keywords << QLatin1String("import"); + keywords << QLatin1String("in"); + keywords << QLatin1String("instanceof"); + keywords << QLatin1String("int"); + keywords << QLatin1String("interface"); + keywords << QLatin1String("long"); + keywords << QLatin1String("native"); + keywords << QLatin1String("new"); + keywords << QLatin1String("package"); + keywords << QLatin1String("private"); + keywords << QLatin1String("protected"); + keywords << QLatin1String("public"); + keywords << QLatin1String("return"); + keywords << QLatin1String("short"); + keywords << QLatin1String("static"); + keywords << QLatin1String("super"); + keywords << QLatin1String("switch"); + keywords << QLatin1String("synchronized"); + keywords << QLatin1String("this"); + keywords << QLatin1String("throw"); + keywords << QLatin1String("throws"); + keywords << QLatin1String("transient"); + keywords << QLatin1String("true"); + keywords << QLatin1String("try"); + keywords << QLatin1String("typeof"); + keywords << QLatin1String("undefined"); + keywords << QLatin1String("var"); + keywords << QLatin1String("void"); + keywords << QLatin1String("volatile"); + keywords << QLatin1String("while"); + keywords << QLatin1String("with"); + + return keywords; +} + int QScriptHighlighter::onBlockStart() { int state = 0; @@ -224,3 +238,23 @@ int QScriptHighlighter::onBlockStart() void QScriptHighlighter::onOpeningParenthesis(QChar, int) {} void QScriptHighlighter::onClosingParenthesis(QChar, int) {} void QScriptHighlighter::onBlockEnd(int state, int) { return setCurrentBlockState(state); } + +void QScriptHighlighter::highlightWhitespace(const QScriptIncrementalScanner::Token &token, const QString &text, int nonWhitespaceFormat) +{ + const QTextCharFormat normalFormat = m_formats[nonWhitespaceFormat]; + const QTextCharFormat visualSpaceFormat = m_formats[VisualWhitespace]; + + const int end = token.end(); + int index = token.offset; + + while (index != end) { + const bool isSpace = text.at(index).isSpace(); + const int start = index; + + do { ++index; } + while (index != end && text.at(index).isSpace() == isSpace); + + const int tokenLength = index - start; + setFormat(start, tokenLength, isSpace ? visualSpaceFormat : normalFormat); + } +} diff --git a/src/shared/qscripthighlighter/qscripthighlighter.h b/src/shared/qscripthighlighter/qscripthighlighter.h index c9a66faeb5..9d654e9c55 100644 --- a/src/shared/qscripthighlighter/qscripthighlighter.h +++ b/src/shared/qscripthighlighter/qscripthighlighter.h @@ -54,12 +54,11 @@ public: // MS VC 6 compatible, still. void setFormats(const QVector<QTextCharFormat> &s); - static const QVector<QTextCharFormat> &defaultFormats(); QTextCharFormat labelTextCharFormat() const { return m_formats[LabelFormat]; } - static QSet<QString> keywords(); + QSet<QString> keywords(); protected: // The functions are notified whenever parentheses are encountered. @@ -70,11 +69,12 @@ protected: // sets the enriched user state, or simply calls setCurrentBlockState(state); virtual void onBlockEnd(int state, int firstNonSpace); + virtual void highlightWhitespace(const QScriptIncrementalScanner::Token &token, const QString &text, int nonWhitespaceFormat); + protected: QScriptIncrementalScanner m_scanner; private: - static QSet<QString> m_keywords; bool m_duiEnabled; QTextCharFormat m_formats[NumFormats]; }; diff --git a/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp b/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp index 8aecb1f568..851110f600 100644 --- a/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp +++ b/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp @@ -4,8 +4,7 @@ using namespace SharedTools; -QScriptIncrementalScanner::QScriptIncrementalScanner(bool duiEnabled): - m_duiEnabled(duiEnabled) +QScriptIncrementalScanner::QScriptIncrementalScanner() { reset(); } @@ -30,9 +29,7 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) InputNumber, InputAsterix, InputSlash, - InputParen, InputSpace, - InputHash, InputQuotation, InputApostrophe, InputSep, @@ -42,13 +39,13 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) // states enum { StateStandard, - StateCommentStart1, - StateCCommentStart2, - StateCppCommentStart2, - StateCComment, - StateCppComment, - StateCCommentEnd1, - StateCCommentEnd2, + StateCommentStart1, // '/' + StateCCommentStart2, // '*' after a '/' + StateCppCommentStart2, // '/' after a '/' + StateCComment, // after a "/*" + StateCppComment, // after a "//" + StateCCommentEnd1, // '*' in a CppComment + StateCCommentEnd2, // '/' after a '*' in a CppComment StateStringStart, StateString, StateStringEnd, @@ -56,32 +53,28 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) StateString2, StateString2End, StateNumber, - StatePreProcessor, NumStates }; static const uchar table[NumStates][NumInputs] = { - { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStandard - { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 - { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 - { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // CppCommentStart2 - { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment - { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment - { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 - { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 - { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart - { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString - { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd - { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start - { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 - { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateString2End - { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateNumber - { StatePreProcessor, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard } // StatePreProcessor + // InputAlpha InputNumber InputAsterix InputSlash InputSpace InputQuotation InputApostrophe InputSep + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateStandard + { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppCommentStart2 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment + { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 + { StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart + { StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateString2End + { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard } // StateNumber }; - QString buffer; - buffer.reserve(text.length()); - int state = startState; if (text.isEmpty()) { blockEnd(state, 0); @@ -96,7 +89,6 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) static const QString alphabeth = QLatin1String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); static const QString mathChars = QString::fromLatin1("xXeE"); static const QString numbers = QString::fromLatin1("0123456789"); - bool questionMark = false; QChar lastChar; int firstNonSpace = -1; @@ -104,13 +96,11 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) forever { const QChar qc = text.at(i); - - bool lookAtBinding = false; + const char c = qc.toLatin1(); if (lastWasBackSlash) { input = InputSep; } else { - const char c = qc.toLatin1(); switch (c) { case '*': input = InputAsterix; @@ -118,34 +108,6 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) case '/': input = InputSlash; break; - case '(': case '[': case '{': - input = InputParen; - if (state == StateStandard - || state == StateNumber - || state == StatePreProcessor - || state == StateCCommentEnd2 - || state == StateCCommentEnd1 - || state == StateString2End - || state == StateStringEnd - ) - openingParenthesis(c, i); - break; - case ')': case ']': case '}': - input = InputParen; - if (state == StateStandard - || state == StateNumber - || state == StatePreProcessor - || state == StateCCommentEnd2 - || state == StateCCommentEnd1 - || state == StateString2End - || state == StateStringEnd - ) { - closingParenthesis(c, i); - } - break; - case '#': - input = InputHash; - break; case '"': input = InputQuotation; break; @@ -166,45 +128,14 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) input = InputNumber; } break; - case ':': { - input = InputSep; - QChar nextChar = ' '; - if (i < text.length() - 1) - nextChar = text.at(i + 1); - - if (state == StateStandard && !questionMark && lastChar != ':' && nextChar != ':') { - int start = i - 1; - - // skip white spaces - for (; start != -1; --start) { - if (! text.at(start).isSpace()) - break; - } - - int lastNonSpace = start + 1; - - for (; start != -1; --start) { - const QChar ch = text.at(start); - if (! (ch.isLetterOrNumber() || ch == QLatin1Char('_') || ch == QLatin1Char('.'))) - break; - } - - ++start; - - lookAtBinding = true; - - if (m_duiEnabled && text.midRef(start, lastNonSpace - start) == QLatin1String("id")) { - setFormat(start, i - start, Token::Keyword); - } else { - setFormat(start, i - start, Token::Label); - } - } + case '.': + if (state == StateNumber) + input = InputNumber; + else + input = InputSep; break; - } default: { - if (!questionMark && qc == QLatin1Char('?')) - questionMark = true; - if (qc.isLetter() || qc == QLatin1Char('_')) + if (qc.isLetter() || c == '_') input = InputAlpha; else input = InputSep; @@ -219,23 +150,20 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) lastNonSpace = i; } - lastWasBackSlash = !lastWasBackSlash && qc == QLatin1Char('\\'); - - if (input == InputAlpha) - buffer += qc; + lastWasBackSlash = !lastWasBackSlash && c == '\\'; state = table[state][input]; switch (state) { case StateStandard: { - setFormat(i, 1, Token::Empty); if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - if (!buffer.isEmpty() && input != InputAlpha ) { - if (! lookAtBinding) - highlightKeyword(i, buffer); - buffer.clear(); + + if (input == InputAlpha ) { + insertIdentifier(i); + } else if (input == InputSep || input == InputAsterix) { + insertCharToken(i, c); } break; @@ -243,103 +171,82 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) case StateCommentStart1: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = true; - buffer.resize(0); break; case StateCCommentStart2: - setFormat(i - 1, 2, Token::Comment); makeLastStandard = false; - buffer.resize(0); + insertComment(i - 1, 2); break; case StateCppCommentStart2: - setFormat(i - 1, 2, Token::Comment); + insertComment(i - 1, 2); makeLastStandard = false; - buffer.resize(0); break; case StateCComment: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Comment); - buffer.resize(0); + insertComment(i, 1); break; case StateCppComment: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Comment); - buffer.resize(0); + insertComment(i, 1); break; case StateCCommentEnd1: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Comment); - buffer.resize(0); + insertComment(i, 1); break; case StateCCommentEnd2: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Comment); - buffer.resize(0); + insertComment(i, 1); break; case StateStringStart: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Empty); - buffer.resize(0); + insertString(i); break; case StateString: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::String); - buffer.resize(0); + insertString(i); break; case StateStringEnd: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Empty); - buffer.resize(0); + insertString(i); break; case StateString2Start: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Empty); - buffer.resize(0); + insertString(i); break; case StateString2: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::String); - buffer.resize(0); + insertString(i); break; case StateString2End: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::Empty); - buffer.resize(0); + insertString(i); break; case StateNumber: if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); - makeLastStandard = false; - setFormat( i, 1, Token::Number); - buffer.resize(0); - break; - case StatePreProcessor: - if (makeLastStandard) - setFormat(i - 1, 1, Token::Empty); + insertCharToken(i - 1, text.at(i - 1).toAscii()); makeLastStandard = false; - setFormat(i, 1, Token::PreProcessor); - buffer.resize(0); + insertNumber(i); break; } @@ -349,7 +256,7 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) break; } - highlightKeyword(text.length(), buffer); + scanForKeywords(text); if (state == StateCComment || state == StateCCommentEnd1 @@ -363,63 +270,63 @@ void QScriptIncrementalScanner::operator()(int startState, const QString &text) blockEnd(state, firstNonSpace); } -void QScriptIncrementalScanner::highlightKeyword(int currentPos, const QString &buffer) +void QScriptIncrementalScanner::insertToken(int start, int length, Token::Kind kind, bool forceNewToken) { - if (buffer.isEmpty()) - return; - - if ((m_duiEnabled && buffer.at(0).isUpper()) || (! m_duiEnabled && buffer.at(0) == QLatin1Char('Q'))) { - setFormat(currentPos - buffer.length(), buffer.length(), Token::Type); + if (m_tokens.isEmpty() || forceNewToken) { + m_tokens.append(Token(start, length, kind)); } else { - if (m_keywords.contains(buffer)) - setFormat(currentPos - buffer.length(), buffer.length(), Token::Keyword); + Token &lastToken(m_tokens.last()); + + if (lastToken.kind == kind && lastToken.end() == start) { + lastToken.length += 1; + } else { + m_tokens.append(Token(start, length, kind)); + } } } -void QScriptIncrementalScanner::openingParenthesis(char c, int i) +void QScriptIncrementalScanner::insertCharToken(int start, const char c) { Token::Kind kind; switch (c) { - case '(': - kind = Token::LeftParenthesis; - break; - - case '[': - kind = Token::LeftBracket; - break; - - case '{': - kind = Token::LeftBrace; - break; - - default: - return; + case '!': + case '<': + case '>': + case '+': + case '-': + case '*': + case '/': + case '%': kind = Token::Operator; break; + + case ';': kind = Token::Semicolon; break; + case ':': kind = Token::Colon; break; + case ',': kind = Token::Comma; break; + case '.': kind = Token::Dot; break; + + case '(': kind = Token::LeftParenthesis; break; + case ')': kind = Token::RightParenthesis; break; + case '{': kind = Token::LeftBrace; break; + case '}': kind = Token::RightBrace; break; + case '[': kind = Token::LeftBracket; break; + case ']': kind = Token::RightBracket; break; + + default: kind = Token::Identifier; break; } - m_tokens.append(Token(i, 1, kind)); + insertToken(start, 1, kind, true); } -void QScriptIncrementalScanner::closingParenthesis(char c, int i) +void QScriptIncrementalScanner::scanForKeywords(const QString &text) { - Token::Kind kind; - - switch (c) { - case ')': - kind = Token::RightParenthesis; - break; + for (int i = 0; i < m_tokens.length(); ++i) { + Token &t(m_tokens[i]); - case ']': - kind = Token::RightBracket; - break; - - case '}': - kind = Token::RightBrace; - break; + if (t.kind != Token::Identifier) + continue; - default: - return; + const QString id = text.mid(t.offset, t.length); + if (m_keywords.contains(id)) + t.kind = Token::Keyword; } - - m_tokens.append(Token(i, 1, kind)); } diff --git a/src/shared/qscripthighlighter/qscriptincrementalscanner.h b/src/shared/qscripthighlighter/qscriptincrementalscanner.h index 4164db4313..531a37464e 100644 --- a/src/shared/qscripthighlighter/qscriptincrementalscanner.h +++ b/src/shared/qscripthighlighter/qscriptincrementalscanner.h @@ -15,10 +15,8 @@ public: int offset; int length; enum Kind { - Empty, Keyword, - Type, - Label, + Identifier, String, Comment, Number, @@ -28,18 +26,23 @@ public: RightBrace, LeftBracket, RightBracket, - PreProcessor + Operator, + Semicolon, + Colon, + Comma, + Dot } kind; - Token(int o, int l, Kind k): offset(o), length(l), kind(k) {} + inline Token(int o, int l, Kind k): offset(o), length(l), kind(k) {} + inline int end() const { return offset + length; } }; public: - QScriptIncrementalScanner(bool duiEnabled = false); + QScriptIncrementalScanner(); virtual ~QScriptIncrementalScanner(); - void setKeywords(const QSet<QString> &keywords) - { m_keywords = keywords; } + void setKeywords(const QSet<QString> keywords) + { m_keywords = keywords;; } void reset(); @@ -57,15 +60,20 @@ public: private: void blockEnd(int state, int firstNonSpace) { m_endState = state; m_firstNonSpace = firstNonSpace; } - void setFormat(int start, int count, Token::Kind kind) - { m_tokens.append(Token(start, count, kind)); } - void highlightKeyword(int currentPos, const QString &buffer); - void openingParenthesis(char c, int i); - void closingParenthesis(char c, int i); + void insertString(int start) + { insertToken(start, 1, Token::String, false); } + void insertComment(int start, int length) + { insertToken(start, length, Token::Comment, false); } + void insertCharToken(int start, const char c); + void insertIdentifier(int start) + { insertToken(start, 1, Token::Identifier, false); } + void insertNumber(int start) + { insertToken(start, 1, Token::Number, false); } + void insertToken(int start, int length, Token::Kind kind, bool forceNewToken); + void scanForKeywords(const QString &text); private: QSet<QString> m_keywords; - bool m_duiEnabled; int m_endState; int m_firstNonSpace; QList<QScriptIncrementalScanner::Token> m_tokens; diff --git a/src/shared/qscripthighlighter/test/main.cpp b/src/shared/qscripthighlighter/test/main.cpp index 749fa4876d..5f955e3243 100644 --- a/src/shared/qscripthighlighter/test/main.cpp +++ b/src/shared/qscripthighlighter/test/main.cpp @@ -33,13 +33,22 @@ #include <QMainWindow> #include <QApplication> +QString presetText = "import Qt 4.6\n" + "\n" + "Item {\n" + " id: Zoo\n" + " width: 1 + -1*3\n" + "}\n"; + int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow mw; QTextEdit *textEdit = new QTextEdit; - new SharedTools::QScriptHighlighter(textEdit->document()); + if (!presetText.isEmpty()) + textEdit->setText(presetText); + new SharedTools::QScriptHighlighter(true, textEdit->document()); mw.setCentralWidget(textEdit); mw.show(); return app.exec(); diff --git a/src/tools/cplusplus/Main.cpp b/src/tools/cplusplus/Main.cpp new file mode 100644 index 0000000000..16c9908a13 --- /dev/null +++ b/src/tools/cplusplus/Main.cpp @@ -0,0 +1,557 @@ + +#include <QCoreApplication> +#include <QStringList> +#include <QTextDocument> +#include <QTextCursor> +#include <QTextBlock> +#include <QDir> +#include <QDebug> + +#include <Control.h> +#include <Parser.h> +#include <AST.h> +#include <ASTVisitor.h> +#include <Symbols.h> +#include <CoreTypes.h> +#include <Literals.h> +#include <CppDocument.h> +#include <Overview.h> +#include <Names.h> +#include <Scope.h> + +#include <iostream> +#include <cstdlib> + +using namespace CPlusPlus; + +static const char copyrightHeader[] = +"/**************************************************************************\n" +"**\n" +"** This file is part of Qt Creator\n" +"**\n" +"** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" +"**\n" +"** Contact: Nokia Corporation (qt-info@nokia.com)\n" +"**\n" +"** Commercial Usage\n" +"**\n" +"** Licensees holding valid Qt Commercial licenses may use this file in\n" +"** accordance with the Qt Commercial License Agreement provided with the\n" +"** Software or, alternatively, in accordance with the terms contained in\n" +"** a written agreement between you and Nokia.\n" +"**\n" +"** GNU Lesser General Public License Usage\n" +"**\n" +"** Alternatively, this file may be used under the terms of the GNU Lesser\n" +"** General Public License version 2.1 as published by the Free Software\n" +"** Foundation and appearing in the file LICENSE.LGPL included in the\n" +"** packaging of this file. Please review the following information to\n" +"** ensure the GNU Lesser General Public License version 2.1 requirements\n" +"** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n" +"**\n" +"** If you are unsure which license is appropriate for your use, please\n" +"** contact the sales department at http://qt.nokia.com/contact.\n" +"**\n" +"**************************************************************************/\n" +; + +class SearchListNodes: protected ASTVisitor +{ + QList<QByteArray> _listNodes; + +public: + SearchListNodes(Control *control) + : ASTVisitor(control) + { } + + QList<QByteArray> operator()(AST *ast) + { + _listNodes.clear(); + accept(ast); + return _listNodes; + } + +protected: + virtual bool visit(ClassSpecifierAST *ast) + { + const QString className = oo(ast->symbol->name()); + + if (! (className.length() > 3 && className.endsWith(QLatin1String("AST")))) + return true; + + for (unsigned i = 0; i < ast->symbol->memberCount(); ++i) { + Symbol *member = ast->symbol->memberAt(i); + Name *memberName = member->name(); + + if (! memberName) + continue; + else if (! memberName->identifier()) + continue; + + if (! qstrcmp("next", memberName->identifier()->chars())) { + _listNodes.append(className.toUtf8()); + break; + } + } + + return true; + } + +private: + Overview oo; +}; + +class VisitCG: protected ASTVisitor +{ + QDir _cplusplusDir; + QList<QByteArray> _listNodes; + QTextStream *out; + +public: + VisitCG(const QDir &cplusplusDir, Control *control) + : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0) + { } + + void operator()(AST *ast) + { + QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTVisit.cpp")); + + QFile file(fileInfo.absoluteFilePath()); + if (! file.open(QFile::WriteOnly)) + return; + + QTextStream output(&file); + out = &output; + + *out << copyrightHeader << + "\n" + "#include \"AST.h\"\n" + "#include \"ASTVisitor.h\"\n" + "\n" + "using namespace CPlusPlus;\n" << endl; + + SearchListNodes listNodes(control()); + _listNodes = listNodes(ast); + + accept(ast); + } + +protected: + using ASTVisitor::visit; + + QMap<QByteArray, ClassSpecifierAST *> classMap; + + QByteArray id_cast(NameAST *name) + { + if (! name) + return QByteArray(); + + Identifier *id = identifier(name->asSimpleName()->identifier_token); + + return QByteArray::fromRawData(id->chars(), id->size()); + } + + void visitMembers(Class *klass) + { + const QByteArray className = klass->name()->identifier()->chars(); + + // *out << " // visit " << className.constData() << endl; + for (unsigned i = 0; i < klass->memberCount(); ++i) { + Symbol *member = klass->memberAt(i); + if (! member->name()) + continue; + + Identifier *id = member->name()->identifier(); + + if (! id) + continue; + + const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size()); + if (member->type().isUnsigned() && memberName.endsWith("_token")) { + // nothing to do. The member is a token. + + } else if (PointerType *ptrTy = member->type()->asPointerType()) { + + if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) { + QByteArray typeName = namedTy->name()->identifier()->chars(); + + if (_listNodes.contains(typeName) && memberName != "next") { + *out + << " for (" << typeName.constData() << " *it = " + << memberName.constData() << "; it; it = it->next)" << endl + << " accept(it, visitor);" << endl; + + } else if (typeName.endsWith("AST") && memberName != "next") { + *out << " accept(" << memberName.constData() << ", visitor);" << endl; + } + } + } + } + + for (unsigned i = 0; i < klass->baseClassCount(); ++i) { + const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars(); + + if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0)) { + visitMembers(baseClassSpec->symbol); + } + } + } + + bool checkMethod(Symbol *accept0Method) const + { + Declaration *decl = accept0Method->asDeclaration(); + if (! decl) + return false; + + Function *funTy = decl->type()->asFunctionType(); + if (! funTy) + return false; + + else if (funTy->isPureVirtual()) + return false; + + return true; + } + + virtual bool visit(ClassSpecifierAST *ast) + { + Class *klass = ast->symbol; + const QByteArray className = id_cast(ast->name); + + Identifier *visit_id = control()->findOrInsertIdentifier("accept0"); + Symbol *accept0Method = klass->members()->lookat(visit_id); + for (; accept0Method; accept0Method = accept0Method->next()) { + if (accept0Method->identifier() != visit_id) + continue; + + if (checkMethod(accept0Method)) + break; + } + + if (! accept0Method) + return true; + + classMap.insert(className, ast); + + *out + << "void " << className.constData() << "::accept0(ASTVisitor *visitor)" << endl + << "{" << endl + << " if (visitor->visit(this)) {" << endl; + + visitMembers(klass); + + *out + << " }" << endl + << " visitor->endVisit(this);" << endl + << "}" << endl + << endl; + + return true; + } +}; + +QTextCursor createCursor(TranslationUnit *unit, AST *ast, QTextDocument *document) +{ + unsigned startLine, startColumn, endLine, endColumn; + unit->getTokenStartPosition(ast->firstToken(), &startLine, &startColumn); + unit->getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn); + + QTextCursor tc(document); + tc.setPosition(document->findBlockByNumber(startLine - 1).position()); + tc.setPosition(document->findBlockByNumber(endLine - 1).position() + endColumn - 1, + QTextCursor::KeepAnchor); + + int charsToSkip = 0; + forever { + QChar ch = document->characterAt(tc.position() + charsToSkip); + + if (! ch.isSpace()) + break; + + ++charsToSkip; + + if (ch == QChar::ParagraphSeparator) + break; + } + + tc.setPosition(tc.position() + charsToSkip, QTextCursor::KeepAnchor); + return tc; +} + +class ASTNodes +{ +public: + ASTNodes(): base(0) {} + + ClassSpecifierAST *base; // points to "class AST" + QList<ClassSpecifierAST *> deriveds; // n where n extends AST + QList<QTextCursor> endOfPublicClassSpecifiers; +}; + +class FindASTNodes: protected ASTVisitor +{ +public: + FindASTNodes(Document::Ptr doc, QTextDocument *document) + : ASTVisitor(doc->control()), document(document) + { + } + + ASTNodes operator()(AST *ast) + { + accept(ast); + return _nodes; + } + +protected: + virtual bool visit(ClassSpecifierAST *ast) + { + Class *klass = ast->symbol; + Q_ASSERT(klass != 0); + + const QString className = oo(klass->name()); + + if (className.endsWith("AST")) { + if (className == QLatin1String("AST")) + _nodes.base = ast; + else { + _nodes.deriveds.append(ast); + + AccessDeclarationAST *accessDeclaration = 0; + for (DeclarationListAST *it = ast->member_specifiers; it; it = it->next) { + if (AccessDeclarationAST *decl = it->declaration->asAccessDeclaration()) { + if (tokenKind(decl->access_specifier_token) == T_PUBLIC) + accessDeclaration = decl; + } + } + + if (! accessDeclaration) + qDebug() << "no access declaration for class:" << className; + + Q_ASSERT(accessDeclaration != 0); + + QTextCursor tc = createCursor(translationUnit(), accessDeclaration, document); + tc.setPosition(tc.position()); + + _nodes.endOfPublicClassSpecifiers.append(tc); + } + } + + return true; + } + +private: + QTextDocument *document; + ASTNodes _nodes; + Overview oo; +}; + +class RemoveCastMethods: protected ASTVisitor +{ +public: + RemoveCastMethods(Document::Ptr doc, QTextDocument *document) + : ASTVisitor(doc->control()), document(document) {} + + QList<QTextCursor> operator()(AST *ast) + { + _cursors.clear(); + accept(ast); + return _cursors; + } + +protected: + virtual bool visit(FunctionDefinitionAST *ast) + { + Function *fun = ast->symbol; + const QString functionName = oo(fun->name()); + + if (functionName.length() > 3 && functionName.startsWith(QLatin1String("as")) + && functionName.at(2).isUpper()) { + + QTextCursor tc = createCursor(translationUnit(), ast, document); + + //qDebug() << qPrintable(tc.selectedText()); + _cursors.append(tc); + } + + return true; + } + +private: + QTextDocument *document; + QList<QTextCursor> _cursors; + Overview oo; +}; + +QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir) +{ + QStringList astDerivedClasses; + + QFileInfo fileAST_h(cplusplusDir, QLatin1String("AST.h")); + Q_ASSERT(fileAST_h.exists()); + + const QString fileName = fileAST_h.absoluteFilePath(); + + QFile file(fileName); + if (! file.open(QFile::ReadOnly)) + return astDerivedClasses; + + const QString source = QTextStream(&file).readAll(); + file.close(); + + QTextDocument document; + document.setPlainText(source); + + Document::Ptr doc = Document::create(fileName); + const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fileName); + doc->setSource(preprocessedCode); + doc->check(); + + FindASTNodes process(doc, &document); + ASTNodes astNodes = process(doc->translationUnit()->ast()); + + RemoveCastMethods removeCastMethods(doc, &document); + + QList<QTextCursor> baseCastMethodCursors = removeCastMethods(astNodes.base); + QMap<ClassSpecifierAST *, QList<QTextCursor> > cursors; + QMap<ClassSpecifierAST *, QString> replacementCastMethods; + + Overview oo; + + QStringList castMethods; + foreach (ClassSpecifierAST *classAST, astNodes.deriveds) { + cursors[classAST] = removeCastMethods(classAST); + const QString className = oo(classAST->symbol->name()); + const QString methodName = QLatin1String("as") + className.mid(0, className.length() - 3); + replacementCastMethods[classAST] = QString(" virtual %1 *%2() { return this; }\n").arg(className, methodName); + castMethods.append(QString(" virtual %1 *%2() { return 0; }\n").arg(className, methodName)); + + astDerivedClasses.append(className); + } + + if (! baseCastMethodCursors.isEmpty()) { + castMethods.sort(); + for (int i = 0; i < baseCastMethodCursors.length(); ++i) { + baseCastMethodCursors[i].removeSelectedText(); + } + + baseCastMethodCursors.first().insertText(castMethods.join(QLatin1String(""))); + } + + for (int classIndex = 0; classIndex < astNodes.deriveds.size(); ++classIndex) { + ClassSpecifierAST *classAST = astNodes.deriveds.at(classIndex); + + // remove the cast methods. + QList<QTextCursor> c = cursors.value(classAST); + for (int i = 0; i < c.length(); ++i) { + c[i].removeSelectedText(); + } + + astNodes.endOfPublicClassSpecifiers[classIndex].insertText(replacementCastMethods.value(classAST)); + } + + if (file.open(QFile::WriteOnly)) { + QTextStream out(&file); + out << document.toPlainText(); + } + + VisitCG cg(cplusplusDir, doc->control()); + cg(doc->translationUnit()->ast()); + + return astDerivedClasses; +} + +class FindASTForwards: protected ASTVisitor +{ +public: + FindASTForwards(Document::Ptr doc, QTextDocument *document) + : ASTVisitor(doc->control()), document(document) + {} + + QList<QTextCursor> operator()(AST *ast) + { + accept(ast); + return _cursors; + } + +protected: + bool visit(SimpleDeclarationAST *ast) + { + if (ElaboratedTypeSpecifierAST *e = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) { + if (tokenKind(e->classkey_token) == T_CLASS && !ast->declarators) { + QString className = oo(e->name->name); + + if (className.length() > 3 && className.endsWith(QLatin1String("AST"))) { + QTextCursor tc = createCursor(translationUnit(), ast, document); + _cursors.append(tc); + } + } + } + + return true; + } + +private: + QTextDocument *document; + QList<QTextCursor> _cursors; + Overview oo; +}; + +void generateASTFwd_h(const Snapshot &snapshot, const QDir &cplusplusDir, const QStringList &astDerivedClasses) +{ + QFileInfo fileASTFwd_h(cplusplusDir, QLatin1String("ASTfwd.h")); + Q_ASSERT(fileASTFwd_h.exists()); + + const QString fileName = fileASTFwd_h.absoluteFilePath(); + + QFile file(fileName); + if (! file.open(QFile::ReadOnly)) + return; + + const QString source = QTextStream(&file).readAll(); + file.close(); + + QTextDocument document; + document.setPlainText(source); + + Document::Ptr doc = Document::create(fileName); + const QByteArray preprocessedCode = snapshot.preprocessedCode(source, fileName); + doc->setSource(preprocessedCode); + doc->check(); + + FindASTForwards process(doc, &document); + QList<QTextCursor> cursors = process(doc->translationUnit()->ast()); + + for (int i = 0; i < cursors.length(); ++i) + cursors[i].removeSelectedText(); + + QString replacement; + foreach (const QString &astDerivedClass, astDerivedClasses) { + replacement += QString(QLatin1String("class %1;\n")).arg(astDerivedClass); + } + + cursors.first().insertText(replacement); + + if (file.open(QFile::WriteOnly)) { + QTextStream out(&file); + out << document.toPlainText(); + } +} + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + QStringList files = app.arguments(); + files.removeFirst(); + + if (files.isEmpty()) { + std::cerr << "Usage: cplusplus [path to C++ front-end]" << std::endl; + return EXIT_FAILURE; + } + + QDir cplusplusDir(files.first()); + Snapshot snapshot; + + QStringList astDerivedClasses = generateAST_H(snapshot, cplusplusDir); + astDerivedClasses.sort(); + generateASTFwd_h(snapshot, cplusplusDir, astDerivedClasses); +} diff --git a/src/tools/cplusplus/cplusplus.pro b/src/tools/cplusplus/cplusplus.pro new file mode 100644 index 0000000000..fe3bba5c73 --- /dev/null +++ b/src/tools/cplusplus/cplusplus.pro @@ -0,0 +1,15 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Mon Nov 9 11:48:58 2009 +###################################################################### + +QT = core gui +macx:CONFIG -= app_bundle +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../libs/cplusplus/cplusplus-lib.pri) + +# Input +SOURCES += Main.cpp diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index 24fbe7865f..dab517287b 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -70,6 +70,7 @@ private slots: void assignment_2(); // objc++ + void objc_simple_class(); void objc_attributes_followed_by_at_keyword(); void objc_protocol_forward_declaration_1(); void objc_protocol_definition_1(); @@ -120,11 +121,11 @@ void tst_AST::template_id_1() QVERIFY(ast->asTemplateId() != 0); QCOMPARE(ast->asTemplateId()->identifier_token, 1U); QCOMPARE(ast->asTemplateId()->less_token, 2U); - QVERIFY(ast->asTemplateId()->template_arguments != 0); - QVERIFY(ast->asTemplateId()->template_arguments->template_argument != 0); - QVERIFY(ast->asTemplateId()->template_arguments->template_argument->asNumericLiteral() != 0); - QCOMPARE(ast->asTemplateId()->template_arguments->template_argument->asNumericLiteral()->literal_token, 3U); - QVERIFY(ast->asTemplateId()->template_arguments->next == 0); + QVERIFY(ast->asTemplateId()->template_argument_list != 0); + QVERIFY(ast->asTemplateId()->template_argument_list->value != 0); + QVERIFY(ast->asTemplateId()->template_argument_list->value->asNumericLiteral() != 0); + QCOMPARE(ast->asTemplateId()->template_argument_list->value->asNumericLiteral()->literal_token, 3U); + QVERIFY(ast->asTemplateId()->template_argument_list->next == 0); QCOMPARE(ast->asTemplateId()->greater_token, 4U); } @@ -149,9 +150,9 @@ void tst_AST::new_expression_1() QVERIFY(expr->new_type_id != 0); QVERIFY(expr->new_initializer == 0); - QVERIFY(expr->new_type_id->type_specifier != 0); - QVERIFY(expr->new_type_id->ptr_operators == 0); - QVERIFY(expr->new_type_id->new_array_declarators == 0); + QVERIFY(expr->new_type_id->type_specifier_list != 0); + QVERIFY(expr->new_type_id->ptr_operator_list == 0); + QVERIFY(expr->new_type_id->new_array_declarator_list == 0); } void tst_AST::new_expression_2() @@ -374,7 +375,7 @@ void tst_AST::while_statement() CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement(); QVERIFY(body_stmt != 0); QCOMPARE(body_stmt->lbrace_token, 5U); - QVERIFY(body_stmt->statements == 0); + QVERIFY(body_stmt->statement_list == 0); QCOMPARE(body_stmt->rbrace_token, 6U); } @@ -396,17 +397,17 @@ void tst_AST::while_condition_statement() // check condition ConditionAST *condition = stmt->condition->asCondition(); QVERIFY(condition != 0); - QVERIFY(condition->type_specifier != 0); - QVERIFY(condition->type_specifier->asSimpleSpecifier() != 0); - QCOMPARE(condition->type_specifier->asSimpleSpecifier()->specifier_token, 3U); - QVERIFY(condition->type_specifier->next == 0); + QVERIFY(condition->type_specifier_list != 0); + QVERIFY(condition->type_specifier_list->value->asSimpleSpecifier() != 0); + QCOMPARE(condition->type_specifier_list->value->asSimpleSpecifier()->specifier_token, 3U); + QVERIFY(condition->type_specifier_list->next == 0); QVERIFY(condition->declarator != 0); QVERIFY(condition->declarator->core_declarator != 0); QVERIFY(condition->declarator->core_declarator->asDeclaratorId() != 0); QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name != 0); QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName() != 0); QCOMPARE(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName()->identifier_token, 4U); - QVERIFY(condition->declarator->postfix_declarators == 0); + QVERIFY(condition->declarator->postfix_declarator_list == 0); QVERIFY(condition->declarator->initializer != 0); QVERIFY(condition->declarator->initializer->asSimpleName() != 0); QCOMPARE(condition->declarator->initializer->asSimpleName()->identifier_token, 6U); @@ -415,7 +416,7 @@ void tst_AST::while_condition_statement() CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement(); QVERIFY(body_stmt != 0); QCOMPARE(body_stmt->lbrace_token, 8U); - QVERIFY(body_stmt->statements == 0); + QVERIFY(body_stmt->statement_list == 0); QCOMPARE(body_stmt->rbrace_token, 9U); } @@ -439,7 +440,7 @@ void tst_AST::for_statement() QVERIFY(stmt->statement != 0); QVERIFY(stmt->statement->asCompoundStatement() != 0); QCOMPARE(stmt->statement->asCompoundStatement()->lbrace_token, 6U); - QVERIFY(stmt->statement->asCompoundStatement()->statements == 0); + QVERIFY(stmt->statement->asCompoundStatement()->statement_list == 0); QCOMPARE(stmt->statement->asCompoundStatement()->rbrace_token, 7U); } @@ -457,13 +458,13 @@ void tst_AST::cpp_initializer_or_function_declaration() SimpleDeclarationAST *simple_decl = stmt->declaration->asSimpleDeclaration(); QVERIFY(simple_decl != 0); - QVERIFY(simple_decl->decl_specifier_seq != 0); - QVERIFY(simple_decl->decl_specifier_seq->next == 0); - QVERIFY(simple_decl->declarators != 0); - QVERIFY(simple_decl->declarators->next == 0); + QVERIFY(simple_decl->decl_specifier_list != 0); + QVERIFY(simple_decl->decl_specifier_list->next == 0); + QVERIFY(simple_decl->declarator_list != 0); + QVERIFY(simple_decl->declarator_list->next == 0); QCOMPARE(simple_decl->semicolon_token, 6U); - NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_seq->asNamedTypeSpecifier(); + NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_list->value->asNamedTypeSpecifier(); QVERIFY(named_ty != 0); QVERIFY(named_ty->name != 0); @@ -471,11 +472,11 @@ void tst_AST::cpp_initializer_or_function_declaration() QVERIFY(simple_named_ty != 0); QCOMPARE(simple_named_ty->identifier_token, 1U); - DeclaratorAST *declarator = simple_decl->declarators->declarator; + DeclaratorAST *declarator = simple_decl->declarator_list->value; QVERIFY(declarator != 0); QVERIFY(declarator->core_declarator != 0); - QVERIFY(declarator->postfix_declarators != 0); - QVERIFY(declarator->postfix_declarators->next == 0); + QVERIFY(declarator->postfix_declarator_list != 0); + QVERIFY(declarator->postfix_declarator_list->next == 0); QVERIFY(declarator->initializer == 0); DeclaratorIdAST *decl_id = declarator->core_declarator->asDeclaratorId(); @@ -484,7 +485,7 @@ void tst_AST::cpp_initializer_or_function_declaration() QVERIFY(decl_id->name->asSimpleName() != 0); QCOMPARE(decl_id->name->asSimpleName()->identifier_token, 2U); - FunctionDeclaratorAST *fun_declarator = declarator->postfix_declarators->asFunctionDeclarator(); + FunctionDeclaratorAST *fun_declarator = declarator->postfix_declarator_list->value->asFunctionDeclarator(); QVERIFY(fun_declarator != 0); QCOMPARE(fun_declarator->lparen_token, 3U); QVERIFY(fun_declarator->parameters != 0); @@ -492,24 +493,38 @@ void tst_AST::cpp_initializer_or_function_declaration() // check the formal arguments ParameterDeclarationClauseAST *param_clause = fun_declarator->parameters; - QVERIFY(param_clause->parameter_declarations != 0); - QVERIFY(param_clause->parameter_declarations->next == 0); + QVERIFY(param_clause->parameter_declaration_list != 0); + QVERIFY(param_clause->parameter_declaration_list->next == 0); QCOMPARE(param_clause->dot_dot_dot_token, 0U); // check the parameter - DeclarationListAST *declarations = param_clause->parameter_declarations->asDeclarationList(); + DeclarationListAST *declarations = param_clause->parameter_declaration_list; QVERIFY(declarations); - QVERIFY(declarations->declaration); + QVERIFY(declarations->value); QVERIFY(! declarations->next); - ParameterDeclarationAST *param = declarations->declaration->asParameterDeclaration(); + ParameterDeclarationAST *param = declarations->value->asParameterDeclaration(); QVERIFY(param); - QVERIFY(param->type_specifier != 0); - QVERIFY(param->type_specifier->next == 0); - QVERIFY(param->type_specifier->asNamedTypeSpecifier() != 0); - QVERIFY(param->type_specifier->asNamedTypeSpecifier()->name != 0); - QVERIFY(param->type_specifier->asNamedTypeSpecifier()->name->asSimpleName() != 0); - QCOMPARE(param->type_specifier->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U); + QVERIFY(param->type_specifier_list != 0); + QVERIFY(param->type_specifier_list->next == 0); + QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier() != 0); + QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name != 0); + QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName() != 0); + QCOMPARE(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U); +} + +void tst_AST::objc_simple_class() +{ + QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" + "@interface Zoo {} +(id)alloc;-(id)init;@end\n" + "@implementation Zoo\n" + "+(id)alloc{}\n" + "-(id)init{}\n" + "@end\n" + )); + + AST *ast = unit->ast(); + QVERIFY(ast); } void tst_AST::objc_attributes_followed_by_at_keyword() @@ -553,12 +568,12 @@ void tst_AST::normal_array_access() FunctionDefinitionAST *func = ast->asFunctionDefinition(); QVERIFY(func); - StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; + StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list; QVERIFY(bodyStatements); QVERIFY(bodyStatements->next); QVERIFY(bodyStatements->next->next); - QVERIFY(bodyStatements->next->next->statement); - ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression; + QVERIFY(bodyStatements->next->next->value); + ExpressionAST *expr = bodyStatements->next->next->value->asReturnStatement()->expression; QVERIFY(expr); PostfixExpressionAST *postfixExpr = expr->asPostfixExpression(); @@ -573,8 +588,8 @@ void tst_AST::normal_array_access() } { - QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next); - ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess(); + QVERIFY(postfixExpr->postfix_expression_list && !postfixExpr->postfix_expression_list->next); + ArrayAccessAST *rhs = postfixExpr->postfix_expression_list->value->asArrayAccess(); QVERIFY(rhs && rhs->expression); SimpleNameAST *b = rhs->expression->asSimpleName(); QVERIFY(b); @@ -597,9 +612,9 @@ void tst_AST::array_access_with_nested_expression() FunctionDefinitionAST *func = ast->asFunctionDefinition(); QVERIFY(func); - StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; - QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->statement); - ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression; + StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list; + QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->value); + ExpressionAST *expr = bodyStatements->next->next->value->asReturnStatement()->expression; QVERIFY(expr); CastExpressionAST *castExpr = expr->asCastExpression(); @@ -619,8 +634,8 @@ void tst_AST::array_access_with_nested_expression() } { - QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next); - ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess(); + QVERIFY(postfixExpr->postfix_expression_list && !postfixExpr->postfix_expression_list->next); + ArrayAccessAST *rhs = postfixExpr->postfix_expression_list->value->asArrayAccess(); QVERIFY(rhs && rhs->expression); SimpleNameAST *b = rhs->expression->asSimpleName(); QVERIFY(b); @@ -642,11 +657,11 @@ void tst_AST::objc_msg_send_expression() FunctionDefinitionAST *func = ast->asFunctionDefinition(); QVERIFY(func); - StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; - QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->statement); + StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list; + QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->value); {// check the NSObject declaration - DeclarationStatementAST *firstStatement = bodyStatements->statement->asDeclarationStatement(); + DeclarationStatementAST *firstStatement = bodyStatements->value->asDeclarationStatement(); QVERIFY(firstStatement); DeclarationAST *objDecl = firstStatement->declaration; QVERIFY(objDecl); @@ -654,8 +669,8 @@ void tst_AST::objc_msg_send_expression() QVERIFY(simpleDecl); {// check the type (NSObject) - QVERIFY(simpleDecl->decl_specifier_seq && !simpleDecl->decl_specifier_seq->next); - NamedTypeSpecifierAST *namedType = simpleDecl->decl_specifier_seq->asNamedTypeSpecifier(); + QVERIFY(simpleDecl->decl_specifier_list && !simpleDecl->decl_specifier_list->next); + NamedTypeSpecifierAST *namedType = simpleDecl->decl_specifier_list->value->asNamedTypeSpecifier(); QVERIFY(namedType && namedType->name); SimpleNameAST *typeName = namedType->name->asSimpleName(); QVERIFY(typeName); @@ -663,20 +678,22 @@ void tst_AST::objc_msg_send_expression() } {// check the assignment - QVERIFY(simpleDecl->declarators && !simpleDecl->declarators->next); - DeclaratorAST *declarator = simpleDecl->declarators->declarator; + QVERIFY(simpleDecl->declarator_list && !simpleDecl->declarator_list->next); + DeclaratorAST *declarator = simpleDecl->declarator_list->value; QVERIFY(declarator); - QVERIFY(!declarator->attributes); + QVERIFY(!declarator->attribute_list); - QVERIFY(declarator->ptr_operators && !declarator->ptr_operators->next && declarator->ptr_operators->asPointer() && !declarator->ptr_operators->asPointer()->cv_qualifier_seq); + QVERIFY(declarator->ptr_operator_list && !declarator->ptr_operator_list->next + && declarator->ptr_operator_list->value->asPointer() + && ! declarator->ptr_operator_list->value->asPointer()->cv_qualifier_list); QVERIFY(declarator->core_declarator && declarator->core_declarator->asDeclaratorId()); NameAST *objNameId = declarator->core_declarator->asDeclaratorId()->name; QVERIFY(objNameId && objNameId->asSimpleName()); QCOMPARE(QLatin1String(unit->identifier(objNameId->asSimpleName()->identifier_token)->chars()), QLatin1String("obj")); - QVERIFY(!declarator->postfix_declarators); - QVERIFY(!declarator->post_attributes); + QVERIFY(!declarator->postfix_declarator_list); + QVERIFY(!declarator->post_attribute_list); ExpressionAST *initializer = declarator->initializer; QVERIFY(initializer); @@ -692,7 +709,7 @@ void tst_AST::objc_msg_send_expression() } {// check the return statement - ExpressionAST *expr = bodyStatements->next->statement->asReturnStatement()->expression; + ExpressionAST *expr = bodyStatements->next->value->asReturnStatement()->expression; QVERIFY(expr); ObjCMessageExpressionAST *msgExpr = expr->asObjCMessageExpression(); @@ -727,11 +744,11 @@ void tst_AST::objc_msg_send_expression_without_selector() FunctionDefinitionAST *func = ast->asFunctionDefinition(); QVERIFY(func); - StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; + StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list; QVERIFY(bodyStatements && bodyStatements->next); - QVERIFY(bodyStatements->next->statement); - QVERIFY(bodyStatements->next->statement->asReturnStatement()); - QVERIFY(!bodyStatements->next->statement->asReturnStatement()->expression); + QVERIFY(bodyStatements->next->value); + QVERIFY(bodyStatements->next->value->asReturnStatement()); + QVERIFY(!bodyStatements->next->value->asReturnStatement()->expression); } QTEST_APPLESS_MAIN(tst_AST) diff --git a/tests/auto/cplusplus/lookup/tst_lookup.cpp b/tests/auto/cplusplus/lookup/tst_lookup.cpp index 8b64c58395..abccca3568 100644 --- a/tests/auto/cplusplus/lookup/tst_lookup.cpp +++ b/tests/auto/cplusplus/lookup/tst_lookup.cpp @@ -6,7 +6,10 @@ #include <ASTVisitor.h> #include <TranslationUnit.h> #include <CppDocument.h> +#include <Literals.h> #include <LookupContext.h> +#include <Name.h> +#include <ResolveExpression.h> #include <Symbols.h> #include <Overview.h> @@ -55,6 +58,11 @@ class tst_Lookup: public QObject private Q_SLOTS: void base_class_defined_1(); + + // Objective-C + void simple_class_1(); + void class_with_baseclass(); + void class_with_protocol_with_protocol(); }; void tst_Lookup::base_class_defined_1() @@ -110,5 +118,204 @@ void tst_Lookup::base_class_defined_1() QVERIFY(classToAST.value(derivedClass) != 0); } +void tst_Lookup::simple_class_1() +{ + const QByteArray source = "\n" + "@interface Zoo {} +(id)alloc; -(id)init; @end\n" + "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n"; + + Document::Ptr doc = Document::create("simple_class_1"); + doc->setSource(source); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 2U); + + Snapshot snapshot; + snapshot.insert(doc->fileName(), doc); + + Document::Ptr emptyDoc = Document::create("<empty>"); + + ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass(); + QVERIFY(iface); + QVERIFY(iface->isInterface()); + QCOMPARE(iface->memberCount(), 2U); + + ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass(); + QVERIFY(impl); + QVERIFY(!impl->isInterface()); + QCOMPARE(impl->memberCount(), 3U); + + ObjCMethod *allocMethod = impl->memberAt(0)->asObjCMethod(); + QVERIFY(allocMethod); + QVERIFY(allocMethod->name() && allocMethod->name()->identifier()); + QCOMPARE(QLatin1String(allocMethod->name()->identifier()->chars()), QLatin1String("alloc")); + + ObjCMethod *deallocMethod = impl->memberAt(2)->asObjCMethod(); + QVERIFY(deallocMethod); + QVERIFY(deallocMethod->name() && deallocMethod->name()->identifier()); + QCOMPARE(QLatin1String(deallocMethod->name()->identifier()->chars()), QLatin1String("dealloc")); + + const LookupContext ctxt(impl, emptyDoc, doc, snapshot); + + // check class resolving: + const QList<Symbol *> candidates = ctxt.resolveObjCClass(impl->name()); + QCOMPARE(candidates.size(), 2); + QVERIFY(candidates.contains(iface)); + QVERIFY(candidates.contains(impl)); + + // check scope expansion: + QList<Scope *> expandedScopes; + ctxt.expand(impl->members(), ctxt.visibleScopes(), &expandedScopes); + QCOMPARE(expandedScopes.size(), 2); + + const ResolveExpression resolver(ctxt); + + // check method resolving: + QList<ResolveExpression::Result> results = resolver.resolveMember(allocMethod->name(), impl); + QCOMPARE(results.size(), 2); + QVERIFY(results.at(0).second == allocMethod || results.at(1).second == allocMethod); + QVERIFY(results.at(0).second->asDeclaration() || results.at(1).second->asDeclaration()); + + results = resolver.resolveMember(deallocMethod->name(), impl); + QCOMPARE(results.size(), 1); + QCOMPARE(results.at(0).second, deallocMethod); +} + +void tst_Lookup::class_with_baseclass() +{ + const QByteArray source = "\n" + "@implementation BaseZoo {} -(void)baseDecl; -(void)baseMethod{} @end\n" + "@interface Zoo: BaseZoo {} +(id)alloc; -(id)init; @end\n" + "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n"; + + Document::Ptr doc = Document::create("class_with_baseclass"); + doc->setSource(source); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 3U); + + Snapshot snapshot; + snapshot.insert(doc->fileName(), doc); + + Document::Ptr emptyDoc = Document::create("<empty>"); + + ObjCClass *baseZoo = doc->globalSymbolAt(0)->asObjCClass(); + QVERIFY(baseZoo); + QVERIFY(!baseZoo->isInterface()); + QCOMPARE(baseZoo->memberCount(), 2U); + + ObjCClass *zooIface = doc->globalSymbolAt(1)->asObjCClass(); + QVERIFY(zooIface); + QVERIFY(zooIface->isInterface()); + QVERIFY(zooIface->baseClass()->name() == baseZoo->name()); + + ObjCClass *zooImpl = doc->globalSymbolAt(2)->asObjCClass(); + QVERIFY(zooImpl); + QVERIFY(!zooImpl->isInterface()); + QCOMPARE(zooImpl->memberCount(), 3U); + + Declaration *baseDecl = baseZoo->memberAt(0)->asDeclaration(); + QVERIFY(baseDecl); + QVERIFY(baseDecl->name() && baseDecl->name()->identifier()); + QCOMPARE(QLatin1String(baseDecl->name()->identifier()->chars()), QLatin1String("baseDecl")); + + ObjCMethod *baseMethod = baseZoo->memberAt(1)->asObjCMethod(); + QVERIFY(baseMethod); + QVERIFY(baseMethod->name() && baseMethod->name()->identifier()); + QCOMPARE(QLatin1String(baseMethod->name()->identifier()->chars()), QLatin1String("baseMethod")); + + const LookupContext ctxt(zooImpl, emptyDoc, doc, snapshot); + + const QList<Symbol *> candidates = ctxt.resolveObjCClass(baseZoo->name()); + QCOMPARE(candidates.size(), 1); + QVERIFY(candidates.contains(baseZoo)); + + QList<Scope *> expandedScopes; + ctxt.expand(zooImpl->members(), ctxt.visibleScopes(), &expandedScopes); + QCOMPARE(expandedScopes.size(), 3); + + const ResolveExpression resolver(ctxt); + + QList<ResolveExpression::Result> results = resolver.resolveMember(baseDecl->name(), zooImpl); + QCOMPARE(results.size(), 1); + QCOMPARE(results.at(0).second, baseDecl); + + results = resolver.resolveMember(baseMethod->name(), zooImpl); + QCOMPARE(results.size(), 1); + QCOMPARE(results.at(0).second, baseMethod); +} + +void tst_Lookup::class_with_protocol_with_protocol() +{ + const QByteArray source = "\n" + "@protocol P1 -(void)p1method; @end\n" + "@protocol P2 <P1> -(void)p2method; @end\n" + "@interface Zoo <P2> {} +(id)alloc; -(id)init; @end\n" + "@implementation Zoo +(id)alloc{} -(id)init{} -(void)dealloc{} @end\n"; + + Document::Ptr doc = Document::create("class_with_protocol_with_protocol"); + doc->setSource(source); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 4U); + + Snapshot snapshot; + snapshot.insert(doc->fileName(), doc); + + Document::Ptr emptyDoc = Document::create("<empty>"); + + ObjCProtocol *P1 = doc->globalSymbolAt(0)->asObjCProtocol(); + QVERIFY(P1); + QCOMPARE(P1->memberCount(), 1U); + QCOMPARE(P1->protocolCount(), 0U); + + Declaration *p1method = P1->memberAt(0)->asDeclaration(); + QVERIFY(p1method); + QCOMPARE(QLatin1String(p1method->name()->identifier()->chars()), QLatin1String("p1method")); + + ObjCProtocol *P2 = doc->globalSymbolAt(1)->asObjCProtocol(); + QVERIFY(P2); + QCOMPARE(P2->memberCount(), 1U); + QCOMPARE(P2->protocolCount(), 1U); + QCOMPARE(QLatin1String(P2->protocolAt(0)->name()->identifier()->chars()), QLatin1String("P1")); + + ObjCClass *zooImpl = doc->globalSymbolAt(3)->asObjCClass(); + QVERIFY(zooImpl); + + const LookupContext ctxt(zooImpl, emptyDoc, doc, snapshot); + + { + const QList<Symbol *> candidates = ctxt.resolveObjCProtocol(P1->name()); + QCOMPARE(candidates.size(), 1); + QVERIFY(candidates.contains(P1)); + } + + { + const QList<Symbol *> candidates = ctxt.resolveObjCProtocol(P2->protocolAt(0)->name()); + QCOMPARE(candidates.size(), 1); + QVERIFY(candidates.contains(P1)); + } + + QList<Scope *> expandedScopes; + ctxt.expand(zooImpl->members(), ctxt.visibleScopes(), &expandedScopes); + QCOMPARE(expandedScopes.size(), 4); + + const ResolveExpression resolver(ctxt); + + QList<ResolveExpression::Result> results = resolver.resolveMember(p1method->name(), zooImpl); + QCOMPARE(results.size(), 1); + QCOMPARE(results.at(0).second, p1method); + + results = resolver.resolveMember(p1method->name(), zooImpl); + QCOMPARE(results.size(), 1); + QCOMPARE(results.at(0).second, p1method); +} + QTEST_APPLESS_MAIN(tst_Lookup) #include "tst_lookup.moc" diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 6da954ae92..33ddf1c3e5 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -31,11 +31,13 @@ public: { control.setDiagnosticClient(&diag); } TranslationUnit *parse(const QByteArray &source, - TranslationUnit::ParseMode mode) + TranslationUnit::ParseMode mode, + bool enableObjc) { StringLiteral *fileId = control.findOrInsertStringLiteral("<stdin>"); TranslationUnit *unit = new TranslationUnit(&control, fileId); unit->setSource(source.constData(), source.length()); + unit->setObjCEnabled(enableObjc); unit->parse(mode); return unit; } @@ -58,8 +60,8 @@ public: Semantic sem(unit->control()); TranslationUnitAST *ast = unit->ast()->asTranslationUnit(); QVERIFY(ast); - for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) { - sem.check(decl->declaration, globals); + for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) { + sem.check(decl->value, globals); } } @@ -76,19 +78,24 @@ public: : errorCount(0) { } - virtual void report(int, StringLiteral *, - unsigned, unsigned, - const char *, va_list) - { ++errorCount; } + virtual void report(int /*level*/, + StringLiteral *fileName, + unsigned line, unsigned column, + const char *format, va_list ap) + { + ++errorCount; + + qDebug() << fileName->chars()<<':'<<line<<':'<<column<<' '<<QString().sprintf(format, ap); + } }; Diagnostic diag; - QSharedPointer<Document> document(const QByteArray &source) + QSharedPointer<Document> document(const QByteArray &source, bool enableObjc = false) { diag.errorCount = 0; // reset the error count. - TranslationUnit *unit = parse(source, TranslationUnit::ParseTranlationUnit); + TranslationUnit *unit = parse(source, TranslationUnit::ParseTranlationUnit, enableObjc); QSharedPointer<Document> doc(new Document(unit)); doc->check(); doc->errorCount = diag.errorCount; @@ -110,6 +117,17 @@ private slots: void template_instance_1(); void expression_under_cursor_1(); + + void bracketed_expression_under_cursor_1(); + void bracketed_expression_under_cursor_2(); + void bracketed_expression_under_cursor_3(); + void bracketed_expression_under_cursor_4(); + void bracketed_expression_under_cursor_5(); + void bracketed_expression_under_cursor_6(); + void bracketed_expression_under_cursor_7(); + void bracketed_expression_under_cursor_8(); + + void objcClass_1(); }; void tst_Semantic::function_declaration_1() @@ -438,5 +456,170 @@ void tst_Semantic::expression_under_cursor_1() QCOMPARE(expression, QString("bar")); } +void tst_Semantic::bracketed_expression_under_cursor_1() +{ + const QString plainText = "int i = 0, j[1], k = j[i"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, QString("i")); +} + +void tst_Semantic::bracketed_expression_under_cursor_2() +{ + const QString plainText = "[receiver msg"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, plainText); +} + +void tst_Semantic::bracketed_expression_under_cursor_3() +{ + const QString plainText = "[receiver msgParam1:0 msgParam2"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, plainText); +} + +void tst_Semantic::bracketed_expression_under_cursor_4() +{ + const QString plainText = "[receiver msgParam1:0 msgParam2:@\"zoo\" msgParam3"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, plainText); +} + +void tst_Semantic::bracketed_expression_under_cursor_5() +{ + const QString plainText = "if ([receiver message"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, QString("[receiver message")); +} + +void tst_Semantic::bracketed_expression_under_cursor_6() +{ + const QString plainText = "if ([receiver msgParam1:1 + i[1] msgParam2"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, QString("[receiver msgParam1:1 + i[1] msgParam2")); +} + +void tst_Semantic::bracketed_expression_under_cursor_7() +{ + const QString plainText = "int i = 0, j[1], k = j[(i == 0) ? 0 : i"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, QString("i")); +} + +void tst_Semantic::bracketed_expression_under_cursor_8() +{ + const QString plainText = "[[receiver msg] param1:[receiver msg] param2"; + + QTextDocument textDocument; + textDocument.setPlainText(plainText); + + QTextCursor tc(&textDocument); + tc.movePosition(QTextCursor::End); + + ExpressionUnderCursor expressionUnderCursor; + const QString expression = expressionUnderCursor(tc); + + QCOMPARE(expression, plainText); +} + +void tst_Semantic::objcClass_1() +{ + QSharedPointer<Document> doc = document("\n" + "@interface Zoo {} +(id)alloc;-(id)init;@end\n" + "@implementation Zoo\n" + "+(id)alloc{}\n" + "-(id)init{}\n" + "-(void)dealloc{}\n" + "@end\n", + true); + + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->symbolCount(), 2U); + + ObjCClass *iface = doc->globals->symbolAt(0)->asObjCClass(); + QVERIFY(iface); + QVERIFY(iface->isInterface()); + QCOMPARE(iface->memberCount(), 2U); + + ObjCClass *impl = doc->globals->symbolAt(1)->asObjCClass(); + QVERIFY(impl); + QVERIFY(!impl->isInterface()); + QCOMPARE(impl->memberCount(), 3U); + + ObjCMethod *allocMethod = impl->memberAt(0)->asObjCMethod(); + QVERIFY(allocMethod); + QVERIFY(allocMethod->name() && allocMethod->name()->identifier()); + QCOMPARE(QLatin1String(allocMethod->name()->identifier()->chars()), QLatin1String("alloc")); + QVERIFY(allocMethod->isStatic()); + + ObjCMethod *deallocMethod = impl->memberAt(2)->asObjCMethod(); + QVERIFY(deallocMethod); + QVERIFY(deallocMethod->name() && deallocMethod->name()->identifier()); + QCOMPARE(QLatin1String(deallocMethod->name()->identifier()->chars()), QLatin1String("dealloc")); + QVERIFY(!deallocMethod->isStatic()); +} + QTEST_APPLESS_MAIN(tst_Semantic) #include "tst_semantic.moc" diff --git a/tests/manual/cplusplus/main.cpp b/tests/manual/cplusplus/main.cpp index 63efc8b985..adc3c0c918 100644 --- a/tests/manual/cplusplus/main.cpp +++ b/tests/manual/cplusplus/main.cpp @@ -377,8 +377,9 @@ int main(int argc, char *argv[]) Namespace *globalNamespace = control.newNamespace(0, 0); Semantic sem(&control); - for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) { - sem.check(decl->declaration, globalNamespace->members()); + for (DeclarationListAST *it = ast->declarations; it; it = it->next) { + DeclarationAST *declaration = it->value; + sem.check(declaration, globalNamespace->members()); } return EXIT_SUCCESS; |