/** * 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 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 \TechDivision\PBC\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->docBlock = $this->getDocBlock($tokens, T_FUNCTION); // Get the function signature $functionDefinition->isFinal = $this->hasSignatureToken($tokens, T_FINAL, T_FUNCTION); $functionDefinition->isAbstract = $this->hasSignatureToken($tokens, T_ABSTRACT, T_FUNCTION); $functionDefinition->visibility = $this->getFunctionVisibility($tokens); $functionDefinition->isStatic = $this->hasSignatureToken($tokens, T_STATIC, T_FUNCTION); $functionDefinition->name = $this->getFunctionName($tokens); // Lets also get out parameters $functionDefinition->parameterDefinitions = $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->preconditions = $annotationParser->getConditions($functionDefinition->getDocBlock(), PBC_KEYWORD_PRE, $privateContext); // Does this method require the use of our "old" mechanism? $functionDefinition->usesOld = $this->usesKeyword($functionDefinition->getDocBlock(), PBC_KEYWORD_OLD); // We have to get the body of the function, so we can recreate it $functionDefinition->body = $this->getFunctionBody($tokens); // So we got our docBlock, now we can parse the postcondition annotations from it $functionDefinition->postconditions = $annotationParser->getConditions($functionDefinition->getDocBlock(), PBC_KEYWORD_POST, $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); } // All done? Then lock the definition to make it a DTO $functionDefinition->lock(); return $functionDefinition; }
/** * 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; }