/*! Handle declaration in foreach statement */ bool PointerDeclarationFormatter::visit(ForeachStatementAST *ast) { CHECK_RV(ast, "Invalid AST", true); printCandidate(ast); DeclaratorAST *declarator = ast->declarator; CHECK_RV(declarator, "No declarator", true); CHECK_RV(declarator->ptr_operator_list, "No Pointer or references", true); CHECK_RV(ast->type_specifier_list, "No type specifier", true); SpecifierAST *firstSpecifier = ast->type_specifier_list->value; CHECK_RV(firstSpecifier, "No first type specifier", true); CHECK_RV(ast->symbol, "No symbol", true); Symbol *symbol = ast->symbol->memberAt(0); // Specify activation range const int lastActivationToken = declarator->equal_token ? declarator->equal_token - 1 : declarator->lastToken() - 1; TokenRange range(firstSpecifier->firstToken(), lastActivationToken); checkAndRewrite(declarator, symbol, range); return true; }
/*! Handle (1) Simple declarations like in "char *s, *t, *int foo();" (2) Return types of function declarations. */ bool PointerDeclarationFormatter::visit(SimpleDeclarationAST *ast) { CHECK_RV(ast, "Invalid AST", true); printCandidate(ast); const unsigned tokenKind = tokenAt(ast->firstToken()).kind(); const bool astIsOk = tokenKind != T_CLASS && tokenKind != T_STRUCT && tokenKind != T_ENUM; CHECK_RV(astIsOk, "Nothing to do for class/struct/enum", true); DeclaratorListAST *declaratorList = ast->declarator_list; CHECK_RV(declaratorList, "No declarator list", true); DeclaratorAST *firstDeclarator = declaratorList->value; CHECK_RV(firstDeclarator, "No declarator", true); CHECK_RV(ast->symbols, "No Symbols", true); CHECK_RV(ast->symbols->value, "No Symbol", true); List<Symbol *> *sit = ast->symbols; DeclaratorListAST *dit = declaratorList; for (; sit && dit; sit = sit->next, dit = dit->next) { DeclaratorAST *declarator = dit->value; Symbol *symbol = sit->value; const bool isFirstDeclarator = declarator == firstDeclarator; // If were not handling the first declarator, we need to remove // characters from the beginning since our rewritten declaration // will contain all type specifiers. int charactersToRemove = 0; if (!isFirstDeclarator) { const int startAST = m_cppRefactoringFile->startOf(ast); const int startFirstDeclarator = m_cppRefactoringFile->startOf(firstDeclarator); CHECK_RV(startAST < startFirstDeclarator, "No specifier", true); charactersToRemove = startFirstDeclarator - startAST; } // Specify activation range int lastActivationToken = 0; TokenRange range; // (2) Handle function declaration's return type if (symbol->type()->asFunctionType()) { PostfixDeclaratorListAST *pfDeclaratorList = declarator->postfix_declarator_list; CHECK_RV(pfDeclaratorList, "No postfix declarator list", true); PostfixDeclaratorAST *pfDeclarator = pfDeclaratorList->value; CHECK_RV(pfDeclarator, "No postfix declarator", true); FunctionDeclaratorAST *functionDeclarator = pfDeclarator->asFunctionDeclarator(); CHECK_RV(functionDeclarator, "No function declarator", true); // End the activation range before the '(' token. lastActivationToken = functionDeclarator->lparen_token - 1; SpecifierListAST *specifierList = isFirstDeclarator ? ast->decl_specifier_list : declarator->attribute_list; unsigned firstActivationToken = 0; bool foundBegin = false; firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( specifierList, m_cppRefactoringFile->cppDocument()->translationUnit(), lastActivationToken, &foundBegin); if (!foundBegin) { CHECK_RV(!isFirstDeclarator, "Declaration without attributes not supported", true); firstActivationToken = declarator->firstToken(); } range.start = firstActivationToken; // (1) Handle 'normal' declarations. } else { if (isFirstDeclarator) { bool foundBegin = false; unsigned firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( ast->decl_specifier_list, m_cppRefactoringFile->cppDocument()->translationUnit(), declarator->firstToken(), &foundBegin); CHECK_RV(foundBegin, "Declaration without attributes not supported", true); range.start = firstActivationToken; } else { range.start = declarator->firstToken(); } lastActivationToken = declarator->equal_token ? declarator->equal_token - 1 : declarator->lastToken() - 1; } range.end = lastActivationToken; checkAndRewrite(declarator, symbol, range, charactersToRemove); } return true; }