示例#1
0
文件: Compiler.php 项目: krecek/nrsn
	public function generateCode($className, $parentName)
	{
		foreach ($this->extensions as $extension) {
			$extension->beforeCompile();
			$this->container->addDependency(NClassReflection::from($extension)->getFileName());
		}

		$classes[] = $class = $this->container->generateClass($parentName);
		$class->setName($className)
			->addMethod('initialize');

		foreach ($this->extensions as $extension) {
			$extension->afterCompile($class);
		}

		$defs = $this->container->getDefinitions();
		ksort($defs);
		$list = array_keys($defs);
		foreach (array_reverse($defs, TRUE) as $name => $def) {
			if ($def->class === 'NDINestedAccessor' && ($found = preg_grep('#^'.$name.'\.#i', $list))) {
				$list = array_diff($list, $found);
				$def->class = $className . '_' . preg_replace('#\W+#', '_', $name);
				$class->documents = preg_replace("#\\S+(?= \\$$name\\z)#", $def->class, $class->documents);
				$classes[] = $accessor = new NPhpClassType($def->class);
				foreach ($found as $item) {
					if ($defs[$item]->internal) {
						continue;
					}
					$short = substr($item, strlen($name)  + 1);
					$accessor->addDocument($defs[$item]->shared
						? "@property {$defs[$item]->class} \$$short"
						: "@method {$defs[$item]->class} create" . ucfirst("$short()"));
				}
			}
		}

		return implode("\n\n\n", $classes);
	}
	/**
	 * Generates PHP class.
	 * @return NPhpClassType
	 */
	public function generateClass($parentClass = 'NDIContainer')
	{
		unset($this->definitions[self::THIS_CONTAINER]);
		$this->addDefinition(self::THIS_CONTAINER)->setClass($parentClass);

		$this->prepareClassList();

		$class = new NPhpClassType('Container');
		$class->addExtend($parentClass);
		$class->addMethod('__construct')
			->addBody('parent::__construct(?);', array($this->expand($this->parameters)));

		$classes = $class->addProperty('classes', array());
		foreach ($this->classes as $name => $foo) {
			try {
				$classes->value[$name] = $this->sanitizeName($this->getByType($name));
			} catch (NServiceCreationException $e) {
				$classes->value[$name] = new NPhpLiteral('FALSE, //' . strstr($e->getMessage(), ':'));
			}
		}

		$meta = $class->addProperty('meta', array());
		foreach ($this->definitions as $name => $def) {
			foreach ($this->expand($def->tags) as $tag => $value) {
				$meta->value[$name][NDIContainer::TAGS][$tag] = $value;
			}
		}

		foreach ($this->definitions as $name => $def) {
			try {
				$type = ($tmp=$def->class) ? $tmp : 'object';
				$sanitized = $this->sanitizeName($name);
				if (!NPhpHelpers::isIdentifier($sanitized)) {
					throw new NServiceCreationException('Name contains invalid characters.');
				}
				if ($def->shared && $name === $sanitized) {
					$class->addDocument("@property $type \$$name");
				}
				$method = $class->addMethod(($def->shared ? 'createService' : 'create') . ucfirst($sanitized))
					->addDocument("@return $type")
					->setVisibility($def->shared || $def->internal ? 'protected' : 'public')
					->setBody($name === self::THIS_CONTAINER ? 'return $this;' : $this->generateService($name));

				foreach ($this->expand($def->parameters) as $k => $v) {
					$tmp = explode(' ', is_int($k) ? $v : $k);
					$param = is_int($k) ? $method->addParameter(end($tmp)) : $method->addParameter(end($tmp), $v);
					if (isset($tmp[1])) {
						$param->setTypeHint($tmp[0]);
					}
				}
			} catch (Exception $e) {
				throw new NServiceCreationException("Service '$name': " . $e->getMessage());
			}
		}

		return $class;
	}