~ubuntu-branches/ubuntu/utopic/kdevelop-php/utopic

« back to all changes in this revision

Viewing changes to duchain/builders/declarationbuilder.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2010-03-14 10:19:34 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100314101934-d24i8t1niai087ul
Tags: 1.0.0~beta4-1
New upstream release. (Closes: #573811)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <language/duchain/stringhelpers.h>
30
30
#include <language/duchain/aliasdeclaration.h>
31
31
#include <language/duchain/types/integraltype.h>
 
32
#include <language/duchain/types/unsuretype.h>
32
33
 
33
34
#include <interfaces/icore.h>
34
35
#include <interfaces/ilanguagecontroller.h>
515
516
 
516
517
void DeclarationBuilder::visitParameter(ParameterAst *node)
517
518
{
 
519
    AbstractFunctionDeclaration* funDec = dynamic_cast<AbstractFunctionDeclaration*>(currentDeclaration());
 
520
    Q_ASSERT(funDec);
518
521
    if (node->defaultValue) {
519
 
        AbstractFunctionDeclaration* funDec = dynamic_cast<AbstractFunctionDeclaration*>(currentDeclaration());
520
 
        if (funDec) {
521
 
            funDec->addDefaultParameter(IndexedString(editor()->parseSession()->symbol(node->defaultValue)));
 
522
        QString symbol = editor()->parseSession()->symbol(node->defaultValue);
 
523
        funDec->addDefaultParameter(IndexedString(symbol));
 
524
        if ( node->parameterType && symbol.compare(QLatin1String("null"), Qt::CaseInsensitive) != 0 ) {
 
525
            reportError(i18n("Default value for parameters with a class type hint can only be NULL."), node->defaultValue);
522
526
        }
 
527
    } else if ( !node->defaultValue && funDec->defaultParametersSize() ) {
 
528
        reportError(i18n("Following parameters must have a default value assigned."), node);
523
529
    }
524
530
    {
 
531
        // create variable declaration for argument
525
532
        DUChainWriteLocker lock(DUChain::lock());
526
533
        SimpleRange newRange = editorFindRange(node->variable, node->variable);
527
 
        openDefinition<Declaration>(identifierForNode(node->variable), newRange);
 
534
        openDefinition<VariableDeclaration>(identifierForNode(node->variable), newRange);
528
535
        currentDeclaration()->setKind(Declaration::Instance);
529
536
    }
530
537
 
653
660
    DUChainWriteLocker lock(DUChain::lock());
654
661
    // check if this variable is already declared
655
662
    {
656
 
        QList< Declaration* > decs = parentCtx->findLocalDeclarations(identifier.first(), startPos(node));
 
663
        QList< Declaration* > decs = parentCtx->findDeclarations(identifier.first(), startPos(node));
657
664
        if ( !decs.isEmpty() ) {
658
665
            QList< Declaration* >::const_iterator it = decs.constEnd() - 1;
659
666
            while ( true ) {
660
667
                // we expect that the list of declarations has the newest declaration at back
661
668
                if ( dynamic_cast<VariableDeclaration*>( *it ) ) {
662
 
                    if ( (*it)->abstractType()->indexed() == type->indexed() ) {
663
 
                        encounter(*it);
664
 
                        return;
 
669
                    encounter(*it);
 
670
                    if ( (*it)->abstractType() && !(*it)->abstractType()->equals(type.unsafeData()) ) {
 
671
                        // if it's currently mixed and we now get something more definite, use that instead
 
672
                        if ( ReferenceType::Ptr rType = ReferenceType::Ptr::dynamicCast((*it)->abstractType()) ) {
 
673
                            if ( IntegralType::Ptr integral = IntegralType::Ptr::dynamicCast(rType->baseType()) ) {
 
674
                                if ( integral->dataType() == IntegralType::TypeMixed ) {
 
675
                                    // referenced mixed to referenced @p type
 
676
                                    ReferenceType::Ptr newType(new ReferenceType());
 
677
                                    newType->setBaseType(type);
 
678
                                    (*it)->setType(newType);
 
679
                                    return;
 
680
                                }
 
681
                            }
 
682
                        }
 
683
                        if ( IntegralType::Ptr integral = IntegralType::Ptr::dynamicCast((*it)->abstractType()) ) {
 
684
                            if ( integral->dataType() == IntegralType::TypeMixed ) {
 
685
                                // mixed to @p type
 
686
                                (*it)->setType(type);
 
687
                                return;
 
688
                            }
 
689
                        }
 
690
                        // else make it unsure
 
691
                        UnsureType::Ptr unsure = UnsureType::Ptr::dynamicCast((*it)->abstractType());
 
692
                        // maybe it's referenced?
 
693
                        ReferenceType::Ptr rType = ReferenceType::Ptr::dynamicCast((*it)->abstractType());
 
694
                        if ( !unsure && rType ) {
 
695
                            unsure = UnsureType::Ptr::dynamicCast(rType->baseType());
 
696
                        }
 
697
                        if ( !unsure ) {
 
698
                            unsure = UnsureType::Ptr(new UnsureType());
 
699
                            if ( rType ) {
 
700
                                unsure->addType(rType->baseType()->indexed());
 
701
                            } else {
 
702
                                unsure->addType((*it)->indexedType());
 
703
                            }
 
704
                        }
 
705
                        unsure->addType(type->indexed());
 
706
                        if ( rType ) {
 
707
                            rType->setBaseType(AbstractType::Ptr(unsure.unsafeData()));
 
708
                            (*it)->setType(rType);
 
709
                        } else {
 
710
                            (*it)->setType(unsure);
 
711
                        }
665
712
                    }
666
 
                    break;
 
713
                    return;
667
714
                }
668
715
                if ( it == decs.constBegin() ) {
669
716
                    break;
1049
1096
    // when we are recompiling, it's important to mark decs as encountered
1050
1097
    // and update their comments
1051
1098
    if ( recompiling() && !wasEncountered(dec) ) {
1052
 
        kDebug() << "old:" << dec->comment();
1053
1099
        dec->setComment(comment());
1054
1100
        setEncountered(dec);
1055
 
        kDebug() << "new:" << dec->comment();
1056
1101
    }
1057
1102
}
1058
1103