<?php
/**
* Comment
*/
use Foo\{function bar, const BAZ};

use /* comment */ function bar\math\{
    Msin,
    level\Mcos as BarCos,
    Mcosh,
};

include $blah;


/**
* Comment
*/


/**
* Comment
*/
function foo()
{
}//end foo()

function func1() {

}//end func1()


function func2() {

}//end func2()

function func3() {

}//end func3()


class MyClass
{
    function func1() {

    }//end func1()


    function func2() {

    }//end func2()

    function func3() {

    }//end func3()
}//end class


interface MyInterface
{
    function func1();


    function func2();

    function func3();
}//end interface


class MyClass
{


    function func1() {

    }//end func1()


    function func2() {

    }//end func2()



    function func3() {

    }//end func3()


}//end class


interface MyInterface
{


    function func1();


    function func2();



    function func3();


}//end interface

class MyClass
{
    function func1() {

    }//end func1()
}//end class


interface MyInterface
{
    function func1();
}//end interface


class MyClass
{

    /**
     * The tag that this element represents (omitting the @ symbol).
     *
     * @var string
     */
    protected $tag = '';


    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {

    }//end func1()

    /**
     * Function comment.
     *
     * @return boolean
     */
    function func2() {

    }//end func2()


    /**
     * Function comment.
     *
     * @return boolean
     */
    function func3() {

    }//end func3()

}//end class


interface MyInterface
{

    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1();



    /**
     * Function comment.
     *
     * @return boolean
     */
    function func2();


    /**
     * Function comment.
     *
     * @return boolean
     */
    function func3();

}//end interface

class MyClass
{

    protected $tag = '';

    protected $tag = '';


    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {

    }//end func1()


}//end class

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 1

interface MyInterface
{

    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1();


    /**
     * Function comment.
     *
     * @return boolean
     */
    function func2();

    /**
     * Function comment.
     *
     * @return boolean
     */
    function func3();


}//end interface

class MyClass
{

    protected $tag = '';

    protected $tag = '';

    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {

    }//end func1()


}//end class

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 2

// Closures should be ignored.
preg_replace_callback(
    '~-([a-z])~',
    function ($match) {
        return strtoupper($match[1]);
    },
    'hello-world'
);

$callback = function ($bar) use ($foo)
            {
                $bar += $foo;
            };

class MyClass
{
    function func1() {
    }
}


function test() {

}//end test()


if ($foo) {
    /**
     * Comment
     */
    function foo() {
        // Code here
    }
    /**
     * Comment
     */
    function bar() {
        // Code here
    }
}

// foo
function foo() {
}


// phpcs:disable Standard.Category.Sniff -- for reasons.
function bar() {
}


// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 0
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 0
class MyClass
{
    protected $tag = '';

    /**
     * Function comment.
     *
     * @return boolean
     */
    private static function func1() {

    }//end func1()

    /**
     * Function comment.
     *
     * @return boolean
     */
    private static function func2() {

    }//end func1()


}//end class

class MyClass {
    function a(){}
    function b(){}
    function c(){}
}

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 1
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 1
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 1

class MyClass {
    function a(){}
    function b(){}
    function c(){}
}

$util->setLogger(new class {
    public function a(){}
    private function b(){}
    protected function c(){}
});

?>

<?php
function functionInEmbeddedPHP() {

}

// Make sure the indentation for the function comment does not get removed.
class MyClass
{

    protected $tag = '';



    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {}

}//end class

class MyClass
{



    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {}

}//end class

class MyClass
{
    // Unrelated comment.
    /**
     * Function comment.
     *
     * @return boolean
     */
    function func1() {}
    // phpcs:disable Standard.Category.Sniff -- for reasons.
    /**
     * Function comment.
     *
     * @return boolean
     */
    function func2() {}
}//end class

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 2

echo 'just some code to let the below line test blank lines before';
echo 'something'; function testingFunctionNotOnOwnLine() {} echo 'somethingelse';
echo 'just some code to let the above line test blank lines after';

trait MyTrait {


    public function a(){}




    public function b(){}
    public function c(){}
}

$anon_class = new class() {
    public function a(){}

    protected function b(){}




    private function c(){}

};

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 1
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 3

class MyClass {
    function a(){}
    function b(){}
    function c(){}
}

$bar = function () {
    {
        function a(){}
        function b(){}
        function c(){}
    }
};
class Foo {
    public function returnAnonymousClass() {
        return new class() {
            public function baz() {}
        };
    }

    public function bar() {
        function forbidden() {}
    }
}

if (function_exists('foo') === false) {
    function foo(){}
}

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 0
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 0
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 0

interface OneBlankLineBeforeFirstFunctionClassInterface
{


    /** @return mixed */
    public function interfaceMethod();
}

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 1
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 0
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 0

class MyClass {

    // phpcs:disable Stnd.Cat.Sniff -- For reasons.

    /**
     * Description.
     */
    function a(){}

    /**
     * Description.
     */
    function b(){}

    /**
     * Description.
     */
    function c(){}

    // phpcs:enable
}

class MyClass {
    // Some unrelated comment
    /**
     * Description.
     */
    function a(){}

    /**
     * Description.
     */
    function b(){}

    /**
     * Description.
     */
    function c(){}
    // function d() {}
}

class ClassWithAttributes {

    #[Attribute1]
    #[Attribute2]
    function a(){}


    #[Attribute3]
    function b(){}
    #[Attribute4]
    function c(){}


    /**
     * Description.
     */
    #[Attribute5]
    function d(){}
    /**
     * Description.
     */
    #[Attribute6]
    #[Attribute7]
    function e(){}


    #[Attribute8]
    #[Attribute9]
    function f(){}
}

// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacing 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 2

// Issue #3904.
echo 'this line belongs with the #3904 test';
class Person {public function __construct($name){}}
echo 'this line belongs with the #3904 test';

function Foo() {} function bar($name){}
echo 'this line belongs with the #3904 test';


/**
 * foo.
 */
function a() {
}/**
 * foo.
 */
function b() {
}


// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 1
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 0

class DocblockFollowedByAttributesCorrectSpacing {

    /**
     * No error.
     */
    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    function FirstFunction()
    {
        // Code
    }
}

class DocblockFollowedByAttributesTooMuchSpacing {



    /**
     * Docblock.
     */
    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    function FirstFunction()
    {
        // Code
    }
}

class DocblockFollowedByAttributesTooLittleSpacing {
    /**
     * Docblock.
     */
    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    function FirstFunction()
    {
        // Code
    }
}

class DocblockPrecededByAttributesCorrectSpacing {

    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    /**
     * No error.
     */
    function FirstFunction()
    {
        // Code
    }
}

class DocblockPrecededByAttributesTooMuchSpacing {


    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    /**
     * Docblock.
     */
    function FirstFunction()
    {
        // Code
    }
}

class DocblockPrecededByAttributesTooLittleSpacing {
    #[AttributesShouldBeJumpedOver]
    #[
        ASecondAttributeShouldBeJumpedOverToo
    ]#[AndAThirdAsWell]
    /**
     * Docblock.
     */
    function FirstFunction()
    {
        // Code
    }
}

// Reset properties to their default value.
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingBeforeFirst 2
// phpcs:set Squiz.WhiteSpace.FunctionSpacing spacingAfterLast 2

class SilenceBeforeErrorIfPreviousThingWasAFunctionBug
{
    /**
     * Docblock.
     */

    #[ReturnTypeWillChange]





    #[

        AnotherAttribute

    ]#[AndAThirdAsWell]

    public function blankLineDetectionA()
    {

    }//end blankLineDetectionA()

    /**
     * Docblock.
     */
    #[ReturnTypeWillChange]

    public function blankLineDetectionB()
    {

    }//end blankLineDetectionB()
}//end class

// Issue #945.
class OnlyAcceptFirstDocblockAsBelongingWithFunction {
    /**
     * Superfluous docblock
     */


    /**
     * Function docblock
     */
    function correctSpacing($x) {}


    /**
     * Superfluous docblock
     */
    /**
     * Function docblock
     */
    function incorrectSpacing($x) {}


}
