function loadTemplate($func = null) { if (!$func) { $func = $this->func; } $ref = new \ReflectionFunction($func); $codes = file_get_contents($ref->getFileName()); $parser = PHPTokenParser::getParser($codes); $tmp = file($ref->getFileName()); $start_template = false; $template = ""; for ($i = $ref->getEndLine();; $i++) { if (!isset($tmp[$i])) { break; } $line = $tmp[$i]; //宣言部分の終了 if (!$start_template && strpos($line, "?>") !== false) { $start_template = true; $diff = substr($line, strpos($line, "?>") + strlen("?>")); $template .= ltrim($diff); continue; } if ($start_template) { $template .= $tmp[$i]; } } $template = $parser->cleanup($template); $this->setTemplate($template); }
/** * @test */ function docCommentの受け取り() { /* Comment 形式 */ $codes = []; $codes[] = "<?php "; $codes[] = '/*'; $codes[] = ' * @hogehoge'; $codes[] = ' */'; $codes[] = 'return [];'; $codes[] = '?>'; $codes[] = '<h1>this is body</h1>'; $codes = implode("\n", $codes); $parser = PHPTokenParser::getParser($codes); $code = $parser->cleanup(); $this->assertContains("this is body", $code); $comment = $parser->getDocComment(); $this->assertNotEmpty($comment); $this->assertContains("@hogehoge", $comment); /* DocComment形式 ----- */ $codes = []; $codes[] = "<?php "; $codes[] = '/**'; $codes[] = ' * @hogehoge'; $codes[] = ' */'; $codes[] = 'return [];'; $codes[] = '?>'; $codes[] = '<h1>this is body</h1>'; $codes = implode("\n", $codes); $parser = PHPTokenParser::getParser($codes); $code = $parser->cleanup(); $this->assertContains("this is body", $code); $comment = $parser->getDocComment(); $this->assertNotEmpty($comment); $this->assertContains("@hogehoge", $comment); //inline comment test $codes = []; $codes[] = "<?php "; $codes[] = '// @hogehoge'; $codes[] = '// @fugafuga'; $codes[] = 'return [];'; $codes[] = '?>'; $codes[] = '<h1>this is body</h1>'; $codes = implode("\n", $codes); $parser = PHPTokenParser::getParser($codes); $code = $parser->cleanup(); $this->assertContains("this is body", $code); $comment = $parser->getDocComment(); $this->assertNotEmpty($comment); $this->assertContains("@hogehoge", $comment); $this->assertContains("@fugafuga", $comment); }
function compile(Engine $factory) { $template = $this->template; //コードを綺麗にする $template = PHPTokenParser::getParser($template)->cleanup(); //Sectionを変換する $template = $this->replaceSections($template); $prefix = array(); //引数を変数に展開する $prefix[] = '<?php '; $prefix[] = 'foreach($' . $this->getHolderName() . '->values() as $name => $value){'; $prefix[] = ' $$name = $value;'; $prefix[] = '}'; $prefix[] = '?>'; return implode("\n", $prefix) . $template; }
/** * コードを解析する * @param string $path */ private function parseTemplate($path) { //parserの作成 $codes = file_get_contents($path); $parser = PHPTokenParser::getParser($codes); //コメントがあるかどうか判定する $comment = $parser->getDocComment(); if ($comment) { $this->parseAnnotations($comment); } return $parser->getBody(); }
/** * クロージャーの宣言部分を取得する * * @param \Closure $closure * @return string */ private function getClosureCode(\Closure $closure) { $reflection = new \ReflectionFunction($closure); $startLine = $reflection->getStartLine() - 1; // Open file and seek to the first line of the closure $file = new \SplFileObject($reflection->getFileName()); // Closureの開始コードまで移動 $file->seek($startLine); $params = []; foreach ($reflection->getParameters() as $param) { /* @var $param \ReflectionParameter */ if ($param->getClass()) { $params[] = "\\" . $param->getClass()->getName() . ' $' . $param->getName(); } else { $params[] = '$' . $param->getName(); } } $code_prefix = "function(" . implode(",", $params) . ")"; // Retrieve all of the lines that contain code for the closure $code = ''; while ($file->key() < $reflection->getEndLine()) { $line = $file->current(); $line = ltrim($line); // skip comment if (preg_match("#^//#", $line)) { $file->next(); continue; } $code .= $line; $file->next(); } // Only keep the code defining that closure $begin = strpos($code, 'function'); $begin = strpos($code, '{', $begin); $end = strrpos($code, '}'); $code = substr($code, $begin, $end - $begin + 1); $code = $code_prefix . preg_replace("/([\t ]+)}\$/m", "}", $code); // use句のreplaceを行う $parser = PHPTokenParser::getParser(file_get_contents($reflection->getFileName())); $code = $parser->cleanup($code); return $code; }