/** * Convert a ClassModel into an array of statements for the php parser * * @param ClassModel $classModel * @return array */ public function transform(ClassModel $classModel) { // create namespace $namespace = $this->factory->namespace($classModel->getNamespace()); // create class $class = $this->factory->class($classModel->getName()); $class->implement($classModel->getInterface()); // add class properties foreach ($classModel->getProperties() as $propertyModel) { $property = $this->factory->property($propertyModel->getName()); $property->setDefault($propertyModel->getDefaultValue()); switch ($propertyModel->getVisibility()) { case PropertyModel::VISIBILITY_PUBLIC: $property->makePublic(); break; case PropertyModel::VISIBILITY_PROTECTED: $property->makeProtected(); break; case PropertyModel::VISIBILITY_PRIVATE: $property->makePrivate(); break; default: throw new UnexpectedValueException('Property visibility must be public, protected, private'); } // add property to class $class->addStmt($property); } // add class methods foreach ($classModel->getMethods() as $methodModel) { $method = $this->factory->method($methodModel->getName()); $method->makePublic(); // add method body $body = '<?php ' . $methodModel->getBody(); $methodStatements = $this->parser->parse($body); if (null !== $methodStatements) { $methodStatements = $this->nodeTraverser->traverse($methodStatements); $method->addStmts($methodStatements); } // add method parameters foreach ($methodModel->getParameters() as $parameterModel) { $parameter = $this->factory->param($parameterModel->getName()); if ($parameterModel->hasTypeHint()) { $parameter->setTypeHint($parameterModel->getTypeHint()); } if ($parameterModel->isOptional()) { $parameter->setDefault($parameterModel->getDefaultValue()); } $method->addParam($parameter); } // add method to class $class->addStmt($method); } // add class to namespace $namespace->addStmt($class); // return an array of statements return [$namespace->getNode()]; }
/** * Create wait method * * @param ClassModel $classModel * @return null */ private function addWait(ClassModel $classModel) { $reflectionClass = new \ReflectionClass($classModel->getInterface()); if (!in_array('Tebru\\Retrofit\\Http\\AsyncAware', $reflectionClass->getInterfaceNames(), true)) { return null; } $methodModel = new MethodModel($classModel, 'wait'); $methodModel->setBody('$this->client->wait();'); $classModel->addMethod($methodModel); }
/** * Write the model to a file * * @param ClassModel $classModel */ public function write(ClassModel $classModel) { // create cache directory and get filename $path = $this->cacheDir . $this->interfaceToPath($classModel->getInterface()); $this->filesystem->mkdir($path); $filename = $path . DIRECTORY_SEPARATOR . $classModel->getName() . '.php'; // convert class model to string $statements = $this->classModelTransformer->transform($classModel); $class = $this->printer->prettyPrintFile($statements); // write file $this->filesystem->dumpFile($filename, $class); }
/** * Create constructor * * @param ClassModel $classModel */ private function addConstructor(ClassModel $classModel) { $methodModel = new MethodModel($classModel, '__construct'); $baseUrl = new ParameterModel($methodModel, 'baseUrl', false); $client = new ParameterModel($methodModel, 'client', false); $client->setTypeHint('\\Tebru\\Retrofit\\Adapter\\HttpClientAdapter'); $serializer = new ParameterModel($methodModel, 'serializer', false); $serializer->setTypeHint('\\JMS\\Serializer\\SerializerInterface'); $eventDispatcher = new ParameterModel($methodModel, 'eventDispatcher', false); $eventDispatcher->setTypeHint('\\Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); $methodModel->addParameter($baseUrl); $methodModel->addParameter($client); $methodModel->addParameter($serializer); $methodModel->addParameter($eventDispatcher); $methodBody = ['$this->baseUrl = $baseUrl;', '$this->client = $client;', '$this->serializer = $serializer;', '$this->eventDispatcher = $eventDispatcher;']; $methodModel->setBody(implode($methodBody)); $classModel->addMethod($methodModel); }