b777c4d770ee839c93eb5dbf85e2c5198daf2069
[yaffs-website] / vendor / psy / psysh / src / Compiler.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2018 Justin Hileman
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Psy;
13
14 use Symfony\Component\Finder\Finder;
15
16 /**
17  * A Psy Shell Phar compiler.
18  */
19 class Compiler
20 {
21     private $version;
22
23     /**
24      * Compiles psysh into a single phar file.
25      *
26      * @param string $pharFile The full path to the file to create
27      */
28     public function compile($pharFile = 'psysh.phar')
29     {
30         if (file_exists($pharFile)) {
31             unlink($pharFile);
32         }
33
34         $this->version = Shell::VERSION;
35
36         $phar = new \Phar($pharFile, 0, 'psysh.phar');
37         $phar->setSignatureAlgorithm(\Phar::SHA1);
38
39         $phar->startBuffering();
40
41         $finder = Finder::create()
42             ->files()
43             ->ignoreVCS(true)
44             ->name('*.php')
45             ->notName('Compiler.php')
46             ->in(__DIR__);
47
48         foreach ($finder as $file) {
49             $this->addFile($phar, $file);
50         }
51
52         $finder = Finder::create()
53             ->files()
54             ->ignoreVCS(true)
55             ->name('*.php')
56             ->exclude('Tests')
57             ->exclude('tests')
58             ->exclude('Test')
59             ->exclude('test')
60             ->in(dirname(__DIR__) . '/build-vendor');
61
62         foreach ($finder as $file) {
63             $this->addFile($phar, $file);
64         }
65
66         // Stubs
67         $phar->setStub($this->getStub());
68
69         $phar->stopBuffering();
70
71         unset($phar);
72     }
73
74     /**
75      * Add a file to the psysh Phar.
76      *
77      * @param \Phar        $phar
78      * @param \SplFileInfo $file
79      * @param bool         $strip (default: true)
80      */
81     private function addFile($phar, $file, $strip = true)
82     {
83         $path = str_replace(dirname(__DIR__) . DIRECTORY_SEPARATOR, '', $file->getRealPath());
84
85         $content = file_get_contents($file);
86         if ($strip) {
87             $content = $this->stripWhitespace($content);
88         } elseif ('LICENSE' === basename($file)) {
89             $content = "\n" . $content . "\n";
90         }
91
92         $phar->addFromString($path, $content);
93     }
94
95     /**
96      * Removes whitespace from a PHP source string while preserving line numbers.
97      *
98      * @param string $source A PHP string
99      *
100      * @return string The PHP string with the whitespace removed
101      */
102     private function stripWhitespace($source)
103     {
104         if (!function_exists('token_get_all')) {
105             return $source;
106         }
107
108         $output = '';
109         foreach (token_get_all($source) as $token) {
110             if (is_string($token)) {
111                 $output .= $token;
112             } elseif (in_array($token[0], [T_COMMENT, T_DOC_COMMENT])) {
113                 $output .= str_repeat("\n", substr_count($token[1], "\n"));
114             } elseif (T_WHITESPACE === $token[0]) {
115                 // reduce wide spaces
116                 $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
117                 // normalize newlines to \n
118                 $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
119                 // trim leading spaces
120                 $whitespace = preg_replace('{\n +}', "\n", $whitespace);
121                 $output .= $whitespace;
122             } else {
123                 $output .= $token[1];
124             }
125         }
126
127         return $output;
128     }
129
130     private static function getStubLicense()
131     {
132         $license = file_get_contents(dirname(__DIR__) . '/LICENSE');
133         $license = str_replace('The MIT License (MIT)', '', $license);
134         $license = str_replace("\n", "\n * ", trim($license));
135
136         return $license;
137     }
138
139     const STUB_AUTOLOAD = <<<'EOS'
140     Phar::mapPhar('psysh.phar');
141     require 'phar://psysh.phar/build-vendor/autoload.php';
142 EOS;
143
144     /**
145      * Get a Phar stub for psysh.
146      *
147      * This is basically the psysh bin, with the autoload require statements swapped out.
148      *
149      * @return string
150      */
151     private function getStub()
152     {
153         $content = file_get_contents(dirname(__DIR__) . '/bin/psysh');
154         $content = preg_replace('{/\* <<<.*?>>> \*/}sm', self::STUB_AUTOLOAD, $content);
155         $content = preg_replace('/\\(c\\) .*?with this source code./sm', self::getStubLicense(), $content);
156
157         $content .= '__HALT_COMPILER();';
158
159         return $content;
160     }
161 }