Changeset View
Changeset View
Standalone View
Standalone View
duchain/declarationbuilder.cpp
Show First 20 Lines • Show All 382 Lines • ▼ Show 20 Line(s) | 376 | { | |||
---|---|---|---|---|---|
383 | Python::AstDefaultVisitor::visitWithItem(node); | 383 | Python::AstDefaultVisitor::visitWithItem(node); | ||
384 | } | 384 | } | ||
385 | 385 | | |||
386 | void DeclarationBuilder::visitFor(ForAst* node) | 386 | void DeclarationBuilder::visitFor(ForAst* node) | ||
387 | { | 387 | { | ||
388 | if ( node->iterator ) { | 388 | if ( node->iterator ) { | ||
389 | ExpressionVisitor v(currentContext()); | 389 | ExpressionVisitor v(currentContext()); | ||
390 | v.visitNode(node->iterator); | 390 | v.visitNode(node->iterator); | ||
391 | assignToUnknown(node->target, Helper::contentOfIterable(v.lastType())); | 391 | assignToUnknown(node->target, Helper::contentOfIterable(v.lastType(), topContext())); | ||
392 | } | 392 | } | ||
393 | Python::ContextBuilder::visitFor(node); | 393 | Python::ContextBuilder::visitFor(node); | ||
394 | } | 394 | } | ||
395 | 395 | | |||
396 | Declaration* DeclarationBuilder::findDeclarationInContext(QStringList dottedNameIdentifier, TopDUContext* ctx) const | 396 | Declaration* DeclarationBuilder::findDeclarationInContext(QStringList dottedNameIdentifier, TopDUContext* ctx) const | ||
397 | { | 397 | { | ||
398 | DUChainReadLocker lock(DUChain::lock()); | 398 | DUChainReadLocker lock(DUChain::lock()); | ||
399 | DUContext* currentContext = ctx; | 399 | DUContext* currentContext = ctx; | ||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Line(s) | 489 | { | |||
492 | // because it is actually used *before* its real declaration: [foo for foo in bar] | 492 | // because it is actually used *before* its real declaration: [foo for foo in bar] | ||
493 | // The DUChain doesn't like this, so for now, the declaration is at the opening bracket, | 493 | // The DUChain doesn't like this, so for now, the declaration is at the opening bracket, | ||
494 | // and both other occurrences are uses of that declaration. | 494 | // and both other occurrences are uses of that declaration. | ||
495 | // TODO add a special case to the usebuilder to display the second occurrence as a declaration | 495 | // TODO add a special case to the usebuilder to display the second occurrence as a declaration | ||
496 | spoofNodePosition(node->target, currentContext()->range().start.column - 1); | 496 | spoofNodePosition(node->target, currentContext()->range().start.column - 1); | ||
497 | 497 | | |||
498 | ExpressionVisitor v(currentContext()); | 498 | ExpressionVisitor v(currentContext()); | ||
499 | v.visitNode(node->iterator); | 499 | v.visitNode(node->iterator); | ||
500 | assignToUnknown(node->target, Helper::contentOfIterable(v.lastType())); | 500 | assignToUnknown(node->target, Helper::contentOfIterable(v.lastType(), topContext())); | ||
501 | } | 501 | } | ||
502 | 502 | | |||
503 | void DeclarationBuilder::visitImport(ImportAst* node) | 503 | void DeclarationBuilder::visitImport(ImportAst* node) | ||
504 | { | 504 | { | ||
505 | Python::ContextBuilder::visitImport(node); | 505 | Python::ContextBuilder::visitImport(node); | ||
506 | DUChainWriteLocker lock; | 506 | DUChainWriteLocker lock; | ||
507 | foreach ( AliasAst* name, node->names ) { | 507 | foreach ( AliasAst* name, node->names ) { | ||
508 | QString moduleName = name->name->value; | 508 | QString moduleName = name->name->value; | ||
▲ Show 20 Lines • Show All 704 Lines • ▼ Show 20 Line(s) | 1211 | else { | |||
1213 | // the declaration is already there, just update the type | 1213 | // the declaration is already there, just update the type | ||
1214 | if ( ! attributeDeclaration->type<FunctionType>() ) { | 1214 | if ( ! attributeDeclaration->type<FunctionType>() ) { | ||
1215 | auto newType = Helper::mergeTypes(attributeDeclaration->abstractType(), element.type); | 1215 | auto newType = Helper::mergeTypes(attributeDeclaration->abstractType(), element.type); | ||
1216 | attributeDeclaration->setAbstractType(newType); | 1216 | attributeDeclaration->setAbstractType(newType); | ||
1217 | } | 1217 | } | ||
1218 | } | 1218 | } | ||
1219 | } | 1219 | } | ||
1220 | 1220 | | |||
1221 | void tryUnpackType(AbstractType::Ptr sourceType, QVector<AbstractType::Ptr>& outTypes, int starred) { | 1221 | void DeclarationBuilder::tryUnpackType(AbstractType::Ptr sourceType, QVector<AbstractType::Ptr>& outTypes, int starred) { | ||
1222 | // Helper for assignToTuple() below. | | |||
1223 | // If sourceType is a container that can be unpacked into outTypes, do so. | | |||
1224 | if ( const auto indexed = sourceType.cast<IndexedContainer>() ) { | 1222 | if ( const auto indexed = sourceType.cast<IndexedContainer>() ) { | ||
1225 | int spare = indexed->typesCount() - outTypes.length(); | 1223 | int spare = indexed->typesCount() - outTypes.length(); | ||
1226 | if ( spare < -1 or (starred == -1 and spare != 0) ) { | 1224 | if ( spare < -1 or (starred == -1 and spare != 0) ) { | ||
1227 | return; // Wrong number of elements to unpack. | 1225 | return; // Wrong number of elements to unpack. | ||
1228 | } | 1226 | } | ||
1229 | for ( int i_out = 0, i_in = 0; i_out < outTypes.length(); ++i_out ) { | 1227 | for ( int i_out = 0, i_in = 0; i_out < outTypes.length(); ++i_out ) { | ||
1230 | if ( i_out == starred ) { // PEP-3132. Made into list in assignToTuple(). | 1228 | if ( i_out == starred ) { // PEP-3132. Made into list in assignToTuple(). | ||
1231 | for (; spare >= 0; --spare, ++i_in ) { | 1229 | for (; spare >= 0; --spare, ++i_in ) { | ||
1232 | auto content = indexed->typeAt(i_in).abstractType(); | 1230 | auto content = indexed->typeAt(i_in).abstractType(); | ||
1233 | outTypes[i_out] = Helper::mergeTypes(outTypes.at(i_out), content); | 1231 | outTypes[i_out] = Helper::mergeTypes(outTypes.at(i_out), content); | ||
1234 | } | 1232 | } | ||
1235 | } else { | 1233 | } else { | ||
1236 | auto content = indexed->typeAt(i_in).abstractType(); | 1234 | auto content = indexed->typeAt(i_in).abstractType(); | ||
1237 | outTypes[i_out] = Helper::mergeTypes(outTypes.at(i_out), content); | 1235 | outTypes[i_out] = Helper::mergeTypes(outTypes.at(i_out), content); | ||
1238 | ++i_in; | 1236 | ++i_in; | ||
1239 | } | 1237 | } | ||
1240 | } | 1238 | } | ||
1241 | } else { | 1239 | } else { | ||
1242 | auto content = Helper::contentOfIterable(sourceType); | 1240 | auto content = Helper::contentOfIterable(sourceType, topContext()); | ||
1243 | if ( !Helper::isUsefulType(content) ) { | 1241 | if ( !Helper::isUsefulType(content) ) { | ||
1244 | return; | 1242 | return; | ||
1245 | } | 1243 | } | ||
1246 | for (auto out = outTypes.begin(); out != outTypes.end(); ++out) { | 1244 | for (auto out = outTypes.begin(); out != outTypes.end(); ++out) { | ||
1247 | *out = Helper::mergeTypes(*out, content); | 1245 | *out = Helper::mergeTypes(*out, content); | ||
1248 | } | 1246 | } | ||
1249 | } | 1247 | } | ||
1250 | } | 1248 | } | ||
▲ Show 20 Lines • Show All 654 Lines • Show Last 20 Lines |