/** * Will find the index of the last character within a structure * * @param string $code The structure code to search in * @param string $structureName Name of the structure to get the last index for * @param string $structureType Type of the structure in question * * @return integer */ protected function findLastStructureIndex($code, $structureName, $structureType) { // determine which keyword we should search for switch ($structureType) { case InterfaceDefinition::TYPE: $structureKeyword = 'interface'; break; case TraitDefinition::TYPE: $structureKeyword = 'trait'; break; default: $structureKeyword = 'class'; break; } // cut everything in front of the first bracket so we have a better start $matches = array(); preg_match('/.*' . $structureKeyword . '\\s+' . $structureName . '.+?{/s', $code, $matches); if (count($matches) != 1) { throw new GeneratorException(sprintf('Could not find last index for stucture %s. Cannot generate proxy skeleton.', $structureName)); } $offset = strlen(reset($matches)) - 1; // get a parser util and get the bracket span $parserUtil = new Parser(); $structureSpan = $parserUtil->getBracketSpan($code, '{', $offset); return $structureSpan + $offset - 1; }
/** * Will return a list of parameter definition objects extracted from a given token array * * @param array $tokens The token array * * @return \AppserverIo\Doppelgaenger\Entities\Lists\ParameterDefinitionList * * TODO Does this have to be this long? */ public function getParameterDefinitionList(array $tokens) { // Check the tokens $parameterString = ''; $parameterDefinitionList = new ParameterDefinitionList(); $tokenCount = count($tokens); for ($i = 0; $i < $tokenCount; $i++) { // If we got the function definition, no scan everything from the first ( to the next ) if ($tokens[$i][0] === T_FUNCTION) { $bracketPassed = null; for ($j = $i; $j < $tokenCount; $j++) { // If we got the function definition, no scan everything from the first ( to the closing ) if ($tokens[$j] === '(') { if ($bracketPassed === null) { $bracketPassed = 1; // We do not want to get this token as well. continue; } else { $bracketPassed++; } } // We got A closing bracket, decrease the counter if ($tokens[$j] === ')') { $bracketPassed--; } if ($bracketPassed > 0 && $bracketPassed !== null) { // Collect what we get if (is_array($tokens[$j])) { $parameterString .= $tokens[$j][1]; } else { $parameterString .= $tokens[$j]; } } elseif ($bracketPassed !== null) { // If we got the closing bracket we can leave both loops break 2; } } } } // Now lets analyse what we got $parameterStrings = explode(',', $parameterString); $parserUtils = new Parser(); foreach ($parameterStrings as $key => $param) { if ($parserUtils->getBracketCount($param, '(') > 0) { $param = $param . ', ' . $parameterStrings[$key + 1]; unset($parameterStrings[$key + 1]); } $param = trim($param); $paramPieces = explode('$', $param); // Get a new ParameterDefinition $parameterDefinition = new ParameterDefinition(); // we either get one or two pieces if (count($paramPieces) === 1) { continue; } elseif (count($paramPieces) === 2) { $parameterDefinition->type = trim($paramPieces[0]); // We might have an overload going on $nameArray = explode('=', $paramPieces[1]); $parameterDefinition->name = '$' . trim($nameArray[0]); // check if we got a default value for overloading if (isset($nameArray[1])) { unset($nameArray[0]); $parameterDefinition->defaultValue = trim(implode('=', $nameArray)); } } // Add the definition to the list $parameterDefinitionList->add($parameterDefinition); } return $parameterDefinitionList; }
/** * Will return an instance of an AbstractPointcut based on the given expression * * @param string $expression Expression specifying a certain pointcut * * @return \AppserverIo\Doppelgaenger\Interfaces\PointcutInterface * * @throws \InvalidArgumentException */ public function getInstance($expression) { // might be a simple type of pointcut $isNegated = false; // there are advices which do not reference any pointcuts, spare them the parsing if (empty($expression)) { $type = 'blank'; } else { // first of all we have to get the type of the pointcut // check for connector pointcuts first $expression = trim($expression); // if we are already in a wrapping connector pointcut then we will cut it off as those are not distinguished // by type but rather by their connector $expression = $this->trimConnectorTypes($expression); // now lets have a look if we are wrapped in some outer brackets $parserUtil = new Parser(); if (strlen($expression) === $parserUtil->getBracketSpan($expression, '(')) { $expression = substr($expression, 1, strlen($expression) - 2); } // now check if we do have any "and" connectors here if (strpos($expression, AndPointcut::CONNECTOR) !== false) { $class = '\\AppserverIo\\Doppelgaenger\\Entities\\Pointcuts\\AndPointcut'; $tmp = $this->findConnectorPointcut($expression, $class); if ($tmp !== false) { return $tmp; } } // or-connection comes second if (strpos($expression, OrPointcut::CONNECTOR) !== false) { $class = '\\AppserverIo\\Doppelgaenger\\Entities\\Pointcuts\\OrPointcut'; $tmp = $this->findConnectorPointcut($expression, $class); if ($tmp !== false) { return $tmp; } } // trim the expression from containing brackets first while ($expression[0] === '(' && $expression[strlen($expression) - 1] === ')') { $expression = substr($expression, 1, strlen($expression) - 2); } if (strpos($expression, '!') !== false) { $isNegated = true; $expression = str_replace('!', '', $expression); } $type = trim(strstr($expression, '(', true)); } // build up the class name and check if we know a class like that $class = '\\AppserverIo\\Doppelgaenger\\Entities\\Pointcuts\\' . ucfirst($type) . 'Pointcut'; // check if we got a valid class if (!class_exists($class)) { throw new \InvalidArgumentException(sprintf('Could not resolve the expression %s to any known pointcut type', $expression)); } $pointcut = new $class(substr(trim(str_replace($type, '', $expression), '( '), 0, -1), $isNegated); return $pointcut; }