<commit_before><?php

namespace IdeHelper\Annotator;

use Bake\View\Helper\DocBlockHelper;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Utility\Inflector;
use Cake\View\View;
use IdeHelper\Annotation\AnnotationFactory;
use IdeHelper\Annotation\VariableAnnotation;
use IdeHelper\Annotator\Template\VariableExtractor;
use PHP_CodeSniffer\Files\File;
use RuntimeException;

class TemplateAnnotator extends AbstractAnnotator {

	/**
	 * @param string $path Path to file.
	 * @return bool
	 */
	public function annotate($path) {
		$content = file_get_contents($path);

		$annotations = $this->_buildAnnotations($path, $content);

		return $this->_annotate($path, $content, $annotations);
	}

	/**
	 * @param string $path
	 * @param string $content
	 * @param \IdeHelper\Annotation\AbstractAnnotation[] $annotations
	 *
	 * @return bool
	 */
	protected function _annotate($path, $content, array $annotations) {
		if (!count($annotations)) {
			return false;
		}

		$file = $this->_getFile($path, $content);

		$phpOpenTagIndex = $file->findNext(T_OPEN_TAG, 0);
		if ($phpOpenTagIndex === false) {
			$phpOpenTagIndex = null;
		}

		$needsPhpTag = $phpOpenTagIndex === null || $this->_needsPhpTag($file, $phpOpenTagIndex);
		$docBlockCloseTagIndex = null;
		if ($needsPhpTag) {
			$phpOpenTagIndex = null;
		} else {
			$docBlockCloseTagIndex = $this->_findExistingDocBlock($file, $phpOpenTagIndex);
		}

		$this->_resetCounter();
		if ($docBlockCloseTagIndex && !$this->isInlineDocBlock($file, $docBlockCloseTagIndex)) {
			$newContent = $this->_appendToExistingDocBlock($file, $docBlockCloseTagIndex, $annotations);
		} else {
			$newContent = $this->_addNewTemplateDocBlock($file, $annotations, $phpOpenTagIndex, $docBlockCloseTagIndex);
		}

		$this->_displayDiff($content, $newContent);
		$this->_storeFile($path, $newContent);

		$this->_report();

		return true;
	}

	/**
	 * @param \PHP_CodeSniffer\Files\File $file
	 * @param int $phpOpenTagIndex
	 * @return int|null
	 */
	protected function _findExistingDocBlock(File $file, $phpOpenTagIndex) {
		$tokens = $file->getTokens();

		$nextIndex = $file->findNext(T_WHITESPACE, $phpOpenTagIndex + 1, null, true);
		if ($tokens[$nextIndex]['type'] !== 'T_DOC_COMMENT_OPEN_TAG') {
			return null;
		}<commit_msg>Fix dry run for templates.<commit_after><?php

namespace IdeHelper\Annotator;

use Bake\View\Helper\DocBlockHelper;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Utility\Inflector;
use Cake\View\View;
use IdeHelper\Annotation\AnnotationFactory;
use IdeHelper\Annotation\VariableAnnotation;
use IdeHelper\Annotator\Template\VariableExtractor;
use PHP_CodeSniffer\Files\File;
use RuntimeException;

class TemplateAnnotator extends AbstractAnnotator {

	/**
	 * @param string $path Path to file.
	 * @return bool
	 */
	public function annotate($path) {
		$content = file_get_contents($path);

		$annotations = $this->_buildAnnotations($path, $content);

		return $this->_annotate($path, $content, $annotations);
	}

	/**
	 * @param string $path
	 * @param string $content
	 * @param \IdeHelper\Annotation\AbstractAnnotation[] $annotations
	 *
	 * @return bool
	 */
	protected function _annotate($path, $content, array $annotations) {
		if (!count($annotations)) {
			return false;
		}

		$file = $this->_getFile($path, $content);

		$phpOpenTagIndex = $file->findNext(T_OPEN_TAG, 0);
		if ($phpOpenTagIndex === false) {
			$phpOpenTagIndex = null;
		}

		$needsPhpTag = $phpOpenTagIndex === null || $this->_needsPhpTag($file, $phpOpenTagIndex);
		$docBlockCloseTagIndex = null;
		if ($needsPhpTag) {
			$phpOpenTagIndex = null;
		} else {
			$docBlockCloseTagIndex = $this->_findExistingDocBlock($file, $phpOpenTagIndex);
		}

		$this->_resetCounter();
		if ($docBlockCloseTagIndex && !$this->isInlineDocBlock($file, $docBlockCloseTagIndex)) {
			$newContent = $this->_appendToExistingDocBlock($file, $docBlockCloseTagIndex, $annotations);
		} else {
			$newContent = $this->_addNewTemplateDocBlock($file, $annotations, $phpOpenTagIndex, $docBlockCloseTagIndex);
		}

		if ($newContent === $content) {
			$this->_reportSkipped();
			return false;
		}

		$this->_displayDiff($content, $newContent);
		$this->_storeFile($path, $newContent);

		$this->_report();

		return true;
	}

	/**
	 * @param \PHP_CodeSniffer\Files\File $file
	 * @param int $phpOpenTagIndex
	 * @return int|null
	 */
	protected function _findExistingDocBlock(File $file, $phpOpenTagIndex) {
		$tokens = $file->getTokens();

		$nextIndex = $file->findNext(T_WHITESPACE, $phpOpenTagIndex + 1, null, true);
		if ($tokens[$nextIndex]['type'] !== 'T_DOC_COMMENT_OPEN_TAG') {
			return null;
		}
{'fraction_non_alphanumeric': 0.14748434463398835, 'fraction_numerical': 0.0008637443316778234, 'mean_word_length': 5.070773263433814, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4894808', 'n_tokens_mistral': 1664, 'n_tokens_neox': 1506, 'n_words': 294}