/******************************************************************************* * Copyright (c) 2009,2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Zend Technologies * Dawid PakuĊ‚a - convert to JUnit4 *******************************************************************************/ package org.eclipse.php.core.tests.dom_ast.rewrite; import static org.junit.Assert.assertTrue; import java.util.List; import org.eclipse.dltk.ast.Modifiers; import org.eclipse.php.core.PHPVersion; import org.eclipse.php.core.ast.nodes.ArrayElement; import org.eclipse.php.core.ast.nodes.ClassDeclaration; import org.eclipse.php.core.ast.nodes.FieldsDeclaration; import org.eclipse.php.core.ast.nodes.FunctionDeclaration; import org.eclipse.php.core.ast.nodes.FunctionInvocation; import org.eclipse.php.core.ast.nodes.InterfaceDeclaration; import org.eclipse.php.core.ast.nodes.LambdaFunctionDeclaration; import org.eclipse.php.core.ast.nodes.MethodDeclaration; import org.eclipse.php.core.ast.nodes.NamespaceName; import org.eclipse.php.core.ast.nodes.Scalar; import org.eclipse.php.core.ast.nodes.StaticConstantAccess; import org.eclipse.php.core.ast.nodes.TraitAliasStatement; import org.eclipse.php.core.ast.nodes.TraitDeclaration; import org.eclipse.php.core.ast.nodes.TraitPrecedenceStatement; import org.eclipse.php.core.ast.nodes.TraitUseStatement; import org.eclipse.php.core.ast.nodes.Variable; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite.SuiteClasses; /** * AST rewrite test which tests the ASTRewriteAnalyzer implementation. * * @author shalom */ public class ASTRewriteTestsPHP54 extends ASTRewriteTests { @RunWith(org.junit.runners.Suite.class) @SuiteClasses({ ASTRewriteTestsPHP54.class, NodeDeletionTests.class, ASTRewriteTestsPHP54.class }) public static class Suite { } @Override protected PHPVersion getPHPVersion() { return PHPVersion.PHP5_4; } @Test public void classConstant() throws Exception { String str = "<?php $a = MyClass::MY_CONST; ?>"; initialize(str); List<StaticConstantAccess> staticConstants = getAllOfType(program, StaticConstantAccess.class); assertTrue("Unexpected list size.", staticConstants.size() == 1); ((NamespaceName) staticConstants.get(0).getClassName()).segments().get(0).setName("Foo"); staticConstants.get(0).setConstant(ast.newIdentifier("BAR_CONST")); rewrite(); checkResult("<?php $a = Foo::BAR_CONST; ?>"); } @Test public void classDeclarationReplaceSuper() throws Exception { String str = "<?php class MyClass extends Foo { } ?> "; initialize(str); List<ClassDeclaration> declarations = getAllOfType(program, ClassDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); ((NamespaceName) declarations.get(0).getSuperClass()).segments().get(0).setName("Bar"); rewrite(); checkResult("<?php class MyClass extends Bar { } ?> "); } @Test public void classDeclarationRenameInterface() throws Exception { String str = "<?php class MyClass extends AAA implements Foo,Bar{ } ?> "; initialize(str); List<ClassDeclaration> declarations = getAllOfType(program, ClassDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); ((NamespaceName) declarations.get(0).interfaces().get(1)).segments().get(0).setName("BooBo"); rewrite(); checkResult("<?php class MyClass extends AAA implements Foo,BooBo{ } ?> "); } @Test public void interfaceDeclarationRenameExtend() throws Exception { String str = "<?php interface MyInterface extends Foo, Bar{ const MY_CONSTANT = 3; public function myFunction($a); } ?> "; initialize(str); List<InterfaceDeclaration> declarations = getAllOfType(program, InterfaceDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); ((NamespaceName) declarations.get(0).interfaces().get(0)).segments().get(0).setName("Boobo"); rewrite(); checkResult( "<?php interface MyInterface extends Boobo, Bar{ const MY_CONSTANT = 3; public function myFunction($a); } ?> "); } // FIXME should fix this case,the scalar's end is wrong! // @Test public void emptyHeredoc() throws Exception { // String str = "<?php <<<Heredoc\nabc\nefg\nHeredoc;\n?>"; // initialize(str); // // List<Quote> quotes = getAllOfType(program, Quote.class); // assertTrue("Unexpected list size.", quotes.size() == 1); // quotes.get(0).expressions().clear(); // quotes.get(0).expressions().add(ast.newScalar("Hello World\n")); // rewrite(); // checkResult("<?php <<<Heredoc\nHello World\nefg\nHeredoc;\n?>"); // } @Test public void emptyHeredoc() throws Exception { String str = "<?php <<<Heredoc\nHeredoc;\n?>"; initialize(str); checkResult("<?php <<<Heredoc\nHeredoc;\n?>"); } @Test public void traitDeclarationSimple() throws Exception { String str = "<?php trait MyTrait { } ?> "; initialize(str); List<TraitDeclaration> declarations = getAllOfType(program, TraitDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); declarations.get(0).setName(ast.newIdentifier("Foo")); rewrite(); checkResult("<?php trait Foo { } ?> "); } @Test public void traitFieldDeclaration() throws Exception { String str = "<?php trait A { public $a = 3; final private static $var; }?>"; initialize(str); List<FieldsDeclaration> declarations = getAllOfType(program, FieldsDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 2); declarations.get(0).fields().add(ast.newSingleFieldDeclaration(ast.newVariable("b"), ast.newScalar("4"))); declarations.get(0).fields().get(0).getValue().delete(); declarations.get(1).setModifier(Modifiers.AccProtected | Modifiers.AccFinal); rewrite(); checkResult("<?php trait A { public $a, $b = 4; protected final $var; }?>"); } @Test public void traitFunctionDeclaration() throws Exception { String str = "<?php function foo() {} ?> "; initialize(str); List<FunctionDeclaration> declarations = getAllOfType(program, FunctionDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); declarations.get(0).setFunctionName(ast.newIdentifier("bar")); declarations.get(0).formalParameters() .add(ast.newFormalParameter(ast.newIdentifier("int"), ast.newVariable("a"), null, false)); rewrite(); checkResult("<?php function bar(int $a) {} ?> "); } @Test public void functionDeclarationWithCallableParam2() throws Exception { String str = "<?php function foo($a, callable $b) {} ?> "; initialize(str); List<FunctionDeclaration> declarations = getAllOfType(program, FunctionDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); declarations.get(0).formalParameters().get(1).setParameterType(ast.newIdentifier("string")); rewrite(); checkResult("<?php function foo($a, string $b) {} ?> "); } @Test public void traitMethodDeclaration() throws Exception { String str = "<?php trait A { public function foo(int $a){} }?> "; initialize(str); List<MethodDeclaration> declarations = getAllOfType(program, MethodDeclaration.class); assertTrue("Unexpected list size.", declarations.size() == 1); declarations.get(0).setModifier(Modifiers.AccProtected | Modifiers.AccAbstract); declarations.get(0).getFunction().setFunctionName(ast.newIdentifier("bar")); rewrite(); checkResult("<?php trait A { protected abstract function bar(int $a){} }?> "); } @Test public void arrayInitializer() throws Exception { String str = "<?php $f = [new Human('Gonzalo'), 'hello']; ?>"; initialize(str); List<ArrayElement> arrayAccess = getAllOfType(program, ArrayElement.class); assertTrue("Unexpected list size.", arrayAccess.size() == 2); ((Scalar) arrayAccess.get(1).getValue()).setStringValue("'world'"); rewrite(); checkResult("<?php $f = [new Human('Gonzalo'), 'world']; ?>"); } @Test public void classInitializer() throws Exception { String str = "<?php (new Human('Gonzalo'))->hello(); ?>"; initialize(str); List<FunctionInvocation> arrayAccess = getAllOfType(program, FunctionInvocation.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); Variable name = ast.newVariable("world"); name.setIsDollared(false); ((FunctionInvocation) arrayAccess.get(0)).getFunctionName().setName(name); rewrite(); checkResult("<?php (new Human('Gonzalo'))->world(); ?>"); } @Test public void expresionFunctionInvocation() throws Exception { String str = "<?php $human->{'hello'}(); ?>"; initialize(str); List<FunctionInvocation> arrayAccess = getAllOfType(program, FunctionInvocation.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); ((Variable) arrayAccess.get(0).getFunctionName().getName()).setName(ast.newScalar("'world'")); rewrite(); checkResult("<?php $human->{'world'}(); ?>"); } @Test public void staticLambdaFunction() throws Exception { String str = "<?php $lambda = static function () { }; ?>"; initialize(str); List<LambdaFunctionDeclaration> arrayAccess = getAllOfType(program, LambdaFunctionDeclaration.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); } @Test public void useTrait1() throws Exception { String str = "<?php class Test { use Hello, World; } ?>"; initialize(str); List<TraitUseStatement> arrayAccess = getAllOfType(program, TraitUseStatement.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); arrayAccess.get(0).getTraitList().get(0).segments().get(0).setName("Hi"); rewrite(); checkResult("<?php class Test { use Hi, World; } ?>"); } @Test public void useTrait2() throws Exception { String str = "<?php class Aliased_Talker { use A, B {B::smallTalk insteadof A;\nA::bigTalk insteadof B;\nB::bigTalk as talk;\n}\n } ?>"; initialize(str); List<TraitPrecedenceStatement> arrayAccess = getAllOfType(program, TraitPrecedenceStatement.class); assertTrue("Unexpected list size.", arrayAccess.size() == 2); arrayAccess.get(0).getPrecedence().getMethodReference().getClassName().segments().get(0).setName("B1"); arrayAccess.get(0).getPrecedence().getMethodReference().setFunctionName(ast.newIdentifier("bigTalk")); List<TraitAliasStatement> aliasStatement = getAllOfType(program, TraitAliasStatement.class); assertTrue("Unexpected list size.", aliasStatement.size() == 1); aliasStatement.get(0).getAlias().setFunctionName(ast.newIdentifier("talking")); rewrite(); checkResult( "<?php class Aliased_Talker { use A, B {B1::bigTalk insteadof A;\nA::bigTalk insteadof B;\nB::bigTalk as talking;\n}\n } ?>"); } @Test public void useTrait3() throws Exception { String str = "<?php class Test { use HelloWorld { sayHello as protected; } } ?>"; initialize(str); List<TraitAliasStatement> arrayAccess = getAllOfType(program, TraitAliasStatement.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); arrayAccess.get(0).getAlias().setModifier(Modifiers.AccPublic); rewrite(); checkResult("<?php class Test { use HelloWorld { sayHello as public; } } ?>"); } @Test public void useTrait4() throws Exception { String str = "<?php class Test { use HelloWorld { sayHello as private myPrivateHello; } } ?>"; initialize(str); List<TraitAliasStatement> arrayAccess = getAllOfType(program, TraitAliasStatement.class); assertTrue("Unexpected list size.", arrayAccess.size() == 1); arrayAccess.get(0).getAlias().setModifier(Modifiers.AccPublic); arrayAccess.get(0).getAlias().setFunctionName(ast.newIdentifier("myPublicHello")); rewrite(); checkResult("<?php class Test { use HelloWorld { sayHello as public myPublicHello; } } ?>"); } }