提交 71bac574 编写于 作者: A Andrey Breslav

Got rid of CompileSession class: this class shouldn't have had any objects,...

Got rid of CompileSession class: this class shouldn't have had any objects, now it is transformed into KotlinToJVMBytecodeCompiler
上级 da382308
......@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GeneratedClassLoader;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.FqName;
......@@ -125,9 +126,6 @@ public class CompileEnvironment {
}
public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
CompileSession moduleCompileSession = newCompileSession();
moduleCompileSession.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
if (moduleBuilder.getSourceFiles().isEmpty()) {
throw new CompileEnvironmentException("No source files where defined");
}
......@@ -150,45 +148,34 @@ public class CompileEnvironment {
CompileEnvironmentUtil.ensureRuntime(environment, compilerDependencies);
if (!moduleCompileSession.analyze() && !ignoreErrors) {
return null;
}
return moduleCompileSession.generate(false).getFactory();
return analyze();
}
public ClassLoader compileText(String code) {
CompileSession session = newCompileSession();
environment.addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
if (!session.analyze() && !ignoreErrors) {
ClassFileFactory factory = analyze();
if (factory == null) {
return null;
}
ClassFileFactory factory = session.generate(false).getFactory();
return new GeneratedClassLoader(factory);
}
public boolean compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = newCompileSession();
session.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
environment.addSources(sourceFileOrDir);
return compileBunchOfSources(jar, outputDir, includeRuntime, session);
return compileBunchOfSources(jar, outputDir, includeRuntime);
}
public boolean compileBunchOfSourceDirectories(List<String> sources, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = newCompileSession();
session.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
for (String source : sources) {
environment.addSources(source);
}
return compileBunchOfSources(jar, outputDir, includeRuntime, session);
return compileBunchOfSources(jar, outputDir, includeRuntime);
}
private boolean compileBunchOfSources(String jar, String outputDir, boolean includeRuntime, CompileSession session) {
private boolean compileBunchOfSources(String jar, String outputDir, boolean includeRuntime) {
FqName mainClass = null;
for (JetFile file : environment.getSourceFiles()) {
if (JetMainDetector.hasMain(file.getDeclarations())) {
......@@ -200,11 +187,11 @@ public class CompileEnvironment {
CompileEnvironmentUtil.ensureRuntime(environment, compilerDependencies);
if (!session.analyze() && !ignoreErrors) {
ClassFileFactory factory = analyze();
if (factory == null) {
return false;
}
ClassFileFactory factory = session.generate(false).getFactory();
if (jar != null) {
try {
CompileEnvironmentUtil.writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime);
......@@ -221,8 +208,15 @@ public class CompileEnvironment {
return true;
}
private CompileSession newCompileSession() {
return new CompileSession(environment, messageRenderer, errorStream, verbose, compilerDependencies);
private ClassFileFactory analyze() {
boolean stubs = compilerDependencies.getCompilerSpecialMode().isStubs();
GenerationState generationState =
KotlinToJVMBytecodeCompiler
.analyzeAndGenerate(environment, compilerDependencies, messageRenderer, errorStream, verbose, stubs);
if (generationState == null) {
return null;
}
return generationState.getFactory();
}
/**
......
......@@ -27,6 +27,7 @@ import jet.modules.Module;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GeneratedClassLoader;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
......@@ -159,14 +160,13 @@ public class CompileEnvironmentUtil {
ensureRuntime(scriptEnvironment, dependencies);
scriptEnvironment.addSources(moduleFile);
CompileSession scriptCompileSession = new CompileSession(scriptEnvironment, messageRenderer, errorStream, verbose, dependencies);
if (!scriptCompileSession.analyze()) {
GenerationState generationState = KotlinToJVMBytecodeCompiler
.analyzeAndGenerate(scriptEnvironment, dependencies, messageRenderer, errorStream, verbose, false);
if (generationState == null) {
return null;
}
ClassFileFactory factory = scriptCompileSession.generate(true).getFactory();
List<Module> modules = runDefineModules(dependencies, moduleFile, factory);
List<Module> modules = runDefineModules(dependencies, moduleFile, generationState.getFactory());
Disposer.dispose(disposable);
return modules;
......
......@@ -25,6 +25,7 @@ import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.CompilationErrorHandler;
......@@ -51,88 +52,43 @@ import java.util.Collection;
import java.util.List;
/**
* The session which handles analyzing and compiling a single module.
*
* @author yole
* @author abreslav
*/
public class CompileSession {
private final JetCoreEnvironment environment;
private final MessageCollector messageCollector;
private boolean stubs = false;
private final MessageRenderer messageRenderer;
private final PrintStream errorStream;
private final boolean verbose;
private final CompilerDependencies compilerDependencies;
private AnalyzeExhaust bindingContext;
public CompileSession(JetCoreEnvironment environment, MessageRenderer messageRenderer, PrintStream errorStream, boolean verbose,
@NotNull CompilerDependencies compilerDependencies) {
this.environment = environment;
this.messageRenderer = messageRenderer;
this.errorStream = errorStream;
this.verbose = verbose;
this.compilerDependencies = compilerDependencies;
this.messageCollector = new MessageCollector(this.messageRenderer);
}
public class KotlinToJVMBytecodeCompiler {
@NotNull
public AnalyzeExhaust getBindingContext() {
return bindingContext;
}
@Nullable
public static GenerationState analyzeAndGenerate(
JetCoreEnvironment environment,
CompilerDependencies dependencies,
public void setStubs(boolean stubs) {
this.stubs = stubs;
}
MessageRenderer messageRenderer,
PrintStream errorStream,
boolean verbose,
public boolean analyze() {
reportSyntaxErrors();
analyzeAndReportSemanticErrors();
boolean stubs
) {
AnalyzeExhaust exhaust = analyze(environment, dependencies, messageRenderer, errorStream, stubs);
messageCollector.printTo(errorStream);
return !messageCollector.hasErrors();
}
/**
* @see JetTypeMapper#getFQName(DeclarationDescriptor)
* TODO possibly duplicates DescriptorUtils#getFQName(DeclarationDescriptor)
*/
private static String fqName(ClassOrNamespaceDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration == null || containingDeclaration instanceof ModuleDescriptor || containingDeclaration.getName().equals(JavaDescriptorResolver.JAVA_ROOT)) {
return descriptor.getName();
if (exhaust == null) {
return null;
}
else {
return fqName((ClassOrNamespaceDescriptor) containingDeclaration) + "." + descriptor.getName();
}
}
private void analyzeAndReportSemanticErrors() {
Predicate<PsiFile> filesToAnalyzeCompletely =
stubs ? Predicates.<PsiFile>alwaysFalse() : Predicates.<PsiFile>alwaysTrue();
bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY,
compilerDependencies);
return generate(environment, dependencies, messageRenderer, errorStream, verbose, exhaust, stubs);
}
for (Diagnostic diagnostic : bindingContext.getBindingContext().getDiagnostics()) {
reportDiagnostic(messageCollector, diagnostic);
}
@Nullable
private static AnalyzeExhaust analyze(
JetCoreEnvironment environment,
CompilerDependencies dependencies,
reportIncompleteHierarchies(messageCollector);
}
MessageRenderer messageRenderer,
PrintStream errorStream,
private void reportIncompleteHierarchies(MessageCollector collector) {
Collection<ClassDescriptor> incompletes = bindingContext.getBindingContext().getKeys(BindingContext.INCOMPLETE_HIERARCHY);
if (!incompletes.isEmpty()) {
StringBuilder message = new StringBuilder("The following classes have incomplete hierarchies:\n");
for (ClassDescriptor incomplete : incompletes) {
message.append(" ").append(fqName(incomplete)).append("\n");
}
collector.report(Severity.ERROR, message.toString(), null, -1, -1);
}
}
boolean stubs) {
final MessageCollector messageCollector = new MessageCollector(messageRenderer);
private void reportSyntaxErrors() {
//reportSyntaxErrors();
for (JetFile file : environment.getSourceFiles()) {
file.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
......@@ -144,38 +100,87 @@ public class CompileSession {
}
});
}
}
private static void reportDiagnostic(MessageCollector collector, Diagnostic diagnostic) {
DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumn(diagnostic);
VirtualFile virtualFile = diagnostic.getPsiFile().getVirtualFile();
String path = virtualFile == null ? null : virtualFile.getPath();
collector.report(diagnostic.getSeverity(), diagnostic.getMessage(), path, lineAndColumn.getLine(), lineAndColumn.getColumn());
//analyzeAndReportSemanticErrors();
Predicate<PsiFile> filesToAnalyzeCompletely =
stubs ? Predicates.<PsiFile>alwaysFalse() : Predicates.<PsiFile>alwaysTrue();
AnalyzeExhaust exhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY,
dependencies);
for (Diagnostic diagnostic : exhaust.getBindingContext().getDiagnostics()) {
reportDiagnostic(messageCollector, diagnostic);
}
reportIncompleteHierarchies(messageCollector, exhaust);
messageCollector.printTo(errorStream);
return messageCollector.hasErrors() ? null : exhaust;
}
@NotNull
public GenerationState generate(boolean module) {
private static GenerationState generate(
JetCoreEnvironment environment,
CompilerDependencies dependencies,
final MessageRenderer messageRenderer,
final PrintStream errorStream,
boolean verbose,
AnalyzeExhaust exhaust,
boolean stubs) {
Project project = environment.getProject();
class BackendProgress implements Progress {
@Override
public void log(String message) {
errorStream.println(messageRenderer.render(Severity.LOGGING, message, null, -1, -1));
}
}
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs),
verbose ? new BackendProgress() : Progress.DEAF, bindingContext, environment.getSourceFiles(), compilerDependencies.getCompilerSpecialMode());
verbose ? new BackendProgress() : Progress.DEAF, exhaust, environment.getSourceFiles(), dependencies.getCompilerSpecialMode());
generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
List<CompilerPlugin> plugins = environment.getCompilerPlugins();
if (!module) {
if (plugins != null) {
CompilerPluginContext context = new CompilerPluginContext(project, bindingContext.getBindingContext(), environment.getSourceFiles());
for (CompilerPlugin plugin : plugins) {
plugin.processFiles(context);
}
if (plugins != null) {
CompilerPluginContext context = new CompilerPluginContext(project, exhaust.getBindingContext(), environment.getSourceFiles());
for (CompilerPlugin plugin : plugins) {
plugin.processFiles(context);
}
}
return generationState;
}
private class BackendProgress implements Progress {
@Override
public void log(String message) {
errorStream.println(messageRenderer.render(Severity.LOGGING, message, null, -1, -1));
private static void reportDiagnostic(MessageCollector collector, Diagnostic diagnostic) {
DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumn(diagnostic);
VirtualFile virtualFile = diagnostic.getPsiFile().getVirtualFile();
String path = virtualFile == null ? null : virtualFile.getPath();
collector.report(diagnostic.getSeverity(), diagnostic.getMessage(), path, lineAndColumn.getLine(), lineAndColumn.getColumn());
}
private static void reportIncompleteHierarchies(MessageCollector collector, AnalyzeExhaust exhaust) {
Collection<ClassDescriptor> incompletes = exhaust.getBindingContext().getKeys(BindingContext.INCOMPLETE_HIERARCHY);
if (!incompletes.isEmpty()) {
StringBuilder message = new StringBuilder("The following classes have incomplete hierarchies:\n");
for (ClassDescriptor incomplete : incompletes) {
message.append(" ").append(fqName(incomplete)).append("\n");
}
collector.report(Severity.ERROR, message.toString(), null, -1, -1);
}
}
/**
* @see JetTypeMapper#getFQName(DeclarationDescriptor)
* TODO possibly duplicates DescriptorUtils#getFQName(DeclarationDescriptor)
*/
private static String fqName(ClassOrNamespaceDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration == null || containingDeclaration instanceof ModuleDescriptor || containingDeclaration.getName().equals(JavaDescriptorResolver.JAVA_ROOT)) {
return descriptor.getName();
}
else {
return fqName((ClassOrNamespaceDescriptor) containingDeclaration) + "." + descriptor.getName();
}
}
}
......@@ -23,7 +23,7 @@ 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.CompileSession;
import org.jetbrains.jet.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.compiler.MessageRenderer;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
......@@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.parsing.JetParsingTest;
import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.URL;
......@@ -74,10 +75,8 @@ public class TestlibTest extends CodegenTestCase {
private TestSuite doBuildSuite() {
try {
PrintStream err = System.err;
CompilerDependencies compilerDependencies = CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR);
CompileSession session = new CompileSession(myEnvironment, MessageRenderer.PLAIN, System.err, false,
compilerDependencies);
File junitJar = new File("libraries/lib/junit-4.9.jar");
if (!junitJar.exists()) {
......@@ -92,19 +91,21 @@ public class TestlibTest extends CodegenTestCase {
myEnvironment.addSources(localFileSystem.findFileByPath(JetParsingTest.getTestDataDir() + "/../../libraries/stdlib/test"));
myEnvironment.addSources(localFileSystem.findFileByPath(JetParsingTest.getTestDataDir() + "/../../libraries/kunit/src"));
if (!session.analyze()) {
GenerationState generationState = KotlinToJVMBytecodeCompiler
.analyzeAndGenerate(myEnvironment, compilerDependencies, MessageRenderer.PLAIN, err, false, false);
if (generationState == null) {
throw new RuntimeException("There were compilation errors");
}
GenerationState state = session.generate(false);
ClassFileFactory classFileFactory = state.getFactory();
ClassFileFactory classFileFactory = generationState.getFactory();
final GeneratedClassLoader loader = new GeneratedClassLoader(
classFileFactory,
new URLClassLoader(new URL[]{ForTestCompileRuntime.runtimeJarForTests().toURI().toURL(), junitJar.toURI().toURL()},
TestCase.class.getClassLoader()));
JetTypeMapper typeMapper = state.getInjector().getJetTypeMapper();
JetTypeMapper typeMapper = generationState.getInjector().getJetTypeMapper();
TestSuite suite = new TestSuite("stdlib_test");
try {
for(JetFile jetFile : myEnvironment.getSourceFiles()) {
......@@ -112,7 +113,7 @@ public class TestlibTest extends CodegenTestCase {
if(decl instanceof JetClass) {
JetClass jetClass = (JetClass) decl;
ClassDescriptor descriptor = (ClassDescriptor) session.getBindingContext().getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, jetClass);
ClassDescriptor descriptor = (ClassDescriptor) generationState.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, jetClass);
Set<JetType> allSuperTypes = new THashSet<JetType>();
DescriptorUtils.addSuperTypes(descriptor.getDefaultType(), allSuperTypes);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册