selene / writer
Helper component for generating source code
Installs: 272
Dependents: 1
Suggesters: 0
Security: 0
Watchers: 1
Open Issues: 0
pkg:composer/selene/writer
Requires
- selene/common: dev-development
Requires (Dev)
- league/phpunit-coverage-listener: dev-master
- selene/testsuite: dev-development
This package is not auto-updated.
Last update: 2015-12-07 10:26:36 UTC
README
Installation
Require Selene\Module\Writer in your composer file.
{
"require": {
"selene/writer": "dev-development"
}
}
Then, run the composer install or update command.
$ composer install
The Writer
Dumping strings
Write a 2 line text block:
<?php
use \Selene\Module\Writer\Writer;
$writer = new Writer;
$writer
->writeln('foo')
->writeln('bar');
echo $writer->dump(); //"foo\n bar"
Behavior
By defatault, the Writer will remove trailing spaces at the end of each line.
You may override this behavior by calling the allowTrailingSpace()
method.
<?php use \Selene\Module\Writer\Writer; $writer = new Writer; $writer->allowTrailingSpace(true); // will now preserve trailing space chars for each line.
Indentation
The default indentation level is 4 spaces.
If you require a different level using spaces, you'll have to specify this on the. constructor:
<?php
use \Selene\Module\Writer\Writer;
$writer = new Writer(2);
$writer
->writeln('foo')
->writeln('bar');
echo $writer->dump(); //"foo\n bar"
You may also change spaces to tabs using the useTabs() method.
<?php use \Selene\Module\Writer\Writer; $writer = new Writer; $writer->useTabs(true); // …
Output indentation
Output indentation indents the whole block and is applied just before the
string is being dumped. The value passed to setOutputIndentation(int $level)
acts as a multiplyer.
API
Fluent methods:
Selene\Module\Writer\Writerwriteln(string|null $str)
Adds a line.Selene\Module\Writer\Writerindent(void) Adds an indentation.Selene\Module\Writer\Writerreplaceln( string $str, int $index)
Replaces a line at a line index.Selene\Module\Writer\Writerremoveln(int $index)
Removes a line at a line index.Selene\Module\Writer\Writerpopln (void)
Removes the last line.Selene\Module\Writer\Writerappendln (string $str)
Appends a string to the last line.
None fluent methods:
voidignoreNull(bool $ignore)
Don't add a line if$strinWriter::writeln()isnull. Default is on.voidallowTrailingSpace(bool $space)
Allow/Disallow traling space chars. Default is off.voiduseTabs(void)
Use Tabs for indentation instead of spaces.voidsetOutputIndentation(int $level)
Sets the output indentation level of the whole text block.
The level value increments the indentation by one indent, e.g.0is no additional indentation,1is one indent, etc.
Default is0.intgetOutputIndentation(void)
Gets the output indentation level. (seeWriter::setOutputIndentation());
Generators
Dump PSR-2 compliant php source code.
There're three object generators, InterfaceWriter, ClassWriter, and TraitWriter.
All object generators share a common API.
Shared API
setParent(
string $parent)
This is a one time operation. Once the parent is set, you cannot change it.$parentname must be the FQN of the parent interface or class.addUseStatement(
string $use)
Adds a use statement to the php document. Naming conflicts will automatically be resolved, however you can set your own alias by declating the import like this\Acme\Foo as FooAlias. By defaultAcme\Lib\Foowill becomeLibFoo, orAcmeLibFoo, orAcmeLibFooAlias, and so on. Note that the use statement is considered to be the FQN;getImportResolver( )
Will return an instance ofSelene\Module\Writer\Object\ImportResolver. This is useful if you need to know the aliases name of a imported string (interface, trait, parent class or usestatement), e.g.
<?php
$alias = $cg->getImportResolver()->getAlias('Acme\MyClass') // e.g. AcmeMyClassAlias;
voidaddConstant(Selene\Module\Writer\Object\Constant $constant)
Adds a constant to the interface.voidaddMethod(Selene\Module\Writer\Object\MethodInterface $method)
Takes an object of typeSelene\Module\Writer\Object\MethodInterfaceand adds it to the object declaration.Selene\Module\Writer\Object\DocBlockgetDoc(void)
Returns an instance ofSelene\Module\Writer\Object\DocBlockthat represents the document level docblock.Selene\Module\Writer\Object\DocBlockgetObjDoc(void)
Returns an instance ofSelene\Module\Writer\Object\DocBlockthat represents the object level docblock.voidnoAutoGenerateTag( void )
By default, the objectwriter will add a timestamp to the document level docblock. Use this if you wan't to deactivate this behavior.
InterfaceWriter
Use this for autogenerating php interfaces.
<?php
use \Selene\Module\Writer\Object\ClassWriter;
$iw = new InterfaceWriter('Foo', 'Acme', '\Acme\Parent');
file_put_contents('Acme/Foo.php', $iw->generate());
Results in:
<?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)
Takes an object of typeSelene\Module\Writer\Object\InterfaceMethodand adds it to the interface.
ClassWriter
Use this for autogenerating php classes.
<?php
use \Selene\Module\Writer\Object\ClassWriter;
$cg = new ClassWriter('Foo', 'Acme');
file_put_contents('Acme/Foo.php', $cg->generate());
Results in:
<?php
/**
* This file was generated at 2014-07-08 12:23:22.
*/
namespace Acme;
/**
* @class Foo
*/
class Foo
{
}
API
In addition to the InterfaceWriter:
voidaddTrait(string $trait)
Takes a FQN of a trait and adds it as a trait. Traits will be automatically added to the use statements list, except they're belong to exact same namespace of the class.voidaddInterface(string $interface)
Adds an interface. Will be automatically added to the class imports.voidsetAbstract(boolean $abstract)
Toggle this class abstract.voidaddMethod(MethodInterface $method)
Takes an object of typeMethodand adds it to the class.voidsetProperties(array $properties)
Set the class properties.$propertiesmust be an array ofSelene\Module\Writer\Object\Propertyinstances.voidaddProperty(Selene\Module\Writer\Object\Property $property)
Takes an object of typeSelene\Module\Writer\Object\Propertyand adds it as a class property.voiduseTraitMethodAs(string $trait,string $method,string $replacement,[string $visibility])
Replaces a method naming conflict between a trait an a class. Default visiblity ispublic.voidreplaceTraitConflict(string $trait,string $conflict,string $method)
Replaces a method conflict between two traits.
Example
Generating a class with constants, methods, properties, and traits.
<?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();
Results in
<?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
Behaves like the ClassWriter except there're no constants and interfaces.
Setting method bodies is up to you. However, if you rely on class base names that have been imported you can utilize the import resolver to determine the actual shortname that's used on the object writer.
Also see the Shared API section.
<?php
// $cl beeing the object writer instance.
$body = 'return new '.$cl->getImportResolver()->getAlias('Acme\MyClass').';';
$method->setBody($body);