Example #1
0
 /**
  * Returns a property/parameter/constant/static variable value definition.
  *
  * @param array $tokens Tokenized definition
  * @param \TokenReflection\ReflectionElement $reflection Caller reflection
  * @return string
  * @throws \TokenReflection\Exception\RuntimeException If an invalid reflection object was provided.
  * @throws \TokenReflection\Exception\RuntimeException If an invalid source code was provided.
  */
 public static final function getValueDefinition(array $tokens, ReflectionElement $reflection)
 {
     if ($reflection instanceof ReflectionConstant || $reflection instanceof ReflectionFunction) {
         $namespace = $reflection->getNamespaceName();
     } elseif ($reflection instanceof ReflectionParameter) {
         $namespace = $reflection->getDeclaringFunction()->getNamespaceName();
     } elseif ($reflection instanceof ReflectionProperty || $reflection instanceof ReflectionMethod) {
         $namespace = $reflection->getDeclaringClass()->getNamespaceName();
     } else {
         throw new Exception\RuntimeException('Invalid reflection object given.', Exception\RuntimeException::INVALID_ARGUMENT, $reflection);
     }
     // Process __LINE__ constants; replace with the line number of the corresponding token
     foreach ($tokens as $index => $token) {
         if (T_LINE === $token[0]) {
             $tokens[$index] = array(T_LNUMBER, $token[2], $token[2]);
         }
     }
     $source = self::getSourceCode($tokens);
     $constants = self::findConstants($tokens, $reflection);
     if (!empty($constants)) {
         foreach (array_reverse($constants, true) as $offset => $constant) {
             $value = '';
             try {
                 switch ($constant) {
                     case '__FILE__':
                         $value = $reflection->getFileName();
                         break;
                     case '__DIR__':
                         $value = dirname($reflection->getFileName());
                         break;
                     case '__FUNCTION__':
                         if ($reflection instanceof IReflectionParameter) {
                             $value = $reflection->getDeclaringFunctionName();
                         } elseif ($reflection instanceof IReflectionFunctionBase) {
                             $value = $reflection->getName();
                         }
                         break;
                     case '__CLASS__':
                         if ($reflection instanceof IReflectionConstant || $reflection instanceof IReflectionParameter || $reflection instanceof IReflectionProperty || $reflection instanceof IReflectionMethod) {
                             $value = $reflection->getDeclaringClassName() ?: '';
                         }
                         break;
                     case '__TRAIT__':
                         if ($reflection instanceof IReflectionMethod || $reflection instanceof IReflectionProperty) {
                             $value = $reflection->getDeclaringTraitName() ?: '';
                         } elseif ($reflection instanceof IReflectionParameter) {
                             $method = $reflection->getDeclaringFunction();
                             if ($method instanceof IReflectionMethod) {
                                 $value = $method->getDeclaringTraitName() ?: '';
                             }
                         }
                         break;
                     case '__METHOD__':
                         if ($reflection instanceof IReflectionParameter) {
                             if (null !== $reflection->getDeclaringClassName()) {
                                 $value = $reflection->getDeclaringClassName() . '::' . $reflection->getDeclaringFunctionName();
                             } else {
                                 $value = $reflection->getDeclaringFunctionName();
                             }
                         } elseif ($reflection instanceof IReflectionConstant || $reflection instanceof IReflectionProperty) {
                             $value = $reflection->getDeclaringClassName() ?: '';
                         } elseif ($reflection instanceof IReflectionMethod) {
                             $value = $reflection->getDeclaringClassName() . '::' . $reflection->getName();
                         } elseif ($reflection instanceof IReflectionFunction) {
                             $value = $reflection->getName();
                         }
                         break;
                     case '__NAMESPACE__':
                         if ($reflection instanceof IReflectionConstant && null !== $reflection->getDeclaringClassName() || $reflection instanceof IReflectionProperty) {
                             $value = $reflection->getDeclaringClass()->getNamespaceName();
                         } elseif ($reflection instanceof IReflectionParameter) {
                             if (null !== $reflection->getDeclaringClassName()) {
                                 $value = $reflection->getDeclaringClass()->getNamespaceName();
                             } else {
                                 $value = $reflection->getDeclaringFunction()->getNamespaceName();
                             }
                         } elseif ($reflection instanceof IReflectionMethod) {
                             $value = $reflection->getDeclaringClass()->getNamespaceName();
                         } else {
                             $value = $reflection->getNamespaceName();
                         }
                         break;
                     default:
                         if (0 === stripos($constant, 'self::') || 0 === stripos($constant, 'parent::')) {
                             // Handle self:: and parent:: definitions
                             if ($reflection instanceof ReflectionConstant && null === $reflection->getDeclaringClassName()) {
                                 throw new Exception\RuntimeException('Top level constants cannot use self:: and parent:: references.', Exception\RuntimeException::UNSUPPORTED, $reflection);
                             } elseif ($reflection instanceof ReflectionParameter && null === $reflection->getDeclaringClassName()) {
                                 throw new Exception\RuntimeException('Function parameters cannot use self:: and parent:: references.', Exception\RuntimeException::UNSUPPORTED, $reflection);
                             }
                             if (0 === stripos($constant, 'self::')) {
                                 $className = $reflection->getDeclaringClassName();
                             } else {
                                 $declaringClass = $reflection->getDeclaringClass();
                                 $className = $declaringClass->getParentClassName() ?: self::CONSTANT_NOT_FOUND;
                             }
                             $constantName = $className . substr($constant, strpos($constant, '::'));
                         } else {
                             $constantName = self::resolveClassFQN($constant, $reflection->getNamespaceAliases(), $namespace);
                             if ($cnt = strspn($constant, '\\')) {
                                 $constantName = str_repeat('\\', $cnt) . $constantName;
                             }
                         }
                         $constantReflection = $reflection->getBroker()->getConstant($constantName);
                         $value = $constantReflection->getValue();
                 }
             } catch (Exception\RuntimeException $e) {
                 $value = self::CONSTANT_NOT_FOUND;
             }
             $source = substr_replace($source, var_export($value, true), $offset, strlen($constant));
         }
     }
     return self::evaluate(sprintf("return %s;\n", $source));
 }