/** * 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)); }