-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
623 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <llvm/Support/CommandLine.h> | ||
|
||
namespace nixd { | ||
|
||
extern llvm::cl::OptionCategory NixdCategory; | ||
|
||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#pragma once | ||
|
||
#include "nixd/Protocol/AttrSet.h" | ||
#include "nixd/Support/StreamProc.h" | ||
|
||
#include <lspserver/LSPServer.h> | ||
|
||
#include <thread> | ||
|
||
namespace nixd { | ||
|
||
class AttrSetClient : public lspserver::LSPServer { | ||
|
||
llvm::unique_function<void(const EvalExprParams &Params, | ||
lspserver::Callback<EvalExprResponse> Reply)> | ||
EvalExpr; | ||
|
||
llvm::unique_function<void(const AttrPathInfoParams &Params, | ||
lspserver::Callback<AttrPathInfoResponse> Reply)> | ||
AttrPathInfo; | ||
|
||
llvm::unique_function<void( | ||
const AttrPathCompleteParams &Params, | ||
lspserver::Callback<AttrPathCompleteResponse> Reply)> | ||
AttrPathComplete; | ||
|
||
public: | ||
AttrSetClient(std::unique_ptr<lspserver::InboundPort> In, | ||
std::unique_ptr<lspserver::OutboundPort> Out); | ||
|
||
/// \brief Request eval some expression. | ||
/// The expression should be evaluted to attrset. | ||
void evalExpr(const EvalExprParams &Params, | ||
lspserver::Callback<EvalExprResponse> Reply) { | ||
return EvalExpr(Params, std::move(Reply)); | ||
} | ||
|
||
void attrpathInfo(const AttrPathInfoParams &Params, | ||
lspserver::Callback<AttrPathInfoResponse> Reply) { | ||
AttrPathInfo(Params, std::move(Reply)); | ||
} | ||
|
||
void attrpathComplete(const AttrPathCompleteParams &Params, | ||
lspserver::Callback<AttrPathCompleteResponse> Reply) { | ||
AttrPathComplete(Params, std::move(Reply)); | ||
} | ||
|
||
/// Get executable path for launching the server. | ||
/// \returns null terminated string. | ||
static const char *getExe(); | ||
}; | ||
|
||
class AttrSetClientProc { | ||
StreamProc Proc; | ||
AttrSetClient Client; | ||
std::thread Input; | ||
|
||
public: | ||
/// \brief Check if the process is still alive | ||
/// \returns nullptr if it has been dead. | ||
AttrSetClient *client(); | ||
~AttrSetClientProc() { | ||
Client.closeInbound(); | ||
Input.join(); | ||
} | ||
|
||
/// \see StreamProc::StreamProc | ||
AttrSetClientProc(const std::function<int()> &Action); | ||
}; | ||
|
||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
#pragma once | ||
|
||
namespace nixd::util { | ||
namespace nixd { | ||
|
||
/// \brief fork this process and create some pipes connected to the new process. | ||
/// | ||
/// stdin, stdout, stderr in the new process will be closed, and these fds could | ||
/// be used to communicate with it. | ||
/// | ||
/// \returns pid of child process, in parent. | ||
/// \returns 0 in child. | ||
int forkPiped(int &In, int &Out, int &Err); | ||
|
||
} // namespace nixd::util | ||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma once | ||
|
||
#include "nixd/Support/PipedProc.h" | ||
|
||
#include <llvm/Support/raw_ostream.h> | ||
#include <lspserver/Connection.h> | ||
|
||
namespace nixd { | ||
|
||
struct StreamProc { | ||
std::unique_ptr<util::PipedProc> Proc; | ||
std::unique_ptr<llvm::raw_fd_ostream> Stream; | ||
|
||
/// \brief Launch a streamed process with \p Action. | ||
/// | ||
/// The value returned by \p Action will be interpreted as process's exit | ||
/// value. | ||
StreamProc(const std::function<int()> &Action); | ||
|
||
[[nodiscard]] std::unique_ptr<lspserver::InboundPort> mkIn() const; | ||
|
||
[[nodiscard]] std::unique_ptr<lspserver::OutboundPort> mkOut() const; | ||
}; | ||
|
||
} // namespace nixd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#include "nixd/CommandLine/Options.h" | ||
|
||
llvm::cl::OptionCategory nixd::NixdCategory("nixd library options"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "AST.h" | ||
|
||
using namespace nixf; | ||
|
||
[[nodiscard]] const EnvNode *nixd::upEnv(const nixf::Node &Desc, | ||
const VariableLookupAnalysis &VLA, | ||
const ParentMapAnalysis &PM) { | ||
const nixf::Node *N = &Desc; // @nonnull | ||
while (!VLA.env(N) && PM.query(*N) && !PM.isRoot(*N)) | ||
N = PM.query(*N); | ||
assert(N); | ||
return VLA.env(N); | ||
} | ||
|
||
bool nixd::havePackageScope(const Node &N, const VariableLookupAnalysis &VLA, | ||
const ParentMapAnalysis &PM) { | ||
// Firstly find the first "env" enclosed with this variable. | ||
const EnvNode *Env = upEnv(N, VLA, PM); | ||
if (!Env) | ||
return false; | ||
|
||
// Then, search up until there are some `with`. | ||
for (; Env; Env = Env->parent()) { | ||
if (!Env->isWith()) | ||
continue; | ||
// this env is "with" expression. | ||
const Node *With = Env->syntax(); | ||
assert(With && With->kind() == Node::NK_ExprWith); | ||
const Node *WithBody = static_cast<const ExprWith &>(*With).with(); | ||
if (!WithBody) | ||
continue; // skip incomplete with epxression. | ||
|
||
// Se if it is "ExprVar“. Stupid. | ||
if (WithBody->kind() != Node::NK_ExprVar) | ||
continue; | ||
|
||
// Hardcoded "pkgs", even more stupid. | ||
if (static_cast<const ExprVar &>(*WithBody).id().name() == "pkgs") | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
std::pair<std::vector<std::string>, std::string> | ||
nixd::getScopeAndPrefix(const Node &N, const ParentMapAnalysis &PM) { | ||
if (N.kind() != Node::NK_Identifer) | ||
return {}; | ||
|
||
// FIXME: impl scoped packages | ||
std::string Prefix = static_cast<const Identifier &>(N).name(); | ||
return {{}, Prefix}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/// \file | ||
/// \brief This file declares some common analysis (tree walk) on the AST. | ||
|
||
#include <nixf/Sema/ParentMap.h> | ||
#include <nixf/Sema/VariableLookup.h> | ||
|
||
namespace nixd { | ||
|
||
/// \brief Search up until there are some node associated with "EnvNode". | ||
[[nodiscard]] const nixf::EnvNode * | ||
upEnv(const nixf::Node &Desc, const nixf::VariableLookupAnalysis &VLA, | ||
const nixf::ParentMapAnalysis &PM); | ||
|
||
/// \brief Determine whether or not some node has enclosed "with pkgs; [ ]" | ||
/// | ||
/// Yes, this evaluation isn't flawless. What if the identifier isn't "pkgs"? We | ||
/// can't dynamically evaluate everything each time and invalidate them | ||
/// immediately after document updates. Therefore, this heuristic method | ||
/// represents a trade-off between performance considerations. | ||
[[nodiscard]] bool havePackageScope(const nixf::Node &N, | ||
const nixf::VariableLookupAnalysis &VLA, | ||
const nixf::ParentMapAnalysis &PM); | ||
|
||
/// \brief get variable scope, and it's prefix name. | ||
/// | ||
/// Nixpkgs has some packages scoped in "nested" attrs. | ||
/// e.g. llvmPackages, pythonPackages. | ||
/// Try to find these name as a pre-selected scope, the last value is "prefix". | ||
std::pair<std::vector<std::string>, std::string> | ||
getScopeAndPrefix(const nixf::Node &N, const nixf::ParentMapAnalysis &PM); | ||
|
||
} // namespace nixd |
Oops, something went wrong.