/** * Parse assertions which are a collection of others * * @param string $connective How are they combined? E.g. "||" * @param \stdClass $annotation The annotation to create chained assertions from * * @return \AppserverIo\Doppelgaenger\Entities\Assertions\ChainedAssertion */ protected function createChainedAssertion($connective, \stdClass $annotation) { // Get all the parts of the string $assertionArray = explode(' ', $annotation->values['typeHint']); // Check all string parts for the | character $combinedPart = ''; $combinedIndex = 0; foreach ($assertionArray as $key => $assertionPart) { // Check which part contains the | but does not only consist of it if ($this->filterOrCombinator($assertionPart) && trim($assertionPart) !== $connective) { $combinedPart = trim($assertionPart); $combinedIndex = $key; break; } } // Now we have to create all the separate assertions for each part of the $combinedPart string $assertionList = new AssertionList(); foreach (explode($connective, $combinedPart) as $partString) { // Rebuild the assertion string with one partial string of the combined part $tmp = $assertionArray; $tmp[$combinedIndex] = $partString; $annotation->values['typeHint'] = $partString; $assertion = $this->getInstance($annotation); if (is_bool($assertion)) { continue; } else { $assertionList->add($assertion); } } // We got everything. Create a ChainedAssertion instance return new ChainedAssertion($assertionList, '||'); }
/** * Will get the conditions for a certain assertion indicating keyword like @requires or, if configured, @param * * @param string $docBlock The DocBlock to search in * @param string $conditionKeyword The keyword we are searching for, use assertion defining tags here! * @param boolean|null $privateContext If we have to mark the parsed annotations as having a private context * as we would have trouble finding out for ourselves. * * @return boolean|\AppserverIo\Doppelgaenger\Entities\Lists\AssertionList */ public function getConditions($docBlock, $conditionKeyword, $privateContext = null) { // There are only 3 valid condition types if ($conditionKeyword !== Requires::ANNOTATION && $conditionKeyword !== Ensures::ANNOTATION && $conditionKeyword !== Invariant::ANNOTATION) { return false; } // get the annotations for the passed condition keyword $annotations = $this->getAnnotationsByType($docBlock, $conditionKeyword); // if we have to enforce basic type safety we need some more annotations if ($this->config->getValue('enforcement/enforce-default-type-safety') === true) { // lets switch the switch ($conditionKeyword) { case Ensures::ANNOTATION: // we have to consider @return annotations as well $annotations = array_merge($annotations, $this->getAnnotationsByType($docBlock, 'return')); break; case Requires::ANNOTATION: // we have to consider @param annotations as well $annotations = array_merge($annotations, $this->getAnnotationsByType($docBlock, 'param')); break; default: break; } } // lets build up the result array $assertionFactory = new AssertionFactory(); $result = new AssertionList(); foreach ($annotations as $annotation) { // try to create assertion instances for all annotations try { $assertion = $assertionFactory->getInstance($annotation); } catch (\Exception $e) { error_log($e->getMessage()); continue; } if ($assertion !== false) { // Do we already got a private context we can set? If not we have to find out four ourselves if ($privateContext !== null) { // Add the context (wether private or not) $assertion->setPrivateContext($privateContext); } else { // Add the context (private or not) $this->determinePrivateContext($assertion); } // finally determine the minimal scope of this assertion and add it to our result $this->determineMinimalScope($assertion); $result->add($assertion); } } return $result; }