herrera-io/annotations

该软件包已被 放弃,并且不再维护。未建议替代软件包。

Doctrine 注释的标记化器。

1.0.1 2014-02-03 17:34 UTC

This package is not auto-updated.

Last update: 2021-12-07 01:33:12 UTC


README

Build Status

Annotations 库用于对 Doctrine 风格的 注释 进行标记化和转换。与 Doctrine Annotations 库不同,这个库不需要类或常量存在,也不进行评估。

Doctrine Annotations 库中的 DocLexer 类用于从注释的文档块中生成标记。该库处理这些标记的过滤、验证和转换。

示例

use Herrera\Annotations\Tokenizer;

$tokenizer = new Tokenizer();

$tokens = $tokenizer->parse(
    <<<DOCBLOCK
/**
 * @My\Annotation(
 *     a="string value",
 *     @Nested,
 *     {"a list"},
 *     A_CONSTANT
 * )
 */
DOCBLOCK
);

/*
 * array(
 *     array(DocLexer::T_AT),
 *     array(DocLexer::T_IDENTIFIER, 'My\\Annotation'),
 *     array(DocLexer::T_OPEN_PARENTHESIS),
 *     array(DocLexer::T_IDENTIFIER, 'a'),
 *     array(DocLexer::T_EQUALS),
 *     array(DocLexer::T_STRING, 'string value'),
 *     array(DocLexer::T_COMMA),
 *     array(DocLexer::T_AT),
 *     array(DocLexer::T_IDENTIFIER, 'Nested'),
 *     array(DocLexer::T_OPEN_CURLY_BRACES),
 *     array(DocLexer::T_STRING, 'a list'),
 *     array(DocLexer::T_COMMA),
 *     array(DocLexer::T_IDENTIFIER, 'A_CONSTANT'),
 *     array(DocLexer::T_CLOSE_CURLY_BRACES),
 *     array(DocLexer::T_CLOSE_PARENTHESIS)
 * )
 */

安装

将其作为 Composer 依赖项添加

$ composer require herrera-io/annotations=~1.0

标记化

要标记化文档块注释,您首先需要创建一个 Tokenizer 实例。该对象可以重复使用以解析所需数量的文档块

use Herrera\Annotations\Tokenizer;

$tokenizer = new Tokenizer();

$tokenizer->ignore(
    array(
        'author',
        'package'
    )
);

$aliases = array('ORM' => 'Doctrine\\ORM\\Mapping');

$parsed = $tokenizer->parse($docblock, $aliases);

ignore() 方法允许您指定要忽略的注释列表。默认情况下,不忽略任何注释,因此注册 Doctrine 提供的默认列表可能是有益的

array(
  'Annotation', 'Attribute', 'Attributes', 'Required', 'SuppressWarnings',
  'TODO', 'Target', 'abstract', 'access', 'api', 'author', 'category', 'code',
  'codeCoverageIgnore', 'codeCoverageIgnoreEnd', 'codeCoverageIgnoreStart',
  'copyright', 'deprec', 'deprecated', 'endcode', 'example', 'exception',
  'filesource', 'final', 'fixme', 'global', 'ignore', 'ingroup', 'inheritDoc',
  'inheritdoc', 'internal', 'license', 'link', 'magic', 'method', 'name',
  'override', 'package', 'package_version', 'param', 'private', 'property',
  'return', 'see', 'since', 'static', 'staticVar', 'staticvar', 'subpackage',
  'throw', 'throws', 'todo', 'tutorial', 'usedby', 'uses', 'var', 'version',
)

$aliases 参数允许您指定可能用于注释名称的别名列表。例如,通常使用以下方式缩短 Doctrine ORM 注释的名称

use Doctrine\ORM\Mapping as ORM;

$aliases 示例演示了仅将 ORM 命名空间别名映射到 Doctrine\ORM\Mapping。可以同时指定其他别名

$aliases = array(
    'Assert' => 'Symfony\Component\Validator\Constraints',
    'ORM' => 'Doctrine\ORM\Mapping',
    'Route' => 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Route',
);

$parsed 的值是标记的数组。每个标记将包含标记的数字标识符,后面跟随从文档块中解析出的值(如果适用)。

您可以在这里找到标记标识符的参考。

此示例文档块

/**
 * @author Some Author <[email protected]>
 *
 * @package MyPackage
 *
 * @ORM\Column(name="MyColumn")
 */

$tokens 中将产生以下标记

$parsed = array(
    array(DocLexer::T_AT),
    array(DocLexer::T_IDENTIFIER, 'Doctrine\\ORM\\Mapping\\Column'),
    array(DocLexer::T_OPEN_PARENTHESIS),
    array(DocLexer::T_IDENTIFIER, 'name'),
    array(DocLexer::T_EQUALS),
    array(DocLexer::T_STRING, 'MyColumn'),
    array(DocLexer::T_CLOSE_PARENTHESIS)
);

转换

一旦您已解析文档块以获取其标记,您可能需要将标记列表转换为另一种格式。在介绍可用的转换器之前,我需要向您展示如何创建由转换器使用的 TokensSequence 实例。

标记和序列

转换器在将标记列表转换为另一种格式时使用 TokensSequence 类。Tokens 类类似于数组,但它还会在使用过程中验证标记。Sequence 类是 Tokens 的扩展,但它还会验证标记的使用顺序。

转换器只需要您使用 Tokens,但它们也与 Sequence 类兼容。您可能需要使用 Sequence 类的唯一情况是进行注释问题的调试,或者如果您从除 Tokenizer 类之外的任何内容接收标记。

创建这两个类中的任意一个实例非常简单

use Herrera\Annotations\Sequence;
use Herrera\Annotations\Tokens;

$tokens = new Tokens($parsed);
$sequence = new Sequence($parsed);
$sequence = new Sequence($tokens); // also accepts a Tokens object

转换为数组

使用ToArray实例将令牌转换为简单的数组。

use Herrera\Annotations\Convert\ToArray;

$toArray = new ToArray();

$array = $toArray->convert($tokens);

$array的值是一个对象数组。每个对象代表文档块中的一个单独注释。每个对象将有两个属性:namevalues。所有包含在()中的值都将位于values中,包括嵌套注释。

以下示例

$array = $toArray->convert(
    new Tokens (
        $tokenizer->parse(
        <<<DOCBLOCK
/**
 * @Annotation\A("Just a simple value.")
 * @Annotation\B(
 *     name="SomeName",
 *     nested=@Annotation(),
 *     {
 *         "an array",
 *         {
 *             "within an array"
 *         }
 *     }
 * )
 */
DOCBLOCK
        )
    )
);

将得到以下数组

$array = array(
    (object) array(
        'name' => 'Annotation\\A',
        'values' => array(
            'Just a simple value.'
        )
    ),
    (object) array(
        'name' => 'Annotations\\B',
        'values' => array(
            'name' => 'SomeName',
            'nested' => (object) array(
                'name' => 'Annotation',
                'values' => array()
            ),
            array(
                'an array',
                array(
                    'within an array'
                )
            )
        )
    ),
);

echo $array[0]->name;  // "Annotation\A"
echo $array[0]->values[0]; // "Just a simple value."
echo $array[1]->values['nested']->name; // "Annotation"

转换为字符串

使用ToString实例将令牌转换为它们的字符串表示形式。

use Herrera\Annotations\Convert\ToString;

$toString = new ToString();

$string = $toString->convert($tokens);

使用此示例

$string = $toString->convert(
    new Tokens(
        $tokenizer->parse(
        <<<DOCBLOCK
/**
 * @Annotation\A("Just a simple value.")
 * @Annotation\B(
 *     name="SomeName",
 *     nested=@Annotation(),
 *     {
 *         "an array",
 *         {
 *             "within an array"
 *         }
 *     }
 * )
 */
DOCBLOCK
        )
    )
);

结果将与之前相似,但没有任何格式

$string = <<<STRING
@Annotation\A("Just a simple value.")
@Annotation\B(name="SomeName",nested=@Annotation(),{"an array",{"within an array"}})';
STRING;

虽然字符串转换器支持格式化,但它提供的选项非常有限

  • setBreakChar($char) — 设置换行符。 (默认: \n)
  • setIndentChar($char) — 设置缩进字符。 (默认: (空格))
  • setIndentSize($size) — 设置缩进大小。 (默认: 0 (零))
  • useColonSpace($bool) — 切换是否在用于赋值的冒号后添加空格。 (默认: false) (示例: @Name({key: "value"}))

经过轻微修改

$toString->setIndentSize(4);

我们可以得到返回的格式化字符串

$string = <<<STRUNG
@Annotation\A(
    "Just a simple value."
)
@Annotation\B(
    name="SomeName",
    nested=@Annotation(),
    {
        "an array",
        {
            "within an array"
        }
    }
)
STRUNG;

转换为XML

使用ToXml实例将令牌转换为XML文档。

use Herrera\Annotations\Convert\ToXml;

$toXml = new ToXml();

$doc = $toXml->convert($tokens);

使用此示例

$doc = $toXml->convert(
    new Tokens(
        $tokenizer->parse(
        <<<DOCBLOCK
/**
 * @Annotation\A("Just a simple value.")
 * @Annotation\B(
 *     name="SomeName",
 *     nested=@Annotation(),
 *     {
 *         "an array",
 *         {
 *             "within an array"
 *         }
 *     }
 * )
 */
DOCBLOCK
        )
    )
);

echo $doc->saveXML();

将生成以下XML

<?xml version="1.0"?>
<annotations>
  <annotation name="Annotation\A">
    <value type="string">Just a simple value.</value>
  </annotation>
  <annotation name="Annotation\B">
    <value key="name" type="string">SomeName</value>
    <annotation key="nested" name="Annotation"/>
    <values>
      <value type="string">an array</value>
      <values>
        <value type="string">within an array</value>
      </values>
    </values>
  </annotation>
</annotations>

您还可以使用ToXml::validate($input)验证注释XML,其中$input可以是一个XML字符串或DOMDocument实例。如果您只需要访问XML模式,您可以使用类常量ToXml::SCHEMA获取文件路径。

虽然您可能可以使用HERRERA_ANNOTATIONS_SCHEMA常量获取模式路径,但我不建议这样做。它仅在加载ToXml类后才可用,并且名称的连续性不能保证。