All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.juniversal.translator.csharp.CompilationUnitWriter Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2012-2015, Microsoft Mobile
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.juniversal.translator.csharp;

import org.eclipse.jdt.core.dom.*;
import org.jetbrains.annotations.Nullable;
import org.juniversal.translator.core.BufferTargetWriter;
import org.juniversal.translator.core.SourceFileWriter;
import org.juniversal.translator.core.Var;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static org.juniversal.translator.core.ASTUtil.forEach;
import static org.juniversal.translator.core.ASTUtil.isGenericImport;


// TODO: Finish this

class CompilationUnitWriter extends CSharpASTNodeWriter {
    CompilationUnitWriter(CSharpSourceFileWriter cSharpASTWriters) {
        super(cSharpASTWriters);
    }

    public void write(CompilationUnit compilationUnit) {
        copySpaceAndComments();

        // First visit & write out the guts of the class, using a BufferTargetWriter to capture all output.   We do
        // this first to capture the usage of anything that needs an explicit "using" statement in C# but doesn't
        // have an import in Java.   The top of the file, with the "using" statements, is written later, down below
        BufferTargetWriter bufferTargetWriter = new BufferTargetWriter(getSourceFileWriter().getTargetWriter());
        try (SourceFileWriter.RestoreTargetWriter ignored = getSourceFileWriter().setTargetWriter(bufferTargetWriter)) {
            writeNamespaceAndTypeDeclaration(compilationUnit);
        }

        @Nullable PackageDeclaration packageDeclaration = compilationUnit.getPackage();
        if (packageDeclaration != null) {
            // TODO: This results in an extra newline normally; distinguish between case where package is only thing on line & multiple things on that line
            setPositionToEndOfNodeSpaceAndComments(packageDeclaration);
        } else {
            setPositionToStartOfNode(compilationUnit);
            skipSpaceAndComments();
        }

        // Write
        copySpaceAndComments();
        writeUsingStatements(compilationUnit);

        copySpaceAndComments();
        write(bufferTargetWriter);

        setPositionToEndOfNode(compilationUnit);
    }

    private void writeUsingStatements(CompilationUnit compilationUnit) {
        Map annotationMap = getSourceFileWriter().getTranslator().getAnnotationMap();
        Set genericUsings = new HashSet<>();

        Var wroteUsing = new Var<>(false);
        forEach(compilationUnit.imports(), (ImportDeclaration importDeclaration) -> {
            Name importDeclarationName = importDeclaration.getName();

            String importDeclarationFullyQualifiedName = importDeclarationName.getFullyQualifiedName();

            // Skip imports for the Nullable annotation and mapped annotations
            if (importDeclarationFullyQualifiedName.equals("org.jetbrains.annotations.Nullable") ||
                annotationMap.containsKey(importDeclarationFullyQualifiedName)) {
                setPositionToEndOfNode(importDeclaration);
                return;
            }

            if (importDeclaration.isStatic())
                throw sourceNotSupported("Static imports aren't currently supported");

            if (!(importDeclarationName instanceof QualifiedName))
                throw sourceNotSupported("Class import is unexpectedly not a fully qualified name (with a '.' in it)");
            QualifiedName qualifiedName = (QualifiedName) importDeclarationName;

            @Nullable String namespaceToImportForGenericClass = null;
            if (isGenericImport(importDeclaration)) {
                namespaceToImportForGenericClass = qualifiedName.getQualifier().getFullyQualifiedName();
                if (genericUsings.contains(namespaceToImportForGenericClass))
                    return;
            }

            copySpaceAndComments();
            matchAndWrite("import", "using");

            copySpaceAndComments();
            if (importDeclaration.isOnDemand()) {
                writeNode(importDeclarationName);
                skipSpaceAndComments();
                match(".");
                skipSpaceAndComments();
                match("*");
            } else {
                if (namespaceToImportForGenericClass != null) {
                    write(namespaceToImportForGenericClass);
                    genericUsings.add(namespaceToImportForGenericClass);
                    setPositionToEndOfNode(qualifiedName);
                }
                else {
                    writeNodeAtDifferentPosition(qualifiedName.getName());
                    write(" = ");
                    writeNode(qualifiedName);
                }
            }

            copySpaceAndComments();
            matchAndWrite(";");
            wroteUsing.set(true);
        });

        if (wroteUsing.value())
            writeln();

        for (String extraUsing : getContext().getExtraUsings()) {
            write("using ");
            write(extraUsing);
            writeln(";");
        }
    }

    private void writeNamespaceAndTypeDeclaration(CompilationUnit compilationUnit) {
        @Nullable PackageDeclaration packageDeclaration = compilationUnit.getPackage();

        int previousIndent = 0;
        if (packageDeclaration != null) {
            int previousPosition = getPosition();
            setPositionToStartOfNode(packageDeclaration);
            matchAndWrite("package", "namespace");

            copySpaceAndComments();
            writeNode(packageDeclaration.getName());

            write(" {");
            previousIndent = getTargetWriter().incrementAdditionalIndentation(getPreferredIndent());
            writeln();

            setPosition(previousPosition);
        }

/*

        if (packageDeclaration != null)
        return getNamespaceNameForPackageName(packageDeclaration == null ? null : packageDeclaration
                .getName());
*/

        AbstractTypeDeclaration firstTypeDeclaration = (AbstractTypeDeclaration) compilationUnit.types().get(0);

        //copySpaceAndComments();
        setPositionToStartOfNode(firstTypeDeclaration);
        writeNode(firstTypeDeclaration);
        copySpaceAndComments();

        if (packageDeclaration != null) {
            getTargetWriter().setAdditionalIndentation(previousIndent);
            writeln();
            writeln("}");
        }

/*
        writeln();

        context.setPosition(firstTypeDeclaration.getStartPosition());
        copySpaceAndComments();   // Skip any Javadoc included in the node

        writeNode(context, firstTypeDeclaration);
*/
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy