bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast) { unsigned sourceLocation; if (ast->name) sourceLocation = ast->name->firstToken(); else sourceLocation = ast->firstToken(); Name *protocolName = semantic()->check(ast->name, _scope); ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, protocolName); protocol->setStartOffset(tokenAt(ast->firstToken()).offset); 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; Name *protocolName = semantic()->check(name, _scope); ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); protocol->addProtocol(baseProtocol); } } int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Public); for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) { semantic()->check(it->declaration, protocol->members()); } (void) semantic()->switchObjCVisibility(previousObjCVisibility); ast->symbol = protocol; _scope->enterSymbol(protocol); return false; }
bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) { unsigned sourceLocation; if (ast->class_name) sourceLocation = ast->class_name->firstToken(); else sourceLocation = ast->firstToken(); Name *className = semantic()->check(ast->class_name, _scope); ObjCClass *klass = control()->newObjCClass(sourceLocation, className); klass->setStartOffset(tokenAt(ast->firstToken()).offset); klass->setEndOffset(tokenAt(ast->lastToken()).offset); ast->symbol = klass; klass->setInterface(ast->interface_token != 0); if (ast->category_name) { Name *categoryName = semantic()->check(ast->category_name, _scope); klass->setCategoryName(categoryName); } if (ast->superclass) { Name *superClassName = semantic()->check(ast->superclass, _scope); ObjCBaseClass *superKlass = control()->newObjCBaseClass(ast->superclass->firstToken(), superClassName); klass->setBaseClass(superKlass); } 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; Name *protocolName = semantic()->check(name, _scope); ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); klass->addProtocol(baseProtocol); } } _scope->enterSymbol(klass); 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()); } } (void) semantic()->switchObjCVisibility(Function::Public); for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) { semantic()->check(it->declaration, klass->members()); } (void) semantic()->switchObjCVisibility(previousObjCVisibility); return false; }
void CppTree2Uml::parseTemplateDeclaration(TemplateDeclarationAST* ast) { TemplateParameterListAST* parmListAST = ast->templateParameterList(); if (parmListAST == NULL) return; QList<TemplateParameterAST*> parmList = parmListAST->templateParameterList(); for (int i = 0; i < parmList.size(); ++i) { // The template is either a typeParameter or a typeValueParameter. TemplateParameterAST* tmplParmNode = parmList.at(i); TypeParameterAST* typeParmNode = tmplParmNode->typeParameter(); if (typeParmNode) { NameAST* nameNode = typeParmNode->name(); if (nameNode) { QString typeName = nameNode->unqualifiedName()->text(); Model_Utils::NameAndType nt(typeName, NULL); m_templateParams.append(nt); } else { uError() << "nameNode is NULL"; } } ParameterDeclarationAST* valueNode = tmplParmNode->typeValueParameter(); if (valueNode) { TypeSpecifierAST* typeSpec = valueNode->typeSpec(); if (typeSpec == NULL) { uError() << "typeSpec is NULL"; continue; } QString typeName = typeSpec->name()->text(); UMLObject *t = Import_Utils::createUMLObject(UMLObject::ot_UMLObject, typeName, m_currentNamespace[m_nsCnt]); DeclaratorAST* declNode = valueNode->declarator(); NameAST* nameNode = declNode->declaratorId(); if (nameNode == NULL) { uError() << "CppTree2Uml::parseTemplateDeclaration(value):" << " nameNode is NULL"; continue; } QString paramName = nameNode->unqualifiedName()->text(); Model_Utils::NameAndType nt(paramName, t); m_templateParams.append(nt); } } if (ast->declaration()) TreeParser::parseDeclaration(ast->declaration()); }
void CppTree2Uml::parseEnumSpecifier(EnumSpecifierAST* ast) { NameAST *nameNode = ast->name(); if (nameNode == NULL) return; // skip constants QString typeName = nameNode->unqualifiedName()->text().trimmed(); if (typeName.isEmpty()) return; // skip constants UMLObject *o = Import_Utils::createUMLObject(UMLObject::ot_Enum, typeName, m_currentNamespace[m_nsCnt], ast->comment()); QList<EnumeratorAST*> l = ast->enumeratorList(); for (int i = 0; i < l.size(); ++i) { QString enumLiteral = l.at(i)->id()->text(); QString enumLiteralValue = QString(); if (l.at(i)->expr()) { enumLiteralValue = l.at(i)->expr()->text(); } Import_Utils::addEnumLiteral((UMLEnum*)o, enumLiteral, QString(), enumLiteralValue); } }
void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions) const { AST *ast = positions.ast; if (ast->asCompoundStatement()) { // Allow first selecting the contents of the scope, without selecting the braces, and // afterwards select the contents together with braces. if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting inner contents of compound statement."; unsigned firstInnerTokenIndex = positions.firstTokenIndex + 1; unsigned lastInnerTokenIndex = positions.lastTokenIndex - 2; Token firstInnerToken = m_unit->tokenAt(firstInnerTokenIndex); Token lastInnerToken = m_unit->tokenAt(lastInnerTokenIndex); if (debug) { qDebug() << "LastInnerToken:" << lastInnerToken.spell(); qDebug() << "FirstInnerToken:" << firstInnerToken.spell(); } // Check if compound statement is empty, then select just the blank space inside it. int newPosStart, newPosEnd; if (positions.secondToLastTokenIndex - positions.firstTokenIndex <= 1) { // TODO: If the empty space has a new tab character, or spaces, and the document is // not saved, the last semantic info is not updated, and the selection is not // properly computed. Figure out how to work around this. newPosStart = getTokenEndCursorPosition(positions.firstTokenIndex, m_workingCursor); newPosEnd = getTokenStartCursorPosition(positions.secondToLastTokenIndex, m_workingCursor); if (debug) qDebug() << "Selecting inner contents of compound statement which is empty."; } else { // Select the inner contents of the scope, without the braces. newPosStart = getTokenStartCursorPosition(firstInnerTokenIndex, m_workingCursor); newPosEnd = getTokenEndCursorPosition(lastInnerTokenIndex, m_workingCursor); } if (debug) { qDebug() << "New" << newPosStart << newPosEnd << "Old" << m_workingCursor.anchor() << m_workingCursor.position(); } positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } // Next time, we select the braces as well. Reverse for shrinking. // The positions already have the correct selection, so no need to set them. } else if (CallAST *callAST = ast->asCall()) { unsigned firstParenTokenIndex = callAST->lparen_token; unsigned lastParenTokenIndex = callAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } // Select the parenthesis of the call, and everything between. int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); bool isInFunctionName = m_initialChangeSelectionCursor.position() <= newPosStart; // If cursor is inside the function name, select the name implicitly (because it's a // different AST node), and then the whole call expression (so just one step). // If cursor is inside parentheses, on first step select everything inside them, // on second step select the everything inside parentheses including them, // on third step select the whole call expression. if (currentASTStep() == 1 && !isInFunctionName) { if (debug) qDebug() << "Selecting everything inside parentheses."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2 && !isInFunctionName) { if (debug) qDebug() << "Selecting everything inside and including " "the parentheses of the function call."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (StringLiteralAST *stringLiteralAST = ast->asStringLiteral()) { // Select literal without quotes on first step, and the whole literal on next step. if (currentASTStep() == 1) { Token firstToken = m_unit->tokenAt(stringLiteralAST->firstToken()); bool isRawLiteral = firstToken.f.kind >= T_FIRST_RAW_STRING_LITERAL && firstToken.f.kind <= T_RAW_UTF32_STRING_LITERAL; if (debug && isRawLiteral) qDebug() << "Is raw literal."; // Start from positions that include quotes. int newPosEnd = positions.astPosEnd; // Decrement last position to skip last quote. --newPosEnd; // If raw literal also skip parenthesis. if (isRawLiteral) --newPosEnd; // Start position will be the end position minus the size of the actual contents of the // literal. int newPosStart = newPosEnd - static_cast<int>(firstToken.string->size()); // Skip raw literal parentheses. if (isRawLiteral) newPosStart += 2; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; if (debug) qDebug() << "Selecting inner contents of string literal."; } } else if (NumericLiteralAST *numericLiteralAST = ast->asNumericLiteral()) { Token firstToken = m_unit->tokenAt(numericLiteralAST->firstToken()); // If char literal, select it without quotes on first step. if (firstToken.isCharLiteral()) { if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting inner contents of char literal."; positions.astPosEnd = positions.astPosEnd - 1; positions.astPosStart = positions.astPosEnd - int(firstToken.literal->size()); } } } else if (ForStatementAST *forStatementAST = ast->asForStatement()) { unsigned firstParenTokenIndex = forStatementAST->lparen_token; unsigned lastParenTokenIndex = forStatementAST->rparen_token; fineTuneForStatementPositions(firstParenTokenIndex, lastParenTokenIndex, positions); } else if (RangeBasedForStatementAST *rangeForStatementAST = ast->asRangeBasedForStatement()) { unsigned firstParenTokenIndex = rangeForStatementAST->lparen_token; unsigned lastParenTokenIndex = rangeForStatementAST->rparen_token; fineTuneForStatementPositions(firstParenTokenIndex, lastParenTokenIndex, positions); } else if (ClassSpecifierAST *classSpecificerAST = ast->asClassSpecifier()) { unsigned firstBraceTokenIndex = classSpecificerAST->lbrace_token; unsigned lastBraceTokenIndex = classSpecificerAST->rbrace_token; unsigned classKeywordTokenIndex = classSpecificerAST->classkey_token; Token firstBraceToken = m_unit->tokenAt(firstBraceTokenIndex); Token lastBraceToken = m_unit->tokenAt(lastBraceTokenIndex); Token classKeywordToken = m_unit->tokenAt(classKeywordTokenIndex); if (debug) { qDebug() << "firstBraceToken:" << firstBraceToken.spell(); qDebug() << "lastBraceToken:" << lastBraceToken.spell(); qDebug() << "classKeywordToken:" << classKeywordToken.spell(); } int newPosStart = getTokenStartCursorPosition(firstBraceTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastBraceTokenIndex, m_workingCursor); bool isOutsideBraces = m_initialChangeSelectionCursor.position() <= newPosStart; bool isInsideBraces = !isOutsideBraces; int classKeywordPosStart = getTokenStartCursorPosition(classKeywordTokenIndex, m_workingCursor); int classKeywordPosEnd = getTokenEndCursorPosition(classKeywordTokenIndex, m_workingCursor); bool isInClassKeyword = m_initialChangeSelectionCursor.anchor() >= classKeywordPosStart && m_initialChangeSelectionCursor.position() <= classKeywordPosEnd; bool isInClassName = false; int classNamePosEnd = newPosEnd; NameAST *nameAST = classSpecificerAST->name; if (nameAST) { SimpleNameAST *classNameAST = nameAST->asSimpleName(); if (classNameAST) { unsigned identifierTokenIndex = classNameAST->identifier_token; Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) qDebug() << "identifierToken:" << identifierToken.spell(); int classNamePosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); classNamePosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); isInClassName = m_initialChangeSelectionCursor.anchor() >= classNamePosStart && m_initialChangeSelectionCursor.position() <= classNamePosEnd; } } if (currentASTStep() == 1 && isInsideBraces) { if (debug) qDebug() << "Selecting everything inside braces of class statement."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2 && isInsideBraces) { if (debug) qDebug() << "Selecting braces of class statement."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } if (currentASTStep() == 1 && isInClassKeyword) { if (debug) qDebug() << "Selecting class keyword."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classKeywordPosEnd; } if (currentASTStep() == 2 && isInClassKeyword) { if (debug) qDebug() << "Selecting class keyword and name."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classNamePosEnd; } if (currentASTStep() == 1 && isInClassName) { if (debug) qDebug() << "Selecting class keyword and name."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classNamePosEnd; } } else if (NamespaceAST *namespaceAST = ast->asNamespace()) { unsigned namespaceTokenIndex = namespaceAST->namespace_token; unsigned identifierTokenIndex = namespaceAST->identifier_token; Token namespaceToken = m_unit->tokenAt(namespaceTokenIndex); Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) { qDebug() << "namespace token:" << namespaceToken.spell(); qDebug() << "identifier token:" << identifierToken.spell(); } int namespacePosStart = getTokenStartCursorPosition(namespaceTokenIndex, m_workingCursor); int namespacePosEnd = getTokenEndCursorPosition(namespaceTokenIndex, m_workingCursor); int identifierPosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); int identifierPosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); bool isInNamespaceKeyword = m_initialChangeSelectionCursor.position() <= namespacePosEnd; bool isInNamespaceIdentifier = m_initialChangeSelectionCursor.anchor() >= identifierPosStart && m_initialChangeSelectionCursor.position() <= identifierPosEnd; if (currentASTStep() == 1) { if (isInNamespaceKeyword) { if (debug) qDebug() << "Selecting namespace keyword."; positions.astPosStart = namespacePosStart; positions.astPosEnd = namespacePosEnd; } else if (isInNamespaceIdentifier) { if (debug) qDebug() << "Selecting namespace identifier."; positions.astPosStart = identifierPosStart; positions.astPosEnd = identifierPosEnd; } } else if (currentASTStep() == 2) { if (isInNamespaceKeyword || isInNamespaceIdentifier) { if (debug) qDebug() << "Selecting namespace keyword and identifier."; positions.astPosStart = namespacePosStart; positions.astPosEnd = identifierPosEnd; } } } else if (ExpressionListParenAST *parenAST = ast->asExpressionListParen()) { unsigned firstParenTokenIndex = parenAST->lparen_token; unsigned lastParenTokenIndex = parenAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } // Select the parentheses, and everything between. int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting everything inside parentheses."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2) { if (debug) qDebug() << "Selecting everything inside including the parentheses."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (FunctionDeclaratorAST* functionDeclaratorAST = ast->asFunctionDeclarator()) { unsigned firstParenTokenIndex = functionDeclaratorAST->lparen_token; unsigned lastParenTokenIndex = functionDeclaratorAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting everything inside and including the parentheses."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) { if (!functionDefinitionAST->function_body) return; CompoundStatementAST *compoundStatementAST = functionDefinitionAST->function_body->asCompoundStatement(); if (!compoundStatementAST) return; if (!functionDefinitionAST->decl_specifier_list || !functionDefinitionAST->decl_specifier_list->value) return; SimpleSpecifierAST *simpleSpecifierAST = functionDefinitionAST->decl_specifier_list->value->asSimpleSpecifier(); if (!simpleSpecifierAST) return; unsigned firstBraceTokenIndex = compoundStatementAST->lbrace_token; unsigned specifierTokenIndex = simpleSpecifierAST->firstToken(); Token firstBraceToken = m_unit->tokenAt(firstBraceTokenIndex); Token specifierToken = m_unit->tokenAt(specifierTokenIndex); if (debug) { qDebug() << "firstBraceToken:" << firstBraceToken.spell(); qDebug() << "specifierToken:" << specifierToken.spell(); } int firstBracePosEnd = getTokenStartCursorPosition(firstBraceTokenIndex, m_workingCursor); bool isOutsideBraces = m_initialChangeSelectionCursor.position() <= firstBracePosEnd; if (currentASTStep() == 1 && isOutsideBraces) { int newPosStart = getTokenStartCursorPosition(specifierTokenIndex, m_workingCursor); if (debug) qDebug() << "Selecting everything to the left of the function braces."; positions.astPosStart = newPosStart; positions.astPosEnd = firstBracePosEnd - 1; } } else if (DeclaratorAST *declaratorAST = ast->asDeclarator()) { PostfixDeclaratorListAST *list = declaratorAST->postfix_declarator_list; if (!list) return; PostfixDeclaratorAST *postfixDeclarator = list->value; if (!postfixDeclarator) return; FunctionDeclaratorAST *functionDeclarator = postfixDeclarator->asFunctionDeclarator(); if (!functionDeclarator) return; SpecifierListAST *cv_list = functionDeclarator->cv_qualifier_list; if (!cv_list) return; SpecifierAST *first_cv = cv_list->value; if (!first_cv) return; unsigned firstCVTokenIndex = first_cv->firstToken(); Token firstCVToken = m_unit->tokenAt(firstCVTokenIndex); if (debug) { qDebug() << "firstCVTokenIndex:" << firstCVToken.spell(); } int cvPosStart = getTokenStartCursorPosition(firstCVTokenIndex, m_workingCursor); bool isBeforeCVList = m_initialChangeSelectionCursor.position() < cvPosStart; if (currentASTStep() == 1 && isBeforeCVList) { if (debug) qDebug() << "Selecting function declarator without CV qualifiers."; int newPosEnd = cvPosStart; positions.astPosEnd = newPosEnd - 1; } } else if (TemplateIdAST *templateIdAST = ast->asTemplateId()) { unsigned identifierTokenIndex = templateIdAST->identifier_token; Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) { qDebug() << "identifierTokenIndex:" << identifierToken.spell(); } int newPosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); bool isInsideIdentifier = m_initialChangeSelectionCursor.anchor() >= newPosStart && m_initialChangeSelectionCursor.position() <= newPosEnd; if (currentASTStep() == 1 && isInsideIdentifier) { if (debug) qDebug() << "Selecting just identifier before selecting template id."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (TemplateDeclarationAST *templateDeclarationAST = ast->asTemplateDeclaration()) { unsigned templateKeywordTokenIndex = templateDeclarationAST->template_token; unsigned greaterTokenIndex = templateDeclarationAST->greater_token; Token templateKeywordToken = m_unit->tokenAt(templateKeywordTokenIndex); Token greaterToken = m_unit->tokenAt(greaterTokenIndex); if (debug) { qDebug() << "templateKeywordTokenIndex:" << templateKeywordToken.spell(); qDebug() << "greaterTokenIndex:" << greaterToken.spell(); } int templateKeywordPosStart = getTokenStartCursorPosition(templateKeywordTokenIndex, m_workingCursor); int templateKeywordPosEnd = getTokenEndCursorPosition(templateKeywordTokenIndex, m_workingCursor); int templateParametersPosEnd = getTokenEndCursorPosition(greaterTokenIndex, m_workingCursor); bool isInsideTemplateKeyword = m_initialChangeSelectionCursor.anchor() >= templateKeywordPosStart && m_initialChangeSelectionCursor.position() <= templateKeywordPosEnd; if (currentASTStep() == 1 && isInsideTemplateKeyword) { if (debug) qDebug() << "Selecting template keyword."; positions.astPosStart = templateKeywordPosStart; positions.astPosEnd = templateKeywordPosEnd; } if (currentASTStep() == 2 && isInsideTemplateKeyword) { if (debug) qDebug() << "Selecting template keyword and parameters."; positions.astPosStart = templateKeywordPosStart; positions.astPosEnd = templateParametersPosEnd; } } else if (LambdaExpressionAST *lambdaExpressionAST = ast->asLambdaExpression()) { // TODO: Fix more lambda cases. LambdaIntroducerAST *lambdaIntroducerAST = lambdaExpressionAST->lambda_introducer; LambdaDeclaratorAST *lambdaDeclaratorAST = lambdaExpressionAST->lambda_declarator; if (!lambdaDeclaratorAST) return; TrailingReturnTypeAST *trailingReturnTypeAST = lambdaDeclaratorAST->trailing_return_type; unsigned firstSquareBracketTokenIndex = lambdaIntroducerAST->lbracket_token; unsigned lastParenTokenIndex = lambdaDeclaratorAST->rparen_token; Token firstSquareBracketToken = m_unit->tokenAt(firstSquareBracketTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstSquareBracketToken:" << firstSquareBracketToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } int firstSquareBracketPosStart = getTokenStartCursorPosition(firstSquareBracketTokenIndex, m_workingCursor); int lastParenPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); bool isInsideDeclarator = m_initialChangeSelectionCursor.anchor() >= firstSquareBracketPosStart && m_initialChangeSelectionCursor.position() <= lastParenPosEnd; if (currentASTStep() == 1 && isInsideDeclarator) { if (debug) qDebug() << "Selecting lambda capture group and arguments."; positions.astPosStart = firstSquareBracketPosStart; positions.astPosEnd = lastParenPosEnd; } if (currentASTStep() == 2 && isInsideDeclarator && trailingReturnTypeAST) { if (debug) qDebug() << "Selecting lambda prototype."; unsigned lastReturnTypeTokenIndex = trailingReturnTypeAST->lastToken(); Token lastReturnTypeToken = m_unit->tokenAt(lastReturnTypeTokenIndex); if (debug) qDebug() << "lastReturnTypeToken:" << lastReturnTypeToken.spell(); int lastReturnTypePosEnd = getTokenEndCursorPosition(lastReturnTypeTokenIndex, m_workingCursor); positions.astPosStart = firstSquareBracketPosStart; positions.astPosEnd = lastReturnTypePosEnd - 2; } } }
void TypeDesc::init( QString stri ) { m_data = 0; maybeInit(); if ( stri.isEmpty() ) return ; m_data->m_dec = stri; ///Store the decoration QStringList ls = splitType( stri ); QString str = ls.front().stripWhiteSpace(); ///Extract multiple types that may be written as a scope and put them to the next-types-list if ( !ls.isEmpty() ) { ls.pop_front(); if ( !ls.isEmpty() ) { m_data->m_nextType = TypeDescPointer( new TypeDescShared( ls.join( "::" ) ) ); } } while ( str.startsWith( QString( functionMark ) ) ) { m_data->m_functionDepth++; str = str.mid( strlen( functionMark ) ).stripWhiteSpace(); } bool isFunction = false, shorten = true; //Little hack done for performance-reasons, to do less comparing if( str.length() >= 4 ) { QChar c = str[0]; switch( c.latin1() ) { case 's': if( str[1] == 'h' ) { if( str.startsWith( "short" ) ) shorten = false; } else if( str[1] == 'i' ) { if( str.startsWith( "signed" ) ) shorten = false; } break; case 'l': if( str.startsWith( "long" ) ) shorten = false; break; case 'u': if( str.startsWith( "unsigned" ) ) shorten = false; break; case 'o': if( str.startsWith( "operator " ) ) { isFunction = true; shorten = false; } } } ///Since function-names are also processed by this function, this check has to be done if( shorten ) { ///Remove any prefixes like const or typename(very limited algorithm) int len = str.find( "<" ); if ( len == -1 ) len = str.length(); int currentStart = 0; bool wasEmpty = false; for ( int a = 0; a < len; a++ ) { if ( str[ a ] == ' ' ) { wasEmpty = true; } else if( wasEmpty && isValidIdentifierSign( str[a] ) ){ currentStart = a; wasEmpty = false; } } str = str.mid( currentStart ); } #ifdef USELEXER Driver d; Lexer lex( &d ); lex.setSource( str ); Parser parser( &d, &lex ); TypeSpecifierAST::Node typeSpec; if ( parser.parseTypeSpecifier( typeSpec ) ) { NameAST * name = typeSpec->name(); QPtrList<ClassOrNamespaceNameAST> l = name->classOrNamespaceNameList(); QPtrListIterator<ClassOrNamespaceNameAST> it( l ); QString type; while ( it.current() ) { if ( it.current() ->name() ) { type += it.current() ->name() ->text() + "::"; } ++it; } if ( name->unqualifiedName() && name->unqualifiedName() ->name() ) { type += name->unqualifiedName() ->name() ->text(); } m_data->m_cleanName = type.stripWhiteSpace(); takeTemplateParams( str ); m_data->m_pointerDepth = countExtract( '*', str ); } #else if( !isFunction ) { takeData( str ); m_data->m_pointerDepth = countExtract( '*', str ); } else { m_data->m_cleanName = str; } #endif }