Skip to content

Commit

Permalink
Did cs, java, and js.
Browse files Browse the repository at this point in the history
  • Loading branch information
InsertCreativityHere committed Dec 11, 2024
1 parent 2ad9856 commit f34b90f
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 794 deletions.
265 changes: 71 additions & 194 deletions cpp/src/slice2cs/CsUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include "CsUtil.h"
#include "../Slice/MetadataValidation.h"
#include "../Slice/Util.h"
#include "DotNetNames.h"
#include "Ice/StringUtil.h"
Expand Down Expand Up @@ -1864,212 +1865,88 @@ Slice::CsGenerator::toArrayAlloc(const string& decl, const string& sz)
void
Slice::CsGenerator::validateMetadata(const UnitPtr& u)
{
MetadataVisitor visitor;
u->visit(&visitor);
}

bool
Slice::CsGenerator::MetadataVisitor::visitUnitStart(const UnitPtr& unit)
{
// Validate file metadata in the top-level file and all included files.
for (const auto& file : unit->allFiles())
{
DefinitionContextPtr dc = unit->findDefinitionContext(file);
assert(dc);

MetadataList newFileMetadata;
for (const auto& metadata : dc->getMetadata())
{
string_view directive = metadata->directive();
if (directive.find("cs:") == 0 && directive != "cs:attribute")
{
ostringstream msg;
msg << "ignoring invalid file metadata '" << *metadata << "'";
unit->warning(metadata->file(), metadata->line(), InvalidMetadata, msg.str());
continue;
}
newFileMetadata.push_back(metadata);
}
dc->setMetadata(std::move(newFileMetadata));
}
return true;
}

bool
Slice::CsGenerator::MetadataVisitor::visitModuleStart(const ModulePtr& p)
{
validate(p);
return true;
}

void
Slice::CsGenerator::MetadataVisitor::visitClassDecl(const ClassDeclPtr& p)
{
validate(p);
}

bool
Slice::CsGenerator::MetadataVisitor::visitExceptionStart(const ExceptionPtr& p)
{
validate(p);
return true;
}

bool
Slice::CsGenerator::MetadataVisitor::visitStructStart(const StructPtr& p)
{
validate(p);
return true;
}

void
Slice::CsGenerator::MetadataVisitor::visitOperation(const OperationPtr& p)
{
validate(p);
for (const auto& param : p->parameters())
{
visitParameter(param);
}
}

void
Slice::CsGenerator::MetadataVisitor::visitParameter(const ParameterPtr& p)
{
validate(p);
}

void
Slice::CsGenerator::MetadataVisitor::visitDataMember(const DataMemberPtr& p)
{
validate(p);
}

void
Slice::CsGenerator::MetadataVisitor::visitSequence(const SequencePtr& p)
{
validate(p);
}

void
Slice::CsGenerator::MetadataVisitor::visitDictionary(const DictionaryPtr& p)
{
validate(p);
}
map<string, MetadataInfo> knownMetadata;

void
Slice::CsGenerator::MetadataVisitor::visitEnum(const EnumPtr& p)
{
validate(p);
}
// "cs:attribute"
MetadataInfo attributeInfo;
attributeInfo.validOn = {
typeid(Unit),
typeid(Module),
typeid(InterfaceDecl),
typeid(ClassDecl),
typeid(Operation),
typeid(Slice::Exception),
typeid(Struct),
typeid(Enum),
typeid(Const),
typeid(Parameter),
typeid(DataMember)};
attributeInfo.acceptedArgumentKind = MetadataArgumentKind::RequiredTextArgument;
attributeInfo.mustBeUnique = false;
knownMetadata.emplace("cs:attribute", attributeInfo);

void
Slice::CsGenerator::MetadataVisitor::visitConst(const ConstPtr& p)
{
validate(p);
}
// "cs:class"
MetadataInfo classInfo;
classInfo.validOn = {typeid(Struct)};
classInfo.acceptedArgumentKind = MetadataArgumentKind::NoArguments;
knownMetadata.emplace("cs:class", std::move(classInfo));

void
Slice::CsGenerator::MetadataVisitor::validate(const ContainedPtr& cont)
{
MetadataList newLocalMetadata;
for (const auto& metadata : cont->getMetadata())
// "cs:generic"
MetadataInfo genericInfo;
genericInfo.validOn = {typeid(Sequence), typeid(Dictionary)};
genericInfo.acceptedArgumentKind = MetadataArgumentKind::RequiredTextArgument;
genericInfo.extraValidation = [](const MetadataPtr& meta, const SyntaxTreeBasePtr& p) -> optional<string>
{
string_view directive = metadata->directive();
string_view arguments = metadata->arguments();

if (directive.find("cs:") == 0)
const string& argument = meta->arguments();
if (auto seq = dynamic_pointer_cast<Sequence>(p); seq && seq->type()->isClassType())
{
SequencePtr seq = dynamic_pointer_cast<Sequence>(cont);
if (seq)
{
if (directive == "cs:generic")
{
if (arguments == "LinkedList" || arguments == "Queue" || arguments == "Stack")
{
if (!seq->type()->isClassType())
{
newLocalMetadata.push_back(metadata);
continue;
}
}
else if (!arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue; // Custom type or List<T>
}
}
}
else if (dynamic_pointer_cast<Struct>(cont))
{
if ((directive == "cs:class" || directive == "cs:property") && arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue;
}
if (directive == "cs:implements" && !arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue;
}
}
else if (dynamic_pointer_cast<ClassDecl>(cont) || dynamic_pointer_cast<Exception>(cont))
if (argument == "LinkedList" || argument == "Queue" || argument == "Stack")
{
if (directive == "cs:property" && arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue;
}
return "'cs:generic:" + argument + "' is not supported on for sequences of objects; only 'List' is supported for object sequences";
}
else if (dynamic_pointer_cast<InterfaceDecl>(cont))
{
if (directive == "cs:implements" && !arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue;
}
}
else if (dynamic_pointer_cast<Dictionary>(cont))
{
if (directive == "cs:generic")
{
if (arguments == "SortedDictionary" || arguments == "SortedList")
{
newLocalMetadata.push_back(metadata);
continue;
}
}
}
else if (dynamic_pointer_cast<DataMember>(cont))
{
DataMemberPtr dataMember = dynamic_pointer_cast<DataMember>(cont);
StructPtr st = dynamic_pointer_cast<Struct>(dataMember->container());
ExceptionPtr ex = dynamic_pointer_cast<Exception>(dataMember->container());
ClassDeclPtr cl = dynamic_pointer_cast<ClassDecl>(dataMember->container());
static const string csTypePrefix = "cs:type:";
// TODO Seems like this validation only got half written?...
}
else if (dynamic_pointer_cast<Module>(cont))
}
else if (dynamic_pointer_cast<Dictionary>(p))
{
if (argument != "SortedDictionary" && argument != "SortedList")
{
if (directive == "cs:namespace" && !arguments.empty())
{
newLocalMetadata.push_back(metadata);
continue;
}
return "the 'cs:generic' metadata only supports 'SortedDictionary' and 'SortedList' as arguments when applied to a dictionary";
}
}
return nullopt;
};
knownMetadata.emplace("cs:generic", genericInfo);

if (directive == "cs:attribute" && !arguments.empty())
// TODO: this is being removed. We tell the validator to perform basically no checking.
// "cs:implements"
MetadataInfo implementsInfo;
implementsInfo.acceptedArgumentKind = MetadataArgumentKind::OptionalTextArgument;
implementsInfo.mustBeUnique = false;
knownMetadata.emplace("cs:implements", std::move(implementsInfo));

// "cs:namespace"
MetadataInfo namespaceInfo;
namespaceInfo.validOn = {typeid(Module)};
namespaceInfo.acceptedArgumentKind = MetadataArgumentKind::SingleArgument;
namespaceInfo.extraValidation = [](const MetadataPtr&, const SyntaxTreeBasePtr& p) -> optional<string>
{
// 'cs:namespace' can only be applied to top-level modules
if (auto mod = dynamic_pointer_cast<Module>(p))
{
// Top-level modules are contained by the 'Unit'. Non-top-level modules are contained in 'Module's.
if (!dynamic_pointer_cast<Unit>(mod->container()))
{
newLocalMetadata.push_back(metadata);
continue;
return "the 'cs:namespace' metadata can only be applied to top-level modules";
}

ostringstream msg;
msg << "ignoring invalid metadata '" << *metadata << "'";
cont->unit()->warning(metadata->file(), metadata->line(), InvalidMetadata, msg.str());
continue;
}
newLocalMetadata.push_back(metadata);
}
return nullopt;
};
knownMetadata.emplace("cs:namespace", std::move(namespaceInfo));

// "cs:property"
MetadataInfo propertyInfo;
propertyInfo.validOn = {typeid(ClassDecl), typeid(Slice::Exception), typeid(Struct)};
propertyInfo.acceptedArgumentKind = MetadataArgumentKind::NoArguments;
knownMetadata.emplace("cs:property", std::move(propertyInfo));

cont->setMetadata(std::move(newLocalMetadata));
Slice::validateMetadata(u, "cs", knownMetadata);
}
28 changes: 0 additions & 28 deletions cpp/src/slice2cs/CsUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ namespace Slice
//
static std::string toArrayAlloc(const std::string& decl, const std::string& sz);

//
// Validate all metadata in the unit with a "cs:" prefix.
//
static void validateMetadata(const UnitPtr&);

//
Expand Down Expand Up @@ -102,31 +99,6 @@ namespace Slice
int,
bool,
const std::string& = "");

private:
class MetadataVisitor final : public ParserVisitor
{
public:
bool visitUnitStart(const UnitPtr&) final;
bool visitModuleStart(const ModulePtr&) final;
void visitClassDecl(const ClassDeclPtr&) final;
bool visitExceptionStart(const ExceptionPtr&) final;
bool visitStructStart(const StructPtr&) final;
void visitOperation(const OperationPtr&) final;
void visitParameter(const ParameterPtr&) final;
void visitDataMember(const DataMemberPtr&) final;
void visitSequence(const SequencePtr&) final;
void visitDictionary(const DictionaryPtr&) final;
void visitEnum(const EnumPtr&) final;
void visitConst(const ConstPtr&) final;

bool shouldVisitIncludedDefinitions() const final { return true; }

private:
void validate(const ContainedPtr&);

std::string _fileName;
};
};
}

Expand Down
Loading

0 comments on commit f34b90f

Please sign in to comment.