Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for cpp:identifier Metadata, and the Groundwork for xxx:identifier Metadata in General #3292

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cpp/src/Slice/MetadataValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ Slice::validateMetadata(const UnitPtr& p, string_view prefix, map<string, Metada
MetadataInfo deprecatedInfo = {
.validOn =
{typeid(InterfaceDecl),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just swapped the order here to be consistent with other lists.

typeid(ClassDecl),
typeid(Operation),
typeid(Exception),
typeid(ClassDecl),
typeid(Slice::Exception),
typeid(Struct),
typeid(Sequence),
typeid(Dictionary),
Expand Down
62 changes: 33 additions & 29 deletions cpp/src/Slice/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ compareTag(const T& lhs, const T& rhs)
return lhs->tag() < rhs->tag();
}

// NOTE: It is important that this list is kept in alphabetical order!
constexpr string_view languages[] = {"cpp", "cs", "java", "js", "matlab", "php", "python", "ruby", "swift"};

// Forward declare things from Bison and Flex the parser can use.
extern int slice_parse();
extern int slice_lineno;
Expand Down Expand Up @@ -104,8 +107,6 @@ Slice::Metadata::Metadata(string rawMetadata, string file, int line) : GrammarBa
if (firstColonPos != string::npos)
{
// Check if the metadata starts with a language prefix.
// NOTE: It is important that this list is kept in alphabetical order!
constexpr string_view languages[] = {"cpp", "cs", "java", "js", "matlab", "php", "python", "rb", "swift"};
string prefix = rawMetadata.substr(0, firstColonPos);
bool hasLangPrefix = binary_search(&languages[0], &languages[sizeof(languages) / sizeof(*languages)], prefix);
if (hasLangPrefix)
Expand Down Expand Up @@ -554,35 +555,37 @@ Slice::Contained::container() const
}

string
Slice::Contained::name() const
Slice::Contained::name(bool mappedName) const
{
return _name;
}
// If the mapped name was requested, we first check if any 'xxx:identifier' has been applied to this element.
// If so, we return that instead of the element's Slice identifier.
if (mappedName)
{
static const string metadata = string(_unit->languagePrefix()) + ":identifier";
if (auto customName = getMetadataArgs(metadata))
{
return *customName;
}
}

string
Slice::Contained::scoped() const
{
return _scoped;
return _name;
}

string
Slice::Contained::scope() const
Slice::Contained::scoped(bool mappedName) const
{
string::size_type idx = _scoped.rfind("::");
assert(idx != string::npos);
return string(_scoped, 0, idx + 2);
return scope(mappedName) + name(mappedName);
}

string
Slice::Contained::flattenedScope() const
Slice::Contained::scope(bool mappedName) const
{
string s = scope();
string::size_type pos = 0;
while ((pos = s.find("::", pos)) != string::npos)
string scoped;
if (auto container = dynamic_pointer_cast<Contained>(_container))
{
s.replace(pos, 2, "_");
scoped = container->scoped(mappedName);
}
return s;
return scoped + "::";
}

string
Expand Down Expand Up @@ -1050,12 +1053,6 @@ Slice::Contained::Contained(const ContainerPtr& container, const string& name)
_container(container),
_name(name)
{
ContainedPtr cont = dynamic_pointer_cast<Contained>(_container);
if (cont)
{
_scoped = cont->scoped();
}
_scoped += "::" + _name;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't much point to _scoped now.

Most of the calls to scoped() and scope() are for mapped identifiers, and now we have to compute their values on the fly. So, there's even less point to caching the _scoped name up-front. So, I removed it.

assert(_unit);
_file = _unit->currentFile();
_line = _unit->currentLine();
Expand Down Expand Up @@ -4555,19 +4552,25 @@ Slice::DataMember::DataMember(
// ----------------------------------------------------------------------
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the code below this is to allow the compilers to inject their languagePrefix into libSlice.


UnitPtr
Slice::Unit::createUnit(bool all, const StringList& defaultFileMetadata)
Slice::Unit::createUnit(string_view languagePrefix, bool all, const StringList& defaultFileMetadata)
{
MetadataList defaultMetadata;
for (const auto& metadataString : defaultFileMetadata)
{
defaultMetadata.push_back(make_shared<Metadata>(metadataString, "<command-line>", 0));
}

UnitPtr unit{new Unit{all, std::move(defaultMetadata)}};
UnitPtr unit{new Unit{languagePrefix, all, std::move(defaultMetadata)}};
unit->_unit = unit;
return unit;
}

string_view
Slice::Unit::languagePrefix() const
{
return _languagePrefix;
}

void
Slice::Unit::setDocComment(const string& comment)
{
Expand Down Expand Up @@ -5017,15 +5020,16 @@ Slice::Unit::getTopLevelModules(const string& file) const
}
}

Slice::Unit::Unit(bool all, MetadataList defaultFileMetadata)
Slice::Unit::Unit(std::string_view languagePrefix, bool all, MetadataList defaultFileMetadata)
: SyntaxTreeBase(nullptr),
Container(nullptr),
_languagePrefix(languagePrefix),
_all(all),
_defaultFileMetadata(std::move(defaultFileMetadata)),
_errors(0),
_currentIncludeLevel(0)

{
assert(binary_search(&languages[0], &languages[sizeof(languages) / sizeof(*languages)], _languagePrefix));
}

// ----------------------------------------------------------------------
Expand Down
21 changes: 13 additions & 8 deletions cpp/src/Slice/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,11 @@ namespace Slice
{
public:
[[nodiscard]] ContainerPtr container() const;
[[nodiscard]] std::string name() const;
[[nodiscard]] std::string scoped() const;
[[nodiscard]] std::string scope() const;
[[nodiscard]] std::string flattenedScope() const;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flattenedScope was only used by slice2cpp, so I moved the logic into that compiler.


[[nodiscard]] std::string name(bool mappedName = false) const;
[[nodiscard]] std::string scoped(bool mappedName = false) const;
[[nodiscard]] std::string scope(bool mappedName = false) const;

[[nodiscard]] std::string file() const;
[[nodiscard]] int line() const;

Expand Down Expand Up @@ -401,7 +402,6 @@ namespace Slice

ContainerPtr _container;
std::string _name;
std::string _scoped;
std::string _file;
int _line;
std::string _docComment;
Expand Down Expand Up @@ -453,7 +453,6 @@ namespace Slice
EnumeratorList enumerators() const;
EnumeratorList enumerators(const std::string& identifier) const;
ContainedList contents() const;
std::string thisScope() const;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only used internally.
Instead of keeping it public and adding the mappedName flag, I just made it protected, so only things in libSlice (which don't care about mapped names) can access it.

void visit(ParserVisitor* visitor) override;

bool checkIntroduced(const std::string& scopedName, ContainedPtr namedThing = nullptr);
Expand Down Expand Up @@ -483,6 +482,8 @@ namespace Slice
}

protected:
std::string thisScope() const;

bool validateConstant(
const std::string& name,
const TypePtr& type,
Expand Down Expand Up @@ -988,7 +989,10 @@ namespace Slice
class Unit final : public virtual Container
{
public:
static UnitPtr createUnit(bool all, const StringList& defaultFileMetadata = StringList());
static UnitPtr
createUnit(std::string_view languagePrefix, bool all, const StringList& defaultFileMetadata = StringList());

[[nodiscard]] std::string_view languagePrefix() const;

void setDocComment(const std::string& comment);
void addToDocComment(const std::string& comment);
Expand Down Expand Up @@ -1040,11 +1044,12 @@ namespace Slice
std::set<std::string> getTopLevelModules(const std::string& file) const;

private:
Unit(bool all, MetadataList defaultFileMetadata);
Unit(std::string_view languagePrefix, bool all, MetadataList defaultFileMetadata);

void pushDefinitionContext();
void popDefinitionContext();

const std::string_view _languagePrefix;
bool _all;
MetadataList _defaultFileMetadata;
int _errors;
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/ice2slice/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ compile(const vector<string>& argv)
}
else
{
UnitPtr p = Unit::createUnit(false);
UnitPtr p = Unit::createUnit("icerpc", false);
int parseStatus = p->parse(*i, cppHandle, debug);

if (!icecpp->close())
Expand Down
Loading
Loading