Parse the annotations contained in commented lines, starting with #

Annotation format is '@' followed by a word, followed by an optional ':' or '=', followed by a quoted value,
e.g.
<code>@foo="bar"</code>

@param string $fileContents
@return array
497931
public function parseAnnotations($fileContents)
    {
        $ret = array();
        if (preg_match('/^#\s*@(\w+)[:=]?\s+([\'"])?(.*)\2\s*$/m', $fileContents, $m)) {
            $ret[$m[1]] = $m[3];
        }
        return $ret;
    }
240175
private function getFileContents($files)
	{
		$content = '';
		$basePath = $this->basePath;

		array_walk($files,function(&$value, $key) use(&$content, $basePath){
			if(file_exists($basePath.$value))
			$content .= file_get_contents($basePath.$value);
		});
		return $content;
	}
115525
private function parsing() : void
    {
        $lines = explode("\n", $this->raw);

        foreach ($lines as $line) {
            // check "at" mark
            if (false === strpos($line, '@')) {
                continue;
            }

            // check inline annotation
            if ($anp = strpos($line, '//')) {
                $line = substr($line, 0, $anp);
            }

            // trim blanks
            $line = trim(ltrim($line, ' *'));

            // analyze expr
            if (false === $fws = strpos($line, ' ')) {
                // @some-key
                $key = substr($line, 1);
                $val = true;
            } else {
                // @some-key some-val
                $key = substr($line, 1, $fws - 1);
                $val = trim(substr($line, $fws));
            }

            $this->lines[] = [$key, $val];

            $this->declares[$key][] = $val;
        }
    }
36903
protected function createAnnotationObjects(array $annotations)
    {
        $objects     = array();

        //var_dump($annotations);

        foreach ($annotations as $name => $args) {
            $name = ucfirst($name);
            $class = $this->defaultNamespace . $name . 'Annotation';

            if (in_array(strtolower($name), self::getExcludeAnnotationList())) {
                continue;
            }

            if (! array_key_exists($class, $objects)) {
                if (!class_exists($class)) {
                    if ($this->strict) {
                        throw new \Exception(sprintf('Annotation Class Not Found: %s', $class));
                    } else {
                        continue;
                    }
                }

                $objects[$name] = new $class();
            }
            //var_dump($args);
            foreach ($args as $key => $value) {
                $objects[$name]->set($key, $value);
            }
        }

        return $objects;
    }
1218882
private function lex(string $contents): array
    {
        $contents = $this->removeSuperfluousStartingWhitespace($contents);

        // performance optimalization; if there is no inline tag, don't bother splitting it up.
        if (strpos($contents, '{@') === false) {
            return [$contents];
        }

        return preg_split(
            '/\{
                # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
                (?!@\})
                # We want to capture the whole tag line, but without the inline tag delimiters.
                (\@
                    # Match everything up to the next delimiter.
                    [^{}]*
                    # Nested inline tag content should not be captured, or it will appear in the result separately.
                    (?:
                        # Match nested inline tags.
                        (?:
                            # Because we did not catch the tag delimiters earlier, we must be explicit with them here.
                            # Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
                            \{(?1)?\}
                            |
                            # Make sure we match hanging "{".
                            \{
                        )
                        # Match content after the nested inline tag.
                        [^{}]*
                    )* # If there are more inline tags, match them as well. We use "*" since there may not be any
                       # nested inline tags.
                )
            \}/Sux',
            $contents,
            0,
            PREG_SPLIT_DELIM_CAPTURE
        );
    }
1148620
protected function _addNewDocBlock(File $file, $classIndex, array $annotations) {
		$tokens = $file->getTokens();

		foreach ($annotations as $key => $annotation) {
			if (is_string($annotation)) {
				continue;
			}
			$annotations[$key] = (string)$annotation;
		}

		$helper = new DocBlockHelper(new View());
		$annotationString = $helper->classDescription('', '', $annotations);
		if (PHP_EOL !== "\n") {
			$annotationString = str_replace("\n", PHP_EOL, $annotationString);
		}

		$fixer = $this->_getFixer($file);

		$docBlock = $annotationString . PHP_EOL;
		$fixer->replaceToken($classIndex, $docBlock . $tokens[$classIndex]['content']);

		$contents = $fixer->getContents();

		$this->_counter[static::COUNT_ADDED] = count($annotations);

		return $contents;
	}
317525
private function parseAnnotations($docBlock, $pattern, callable $callback)
    {
        $annotations = [];
        // Strip away the docblock header and footer to ease parsing of one line annotations
        $docBlock = substr($docBlock, 3, -2);

        if (preg_match_all($pattern, $docBlock, $matches) && is_callable($callback)) {
            return call_user_func($callback, $matches);
        }

        return $annotations;
    }
1031348
private function getParamsFromAnnotationArray(array $annotations)
    {
        $params = array();
        foreach ($annotations as $annotation) {
            if ($annotation instanceof ParamInterface) {
                $params[$annotation->getName()] = $annotation;
            }
        }

        return $params;
    }
1060705
private function parse($tokens, ?TypeContext $context = null): array
    {
        $count = count($tokens);
        $tagCount = 0;
        $tags = [];

        for ($i = 1; $i < $count; $i += 2) {
            $tags[] = $this->tagFactory->create($tokens[$i], $context);
            $tokens[$i] = '%' . ++$tagCount . '$s';
        }

        //In order to allow "literal" inline tags, the otherwise invalid
        //sequence "{@}" is changed to "@", and "{}" is changed to "}".
        //"%" is escaped to "%%" because of vsprintf.
        //See unit tests for examples.
        for ($i = 0; $i < $count; $i += 2) {
            $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
        }

        return [implode('', $tokens), $tags];
    }
65006
private function checkFile(\SplFileInfo $fileInfo, string $annotation): void
    {
        $contents = (string)file_get_contents($fileInfo->getPathname());
        if ($this->isAnnotationInClassDocBlock($contents, $annotation) === true) {
            return;
        }

        $matches  = [];
        preg_match_all(
            <<<REGEXP
%(?<docblock>/\*(?:[^*]|\n|(?:\*(?:[^/]|\n)))*\*/|\n)\s+?public\s+?function\s+?(?<method>.+?)\(%
REGEXP
            . 'si',
            $contents,
            $matches
        );
        if ('' === $matches[0]) {
            $this->errors[$fileInfo->getFilename()][] = 'Failed finding any doc blocks';

            return;
        }
        foreach ($matches['method'] as $key => $method) {
            $docblock = $matches['docblock'][$key];
            /* Found the annotation - continue */
            if (false !== \strpos($docblock, '@' . $annotation)) {
                continue;
            }
            /* No @test annotation found & method not beginning test =  not a test, so continue */
            if (false === \strpos($docblock, '@test') && false === \strpos($method, 'test')) {
                continue;
            }
            $this->errors[$fileInfo->getFilename()][] =
                'Failed finding @' . $annotation . ' for method: ' . $method;
        }
    }
554759
public function parseIncr($files)
    {
        foreach($files as $file)
        {
            if(isset($this->fileMap[$file]))
            {
                unset($this->fileMap[$file]);
            }
            if(!is_file($file))
            {
                continue;
            }
            $content = file_get_contents($file);
            if(preg_match('/namespace ([^;]+);/', $content, $matches) <= 0)
            {
                continue;
            }
            $namespace = trim($matches[1]);
            $className = $namespace . '\\' . basename($file, '.php');
            if(class_exists($className))
            {
                $this->parse($className);
            }
        }
    }
393455
protected function split($content)
    {
        // Pull off all annotation lines
        $continuation = false;
        $annotation = '';

        $lines = explode("\n", $content);
        $remaining = $lines;

        foreach ($lines as $i => $line) {
            if (!$line) {
                $continuation = false;
                continue;
            }

            if ($line[0] == '@') {
                $this->addAnnotation($annotation);
                $annotation = '';
                $continuation = true;
            } elseif ($continuation) {
                $annotation .= ' ';
            } else {
                continue;
            }

            $annotation .= trim($line);
            unset($remaining[$i]);
        }

        $this->addAnnotation($annotation);

        // Split remaining lines by paragrah
        $remaining = implode("\n", $remaining);
        $parts = preg_split("/(\n\n|\r\n\r\n)/", $remaining, -1, PREG_SPLIT_NO_EMPTY);

        // Into two parts
        if ($parts) {
            $first = $parts[0];
            $this->shortDescription = trim($first);

            $rest = array_slice($parts, 1);
            if ($rest) {
                $long = implode("\n\n", $rest);
                $long = preg_replace('/(\w) *\n *(\w)/', '\1 \2', $long);
                $long = trim($long);
                $this->longDescription = $long;
            }
        }
    }
882223
public function extract($files)
    {
        $methods = [];
        foreach ($files as $file) {
            $nodes = $this->parser->parse($file->getContents());
            if ($nodes === null) {
                error_log($file . ' does not contains any node');
                continue;
            }

            $this->parse($nodes, $methods);
            $this->progress();
        }

        return $methods;
    }
679613
protected function parseAnnotationPattern(string &$annotationPattern, array &$annotationPropertyConstraints): void
    {
        if (strpos($annotationPattern, '(') !== false) {
            $matches = [];
            preg_match(self::PATTERN_MATCHMETHODNAMEANDARGUMENTS, $annotationPattern, $matches);

            $annotationPattern = $matches['MethodName'];
            $annotationPropertiesPattern = $matches['MethodArguments'];
            $annotationPropertyConstraints = $this->getArgumentConstraintsFromMethodArgumentsPattern($annotationPropertiesPattern);
        }
    }
444611
private function filterAnnotations(array $annotations): array
    {
        $annotations = \array_filter($annotations, function ($annotation) {
            $ref = new \ReflectionObject($annotation);

            return 0 === \mb_strpos($ref->getNamespaceName(), 'TSantos\Serializer');
        });

        return $annotations;
    }
346752
private function xmlToObj($fileContents)
  {
    $fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
    $fileContents = trim(str_replace('"', "'", $fileContents));
    $simpleXml    = simplexml_load_string($fileContents, null, LIBXML_NOCDATA);

    return $simpleXml;
  }
777080
public function extractMigrationInfoFromSource($fileContents)
    {
        $stream = new PhpSourceStream($fileContents);

        $result = [];

        while ($stream->forward()) {
            $tokenCode = $stream->getCurrentCode();

            if ($tokenCode == T_NAMESPACE) {
                $namespace = $this->extractNamespace($stream);
                if ($namespace === null) {
                    return null;
                }

                $result['namespace'] = $namespace;
            }

            if ($tokenCode == T_CLASS) {
                $className = $this->extractClassName($stream);
                if ($className === null) {
                    return null;
                }

                $result['class'] = $className;
            }
        }

        if (!$result) {
            return null;
        }

        return $result;
    }