diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index c0594fc2eb0..39862f0051e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -17,6 +17,9 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.commons.Method; +import java.util.Collections; +import java.util.List; + public class GenerationState { private final ClassFileFactory factory; private final Project project; @@ -85,14 +88,31 @@ public class GenerationState { public void compile(JetFile psiFile) { final JetNamespace namespace = psiFile.getRootNamespace(); - NamespaceCodegen codegen = forNamespace(namespace); final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY); - bindingContexts.push(bindingContext); - typeMapper = new JetTypeMapper(standardLibrary, bindingContext); - try { - AnalyzingUtils.throwExceptionOnErrors(bindingContext); + AnalyzingUtils.throwExceptionOnErrors(bindingContext); + compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace)); +// NamespaceCodegen codegen = forNamespace(namespace); +// 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 namespaces) { + typeMapper = new JetTypeMapper(standardLibrary, bindingContext); + bindingContexts.push(bindingContext); + try { + for (JetNamespace namespace : namespaces) { + NamespaceCodegen codegen = forNamespace(namespace); + codegen.generate(namespace); + } } finally { bindingContexts.pop(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 94e330a7756..7b39810143c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import java.util.Collections; +import java.util.List; //import org.jetbrains.jet.lang.resolve.java.JavaPackageScope; //import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; @@ -66,7 +67,12 @@ public class AnalyzingUtils { public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { Project project = namespace.getProject(); + List declarations = Collections.singletonList(namespace); + return analyzeNamespaces(project, declarations, flowDataTraceFactory); + } + + public BindingContext analyzeNamespaces(@NotNull Project project, @NotNull List declarations, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { BindingTraceContext bindingTraceContext = new BindingTraceContext(); JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, flowDataTraceFactory); @@ -105,7 +111,7 @@ public class AnalyzingUtils { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { throw new IllegalStateException("Must be guaranteed not to happen by the parser"); } - }, Collections.singletonList(namespace)); + }, declarations); return bindingTraceContext.getBindingContext(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 43d992ed5ce..504db799c1e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -61,7 +61,7 @@ public class TopDownAnalyzer { public static void process( @NotNull JetSemanticServices semanticServices, @NotNull BindingTrace trace, - @NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { + @NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace); new TypeHierarchyResolver(context).process(outerScope, owner, declarations); new DeclarationResolver(context).process(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index fbf91dd2808..b0e5e5a164b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -37,7 +37,7 @@ public class TypeHierarchyResolver { this.context = context; } - public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { + public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List declarations) { collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in @@ -62,7 +62,7 @@ public class TypeHierarchyResolver { private void collectNamespacesAndClassifiers( @NotNull final JetScope outerScope, @NotNull final NamespaceLike owner, - @NotNull Collection declarations) { + @NotNull Collection declarations) { for (JetDeclaration declaration : declarations) { declaration.accept(new JetVisitorVoid() { @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index f0423457999..ec4ce7e7ee9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -48,8 +48,12 @@ public class CallResolver { @NotNull ReceiverDescriptor receiver, @NotNull final JetSimpleNameExpression nameExpression, @NotNull JetType expectedType) { + String referencedName = nameExpression.getReferencedName(); + if (referencedName == null) { + return null; + } Call call = CallMaker.makePropertyCall(nameExpression); - List> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, nameExpression.getReferencedName()); + List> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, referencedName); return resolveCallToDescriptor(trace, scope, call, nameExpression.getNode(), expectedType, prioritizedTasks, nameExpression); } diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index 9c12a4b27d3..c29a35c2ea3 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -1,12 +1,14 @@ package org.jetbrains.jet.plugin.compiler; +import com.google.common.collect.Lists; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.compiler.TranslatingCompiler; +import com.intellij.openapi.editor.Document; 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.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -15,14 +17,20 @@ import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.codegen.ClassFileFactory; 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.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 java.io.File; import java.io.IOException; -import java.util.HashMap; import java.util.List; -import java.util.Map; + +import static com.intellij.openapi.compiler.CompilerMessageCategory.ERROR; /** * @author yole @@ -45,67 +53,148 @@ public class JetCompiler implements TranslatingCompiler { } @Override - public void compile(CompileContext compileContext, Chunk moduleChunk, VirtualFile[] virtualFiles, OutputSink outputSink) { - Map moduleMap = new HashMap(); + public void compile(final CompileContext compileContext, Chunk moduleChunk, final VirtualFile[] virtualFiles, OutputSink outputSink) { + if (virtualFiles.length == 0) return; - 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); + Module module = compileContext.getModuleByFile(virtualFiles[0]); + final VirtualFile outputDir = compileContext.getModuleOutputDirectory(module); + if (outputDir == null) { + compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1); + return; } - for (ModuleCompileState state : moduleMap.values()) { - state.done(); - } - - } - - 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() { - @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); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + GenerationState generationState = new GenerationState(compileContext.getProject(), false); + List namespaces = Lists.newArrayList(); + for (VirtualFile virtualFile : virtualFiles) { + PsiFile psiFile = PsiManager.getInstance(compileContext.getProject()).findFile(virtualFile); if (psiFile instanceof JetFile) { - state.compile((JetFile) psiFile); + namespaces.add(((JetFile) psiFile).getRootNamespace()); } } - }); - } - public void done() { - VirtualFile outputDir = compileContext.getModuleOutputDirectory(module); - final ClassFileFactory factory = state.getFactory(); - List 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(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0); + BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(compileContext.getProject(), namespaces, JetControlFlowDataTraceFactory.EMPTY); + + boolean errors = false; + for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { + switch (diagnostic.getSeverity()) { + case ERROR: + errors = true; + report(diagnostic, CompilerMessageCategory.ERROR, compileContext); + break; + 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 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 moduleMap = new HashMap(); +// +// 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() { +// @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 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); +// } +// } +// } +// } }