Skip to content

Commit bedd157

Browse files
authored
Caching (#260)
1 parent 34d3d20 commit bedd157

File tree

11 files changed

+494
-82
lines changed

11 files changed

+494
-82
lines changed

src/Cache/Cache.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace LanguageServer\Cache;
5+
6+
use Sabre\Event\Promise;
7+
8+
/**
9+
* A key/value store for caching purposes
10+
*/
11+
interface Cache
12+
{
13+
/**
14+
* Gets a value from the cache
15+
*
16+
* @param string $key
17+
* @return Promise <mixed>
18+
*/
19+
public function get(string $key): Promise;
20+
21+
/**
22+
* Sets a value in the cache
23+
*
24+
* @param string $key
25+
* @param mixed $value
26+
* @return Promise
27+
*/
28+
public function set(string $key, $value): Promise;
29+
}

src/Cache/ClientCache.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace LanguageServer\Cache;
5+
6+
use LanguageServer\LanguageClient;
7+
use Sabre\Event\Promise;
8+
9+
/**
10+
* Caches content through a xcache/* requests
11+
*/
12+
class ClientCache implements Cache
13+
{
14+
/**
15+
* @param LanguageClient $client
16+
*/
17+
public function __construct(LanguageClient $client)
18+
{
19+
$this->client = $client;
20+
}
21+
22+
/**
23+
* Gets a value from the cache
24+
*
25+
* @param string $key
26+
* @return Promise <mixed>
27+
*/
28+
public function get(string $key): Promise
29+
{
30+
return $this->client->xcache->get($key)->then('unserialize')->otherwise(function () {
31+
// Ignore
32+
});
33+
}
34+
35+
/**
36+
* Sets a value in the cache
37+
*
38+
* @param string $key
39+
* @param mixed $value
40+
* @return Promise
41+
*/
42+
public function set(string $key, $value): Promise
43+
{
44+
return $this->client->xcache->set($key, serialize($value))->otherwise(function () {
45+
// Ignore
46+
});
47+
}
48+
}

src/Cache/FileSystemCache.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace LanguageServer\Cache;
5+
6+
use LanguageServer\LanguageClient;
7+
use Sabre\Event\Promise;
8+
9+
/**
10+
* Caches content on the file system
11+
*/
12+
class FileSystemCache implements Cache
13+
{
14+
/**
15+
* @var string
16+
*/
17+
public $cacheDir;
18+
19+
public function __construct()
20+
{
21+
if (PHP_OS === 'WINNT') {
22+
$this->cacheDir = getenv('LOCALAPPDATA') . '\\PHP Language Server\\';
23+
} else if (getenv('XDG_CACHE_HOME')) {
24+
$this->cacheDir = getenv('XDG_CACHE_HOME') . '/phpls/';
25+
} else {
26+
$this->cacheDir = getenv('HOME') . '/.phpls/';
27+
}
28+
}
29+
30+
/**
31+
* Gets a value from the cache
32+
*
33+
* @param string $key
34+
* @return Promise <mixed>
35+
*/
36+
public function get(string $key): Promise
37+
{
38+
try {
39+
$file = $this->cacheDir . urlencode($key);
40+
if (!file_exists($file)) {
41+
return Promise\resolve(null);
42+
}
43+
return Promise\resolve(unserialize(file_get_contents($file)));
44+
} catch (\Exception $e) {
45+
return Promise\resolve(null);
46+
}
47+
}
48+
49+
/**
50+
* Sets a value in the cache
51+
*
52+
* @param string $key
53+
* @param mixed $value
54+
* @return Promise
55+
*/
56+
public function set(string $key, $value): Promise
57+
{
58+
try {
59+
$file = $this->cacheDir . urlencode($key);
60+
if (!file_exists($this->cacheDir)) {
61+
mkdir($this->cacheDir);
62+
}
63+
file_put_contents($file, serialize($value));
64+
} finally {
65+
return Promise\resolve(null);
66+
}
67+
}
68+
}

src/Client/XCache.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace LanguageServer\Client;
5+
6+
use LanguageServer\ClientHandler;
7+
use LanguageServer\Protocol\Message;
8+
use Sabre\Event\Promise;
9+
10+
/**
11+
* Provides method handlers for all xcache/* methods
12+
*/
13+
class XCache
14+
{
15+
/**
16+
* @var ClientHandler
17+
*/
18+
private $handler;
19+
20+
public function __construct(ClientHandler $handler)
21+
{
22+
$this->handler = $handler;
23+
}
24+
25+
/**
26+
* @param string $key
27+
* @return Promise <mixed>
28+
*/
29+
public function get(string $key): Promise
30+
{
31+
return $this->handler->request('xcache/get', ['key' => $key]);
32+
}
33+
34+
/**
35+
* @param string $key
36+
* @param mixed $value
37+
* @return Promise <mixed>
38+
*/
39+
public function set(string $key, $value): Promise
40+
{
41+
return $this->handler->notify('xcache/set', ['key' => $key, 'value' => $value]);
42+
}
43+
}

src/Index/DependenciesIndex.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ public function getDependencyIndex(string $packageName): Index
3434
return $this->indexes[$packageName];
3535
}
3636

37+
/**
38+
* @param string $packageName
39+
* @param Index $index
40+
* @return void
41+
*/
42+
public function setDependencyIndex(string $packageName, Index $index)
43+
{
44+
$this->indexes[$packageName] = $index;
45+
$this->registerIndex($index);
46+
}
47+
3748
/**
3849
* @param string $packageName
3950
* @return void

src/Index/Index.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Represents the index of a project or dependency
1111
* Serializable for caching
1212
*/
13-
class Index implements ReadableIndex
13+
class Index implements ReadableIndex, \Serializable
1414
{
1515
use EmitterTrait;
1616

@@ -185,4 +185,30 @@ public function removeReferenceUri(string $fqn, string $uri)
185185
}
186186
array_splice($this->references[$fqn], $index, 1);
187187
}
188+
189+
/**
190+
* @param string $serialized
191+
* @return void
192+
*/
193+
public function unserialize($serialized)
194+
{
195+
$data = unserialize($serialized);
196+
foreach ($data as $prop => $val) {
197+
$this->$prop = $val;
198+
}
199+
}
200+
201+
/**
202+
* @param string $serialized
203+
* @return string
204+
*/
205+
public function serialize()
206+
{
207+
return serialize([
208+
'definitions' => $this->definitions,
209+
'references' => $this->references,
210+
'complete' => $this->complete,
211+
'staticComplete' => $this->staticComplete
212+
]);
213+
}
188214
}

0 commit comments

Comments
 (0)