diff --git a/idea/src/org/jetbrains/jet/plugin/internal/Location.java b/idea/src/org/jetbrains/jet/plugin/internal/Location.java new file mode 100644 index 00000000000..c8ac0ce3889 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/internal/Location.java @@ -0,0 +1,115 @@ +/* + * 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.plugin.internal; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetFile; + +/** +* @author Nikolay Krasko +*/ +public class Location { + @Nullable + final Editor editor; + + @Nullable + final JetFile jetFile; + + final long modificationStamp; + + final int startOffset; + final int endOffset; + + private Location(@Nullable Editor editor, Project project) { + this.editor = editor; + + if (editor != null) { + modificationStamp = editor.getDocument().getModificationStamp(); + startOffset = editor.getSelectionModel().getSelectionStart(); + endOffset = editor.getSelectionModel().getSelectionEnd(); + + VirtualFile vFile = ((EditorEx) editor).getVirtualFile(); + if (vFile == null) { + jetFile = null; + } + else { + PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile); + jetFile = psiFile instanceof JetFile ? (JetFile) psiFile : null; + } + } + else { + modificationStamp = 0; + startOffset = 0; + endOffset = 0; + jetFile = null; + } + } + + public static Location fromEditor(Editor editor, Project project) { + return new Location(editor, project); + } + + @Nullable + public JetFile getJetFile() { + return jetFile; + } + + @Nullable + public Editor getEditor() { + return editor; + } + + public int getStartOffset() { + return startOffset; + } + + public int getEndOffset() { + return endOffset; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Location)) return false; + + Location location = (Location)o; + + if (modificationStamp != location.modificationStamp) return false; + if (endOffset != location.endOffset) return false; + if (startOffset != location.startOffset) return false; + if (editor != null ? !editor.equals(location.editor) : location.editor != null) return false; + if (jetFile != null ? !jetFile.equals(location.jetFile) : location.jetFile != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = editor != null ? editor.hashCode() : 0; + result = 31 * result + (jetFile != null ? jetFile.hashCode() : 0); + result = 31 * result + (int)(modificationStamp ^ (modificationStamp >>> 32)); + result = 31 * result + startOffset; + result = 31 * result + endOffset; + return result; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java index 13b5c99bdd1..6dd09b9a0c3 100644 --- a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java +++ b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java @@ -27,22 +27,21 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ScrollType; -import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; import com.intellij.util.Alarm; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.codegen.ClassBuilderFactories; import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.CompilationErrorHandler; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.plugin.internal.Location; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.util.LongRunningReadTask; import javax.swing.*; import java.awt.*; @@ -54,67 +53,89 @@ import java.util.List; import java.util.Scanner; public class BytecodeToolwindow extends JPanel implements Disposable { - private static final int UPDATE_DELAY = 500; + private static final int UPDATE_DELAY = 1000; private static final String DEFAULT_TEXT = "/*\n" + "Generated bytecode for Kotlin source file.\n" + "No Kotlin source file is opened.\n" + "*/"; - private final Editor myEditor; - private final Alarm myUpdateAlarm; - private Location myCurrentLocation; - private final Project myProject; - - - public BytecodeToolwindow(Project project) { - super(new BorderLayout()); - myProject = project; - myEditor = - EditorFactory.getInstance().createEditor(EditorFactory.getInstance().createDocument(""), project, JavaFileType.INSTANCE, true); - add(myEditor.getComponent()); - myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this); - myUpdateAlarm.addRequest(new Runnable() { - @Override - public void run() { - myUpdateAlarm.addRequest(this, UPDATE_DELAY); - Location location = Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor()); - if (!Comparing.equal(location, myCurrentLocation)) { - updateBytecode(location, myCurrentLocation); - myCurrentLocation = location; - } + public class UpdateBytecodeToolWindowTask extends LongRunningReadTask { + @Override + protected Location prepareRequestInfo() { + Location location = Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor(), myProject); + if (location.getEditor() == null || location.getJetFile() == null) { + return null; } - }, UPDATE_DELAY); - } - private void updateBytecode(Location location, Location oldLocation) { - Editor editor = location.editor; + return location; + } - if (editor == null) { + @NotNull + @Override + protected Location cloneRequestInfo(@NotNull Location location) { + Location newLocation = super.cloneRequestInfo(location); + assert location.equals(newLocation) : "cloneRequestInfo should generate same location object"; + return newLocation; + } + + @Override + protected void hideResultOnInvalidLocation() { setText(DEFAULT_TEXT); } - else { - VirtualFile vFile = ((EditorEx)editor).getVirtualFile(); - if (vFile == null) { - setText(DEFAULT_TEXT); + + @NotNull + @Override + protected String processRequest(@NotNull Location location) { + JetFile jetFile = location.getJetFile(); + assert jetFile != null; + + GenerationState state; + try { + AnalyzeExhaust binding = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile); + if (binding.isError()) { + return printStackTraceToString(binding.getError()); + } + state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEXT, binding, Collections.singletonList(jetFile)); + state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Exception e) { + return printStackTraceToString(e); + } + + StringBuilder answer = new StringBuilder(); + + final ClassFileFactory factory = state.getFactory(); + for (String filename : factory.files()) { + answer.append("// ================ "); + answer.append(filename); + answer.append(" =================\n"); + answer.append(factory.asText(filename)).append("\n\n"); + } + + return answer.toString(); + } + + @Override + protected void onResultReady(@NotNull Location requestInfo, final String resultText) { + Editor editor = requestInfo.getEditor(); + assert editor != null; + + if (resultText == null) { return; } - PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); - if (!(psiFile instanceof JetFile)) { - setText(DEFAULT_TEXT); - return; - } + setText(resultText); - if (oldLocation == null || - !Comparing.equal(oldLocation.editor, location.editor) || - oldLocation.modificationStamp != location.modificationStamp) { - setText(generateToText((JetFile)psiFile)); - } + int fileStartOffset = requestInfo.getStartOffset(); + int fileEndOffset = requestInfo.getEndOffset(); Document document = editor.getDocument(); - int startLine = document.getLineNumber(location.startOffset); - int endLine = document.getLineNumber(location.endOffset); - if (endLine > startLine && location.endOffset > 0 && document.getCharsSequence().charAt(location.endOffset - 1) == '\n') { + int startLine = document.getLineNumber(fileStartOffset); + int endLine = document.getLineNumber(fileEndOffset); + if (endLine > startLine && fileEndOffset > 0 && document.getCharsSequence().charAt(fileEndOffset - 1) == '\n') { endLine--; } @@ -135,6 +156,37 @@ public class BytecodeToolwindow extends JPanel implements Disposable { } } + private final Editor myEditor; + private final Alarm myUpdateAlarm; + private final Project myProject; + + private UpdateBytecodeToolWindowTask currentTask = null; + + public BytecodeToolwindow(Project project) { + super(new BorderLayout()); + myProject = project; + myEditor = EditorFactory.getInstance().createEditor( + EditorFactory.getInstance().createDocument(""), project, JavaFileType.INSTANCE, true); + add(myEditor.getComponent()); + + myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this); + myUpdateAlarm.addRequest(new Runnable() { + @Override + public void run() { + myUpdateAlarm.addRequest(this, UPDATE_DELAY); + UpdateBytecodeToolWindowTask task = new UpdateBytecodeToolWindowTask(); + task.init(); + + if (task.shouldStart(currentTask)) { + currentTask = task; + currentTask.run(); + } + } + }, UPDATE_DELAY); + + setText(DEFAULT_TEXT); + } + private static Pair mapLines(String text, int startLine, int endLine) { int byteCodeLine = 0; int byteCodeStartLine = -1; @@ -192,109 +244,29 @@ public class BytecodeToolwindow extends JPanel implements Disposable { } } - private void setText(final String text) { + private static String printStackTraceToString(Throwable e) { + StringWriter out = new StringWriter(1024); + PrintWriter printWriter = new PrintWriter(out); + try { + e.printStackTrace(printWriter); + return out.toString().replace("\r", ""); + } + finally { + printWriter.close(); + } + } + + private void setText(@NotNull final String resultText) { new WriteCommandAction(myProject) { @Override protected void run(Result result) throws Throwable { - myEditor.getDocument().setText(text); + myEditor.getDocument().setText(resultText); } }.execute(); } - protected String generateToText(JetFile file) { - GenerationState state; - try { - AnalyzeExhaust binding = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); -// AnalyzingUtils.throwExceptionOnErrors(binding); - if (binding.isError()) { - return printStackTraceToString(binding.getError()); - } - state = new GenerationState(file.getProject(), ClassBuilderFactories.TEXT, binding, Collections.singletonList(file)); - state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); - } - catch (Exception e) { - return printStackTraceToString(e); - } - - - StringBuilder answer = new StringBuilder(); - - final ClassFileFactory factory = state.getFactory(); - for (String filename : factory.files()) { - answer.append("// ================ "); - answer.append(filename); - answer.append(" =================\n"); - answer.append(factory.asText(filename)).append("\n\n"); - } - - return answer.toString(); - } - - private static String printStackTraceToString(Throwable e) {StringWriter out = new StringWriter(1024); - e.printStackTrace(new PrintWriter(out)); - return out.toString().replace("\r", ""); - } - @Override public void dispose() { EditorFactory.getInstance().releaseEditor(myEditor); } - - public static class Location { - final Editor editor; - final long modificationStamp; - final int startOffset; - final int endOffset; - - private Location(Editor editor) { - this.editor = editor; - modificationStamp = editor != null ? editor.getDocument().getModificationStamp() : 0; - startOffset = editor != null ? editor.getSelectionModel().getSelectionStart() : 0; - endOffset = editor != null ? editor.getSelectionModel().getSelectionEnd() : 0; - } - - public static Location fromEditor(Editor editor) { - return new Location(editor); - } - - public Editor getEditor() { - return editor; - } - - public long getModificationStamp() { - return modificationStamp; - } - - public int getStartOffset() { - return startOffset; - } - - public int getEndOffset() { - return endOffset; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Location)) return false; - - Location location = (Location)o; - - if (endOffset != location.endOffset) return false; - if (modificationStamp != location.modificationStamp) return false; - if (startOffset != location.startOffset) return false; - if (editor != null ? !editor.equals(location.editor) : location.editor != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = editor != null ? editor.hashCode() : 0; - result = 31 * result + (int)(modificationStamp ^ (modificationStamp >>> 32)); - result = 31 * result + startOffset; - result = 31 * result + endOffset; - return result; - } - } -} +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java index a440827fdd5..0f17f04c340 100644 --- a/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java +++ b/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java @@ -24,17 +24,14 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.Alarm; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetElement; @@ -47,10 +44,10 @@ import org.jetbrains.jet.lang.resolve.calls.inference.BoundsOwner; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetFileType; -import org.jetbrains.jet.plugin.internal.codewindow.BytecodeToolwindow; +import org.jetbrains.jet.plugin.internal.Location; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.util.LongRunningReadTask; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; -import org.jetbrains.jet.util.slicedmap.WritableSlice; import javax.swing.*; import java.awt.*; @@ -67,110 +64,121 @@ public class ResolveToolwindow extends JPanel implements Disposable { public static final String BAR = "\n\n===\n\n"; - private static final int UPDATE_DELAY = 500; + private static final int UPDATE_DELAY = 1000; private static final String DEFAULT_TEXT = "/*\n" + "Information about symbols resolved by\nKotlin compiler.\n" + "No Kotlin source file is opened.\n" + "*/"; - private final Editor myEditor; - private final Alarm myUpdateAlarm; - private BytecodeToolwindow.Location myCurrentLocation; - private final Project myProject; + private static final String NO_REFERENCE_TEXT = "/*\n" + + "Information about symbols resolved by\nKotlin compiler.\n" + + "Invalid place for getting reference information.\n" + + "*/"; + + private class UpdateResolveToolWindowTask extends LongRunningReadTask { + @Override + protected Location prepareRequestInfo() { + Location location = Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor(), myProject); + if (location.getEditor() == null || location.getJetFile() == null) { + return null; + } + + return location; + } + + @Override + protected void hideResultOnInvalidLocation() { + setText(DEFAULT_TEXT); + } + + @NotNull + @Override + protected String processRequest(@NotNull Location requestInfo) { + JetFile jetFile = requestInfo.getJetFile(); + assert jetFile != null; + + int startOffset = requestInfo.getStartOffset(); + int endOffset = requestInfo.getEndOffset(); + + BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile).getBindingContext(); + + PsiElement elementAtOffset; + if (startOffset == endOffset) { + elementAtOffset = PsiUtilCore.getElementAtOffset(jetFile, startOffset); + } + else { + PsiElement start = PsiUtilCore.getElementAtOffset(jetFile, startOffset); + PsiElement end = PsiUtilCore.getElementAtOffset(jetFile, endOffset - 1); + elementAtOffset = PsiTreeUtil.findCommonParent(start, end); + } + + PsiElement elementWithDebugInfo = findData(bindingContext, elementAtOffset, RESOLUTION_DEBUG_INFO); + if (elementWithDebugInfo != null) { + return renderDebugInfo(elementWithDebugInfo, bindingContext.get(RESOLUTION_DEBUG_INFO, elementWithDebugInfo), null); + } + + @SuppressWarnings("unchecked") + PsiElement elementWithResolvedCall = findData(bindingContext, elementAtOffset, (ReadOnlySlice) RESOLVED_CALL); + if (elementWithResolvedCall instanceof JetElement) { + return renderDebugInfo(elementWithResolvedCall, null, + bindingContext.get(RESOLVED_CALL, (JetElement) elementWithResolvedCall)); + } + + JetExpression parentExpression = (elementAtOffset instanceof JetExpression) ? + (JetExpression) elementAtOffset : + PsiTreeUtil.getParentOfType(elementAtOffset, JetExpression.class); + + if (parentExpression != null) { + JetType type = bindingContext.get(EXPRESSION_TYPE, parentExpression); + String text = parentExpression + "|" + parentExpression.getText() + "| : " + type; + if (parentExpression instanceof JetReferenceExpression) { + JetReferenceExpression referenceExpression = (JetReferenceExpression) parentExpression; + DeclarationDescriptor target = bindingContext.get(REFERENCE_TARGET, referenceExpression); + text += "\nReference target: \n" + target; + } + + return text; + } + + return NO_REFERENCE_TEXT; + } + + @Override + protected void onResultReady(@NotNull Location requestInfo, @Nullable final String resultText) { + if (resultText != null) { + setText(resultText); + } + } + } + + private final Alarm myUpdateAlarm; + private final Editor myEditor; + private UpdateResolveToolWindowTask currentTask = null; + + private final Project myProject; public ResolveToolwindow(Project project) { super(new BorderLayout()); myProject = project; - myEditor = EditorFactory.getInstance().createEditor(EditorFactory.getInstance().createDocument(""), project, JetFileType.INSTANCE, true); + myEditor = EditorFactory.getInstance() + .createEditor(EditorFactory.getInstance().createDocument(""), project, JetFileType.INSTANCE, true); add(myEditor.getComponent()); myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this); myUpdateAlarm.addRequest(new Runnable() { @Override public void run() { myUpdateAlarm.addRequest(this, UPDATE_DELAY); - BytecodeToolwindow.Location location = BytecodeToolwindow.Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor()); - if (!Comparing.equal(location, myCurrentLocation)) { - render(location, myCurrentLocation); - myCurrentLocation = location; + UpdateResolveToolWindowTask task = new UpdateResolveToolWindowTask(); + task.init(); + + if (task.shouldStart(currentTask)) { + currentTask = task; + currentTask.run(); } } }, UPDATE_DELAY); - } - private void render(BytecodeToolwindow.Location location, BytecodeToolwindow.Location oldLocation) { - Editor editor = location.getEditor(); - if (editor == null) { - setText(DEFAULT_TEXT); - } - else { - VirtualFile vFile = ((EditorEx) editor).getVirtualFile(); - if (vFile == null) { - setText(DEFAULT_TEXT); - return; - } - - PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); - if (!(psiFile instanceof JetFile)) { - setText(DEFAULT_TEXT); - return; - } - - - int startOffset = location.getStartOffset(); - int endOffset = location.getEndOffset(); - if (oldLocation == null || !Comparing.equal(oldLocation.getEditor(), location.getEditor()) - || oldLocation.getStartOffset() != startOffset - || oldLocation.getEndOffset() != endOffset) { - - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) psiFile) - .getBindingContext(); - - - PsiElement elementAtOffset; - if (startOffset == endOffset) { - elementAtOffset = PsiUtilCore.getElementAtOffset(psiFile, startOffset); - } - else { - PsiElement start = PsiUtilCore.getElementAtOffset(psiFile, startOffset); - PsiElement end = PsiUtilCore.getElementAtOffset(psiFile, endOffset - 1); - elementAtOffset = PsiTreeUtil.findCommonParent(start, end); - } - - PsiElement currentElement = elementAtOffset; - - boolean callFound = false; - - PsiElement elementWithDebugInfo = findData(bindingContext, currentElement, RESOLUTION_DEBUG_INFO); - if (elementWithDebugInfo != null) { - callFound = true; - setText(renderDebugInfo(elementWithDebugInfo, bindingContext.get(RESOLUTION_DEBUG_INFO, elementWithDebugInfo), null)); - } - else { - PsiElement elementWithResolvedCall = findData(bindingContext, currentElement, (WritableSlice) RESOLVED_CALL); - if (elementWithResolvedCall instanceof JetElement) { - callFound = true; - setText(renderDebugInfo(elementWithResolvedCall, null, bindingContext.get(RESOLVED_CALL, (JetElement) elementWithResolvedCall))); - } - } - - if (!callFound) { - - JetExpression parentExpression = (elementAtOffset instanceof JetExpression) ? - (JetExpression) elementAtOffset : - PsiTreeUtil.getParentOfType(elementAtOffset, JetExpression.class); - if (parentExpression != null) { - JetType type = bindingContext.get(EXPRESSION_TYPE, parentExpression); - String text = parentExpression + "|" + parentExpression.getText() + "| : " + type; - if (parentExpression instanceof JetReferenceExpression) { - JetReferenceExpression referenceExpression = (JetReferenceExpression) parentExpression; - DeclarationDescriptor target = bindingContext.get(REFERENCE_TARGET, referenceExpression); - text += "\nReference target: \n" + target; - } - setText(text); - } - } - } - } + setText(DEFAULT_TEXT); } @Nullable @@ -182,18 +190,22 @@ public class ResolveToolwindow extends JPanel implements Disposable { if (data != null && data != NO_DEBUG_INFO) { return currentElement; } - } + currentElement = currentElement.getParent(); } + return null; } - private static String renderDebugInfo(PsiElement currentElement, + @NotNull + private static String renderDebugInfo( + PsiElement currentElement, @Nullable ResolutionDebugInfo.Data debugInfo, - @Nullable ResolvedCall call) { + @Nullable ResolvedCall call + ) { StringBuilder result = new StringBuilder(); - + if (debugInfo != null) { List> resolutionTasks = debugInfo.get(TASKS); for (ResolutionTask resolutionTask : resolutionTasks) { @@ -215,9 +227,11 @@ public class ResolveToolwindow extends JPanel implements Disposable { return result.toString(); } - private static void renderResolutionLogForCall(Data debugInfo, + private static void renderResolutionLogForCall( + Data debugInfo, ResolvedCallWithTrace resolvedCall, - StringBuilder result) { + StringBuilder result + ) { result.append("Trying to call ").append(resolvedCall.getCandidateDescriptor()).append("\n"); StringBuilder errors = debugInfo.getByKey(ERRORS, resolvedCall); if (errors != null) { @@ -254,7 +268,6 @@ public class ResolveToolwindow extends JPanel implements Disposable { } private static String renderCall(StringBuilder builder, ResolvedCall resolvedCall) { - CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); ReceiverDescriptor thisObject = resolvedCall.getThisObject(); @@ -329,17 +342,17 @@ public class ResolveToolwindow extends JPanel implements Disposable { if (receiverArgument.exists()) { builder.append("/").append(receiverArgument); } - + if (thisObject.exists()) { builder.append("/this=").append(thisObject); } - + if (thisObject.exists() || receiverArgument.exists()) { builder.append("/."); } } - private void setText(final String text) { + private void setText(@NotNull final String text) { new WriteCommandAction(myProject) { @Override protected void run(Result result) throws Throwable { diff --git a/idea/src/org/jetbrains/jet/plugin/util/LongRunningReadTask.java b/idea/src/org/jetbrains/jet/plugin/util/LongRunningReadTask.java index 39fe4617090..62964642ccd 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/LongRunningReadTask.java +++ b/idea/src/org/jetbrains/jet/plugin/util/LongRunningReadTask.java @@ -35,7 +35,7 @@ public abstract class LongRunningReadTask { INITIALIZED, STARTED, FINISHED, - FINISHED_AND_PROCESSED + FINISHED_WITH_ACTUAL_DATA } private ProgressIndicator progressIndicator = null; @@ -45,7 +45,7 @@ public abstract class LongRunningReadTask { protected LongRunningReadTask() {} /** Should be executed in GUI thread */ - public boolean isShouldStartWithCancel(@Nullable LongRunningReadTask previousTask) { + public boolean shouldStart(@Nullable LongRunningReadTask previousTask) { ApplicationManager.getApplication().assertIsDispatchThread(); if (currentState != State.INITIALIZED) { @@ -60,20 +60,19 @@ public abstract class LongRunningReadTask { } if (requestInfo == null) { - if (previousTask != null && (previousTask.currentState == State.FINISHED_AND_PROCESSED || previousTask.currentState == State.FINISHED)) { + if (previousTask != null && (previousTask.currentState == State.FINISHED_WITH_ACTUAL_DATA || previousTask.currentState == State.FINISHED)) { previousTask.hideResultOnInvalidLocation(); } return false; } - if (previousTask != null) { if (previousTask.currentState == State.STARTED) { // Start new task only if previous isn't working on similar request return !requestInfo.equals(previousTask.requestInfo); } - else if (previousTask.currentState == State.FINISHED_AND_PROCESSED) { + else if (previousTask.currentState == State.FINISHED_WITH_ACTUAL_DATA) { if (requestInfo.equals(previousTask.requestInfo)) { return false; } @@ -144,7 +143,7 @@ public abstract class LongRunningReadTask { if (resultData != null) { RequestInfo actualInfo = prepareRequestInfo(); if (requestInfo.equals(actualInfo)) { - currentState = State.FINISHED_AND_PROCESSED; + currentState = State.FINISHED_WITH_ACTUAL_DATA; onResultReady(actualInfo, resultData); } } @@ -172,6 +171,8 @@ public abstract class LongRunningReadTask { /** * Executed in GUI Thread. + * + * @return null if current request is invalid and task shouldn't be executed. */ @Nullable protected abstract RequestInfo prepareRequestInfo();