/** * Returns a FunctionDefinition 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 FunctionDefinition object. * * @param array $tokens The token array * @param boolean $getRecursive Do we have to get the ancestral conditions as well? * * @return \AppserverIo\Doppelgaenger\Entities\Definitions\FunctionDefinition */ protected function getDefinitionFromTokens(array $tokens, $getRecursive) { // First of all we need a new FunctionDefinition to fill $functionDefinition = new FunctionDefinition(); // For our next step we would like to get the doc comment (if any) $functionDefinition->setDocBlock($this->getDocBlock($tokens, T_FUNCTION)); // Get start and end line $functionDefinition->setStartLine($this->getStartLine($tokens)); $functionDefinition->setEndLine($this->getEndLine($tokens)); // Get the function signature $functionDefinition->setIsFinal($this->hasSignatureToken($tokens, T_FINAL, T_FUNCTION)); $functionDefinition->setIsAbstract($this->hasSignatureToken($tokens, T_ABSTRACT, T_FUNCTION)); $functionDefinition->setVisibility($this->getFunctionVisibility($tokens)); $functionDefinition->setIsStatic($this->hasSignatureToken($tokens, T_STATIC, T_FUNCTION)); $functionDefinition->setName($this->getFunctionName($tokens)); $functionDefinition->setStructureName($this->currentDefinition->getQualifiedName()); // Lets also get out parameters $functionDefinition->setParameterDefinitions($this->getParameterDefinitionList($tokens)); // Do we have a private context here? If so we have to tell the annotation parser $privateContext = false; if ($functionDefinition->getVisibility() === 'private') { $privateContext = true; } // So we got our docBlock, now we can parse the precondition annotations from it $annotationParser = new AnnotationParser($this->file, $this->config, $this->tokens, $this->currentDefinition); $functionDefinition->setPreconditions($annotationParser->getConditions($functionDefinition->getDocBlock(), Requires::ANNOTATION, $privateContext)); // get the advices $functionDefinition->getPointcutExpressions()->attach($annotationParser->getPointcutExpressions($functionDefinition->getDocBlock(), Joinpoint::TARGET_METHOD, $functionDefinition->getName())); // Does this method require the use of our "old" mechanism? $functionDefinition->setUsesOld($this->usesKeyword($functionDefinition->getDocBlock(), ReservedKeywords::OLD)); // We have to get the body of the function, so we can recreate it $functionDefinition->setBody($this->getFunctionBody($tokens)); // So we got our docBlock, now we can parse the postcondition annotations from it $functionDefinition->setPostconditions($annotationParser->getConditions($functionDefinition->getDocBlock(), Ensures::ANNOTATION, $privateContext)); // 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($functionDefinition); } return $functionDefinition; }