Вход Регистрация
Файл: gapps/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php
Строк: 308
<?php

namespace PhpParserNodeVisitor;

use 
PhpParser;
use 
PhpParserNode;
use 
PhpParserNodeName;
use 
PhpParserNodeStmt;
use 
PhpParserNodeExpr;

class 
NameResolverTest extends PHPUnit_Framework_TestCase
{
    private function 
canonicalize($string) {
        return 
str_replace("rn""n"$string);
    }

    
/**
     * @covers PhpParserNodeVisitorNameResolver
     */
    
public function testResolveNames() {
        
$code = <<<'EOC'
<?php

namespace Foo {
    use Hallo as Hi;

    new Bar();
    new Hi();
    new HiBar();
    new Bar();
    new namespaceBar();

    bar();
    hi();
    Hibar();
    foobar();
    bar();
    namespacebar();
}
namespace {
    use Hallo as Hi;

    new Bar();
    new Hi();
    new HiBar();
    new Bar();
    new namespaceBar();

    bar();
    hi();
    Hibar();
    foobar();
    bar();
    namespacebar();
}
namespace Bar {
    use function foobar as baz;
    use const fooBAR as BAZ;
    use foo as bar;

    bar();
    baz();
    barfoo();
    bazfoo();
    BAR();
    BAZ();
    BARFOO();
    BAZFOO();

    bar;
    baz;
    barfoo;
    bazfoo;
    BAR;
    BAZ;
    BARFOO;
    BAZFOO;
}
namespace Baz {
    use AT{BC, DE};
    use function XT{bc, de};
    use const YT{BC, DE};
    use ZT{G, function f, const K};

    new C;
    new E;
    new CD;
    new EF;
    new G;

    c();
    e();
    f();
    C;
    E;
    K;
}
EOC;
        
$expectedCode = <<<'EOC'
namespace Foo {
    use Hallo as Hi;
    new FooBar();
    new Hallo();
    new HalloBar();
    new Bar();
    new FooBar();
    bar();
    hi();
    Hallobar();
    Foofoobar();
    bar();
    Foobar();
}
namespace {
    use Hallo as Hi;
    new Bar();
    new Hallo();
    new HalloBar();
    new Bar();
    new Bar();
    bar();
    hi();
    Hallobar();
    foobar();
    bar();
    bar();
}
namespace Bar {
    use function foobar as baz;
    use const fooBAR as BAZ;
    use foo as bar;
    bar();
    foobar();
    foofoo();
    Barbazfoo();
    BAR();
    foobar();
    fooFOO();
    BarBAZFOO();
    bar;
    baz;
    foofoo;
    Barbazfoo;
    BAR;
    fooBAR;
    fooFOO;
    BarBAZFOO;
}
namespace Baz {
    use AT{BC, DE};
    use function XT{bc, de};
    use const YT{BC, DE};
    use ZT{G, function f, const K};
    new ATBC();
    new ATDE();
    new ATBCD();
    new ATDEF();
    new ZTG();
    XTbc();
    XTde();
    ZTf();
    YTBC;
    YTDE;
    ZTK;
}
EOC;

        
$parser        = new PhpParserParserPhp7(new PhpParserLexerEmulative);
        
$prettyPrinter = new PhpParserPrettyPrinterStandard;
        
$traverser     = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$stmts $parser->parse($code);
        
$stmts $traverser->traverse($stmts);

        
$this->assertSame(
            
$this->canonicalize($expectedCode),
            
$prettyPrinter->prettyPrint($stmts)
        );
    }

    
/**
     * @covers PhpParserNodeVisitorNameResolver
     */
    
public function testResolveLocations() {
        
$code = <<<'EOC'
<?php
namespace NS;

class A extends B implements C, D {
    use E, F, G {
        f as private g;
        E::h as i;
        E::j insteadof F, G;
    }
}

interface A extends C, D {
    public function a(A $a) : A;
}

function fn() : A {}
function fn2() : array {}
function() : A {};

A::b();
A::$b;
A::B;
new A;
$a instanceof A;

namespacea();
namespaceA;

try {
    $someThing;
} catch (A $a) {
    $someThingElse;
}
EOC;
        
$expectedCode = <<<'EOC'
namespace NS;

class A extends NSB implements NSC, NSD
{
    use NSE, NSF, NSG {
        f as private g;
        NSE::h as i;
        NSE::j insteadof NSF, NSG;
    }
}
interface A extends NSC, NSD
{
    public function a(NSA $a) : NSA;
}
function fn() : NSA
{
}
function fn2() : array
{
}
function () : NSA {
};
NSA::b();
NSA::$b;
NSA::B;
new NSA();
$a instanceof NSA;
NSa();
NSA;
try {
    $someThing;
} catch (NSA $a) {
    $someThingElse;
}
EOC;

        
$parser        = new PhpParserParserPhp7(new PhpParserLexerEmulative);
        
$prettyPrinter = new PhpParserPrettyPrinterStandard;
        
$traverser     = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$stmts $parser->parse($code);
        
$stmts $traverser->traverse($stmts);

        
$this->assertSame(
            
$this->canonicalize($expectedCode),
            
$prettyPrinter->prettyPrint($stmts)
        );
    }

    public function 
testNoResolveSpecialName() {
        
$stmts = array(new NodeExprNew_(new Name('self')));

        
$traverser = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$this->assertEquals($stmts$traverser->traverse($stmts));
    }

    public function 
testAddNamespacedName() {
        
$nsStmts = array(
            new 
StmtClass_('A'),
            new 
StmtInterface_('B'),
            new 
StmtFunction_('C'),
            new 
StmtConst_(array(
                new 
NodeConst_('D', new NodeScalarLNumber(42))
            )),
            new 
StmtTrait_('E'),
            new 
ExprNew_(new StmtClass_(null)),
        );

        
$traverser = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$stmts $traverser->traverse([new StmtNamespace_(new Name('NS'), $nsStmts)]);
        
$this->assertSame('NS\A', (string) $stmts[0]->stmts[0]->namespacedName);
        
$this->assertSame('NS\B', (string) $stmts[0]->stmts[1]->namespacedName);
        
$this->assertSame('NS\C', (string) $stmts[0]->stmts[2]->namespacedName);
        
$this->assertSame('NS\D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName);
        
$this->assertSame('NS\E', (string) $stmts[0]->stmts[4]->namespacedName);
        
$this->assertObjectNotHasAttribute('namespacedName'$stmts[0]->stmts[5]->class);

        
$stmts $traverser->traverse([new StmtNamespace_(null$nsStmts)]);
        
$this->assertSame('A',     (string) $stmts[0]->stmts[0]->namespacedName);
        
$this->assertSame('B',     (string) $stmts[0]->stmts[1]->namespacedName);
        
$this->assertSame('C',     (string) $stmts[0]->stmts[2]->namespacedName);
        
$this->assertSame('D',     (string) $stmts[0]->stmts[3]->consts[0]->namespacedName);
        
$this->assertSame('E',     (string) $stmts[0]->stmts[4]->namespacedName);
        
$this->assertObjectNotHasAttribute('namespacedName'$stmts[0]->stmts[5]->class);
    }

    
/**
     * @dataProvider provideTestError
     */
    
public function testError(Node $stmt$errorMsg) {
        
$this->setExpectedException('PhpParserError'$errorMsg);

        
$traverser = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);
        
$traverser->traverse(array($stmt));
    }

    public function 
provideTestError() {
        return array(
            array(
                new 
StmtUse_(array(
                    new 
StmtUseUse(new Name('AB'), 'B'0, array('startLine' => 1)),
                    new 
StmtUseUse(new Name('CD'), 'B'0, array('startLine' => 2)),
                ), 
StmtUse_::TYPE_NORMAL),
                
'Cannot use CD as B because the name is already in use on line 2'
            
),
            array(
                new 
StmtUse_(array(
                    new 
StmtUseUse(new Name('ab'), 'b'0, array('startLine' => 1)),
                    new 
StmtUseUse(new Name('cd'), 'B'0, array('startLine' => 2)),
                ), 
StmtUse_::TYPE_FUNCTION),
                
'Cannot use function cd as B because the name is already in use on line 2'
            
),
            array(
                new 
StmtUse_(array(
                    new 
StmtUseUse(new Name('AB'), 'B'0, array('startLine' => 1)),
                    new 
StmtUseUse(new Name('CD'), 'B'0, array('startLine' => 2)),
                ), 
StmtUse_::TYPE_CONSTANT),
                
'Cannot use const CD as B because the name is already in use on line 2'
            
),
            array(
                new 
ExprNew_(new NameFullyQualified('self', array('startLine' => 3))),
                
"'\self' is an invalid class name on line 3"
            
),
            array(
                new 
ExprNew_(new NameRelative('self', array('startLine' => 3))),
                
"'\self' is an invalid class name on line 3"
            
),
            array(
                new 
ExprNew_(new NameFullyQualified('PARENT', array('startLine' => 3))),
                
"'\PARENT' is an invalid class name on line 3"
            
),
            array(
                new 
ExprNew_(new NameRelative('STATIC', array('startLine' => 3))),
                
"'\STATIC' is an invalid class name on line 3"
            
),
        );
    }

    public function 
testClassNameIsCaseInsensitive()
    {
        
$source = <<<'EOC'
<?php
namespace Foo;
use BarBaz;
$test = new baz();
EOC;

        
$parser = new PhpParserParserPhp7(new PhpParserLexerEmulative);
        
$stmts $parser->parse($source);

        
$traverser = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$stmts $traverser->traverse($stmts);
        
$stmt $stmts[0];

        
$this->assertSame(array('Bar''Baz'), $stmt->stmts[1]->expr->class->parts);
    }

    public function 
testSpecialClassNamesAreCaseInsensitive() {
        
$source = <<<'EOC'
<?php
namespace Foo;

class Bar
{
    public static function method()
    {
        SELF::method();
        PARENT::method();
        STATIC::method();
    }
}
EOC;

        
$parser = new PhpParserParserPhp7(new PhpParserLexerEmulative);
        
$stmts $parser->parse($source);

        
$traverser = new PhpParserNodeTraverser;
        
$traverser->addVisitor(new NameResolver);

        
$stmts $traverser->traverse($stmts);
        
$classStmt $stmts[0];
        
$methodStmt $classStmt->stmts[0]->stmts[0];

        
$this->assertSame('SELF', (string)$methodStmt->stmts[0]->class);
        
$this->assertSame('PARENT', (string)$methodStmt->stmts[1]->class);
        
$this->assertSame('STATIC', (string)$methodStmt->stmts[2]->class);
    }
}
Онлайн: 1
Реклама