SVN commit 1057398 by rodda: Protect KZip object from multithreaded access with a mutex - fixes race condition crashes Improve type builder to register types for function arguments and add them to the function type Resolve functions from the correct context Now the uses of functions start to be resolved correctly M +29 -6 duchain/expressionvisitor.cpp M +10 -0 duchain/typebuilder.cpp M +1 -0 duchain/typebuilder.h M +6 -2 duchain/viablefunctions.cpp M +7 -0 javalanguagesupport.cpp M +3 -0 javalanguagesupport.h M +1 -0 parsejob.cpp --- trunk/playground/devtools/kdevelop4-extra-plugins/java/duchain/expressionvisitor.cpp #1057397:1057398 @@ -378,10 +378,25 @@ DeclarationPointer useDecl; AstNode* useNode = 0; - if (lastInstance().isInstance) { + if (lastInstance().declaration) { if (node->methodName) { QualifiedIdentifier id = identifierForNode(node->methodName); - + DUContextPointer searchContext; + { + DUChainReadLocker lock(DUChain::lock()); + StructureType::Ptr classType = lastInstance().declaration->type(); + if (!classType) { + kDebug() << "Type of last instance " << lastInstance().declaration->toString() << "was not a structure."; + return; + } + searchContext = classType->internalContext(currentContext()->topContext()); + if (!searchContext) { + kDebug() << "could not find internal context for the structure type of the class to be searched"; + return; + } + kDebug() << "Looking for function" << id << "in" << searchContext->scopeIdentifier(true); + } + QList parameters; if (node->arguments && node->arguments->expressionSequence) @@ -391,7 +406,10 @@ { visitNode(__it->element); // TODO determine l-value-ness if required - parameters.append(OverloadResolver::Parameter(lastType(), false)); + if (lastType()) { + kDebug() << "Parameter" << lastType()->toString(); + parameters.append(OverloadResolver::Parameter(lastType(), false)); + } __it = __it->next; } @@ -400,18 +418,20 @@ DUChainReadLocker lock(DUChain::lock()); - KDevelop::DUContextPointer currentContextPtr(currentContext()); - OverloadResolver resolver(currentContextPtr); + OverloadResolver resolver(searchContext); + //kDebug() << "Parameter count:" << parameters.count(); useDecl = resolver.resolve(OverloadResolver::ParameterList(parameters), id); if (useDecl) useNode = node->methodName; + + kDebug() << "result" << (useDecl ? useDecl->toString() : "null declaration") << useNode; } if (useNode) usingDeclaration(useNode, useDecl); } else { - kDebug() << "No instance on which to invoke a method"; + kDebug() << "No declaration for the last instance on which to invoke a method"; } } @@ -574,6 +594,9 @@ } } + if (node->methodCall) + visitNode(node->methodCall); + if (useNode) usingDeclaration(useNode, useDecl); } --- trunk/playground/devtools/kdevelop4-extra-plugins/java/duchain/typebuilder.cpp #1057397:1057398 @@ -82,6 +82,16 @@ closeType(); } + +void TypeBuilder::visitParameterDeclarationEllipsis(ParameterDeclarationEllipsisAst* node) +{ + TypeBuilderBase::visitParameterDeclarationEllipsis(node); + + if (hasCurrentType()) + if (FunctionType::Ptr function = currentType()) + function->addArgument(lastType()); +} + void TypeBuilder::visitInterfaceMethodDeclaration(InterfaceMethodDeclarationAst * node) { clearLastType(); --- trunk/playground/devtools/kdevelop4-extra-plugins/java/duchain/typebuilder.h #1057397:1057398 @@ -55,6 +55,7 @@ virtual void visitEnumConstant(EnumConstantAst* node); virtual void visitMethodDeclaration(MethodDeclarationAst *node); + virtual void visitParameterDeclarationEllipsis(ParameterDeclarationEllipsisAst* node); virtual void visitInterfaceMethodDeclaration(InterfaceMethodDeclarationAst * node); virtual void visitConstructorDeclaration(ConstructorDeclarationAst *node); virtual void visitInterfaceDeclaration(InterfaceDeclarationAst *node); --- trunk/playground/devtools/kdevelop4-extra-plugins/java/duchain/viablefunctions.cpp #1057397:1057398 @@ -60,10 +60,14 @@ uint functionArgumentCount = m_type->indexedArgumentsSize(); - if( params.parameters.size() + m_funDecl->defaultParametersSize() < functionArgumentCount && !partial ) + if( params.parameters.size() + m_funDecl->defaultParametersSize() < functionArgumentCount && !partial ) { + //kDebug() << "Not enough parameters + default-parameters"; return; //Not enough parameters + default-parameters - if( params.parameters.size() > functionArgumentCount ) + } + if( params.parameters.size() > functionArgumentCount ) { + //kDebug() << "Too many parameters" << params.parameters.size() << "gt" << functionArgumentCount; return; //Too many parameters + } m_parameterCountMismatch = false; //Match all parameters against the argument-type --- trunk/playground/devtools/kdevelop4-extra-plugins/java/javalanguagesupport.cpp #1057397:1057398 @@ -69,6 +69,7 @@ : KDevelop::IPlugin( KDevJavaSupportFactory::componentData(), parent ) , KDevelop::ILanguageSupport() , m_allJavaContext(0) + , m_javaSourceZipMutex(new QMutex()) , m_javaSourceZip(0) { s_self = this; @@ -166,6 +167,12 @@ return m_javaSourceZip; } + +QMutex* JavaLanguageSupport::javaSourceZipMutex() const +{ + return m_javaSourceZipMutex; +} + KDevelop::ReferencedTopDUContext JavaLanguageSupport::allJavaContext() { if (m_allJavaContext) --- trunk/playground/devtools/kdevelop4-extra-plugins/java/javalanguagesupport.h #1057397:1057398 @@ -64,6 +64,7 @@ static JavaLanguageSupport* self(); + QMutex* javaSourceZipMutex() const; KZip* javaSourceZip() const; private Q_SLOTS: @@ -75,7 +76,9 @@ KDevelop::CodeHighlighting* m_highlighting; KDevelop::ReferencedTopDUContext m_allJavaContext; KUrl m_javaSourceUrl; + QMutex* m_javaSourceZipMutex; mutable KZip* m_javaSourceZip; + static JavaLanguageSupport* s_self; }; --- trunk/playground/devtools/kdevelop4-extra-plugins/java/parsejob.cpp #1057397:1057398 @@ -149,6 +149,7 @@ int offset = filePath.indexOf(".zip"); // TODO - add logic to detect if we should create a new zip object (non-jdk-source-zip) or not + QMutexLocker lock(java()->javaSourceZipMutex()); KZip* zip = java()->javaSourceZip(); if(zip)//->open(QIODevice::ReadOnly)) {