Example #1
0
 /**
  * Compacts the docblock and its annotations.
  *
  * @param string $docblock The docblock.
  *
  * @return string The compacted docblock.
  */
 private function compactAnnotations($docblock)
 {
     $annotations = array();
     $index = -1;
     $inside = 0;
     $tokens = $this->tokenizer->parse($docblock);
     if (empty($tokens)) {
         return str_repeat("\n", substr_count($docblock, "\n"));
     }
     foreach ($tokens as $token) {
         if (0 === $inside && DocLexer::T_AT === $token[0]) {
             $index++;
         } elseif (DocLexer::T_OPEN_PARENTHESIS === $token[0]) {
             $inside++;
         } elseif (DocLexer::T_CLOSE_PARENTHESIS === $token[0]) {
             $inside--;
         }
         if (!isset($annotations[$index])) {
             $annotations[$index] = array();
         }
         $annotations[$index][] = $token;
     }
     $breaks = substr_count($docblock, "\n");
     $docblock = "/**";
     foreach ($annotations as $annotation) {
         $annotation = new Tokens($annotation);
         $docblock .= "\n" . $this->converter->convert($annotation);
     }
     $breaks -= count($annotations);
     if ($breaks > 0) {
         $docblock .= str_repeat("\n", $breaks - 1);
         $docblock .= "\n*/";
     } else {
         $docblock .= ' */';
     }
     return $docblock;
 }
Example #2
0
    public function testIssue14()
    {
        $original = <<<CODE
<?php

// autoload_real.php @generated by Composer

/**
 * @author Made Up <*****@*****.**>
 */
class ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df
{
    private static \$loader;

    /** @inline annotation */
    public static function loadClassLoader(\$class)
    {
        if ('Composer\\Autoload\\ClassLoader' === \$class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    public static function getLoader()
    {
        if (null !== self::\$loader) {
            return self::\$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df', 'loadClassLoader'), true, true);
        self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df', 'loadClassLoader'));

        \$vendorDir = dirname(__DIR__);
        \$baseDir = dirname(\$vendorDir);

        \$includePaths = require __DIR__ . '/include_paths.php';
        array_push(\$includePaths, get_include_path());
        set_include_path(join(PATH_SEPARATOR, \$includePaths));

        \$map = require __DIR__ . '/autoload_namespaces.php';
        foreach (\$map as \$namespace => \$path) {
            \$loader->set(\$namespace, \$path);
        }

        \$map = require __DIR__ . '/autoload_psr4.php';
        foreach (\$map as \$namespace => \$path) {
            \$loader->setPsr4(\$namespace, \$path);
        }

        \$classMap = require __DIR__ . '/autoload_classmap.php';
        if (\$classMap) {
            \$loader->addClassMap(\$classMap);
        }

        \$loader->register(true);

        return \$loader;
    }
}

CODE;
        $expected = <<<CODE
<?php






class ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df
{
private static \$loader;


public static function loadClassLoader(\$class)
{
if ('Composer\\Autoload\\ClassLoader' === \$class) {
require __DIR__ . '/ClassLoader.php';
}
}

public static function getLoader()
{
if (null !== self::\$loader) {
return self::\$loader;
}

spl_autoload_register(array('ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df', 'loadClassLoader'), true, true);
self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitc22fe6e3e5ad79bad24655b3e52999df', 'loadClassLoader'));

\$vendorDir = dirname(__DIR__);
\$baseDir = dirname(\$vendorDir);

\$includePaths = require __DIR__ . '/include_paths.php';
array_push(\$includePaths, get_include_path());
set_include_path(join(PATH_SEPARATOR, \$includePaths));

\$map = require __DIR__ . '/autoload_namespaces.php';
foreach (\$map as \$namespace => \$path) {
\$loader->set(\$namespace, \$path);
}

\$map = require __DIR__ . '/autoload_psr4.php';
foreach (\$map as \$namespace => \$path) {
\$loader->setPsr4(\$namespace, \$path);
}

\$classMap = require __DIR__ . '/autoload_classmap.php';
if (\$classMap) {
\$loader->addClassMap(\$classMap);
}

\$loader->register(true);

return \$loader;
}
}

CODE;
        $tokenizer = new Tokenizer();
        $tokenizer->ignore(array('author', 'inline'));
        $this->php->setTokenizer($tokenizer);
        $this->assertEquals($expected, $this->php->compact($original));
    }
 /**
  * Will return one pointcut which does specifically only match the joinpoints of the structure
  * which this docblock belongs to
  *
  * @param string $docBlock   The DocBlock to search in
  * @param string $targetType Type of the target any resulting joinpoints have, e.g. Joinpoint::TARGET_METHOD
  * @param string $targetName Name of the target any resulting joinpoints have
  *
  * @return \AppserverIo\Doppelgaenger\Entities\Lists\PointcutExpressionList
  */
 public function getPointcutExpressions($docBlock, $targetType, $targetName)
 {
     $pointcutExpressions = new PointcutExpressionList();
     // get our tokenizer and parse the doc Block
     $tokenizer = new Tokenizer();
     $tokenizer->ignore(array('param', 'return', 'throws'));
     $tokens = new Tokens($tokenizer->parse($docBlock));
     // convert to array and run it through our advice factory
     $toArray = new ToArray();
     $annotations = $toArray->convert($tokens);
     // create the entities for the join-points and advices the pointcut describes
     foreach ($annotations as $annotation) {
         // filter out the annotations which are no proper join-points
         if (!class_exists('\\AppserverIo\\Psr\\MetaobjectProtocol\\Aop\\Annotations\\Advices\\' . $annotation->name)) {
             continue;
         }
         // build the join-point
         $joinpoint = new Joinpoint();
         $joinpoint->setTarget($targetType);
         $joinpoint->setCodeHook($annotation->name);
         $joinpoint->setStructure($this->currentDefinition->getQualifiedName());
         $joinpoint->setTargetName($targetName);
         // build the pointcut(s)
         foreach ($annotation->values as $rawAdvice) {
             // as it might be an array we have to sanitize it first
             if (!is_array($rawAdvice)) {
                 $rawAdvice = array($rawAdvice);
             }
             foreach ($rawAdvice as $adviceString) {
                 // create the pointcut
                 $pointcutExpression = new PointcutExpression($adviceString);
                 $pointcutExpression->setJoinpoint($joinpoint);
                 $pointcutExpressions->add($pointcutExpression);
             }
         }
     }
     return $pointcutExpressions;
 }
 /**
  * @param $comment
  * @return mixed
  */
 public function parse($comment)
 {
     return $this->annotationToArray->convert(new Tokens($this->annotationTokenizer->parse($comment)));
 }
 /**
  * Returns the list of file contents compactors.
  *
  * @return CompactorInterface[] The list of compactors.
  *
  * @throws InvalidArgumentException If a class is not valid.
  */
 public function getCompactors()
 {
     $compactors = array();
     if (isset($this->raw->compactors)) {
         foreach ((array) $this->raw->compactors as $class) {
             if (false === class_exists($class)) {
                 throw new InvalidArgumentException(sprintf('The compactor class "%s" does not exist.', $class));
             }
             $compactor = new $class();
             if (false === $compactor instanceof CompactorInterface) {
                 throw new InvalidArgumentException(sprintf('The class "%s" is not a compactor class.', $class));
             }
             if ($compactor instanceof Php) {
                 if (!empty($this->raw->annotations)) {
                     $tokenizer = new Tokenizer();
                     if (isset($this->raw->annotations->ignore)) {
                         $tokenizer->ignore((array) $this->raw->annotations->ignore);
                     }
                     $compactor->setTokenizer($tokenizer);
                 }
             }
             $compactors[] = $compactor;
         }
     }
     return $compactors;
 }
 /**
  * Returns the property type found in the properties configuration
  * annotation.
  *
  * @param \ReflectionProperty $reflectionProperty The property to return the type for
  *
  * @throws \Exception Is thrown if the property has NO bean annotation
  * @return Mapping The found property type mapping
  */
 public function getPropertyTypeFromDocComment(\ReflectionProperty $reflectionProperty)
 {
     // initialize the annotation tokenizer
     $tokenizer = new Tokenizer();
     // set the aliases
     $aliases = array('AS' => 'AppserverIo\\Description\\Api\\Node');
     // parse the doc block
     $parsed = $tokenizer->parse($reflectionProperty->getDocComment(), $aliases);
     // convert tokens and return one
     $tokens = new Tokens($parsed);
     $toArray = new ToArray();
     // iterate over the tokens
     foreach ($toArray->convert($tokens) as $token) {
         if ($token->name == 'AppserverIo\\Description\\Api\\Node\\Mapping') {
             return new $token->name($token);
         }
     }
 }
 public function testIgnored()
 {
     $ignore = array('abc', 'def');
     $this->tokenizer->ignore($ignore);
     $this->assertEquals($ignore, $this->getPropertyValue($this->tokenizer, 'ignored'));
 }
 /**
  * Will register a complete aspect to the AspectRegister.
  * This include its advices and pointcuts which can be looked up from this point on
  *
  * @param \AppserverIo\Doppelgaenger\Entities\Definitions\AspectDefinition $aspectDefinition Structure to register as an aspect
  *
  * @return null
  */
 public function register(AspectDefinition $aspectDefinition)
 {
     // create the new aspect and fill it with things we already know
     $aspect = new Aspect();
     $aspect->setName($aspectDefinition->getName());
     $aspect->setNamespace($aspectDefinition->getNamespace());
     // prepare the tokenizer we will need for further processing
     $needles = array(AfterReturning::ANNOTATION, AfterThrowing::ANNOTATION, After::ANNOTATION, Around::ANNOTATION, Before::ANNOTATION);
     $tokenizer = new Tokenizer();
     $tokenizer->ignore(array('param', 'return', 'throws'));
     // iterate the functions and filter out the ones used as advices
     $scheduledAdviceDefinitions = array();
     foreach ($aspectDefinition->getFunctionDefinitions() as $functionDefinition) {
         $foundNeedle = false;
         foreach ($needles as $needle) {
             // create the advice
             if (strpos($functionDefinition->getDocBlock(), '@' . $needle) !== false) {
                 $foundNeedle = true;
                 $scheduledAdviceDefinitions[$needle][] = $functionDefinition;
                 break;
             }
         }
         // create the pointcut
         if (!$foundNeedle && strpos($functionDefinition->getDocBlock(), '@' . Pointcut::ANNOTATION) !== false) {
             $pointcut = new PointcutDefinition();
             $pointcut->setName($functionDefinition->getName());
             $tokens = new Tokens($tokenizer->parse($functionDefinition->getDocBlock()));
             // convert to array and run it through our advice factory
             $toArray = new ToArray();
             $annotations = $toArray->convert($tokens);
             // create the entities for the join-points and advices the pointcut describes
             $pointcut->setPointcutExpression(new PointcutExpression(array_pop(array_pop($annotations)->values)));
             $aspect->getPointcuts()->add($pointcut);
         }
     }
     $this->add($aspect);
     // do the pointcut lookups where we will need the pointcut factory for later use
     $pointcutFactory = new PointcutFactory();
     foreach ($scheduledAdviceDefinitions as $codeHook => $hookedAdviceDefinitions) {
         foreach ($hookedAdviceDefinitions as $scheduledAdviceDefinition) {
             // create our advice
             $advice = new Advice();
             $advice->setAspectName($aspectDefinition->getQualifiedName());
             $advice->setName($scheduledAdviceDefinition->getName());
             $advice->setCodeHook((string) $codeHook);
             $tokens = new Tokens($tokenizer->parse($scheduledAdviceDefinition->getDocBlock()));
             // convert to array and run it through our advice factory
             $toArray = new ToArray();
             $annotations = $toArray->convert($tokens);
             // create the entities for the join-points and advices the pointcut describes
             foreach ($annotations as $annotation) {
                 $pointcut = $pointcutFactory->getInstance(array_pop($annotation->values));
                 if ($pointcut instanceof PointcutPointcut) {
                     // get the referenced pointcuts for the split parts of the expression
                     $expressionParts = explode(PointcutPointcut::EXPRESSION_CONNECTOR, $pointcut->getExpression());
                     // lookup all the referenced pointcuts
                     $referencedPointcuts = array();
                     foreach ($expressionParts as $expressionPart) {
                         $referencedPointcuts = array_merge($referencedPointcuts, $this->lookupPointcuts($expressionPart));
                     }
                     $pointcut->setReferencedPointcuts($referencedPointcuts);
                 }
                 $advice->getPointcuts()->add($pointcut);
             }
             $aspect->getAdvices()->add($advice);
         }
     }
     $this->set($aspectDefinition->getQualifiedName(), $aspect);
 }
 /**
  * Initializes and returns an array with annotation instances from the
  * passed doc comment.
  *
  * @param string $docComment The doc comment to initialize the annotations from
  * @param array  $ignore     Array with annotations we want to ignore
  * @param array  $aliases    Array with aliases to create annotation instances with
  *
  * @return array The array with the ReflectionAnnotation instances loaded from the passed doc comment
  */
 public static function fromDocComment($docComment, array $ignore = array(), array $aliases = array())
 {
     // initialize the array for the annotations
     $annotations = array();
     // initialize the annotation tokenizer
     $tokenizer = new Tokenizer();
     $tokenizer->ignore($ignore);
     // parse the doc block
     $parsed = $tokenizer->parse($docComment, $aliases);
     // convert tokens and return one
     $tokens = new Tokens($parsed);
     $toArray = new ToArray();
     // register annotations with the real annotation name (not the alias)
     foreach ($toArray->convert($tokens) as $token) {
         // check if we've an annotation that matched an alias
         if (array_key_exists($token->name, $flipped = array_flip($aliases))) {
             $annotationName = $flipped[$token->name];
         } else {
             $annotationName = $token->name;
         }
         // register the annotation with the real annotation name (not the alias)
         $annotations[$annotationName] = ReflectionAnnotation::fromStdClass($token, $aliases);
     }
     // return the list with the annotation instances
     return $annotations;
 }