/** * Compile and get container * * @param DefinitionBuilder $definitionBuilder * @return string Get container code * @throws ReferenceNotImplementsException * @throws \InvalidArgumentException */ public function generateClass(DefinitionBuilder $definitionBuilder) : string { // Generate parameters if exists if (count($definitionBuilder->getParameterCollection())) { $parameterMethodGenerator = $this->generator->defMethod('parameter')->defProtected()->defArgument('parameterName'); $isFirstCondition = true; // Generate parameters foreach ($definitionBuilder->getParameterCollection() as $parameterName => $reference) { $parameterMethodGenerator->defLine($this->generateParameterCondition($parameterName, $reference, $isFirstCondition)); $isFirstCondition = false; } // Close method $parameterMethodGenerator->end(); } $methodGenerator = $this->generator->defMethod('logic')->defProtected()->defArgument('classNameOrServiceName')->defLine('static $singletonCollection = [];'); $scopes = []; $isFirstCondition = true; /** @var ClassDefinition $classDefinition */ foreach ($definitionBuilder->getDefinitionCollection() as $classDefinition) { // Get scopes foreach ($classDefinition->getScopes() as $scope) { $id = $scope::getId(); if (!array_key_exists($id, $scopes)) { $scopes[$id] = []; } // Store definition id $scopes[$id][] = $classDefinition->getServiceName() ?: $classDefinition->getClassName(); } $className = $classDefinition->getClassName(); $serviceName = $classDefinition->getServiceName(); // Name for static service collection $serviceId = $serviceName ?? $className; // Generate if condition by class name or value $methodGenerator->defLine($this->generateStartIfCondition($isFirstCondition, $className, $serviceName)); // Generate static property service access if service is singleton // TODO Move this from if condition if ($classDefinition->isSingleton()) { $methodGenerator->defLine($this->generateStaticFunctionCall($serviceId)); } // Generate constructor call if not $methodGenerator->defLine($this->generateConstructor($classDefinition)); // Generate methods foreach ($classDefinition->getMethodsCollection() as $methodDefinition) { // Constructor is not a method skip it if ($methodDefinition->getMethodName() !== '__construct') { $methodGenerator->defLine($this->generateSetters($classDefinition, $methodDefinition)); } } // Generate properties foreach ($classDefinition->getPropertiesCollection() as $propertyDefinition) { // Generate properties $methodGenerator->defLine($this->generateProperty($classDefinition, $propertyDefinition)); } // Generate return operator $methodGenerator->defLine($this->generateReturnOperator($classDefinition, $serviceId)); // Close if $methodGenerator->defLine($this->generateEndIfCondition()); $isFirstCondition = false; } // Generate if condition by class name or value $methodGenerator->defLine($this->generateStartIfCondition(false, '\\' . $this->generator->getNamespace() . '\\' . $this->generator->getClassName(), self::CONTAINER_DEPENDENCY_NAME)); // Return container $methodGenerator->defLine("\treturn \$this;"); // Close if $methodGenerator->defLine($this->generateEndIfCondition()); // Close method $methodGenerator->end(); // Generate constructor $constructorGenerator = $this->generator->defMethod('__construct'); // Generate scope list $this->generateScopeList($constructorGenerator, $scopes); // Close constructor $constructorGenerator->end(); return "<?php \n" . $this->generator->code(); }
public function testDefDefClassName() { $classGenerator = new ClassGenerator(); $generated = $classGenerator->defName('testClass')->defNamespace('\\test\\space')->code(); $expected = <<<'PHP' namespace \test\space; class testClass { } PHP; static::assertEquals($expected, $generated); }