Only hold content for open files in memory
parent
e75c1592fc
commit
42abb69137
|
@ -153,7 +153,7 @@ class LanguageServer extends \AdvancedJsonRpc\Dispatcher
|
||||||
$shortName = substr($file, strlen($rootPath) + 1);
|
$shortName = substr($file, strlen($rootPath) + 1);
|
||||||
$this->client->window->logMessage(MessageType::INFO, "Parsing file $fileNum/$numTotalFiles: $shortName.");
|
$this->client->window->logMessage(MessageType::INFO, "Parsing file $fileNum/$numTotalFiles: $shortName.");
|
||||||
|
|
||||||
$this->project->getDocument($uri)->updateContent(file_get_contents($file));
|
$this->project->getDocument($uri)->parse(file_get_contents($file));
|
||||||
|
|
||||||
Loop\setTimeout($processFile, 0);
|
Loop\setTimeout($processFile, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@ use LanguageServer\NodeVisitor\{NodeAtPositionFinder, ReferencesAdder, Definitio
|
||||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
||||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||||
use PhpParser\NodeVisitor\NameResolver;
|
use PhpParser\NodeVisitor\NameResolver;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
class PhpDocument
|
class PhpDocument
|
||||||
{
|
{
|
||||||
|
@ -53,14 +54,14 @@ class PhpDocument
|
||||||
*
|
*
|
||||||
* @var Node[]
|
* @var Node[]
|
||||||
*/
|
*/
|
||||||
private $stmts = [];
|
private $statements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from fully qualified name (FQN) to Node
|
* Map from fully qualified name (FQN) to Node
|
||||||
*
|
*
|
||||||
* @var Node[]
|
* @var Node[]
|
||||||
*/
|
*/
|
||||||
private $definitions = [];
|
private $definitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from fully qualified name (FQN) to array of nodes that reference the symbol
|
* Map from fully qualified name (FQN) to array of nodes that reference the symbol
|
||||||
|
@ -150,21 +151,32 @@ class PhpDocument
|
||||||
public function updateContent(string $content)
|
public function updateContent(string $content)
|
||||||
{
|
{
|
||||||
$this->content = $content;
|
$this->content = $content;
|
||||||
$this->parse();
|
$this->parse($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-parses a source file, updates symbols, reports parsing errors
|
* Unloads the content from memory
|
||||||
* that may have occured as diagnostics and returns parsed nodes.
|
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function parse()
|
public function removeContent()
|
||||||
|
{
|
||||||
|
unset($this->content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-parses a source file, updates symbols and reports parsing errors
|
||||||
|
* that may have occured as diagnostics.
|
||||||
|
*
|
||||||
|
* @param string $content
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parse(string $content)
|
||||||
{
|
{
|
||||||
$stmts = null;
|
$stmts = null;
|
||||||
$errors = [];
|
$errors = [];
|
||||||
try {
|
try {
|
||||||
$stmts = $this->parser->parse($this->content);
|
$stmts = $this->parser->parse($content);
|
||||||
} catch (\PhpParser\Error $e) {
|
} catch (\PhpParser\Error $e) {
|
||||||
// Lexer can throw errors. e.g for unterminated comments
|
// Lexer can throw errors. e.g for unterminated comments
|
||||||
// unfortunately we don't get a location back
|
// unfortunately we don't get a location back
|
||||||
|
@ -177,8 +189,8 @@ class PhpDocument
|
||||||
foreach ($errors as $error) {
|
foreach ($errors as $error) {
|
||||||
$diagnostic = new Diagnostic();
|
$diagnostic = new Diagnostic();
|
||||||
$diagnostic->range = new Range(
|
$diagnostic->range = new Range(
|
||||||
new Position($error->getStartLine() - 1, $error->hasColumnInfo() ? $error->getStartColumn($this->content) - 1 : 0),
|
new Position($error->getStartLine() - 1, $error->hasColumnInfo() ? $error->getStartColumn($content) - 1 : 0),
|
||||||
new Position($error->getEndLine() - 1, $error->hasColumnInfo() ? $error->getEndColumn($this->content) : 0)
|
new Position($error->getEndLine() - 1, $error->hasColumnInfo() ? $error->getEndColumn($content) : 0)
|
||||||
);
|
);
|
||||||
$diagnostic->severity = DiagnosticSeverity::ERROR;
|
$diagnostic->severity = DiagnosticSeverity::ERROR;
|
||||||
$diagnostic->source = 'php';
|
$diagnostic->source = 'php';
|
||||||
|
@ -199,7 +211,7 @@ class PhpDocument
|
||||||
$traverser->addVisitor(new ReferencesAdder($this));
|
$traverser->addVisitor(new ReferencesAdder($this));
|
||||||
|
|
||||||
// Add column attributes to nodes
|
// Add column attributes to nodes
|
||||||
$traverser->addVisitor(new ColumnCalculator($this->content));
|
$traverser->addVisitor(new ColumnCalculator($content));
|
||||||
|
|
||||||
// Collect all definitions
|
// Collect all definitions
|
||||||
$definitionCollector = new DefinitionCollector;
|
$definitionCollector = new DefinitionCollector;
|
||||||
|
@ -213,7 +225,7 @@ class PhpDocument
|
||||||
$this->project->addDefinitionDocument($fqn, $this);
|
$this->project->addDefinitionDocument($fqn, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->stmts = $stmts;
|
$this->statements = $stmts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,12 +246,29 @@ class PhpDocument
|
||||||
* Returns this document's text content.
|
* Returns this document's text content.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws Exception If the content was not loaded
|
||||||
*/
|
*/
|
||||||
public function getContent()
|
public function getContent()
|
||||||
{
|
{
|
||||||
|
if (!isset($this->content)) {
|
||||||
|
throw new Exception('Content is not loaded');
|
||||||
|
}
|
||||||
return $this->content;
|
return $this->content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this document's AST.
|
||||||
|
*
|
||||||
|
* @return Node[]
|
||||||
|
*/
|
||||||
|
public function getStatements()
|
||||||
|
{
|
||||||
|
if (!isset($this->statements)) {
|
||||||
|
$this->parse($this->getContent());
|
||||||
|
}
|
||||||
|
return $this->statements;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URI of the document
|
* Returns the URI of the document
|
||||||
*
|
*
|
||||||
|
@ -258,13 +287,10 @@ class PhpDocument
|
||||||
*/
|
*/
|
||||||
public function getNodeAtPosition(Position $position)
|
public function getNodeAtPosition(Position $position)
|
||||||
{
|
{
|
||||||
if ($this->stmts === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$traverser = new NodeTraverser;
|
$traverser = new NodeTraverser;
|
||||||
$finder = new NodeAtPositionFinder($position);
|
$finder = new NodeAtPositionFinder($position);
|
||||||
$traverser->addVisitor($finder);
|
$traverser->addVisitor($finder);
|
||||||
$traverser->traverse($this->stmts);
|
$traverser->traverse($this->getStatements());
|
||||||
return $finder->node;
|
return $finder->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,18 @@ class TextDocument
|
||||||
$this->project->getDocument($textDocument->uri)->updateContent($contentChanges[0]->text);
|
$this->project->getDocument($textDocument->uri)->updateContent($contentChanges[0]->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The document close notification is sent from the client to the server when the document got closed in the client.
|
||||||
|
* The document's truth now exists where the document's uri points to (e.g. if the document's uri is a file uri the
|
||||||
|
* truth now exists on disk).
|
||||||
|
*
|
||||||
|
* @param \LanguageServer\Protocol\TextDocumentItem $textDocument The document that was closed
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function didClose(TextDocumentIdentifier $textDocument)
|
||||||
|
{
|
||||||
|
$this->project->getDocument($textDocument->uri)->removeContent();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The document formatting request is sent from the server to the client to format a whole document.
|
* The document formatting request is sent from the server to the client to format a whole document.
|
||||||
|
|
Loading…
Reference in New Issue