/* * Copyright Red Hat Inc. and/or its affiliates and other contributors * as indicated by the authors tag. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU General Public License version 2. * * This particular file is subject to the "Classpath" exception as provided in the * LICENSE file that accompanied this code. * * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License, * along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.redhat.ceylon.compiler.java.test.bc; import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import junit.framework.Assert; import org.junit.Test; import com.redhat.ceylon.common.Versions; import com.redhat.ceylon.compiler.java.test.CompilerError; import com.redhat.ceylon.compiler.java.test.CompilerTests; import com.redhat.ceylon.compiler.java.util.Util; public class BcTests extends CompilerTests { private final String providerModuleSrc = "provider/module.ceylon"; private final String providerPackageSrc = "provider/package.ceylon"; private final String clientModuleSrc = "client/module.ceylon"; private final String clientModuleName = "com.redhat.ceylon.compiler.java.test.bc.client"; private final String providerModuleName = "com.redhat.ceylon.compiler.java.test.bc.provider"; /** * Checks that we can still compile a client after a change * @param ceylon */ protected void source(String ceylon) { String providerPreSrc = "provider/" + ceylon + "_pre.ceylon"; String providerPostSrc = "provider/" + ceylon + "_post.ceylon"; String clientSrc = "client/" + ceylon + "_client.ceylon"; // Compile provider compile(providerPreSrc, providerModuleSrc, providerPackageSrc); // Compile client compile(clientSrc, clientModuleSrc); // New version of provider compile(providerPostSrc, providerModuleSrc, providerPackageSrc); // Check the client still compilers compile(clientSrc, clientModuleSrc); } /** * Checks that we can still link an existing client after a change * @param ceylon */ protected void binary(String main, String ceylon) { String providerPreSrc = "provider/" + ceylon + "_pre.ceylon"; String providerPostSrc = "provider/" + ceylon + "_post.ceylon"; String clientSrc = "client/" + ceylon + "_client.ceylon"; // Compile provider compile(providerPreSrc, providerModuleSrc, providerPackageSrc); // Compile client compile(clientSrc, clientModuleSrc); // New version of provider compile(providerPostSrc, providerModuleSrc, providerPackageSrc); // Now try running the client ModuleWithArtifact clientModule = new ModuleWithArtifact(clientModuleName, "0.1"); ModuleWithArtifact providerModule = new ModuleWithArtifact(providerModuleName, "0.1"); run(clientModuleName + "." + main, clientModule, providerModule); } @Test public void testClassMethAddDefaultedParam() { source("ClassMethAddDefaultedParam"); binary("classMethAddDefaultedParam", "ClassMethAddDefaultedParam"); } @Test public void testFunctionAddDefaultedParam() { source("FunctionAddDefaultedParam"); binary("functionAddDefaultedParam_client", "FunctionAddDefaultedParam"); } @Test public void testClassInitAddDefaultedParam() { source("ClassInitAddDefaultedParam"); binary("classInitAddDefaultedParam", "ClassInitAddDefaultedParam"); } @Test public void testBinaryVersionIncompatible(){ compile("JavaOldVersion.java"); assertErrors("CeylonNewVersion", new CompilerError(-1, "Ceylon class com.redhat.ceylon.compiler.java.test.bc.JavaOldVersion was compiled by an incompatible version of the Ceylon compiler\n The class was compiled using 0.0.\n This compiler supports "+Versions.JVM_BINARY_MAJOR_VERSION+"."+Versions.JVM_BINARY_MINOR_VERSION+".\n Please try to recompile your module using a compatible compiler.\n Binary compatibility will only be supported after Ceylon 1.2.")); } // tests before we renamed module_.class to $module_.class @Test public void testBinaryVersionIncompatibleModule1() throws IOException { CompilationTask compiler = compileJava("binaryVersionOld/module_.java"); Assert.assertTrue(compiler.call()); // so now make a jar containing the java module File jarFolder = new File(destDir, "com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld/1/"); jarFolder.mkdirs(); File jarFile = new File(jarFolder, "com.redhat.ceylon.compiler.java.test.bc.binaryVersionOld-1.jar"); // now jar it up JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(jarFile)); ZipEntry entry = new ZipEntry("com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld/module_.class"); outputStream.putNextEntry(entry); File javaClass = new File(destDir, "com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld/module_.class"); FileInputStream inputStream = new FileInputStream(javaClass); Util.copy(inputStream, outputStream); inputStream.close(); outputStream.close(); assertErrors("binaryVersion/module", new CompilerError(21, "version '1' of module 'com.redhat.ceylon.compiler.java.test.bc.binaryVersionOld' was compiled by" + " an incompatible version of the compiler" +" (binary version 0.0 of module is not compatible with binary version " +Versions.JVM_BINARY_MAJOR_VERSION+"."+Versions.JVM_BINARY_MINOR_VERSION+" of this compiler)")); } // tests after we renamed module_.class to $module_.class @Test public void testBinaryVersionIncompatibleModule2() throws IOException { CompilationTask compiler = compileJava("binaryVersionOld2/$module_.java"); Assert.assertTrue(compiler.call()); // so now make a jar containing the java module File jarFolder = new File(destDir, "com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld2/1/"); jarFolder.mkdirs(); File jarFile = new File(jarFolder, "com.redhat.ceylon.compiler.java.test.bc.binaryVersionOld2-1.jar"); // now jar it up JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(jarFile)); ZipEntry entry = new ZipEntry("com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld2/$module_.class"); outputStream.putNextEntry(entry); File javaClass = new File(destDir, "com/redhat/ceylon/compiler/java/test/bc/binaryVersionOld2/$module_.class"); FileInputStream inputStream = new FileInputStream(javaClass); Util.copy(inputStream, outputStream); inputStream.close(); outputStream.close(); assertErrors("binaryVersion2/module", new CompilerError(21, "version '1' of module 'com.redhat.ceylon.compiler.java.test.bc.binaryVersionOld2' was compiled by" + " an incompatible version of the compiler" +" (binary version 0.0 of module is not compatible with binary version " +Versions.JVM_BINARY_MAJOR_VERSION+"."+Versions.JVM_BINARY_MINOR_VERSION+" of this compiler)")); } private CompilationTask compileJava(String... sourcePaths) { java.util.List<File> sourceFiles = new ArrayList<File>(sourcePaths.length); for(String file : sourcePaths){ sourceFiles.add(new File(getPackagePath(), file)); } JavaCompiler runCompiler = ToolProvider.getSystemJavaCompiler(); assertNotNull("Missing Java compiler, this test is probably being run with a JRE instead of a JDK!", runCompiler); StandardJavaFileManager runFileManager = runCompiler.getStandardFileManager(null, null, null); // make sure the destination repo exists new File(destDir).mkdirs(); List<String> options = new LinkedList<String>(); options.addAll(Arrays.asList("-sourcepath", getSourcePath(), "-d", destDir, "-cp", getClassPathAsPath())); Iterable<? extends JavaFileObject> compilationUnits1 = runFileManager.getJavaFileObjectsFromFiles(sourceFiles); return runCompiler.getTask(null, runFileManager, null, options, null, compilationUnits1); } }