* @file
*
* This file declares auxiliary methods for java interop implementation
*/
#include "Utils.h"
#include "NativeFFI/Java/AfterTypeCheck/Utils.h"
#include "cangjie/AST/Node.h"
#include "cangjie/AST/Utils.h"
#include "cangjie/Utils/CheckUtils.h"
namespace Cangjie::Native::FFI::Java {
using namespace Cangjie::AST;
using namespace Cangjie::Interop::Java;
const Ptr<ClassDecl> GetSyntheticClass(const ImportManager& importManager, const ClassLikeDecl& cld)
{
ClassDecl* synthetic =
importManager.GetImportedDecl<ClassDecl>(cld.fullPackageName, GetMirrorReferenceWrapperNameFromClassLike(cld));
CJC_NULLPTR_CHECK(synthetic);
return Ptr(synthetic);
}
std::string GetMirrorReferenceWrapperNameFromClassLike(const ClassLikeDecl& mirrorDecl)
{
constexpr auto wrapperNameSuffix = "$impl";
CJC_ASSERT(mirrorDecl.IsInterfaceDecl() || mirrorDecl.IsAbstractClass());
CJC_ASSERT(IsMirror(mirrorDecl));
return mirrorDecl.identifier.Val() + wrapperNameSuffix;
}
std::string GetImplRegistryCompanionClassName(const ClassLikeDecl& javaImplDecl)
{
constexpr auto wrapperNameSuffix = "$reg";
CJC_ASSERT(IsImpl(javaImplDecl));
return javaImplDecl.identifier.Val() + wrapperNameSuffix;
}
std::vector<Ptr<AST::ClassLikeDecl>> GetJavaMirrors(AST::File& file)
{
std::vector<Ptr<ClassLikeDecl>> mirrors;
for (auto& decl : file.decls) {
if (IsMirror(*decl)) {
auto mirror = StaticAs<ASTKind::CLASS_LIKE_DECL>(decl.get());
mirrors.emplace_back(mirror);
}
}
return mirrors;
}
std::vector<Ptr<AST::ClassLikeDecl>> GetJavaMirrors(AST::Package& pkg)
{
std::vector<Ptr<ClassLikeDecl>> mirrors;
for (auto& file : pkg.files) {
auto fileMirrors = GetJavaMirrors(*file);
std::move(fileMirrors.begin(), fileMirrors.end(), std::back_inserter(mirrors));
}
return mirrors;
}
std::vector<Ptr<AST::ClassDecl>> GetJavaImpls(AST::File& file)
{
std::vector<Ptr<ClassDecl>> impls;
for (auto& decl : file.decls) {
if (IsImpl(*decl)) {
if (auto impl = As<ASTKind::CLASS_DECL>(decl.get())) {
impls.push_back(impl);
}
}
}
return impls;
}
std::vector<Ptr<AST::ClassDecl>> GetJavaImpls(AST::Package& pkg)
{
std::vector<Ptr<ClassDecl>> impls;
for (auto& file : pkg.files) {
auto fileImpls = GetJavaImpls(*file);
std::move(fileImpls.begin(), fileImpls.end(), std::back_inserter(impls));
}
return impls;
}
std::vector<Ptr<AST::ClassDecl>> GetJavaImplRegistryCompanions(AST::File& file)
{
std::vector<Ptr<ClassDecl>> companions;
for (auto& decl : file.decls) {
if (IsImplRegistryCompanion(*decl)) {
auto companion = StaticAs<ASTKind::CLASS_DECL>(decl.get());
companions.emplace_back(companion);
}
}
return companions;
}
std::vector<Ptr<AST::ClassDecl>> GetJavaImplRegistryCompanions(AST::Package& pkg)
{
std::vector<Ptr<ClassDecl>> impls;
for (auto& file : pkg.files) {
auto fileImpls = GetJavaImplRegistryCompanions(*file);
std::move(fileImpls.begin(), fileImpls.end(), std::back_inserter(impls));
}
return impls;
}
constexpr std::string_view JAVA_IMPL_REGISTRY_COMPANION_REFERENCE_FIELD_NAME_IN_REFERENCE_WRAPPER = "$reg";
bool IsJavaImplRegistryCompanionReferenceField(const AST::Node& node)
{
if (node.astKind != ASTKind::VAR_DECL) {
return false;
}
auto field = dynamic_cast<const VarDecl*>(&node);
if (!field) {
return false;
}
if (!field->outerDecl || !IsImplReferenceWrapper(*field->outerDecl)) {
return false;
}
return field->identifier == JAVA_IMPL_REGISTRY_COMPANION_REFERENCE_FIELD_NAME_IN_REFERENCE_WRAPPER;
}
}