Пример #1
0
 /**
  * @param \PhpParser\Node\Stmt\Class_ $classNode
  * @return \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject
  */
 public function buildClassObject(\PhpParser\Node\Stmt\Class_ $classNode)
 {
     $classObject = new Model\ClassObject\ClassObject($classNode->name);
     foreach ($classNode->implements as $interfaceNode) {
         $classObject->addInterfaceName($interfaceNode, false);
     }
     $classObject->setModifiers($classNode->type);
     if (!is_null($classNode->extends)) {
         $classObject->setParentClassName(NodeConverter::getValueFromNode($classNode->extends));
     }
     $this->addCommentsFromAttributes($classObject, $classNode);
     return $classObject;
 }
Пример #2
0
 /**
  * @param \PhpParser\Node $node
  */
 public function leaveNode(\PhpParser\Node $node)
 {
     array_pop($this->contextStack);
     if ($this->isContainerNode(end($this->contextStack)) || count($this->contextStack) === 0) {
         // we are on the first level
         if ($node instanceof Node\Stmt\Class_) {
             if (count($this->contextStack) > 0) {
                 if (end($this->contextStack)->getType() == 'Stmt_Namespace') {
                     $currentNamespaceName = NodeConverter::getValueFromNode(end($this->contextStack));
                     $this->currentClassObject->setNamespaceName($currentNamespaceName);
                     $this->currentNamespace->addClass($this->currentClassObject);
                 }
             } else {
                 $this->fileObject->addClass($this->currentClassObject);
                 $this->currentClassObject = null;
                 $this->currentContainer = $this->fileObject;
             }
         } elseif ($node instanceof Node\Stmt\Namespace_) {
             if (null !== $this->currentNamespace) {
                 $this->fileObject->addNamespace($this->currentNamespace);
                 $this->currentNamespace = null;
                 $this->currentContainer = $this->fileObject;
             } else {
                 //TODO: find how this could happen
             }
         } elseif ($node instanceof Node\Stmt\TraitUse) {
             if ($this->currentClassObject) {
                 $this->currentClassObject->addUseTraitStatement($node);
             }
         } elseif ($node instanceof Node\Stmt\Use_) {
             $this->currentContainer->addAliasDeclaration(NodeConverter::convertUseAliasStatementNodeToArray($node));
         } elseif ($node instanceof Node\Stmt\ClassConst) {
             $constants = NodeConverter::convertClassConstantNodeToArray($node);
             foreach ($constants as $constant) {
                 $this->currentContainer->setConstant($constant['name'], $constant['value']);
             }
         } elseif ($node instanceof Node\Stmt\ClassMethod) {
             $this->onFirstLevel = true;
             $method = $this->classFactory->buildClassMethodObject($node);
             $this->currentClassObject->addMethod($method);
         } elseif ($node instanceof Node\Stmt\Property) {
             $property = $this->classFactory->buildPropertyObject($node);
             $this->currentClassObject->addProperty($property);
         } elseif ($node instanceof Node\Stmt\Function_) {
             $this->onFirstLevel = true;
             $function = $this->classFactory->buildFunctionObject($node);
             $this->currentContainer->addFunction($function);
         } elseif (!$node instanceof Node\Name) {
             // any other nodes (except the name node of the current container node)
             // go into statements container
             if ($this->currentContainer->getFirstClass() === false) {
                 $this->currentContainer->addPreClassStatements($node);
             } else {
                 $this->currentContainer->addPostClassStatements($node);
             }
         }
     }
 }
Пример #3
0
 /**
  * @param \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject $classObject
  * @param bool $skipStatements
  * @return \PhpParser\Node\Stmt\Class_
  */
 public function buildClassNode($classObject, $skipStatements = FALSE)
 {
     $factory = new \PhpParser\BuilderFactory();
     $classNodeBuilder = $factory->class($classObject->getName());
     if ($classObject->getParentClassName()) {
         $classNodeBuilder->extend(self::buildNodeFromName($classObject->getParentClassName()));
     }
     $interfaceNames = $classObject->getInterfaceNames();
     if (count($interfaceNames) > 0) {
         call_user_func_array(array($classNodeBuilder, 'implement'), $interfaceNames);
     }
     if (!$skipStatements) {
         $stmts = array();
         $properties = array();
         $methods = array();
         foreach ($classObject->getMethods() as $method) {
             $methods[$method->getName()] = $this->buildMethodNode($method);
         }
         foreach ($classObject->getProperties() as $property) {
             $properties[$property->getName()] = $this->buildPropertyNode($property);
         }
         $constants = $classObject->getConstants();
         if (is_array($constants)) {
             foreach ($constants as $name => $value) {
                 $stmts[] = self::buildClassConstantNode($name, $value);
             }
         }
         foreach ($properties as $property) {
             $stmts[] = $property;
         }
         foreach ($methods as $method) {
             $stmts[] = $method;
         }
         $classNodeBuilder->addStmts($stmts);
     }
     $classNode = $classNodeBuilder->getNode();
     $classNode->type = $classObject->getModifiers();
     $this->addCommentAttributes($classObject, $classNode);
     return $classNode;
 }
Пример #4
0
 /**
  * Not used right now
  * TODO: Needs better implementation
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject
  * @return void
  */
 public function sortMethods($domainObject)
 {
     $objectProperties = $domainObject->getProperties();
     $sortedProperties = array();
     $propertyRelatedMethods = array();
     $customMethods = array();
     // sort all properties and methods according to domainObject sort order
     foreach ($objectProperties as $objectProperty) {
         if ($this->classObject->propertyExists($objectProperty->getName())) {
             $sortedProperties[$objectProperty->getName()] = $this->classObject->getProperty($objectProperty->getName());
             $methodPrefixes = array('get', 'set', 'add', 'remove', 'is');
             foreach ($methodPrefixes as $methodPrefix) {
                 $methodName = self::getMethodName($objectProperty, $methodPrefix);
                 if ($this->classObject->methodExists($methodName)) {
                     $propertyRelatedMethods[$methodName] = $this->classObject->getMethod($methodName);
                 }
             }
         }
     }
     // add the properties that were not in the domainObject
     $classProperties = $this->classObject->getProperties();
     $sortedPropertyNames = array_keys($sortedProperties);
     foreach ($classProperties as $classProperty) {
         if (!in_array($classProperty->getName(), $sortedProperties)) {
             $sortedProperties[$classProperty->getName()] = $classProperty;
         }
     }
     // add custom methods that were manually added to the class
     $classMethods = $this->classObject->getMethods();
     $propertyRelatedMethodNames = array_keys($propertyRelatedMethods);
     foreach ($classMethods as $classMethod) {
         if (!in_array($classMethod->getName(), $propertyRelatedMethodNames)) {
             $customMethods[$classMethod->getName()] = $classMethod;
         }
     }
     $sortedMethods = array_merge($customMethods, $propertyRelatedMethods);
     $this->classObject->setProperties($sortedProperties);
     $this->classObject->setMethods($sortedMethods);
 }
Пример #5
0
 /**
  * compares the number of properties found by parsing
  * with those retrieved from the reflection class
  *
  * @param \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject $classObject
  * @param \TYPO3\CMS\Extbase\Reflection\ClassReflection $classReflection
  * @return void
  */
 public function ParserFindsAllProperties($classObject, $classReflection)
 {
     $reflectionPropertyCount = count($classReflection->getProperties());
     $classObjectPropertCount = count($classObject->getProperties());
     $this->assertEquals($classObjectPropertCount, $reflectionPropertyCount, 'Not all Properties were found!');
 }
Пример #6
0
 /**
  * generate a docComment for class files. Add a license haeder if none found
  * @param \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject $classObject
  *
  * @return void;
  */
 protected function addLicenseHeader($classObject)
 {
     $comments = $classObject->getComments();
     $needsLicenseHeader = true;
     foreach ($comments as $comment) {
         if (strpos($comment, 'GNU General Public License') !== false) {
             $needsLicenseHeader = false;
         }
     }
     if ($needsLicenseHeader) {
         $licenseHeader = $this->renderTemplate('Partials/Classes/licenseHeader.phpt', array('persons' => $this->extension->getPersons()));
         $classObject->addComment($licenseHeader);
     }
 }
Пример #7
0
 /**
  * update means renaming of method name, parameter and replacing
  * parameter names in method body
  *
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty
  * @param string $methodType get,set,add,remove,is
  *
  * @return void
  */
 protected function updateMethod($oldProperty, $newProperty, $methodType)
 {
     $oldMethodName = ClassBuilder::getMethodName($oldProperty, $methodType);
     // the method to be merged
     $mergedMethod = $this->classObject->getMethod($oldMethodName);
     if (!$mergedMethod) {
         // no previous version of the method exists
         return;
     }
     $newMethodName = ClassBuilder::getMethodName($newProperty, $methodType);
     $this->log('updateMethod:' . $oldMethodName . '=>' . $newMethodName, 'extension_builder');
     if ($oldProperty->getName() != $newProperty->getName()) {
         // rename the method
         $mergedMethod->setName($newMethodName);
         $oldMethodBody = $mergedMethod->getBodyStmts();
         $oldComment = $mergedMethod->getDocComment();
         $newMethodBody = $this->replacePropertyNameInMethodBody($oldProperty->getName(), $newProperty->getName(), $oldMethodBody);
         $mergedMethod->setBodyStmts($newMethodBody);
     }
     // update the method parameters
     $methodParameters = $mergedMethod->getParameters();
     if (!empty($methodParameters)) {
         $parameterTags = $mergedMethod->getTagValues('param');
         foreach ($methodParameters as $methodParameter) {
             $oldParameterName = $methodParameter->getName();
             if ($oldParameterName == ClassBuilder::getParameterName($oldProperty, $methodType)) {
                 $newParameterName = ClassBuilder::getParameterName($newProperty, $methodType);
                 $methodParameter->setName($newParameterName);
                 $newMethodBody = $this->replacePropertyNameInMethodBody($oldParameterName, $newParameterName, $mergedMethod->getBodyStmts());
                 $mergedMethod->setBodyStmts($newMethodBody);
             }
             $typeHint = $methodParameter->getTypeHint();
             if ($typeHint) {
                 if ($oldProperty->isRelation()) {
                     /** @var $oldProperty \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\AbstractRelation */
                     if ($typeHint == $oldProperty->getForeignClassName()) {
                         $methodParameter->setTypeHint($this->updateExtensionKey($this->getForeignClassName($newProperty)));
                     }
                 }
             }
             $parameterTags[$methodParameter->getPosition()] = ClassBuilder::getParamTag($newProperty, $methodType);
             $mergedMethod->replaceParameter($methodParameter);
         }
         $mergedMethod->setTag('param', $parameterTags);
     }
     $returnTagValue = $mergedMethod->getTagValue('return');
     if ($returnTagValue != 'void') {
         $mergedMethod->setTag('return', $newProperty->getTypeForComment() . ' ' . $newProperty->getName());
     }
     // replace property names in description
     $mergedMethod->setDescription(str_replace($oldProperty->getName(), $newProperty->getName(), $mergedMethod->getDescription()));
     if ($oldProperty instanceof AbstractRelation && $newProperty instanceof AbstractRelation) {
         $mergedMethod->setDescription(str_replace($oldProperty->getForeignClassName(), $newProperty->getForeignClassName(), $mergedMethod->getDescription()));
     }
     $this->classObject->removeMethod($oldMethodName);
     $this->classObject->addMethod($mergedMethod);
 }
Пример #8
0
 /**
  * generate a docComment for class files. Add a license header if none found
  * @param \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject $classObject
  *
  * @return void;
  */
 protected function addLicenseHeader($classObject)
 {
     $comments = $classObject->getComments();
     $needsLicenseHeader = true;
     foreach ($comments as $comment) {
         if (strpos($comment, 'license information') !== false) {
             $needsLicenseHeader = false;
         }
     }
     $extensionSettings = $this->extension->getSettings();
     if ($needsLicenseHeader && empty($extensionSettings['skipDocComment'])) {
         $licenseHeader = $this->renderTemplate('Partials/Classes/licenseHeader.phpt', array('extension' => $this->extension));
         $classObject->addComment($licenseHeader);
     }
 }