Refactor cli: all the jvm stuff goes under org.jetbrains.jet.cli.jvm, common stuff under org.jetbrains.jet.cli.common

This commit is contained in:
pTalanov
2012-04-25 20:19:15 +04:00
parent b1b9446f13
commit d0d5b147f2
67 changed files with 113 additions and 4056 deletions
@@ -30,9 +30,8 @@ import com.intellij.testFramework.LightVirtualFile;
import com.intellij.testFramework.TestDataFile;
import com.intellij.testFramework.UsefulTestCase;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.jet.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.plugin.JetLanguage;
@@ -24,7 +24,7 @@ import com.intellij.openapi.util.io.FileUtil;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
@@ -17,11 +17,11 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.compiler.CompileEnvironmentConfiguration;
import org.jetbrains.jet.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.compiler.JetCoreEnvironment;
import org.jetbrains.jet.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.compiler.messages.MessageCollector;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
@@ -23,9 +23,9 @@ import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.jet.compiler.CompileEnvironmentConfiguration;
import org.jetbrains.jet.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.compiler.messages.MessageCollector;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration;
@@ -17,7 +17,8 @@
package org.jetbrains.jet.codegen.forTestCompile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
import java.io.File;
@@ -37,9 +38,9 @@ public class ForTestCompileBuiltins {
@Override
protected void doCompile(@NotNull File classesDir) throws Exception {
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(
ExitCode exitCode = new K2JVMCompiler().exec(
System.err, "-output", classesDir.getPath(), "-src", "./compiler/frontend/src", "-mode", "builtins");
if (exitCode != KotlinCompiler.ExitCode.OK) {
if (exitCode != ExitCode.OK) {
throw new IllegalStateException("jdk headers compilation failed: " + exitCode);
}
}
@@ -17,7 +17,8 @@
package org.jetbrains.jet.codegen.forTestCompile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
import java.io.File;
@@ -37,9 +38,9 @@ public class ForTestCompileJdkHeaders {
@Override
protected void doCompile(@NotNull File classesDir) throws Exception {
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(
ExitCode exitCode = new K2JVMCompiler().exec(
System.err, "-output", classesDir.getPath(), "-src", "./jdk-headers/src", "-mode", "jdkHeaders");
if (exitCode != KotlinCompiler.ExitCode.OK) {
if (exitCode != ExitCode.OK) {
throw new IllegalStateException("jdk headers compilation failed: " + exitCode);
}
}
@@ -16,12 +16,10 @@
package org.jetbrains.jet.codegen.forTestCompile;
import com.google.common.io.Files;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
import org.junit.Assert;
import javax.tools.JavaCompiler;
@@ -29,12 +27,9 @@ import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
/**
* Compile stdlib.jar that can be used in tests
@@ -63,12 +58,12 @@ public class ForTestCompileRuntime {
}
private static void compileStdlib(File destdir) throws IOException {
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(System.err,
ExitCode exitCode = new K2JVMCompiler().exec(System.err,
"-output", destdir.getPath(),
"-src", "./libraries/stdlib/src",
"-mode", "stdlib",
"-classpath", "out/production/runtime");
if (exitCode != KotlinCompiler.ExitCode.OK) {
if (exitCode != ExitCode.OK) {
throw new IllegalStateException("stdlib for test compilation failed: " + exitCode);
}
}
@@ -1,103 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.openapi.util.io.FileUtil;
import junit.framework.TestCase;
import org.jetbrains.jet.cli.KotlinCompiler;
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileJdkHeaders;
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.jet.parsing.JetParsingTest;
import org.junit.Assert;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* @author yole
* @author alex.tkachman
*/
public class CompileEnvironmentTest extends TestCase {
public void testSmokeWithCompilerJar() throws IOException {
File tempDir = FileUtil.createTempDirectory("compilerTest", "compilerTest");
try {
File stdlib = ForTestCompileRuntime.runtimeJarForTests();
File jdkHeaders = ForTestCompileJdkHeaders.jdkHeadersForTests();
File resultJar = new File(tempDir, "result.jar");
KotlinCompiler.ExitCode rv = new KotlinCompiler().exec(System.out,
"-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts",
"-jar", resultJar.getAbsolutePath(),
"-stdlib", stdlib.getAbsolutePath(),
"-jdkHeaders", jdkHeaders.getAbsolutePath());
Assert.assertEquals("compilation completed with non-zero code", KotlinCompiler.ExitCode.OK, rv);
FileInputStream fileInputStream = new FileInputStream(resultJar);
try {
JarInputStream is = new JarInputStream(fileInputStream);
try {
final List<String> entries = listEntries(is);
assertTrue(entries.contains("Smoke/namespace.class"));
assertEquals(1, entries.size());
}
finally {
is.close();
}
}
finally {
fileInputStream.close();
}
}
finally {
FileUtil.delete(tempDir);
}
}
public void testSmokeWithCompilerOutput() throws IOException {
File tempDir = FileUtil.createTempDirectory("compilerTest", "compilerTest");
try {
File out = new File(tempDir, "out");
File stdlib = ForTestCompileRuntime.runtimeJarForTests();
File jdkHeaders = ForTestCompileJdkHeaders.jdkHeadersForTests();
KotlinCompiler.ExitCode exitCode = new KotlinCompiler()
.exec(System.out, "-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt", "-output",
out.getAbsolutePath(), "-stdlib", stdlib.getAbsolutePath(), "-jdkHeaders", jdkHeaders.getAbsolutePath());
Assert.assertEquals(KotlinCompiler.ExitCode.OK, exitCode);
assertEquals(1, out.listFiles().length);
assertEquals(1, out.listFiles()[0].listFiles().length);
} finally {
FileUtil.delete(tempDir);
}
}
private static List<String> listEntries(JarInputStream is) throws IOException {
List<String> entries = new ArrayList<String>();
while (true) {
final JarEntry jarEntry = is.getNextJarEntry();
if (jarEntry == null) {
break;
}
entries.add(jarEntry.getName());
}
return entries;
}
}
@@ -1,113 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.plugin.JetLanguage;
import org.junit.Assert;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* @author Stepan Koltsov
*
* @see WriteSignatureTest
*/
public class CompileJavaAgainstKotlinTest extends TestCaseWithTmpdir {
private final File ktFile;
private final File javaFile;
private JetCoreEnvironment jetCoreEnvironment;
public CompileJavaAgainstKotlinTest(File ktFile) {
this.ktFile = ktFile;
Assert.assertTrue(ktFile.getName().endsWith(".kt"));
this.javaFile = new File(ktFile.getPath().replaceFirst("\\.kt", ".java"));
}
@Override
public String getName() {
return ktFile.getName();
}
@Override
protected void runTest() throws Throwable {
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
String text = FileUtil.loadFile(ktFile);
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
Disposer.dispose(myTestRootDisposable);
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
try {
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile));
List<String> options = Arrays.asList(
"-classpath", tmpdir.getPath() + System.getProperty("path.separator") + "out/production/stdlib",
"-d", tmpdir.getPath()
);
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
Assert.assertTrue(task.call());
} finally {
fileManager.close();
}
}
public static Test suite() {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/compileJavaAgainstKotlin", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new CompileJavaAgainstKotlinTest(file);
}
});
}
}
@@ -1,133 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;
import junit.framework.Assert;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.plugin.JetLanguage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
* @author Stepan Koltsov
*/
public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir {
private final File ktAFile;
private final File ktBFile;
public CompileKotlinAgainstKotlinTest(File ktAFile) {
Assert.assertTrue(ktAFile.getName().endsWith("A.kt"));
this.ktAFile = ktAFile;
this.ktBFile = new File(ktAFile.getPath().replaceFirst("A\\.kt$", "B.kt"));
}
@Override
public String getName() {
return ktAFile.getName();
}
private File aDir;
private File bDir;
@Override
protected void setUp() throws Exception {
super.setUp();
aDir = new File(tmpdir, "a");
bDir = new File(tmpdir, "b");
JetTestUtils.mkdirs(aDir);
JetTestUtils.mkdirs(bDir);
}
@Override
protected void runTest() throws Throwable {
compileA();
compileB();
URLClassLoader classLoader = new URLClassLoader(new URL[]{ aDir.toURI().toURL(), bDir.toURI().toURL() });
Class<?> clazz = classLoader.loadClass("bbb.namespace");
Method main = clazz.getMethod("main", new Class[] { String[].class });
main.invoke(null, new Object[] { new String[0] });
}
private void compileA() throws IOException {
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
String text = FileUtil.loadFile(ktAFile);
LightVirtualFile virtualFile = new LightVirtualFile(ktAFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, aDir.getPath());
Disposer.dispose(myTestRootDisposable);
}
private void compileB() throws IOException {
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
jetCoreEnvironment.addToClasspath(aDir);
String text = FileUtil.loadFile(ktBFile);
LightVirtualFile virtualFile = new LightVirtualFile(ktAFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, bDir.getPath());
Disposer.dispose(myTestRootDisposable);
}
public static Test suite() {
class Filter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("A.kt");
}
}
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/compileKotlinAgainstKotlin", true, new Filter(), new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new CompileKotlinAgainstKotlinTest(file);
}
});
}
}
@@ -1,72 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.junit.Assert;
import javax.tools.*;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* @author Stepan Koltsov
* @see ReadJavaBinaryClassTest
*/
public class JavaDescriptorResolverTest extends TestCaseWithTmpdir {
// This test can be implemented in ReadJavaBinaryClass test, but it is simpler here
public void testInner() throws Exception {
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
try {
File file = new File("compiler/testData/javaDescriptorResolver/inner.java");
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file));
List<String> options = Arrays.asList(
"-d", tmpdir.getPath()
);
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
Assert.assertTrue(task.call());
} finally {
fileManager.close();
}
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
jetCoreEnvironment.addToClasspath(tmpdir);
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName("A"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
Assert.assertNotNull(classDescriptor);
}
}
@@ -1,568 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.google.common.io.Files;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.PropertyCodegen;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import org.junit.Assert;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.*;
/**
* @author Stepan Koltsov
*/
class NamespaceComparator {
private final boolean includeObject;
private NamespaceComparator(boolean includeObject) {
this.includeObject = includeObject;
}
public static void compareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb, boolean includeObject,
@NotNull File txtFile) {
String serialized = new NamespaceComparator(includeObject).doCompareNamespaces(nsa, nsb);
try {
for (;;) {
String expected = Files.toString(txtFile, Charset.forName("utf-8")).replace("\r\n", "\n");
if (expected.contains("kick me")) {
// for developer
System.err.println("generating " + txtFile);
Files.write(serialized, txtFile, Charset.forName("utf-8"));
continue;
}
// compare with hardcopy: make sure nothing is lost in output
Assert.assertEquals(expected, serialized);
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String doCompareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) {
StringBuilder sb = new StringBuilder();
Assert.assertEquals(nsa.getName(), nsb.getName());
sb.append("namespace " + nsa.getName() + "\n\n");
Assert.assertTrue(!nsa.getMemberScope().getAllDescriptors().isEmpty());
Set<String> classifierNames = new HashSet<String>();
Set<String> propertyNames = new HashSet<String>();
Set<String> functionNames = new HashSet<String>();
for (DeclarationDescriptor ad : nsa.getMemberScope().getAllDescriptors()) {
if (ad instanceof ClassifierDescriptor) {
classifierNames.add(ad.getName());
}
else if (ad instanceof PropertyDescriptor) {
propertyNames.add(ad.getName());
}
else if (ad instanceof FunctionDescriptor) {
functionNames.add(ad.getName());
}
else {
throw new AssertionError("unknown member: " + ad);
}
}
for (String name : classifierNames) {
ClassifierDescriptor ca = nsa.getMemberScope().getClassifier(name);
ClassifierDescriptor cb = nsb.getMemberScope().getClassifier(name);
Assert.assertTrue(ca != null);
Assert.assertTrue(cb != null);
compareClassifiers(ca, cb, sb);
}
for (String name : propertyNames) {
Set<VariableDescriptor> pa = nsa.getMemberScope().getProperties(name);
Set<VariableDescriptor> pb = nsb.getMemberScope().getProperties(name);
compareDeclarationSets(pa, pb, sb);
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.getterName(name)).isEmpty());
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.setterName(name)).isEmpty());
}
for (String name : functionNames) {
Set<FunctionDescriptor> fa = nsa.getMemberScope().getFunctions(name);
Set<FunctionDescriptor> fb = nsb.getMemberScope().getFunctions(name);
compareDeclarationSets(fa, fb, sb);
}
return sb.toString();
}
private static void compareDeclarationSets(Set<? extends DeclarationDescriptor> a, Set<? extends DeclarationDescriptor> b,
@NotNull StringBuilder sb) {
String at = serializedDeclarationSets(a);
String bt = serializedDeclarationSets(b);
Assert.assertEquals(at, bt);
sb.append(at);
}
private static String serializedDeclarationSets(Collection<? extends DeclarationDescriptor> ds) {
List<String> strings = new ArrayList<String>();
for (DeclarationDescriptor d : ds) {
StringBuilder sb = new StringBuilder();
new Serializer(sb).serialize(d);
strings.add(sb.toString());
}
Collections.sort(strings, new MemberComparator());
StringBuilder r = new StringBuilder();
for (String string : strings) {
r.append(string);
r.append("\n");
}
return r.toString();
}
/**
* This comparator only affects test output, you can drop it if you don't want to understand it.
*/
private static class MemberComparator implements Comparator<String> {
@NotNull
private String normalize(String s) {
return s.replaceFirst(
"^ *(private|final|abstract|open|override|fun|val|var|/\\*.*?\\*/|((?!<init>)<.*?>)| )*",
"")
+ s;
}
@Override
public int compare(@NotNull String a, @NotNull String b) {
return normalize(a).compareTo(normalize(b));
}
}
private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b, @NotNull StringBuilder sb) {
StringBuilder sba = new StringBuilder();
StringBuilder sbb = new StringBuilder();
new FullContentSerialier(sba).serialize((ClassDescriptor) a);
new FullContentSerialier(sbb).serialize((ClassDescriptor) b);
String as = sba.toString();
String bs = sbb.toString();
Assert.assertEquals(as, bs);
sb.append(as);
}
private static class Serializer {
protected final StringBuilder sb;
public Serializer(StringBuilder sb) {
this.sb = sb;
}
public void serialize(ClassKind kind) {
switch (kind) {
case CLASS:
sb.append("class");
break;
case TRAIT:
sb.append("trait");
break;
case OBJECT:
sb.append("object");
break;
case ANNOTATION_CLASS:
sb.append("annotation class");
break;
default:
throw new IllegalStateException("unknown class kind: " + kind);
}
}
private static Object invoke(Method method, Object thiz, Object... args) {
try {
return method.invoke(thiz, args);
} catch (Exception e) {
throw new RuntimeException("failed to invoke " + method + ": " + e, e);
}
}
public void serialize(FunctionDescriptor fun) {
serialize(fun.getModality());
sb.append(" ");
if (!fun.getAnnotations().isEmpty()) {
new Serializer(sb).serializeSeparated(fun.getAnnotations(), " ");
sb.append(" ");
}
if (!fun.getOverriddenDescriptors().isEmpty()) {
sb.append("override /*" + fun.getOverriddenDescriptors().size() + "*/ ");
}
if (fun instanceof ConstructorDescriptor) {
sb.append("/*constructor*/ ");
}
sb.append("fun ");
if (!fun.getTypeParameters().isEmpty()) {
sb.append("<");
new Serializer(sb).serializeCommaSeparated(fun.getTypeParameters());
sb.append(">");
}
if (fun.getReceiverParameter().exists()) {
new TypeSerializer(sb).serialize(fun.getReceiverParameter());
sb.append(".");
}
sb.append(fun.getName());
sb.append("(");
new TypeSerializer(sb).serializeCommaSeparated(fun.getValueParameters());
sb.append("): ");
new TypeSerializer(sb).serialize(fun.getReturnType());
}
public void serialize(ExtensionReceiver extensionReceiver) {
serialize(extensionReceiver.getType());
}
public void serialize(PropertyDescriptor prop) {
serialize(prop.getModality());
sb.append(" ");
if (!prop.getAnnotations().isEmpty()) {
new Serializer(sb).serializeSeparated(prop.getAnnotations(), " ");
sb.append(" ");
}
if (prop.isVar()) {
sb.append("var ");
}
else {
sb.append("val ");
}
if (!prop.getTypeParameters().isEmpty()) {
sb.append(" <");
new Serializer(sb).serializeCommaSeparated(prop.getTypeParameters());
sb.append("> ");
}
if (prop.getReceiverParameter().exists()) {
new TypeSerializer(sb).serialize(prop.getReceiverParameter().getType());
sb.append(".");
}
sb.append(prop.getName());
sb.append(": ");
new TypeSerializer(sb).serialize(prop.getType());
}
public void serialize(ValueParameterDescriptor valueParameter) {
sb.append("/*");
sb.append(valueParameter.getIndex());
sb.append("*/ ");
if (valueParameter.getVarargElementType() != null) {
sb.append("vararg ");
}
sb.append(valueParameter.getName());
sb.append(": ");
if (valueParameter.getVarargElementType() != null) {
new TypeSerializer(sb).serialize(valueParameter.getVarargElementType());
}
else {
new TypeSerializer(sb).serialize(valueParameter.getType());
}
if (valueParameter.hasDefaultValue()) {
sb.append(" = ?");
}
}
public void serialize(Variance variance) {
if (variance == Variance.INVARIANT) {
}
else {
sb.append(variance);
sb.append(' ');
}
}
public void serialize(Modality modality) {
sb.append(modality.name().toLowerCase());
}
public void serialize(AnnotationDescriptor annotation) {
new TypeSerializer(sb).serialize(annotation.getType());
sb.append("(");
serializeCommaSeparated(annotation.getValueArguments());
sb.append(")");
}
public void serializeCommaSeparated(List<?> list) {
serializeSeparated(list, ", ");
}
public void serializeSeparated(List<?> list, String sep) {
boolean first = true;
for (Object o : list) {
if (!first) {
sb.append(sep);
}
serialize(o);
first = false;
}
}
private Method getMethodToSerialize(Object o) {
if (o == null) {
throw new IllegalStateException("won't serialize null");
}
// TODO: cache
for (Method method : this.getClass().getMethods()) {
if (!method.getName().equals("serialize")) {
continue;
}
if (method.getParameterTypes().length != 1) {
continue;
}
if (method.getParameterTypes()[0].equals(Object.class)) {
continue;
}
if (method.getParameterTypes()[0].isInstance(o)) {
method.setAccessible(true);
return method;
}
}
throw new IllegalStateException("don't know how to serialize " + o + " (of " + o.getClass() + ")");
}
public void serialize(Object o) {
Method method = getMethodToSerialize(o);
invoke(method, this, o);
}
public void serialize(String s) {
sb.append(s);
}
public void serialize(ClassDescriptor clazz) {
sb.append(DescriptorUtils.getFQName(clazz));
}
public void serialize(NamespaceDescriptor ns) {
sb.append(DescriptorUtils.getFQName(ns));
}
public void serialize(TypeParameterDescriptor param) {
sb.append("/*");
sb.append(param.getIndex());
if (param.isReified()) {
sb.append(",r");
}
sb.append("*/ ");
serialize(param.getVariance());
sb.append(param.getName());
if (!param.getUpperBounds().isEmpty()) {
sb.append(" : ");
List<String> list = new ArrayList<String>();
for (JetType upper : param.getUpperBounds()) {
StringBuilder sb = new StringBuilder();
new TypeSerializer(sb).serialize(upper);
list.add(sb.toString());
}
Collections.sort(list);
serializeSeparated(list, " & "); // TODO: use where
}
// TODO: lower bounds
}
}
private static class TypeSerializer extends Serializer {
public TypeSerializer(StringBuilder sb) {
super(sb);
}
@Override
public void serialize(TypeParameterDescriptor param) {
sb.append(param.getName());
}
public void serialize(@NotNull JetType type) {
serialize(type.getConstructor().getDeclarationDescriptor());
if (!type.getArguments().isEmpty()) {
sb.append("<");
boolean first = true;
for (TypeProjection proj : type.getArguments()) {
if (!first) {
sb.append(", ");
}
serialize(proj.getProjectionKind());
serialize(proj.getType());
first = false;
}
sb.append(">");
}
if (type.isNullable()) {
sb.append("?");
}
}
}
private static boolean isRootNs(DeclarationDescriptor ns) {
return ns instanceof NamespaceDescriptor && ns.getContainingDeclaration() instanceof ModuleDescriptor;
}
private static class NamespacePrefixSerializer extends Serializer {
public NamespacePrefixSerializer(StringBuilder sb) {
super(sb);
}
@Override
public void serialize(NamespaceDescriptor ns) {
super.serialize(ns);
if (isRootNs(ns)) {
return;
}
sb.append(".");
}
@Override
public void serialize(ClassDescriptor clazz) {
super.serialize(clazz);
sb.append(".");
}
}
private class FullContentSerialier extends Serializer {
private FullContentSerialier(StringBuilder sb) {
super(sb);
}
public void serialize(ClassDescriptor klass) {
if (!klass.getAnnotations().isEmpty()) {
new Serializer(sb).serializeSeparated(klass.getAnnotations(), " ");
sb.append(" ");
}
serialize(klass.getModality());
sb.append(" ");
serialize(klass.getKind());
sb.append(" ");
new Serializer(sb).serialize(klass);
if (!klass.getTypeConstructor().getParameters().isEmpty()) {
sb.append("<");
serializeCommaSeparated(klass.getTypeConstructor().getParameters());
sb.append(">");
}
if (!klass.getTypeConstructor().getSupertypes().isEmpty()) {
sb.append(" : ");
new TypeSerializer(sb).serializeCommaSeparated(new ArrayList<JetType>(klass.getTypeConstructor().getSupertypes()));
}
sb.append(" {\n");
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>();
for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) {
typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType()));
}
List<String> memberStrings = new ArrayList<String>();
for (ConstructorDescriptor constructor : klass.getConstructors()) {
StringBuilder constructorSb = new StringBuilder();
new Serializer(constructorSb).serialize(constructor);
memberStrings.add(constructorSb.toString());
}
JetScope memberScope = klass.getMemberScope(typeArguments);
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
if (!includeObject) {
if (member.getName().matches("equals|hashCode|finalize|wait|notify(All)?|toString|clone|getClass")) {
continue;
}
}
StringBuilder memberSb = new StringBuilder();
new FullContentSerialier(memberSb).serialize(member);
memberStrings.add(memberSb.toString());
}
Collections.sort(memberStrings, new MemberComparator());
for (String memberString : memberStrings) {
sb.append(indent(memberString));
}
if (klass.getClassObjectDescriptor() != null) {
StringBuilder sbForClassObject = new StringBuilder();
new FullContentSerialier(sbForClassObject).serialize(klass.getClassObjectDescriptor());
sb.append(indent(sbForClassObject.toString()));
}
sb.append("}\n");
}
}
private static String indent(String string) {
try {
StringBuilder r = new StringBuilder();
BufferedReader reader = new BufferedReader(new StringReader(string));
for (;;) {
String line = reader.readLine();
if (line == null) {
break;
}
r.append(" ");
r.append(line);
r.append("\n");
}
return r.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -1,132 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.plugin.JetLanguage;
import org.junit.Assert;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* @author Stepan Koltsov
*/
public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir {
private final File ktFile;
private final File javaFile;
private final File txtFile;
public ReadJavaBinaryClassTest(File ktFile) {
this.ktFile = ktFile;
Assert.assertTrue(ktFile.getName().endsWith(".kt"));
this.javaFile = new File(ktFile.getPath().replaceFirst("\\.kt$", ".java"));
this.txtFile = new File(ktFile.getPath().replaceFirst("\\.kt$", ".txt"));
setName(javaFile.getName());
}
@Override
public void runTest() throws Exception {
NamespaceDescriptor nsa = compileKotlin();
NamespaceDescriptor nsb = compileJava();
NamespaceComparator.compareNamespaces(nsa, nsb, false, txtFile);
}
private NamespaceDescriptor compileKotlin() throws Exception {
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
String text = FileUtil.loadFile(ktFile);
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
psiFile, JetControlFlowDataTraceFactory.EMPTY,
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true))
.getBindingContext();
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel("test"));
}
private NamespaceDescriptor compileJava() throws Exception {
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
try {
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile));
List<String> options = Arrays.asList(
"-classpath", "out/production/runtime" + File.pathSeparator + JetTestUtils.getAnnotationsJar().getPath(),
"-d", tmpdir.getPath()
);
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
Assert.assertTrue(task.call());
} finally {
fileManager.close();
}
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
jetCoreEnvironment.addToClasspath(tmpdir);
jetCoreEnvironment.addToClasspath(new File("out/production/runtime"));
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
return javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
}
public static Test suite() {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readJavaBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new ReadJavaBinaryClassTest(file);
}
});
}
}
@@ -1,110 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;
import junit.framework.Assert;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.GenerationUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.plugin.JetLanguage;
import java.io.File;
/**
* Compile Kotlin and then parse model from .class files.
*
* @author Stepan Koltsov
*/
public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir {
private JetCoreEnvironment jetCoreEnvironment;
private final File testFile;
private final File txtFile;
public ReadKotlinBinaryClassTest(@NotNull File testFile) {
this.testFile = testFile;
this.txtFile = new File(testFile.getPath().replaceFirst("\\.kt$", ".txt"));
setName(testFile.getName());
}
@Override
public void runTest() throws Exception {
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
String text = FileUtil.loadFile(testFile);
LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
GenerationState state = GenerationUtils.compileFileGetGenerationStateForTest(psiFile, CompilerSpecialMode.JDK_HEADERS);
ClassFileFactory classFileFactory = state.getFactory();
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
NamespaceDescriptor namespaceFromSource = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, psiFile);
Assert.assertEquals("test", namespaceFromSource.getName());
Disposer.dispose(myTestRootDisposable);
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
jetCoreEnvironment.addToClasspath(tmpdir);
jetCoreEnvironment.addToClasspath(new File("out/production/runtime"));
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
NamespaceComparator.compareNamespaces(namespaceFromSource, namespaceFromClass, false, txtFile);
}
public static Test suite() {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readKotlinBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new ReadKotlinBinaryClassTest(file);
}
});
}
}
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.intellij.testFramework.UsefulTestCase;
import org.jetbrains.jet.JetTestUtils;
import java.io.File;
/**
* @author Stepan Koltsov
*/
public abstract class TestCaseWithTmpdir extends UsefulTestCase {
protected File tmpdir;
@Override
protected void setUp() throws Exception {
super.setUp();
tmpdir = JetTestUtils.tmpDirForTest(this);
}
}
@@ -1,316 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;
import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.plugin.JetLanguage;
import org.junit.Assert;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.EmptyVisitor;
import org.objectweb.asm.commons.Method;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Test correctness of written JVM signature
*
* @author Stepan Koltsov
*
* @see CompileJavaAgainstKotlinTest
*/
public class WriteSignatureTest extends TestCaseWithTmpdir {
private final File ktFile;
private JetCoreEnvironment jetCoreEnvironment;
public WriteSignatureTest(File ktFile) {
this.ktFile = ktFile;
}
@Override
public String getName() {
return ktFile.getName();
}
@Override
protected void runTest() throws Throwable {
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
String text = FileUtil.loadFile(ktFile);
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
Disposer.dispose(myTestRootDisposable);
final Expectation expectation = parseExpectations();
ActualSignature actualSignature = readSignature(expectation.className, expectation.methodName);
String template =
"jvm signature: %s\n" +
"generic signature: %s\n" +
"kotlin signature: %s\n" +
"";
String expected = String.format(template, expectation.jvmSignature, expectation.genericSignature, expectation.kotlinSignature);
String actual = String.format(template, actualSignature.jvmSignature, actualSignature.genericSignature, actualSignature.kotlinSignature);
Assert.assertEquals(expected, actual);
}
private static class ActualSignature {
private final String jvmSignature;
private final String genericSignature;
private final String kotlinSignature;
private ActualSignature(@NotNull String jvmSignature, @Nullable String genericSignature, @Nullable String kotlinSignature) {
this.jvmSignature = jvmSignature;
this.genericSignature = genericSignature;
this.kotlinSignature = kotlinSignature;
}
}
@NotNull
private ActualSignature readSignature(String className, final String methodName) throws Exception {
// ugly unreadable code begin
FileInputStream classInputStream = new FileInputStream(tmpdir + "/" + className.replace('.', '/') + ".class");
try {
class Visitor extends EmptyVisitor {
ActualSignature readSignature;
@Override
public MethodVisitor visitMethod(int access, String name, final String desc, final String signature, String[] exceptions) {
if (name.equals(methodName)) {
final int parameterCount = new Method(name, desc).getArgumentTypes().length;
return new EmptyVisitor() {
String typeParameters = "";
String returnType;
String[] parameterTypes = new String[parameterCount];
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (desc.equals(JvmStdlibNames.JET_METHOD.getDescriptor())) {
return new EmptyVisitor() {
@Override
public void visit(String name, Object value) {
if (name.equals(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD)) {
typeParameters = (String) value;
}
else if (name.equals(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD)) {
returnType = (String) value;
}
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return new EmptyVisitor();
}
@Override
public AnnotationVisitor visitArray(String name) {
return new EmptyVisitor();
}
};
}
else {
return new EmptyVisitor();
}
}
@Override
public AnnotationVisitor visitParameterAnnotation(final int parameter, String desc, boolean visible) {
if (desc.equals(JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor())) {
return new EmptyVisitor() {
@Override
public void visit(String name, Object value) {
if (name.equals(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD)) {
parameterTypes[parameter] = (String) value;
}
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return new EmptyVisitor();
}
@Override
public AnnotationVisitor visitArray(String name) {
return new EmptyVisitor();
}
};
}
else {
return new EmptyVisitor();
}
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
return new EmptyVisitor();
}
@Nullable
private String makeKotlinSignature() {
boolean allNulls = true;
StringBuilder sb = new StringBuilder();
sb.append(typeParameters);
if (typeParameters != null && typeParameters.length() > 0) {
allNulls = false;
}
sb.append("(");
for (String parameterType : parameterTypes) {
sb.append(parameterType);
if (parameterType != null) {
allNulls = false;
}
}
sb.append(")");
sb.append(returnType);
if (returnType != null) {
allNulls = false;
}
if (allNulls) {
return null;
}
else {
return sb.toString();
}
}
@Override
public void visitEnd() {
Assert.assertNull(readSignature);
readSignature = new ActualSignature(desc, signature, makeKotlinSignature());
}
};
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
Visitor visitor = new Visitor();
new ClassReader(classInputStream).accept(visitor,
ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
Assert.assertNotNull("method not found: " + className + "::" + methodName, visitor.readSignature);
return visitor.readSignature;
} finally {
Closeables.closeQuietly(classInputStream);
}
// ugly unreadable code end
}
private static class Expectation {
private final String className;
private final String methodName;
private final String jvmSignature;
private final String genericSignature;
private final String kotlinSignature;
private Expectation(@NotNull String className, @NotNull String methodName,
@NotNull String jvmSignature, @Nullable String genericSignature, @Nullable String kotlinSignature) {
this.className = className;
this.methodName = methodName;
this.jvmSignature = jvmSignature;
this.genericSignature = genericSignature;
this.kotlinSignature = kotlinSignature;
}
}
@NotNull
private static final Pattern methodPattern = Pattern.compile("^// method: *(.*)::(.*?) *(//.*)?");
private static final Pattern jvmSignaturePattern = Pattern.compile("^// jvm signature: *(.+?) *(//.*)?");
private static final Pattern genericSignaturePattern = Pattern.compile("^// generic signature: *(.+?) *(//.*)?");
private static final Pattern kotlinSignaturePattern = Pattern.compile("^// kotlin signature: *(.+?) *(//.*)?");
private Expectation parseExpectations() throws IOException {
List<String> lines = Files.readLines(ktFile, Charset.forName("utf-8"));
for (int i = 0; i < lines.size() - 3; ++i) {
Matcher methodMatcher = methodPattern.matcher(lines.get(i));
if (methodMatcher.matches()) {
Matcher jvmSignatureMatcher = jvmSignaturePattern.matcher(lines.get(i + 1));
Matcher genericSignatureMatcher = genericSignaturePattern.matcher(lines.get(i + 2));
Matcher kotlinSignatureMatcher = kotlinSignaturePattern.matcher(lines.get(i + 3));
if (!jvmSignatureMatcher.matches() || !genericSignatureMatcher.matches() || !kotlinSignatureMatcher.matches()) {
throw new AssertionError("'method:' must be followed ... bla bla ... use the source luke");
}
String className = methodMatcher.group(1);
String methodName = methodMatcher.group(2);
String jvmSignature = jvmSignatureMatcher.group(1);
String genericSignature = genericSignatureMatcher.group(1);
String kotlinSignature = kotlinSignatureMatcher.group(1);
if (genericSignature.equals("null")) {
genericSignature = null;
}
if (kotlinSignature.equals("null")) {
kotlinSignature = null;
}
return new Expectation(className, methodName, jvmSignature, genericSignature, kotlinSignature);
}
}
throw new AssertionError("test instructions not found in " + ktFile);
}
public static Test suite() {
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/writeSignature", true, new JetTestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
return new WriteSignatureTest(file);
}
});
}
}
@@ -1,57 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler.longTest;
import org.jetbrains.annotations.NotNull;
/**
* @author Stepan Koltsov
*/
public class LibFromMaven {
@NotNull
private final String org;
@NotNull
private final String module;
@NotNull
private final String rev;
public LibFromMaven(@NotNull String org, @NotNull String module, @NotNull String rev) {
this.org = org;
this.module = module;
this.rev = rev;
}
@NotNull
public String getOrg() {
return org;
}
@NotNull
public String getModule() {
return module;
}
@NotNull
public String getRev() {
return rev;
}
@Override
public String toString() {
return org + "/" + module + "/" + rev;
}
}
@@ -1,199 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.compiler.longTest;
import com.google.common.io.ByteStreams;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.TimeUtils;
import org.jetbrains.jet.compiler.JetCoreEnvironment;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Stepan Koltsov
*/
public class ResolveDescriptorsFromExternalLibraries {
@NotNull
private final CompilerDependencies compilerDependencies;
public static void main(String[] args) throws Exception {
new ResolveDescriptorsFromExternalLibraries().run();
System.out.println("$");
}
public ResolveDescriptorsFromExternalLibraries() {
System.out.println("Getting compiler dependencies");
compilerDependencies = CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true);
}
private void run() throws Exception {
testLibrary("com.google.guava", "guava", "12.0-rc2");
testLibrary("org.springframework", "spring-core", "3.1.1.RELEASE");
}
private void testLibrary(@NotNull String org, @NotNull String module, @NotNull String rev) throws Exception {
LibFromMaven lib = new LibFromMaven(org, module, rev);
File jar = getLibrary(lib);
System.out.println("Testing library " + lib + "...");
System.out.println("Using file " + jar);
long start = System.currentTimeMillis();
Disposable junk = new Disposable() {
@Override
public void dispose() { }
};
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(junk);
jetCoreEnvironment.addToClasspath(jar);
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(compilerDependencies, jetCoreEnvironment.getProject());
FileInputStream is = new FileInputStream(jar);
try {
ZipInputStream zip = new ZipInputStream(is);
for (;;) {
ZipEntry entry = zip.getNextEntry();
if (entry == null) {
break;
}
String entryName = entry.getName();
if (!entryName.endsWith(".class")) {
continue;
}
if (entryName.matches("(.*/|)package-info\\.class")) {
continue;
}
if (entryName.contains("$")) {
continue;
}
String className = entryName.substring(0, entryName.length() - ".class".length()).replace("/", ".");
ClassDescriptor clazz = injector.getJavaDescriptorResolver().resolveClass(new FqName(className), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
if (clazz == null) {
throw new IllegalStateException("class not found by name " + className + " in " + lib);
}
clazz.getDefaultType().getMemberScope().getAllDescriptors();
}
} finally {
try {
is.close();
}
catch (Throwable e) {}
Disposer.dispose(junk);
}
System.out.println("Testing library " + lib + " done in " + TimeUtils.millisecondsToSecondsString(System.currentTimeMillis() - start) + "s");
}
@NotNull
private File getLibrary(@NotNull LibFromMaven lib) throws Exception {
File userHome = new File(System.getProperty("user.home"));
String fileName = lib.getModule() + "-" + lib.getRev() + ".jar";
File dir = new File(userHome, ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule());
File file = new File(dir, fileName);
if (file.exists()) {
return file;
}
JetTestUtils.mkdirs(dir);
File tmp = new File(dir, fileName + "~");
String uri = url(lib);
GetMethod method = new GetMethod(uri);
FileOutputStream os = null;
System.out.println("Downloading library " + lib + " to " + file);
MultiThreadedHttpConnectionManager connectionManager = null;
try {
connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(connectionManager);
os = new FileOutputStream(tmp);
String userAgent = ResolveDescriptorsFromExternalLibraries.class.getName() + "/commons-httpclient";
method.getParams().setParameter(HttpMethodParams.USER_AGENT, userAgent);
int code = httpClient.executeMethod(method);
if (code != 200) {
throw new RuntimeException("failed to execute GET " + uri + ", code is " + code);
}
InputStream responseBodyAsStream = method.getResponseBodyAsStream();
if (responseBodyAsStream == null) {
throw new RuntimeException("method is executed fine, but response is null");
}
ByteStreams.copy(responseBodyAsStream, os);
os.close();
if (!tmp.renameTo(file)) {
throw new RuntimeException("failed to rename file: " + tmp + " to " + file);
}
return file;
}
finally {
if (method != null) {
try {
method.releaseConnection();
}
catch (Throwable e) {}
}
if (connectionManager != null) {
try {
connectionManager.shutdown();
}
catch (Throwable e) {}
}
if (os != null) {
try {
os.close();
}
catch (Throwable e) {}
}
tmp.delete();
}
}
private static String url(LibFromMaven lib) {
return "http://repo1.maven.org/maven2/" + lib.getOrg().replace(".", "/") + "/" + lib.getModule() + "/" + lib.getRev()
+ "/" + lib.getModule() + "-" + lib.getRev() + ".jar";
}
}