Cache.php
<?php
namespace Tlf\LexerTrait;
/**
* Handles caching of asts & grammar lists
*/
trait Cache {
/**
* Copy of .cache/map.json
*/
protected $cacheMap = null;
public function getCachedAst($filePath){
if ($this->useCache===false)return false;
$cacheDir = dirname(__DIR__, 2).'/.cache/';
if (!is_file($cacheDir.'/map.json'))return false;
$map = $this->cacheMap ?? json_decode(file_get_contents($cacheDir.'/map.json'),true);
$this->cacheMap = $map;
if (!isset($map['files'][$filePath]))return false;
$file = $map['files'][$filePath];
if (sha1_file($filePath)!=$file['sha1'])return false;
$grammarList = $this->getGrammarListForCache();
if ($grammarList != $file['grammarList']) return false;
$astTree = include($file['cachedAstPath']);
if (!is_array($astTree))return false;
$ast = new \Tlf\Lexer\Ast('file');
$ast->setTree($astTree);
return $ast;
}
public function cacheFileAst($filePath, $ast){
if ($this->useCache===false)return;
$tree = $ast->getTree();
$cacheDir = dirname(__DIR__, 2).'/.cache/';
if (!is_dir($cacheDir))mkdir($cacheDir);
if (!is_dir($cacheDir.'/fileast/'))mkdir($cacheDir.'/fileast/');
if (!is_file($cacheDir.'/map.json'))file_put_contents($cacheDir.'/map.json',json_encode([]));
$map = $this->cacheMap ?? json_decode(file_get_contents($cacheDir.'/map.json'),true);
if (isset($map['files'][$filePath]['cachedAstPath'])){
if (is_file($cachedPath = $map['files'][$filePath]['cachedAstPath'])){
unlink($cachedPath);
}
}
$map['files'][$filePath]['sha1'] = sha1_file($filePath);
$map['files'][$filePath]['grammarList'] = $this->getGrammarListForCache();
if (!is_dir($cacheDir.'/fileast'))mkdir($cacheDir.'/fileast');
$cachedAstPath = $cacheDir.'/fileast/'.uniqid().'.php';
$map['files'][$filePath]['cachedAstPath'] = $cachedAstPath;
file_put_contents($cachedAstPath,
'<?php return '
. var_export($tree,true)
.';'
);
$this->cacheMap = $map;
file_put_contents($cacheDir.'/map.json', json_encode($map, JSON_PRETTY_PRINT));
}
public function getGrammarListForCache(){
if ($this->grammarListForCache!=null)return $this->grammarListForCache;
$grammarList = [];
foreach ($this->grammars as $g){
$grammarList[get_class($g)] = filemtime((new \ReflectionClass($g))->getFileName());
}
ksort($grammarList);
$this->grammarListForCache = $grammarList;
return $grammarList;
}
}