<commit_before>/*
 * Copyright 2008, 2009 Google Inc.
 * Copyright 2007 Nintendo Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <set>
#include "java.h"

namespace
{

FILE* createFile(const std::string package, const Node* node)
{
    std::string filename = package;

    size_t pos = 0;
    for (;;)
    {
        pos = filename.find('.', pos);
        if (pos == std::string::npos)
        {
            break;
        }
        filename[pos] = '/';
    }

    filename += "/" + node->getName() + ".java";

    std::string dir;
    std::string path(filename);
    for (;;)
    {
        size_t slash = path.find("/");
        if (slash == std::string::npos)
        {
            break;
        }
        dir += path.substr(0, slash);
        path.erase(0, slash + 1);
        mkdir(dir.c_str(), 0777);
        dir += '/';
    }

    printf("# %s in %s\n", node->getName().c_str(), filename.c_str());
    return fopen(filename.c_str(), "w");
}

}  // namespace

class JavaInterface : public Java
{
    // TODO: Move to Java
    void visitInterfaceElement(const Interface* interface, Node* element)
    {
        if (dynamic_cast<Interface*>(element))
        {
            // Do not process Constructor.
            return;
        }

        optionalStage = 0;
        do
        {
            optionalCount = 0;
            element->accept(this);
            ++optionalStage;
        } while (optionalStage <= optionalCount);
    }

public:
    JavaInterface(const char* source, FILE* file, const char* indent = "es") :
        Java(source, file, indent)
    {
    }

    virtual void at(const ExceptDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public class %s extends RuntimeException {\n", node->getName().c_str());
            // TODO(Shiki): Need a constructor.
            printChildren(node);
        writeln("}");
    }

    virtual void at(const Interface* node)
    {
        assert(!(node->getAttr() & Interface::Supplemental) && !node->isLeaf());
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        std::string name = node->getQualifiedName();
        name = getInterfaceName(name);
        write("public interface %s", name.substr(name.rfind(':') + 1).c_str());
        if (node->getExtends())
        {
            const char* separator = " extends ";
            for (NodeList::iterator i = node->getExtends()->begin();
                 i != node->getExtends()->end();
                 ++i)
            {
                if ((*i)->getName() == Node::getBaseObjectName())
                {
                    // Do not extend from 'Object'.
                    continue;
                }
                write(separator);
                separator = ", ";
                (*i)->accept(this);
            }
        }
        write(" {\n");

        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            visitInterfaceElement(node, *i);
        }

        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
                i != interfaceList.end();
                ++i)
        {
            if (*i == node)
            {
                continue;
            }
            writeln("// %s", (*i)->getName().c_str());
            for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j)
            {
                visitInterfaceElement(*i, *j);
            }
        }

        writeln("}");
    }

    virtual void at(const BinaryExpr* node)
    {
        node->getLeft()->accept(this);
        write(" %s ", node->getName().c_str());
        node->getRight()->accept(this);
    }

    virtual void at(const UnaryExpr* node)
    {
        write("%s", node->getName().c_str());
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
    }

    virtual void at(const GroupingExpression* node)
    {
        write("(");
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
        write(")");
    }

    virtual void at(const Literal* node)
    {
        write("%s", node->getName().c_str());
    }

    virtual void at(const Member* node)
    {
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        write("public ");
        node->getSpec()->accept(this);
        write(" %s;\n", node->getName().c_str());
    }

    virtual void at(const ArrayDcl* node)
    {
        assert(!node->isLeaf());
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        node->getSpec()->accept(this);
        write(" %s", node->getName().c_str());
        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            write("[");
            (*i)->accept(this);
            write("]");
        }
        if (node->isTypedef(node->getParent()))
        {
            write(";\n");
        }
    }

    virtual void at(const ConstDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public static final ");
        node->getSpec()->accept(this);
        write(" %s = ", node->getName().c_str());
        node->getExp()->accept(this);
        write(";\n");
    }

    virtual void at(const Attribute* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        // getter
        Java::getter(node);
        write(";\n");

        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            // setter
            writetab();
            Java::setter(node);
            write(";\n");
        }
    }

    virtual void at(const OpDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        Java::at(node);
        write(";\n");
    }
};

class JavaImport : public Visitor, public Formatter
{
    std::string package;
    const Interface* current;
    bool printed;
    std::string prefixedName;
    std::set<std::string> importSet;

public:
    JavaImport(std::string package, FILE* file, const char* indent) :
        Formatter(file, indent),
        package(package),
        current(0)
    {
    }

    virtual void at(const Node* node)
    {
        visitChildren(node);
    }

    virtual void at(const ScopedName* node)
    {
        assert(current);

        if (node->isBaseObject())
        {
            return;
        }
        std::string name = node->getName();
        Node* resolved = resolve(current, name);
        if (resolved)
        {
            if (Module* module = dynamic_cast<Module*>(resolved->getParent()))
            {
                if (prefixedName != module->getPrefixedName())
                {
                    importSet.insert(Java::getPackageName(module->getPrefixedName()) + "." + node->getIdentifier());
                }
            }
        }
    }

    virtual void at(const Interface* node)
    {
        if (current)
        {
            return;
        }
        current = node;
        if (Module* module = dynamic_cast<Module*>(node->getParent()))
        {<commit_msg>(at(const ScopedName* node)) : Fix to follow typedef name.<commit_after>/*
 * Copyright 2008, 2009 Google Inc.
 * Copyright 2007 Nintendo Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <set>
#include "java.h"

namespace
{

FILE* createFile(const std::string package, const Node* node)
{
    std::string filename = package;

    size_t pos = 0;
    for (;;)
    {
        pos = filename.find('.', pos);
        if (pos == std::string::npos)
        {
            break;
        }
        filename[pos] = '/';
    }

    filename += "/" + node->getName() + ".java";

    std::string dir;
    std::string path(filename);
    for (;;)
    {
        size_t slash = path.find("/");
        if (slash == std::string::npos)
        {
            break;
        }
        dir += path.substr(0, slash);
        path.erase(0, slash + 1);
        mkdir(dir.c_str(), 0777);
        dir += '/';
    }

    printf("# %s in %s\n", node->getName().c_str(), filename.c_str());
    return fopen(filename.c_str(), "w");
}

}  // namespace

class JavaInterface : public Java
{
    // TODO: Move to Java
    void visitInterfaceElement(const Interface* interface, Node* element)
    {
        if (dynamic_cast<Interface*>(element))
        {
            // Do not process Constructor.
            return;
        }

        optionalStage = 0;
        do
        {
            optionalCount = 0;
            element->accept(this);
            ++optionalStage;
        } while (optionalStage <= optionalCount);
    }

public:
    JavaInterface(const char* source, FILE* file, const char* indent = "es") :
        Java(source, file, indent)
    {
    }

    virtual void at(const ExceptDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public class %s extends RuntimeException {\n", node->getName().c_str());
            // TODO(Shiki): Need a constructor.
            printChildren(node);
        writeln("}");
    }

    virtual void at(const Interface* node)
    {
        assert(!(node->getAttr() & Interface::Supplemental) && !node->isLeaf());
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        std::string name = node->getQualifiedName();
        name = getInterfaceName(name);
        write("public interface %s", name.substr(name.rfind(':') + 1).c_str());
        if (node->getExtends())
        {
            const char* separator = " extends ";
            for (NodeList::iterator i = node->getExtends()->begin();
                 i != node->getExtends()->end();
                 ++i)
            {
                if ((*i)->getName() == Node::getBaseObjectName())
                {
                    // Do not extend from 'Object'.
                    continue;
                }
                write(separator);
                separator = ", ";
                (*i)->accept(this);
            }
        }
        write(" {\n");

        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            visitInterfaceElement(node, *i);
        }

        // Expand mixins
        std::list<const Interface*> interfaceList;
        node->collectMixins(&interfaceList, node);
        for (std::list<const Interface*>::const_iterator i = interfaceList.begin();
                i != interfaceList.end();
                ++i)
        {
            if (*i == node)
            {
                continue;
            }
            writeln("// %s", (*i)->getName().c_str());
            for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j)
            {
                visitInterfaceElement(*i, *j);
            }
        }

        writeln("}");
    }

    virtual void at(const BinaryExpr* node)
    {
        node->getLeft()->accept(this);
        write(" %s ", node->getName().c_str());
        node->getRight()->accept(this);
    }

    virtual void at(const UnaryExpr* node)
    {
        write("%s", node->getName().c_str());
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
    }

    virtual void at(const GroupingExpression* node)
    {
        write("(");
        NodeList::iterator elem = node->begin();
        (*elem)->accept(this);
        write(")");
    }

    virtual void at(const Literal* node)
    {
        write("%s", node->getName().c_str());
    }

    virtual void at(const Member* node)
    {
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        write("public ");
        node->getSpec()->accept(this);
        write(" %s;\n", node->getName().c_str());
    }

    virtual void at(const ArrayDcl* node)
    {
        assert(!node->isLeaf());
        if (node->isTypedef(node->getParent()))
        {
            return;
        }

        writetab();
        node->getSpec()->accept(this);
        write(" %s", node->getName().c_str());
        for (NodeList::iterator i = node->begin(); i != node->end(); ++i)
        {
            write("[");
            (*i)->accept(this);
            write("]");
        }
        if (node->isTypedef(node->getParent()))
        {
            write(";\n");
        }
    }

    virtual void at(const ConstDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        write("public static final ");
        node->getSpec()->accept(this);
        write(" %s = ", node->getName().c_str());
        node->getExp()->accept(this);
        write(";\n");
    }

    virtual void at(const Attribute* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }

        // getter
        Java::getter(node);
        write(";\n");

        if (!node->isReadonly() || node->isPutForwards() || node->isReplaceable())
        {
            // setter
            writetab();
            Java::setter(node);
            write(";\n");
        }
    }

    virtual void at(const OpDcl* node)
    {
        writetab();
        if (node->getJavadoc().size())
        {
            write("%s\n", node->getJavadoc().c_str());
            writetab();
        }
        Java::at(node);
        write(";\n");
    }
};

class JavaImport : public Visitor, public Formatter
{
    std::string package;
    const Interface* current;
    bool printed;
    std::string prefixedName;
    std::set<std::string> importSet;

public:
    JavaImport(std::string package, FILE* file, const char* indent) :
        Formatter(file, indent),
        package(package),
        current(0)
    {
    }

    virtual void at(const Node* node)
    {
        visitChildren(node);
    }

    virtual void at(const ScopedName* node)
    {
        assert(current);

        if (node->isBaseObject())
        {
            return;
        }
        std::string name = node->getName();
        Node* resolved = node->search(current);
        if (resolved)
        {
            if (Module* module = dynamic_cast<Module*>(resolved->getParent()))
            {
                if (prefixedName != module->getPrefixedName())
                {
                    importSet.insert(Java::getPackageName(module->getPrefixedName()) + "." + node->getIdentifier());
                }
            }
        }
    }

    virtual void at(const Interface* node)
    {
        if (current)
        {
            return;
        }
        current = node;
        if (Module* module = dynamic_cast<Module*>(node->getParent()))
        {
{'fraction_non_alphanumeric': 0.1602123295934371, 'fraction_numerical': 0.0033779708046809023, 'mean_word_length': 1.707217504898759, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 166, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3250238', 'n_tokens_mistral': 4891, 'n_tokens_neox': 4708, 'n_words': 1056}