blob: 18ae6a91098244e3127221f466e37d686900bfd8 [file] [log] [blame]
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_ENUM
#define SKSL_ENUM
#include "include/private/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLSymbolTable.h"
#include "src/sksl/ir/SkSLVariable.h"
#include <algorithm>
#include <vector>
namespace SkSL {
class Symbol;
class Enum final : public ProgramElement {
public:
static constexpr Kind kProgramElementKind = Kind::kEnum;
Enum(int offset, skstd::string_view typeName, std::shared_ptr<SymbolTable> symbols,
bool isSharedWithCpp, bool isBuiltin = true)
: INHERITED(offset, kProgramElementKind)
, fTypeName(typeName)
, fSymbols(std::move(symbols))
, fIsSharedWithCpp(isSharedWithCpp)
, fIsBuiltin(isBuiltin) {}
skstd::string_view typeName() const {
return fTypeName;
}
std::shared_ptr<SymbolTable> symbols() const {
return fSymbols;
}
bool isBuiltin() const {
return fIsBuiltin;
}
bool isSharedWithCpp() const {
return fIsSharedWithCpp;
}
std::unique_ptr<ProgramElement> clone() const override {
return std::make_unique<Enum>(fOffset, this->typeName(),
SymbolTable::WrapIfBuiltin(this->symbols()),
this->isSharedWithCpp(), /*isBuiltin=*/false);
}
String code() const {
String result = "enum class " + this->typeName() + " {\n";
String separator;
struct Enumerant { skstd::string_view name; SKSL_INT value; };
std::vector<Enumerant> sortedSymbols;
sortedSymbols.reserve(symbols()->count());
this->foreach([&](skstd::string_view name, SKSL_INT value){
sortedSymbols.push_back({name, value});
});
std::sort(sortedSymbols.begin(), sortedSymbols.end(),
[](const Enumerant& a, const Enumerant& b) { return a.value < b.value; });
for (const auto& entry : sortedSymbols) {
result += separator + " " + entry.name + " = " + to_string(entry.value);
separator = ",\n";
}
result += "\n};";
return result;
}
String description() const override {
return this->code();
}
template <typename Fn> void foreach(Fn&& fn) const {
this->symbols()->foreach(
[&fn](skstd::string_view name, const Symbol* symbol) {
fn(name, EnumValue(symbol));
});
}
private:
static SKSL_INT EnumValue(const Symbol* symbol) {
return symbol->as<Variable>().initialValue()->as<IntLiteral>().value();
}
skstd::string_view fTypeName;
std::shared_ptr<SymbolTable> fSymbols;
bool fIsSharedWithCpp;
bool fIsBuiltin;
using INHERITED = ProgramElement;
};
} // namespace SkSL
#endif