selene/writer

此包已被弃用且不再维护。作者建议使用 lucid/writer 包。

生成源代码的辅助组件

dev-development 2014-08-19 03:25 UTC

This package is not auto-updated.

Last update: 2015-12-07 10:26:36 UTC


README

Build Status Latest Stable Version Latest Unstable Version License HHVM Status

Coverage Status Code Climate

安装

在您的composer文件中需要 Selene\Module\Writer

{
    "require": {
        "selene/writer": "dev-development"
    }
}

然后,运行composer install或update命令。

$ composer install

Writer

字符串导出

写一个2行文本块

<?php

use \Selene\Module\Writer\Writer;

$writer = new Writer;

$writer
    ->writeln('foo')
    ->writeln('bar');

echo $writer->dump();  //"foo\n    bar"  

行为

默认情况下,Writer将移除每行末尾的空格。

您可以通过调用allowTrailingSpace()方法来覆盖此行为。

<?php

use \Selene\Module\Writer\Writer;

$writer = new Writer;
$writer->allowTrailingSpace(true); // will now preserve trailing space chars for each line.

缩进

默认缩进级别为4个空格。

如果您需要使用空格设置不同的级别,您必须在构造函数中指定此级别。

<?php

use \Selene\Module\Writer\Writer;

$writer = new Writer(2);

$writer
    ->writeln('foo')
    ->writeln('bar');

echo $writer->dump(); //"foo\n  bar"   

您还可以使用useTabs()方法将空格更改为制表符。

<?php

use \Selene\Module\Writer\Writer;

$writer = new Writer;
$writer->useTabs(true);

// …

输出缩进

输出缩进将整个块缩进,并在字符串被导出之前应用。传递给setOutputIndentation(int $level)的值作为乘数。

API

流畅方法

  • Selene\Module\Writer\Writer writeln( string|null $str )
    添加一行。

  • Selene\Module\Writer\Writer indent( void ) 添加缩进。

  • Selene\Module\Writer\Writer replaceln( string $str, int $index)
    在行索引处替换一行。

  • Selene\Module\Writer\Writer removeln( int $index )
    在行索引处删除一行。

  • Selene\Module\Writer\Writer popln ( void )
    删除最后一行。

  • Selene\Module\Writer\Writer appendln ( string $str )
    将字符串追加到最后一行。

非流畅方法

  • void ignoreNull( bool $ignore )
    如果Writer::writeln()中的$strnull,则不添加行。默认为开启。

  • void allowTrailingSpace( bool $space )
    允许/禁止尾随空格字符。默认为关闭。

  • void useTabs( void )
    使用制表符进行缩进而不是空格。

  • void setOutputIndentation( int $level )
    设置整个文本块的输出缩进级别。
    级别值通过一个缩进增加缩进,例如:0表示没有额外的缩进,1表示一个缩进,等等。
    默认为0

  • int getOutputIndentation( void )
    获取输出缩进级别。(见Writer::setOutputIndentation());

生成器

导出符合PSR-2规范的PHP源代码。

有三个对象生成器,分别是InterfaceWriterClassWriterTraitWriter
所有对象生成器共享一个公共API。

共享API

  • setParent( string $parent )
    这是一个一次性操作。一旦设置了父类,就无法更改。$parent名称必须是父接口或类的完全限定名(FQN)。

  • addUseStatement( string $use )
    将使用语句添加到PHP文档中。命名冲突将自动解决,但您可以像这样声明导入以设置自己的别名:\Acme\Foo as FooAlias。默认情况下,Acme\Lib\Foo将变为LibFooAcmeLibFooAcmeLibFooAlias等。请注意,使用语句被视为全限定名(FQN);

  • getImportResolver( )
    将返回一个Selene\Module\Writer\Object\ImportResolver实例。如果您需要知道导入字符串(接口、特质、父类或使用语句)的别名,这很有用,例如。

<?php
$alias = $cg->getImportResolver()->getAlias('Acme\MyClass') // e.g. AcmeMyClassAlias;
  • void addConstant( Selene\Module\Writer\Object\Constant $constant )
    将常量添加到接口中。

  • void addMethod( Selene\Module\Writer\Object\MethodInterface $method )
    接收一个类型为Selene\Module\Writer\Object\MethodInterface的对象,并将其添加到对象声明中。

  • Selene\Module\Writer\Object\DocBlock getDoc( void )
    返回一个表示文档级别文档块的Selene\Module\Writer\Object\DocBlock实例。

  • Selene\Module\Writer\Object\DocBlock getObjDoc( void )
    返回一个表示对象级别文档块的Selene\Module\Writer\Object\DocBlock实例。

  • void noAutoGenerateTag( void )
    默认情况下,对象编写器会向文档级别文档块添加时间戳。如果您想禁用此行为,请使用此方法。

InterfaceWriter

用于自动生成PHP接口。

<?php 

use \Selene\Module\Writer\Object\ClassWriter;

$iw = new InterfaceWriter('Foo', 'Acme', '\Acme\Parent');

file_put_contents('Acme/Foo.php', $iw->generate());

结果如下

<?php 

/**
 * This file was generated at 2014-07-08 12:23:22.
 */

namespace Acme;

/**
 * @interface Foo
 * @see Acme\Parent
 */
interface Foo extends Parent
{
}

API

  • addMethod( Selene\Module\Writer\Object\MethodInterface $method )
    接收一个类型为Selene\Module\Writer\Object\InterfaceMethod的对象,并将其添加到接口中。

ClassWriter

用于自动生成PHP类。

<?php 

use \Selene\Module\Writer\Object\ClassWriter;

$cg = new ClassWriter('Foo', 'Acme');

file_put_contents('Acme/Foo.php', $cg->generate());

结果如下

<?php 

/**
 * This file was generated at 2014-07-08 12:23:22.
 */

namespace Acme;

/**
 * @class Foo
 */
class Foo
{
}

API

除了InterfaceWriter之外

  • void addTrait( string $trait )
    接收一个特质的FQN并将其添加为特质。特质将自动添加到使用语句列表中,除非它们属于与类完全相同的命名空间。

  • void addInterface( string $interface )
    添加接口。将自动添加到类导入中。

  • void setAbstract( boolean $abstract )
    切换类的抽象属性。

  • void addMethod( MethodInterface $method )
    接收一个类型为Method的对象,并将其添加到类中。

  • void setProperties( array $properties )
    设置类属性。必须是一个包含Selene\Module\Writer\Object\Property实例的数组。

  • void addProperty( Selene\Module\Writer\Object\Property $property )
    接收一个类型为Selene\Module\Writer\Object\Property的对象,并将其添加为类属性。

  • void useTraitMethodAs(string $trait, string $method, string $replacement, [string $visibility])
    替换特质和类之间的方法命名冲突。默认可见性为public

  • void replaceTraitConflict(string $trait, string $conflict, string $method)
    替换两个特质之间的方法冲突。

示例

生成具有常量、方法、属性和特质的类。

<?php

use \Selene\Module\Writer\Writer;
use \Selene\Module\Writer\Object\Constant;
use \Selene\Module\Writer\Object\Argument;
use \Selene\Module\Writer\Object\Method;
use \Selene\Module\Writer\Object\Property;
use \Selene\Module\Writer\Object\ClassGenerator;

$cg = new ClassGenerator('Foo', 'Acme');

$cg->setParent('Acme\Lib\Bar');
$cg->addProperty(new Property('foo', 'string'));
$cg->addConstant(new Constant('T_ASW', '42'));
$cg->addMethod($method = new Method('__construct', Method::IS_PUBLIC, Method::T_VOID));

// declare method:
$method->setDescription('Constructor.')
$method->addArgument(new Argument('foo', Method::T_STRING, 'null'));
$method->setBody('$this->foo = $foo;');

// Add traits:
$cg->addTrait($foo = 'Acme\Lib\Traits\FooTrait');
$cg->addTrait($bar = 'Acme\Lib\Traits\BarTrait');
// resolve trait conflicts:
$cg->useTraitMethodAs($foo, 'getFoo', 'getFooStr', Method::IS_PRIVATE);
$cg->replaceTraitConflict($bar, $foo, 'getBar');

// modify the class doc.
$cg->getObjDoc()
    ->setDescription('Some class.')
    ->setLongDescription("Some more info on the class.\nSome more lines.")
    ->addAnnotation('author', 'Thomas Appel <mail@thomas-appel.com>');

echo $cg->generate();

结果如下

<?php

/**
 * This file was generated at 2014-07-09 02:07:42. 
 */

namespace Acme;

use Acme\Lib\Bar;
use Acme\Lib\Traits\BarTrait;
use Acme\Lib\Traits\FooTrait;

/**
 * Some class.
 *
 * Some more info on the class.
 * Some more lines.
 *
 * @class Foo
 * @see Acme\Lib\Bar
 * @author Thomas Appel <mail@thomas-appel.com>
 */
class Foo extends Bar
{
    const T_ASW = 42;

    use FooTrait, 
        BarTrait {
        FooTrait::getFoo as private getFooStr;  
        BarTrait::getBar insteadof FooTrait;    
    }

    /**
     * foo
     *
     * @var mixed
     */
    string $foo;

    /**
     * Constructor.
     *
     * @param string $foo
     */
    public function __construct($foo = null)
    {
        $this->foo = $foo;
    }
}

TraitWriter

行为类似于ClassWriter,但没有任何常量和接口。

注意

设置方法体取决于您。但是,如果您依赖于已导入的类基名称,则可以使用导入解析器来确定在对象编写器上使用的实际短名称。

另请参阅共享API部分。

<?php

// $cl beeing the object writer instance.

$body = 'return new '.$cl->getImportResolver()->getAlias('Acme\MyClass').';';
$method->setBody($body);