Compiles a project as a whole
This commit is contained in:
@@ -17,6 +17,9 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GenerationState {
|
public class GenerationState {
|
||||||
private final ClassFileFactory factory;
|
private final ClassFileFactory factory;
|
||||||
private final Project project;
|
private final Project project;
|
||||||
@@ -85,14 +88,31 @@ public class GenerationState {
|
|||||||
|
|
||||||
public void compile(JetFile psiFile) {
|
public void compile(JetFile psiFile) {
|
||||||
final JetNamespace namespace = psiFile.getRootNamespace();
|
final JetNamespace namespace = psiFile.getRootNamespace();
|
||||||
NamespaceCodegen codegen = forNamespace(namespace);
|
|
||||||
final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
|
final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
|
||||||
bindingContexts.push(bindingContext);
|
AnalyzingUtils.throwExceptionOnErrors(bindingContext);
|
||||||
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace));
|
||||||
try {
|
// NamespaceCodegen codegen = forNamespace(namespace);
|
||||||
AnalyzingUtils.throwExceptionOnErrors(bindingContext);
|
// bindingContexts.push(bindingContext);
|
||||||
|
// typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||||
|
// try {
|
||||||
|
// AnalyzingUtils.throwExceptionOnErrors(bindingContext);
|
||||||
|
//
|
||||||
|
// codegen.generate(namespace);
|
||||||
|
// }
|
||||||
|
// finally {
|
||||||
|
// bindingContexts.pop();
|
||||||
|
// typeMapper = null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
codegen.generate(namespace);
|
public void compileCorrectNamespaces(BindingContext bindingContext, List<JetNamespace> namespaces) {
|
||||||
|
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||||
|
bindingContexts.push(bindingContext);
|
||||||
|
try {
|
||||||
|
for (JetNamespace namespace : namespaces) {
|
||||||
|
NamespaceCodegen codegen = forNamespace(namespace);
|
||||||
|
codegen.generate(namespace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
bindingContexts.pop();
|
bindingContexts.pop();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
//import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
//import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
||||||
//import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
//import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||||
@@ -66,7 +67,12 @@ public class AnalyzingUtils {
|
|||||||
|
|
||||||
public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||||
Project project = namespace.getProject();
|
Project project = namespace.getProject();
|
||||||
|
List<JetDeclaration> declarations = Collections.<JetDeclaration>singletonList(namespace);
|
||||||
|
|
||||||
|
return analyzeNamespaces(project, declarations, flowDataTraceFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindingContext analyzeNamespaces(@NotNull Project project, @NotNull List<? extends JetDeclaration> declarations, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, flowDataTraceFactory);
|
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, flowDataTraceFactory);
|
||||||
|
|
||||||
@@ -105,7 +111,7 @@ public class AnalyzingUtils {
|
|||||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
||||||
throw new IllegalStateException("Must be guaranteed not to happen by the parser");
|
throw new IllegalStateException("Must be guaranteed not to happen by the parser");
|
||||||
}
|
}
|
||||||
}, Collections.<JetDeclaration>singletonList(namespace));
|
}, declarations);
|
||||||
return bindingTraceContext.getBindingContext();
|
return bindingTraceContext.getBindingContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class TopDownAnalyzer {
|
|||||||
public static void process(
|
public static void process(
|
||||||
@NotNull JetSemanticServices semanticServices,
|
@NotNull JetSemanticServices semanticServices,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<? extends JetDeclaration> declarations) {
|
||||||
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace);
|
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace);
|
||||||
new TypeHierarchyResolver(context).process(outerScope, owner, declarations);
|
new TypeHierarchyResolver(context).process(outerScope, owner, declarations);
|
||||||
new DeclarationResolver(context).process();
|
new DeclarationResolver(context).process();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class TypeHierarchyResolver {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<? extends JetDeclaration> declarations) {
|
||||||
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
||||||
|
|
||||||
createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in
|
createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in
|
||||||
@@ -62,7 +62,7 @@ public class TypeHierarchyResolver {
|
|||||||
private void collectNamespacesAndClassifiers(
|
private void collectNamespacesAndClassifiers(
|
||||||
@NotNull final JetScope outerScope,
|
@NotNull final JetScope outerScope,
|
||||||
@NotNull final NamespaceLike owner,
|
@NotNull final NamespaceLike owner,
|
||||||
@NotNull Collection<JetDeclaration> declarations) {
|
@NotNull Collection<? extends JetDeclaration> declarations) {
|
||||||
for (JetDeclaration declaration : declarations) {
|
for (JetDeclaration declaration : declarations) {
|
||||||
declaration.accept(new JetVisitorVoid() {
|
declaration.accept(new JetVisitorVoid() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,8 +48,12 @@ public class CallResolver {
|
|||||||
@NotNull ReceiverDescriptor receiver,
|
@NotNull ReceiverDescriptor receiver,
|
||||||
@NotNull final JetSimpleNameExpression nameExpression,
|
@NotNull final JetSimpleNameExpression nameExpression,
|
||||||
@NotNull JetType expectedType) {
|
@NotNull JetType expectedType) {
|
||||||
|
String referencedName = nameExpression.getReferencedName();
|
||||||
|
if (referencedName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Call call = CallMaker.makePropertyCall(nameExpression);
|
Call call = CallMaker.makePropertyCall(nameExpression);
|
||||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, nameExpression.getReferencedName());
|
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, referencedName);
|
||||||
return resolveCallToDescriptor(trace, scope, call, nameExpression.getNode(), expectedType, prioritizedTasks, nameExpression);
|
return resolveCallToDescriptor(trace, scope, call, nameExpression.getNode(), expectedType, prioritizedTasks, nameExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package org.jetbrains.jet.plugin.compiler;
|
package org.jetbrains.jet.plugin.compiler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.compiler.CompileContext;
|
import com.intellij.openapi.compiler.CompileContext;
|
||||||
import com.intellij.openapi.compiler.CompileScope;
|
import com.intellij.openapi.compiler.CompileScope;
|
||||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||||
import com.intellij.openapi.compiler.TranslatingCompiler;
|
import com.intellij.openapi.compiler.TranslatingCompiler;
|
||||||
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.module.Module;
|
import com.intellij.openapi.module.Module;
|
||||||
import com.intellij.openapi.util.Computable;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
@@ -15,14 +17,20 @@ import com.intellij.util.Chunk;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
import org.jetbrains.jet.codegen.GenerationState;
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
import static com.intellij.openapi.compiler.CompilerMessageCategory.ERROR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -45,67 +53,148 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(CompileContext compileContext, Chunk<Module> moduleChunk, VirtualFile[] virtualFiles, OutputSink outputSink) {
|
public void compile(final CompileContext compileContext, Chunk<Module> moduleChunk, final VirtualFile[] virtualFiles, OutputSink outputSink) {
|
||||||
Map<Module, ModuleCompileState> moduleMap = new HashMap<Module, ModuleCompileState>();
|
if (virtualFiles.length == 0) return;
|
||||||
|
|
||||||
for (VirtualFile virtualFile : virtualFiles) {
|
Module module = compileContext.getModuleByFile(virtualFiles[0]);
|
||||||
Module module = compileContext.getModuleByFile(virtualFile);
|
final VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
|
||||||
ModuleCompileState state = moduleMap.get(module);
|
if (outputDir == null) {
|
||||||
if (state == null) {
|
compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1);
|
||||||
state = new ModuleCompileState(compileContext, module, outputSink);
|
return;
|
||||||
moduleMap.put(module, state);
|
|
||||||
}
|
|
||||||
state.compile(virtualFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ModuleCompileState state : moduleMap.values()) {
|
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||||
state.done();
|
@Override
|
||||||
}
|
public void run() {
|
||||||
|
GenerationState generationState = new GenerationState(compileContext.getProject(), false);
|
||||||
}
|
List<JetNamespace> namespaces = Lists.newArrayList();
|
||||||
|
for (VirtualFile virtualFile : virtualFiles) {
|
||||||
private static class ModuleCompileState {
|
PsiFile psiFile = PsiManager.getInstance(compileContext.getProject()).findFile(virtualFile);
|
||||||
private final GenerationState state;
|
|
||||||
private final CompileContext compileContext;
|
|
||||||
private final Module module;
|
|
||||||
private final OutputSink outputSink;
|
|
||||||
|
|
||||||
public ModuleCompileState(final CompileContext compileContext, Module module, OutputSink outputSink) {
|
|
||||||
this.compileContext = compileContext;
|
|
||||||
this.module = module;
|
|
||||||
this.outputSink = outputSink;
|
|
||||||
state = ApplicationManager.getApplication().runReadAction(new Computable<GenerationState>() {
|
|
||||||
@Override
|
|
||||||
public GenerationState compute() {
|
|
||||||
return new GenerationState(compileContext.getProject(), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void compile(final VirtualFile virtualFile) {
|
|
||||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(virtualFile);
|
|
||||||
if (psiFile instanceof JetFile) {
|
if (psiFile instanceof JetFile) {
|
||||||
state.compile((JetFile) psiFile);
|
namespaces.add(((JetFile) psiFile).getRootNamespace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void done() {
|
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(compileContext.getProject(), namespaces, JetControlFlowDataTraceFactory.EMPTY);
|
||||||
VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
|
|
||||||
final ClassFileFactory factory = state.getFactory();
|
boolean errors = false;
|
||||||
List<String> files = factory.files();
|
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||||
for (String file : files) {
|
switch (diagnostic.getSeverity()) {
|
||||||
File target = new File(outputDir.getPath(), file);
|
case ERROR:
|
||||||
try {
|
errors = true;
|
||||||
FileUtil.writeToFile(target, factory.asBytes(file));
|
report(diagnostic, CompilerMessageCategory.ERROR, compileContext);
|
||||||
} catch (IOException e) {
|
break;
|
||||||
compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0);
|
case INFO:
|
||||||
|
report(diagnostic, CompilerMessageCategory.INFORMATION, compileContext);
|
||||||
|
break;
|
||||||
|
case WARNING:
|
||||||
|
report(diagnostic, CompilerMessageCategory.WARNING, compileContext);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!errors) {
|
||||||
|
generationState.compileCorrectNamespaces(bindingContext, namespaces);
|
||||||
|
|
||||||
|
final ClassFileFactory factory = generationState.getFactory();
|
||||||
|
List<String> files = factory.files();
|
||||||
|
for (String file : files) {
|
||||||
|
File target = new File(outputDir.getPath(), file);
|
||||||
|
try {
|
||||||
|
FileUtil.writeToFile(target, factory.asBytes(file));
|
||||||
|
} catch (IOException e) {
|
||||||
|
compileContext.addMessage(ERROR, e.getMessage(), null, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Map<Module, ModuleCompileState> moduleMap = new HashMap<Module, ModuleCompileState>();
|
||||||
|
//
|
||||||
|
// for (VirtualFile virtualFile : virtualFiles) {
|
||||||
|
// Module module = compileContext.getModuleByFile(virtualFile);
|
||||||
|
// ModuleCompileState state = moduleMap.get(module);
|
||||||
|
// if (state == null) {
|
||||||
|
// state = new ModuleCompileState(compileContext, module, outputSink);
|
||||||
|
// moduleMap.put(module, state);
|
||||||
|
// }
|
||||||
|
// state.compile(virtualFile);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (ModuleCompileState state : moduleMap.values()) {
|
||||||
|
// state.done();
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void report(Diagnostic diagnostic, CompilerMessageCategory severity, CompileContext compileContext) {
|
||||||
|
PsiFile psiFile = diagnostic.getFactory().getPsiFile(diagnostic);
|
||||||
|
TextRange textRange = diagnostic.getFactory().getTextRange(diagnostic);
|
||||||
|
Document document = psiFile.getViewProvider().getDocument();
|
||||||
|
int line;
|
||||||
|
int col;
|
||||||
|
if (document != null) {
|
||||||
|
line = document.getLineNumber(textRange.getStartOffset());
|
||||||
|
col = textRange.getStartOffset() - document.getLineStartOffset(line) + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line = -1;
|
||||||
|
col = -1;
|
||||||
|
}
|
||||||
|
VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||||
|
if (virtualFile == null) {
|
||||||
|
compileContext.addMessage(ERROR, "[Internal Error] No virtual file for PsiFile. Diagnostic: " + diagnostic.getMessage(), "", -1, -1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compileContext.addMessage(severity, diagnostic.getMessage(), virtualFile.getUrl(), line + 1, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private static class ModuleCompileState {
|
||||||
|
// private final GenerationState state;
|
||||||
|
// private final CompileContext compileContext;
|
||||||
|
// private final Module module;
|
||||||
|
// private final OutputSink outputSink;
|
||||||
|
//
|
||||||
|
// public ModuleCompileState(final CompileContext compileContext, Module module, OutputSink outputSink) {
|
||||||
|
// this.compileContext = compileContext;
|
||||||
|
// this.module = module;
|
||||||
|
// this.outputSink = outputSink;
|
||||||
|
// state = ApplicationManager.getApplication().runReadAction(new Computable<GenerationState>() {
|
||||||
|
// @Override
|
||||||
|
// public GenerationState compute() {
|
||||||
|
// return new GenerationState(compileContext.getProject(), false);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// public void compile(final VirtualFile virtualFile) {
|
||||||
|
// ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
// PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(virtualFile);
|
||||||
|
// if (psiFile instanceof JetFile) {
|
||||||
|
// state.compile((JetFile) psiFile);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void done() {
|
||||||
|
// VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
|
||||||
|
// final ClassFileFactory factory = state.getFactory();
|
||||||
|
// List<String> files = factory.files();
|
||||||
|
// for (String file : files) {
|
||||||
|
// File target = new File(outputDir.getPath(), file);
|
||||||
|
// try {
|
||||||
|
// FileUtil.writeToFile(target, factory.asBytes(file));
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// compileContext.addMessage(ERROR, e.getMessage(), null, 0, 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user