public function introspect(\ReflectionExtension $extension) { $classes = $functions = $constants = array(); foreach ($extension->getClasses() as $class) { assert($class instanceof \ReflectionClass); $phpClass = PhpClass::fromReflection($class); $classes[] = $phpClass; } foreach ($extension->getFunctions() as $function) { assert($function instanceof \ReflectionFunction); $phpFunction = PhpFunction::fromReflection($function); $functions[] = $phpFunction; } foreach ($extension->getConstants() as $name => $value) { $phpConstant = new PhpConstant($name); $phpConstant->setValue($value); $constants[] = $phpConstant; } return array('classes' => $classes, 'functions' => $functions, 'constants' => $constants); }
/** * Returns the value of a constant, or makes up an arbitrary value that * matches the type of the constant. * * The reasoning behind generating an arbitrary value is that for type * inference, the actual value is not important as long as we can infer the * correct type. For other types of data flow analysis it might be interesting * though; we can re-visit it then. * * @param \CG\Generator\PhpConstant $constant * * @return int|real|boolean|string|null */ private function getConstantValue(\CG\Generator\PhpConstant $constant) { if (null !== ($value = $constant->getValue())) { return $value; } if ($constant->hasAttribute('type')) { switch ($constant->getAttribute('type')) { case 'int': case 'integer': return 0; case 'double': case 'float': return 0.1; case 'bool': case 'boolean': return true; case 'string': return 'dummy'; case 'int/float/bool/enum': case '': return null; default: throw new \RuntimeException(sprintf('Unknown constant type "%s".', $constant->getAttribute('type'))); } } return null; }
/** * @param string|PhpConstant $name * @param string $value */ public function setConstant($nameOrConstant, $value = null) { if ($nameOrConstant instanceof PhpConstant) { if (null !== $value) { throw new \InvalidArgumentException('If a PhpConstant object is passed, $value must be null.'); } $name = $nameOrConstant->getName(); $constant = $nameOrConstant; } else { $name = $nameOrConstant; $constant = new PhpConstant($nameOrConstant); $constant->setValue($value); } $this->constants[$name] = $constant; return $this; }
private function tryParsingConstant(\SimpleXMLElement $doc) { foreach ($doc->xpath('//search:varlistentry') as $entryElem) { if (!isset($entryElem->term->constant)) { continue; } $name = (string) $entryElem->term->constant; if (false !== strpos($name, '::')) { list($className, $name) = explode('::', $name); $class = $this->getOrCreateClass($className); if ($class->hasConstant($name)) { continue; } $constant = new PhpConstant($name); $class->setConstant($constant); continue; } $this->constants[$name] = $constant = new PhpConstant($name); $constant->setAttribute('type', (string) $entryElem->term->type); $constant->setAttribute('relative_path', $this->file->getRelativePathname()); $this->typeRefiner->refineConstantType($constant); } }