/**
  * Returns a ClassDefinition from a token array.
  *
  * This method will use a set of other methods to parse a token array and retrieve any
  * possible information from it. This information will be entered into a ClassDefinition object.
  *
  * @param array   $tokens       The token array
  * @param boolean $getRecursive Do we have to load the inherited contracts as well?
  *
  * @return \TechDivision\PBC\Entities\Definitions\InterfaceDefinition
  */
 protected function getDefinitionFromTokens($tokens, $getRecursive = true)
 {
     // First of all we need a new ClassDefinition to fill
     $this->currentDefinition = new InterfaceDefinition();
     // Save the path of the original definition for later use
     $this->currentDefinition->path = $this->file;
     // Get the interfaces own namespace and the namespace which are included via use
     $this->currentDefinition->namespace = $this->getNamespace();
     $this->currentDefinition->usedNamespaces = $this->getUsedNamespaces();
     // For our next step we would like to get the doc comment (if any)
     $this->currentDefinition->docBlock = $this->getDocBlock($tokens, T_INTERFACE);
     // Get the interface identity
     $this->currentDefinition->name = $this->getName($tokens);
     // So we got our docBlock, now we can parse the invariant annotations from it
     $annotationParser = new AnnotationParser($this->file, $this->config, $this->tokens);
     $this->currentDefinition->invariantConditions = $annotationParser->getConditions($this->currentDefinition->docBlock, PBC_KEYWORD_INVARIANT);
     // Lets check if there is any inheritance, or if we implement any interfaces
     $parentNames = $this->getParents($tokens);
     if (count($this->currentDefinition->usedNamespaces) === 0) {
         foreach ($parentNames as $parentName) {
             if (strpos($parentName, '\\') !== false) {
                 $this->currentDefinition->extends[] = $parentName;
             } else {
                 $this->currentDefinition->extends[] = '\\' . $this->currentDefinition->namespace . '\\' . $parentName;
             }
         }
     } else {
         foreach ($this->currentDefinition->usedNamespaces as $alias) {
             foreach ($parentNames as $parentName) {
                 if (strpos($alias, $parentName) !== false) {
                     $this->currentDefinition->extends = '\\' . $alias;
                 }
             }
         }
     }
     // Clean possible double-\
     $this->currentDefinition->extends = str_replace('\\\\', '\\', $this->currentDefinition->extends);
     $this->currentDefinition->constants = $this->getConstants($tokens);
     // Only thing still missing are the methods, so ramp up our FunctionParser
     $functionParser = new FunctionParser($this->file, $this->config, $this->structureDefinitionHierarchy, $this->structureMap, $this->currentDefinition, $this->tokens);
     $this->currentDefinition->functionDefinitions = $functionParser->getDefinitionListFromTokens($tokens);
     return $this->currentDefinition;
 }
 /**
  * Returns a ClassDefinition from a token array.
  *
  * This method will use a set of other methods to parse a token array and retrieve any
  * possible information from it. This information will be entered into a ClassDefinition object.
  *
  * @param array   $tokens       The token array containing structure tokens
  * @param boolean $getRecursive Do we have to get the ancestral conditions as well?
  *
  * @return \TechDivision\PBC\Interfaces\StructureDefinitionInterface
  */
 protected function getDefinitionFromTokens($tokens, $getRecursive = true)
 {
     // First of all we need a new ClassDefinition to fill
     $this->currentDefinition = new ClassDefinition();
     // Save the path of the original definition for later use
     $this->currentDefinition->path = $this->file;
     // File based namespaces do not make much sense, so hand it over here.
     $this->currentDefinition->namespace = $this->getNamespace();
     $this->currentDefinition->name = $this->getName($tokens);
     $this->currentDefinition->usedNamespaces = $this->getUsedNamespaces();
     // For our next step we would like to get the doc comment (if any)
     $this->currentDefinition->docBlock = $this->getDocBlock($tokens, T_CLASS);
     // Lets get the attributes the class might have
     $this->currentDefinition->attributeDefinitions = $this->getAttributes($tokens);
     // So we got our docBlock, now we can parse the invariant annotations from it
     $annotationParser = new AnnotationParser($this->file, $this->config, $this->tokens, $this->currentDefinition);
     $this->currentDefinition->invariantConditions = $annotationParser->getConditions($this->currentDefinition->getDocBlock(), PBC_KEYWORD_INVARIANT);
     // Get the class identity
     $this->currentDefinition->isFinal = $this->hasSignatureToken($this->tokens, T_FINAL, T_CLASS);
     $this->currentDefinition->isAbstract = $this->hasSignatureToken($this->tokens, T_ABSTRACT, T_CLASS);
     // Lets check if there is any inheritance, or if we implement any interfaces
     $this->currentDefinition->extends = trim($this->resolveUsedNamespace($this->currentDefinition, $this->getParent($tokens)), '\\');
     // Get all the interfaces we have
     $this->currentDefinition->implements = $this->getInterfaces($this->currentDefinition);
     // Get all class constants
     $this->currentDefinition->constants = $this->getConstants($tokens);
     // Only thing still missing are the methods, so ramp up our FunctionParser
     $functionParser = new FunctionParser($this->file, $this->config, $this->structureDefinitionHierarchy, $this->structureMap, $this->currentDefinition, $this->tokens);
     $this->currentDefinition->functionDefinitions = $functionParser->getDefinitionListFromTokens($tokens, $getRecursive);
     // If we have to parse the definition in a recursive manner, we have to get the parent invariants
     if ($getRecursive === true) {
         // Add all the assertions we might get from ancestral dependencies
         $this->addAncestralAssertions($this->currentDefinition);
     }
     // Lets get the attributes the class might have
     $this->currentDefinition->attributeDefinitions = $this->getAttributes($tokens, $this->currentDefinition->getInvariants());
     // Lock the definition
     $this->currentDefinition->lock();
     // Before exiting we will add the entry to the current structure definition hierarchy
     $this->structureDefinitionHierarchy->insert($this->currentDefinition);
     return $this->currentDefinition;
 }