PHPPlus.php

<?php

class PHPPlus {

    static public function enable(){
        $trace = debug_backtrace();
        $file = $trace[0]['file'];
        $outputDir = __DIR__.'/output/';
        if (substr($file,0,strlen($outputDir))==$outputDir)throw new \Exception("Cannot operate PHPPlus on processed output files.");
        $outputFile = $outputDir.str_replace(['/','\\'],'_',$file);
        self::processAndOutputFile($outputFile,file_get_contents($file));
        return require($outputFile);        
    }

    static protected function processAndOutputFile($outputFile,$content){
        $niceTokens = self::getTokens($content);
        // print_r($niceTokens);
        $output = self::tokensToString($niceTokens);
        file_put_contents($outputFile,$output);
    }

    static protected function tokensToString($tokens){
        $str = '';
        $lastLine = 1;
        foreach ($tokens as $index => $token){
            // $lastTok = $tokens[$index-1]
                // while($lastLine++<$token['line'])$str .= "\n";
            $code = $token['code'];
            if ($token['type']=='T_CONSTANT_ENCAPSED_STRING')$code = '(new \PHPPlus\Str('.$code.'))';
            $str .= $code;
        }
        return $str;
    }
    static protected function getTokens($content){
        $tokens = token_get_all($content);
        $niceTokens = [];

        $delLine = null;
        foreach ($tokens as $index=>$token){
            $tok = [];
            if (!is_array($token)){
                $lastTok = array_slice($niceTokens,-1)[0];
                $tok['type'] = "UNNAMED_TOKEN";
                $tok['code'] = $token;
                $tok['line'] = $lastTok['line'];
            } else {
                $tok['type'] = token_name($token[0]);
                $tok['code'] = $token[1];
                $tok['line'] = $token[2];
            }
            if ($tok['type']=='T_STRING'&&$tok['code']=='PHPPlus'){
                $next = $tokens[$index+1];
                if (is_array($next)&&$next[1]=='::'){
                    $delLine = $tok['line'];
                    echo 'del line is '.$delLine."\n\n";
                }
            }
            $niceTokens[] = $tok;
        }
        foreach ($niceTokens as $index=>$token){
            if ($token['line']===$delLine){
                unset($niceTokens[$index]);
            }
        }
        return $niceTokens;
    }
}