gool.generator.cpp.CppCodePrinter.java Source code

Java tutorial

Introduction

Here is the source code for gool.generator.cpp.CppCodePrinter.java

Source

/*
 * Copyright 2010 Pablo Arrighi, Alex Concha, Miguel Lezama for version 1.
 * Copyright 2013 Pablo Arrighi, Miguel Lezama, Kevin Mazet for version 2.    
 *
 * This file is part of GOOL.
 *
 * GOOL is free software: you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation, version 3.
 *
 * GOOL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU General Public License along with GOOL,
 * in the file COPYING.txt.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Creates C++ files during the C++ generation process
 */

package gool.generator.cpp;

import gool.ast.core.ClassDef;
import gool.generator.common.CodePrinter;
import gool.generator.common.GeneratorMatcher;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import logger.Log;

import org.apache.commons.lang.StringUtils;

/**
 * Provides the basic functionality to generate C++ code from a list of GOOL
 * classes.
 */
public class CppCodePrinter extends CodePrinter {
    private static final String TEMPLATE_DIR = "gool/generator/cpp/templates/";

    private void createFinallyInclude(File outputDir) {
        FileOutputStream goolHelperOut;
        byte[] buffer = new byte[1024];
        int noOfBytes;

        // Helpers to create by copying the resource
        List<String> goolHelperIn = new ArrayList<String>();
        goolHelperIn.add("finally.h");
        if (!outputDir.isDirectory() && !outputDir.mkdirs()) {
            Log.e(String.format("Impossible to create the directory '%s'", outputDir));
        } else {
            // Print finally
            for (String in : goolHelperIn) {
                InputStream helper;
                try {
                    helper = CppPlatform.class.getResource(in).openStream();

                    goolHelperOut = new FileOutputStream(outputDir + "/" + in);
                    while ((noOfBytes = helper.read(buffer)) != -1) {
                        goolHelperOut.write(buffer, 0, noOfBytes);
                    }
                    goolHelperOut.close();
                    helper.close();
                } catch (IOException e) {
                    Log.e(String.format("Impossible to create the file '%s'", in));
                }
            }
        }
    }

    public CppCodePrinter(File outputDir, Collection<File> myF) {
        super(new CppGenerator(), outputDir, myF);
        createFinallyInclude(outputDir);
    }

    @Override
    public String getTemplateDir() {
        return TEMPLATE_DIR;
    }

    @Override
    public List<File> print(ClassDef pclass) throws FileNotFoundException {

        // GOOL library classes are printed in a different manner
        if (pclass.isGoolLibraryClass()) {
            return printGoolLibraryClass(pclass);
        }
        /*
         * In C++ the parent class and the interfaces are used in the same
         * statement. Example: class Foo : public ClassBar1, InterfaceBar2 ...
         * {}
         */

        if (pclass.getParentClass() != null) {
            pclass.getInterfaces().add(0, pclass.getParentClass());
        }

        String headerFile = processTemplate("header.vm", pclass);
        PrintWriter writer;

        File dir = new File(getOutputDir().getAbsolutePath(),
                StringUtils.replace(pclass.getPackageName(), ".", File.separator));
        dir.mkdirs();
        File classFile = new File(dir, pclass.getName() + ".h");

        writer = new PrintWriter(classFile);
        writer.println(headerFile);
        writer.close();

        /*
         * Only generate header files if this element is an interface or an
         * enumeration.
         */
        if (pclass.isEnum() || pclass.isInterface()) {
            List<File> r = new ArrayList<File>();
            r.add(classFile);
            return r;
        } else {
            return super.print(pclass);
        }
    }

    @Override
    public List<File> printGoolLibraryClass(ClassDef pclass) throws FileNotFoundException {
        String goolClass = pclass.getPackageName() + "." + pclass.getName();

        ArrayList<String> goolClassImplems = new ArrayList<String>();
        for (String Import : GeneratorMatcher.matchImports(goolClass))
            if (Import.startsWith("+"))
                goolClassImplems.add(Import.substring(1));

        List<File> result = new ArrayList<File>();
        for (String goolClassImplem : goolClassImplems) {
            String goolClassImplemName = goolClassImplem.substring(goolClassImplem.lastIndexOf(".") + 1);
            String goolClassImplemPackage = goolClassImplem.substring(0, goolClassImplem.lastIndexOf("."));
            String implemFileName = goolClassImplemName + ".cpp";
            String headerFileName = goolClassImplemName + ".h";
            String codeImplem = GeneratorMatcher.matchGoolClassImplementation(goolClass, implemFileName);
            String codeHeader = GeneratorMatcher.matchGoolClassImplementation(goolClass, headerFileName);
            File dir = new File(getOutputDir().getAbsolutePath(),
                    StringUtils.replace(goolClassImplemPackage, ".", File.separator));
            dir.mkdirs();
            File implemFile = new File(dir, implemFileName);
            File headerFile = new File(dir, headerFileName);

            //print implementation file
            PrintWriter writer = new PrintWriter(implemFile);
            writer.println(codeImplem);
            writer.close();

            //print header file
            writer = new PrintWriter(headerFile);
            writer.println(codeHeader);
            writer.close();
        }
        printedClasses.add(pclass);
        return result;
    }

    @Override
    public String getFileName(String className) {
        return className + ".cpp";
    }
}