Ejemplo n.º 1
0
function filter_classes_by_notes($classes, $notes)
{
    if (!is_array($notes)) {
        $notes = array($notes);
    }
    $parser = new \Nope\Parser();
    $found = array();
    foreach ($classes as $c) {
        $classNotes = $parser->parseClass(new \ReflectionClass($c));
        foreach ($notes as $k) {
            if (isset($classNotes->notes[$k])) {
                $found[] = $c;
            }
        }
    }
    return $found;
}
Ejemplo n.º 2
0
<?php

require __DIR__ . '/../vendor/autoload.php';
/**
 * :foo = {};
 * :bar = true;
 */
class Foo
{
    /** :yep = false; */
    public $pants;
    /** :yep = true; */
    public function setWhoopee()
    {
    }
}
/**
 * :foo = ["z"];
 * :baz = "DING";
 */
class Bar extends Foo
{
    /** :yep = true; */
    public $pants;
    public function setWhoopee()
    {
    }
}
$p = new \Nope\Parser();
dump($p->parseHierarchy(Bar::class));
Ejemplo n.º 3
0
 */
namespace {
    goto classdefs;
    top:
    require "/home/bl/web/bm/big/config.php";
    require __DIR__ . '/../vendor/autoload.php';
    $iter = 10;
    $p = new Nope\FastParser();
    $t = microtime(true);
    $cnt = 0;
    for ($i = 0; $i < $iter; $i++) {
        $cnt += $p->parseClass(\Big\CRM\Data\IOVersion::class) == true;
    }
    var_dump((microtime(true) - $t) / $iter * 1000);
    exit;
    $p = new Nope\Parser();
    $t = microtime(true);
    $cnt = 0;
    for ($i = 0; $i < $iter; $i++) {
        $cnt += $p->parseClass(\Big\CRM\Data\IOVersion::class) == true;
    }
    var_dump((microtime(true) - $t) / $iter * 1000);
    exit;
}
namespace Nope {
    classdefs:
    class FastParser
    {
        const S_NONE = 0;
        const S_NAME = 1;
        const S_JSON = 2;
Ejemplo n.º 4
0
 protected function loadMeta($class)
 {
     $ref = new \ReflectionClass($class);
     if (!$this->parser) {
         $this->parser = new \Nope\Parser();
     }
     $notes = $this->parser->parseHierarchy($ref, \ReflectionProperty::IS_PUBLIC, \ReflectionMethod::IS_PUBLIC);
     $classNotes = $notes->notes;
     if (!isset($classNotes[$this->annotationNamespace])) {
         return null;
     }
     $info = $classNotes[$this->annotationNamespace];
     if ($info === true) {
         $info = [];
     }
     table:
     if (!isset($info['table'])) {
         $info['table'] = $this->getDefaultTable($class);
     }
     class_relations:
     if (isset($info['relations'])) {
         foreach ($info['relations'] as $relKey => &$relDef) {
             $type = $relDef['type'];
             unset($relDef['type']);
             array_unshift($relDef, $type);
             if (!is_array($relDef)) {
                 throw new \Exception("Relation {$relKey} was not valid in class {$class}");
             }
             $relDef['mode'] = 'class';
         }
         unset($relDef);
     }
     class_indexes:
     if (isset($info['indexes'])) {
         // TODO: should be in Meta so the Arrays mapper can share it
         foreach ($info['indexes'] as $idxKey => &$idxDef) {
             if ($idxDef === true) {
                 $idxDef = ['fields' => [$idxKey]];
             }
         }
         unset($idxDef);
     }
     foreach (array('property' => $notes->properties, 'method' => $notes->methods) as $noteType => $noteBag) {
         foreach ($noteBag as $name => $itemNotes) {
             if (!isset($itemNotes[$this->annotationNamespace])) {
                 goto next_note_bag;
             }
             $itemNotes = $itemNotes[$this->annotationNamespace];
             validate:
             if ($diff = array_diff(array_keys($itemNotes), ['has', 'field', 'constructor'])) {
                 throw new \UnexpectedValueException("Invalid keys found in :amiss field/method annotation: " . implode(', ', $diff));
             }
             if (isset($itemNotes['field']) && isset($itemNotes['has'])) {
                 throw new \UnexpectedValueException("Invalid class {$class}: relation and a field declared together on {$name}");
             }
             field:
             if (isset($itemNotes['field'])) {
                 $field = $itemNotes['field'];
                 // NOTE: do not ensure $field['name'] is set here - it happens later in
                 // one big hit.
                 // FIXME: this should also happen in the Meta, but we need to guarantee we
                 // are operating on an array to collect getters and setters, etc
                 if ($field === true) {
                     $field = [];
                 } elseif (is_string($field)) {
                     $field = ['name' => $field];
                 } elseif ($field === false) {
                     // allows us to remove properties from consideration in child classes, i.e. :amiss = {"field": false};
                     goto next_note_bag;
                 } elseif (!is_array($field)) {
                     throw new \UnexpectedValueException();
                 }
                 if ($noteType == 'method') {
                     $key = $this->fillGetterSetter($name, $field, !!'readOnly');
                 } else {
                     $key = $name;
                 }
                 $manualKey = isset($field['id']) ? $field['id'] : null;
                 unset($field['id']);
                 $info['fields'][$manualKey ?: $key] = $field;
             }
             field_relation:
             if (isset($itemNotes['has'])) {
                 $relation = $itemNotes['has'];
                 if (is_string($relation)) {
                     $relation = ["type" => $relation];
                 } elseif ($relation === false) {
                     goto next_note_bag;
                 } elseif (!is_array($relation)) {
                     throw new \UnexpectedValueException();
                 }
                 if (!isset($relation['type'])) {
                     throw new \UnexpectedValueException("Relation {$name} missing 'type'");
                 }
                 $type = $relation['type'];
                 unset($relation['type']);
                 array_unshift($relation, $type);
                 if ($noteType == 'method') {
                     $key = $this->fillGetterSetter($name, $relation, !!'readOnly');
                 } else {
                     $key = $name;
                 }
                 $key = isset($relation['id']) ? $relation['id'] : $key;
                 unset($relation['id']);
                 if (isset($info['relations'][$key])) {
                     throw new \UnexpectedValueException("Duplicate relation {$name} on class {$class}");
                 }
                 $info['relations'][$key] = $relation;
             }
             constructor:
             if ($noteType == 'method' && isset($itemNotes['constructor'])) {
                 if (isset($info['constructor']) && $info['constructor']) {
                     throw new \UnexpectedValueException("Constructor already declared: {$info['constructor']}");
                 }
                 $info['constructor'] = $name;
                 if ($itemNotes['constructor'] !== true) {
                     if (!is_array($itemNotes['constructor'])) {
                         throw new \UnexpectedValueException();
                     }
                     if (isset($info['constructorArgs']) && $info['constructorArgs']) {
                         throw new \UnexpectedValueException("Constructor args declared at class level and also on method {$name}.");
                     }
                     $info['constructorArgs'] = $itemNotes['constructor'];
                 }
             }
             next_note_bag:
         }
     }
     if (isset($info['fields'])) {
         $info['fields'] = $this->resolveUnnamedFields($info['fields']);
     }
     return new \Amiss\Meta(ltrim($class, '\\'), $info);
 }
Ejemplo n.º 5
0
}
if (isset($groups['php'])) {
    foreach ($groups['php'] as $groupId => $group) {
        doctest_run_php_group($group);
    }
}
if (isset($blocks['php'])) {
    foreach ($blocks['php'] as $block) {
        if ($errors = php_lint_errors($block['code'])) {
            $errstr = implode("\n - ", $errors);
            throw new \RuntimeException("Linting block on {$block['file']}:{$block['line']} failed with errors:\n - " . $errstr);
        }
    }
}
lint_nope_blocks:
$nope = new \Nope\Parser();
foreach ($allBlocks as $block) {
    if ($block['lang'] == 'php') {
        $tokens = token_get_all($block['code']);
        foreach ($tokens as $token) {
            if (is_array($token) && $token[0] == T_DOC_COMMENT) {
                $parsed = $nope->parseDocComment($token[1]);
            }
        }
    } elseif ($block['lang'] == 'nope') {
        $parsed = $nope->parseDocComment($block['code']);
    }
}
function doctest_run_php_group($group)
{
    $scope = [];