/**
* @file lspexp.cc
* @brief For createSymMap and other lsp-related functions
* specific to Lsp in *exp classes.
* @author Supakorn 'Jamie' Rassameemasmuang (jamievlin at outlook.com)
*/
#include "common.h"
#include "exp.h"
#define DEC_CREATE_SYM_MAP_EXP(derived_class) \
void derived_class::createSymMap(AsymptoteLsp::SymbolContext* symContext)
namespace absyntax
{
#ifdef HAVE_LSP
DEC_CREATE_SYM_MAP_EXP(nameExp)
{
AsymptoteLsp::SymbolLit accessedName(value->getLit());
position basePos= getPos();
AsymptoteLsp::filePos castedPos=
dynamic_cast<qualifiedName*>(value)
? std::make_pair(
mem::stdString(basePos.filename()),
std::make_pair(basePos.Line(), basePos.Column() + 1)
)
: static_cast<AsymptoteLsp::filePos>(basePos);
auto varUsageIt= symContext->symMap.varUsage.find(accessedName);
if (varUsageIt == symContext->symMap.varUsage.end()) {
symContext->symMap.varUsage.emplace(accessedName, castedPos);
} else {
varUsageIt->second.add(castedPos);
}
symContext->symMap.usageByLines.emplace_back(castedPos.second, accessedName);
}
DEC_CREATE_SYM_MAP_EXP(argument) { val->createSymMap(symContext); }
DEC_CREATE_SYM_MAP_EXP(arglist)
{
for (auto& p : args) {
p.createSymMap(symContext);
}
}
DEC_CREATE_SYM_MAP_EXP(callExp)
{
callee->createSymMap(symContext);
args->createSymMap(symContext);
if (auto col= getColorInformation()) {
auto const& v= col.value();
auto const& colVal= std::get<0>(v);
auto const& alpha= std::get<1>(v);
auto const& beginArgPos= std::get<2>(v);
auto const& lastArgPos= std::get<3>(v);
if (alpha.has_value()) {
auto const& red= std::get<0>(colVal);
auto const& green= std::get<1>(colVal);
auto const& blue= std::get<2>(colVal);
std::tuple<double, double, double, double> rgba(
red, green, blue, alpha.value()
);
symContext->addRGBAColor(rgba, beginArgPos, lastArgPos);
} else {
symContext->addRGBColor(colVal, beginArgPos, lastArgPos);
}
}
}
DEC_CREATE_SYM_MAP_EXP(castExp) { castee->createSymMap(symContext); }
DEC_CREATE_SYM_MAP_EXP(assignExp)
{
dest->createSymMap(symContext);
value->createSymMap(symContext);
}
optional<std::tuple<
callExp::colorInfo, optional<double>, AsymptoteLsp::posInFile,
AsymptoteLsp::posInFile>>
callExp::getColorInformation()
{
auto* namedCallee= dynamic_cast<nameExp*>(callee);
if (namedCallee == nullptr) {
return nullopt;
}
std::string calleeName= static_cast<std::string>(namedCallee->getName());
std::vector<double> colors;
auto getLineColumn= [&argsval= args->args](int const& idx) {
return argsval[idx].val->getPos().LineColumn();
};
if (calleeName == "rgb" || calleeName == "rgba") {
for (auto const& expVec : args->args) {
if (auto* valExp= dynamic_cast<realExp*>(expVec.val)) {
colors.push_back(valExp->getValue<double>());
} else if (auto* valExpI= dynamic_cast<intExp*>(expVec.val)) {
colors.push_back(valExpI->getValue<double>());
}
}
}
if (calleeName == "rgb" && colors.size() == 3) {
callExp::colorInfo col(colors[0], colors[1], colors[2]);
return std::make_tuple(
col, optional<double>(), callee->getPos().LineColumn(),
getLineColumn(2)
);
} else if (calleeName == "rgba" && colors.size() == 4) {
callExp::colorInfo col(colors[0], colors[1], colors[2]);
return std::make_tuple(
col, optional<double>(colors[3]), callee->getPos().LineColumn(),
getLineColumn(3)
);
}
return nullopt;
}
#else
# define DEC_CREATE_SYM_MAP_EXP_EMPTY(derived_class) \
DEC_CREATE_SYM_MAP_EXP(derived_class) {}
DEC_CREATE_SYM_MAP_EXP_EMPTY(nameExp)
DEC_CREATE_SYM_MAP_EXP_EMPTY(argument)
DEC_CREATE_SYM_MAP_EXP_EMPTY(arglist)
DEC_CREATE_SYM_MAP_EXP_EMPTY(callExp)
DEC_CREATE_SYM_MAP_EXP_EMPTY(castExp)
DEC_CREATE_SYM_MAP_EXP_EMPTY(assignExp)
optional<std::tuple<
callExp::colorInfo, optional<double>, AsymptoteLsp::posInFile,
AsymptoteLsp::posInFile>>
callExp::getColorInformation()
{
return nullopt;
}
#endif
}// namespace absyntax